[Top][All Lists]

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

bug#16129: 24.3.50; Emacs slow with follow-mode when buffer ends before

From: Anders Lindgren
Subject: bug#16129: 24.3.50; Emacs slow with follow-mode when buffer ends before last window
Date: Fri, 10 Jan 2014 19:52:18 +0100


I agree that follow-mode slows down Emacs, even though the effect is more visible now compared to earlier. Up to Emacs 22, it really was fast. With Emacs 23 it feels like there is a definitive slowdown, which is visible e.g. when typing plain text fast and when scrolling window. (In fact, at work where I use Windows, I still use Emacs 22.)

Implementing follow-mode in the display engine sounds like a wonderful idea! In fact, when I originally wrote it (back in 1995) I intended it to be a prototype, but I envisioned the real implementation to be done in the display engine. Unfortunately, the people responsible for the display engine at the time didn't like the idea, so I made follow-mode to an all-lisp package.

Concretely, how do we proceed from here? I don't have the necessary knowledge of the internals of the display engine and I don't have much time to spend on a major rewrite like this. However, if someone decides to proceed with this, I will try to support them as much that I can.

    -- Anders

On Fri, Jan 10, 2014 at 10:31 AM, Eli Zaretskii <address@hidden> wrote:
> Date: Tue, 7 Jan 2014 09:13:19 +0100
> From: Anders Lindgren <address@hidden>
> Cc: Stefan Monnier <address@hidden>, address@hidden
> Thanks, I tried it out on the trunk, and it seems to be working correctly!

Thanks for testing.

> I'm open to reimplementing follow-mode in another way, if you think that
> it's necessary. However, there are two different uses of set-window-start,
> and maybe we don't need to change both:
> * Normally, when the position of the active window change, the start of the
> other windows are updated. This occurs very infrequent, and it would
> require a redisplay anyway.
> * When a window shows the empty tail of a buffer, point-max is "hammered"
> into window-start to ensure that the display engine doesn't recenter the
> window.
> Of the two uses, I only consider the second a problem.

I think we should consider both, because they both are detrimental to
the efficiency of redisplay.

You see, the Emacs redisplay has a very complex problem to solve,
because there are a gazillion of ways to change some obscure Lisp data
structure that can potentially change what should be on the glass.
However, if redisplay needed to examine all those potential changes
and decide whether they actually change the displayed portion of the
buffer, redisplay would become painfully slow.

So we have a lot of optimizations in the display engine, each of which
basically says: if none of the following events happened since last
redisplay cycle, then this and that potential changes don't need to be
considered.  Each optimization comes with a list of events that
invalidate it.  Redisplay basically tries to apply each optimization
in sequence, starting from the most aggressive one, until it finds one
that can be applied, or falls back to the unoptimized code, which
redisplays the entire window.

To be able to pull this trick, the display engine maintains a set of
flags, each one of which tells whether a particular kind of event
happened since last redisplay.  These flags are consulted when the
display engine must decide which optimization, if any, is applicable.

One of these flag variables is the window start point: as long as it
stays put, Emacs does not need to bother recomputing it, and does not
need to invalidate the information it keeps about where in the buffer
text is the window start point, given the current value of point.

When a post-command-hook forces a value of window-start, some of these
optimizations are inapplicable, so Emacs responsiveness suffers.  For
example, when follow-mode is on, Emacs frequently needs to redisplay
the same window twice in a row, instead of just once.

> However, it would probably be easy to handle if there would be a
> windows-specific option or call-back that could control if the
> window should be recentered or not.

That's not what I had in mind.  Instead, we could have special code in
the display engine that would automatically scroll the other window(s)
when follow-mode says they should.  IOW, when Emacs redisplays some
window because something changed in it, the display engine could
decide right there and then that some other windows need to be
redisplayed, and moreover, compute their window-start point
automatically or by calling some Lisp.  After all, the relations that
determine the window-start of the windows which participate in
follow-mode is quite simple: the next window should begin where the
previous one ends.  All of this could be done in a single redisplay
cycle, thereby avoiding the need for a post-command-hook in the first
place.  The benefit would be not only a more efficient redisplay, but
also faster Emacs, because many commands do not affect any display,
and many others do not affect windows that are under follow-mode, so
in this case a post-command-hook forces Emacs to perform unnecessary

> While I'm at it, I realized today that the responsiveness when using
> follow-mode was better when running the cursor up and down compared to left
> and right. When looking into the details I saw that the arrow keys no
> longer were bound to previous- and next-char, so we need to apply the patch
> below to follow-mode (I don't have write-access to the archives).

I installed this in your name.  Thanks.

reply via email to

[Prev in Thread] Current Thread [Next in Thread]