4

Setting the mark and moving point activates the region, which appears highlighted (assuming transient-mark-mode is enabled). Once the mark is set it's location is sent to the mark ring, thus changing it.

Is it possible to activate the region without altering the mark ring? I.e. making a selection as in other programs, such as your browser, to leave the region active and call other commands on it (kill, etc.).

The idea is to create a function to be implemented in new commands (something such as my-set-mark), not to change the default Emacs behavior for existing commands/functions.

2 Answers 2

5

It's possible, and in fact it's dead simple, as long as you're okay with where mark already is. There's no pre-existing command for it, but you could use this:

(defun my/activate-region-only ()
  "Activate the region without changing the mark ring."
  (interactive)
  (setq mark-active t))

If you want to set the mark without adding it to the mark ring, you start running into problems. The naive implementation would be something like this:

(defun my/set-mark-no-push ()
  "Set mark at point; activate region.  Do not change mark ring."
  (interactive)
  (set-mark (point)))

But this probably won't behave as you expect. It won't change the mark ring, but the current mark isn't on the mark ring. It only gets sent to the mark ring when a new mark gets set. Most commands that interact with the mark ring (e.g., C-u C-SPC) behave as if the current mark were on top of the mark ring, but this is sort of an illusion.

The upshot of all this is that my/set-mark-no-push, above, will prevent the previous mark from getting put onto the mark ring, but the new mark will still get into the mark ring when some subsequent command sets the mark again. If you want to set the mark without letting the new value go to the mark ring, there doesn't seem to be a clean or easy way to do it, and you're probably better off learning to live with Emacs's eccentricity in this respect.


EDIT: Okay, this turned out to be easier than I thought. Here's what I've got:

(defun my/dont-push-mark (&optional location nomsg activate)
  "As `push-mark', but don't push old mark to mark ring."
  (setq location (or location (point)))
  (if (or activate (not transient-mark-mode))
      (set-mark location)
    (set-marker (mark-marker) location))
  (or nomsg executing-kbd-macro (> (minibuffer-depth) 0)
      (message "Mark set"))
  nil)

(advice-add #'push-mark :override #'my/dont-push-mark)

Most of the code here dealing with NOMSG and ACTIVATE I lifted directly from push-mark. Three caveats:

  1. This will only modify the behavior of functions that use push-mark. That should be most of them, but there may be functions that, for whatever reason, use some other method to add a mark to the mark ring.

  2. Naturally, functions that are expecting to change the mark ring may behave unpredictably with this in effect.

  3. Most importantly, this change will be global. If you want to use the mark ring at all, you may want to write an interface that will add and remove the advice temporarily.

12
  • Yes, I follow you. Setting the mark or pushing it to the mark ring (with push-mark) is straightforward. The point of the question is to leave the mark ring untouched. set-mark also alters the mark-ring. There must be some esoteric way of doing this (or many)!
    – undostres
    Commented Jan 18, 2016 at 18:29
  • I think my point is that leaving the mark ring untouched isn't enough, since set-mark doesn't change the mark ring. You'd need to somehow alter the behavior of every function that changes the mark to prevent it from adding the old mark to the mark ring. Though most of those probably go through push-mark, so the problem may be tractable. Commented Jan 18, 2016 at 18:56
  • @undostres After Aron's comment the closest approximation would be: (defadvice push-mark (around dont-touch-mark-ring activate) "Don't do that!" (set-mark (or location (point))) (unless nomsg (message "Mark set")) (when activate (activate-mark)))
    – Tobias
    Commented Jan 18, 2016 at 19:29
  • I'm sorry, forgot to add that this is intended for new commands, not to change the behavior of existing Emacs commands/functions.
    – undostres
    Commented Jan 18, 2016 at 19:37
  • @AaronHarris On another note, set-mark does change the mark ring since it deletes the previous mark position.
    – undostres
    Commented Jan 18, 2016 at 19:43
-1

No. Mark and point form a region.

You can have temporary highlight just like other program. The region disappears upon actions. But still mark must exist.

The temporary highlight is controlled by two variables, transient-mark-mode and deactivate-mark. If transient-mark-mode and deactivate-mark are at the state (only . t) and nil respectively, the region between the point and mark is temporarily highlighted.

1
  • Yes, you're right. But I'm asking for a way to not alter the mark ring. It seems all mark-related functions change the mark ring one way or another.
    – undostres
    Commented Jan 18, 2016 at 18:30

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.