11

Even using default settings (emacs -Q) I've found large C files can be slow to scroll with Emacs.

If for example, I open a large file and hold Page-Down. It will scroll down 1-2 pages, then hang for a second or two, on releasing the document is scrolled many pages down (20 pages or so). *

I know Emacs is capable of less erratic behavior because if I quickly tap page down, it manages to keep up and doesn't hang as before.

Is it possible to have Emacs not attempt to handle multiple events at once, and instead redraw between events?

Or somehow become more responsive instead of hanging while it attempts to process many events?


* The actual slow-down in this case is caused by syntax highlighting, since if I scroll the entire document once, after that all scrolling is fast. I've looked into different options relating to font locking and concluded that the font locking defaults are reasonable and tweaking them doesn't solve the problem, mentioning this since I've already investigated that and don't think it's an important part of this question.

2
  • 1
    That doesn't sound normal. Have you done any testing to figure out what the cause is? It could be related to your emacs configuration (test with emacs -Q to rule that out), or it could be that your disk is very slow. You might also try turning off syntax highlighting or other helpful behavior (put the buffer into fundamental mode).
    – db48x
    Commented Mar 11, 2017 at 23:07
  • 1
    By default settings I meant emacs -Q, edited question. Slow down is definitely syntax highlighting. However its made worse by emacs attempting to handle all events before redrawing.
    – ideasman42
    Commented Mar 11, 2017 at 23:14

3 Answers 3

12

As you noticed, this basically happens when the redisplay is too slow for some reason. There's not much we can do in the general case (when it's "much too slow") but when it's "just a tad bit too slow" you can try one of those (or both, tho it probably doesn't do anything more than only one of the two):

(setq jit-lock-defer-time 0)
(setq fast-but-imprecise-scrolling t)

Note that they're both new in Emacs-25.

2
  • 2
    The doc-string for the variable fast-but-imprecise-scrolling states "When non-nil, accelerate scrolling operations." Perhaps the example should reflect a non-nil value as that would accelerate scrolling.
    – lawlist
    Commented Mar 13, 2017 at 18:38
  • I tried this but when I start scrolling down/up it never stops till it reaches to the end point :( Mac has a very sensetive scroller so I usually do it fast for example to go to bottom of page I do scroll as much as I can, and when I scroll bottom very fast it freeze on the bottom
    – alper
    Commented Aug 3, 2020 at 13:24
2
  1. One thing you can do is to pass a numeric prefix argument to the scroll command, instead of just pressing and holding down its key to invoke it repeatedly.

    For example, if you are using the <next> key (aka PageDown) then the command it invokes is scroll-up-command. And C-h f scroll-up-command tells you that a numeric prefix arg says to scroll that many lines.

    For example: Suppose that your buffer has 50,000 lines and the cursor is at the top of it (on the first line). If you do C-u 25000 <next> then it will scroll half-way down the buffer (25,000 lines).

    There will still be a pause, but it will be somewhat shorter.

  2. Another possibility is to move down by a certain number of large Emacs thingies. If your buffer separates sections of text using ^L (Control-L, form-feed) characters then you can use the page-navigation commands, such as forward-page, which is bound to C-x ]. Again, you can pass it a numeric prefix argument, to move forward that many pages at once. If there are no ^L chars you can use forward-paragraph (C-<down>) or forward-line or another motion command with a prefix arg.

  3. Similarly, you can use command goto-line (M-g M-g) to go to a particular line number. (Pick a large number.) Command what-line tells you what the current line number is (you can also have it displayed in the mode-line). (M-> takes you to the end of the buffer, where M-x what-line will tell you how many lines there are altogether.)

  4. (Added after your comment about skimming until you see this or that.) Use incremental search for navigation. Search forward for something near where you want to scroll, using either C-s or (for regexp search) C-M-s.

    If you use library Isearch+ then you can also incorporate arbitrary predicates into your search, on the fly.

    That is, you need not search using only pattern matching. You could, for example, search to (1) match a pattern that selects a whole comment block or a complete switch statement, and (2) require that the match have a certain size (number of chars).

    Isearch+ also lets you search for matches to multiple patterns or search for a match to one pattern within a given distance to ("near") a match for another pattern (where the distance is measured in chars, words, sexps, lists, sentences...)

1
  • 1
    Am familiar with ways to jump around the document, holing page down or using the mouse wheel is mainly a way to skim-read a file (you might quickly scroll down until you hit a large comment block of a big switch statement for eg, the digital equivalent of flicking through a book :) ).
    – ideasman42
    Commented Mar 13, 2017 at 19:01
2

Posting this since its a weak solution but better than nothing.

Instead of changing all of emacs behavior its possible to write functions that force-redraw after every operation, which avoids hanging and makes scrolling more responsive for page up/down and mouse wheel.

(global-set-key [next]
 (lambda () (interactive)
   (condition-case nil (scroll-up)
     (end-of-buffer (goto-char (point-max))))
   (redisplay)))

(global-set-key [prior]
 (lambda () (interactive)
   (condition-case nil (scroll-down)
     (beginning-of-buffer (goto-char (point-min))))
   (redisplay)))

(global-set-key (kbd "<mouse-4>")
 (lambda () (interactive) (scroll-down mouse-wheel-scroll-amount) (redisplay)))
(global-set-key (kbd "<mouse-5>")
 (lambda () (interactive) (scroll-up mouse-wheel-scroll-amount) (redisplay)))
3
  • Note that this will tend to make Emacs lag behind your key-repeat, so when you release the key, the scrolling keeps going further than you thought :-(
    – Stefan
    Commented Mar 13, 2017 at 2:21
  • Right, in practice I don't find this such a problem though because I normally only hold down for a short time.
    – ideasman42
    Commented Mar 13, 2017 at 5:11
  • This seems working fine with page/down-up but when I use mouse to scroll down, it gets frozen
    – alper
    Commented Aug 3, 2020 at 13:18

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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