Sean Whitton: GNU Emacs' Transient Mark mode
Something I ve found myself doing as the pandemic rolls on is picking
out and (re-)reading through sections of the GNU Emacs
manual and the
GNU Emacs Lisp reference
manual. This
has got me (too) interested in some of the recent history of Emacs
development, and I did some digging into archives of emacs-devel from
2008 (15M
mbox) regarding the change to turn Transient Mark mode on by default
and set
We avoid turning Transient Mark mode off, but mitigate the second of
the two disadvantages given above.
I can t figure out why it was thought to be a good idea to make
Here we remove both of the disadvantages of Transient Mark mode given
above, and mitigate the main disadvantage of not activating Transient
Mark mode by making it more convenient to activate it temporarily.
For example, this enables using
mark-even-if-inactive
to true by default in Emacs 23.1.
It s not always clear which objections to turning on Transient Mark
mode by default take into account the mark-even-if-inactive
change.
I think that turning on Transient Mark mode along with
mark-even-if-inactive
is a good default. The question that remains
is whether the disadvantages of Transient Mark mode are significant
enough that experienced Emacs users should consider altering Emacs
default behaviour to mitigate them. Here s one popular blog arguing
for some
mitigations.
How might Transient Mark mode be disadvantageous?
The suggestion is that it makes using the mark for navigation rather
than for acting on regions less convenient:
- setting a mark just so you can jump back to it (i) is a distinct
operation you have to think of separately; and (ii) requires two
keypresses,
C-SPC C-SPC
, rather than just one keypress - using
exchange-point-and-mark
activates the region, so to use it for navigation you need to use eitherC-u C-x C-x
orC-x C-x C-g
, neither of which are convenient to type, or else it will be difficult to set regions at the place you ve just jumped to because you ll already have one active.
exchange-point-and-mark
, and it s
subsumed by the problem of that command actually activating the
region. The rest of the time Emacs automatic deactivation of the
region seems sufficient.
How might disabling Transient Mark mode be disadvantageous?
When Transient Mark mode is on, many commands will do something
usefully different when the mark is active. The number of commands in
Emacs which work this way is only going to increase now that Transient
Mark mode is the default.
If you disable Transient Mark mode, then to use those features you
need to temporarily activate Transient Mark mode. This can be fiddly
and/or require a lot of keypresses, depending on exactly where you
want to put the region.
Without being able to see the region, it might be harder to know where
it is. Indeed, this is one of the main reasons for wanting Transient
Mark mode to be the default, to avoid confusing new users. I don t
think this is likely to affect experienced Emacs users often, however,
and on occasions when more precision is really needed, C-u C-x C-x
will make the region visible. So I m not counting this as a
disadvantage.
How might we mitigate these two sets of disadvantages?
Here are the two middle grounds I m considering.
Mitigation #1: Transient Mark mode, but hack C-x C-x
behaviour
(defun spw/exchange-point-and-mark (arg)
"Exchange point and mark, but reactivate mark a bit less often.
Specifically, invert the meaning of ARG in the case where
Transient Mark mode is on but the region is inactive."
(interactive "P")
(exchange-point-and-mark
(if (and transient-mark-mode (not mark-active))
(not arg)
arg)))
(global-set-key [remap exchange-point-and-mark] &aposspw/exchange-point-and-mark)
C-x
C-x
reactivate the mark and require C-u C-x C-x
to use the action
of exchanging point and mark as a means of navigation. There needs to
a binding to reactivate the mark, but in roughly ten years of having
Transient Mark mode turned on, I ve found that the need to reactivate
the mark doesn t come up often, so the shorter and longer bindings
seem the wrong way around. Not sure what I m missing here.
Mitigation #2: disable Transient Mark mode, but enable it temporarily more often
(setq transient-mark-mode nil)
(defun spw/remap-mark-command (command &optional map)
"Remap a mark-* command to temporarily activate Transient Mark mode."
(let* ((cmd (symbol-name command))
(fun (intern (concat "spw/" cmd)))
(doc (concat "Call "
cmd
"&apos and temporarily activate Transient Mark mode.")))
(fset fun (lambda ()
,doc
(interactive)
(call-interactively #&apos,command)
(activate-mark)))
(if map
(define-key map (vector &aposremap command) fun)
(global-set-key (vector &aposremap command) fun))))
(dolist (command &apos(mark-word
mark-sexp
mark-paragraph
mark-defun
mark-page
mark-whole-buffer))
(spw/remap-mark-command command))
(with-eval-after-load &aposorg
(spw/remap-mark-command &aposorg-mark-element org-mode-map)
(spw/remap-mark-command &aposorg-mark-subtree org-mode-map))
;; optional
(global-set-key "\M-=" (lambda () (interactive) (activate-mark)))
;; resettle the previous occupant
(global-set-key "\C-cw" &aposcount-words-region)
C-M-SPC C-M-SPC M-(
to wrap the
following two function arguments in parentheses. And you can hit
M-h
a few times to mark some blocks of text or code, then operate on
them with commands like M-%
and C-/
which behave differently when
the region is active.1
Comparing these mitigations
Both of these mitigations handle the second of the two disadvantages
of Transient Mark mode given above. What remains, then, is
- under the effects of mitigation #1, how much of a barrier to using
marks for navigational purposes is it to have to press
C-SPC C-SPC
instead of having a single binding,C-SPC
, for all manual mark setting2 - under the effects of mitigation #2, how much of a barrier to taking
advantage of commands which act differently when the region is
active is it to have to temporarily enable Transient Mark mode with
C-SPC C-SPC
,M-=
or one of themark-*
commands?
-
The idea of making the
mark-*
commands activate the mark comes from an emacs-devel post by Stefan Monnier in the archives linked above. -
One remaining possibility I m not considering is mitigation #1
plus binding something else to do the same as
C-SPC C-SPC
. I don t believe there are any easily rebindable keys which are easier to type than typingC-SPC
twice. And this does not deal with the two distinct mark-setting operations problem. -
Another way to look at this is the question of which of setting
a mark for navigational purposes and activating a mark should get
C-SPC
and which should getC-SPC C-SPC
.