Innehållsförteckning RecentChanges News ElispArea HowTo Problems Suggestions

TransientMarkMode

Transient Mark mode gives you much of the standard selection-highlighting behavior of other editors. In GNU Emacs 23 and onwards, it is enabled by default. Otherwise, to enable it, put the following in your init file: (transient-mark-mode 1)

In Transient Mark mode, the region is active only temporarily, and it is highlighted while it is active. You activate the region for each command that uses it: place the mark, then move the cursor (and point).

Some features in Emacs support extra behaviors or require it to be on.

Highlighting the region would not be appropriate without Transient Mark mode. Because the region always exists (as soon as the mark exists), without a notion of active region, some text would always be highlighted (except when mark = point), which would prove to be a nuisance.

In Emacs 22 and later, ‘C-SPC C-SPC’ activates Transient Mark mode only temporarily. This means that even if you do not use Transient Mark mode, you can get the effect of it for the space of one command by doing ‘C-SPC C-SPC’.

See also:

Activating Transient Mark Mode Temporarily Prior to Emacs 22

This code snippet is from Emacs CVS.

(defun push-mark-command (arg &optional nomsg)
  "Set mark at where point is.
If no prefix arg and mark is already set there, just activate it.
Display `Mark set' unless the optional second arg NOMSG is non-nil."
  (interactive "P")
  (let ((mark (marker-position (mark-marker))))
    (if (or arg (null mark) (/= mark (point)))
	(push-mark nil nomsg t)
      (setq mark-active t)
      (run-hooks 'activate-mark-hook)
      (unless nomsg
	(message "Mark activated")))))
(defun set-mark-command (arg)
  "Set mark at where point is, or jump to mark.
With no prefix argument, set mark, and push old mark position on local
mark ring; also push mark on global mark ring if last mark was set in
another buffer.  Immediately repeating the command activates
`transient-mark-mode' temporarily.

With argument, e.g. \\[universal-argument] \\[set-mark-command], \
jump to mark, and pop a new position
for mark off the local mark ring \(this does not affect the global
mark ring\).  Use \\[pop-global-mark] to jump to a mark off the global
mark ring \(see `pop-global-mark'\).

If `set-mark-command-repeat-pop' is non-nil, repeating
the \\[set-mark-command] command with no prefix pops the next position
off the local (or global) mark ring and jumps there.

With a double \\[universal-argument] prefix argument, e.g. \\[universal-argument] \
\\[universal-argument] \\[set-mark-command], unconditionally
set mark where point is.

Novice Emacs Lisp programmers often try to use the mark for the wrong
purposes.  See the documentation of `set-mark' for more information."
  (interactive "P")
  (if (eq transient-mark-mode 'lambda)
      (setq transient-mark-mode nil))
  (cond
   ((and (consp arg) (> (prefix-numeric-value arg) 4))
    (push-mark-command nil))
   ((not (eq this-command 'set-mark-command))
    (if arg
	(pop-to-mark-command)
      (push-mark-command t)))
   ((and set-mark-command-repeat-pop
	 (eq last-command 'pop-to-mark-command))
    (setq this-command 'pop-to-mark-command)
    (pop-to-mark-command))
   ((and set-mark-command-repeat-pop
	 (eq last-command 'pop-global-mark)
	 (not arg))
    (setq this-command 'pop-global-mark)
    (pop-global-mark))
   (arg
    (setq this-command 'pop-to-mark-command)
    (pop-to-mark-command))
   ((and (eq last-command 'set-mark-command)
	 mark-active (null transient-mark-mode))
    (setq transient-mark-mode 'lambda)
    (message "Transient-mark-mode temporarily enabled"))
   (t
    (push-mark-command nil))))
(setq set-mark-command-repeat-pop nil)

Commands that Do Not Work Well with Transient Mark Mode

indent-rigidly

  1. Set mark (C-SPC)
  2. Move the cursor a couple of [[lines?]] down
  3. C-x TAB

This works only one time, consecutive presses of ‘C-x TAB’ beep at you (“The mark is not active now”). This works fine when using ‘pc-selection-mode’ and also the standard behaviour when the region is not marked at all. This is quite annoying, I am thinking of disabling Transient Mark mode and settle with the hardcore default behaviour. I don’t know if it messes up with other commands. – MathiasDahl

(setq mark-even-if-inactive t) would probably help with this.

or try these (GNUemacs):

 (global-set-key (kbd "C-x TAB")
                 #'(lambda (arg)
                     (interactive "p")
                     (save-excursion
                       (let ((deactivate-mark nil))
                         (indent-rigidly (min (point) (mark))
                                         (max (point) (mark))
                                         arg)))))
 (global-set-key (kbd "C-x <S-iso-lefttab>")
                 #'(lambda (arg)
                     (interactive "p")
                     (save-excursion
                       (let ((deactivate-mark nil))
                         (indent-rigidly (min (point) (mark))
                                         (max (point) (mark))
                                         (- arg))))))

ClausBrunzema

Actually, I have learned to live without a highlighted region by now. I very seldom feel a need for it. But, it would be nice for those rare times, if there was a way to hilight the region temporarily, for example when doing a “dangerous” rectangle-command. Hmm, well, yes, there’s always the undo command of course… – MaDa
See above, regarding ‘C-SPC C-SPC’ (set-mark-command): it gives you the temporarily highlighted region you’re asking for (temporary transient mark mode). [new] ‘C-SPC C-SPC’ almost does what I want. I don’t want to have transient mark always (given), and I do want to use it sometimes for commands that change their behavior (comment-dwim in particular). But I don’t want to move the mark. I want to make the current region transient for the space of one command without changing anything else. Example use case: I want to paste some piece of spec or reference into a comment with ‘C-y SOMETHING M-;’. Currently, SOMETHING is ‘C-x C-x C-SPC C-SPC C-M-n’ with possibly other fiddling with point in addition to / instead of ‘C-M-n’.
I finally resorted to grepping simple.el until I found that exchange-point-and-mark with a prefix arg is one way. So now I’m down to ‘C-y C-u C-x C-x M-;’. That’ll do. I think what I really want is for yank and clipboard-yank to temporarily set transient-mark-mode, but I’m still thinking about it.

The mark disappears after an editing action, but you can get it back with ‘C-x C-x’ (exchange-point-and-mark). This puts the point at the opposite end of the region, so you have to type it again to get back where you were before: ‘C-x C-x C-x C-x’. Or, you can use this function, and save a few keystrokes:

 (defun toggle-mark ()
   (interactive)
   (if mark-active
       (deactivate-mark)
     (exchange-point-and-mark)
     (exchange-point-and-mark)))

DaveBenjamin

Trouble Activating the Region at the End of a Command

I wrote a small function called ‘duplicate-region’ (see DuplicateStartOfLineOrRegion), and I’d like the mark to be active after calling it.

Transient mark mode is on, I use ‘push-mark’ and ‘exchange-point-and-mark’, (I tried a few other options too) but I can’t make it work. Any idea ?

Cheers! – SebastienRoccaSerra

  (setq deactivate-mark nil)

DrewAdams

Thanks, done! – SebastienRoccaSerra

How do you make C-x C-x turn on highlighting, without changing anything else?


CategoryRegion