emacs: How to use the mark-ring?

1.8k Views Asked by At

When I do a C-u C-SPC, emacs takes me to "where I was before". Subsequent C-u C-SPC presses go back up previous places. That is damn great, and I use it a lot.

But something always bugged me : The only mark missing from the mark-ring is where-I-invoked-this-in-the-1st-place! It's like leaving bread crumbs behind you, and then go "whoops, I may be lost, imma go back and check", then going back without leaving a bread crumb where you are right now!

I tried advising the function, but I can't for the life of me programmatically simulate a C-SPC C-SPC.

  • how can I "see" (echo, message, trace, etc) what a key combination does, like "C-h k" but for repeated key sequences, like C-SPC C-SPC ? Here is what the manual says of the latter (emphasis mine)

C-SPC runs the command set-mark-command, which is an interactive compiled Lisp function in `simple.el'.

It is bound to C-@, C-SPC.

(set-mark-command ARG)

Set the mark where point is, or jump to the mark. Setting the mark also alters the region, which is the text between point and mark; this is the closest equivalent in Emacs to what some editors call the "selection".

With no prefix argument, set the mark at point, and push the old mark position on local mark ring. Also push the old mark on global mark ring, if the previous mark was set in another buffer.

But when I try to use it (non-interactively) "With no prefix argument" in order to "set the mark at point" I get a debugger error "wrong-number-of-arguments"..? (I realize the difference between an argument and a prefix argument).

I would be okay even with a philosophical, non-practical answer. I just want to understand what the idea is here.

4

There are 4 best solutions below

3
yPhil On BEST ANSWER

OK, here is what I did

(defun px-push-mark-once-and-back ()
    "Mark current point (`push-mark') and `set-mark-command' (C-u C-SPC) away."
    (interactive)
    (let ((current-prefix-arg '(4))) ; C-u
        (if (not (eq last-command 'px-push-mark-once-and-back))
                (progn
                    (push-mark)
                    (call-interactively 'set-mark-command))
            (call-interactively 'set-mark-command))))

(global-set-key (kbd "<s-left>") 'px-push-mark-once-and-back)
3
Nicolas Dudebout On

(push-mark) seems to be doing what you want.

0
jdd On

You probably shouldn't be using set-mark or set-mark-command non-interactively. Within elisp, just save point (or whatever location) in a variable with a good name.

Also, C-h i m emacs m mark.

I'm no emacs guru wrt mark movement, I barely use it. I know I've seen the behavior you want before though.

1
event_jr On

Ok, I bundled up two relevant answers from this question into a small package here.

It allows you to use C-- C-SPC to move forward in mark-ring.