SmoothScrolling

mouse wheel & keyboard scroll one line at a time

    ;; scroll one line at a time (less "jumpy" than defaults)
    
    (setq mouse-wheel-scroll-amount '(1 ((shift) . 1))) ;; one line at a time
    
    (setq mouse-wheel-progressive-speed nil) ;; don't accelerate scrolling
    
    (setq mouse-wheel-follow-mouse 't) ;; scroll window under mouse
    
    (setq scroll-step 1) ;; keyboard scroll one line at a time

smooth-scroll.el

"smooth-scroll.el" provides a minor mode “smooth-scroll-mode” which brings “smooth scrolling” and “in-place scrolling” feature to Emacs.

smooth-scrolling.el

http://emacs.wordpress.com/2007/09/10/smooth-scrolling/

Sniplets

If you want the text to scroll one line at a time when you move the cursor past the top or bottom of the window, use the following setting:

   (setq scroll-conservatively 10000)

Unfortunately, the text still jumps sometimes, in a really irritating way. I haven’t been able to work out why or how to stop it.

→ here’s a fix: http://zhangda.wordpress.com/2009/05/21/customize-emacs-automatic-scrolling-and-stop-the-cursor-from-jumping-around-as-i-move-it/

    (setq scroll-margin 1
      scroll-conservatively 0
      scroll-up-aggressively 0.01
      scroll-down-aggressively 0.01)
    (setq-default scroll-up-aggressively 0.01
      scroll-down-aggressively 0.01)

The scrolling will still be jumpy if Emacs is unable to redisplay text fast enough to keep the scrolling rate up (this typically happens on slow terminals). The view will then be recentered around the cursor. Recentering also occurs if you move more than one (or the number specified by scroll-step) lines away from the visible portion of the buffer. – MicheleBini

I was driven crazy by the jumps. I had set scroll-step and scroll-conservatively as suggested here but it was still jumping half-screens at random times when scrolling. FINALLY, after many years of cursing, the suggestion of setting auto-window-vscroll to nil, below on this page, worked - even though Emacs documentation only says it applies to tall lines with large images, which I don’t use. In fact it seems to apply to any scrolling with too-slow terminal and too-fast keyboard repeat rate. So, here’s my tested recipe for civilized scrolling, which works regardless of your screen speed and keyboard speed:

    (setq scroll-step 1)
    (setq scroll-conservatively 10000)
    (setq auto-window-vscroll nil)

I’ve discovered that it is possible to get rid of the jumpiness at the cost of slowing scrolling down quite a bit (but I think I prefer it slow-and-smooth):

   (setq scroll-step           1
         scroll-conservatively 10000)

– GeoffRichards?

Using the above combination can cause a display lock-up in some cases. It is best to leave out ‘scroll-step’ altogether. This is also what the online help recommends. – HenrikEnberg

I’ve found a Emacs Lisp sniplet for smooth scrolling: http://www.cs.utexas.edu/users/hllu/EmacsSmoothScrolling.html. – MarkusKnittig

The above link no longer exists; however you can see it here: http://web.archive.org/web/20061025212623/http://www.cs.utexas.edu/users/hllu/EmacsSmoothScrolling.html.

Also see my solution below, which has a number of advantages over this code:

  • doesn’t allow a scroll margin more than 1 line
  • doesn’t require truncate-lines to be set
  • doesn’t require global rebinding of cursor keys (so also works for C-n/C-p etc.))
  • has enough intelligence to know when it’s preferable not to scroll – AdamSpiers

GeoffRichards? tip works fine (GNU Emacs 21.3.50 Mac OS X/Carbon). I’ve missed this a long time. Another thing I’ve missed is to be able to scroll up (or down) with page-up a number of pages or to the top of the file, and then press the opposite key as many times as the first and get back to exactly the same cursor position. I used this a lot before my Emacs days to take quick glances at code a bit away and it’s a good complement to isearch and pop-mark which I use nowadays. How can I do this in Emacs? – IsakJohnsson?

try binding these to <next> and <prior>:
 (defun chb-page-down ()
   (interactive)
   (when (featurep 'xemacs) (setq zmacs-region-stays t))
   (forward-line
    (- (if (fboundp 'window-displayed-height)      ;XEmacs
           (window-displayed-height)
         (window-text-height))                     ;GNUEmacs
       next-screen-context-lines)))
 (defun chb-page-up ()
   (interactive)
   (when (featurep 'xemacs) (setq zmacs-region-stays t))
   (forward-line
    (- (- (if (fboundp 'window-displayed-height)   ;XEmacs
              (window-displayed-height)
            (window-text-height))                  ;GNUEmacs
          next-screen-context-lines))))

ClausBrunzema

Here’s a comprehensive solution to the problem of scrolling back to the same place after scrolling up or down – I highly recommend this package: http://www.cs.utah.edu/~eeide/emacs/scroll-in-place.el.gz (but we’re getting away from the topic of smooth scrolling). – PeterHeslin

How is this scroll-in-place package better than the built-in ‘scroll-preserve-screen-position’? Also, I’m surprised no one mentioned ‘scroll-margin’ yet. Unfortunately it’s far from perfect: http://www.etc-network.de/blog/mel/emacs/tip-scroll-step.printAdamSpiers

Also possible: the cursor simply stays vertically in the middle of the frame (except at the beginning of buffer). You can always see what is before and after the cursor and it scrolls smoothly, too. But it takes getting used to.

 (add-hook 'post-command-hook
   (lambda ()
     (recenter '("don't redraw"))))

AndreRiemann

This post-command-hook suffers from the same problems as scroll-margin - it often scrolls the window when you don’t want it to (e.g. when you move the point by left-clicking the mouse). Here’s a near-perfect solution for me: http://www.adamspiers.org/elisp/smooth-scrolling.el. – AdamSpiers

I made a little minor mode, where the cursor stays centered in the window. Except when point is moved per mouse click. The above mentioned snippet (post-command-hook) is obsolete. The mode could be found here: centered-cursor-mode.el. – AndreRiemann

None of the above seems to do much for jumpy mouse scrolling. I wrote a snippet that rebinds the mouse scroll wheel to a couple of functions that scroll several lines, pausing between each line. Find it here: http://zwell.net/content/emacs.html#scrolling. – DanZwell?

I added local and global highlighting modes that can help focus attention on a “window” of the several lines that surround the cursor – see HL Spotlight and library hl-spotlight.el. By default, these modes also turn on local or global cursor-centering modes, as defined in centered-cursor-mode.el. – DrewAdams

I used the (setq scroll-conservatively 10000) solution, and it works well enough for me. However, moving the point down (and thus scrolling 1 line at a time) still looked very poor - it was jerky and inconsistent. Every 3rd press would not move the point, but scroll the window a couple of pixels (this is in X, BTW). This happened whether I was just holding the down arrow or pressing it repeatedly. I accidentally stumbled upon the auto-window-vscroll variable, I set it to nil and scrolling down looks much better.

I am using Adam Spiers’ smooth-scrolling.el, but with the defadvices changed to before rather than after, and adding 1 to smooth-scroll-margin everywhere in smooth-scroll-up/down. This provides the advantage that if you scroll up from the very top of a window (or down from the very bottom, and you can be in these situations if changing windows), the script will gracefully scroll the window just enough to put point outside the margin again. Also, as stated just above, (setq auto-window-vscroll nil) is needed in some situations. – KGB

None of these solutions worked for me. Cursor jumped even during non-scrolling-moves. I noticed a short hard-drive activity when the cursor got stuck. My value for ‘auto-save-interval’ was set to 50 chars. So now I’m using:

; Autosave every 500 typed characters
(setq auto-save-interval 500)
; Scroll just one line when hitting bottom of window
(setq scroll-conservatively 10000)

Zarza in Emacs 24.0

Zarza’s solution is the only one that worked for me. Thank you! I turned off auto save interval altogether.

For GNU Emacs 24.3.1 I have normal scrolling, and with the “C key” pressed, you have smooth scrolling (1 line up/down), it works well, should be the visible/easy solution?

(global-set-key (kbd "<C-mouse-4>") 'scroll-down-line)
(global-set-key (kbd "<C-mouse-5>") 'scroll-up-line)

Have you got linum enabled? Try enabling linum-delay which will make up the difference. M-x customize-group RET linum RET

;; Delay updates to give Emacs a chance for other changes
(setq linum-delay t)
;; scrolling to always be a line at a time
(setq scroll-conservatively 10000)

Gayan Weerakutti [Emacs 24.3]


CategoryDisplay CategoryMouse