49

Can I make my cursor in a buffer jump back to its last position? (preferrably without having to mark the previous position)

For example, C-a jumps to the beginning of the current line, can I jump back to where it was before?

For example, when C-x C-f to open a file in a different directory, i want to jump back to the previous position in the path name.

Thanks.

Tim
  • 4,987
  • 7
  • 31
  • 60
  • Will `C-x x` which runs `exchange-point-and-mark` do? Emacs doesn't store all cursor movements, only those you specifically told it to. Adding and popping marks is one way of storing cursor movement history. http://www.emacswiki.org/emacs/MarkCommands - here's a good discussion of the subject. – wvxvw Mar 09 '15 at 16:07
  • 1
    `C-x x` is undefine. `M-x exchange-point-and-mark`: no mark set in this buffer. – Tim Mar 09 '15 at 16:09
  • @Tim It is `C-x C-x`. Also you need to set a mark first for that to work. To set a mark explicitly, you do `C-SPC`. To jump back to the previous mark, you do `C-u C-SPC`. – Kaushal Modi Mar 09 '15 at 16:19
  • Yeah, right, sorry, it was `C-x C-x`. `C-x x` is my own binding. – wvxvw Mar 09 '15 at 16:37
  • (1) what does c-u mean compared to c-x? @kaushalmodi. (2) After C-space, movement of cursor will select the region between now and then, but my intention is only to jump back not selecting region. So is it the right thing to do? – Tim Mar 09 '15 at 16:40
  • @Tim `C-u` is called a *prefix argument*: https://www.gnu.org/software/emacs/manual/html_node/elisp/Prefix-Command-Arguments.html – Kaushal Modi Mar 09 '15 at 17:05
  • 1
    Not sure if this is a duplicate, but http://emacs.stackexchange.com/q/3421/454 might be useful. – phils Mar 09 '15 at 21:50

6 Answers6

50

Here are few mark-related bindings that can help you:

  • C-SPC - set mark and activate region (bound to set-mark-command)
  • C-SPC C-SPC - set mark (activates and then deactivates region)
  • C-x C-x - bound to exchange-point-and-mark
  • C-u C-SPC - move to previous mark

Check out the Mark documentation for better understanding of this topic.

François Févotte
  • 5,917
  • 1
  • 24
  • 37
Kaushal Modi
  • 25,203
  • 3
  • 74
  • 179
  • 19
    Note that commands which are liable to move the cursor some arbitrary (but potentially large) distance from where you were will (typically) automatically push the mark first. So you can frequently get back to where you were before with a single `C-u C-SPC`. – phils Mar 09 '15 at 21:47
  • 4
    With `counsel-mark-ring` it's also possible to list all the marks and navigate them with cursors, getting a real-time preview in the buffer. – Arialdo Martini Jul 02 '19 at 05:57
  • `counsel-mark-ring` is amazing, thanks @ArialdoMartini! – Renato Sep 12 '21 at 19:46
10

If you're doing editing at the locations you land on, goto-last-change will do this for you. http://www.emacswiki.org/emacs/GotoLastChange

incandescentman
  • 4,111
  • 16
  • 53
  • 6
    In Spacemacs it's bound to `g ;` – iLemming Jun 12 '18 at 23:22
  • 1
    Nowadays you should use [goto-chg](https://github.com/emacs-evil/goto-chg) – clemera Dec 25 '19 at 12:38
  • Why to use `goto-chg`: "Another package that do a similar thing is goto-last-change.el (GotoLastChange) by Kevin Rodgers. (If used repeatedly, to go back to earlier edits, it may misalign the position, not accounting for changes that have shorten or lengthen the text before that point.)" -https://www.emacswiki.org/emacs/GotoChg – young_souvlaki Oct 04 '21 at 16:10
4

For users of Doom Emacs (or evil users in general) vim functionality 'jump lists' is implemented and bound to C-i and C-o for O[ut] and I[n] - or backwards from drill down jumps and inwards

Your could also mark positions in files with m <char> and uppercase chars would work across files. To jump to the mark you'd use ` <char>

Nefedov Efim
  • 141
  • 3
  • Also, use `'` (single quote) to jump to the beginning of a marked like. – Lorem Ipsum May 27 '21 at 13:18
  • `C-i` seems to insert a tab char for me. Same for `C-I`. The `C-o` works. – kubanczyk Dec 11 '21 at 12:15
  • 2
    @kubanczyk for you keybind might be shadowed by something else. You can always try `C-h k C-i` to see which funtion is bound to it. (then you might be able to modify config of that package to remove that binding) You can also `C-h k C-o` to see what's correct name for "backwards jumping function" and using `C-h f guess-name` look for "forward jumping function" to see whether it's bound to anything and maybe bind it on your own to `C-i` in normal mode – Nefedov Efim Dec 12 '21 at 15:30
  • @NefedovEfim Thank you for being so helpful! It does not seem that simple though. I feel the rabbit hole goes somewhere along the `evil-want-C-i-jump` but I'm not willing to spend an ~hour to solve it completely. – kubanczyk Dec 12 '21 at 16:38
  • @kubanczyk I hear you but in this case I went ahead and it just took less than a minute. `C-h v evil-want-C-i-jump`, customize, toggle to true, apply and save. Done! – Fred Schoen Mar 30 '23 at 16:12
2

You can use `Registers'.

From emacs info file

13.1 Saving Positions in Registers

C-x r <SPC> R' Record the position of point and the current buffer in register R (point-to-register').

C-x r j R' Jump to the position and buffer saved in register R (jump-to-register').

Typing C-x r <SPC>' (point-to-register'), followed by a character `R', saves both the position of point and the current buffer in register R. The register retains this information until you store something else in it.

The command `C-x r j R' switches to the buffer recorded in register R, and moves point to the recorded position. The contents of the register are not changed, so you can jump to the saved position any number of times.

If you use C-x r j' to go to a saved position, but the buffer it was saved from has been killed,C-x r j' tries to create the buffer again by visiting the same file. Of course, this works only for buffers that were visiting files.

joe
  • 27
  • 2
1

For me it was much easier than current answers describe it. Most of Emacs Lisp functions (like goto-line, lsp-find-implementation or isearch, counsel-search), that significantly modify the cursor position, set the mark before execution. So all you really need is pop-to-mark-command, which will iterate and jump through the list of marks in the current buffer.

And of course it will not "remember" the previous cursor position when you hit arrow button and move one line down, which is kinda useless, as it is faster to hit up arrow button for that:)

tinlyx
  • 1,276
  • 1
  • 12
  • 27
0

For users who jump around by using the universal argument, eg jumping up 10 lines: C-10 C-p, you lose your place. So you can use these to save your place on large-ish movements:

(defun my-next-line (arg)
  "Wrap `next-line' to save point mark."
  (interactive "P")
  (when (and arg (< 4 arg)) (push-mark (point)))
  (next-line arg))

(defun my-previous-line (arg)
  "Wrap `previous-line' to save point mark."
  (interactive "P")
  (when (and arg (< 4 arg)) (push-mark (point)))
  (previous-line arg))

(global-set-key (kbd "C-n") 'my-next-line)
(global-set-key (kbd "C-p") 'my-previous-line)

Then C-u C-SPC (pop) or C-x C-x (exchange-point-and-mark-no-activate, no-pop) to get back.

Micah Elliott
  • 221
  • 3
  • 6