10

GNU Emacs' Transient Mark mode

 3 years ago
source link: https://spwhitton.name/blog/entry/transient-mark-mode/
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

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 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:

  1. 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

  2. using exchange-point-and-mark activates the region, so to use it for navigation you need to use either C-u C-x C-x or C-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.

There are two other disadvantages that people bring up which I am disregarding. The first is that it makes it harder for new users to learn useful ways in which to use the mark when it’s deactivated. This happened to me, but it can be mitigated without making any behavioural changes to Emacs. The second is that the visual highlighting of the region can be distracting. So far as I can tell, this is only a problem with 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] 'spw/exchange-point-and-mark)

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 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/activate-mark (&rest ignore)
  "Temporarily activate Transient Mark mode.

Wrapper suitable for use as advice and to be bound to a key."
  (interactive)
  (activate-mark))
(dolist (command '(mark-word
                   mark-sexp
                   mark-paragraph
                   mark-defun
                   mark-page
                   mark-whole-buffer))
  (advice-add `,command :after #'spw/activate-mark))

;; optional
(global-set-key "\M-=" 'spw/activate-mark)
;; resettle the previous occupant
(global-set-key "\C-cw" 'count-words-region)

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 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.

Comparing these mitigations

Both of these mitigations handle the second of the two disadvantages of Transient Mark mode given above. What remains, then, is

  1. 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 setting

  2. 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 the mark-* commands?

These are unknowns.So I’m going to have to experiment, I think, to determine which mitigation to use, if either. In particular, I don’t know whether it’s really significant that setting a mark for navigational purposes and for region marking purposes are distinct operations under mitigation #1.

My plan is to start with mitigation #2 because that has the additional advantage of allowing me to confirm or disconfirm my belief that not being able to see where the region is will only rarely get in my way.


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK