Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to move forward and backward in Emacs' mark ring

Tags:

emacs

In Emacs, C-u C-SPC will "jump to the mark, and set the mark from position popped off the local mark ring". Is there a way to go the opposite way around the mark ring? Say you have typed C-u C-SPC several times and want to go back to a mark you have seen without going all the way around the ring.

like image 703
hiheelhottie Avatar asked Aug 03 '10 05:08

hiheelhottie


People also ask

How do I go back in Emacs?

To get back into Emacs, type %emacs at the shell prompt. To quit Emacs permanently, type C-x C-c.

How do you set a mark in Emacs?

Or, you can set the mark at the end of the text, move to the beginning, and then type C-x C-u . The most common way to set the mark is with the C- SPC command ( set-mark-command ). This sets the mark where point is. Then you can move point away, leaving the mark behind.


2 Answers

Unlike previous answers, this one does only exactly what was asked: the reverse of C-u C-SPC. I find it the most useful.

(defun unpop-to-mark-command ()   "Unpop off mark ring. Does nothing if mark ring is empty."   (interactive)       (when mark-ring         (setq mark-ring (cons (copy-marker (mark-marker)) mark-ring))         (set-marker (mark-marker) (car (last mark-ring)) (current-buffer))         (when (null (mark t)) (ding))         (setq mark-ring (nbutlast mark-ring))         (goto-char (marker-position (car (last mark-ring)))))) 

Comparing to the answer by scottfrazer, this command has a subtle difference of how it moves the cursor and mark, which more accurately mirrors C-u C-spc, and it does not require that the previous command was a unpop/pop-to-mark-command.

like image 192
Ian Kelling Avatar answered Oct 04 '22 09:10

Ian Kelling


Here's a solution I just finished spending way too much time on. The difference between this and the other solutions is it works across buffers, ie it works on the 'global-mark-ring'. My goal was to emulate history browsing similar to Eclipse or IntelliJ. I bind it to M-left and M-right, obviously you can choose different keys for this.

(defun marker-is-point-p (marker)   "test if marker is current point"   (and (eq (marker-buffer marker) (current-buffer))        (= (marker-position marker) (point))))  (defun push-mark-maybe ()    "push mark onto `global-mark-ring' if mark head or tail is not current location"   (if (not global-mark-ring) (error "global-mark-ring empty")     (unless (or (marker-is-point-p (car global-mark-ring))                 (marker-is-point-p (car (reverse global-mark-ring))))       (push-mark))))   (defun backward-global-mark ()    "use `pop-global-mark', pushing current point if not on ring."   (interactive)   (push-mark-maybe)   (when (marker-is-point-p (car global-mark-ring))     (call-interactively 'pop-global-mark))   (call-interactively 'pop-global-mark))  (defun forward-global-mark ()   "hack `pop-global-mark' to go in reverse, pushing current point if not on ring."   (interactive)   (push-mark-maybe)   (setq global-mark-ring (nreverse global-mark-ring))   (when (marker-is-point-p (car global-mark-ring))     (call-interactively 'pop-global-mark))   (call-interactively 'pop-global-mark)   (setq global-mark-ring (nreverse global-mark-ring)))  (global-set-key [M-left] (quote backward-global-mark)) (global-set-key [M-right] (quote forward-global-mark)) 
like image 20
spopejoy Avatar answered Oct 04 '22 10:10

spopejoy