After issuing scroll-up or scroll-down in emacs, is there a quick way to return the point to its previous position (assuming I didn't remember to add it to the mark ring)?

Alternatively is there any way (without interfering with the mark ring) to alter the scrolling behaviour so that scrolling up then scrolling down (or vice versa) returns the point to its original position? (eg. make scrolling move the point exactly x lines where x is the screen height)

I'm in the process of accustoming myself to emacs and this is one of the most common curse-provoking situations: I scroll around to view another part of my code without remembering to add my line to the mark ring and then it's painful to try to relocate the line of code I was working on. As such, while I'm asking for a technical solution, I'd also be interested to hear how seasoned users avoid this problem. Do you just get used to remembering to set a mark, split the window to look around or use some other pattern?


5 Answers 5

(setq scroll-preserve-screen-position t)

With this setting, if you page up and down, the cursor returns to its original line. It also retains its original column in Emacs version 23 or newer.

You may or may not prefer

(setq scroll-preserve-screen-position 'always)

which always preserves the cursor's screen position when scrolling, rather than preserving the cursor position in the buffer if the original position is still visible.

  • 2
    Thanks from me too! For, (umm many!) years, I've typed "<>" before going scrolling around, just have a search target to return to.
    – JRobert
    Sep 4, 2010 at 18:23
  • For me this causes scroll-up-line (which is what I use with my scroll wheel) to cause the cursor to move forward one character when it hits the top or bottom of the screen.
    – asmeurer
    May 15, 2015 at 20:56
  • @asmeurer I don't observe this. There must be something weird in your init file or a bug in your version of Emacs. May 15, 2015 at 21:10
  • Yeah, I figured that out after I posted this. I opened a new question at emacs.stackexchange.com/questions/12439/….
    – asmeurer
    May 15, 2015 at 21:13
  • I think this should be (setq scroll-preserve-screen-position 'always). Otherwise, C-v M-v does not put point back where you started.(The second point position is visible on the first screenful so point doesn't move back.) May 16, 2015 at 10:09

What I've found to work well is using goto-last-change.el, which pops you back to the location where you last made an edit. I like the binding:

(require 'goto-last-change) ;; download this package and install in load-path
(global-set-key (kbd "C-x C-\\") 'goto-last-change)
  • 2
    Equivalently, without the need for an additional package: C-_ C-f C-_ (undo, move, undo). Sep 4, 2010 at 18:46
  • 1
    @Gilles True, but then your undo stack just grew by two more elements. :) Sep 7, 2010 at 18:32

In answer to your question about how I avoid the problem you describe (looking elsewhere in the code and then returning to the point where I was working)...

Typically, I will split the screen when I need to briefly look elsewhere. Then I can return to the original screen with C-x o, unsplit with C-x 1 and I'm back to normal.

I also use forward and reverse i-search to locate a particular point of interest in the code. I find that's a fairly efficient way to navigate code when I know what I'm looking for.


If I'm only scrolling a few lines from where I'm currently at, I can use this to scroll the window without moving point:

(defun scroll-in-place (scroll-up)
  "Scroll window up (or down) without moving point (if possible).

SCROLL-Up is non-nil to scroll up one line, nil to scroll down."
  (let ((pos (point))
        (col (current-column))
        (up-or-down (if scroll-up 1 -1)))
    (scroll-up up-or-down)
    (if (pos-visible-in-window-p pos)
        (goto-char pos)
      (if (or (eq last-command 'next-line)
              (eq last-command 'previous-line))
          (move-to-column temporary-goal-column)
        (move-to-column col)
        (setq temporary-goal-column col))
      (setq this-command 'next-line))))

;;;; ------------------------------------------------------------------------
(defun scroll-up-in-place ()
  "Scroll window up without moving point (if possible)."
  (scroll-in-place t))

;;;; ------------------------------------------------------------------------
(defun scroll-down-in-place ()
  "Scroll window up without moving point (if possible)."
  (scroll-in-place nil))

(global-set-key (read-kbd-macro "M-<down>") 'scroll-up-in-place)
(global-set-key (read-kbd-macro "M-<up>") 'scroll-down-in-place)

If I'm moving off to a completely different section of a file (or to a different file altogether), I sometimes use breadcrumb though there are lots of other packages that do similar things.

If I need to visually see two areas of code at the same time, I will split the frame horizontally into two windows and then discard the second window when I'm done.

Mostly, though, I just use two frames, one being my current working frame and the other is my reference frame, used for jumping around the same or other files.

  • If all you want to do is see above or below the current point without moving there, you can cycle C-l.
    – asmeurer
    Aug 25, 2014 at 16:49

Package Restore Point does exactly what you described, out of the box.

It checks whether a set of (configurable) commands were executed (by default, mark commands, scroll and page-up/down) and then allows you to go back to the previous point (cursor) position by hitting keyboard-quit, usually bound to C-g or ESC.

Disclaimer: I am the author of this package.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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