23

This question was originally asked at https://stackoverflow.com/questions/15895313/let-emacs-move-the-cursor-off-screen, but all the answers I got more or less said "it can't be done", which with emacs I just don't accept.

Is it possible to let Emacs have the cursor be moved off-screen, like most GUI text editors work? This is one of the biggest things that bothers me when I use Emacs over any GUI editor. When I scroll down, the cursor is "pushed forward" by the top of the buffer.

I had previously thought that this was completely impossible, because this is hard-wired into the architecture of Emacs, but then I saw multiple-cursors, which does exactly this for the secondary cursors (assuming you prevent the scrolling functions from acting on the secondary cursors). Is it maybe possible to use multiple-cursors to have the main cursor in some hidden buffer, and the effective cursor being what I actually edit with? Or maybe some other clever trick? Or maybe my Googling has failed me and this is really already possible without any magic?

I use the terminal emacs, so it should work there.

  • Keep in mind all the multiple-cursors package does is adding fake cursors which aren't subject to the restrictions of the real one. I hope there will be an answer based on the suggestions of your previous question. – wasamasa Sep 23 '14 at 23:37
  • I assume that this problem is specific to using scroll bars, is that right? – nispio Sep 24 '14 at 0:21
  • 1
    So what scroll commands are you using that you would expect not to bring the cursor with you? In my experience the cursor follows you in all editors when using PgUp/PgDn or the arrow keys. – nispio Sep 24 '14 at 4:56
  • 4
    @nispio maybe scrolling with the mouse wheel? – ffevotte Sep 24 '14 at 8:57
  • 2
    Page up and Page down (C-v and M-v) do not move the cursor in emacs unless the cursor moves off the screen. Scrolling is different from moving (the cursor). – asmeurer Sep 24 '14 at 16:06
11

There is a new package available on GNU ELPA called scroll-restore that attempts to remedy this problem. There are a handful of different behaviors to choose from, but the way I have configured it for myself (see below) causes the cursor to turn invisible during scrolling commands, and then jump back to its original location when I start typing again.

So far, I have encountered a few bugs, but the package seems to work as-advertised for the most part. You can test it out by installing it with

M-x package-install RET scroll-restore RET

After the package is installed, you can enable the minor mode with

M-x scroll-restore-mode

Personally, I am binding it to the Scroll Lock key because it seems so incredibly apropos! This is what I am adding to my init file:

(require 'scroll-restore)
(scroll-restore-mode 1)
;; Allow scroll-restore to modify the cursor face
(setq scroll-restore-handle-cursor t)
;; Make the cursor invisible while POINT is off-screen
(setq scroll-restore-cursor-type nil)
;; Jump back to the original cursor position after scrolling
(setq scroll-restore-jump-back t)
;; Toggle scroll-restore-mode with the Scroll Lock key
(global-set-key (kbd "<Scroll_Lock>") 'scroll-restore-mode)
  • 1
    If you have bound a key to it, I suppose that you want to disable it sometimes. Is this mode annoying for normal editting? – T. Verron Oct 17 '14 at 14:03
  • 1
    @T.Verron It seems pretty buggy right now, and one of its failure modes is to "trap" your cursor in an area and not let it leave. The only way I have found to free my cursor again is to disable the mode. Once all of the bugs are worked out, I wouldn't mind using it all the time. – nispio Oct 17 '14 at 15:46
  • 2
    How is this supposed to work? I can't seem to get it to do anything. – asmeurer Oct 18 '14 at 8:16
5

The method that I always use is to set the mark where I want to jump back to, and then when I am done perusing the buffer, I pop the mark using C-u C-SPC. Even when I forget to set the mark before wandering off, I find that popping the mark usually lands me pretty close to where I came from. This is due partly to the fact that some commands (like isearch for example) set the mark without you even realizing. So through the course of your editing, you have been inadvertently leaving a little trail of breadcrumbs.

From the documentation:

set-mark-command is an interactive compiled Lisp function in `simple.el'.

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

(set-mark-command ARG)

....

With prefix argument (e.g., C-u C-SPC), jump to the mark, and set the mark
from position popped off the local mark ring (this does not affect the global
mark ring).  Use C-x C-@ to jump to a mark popped off the global mark ring
(see `pop-global-mark').

I almost never bother with setting bookmarks or registers, but I can almost always find my way back where I came from quickly using either C-u C-SPC or pop-global-mark.

  • Frankly, I think the main reason people want the cursor to be able to move off-screen is because they're used to editors that don't have a proper history of cursor positions. You could also make it so that scroll-up and scroll-down automatically set the mark, so that C-u C-SPC would be sure to get you back where you came from. – Radon Rosborough Dec 31 '16 at 18:06
0

The following code is good enough for me to jump back after mouse wheel scroll:

(advice-add 'mwheel-scroll :before (lambda (arg) (if (not (eq last-command 'mwheel-scroll)) (setq point-before-mwheel-scroll (window-point)))))
(defun jump-back () (goto-char point-before-mwheel-scroll))

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.