* (Not) scrolling past the end of a buffer
@ 2012-10-19 22:34 Jorgen Schaefer
2012-10-20 2:07 ` Stefan Monnier
2012-10-20 16:31 ` Romain Francoise
0 siblings, 2 replies; 6+ messages in thread
From: Jorgen Schaefer @ 2012-10-19 22:34 UTC (permalink / raw)
To: emacs-devel
Hello!
There was a discussion back in February about Emacs scrolling past the
end of buffers, but that discussion never finished (as far as I can
tell).
http://lists.gnu.org/archive/html/emacs-devel/2012-02/msg00314.html
Emacs' scrolling behavior allows for a window to move past the end of a
buffer up to the point where the last line of a buffer is the only
thing displayed. This can be useful for editing, but it is unexpected
behavior for modes that interact with other programs.
Based on the behavior of terminals, the expectation and preference
there is that the input line would remain at the bottom edge of a
window as long as there is enough data to be displayed.
There have been a number of hacks to implement this behavior. For
example, `comint-mode' introduced the variable
`comint-scroll-show-maximum-output' to achieve just this effect, but
it's an incomplete solution as manual scrolling or splitting windows
still can cause the prompt to show up in the middle of a window. The IRC
clients ERC and Circe both implement a specific hook to do this. Both
actually used `window-scroll-functions' for this, which worked well but
is problematic because other functions on the hook rely on the view port
not to change during the running of the hook. Hence a warning to that
effect was added to the hook description and ERC was changed to use
`post-command-hook', causing quite a bit of unnecessary computation.
Eshell and rcirc both have copied the comint behavior after originally
following ERC's approach.
And from the thread linked to above, it seems that some users would like
this behavior in editing buffers as well.
Based on the apparent need for such a functionality, I actually looked
at window.c to see if I can figure out how to add it right in the
scrolling code, but my C seems to be too rusty to actually get this
done. Though a buffer-local variable that's checked from the scrolling
code seems to me to be the correct solution for this problem.
So, with `window-scroll-functions' off-limits to this kind of code,
what's the officially recommended approach for modes that want to keep
their input line at the end of a window, and not break because of
splitting a window (or manual recentering, or any manual scrolling,
or ...)?
Regards,
-- Jorgen
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: (Not) scrolling past the end of a buffer
2012-10-19 22:34 (Not) scrolling past the end of a buffer Jorgen Schaefer
@ 2012-10-20 2:07 ` Stefan Monnier
2012-10-20 9:52 ` Jorgen Schaefer
2012-10-20 16:31 ` Romain Francoise
1 sibling, 1 reply; 6+ messages in thread
From: Stefan Monnier @ 2012-10-20 2:07 UTC (permalink / raw)
To: Jorgen Schaefer; +Cc: emacs-devel
> There was a discussion back in February about Emacs scrolling past the
> end of buffers, but that discussion never finished (as far as I can tell).
It won't end until someone goes through the trouble to write the code.
But those who know the code know that it's going to be a pain to
implement, especially if you want acceptable performance.
IOW, patches welcome,
Stefan
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: (Not) scrolling past the end of a buffer
2012-10-20 2:07 ` Stefan Monnier
@ 2012-10-20 9:52 ` Jorgen Schaefer
2012-10-23 16:25 ` Stefan Monnier
0 siblings, 1 reply; 6+ messages in thread
From: Jorgen Schaefer @ 2012-10-20 9:52 UTC (permalink / raw)
To: Stefan Monnier; +Cc: emacs-devel
On Fri, 19 Oct 2012 22:07:59 -0400
Stefan Monnier <monnier@iro.umontreal.ca> wrote:
> > There was a discussion back in February about Emacs scrolling past
> > the end of buffers, but that discussion never finished (as far as I
> > can tell).
>
> It won't end until someone goes through the trouble to write the code.
> But those who know the code know that it's going to be a pain to
> implement, especially if you want acceptable performance.
> IOW, patches welcome,
As I said, I tried - and failed. :-(
Now, I *do* have some lisp code that does exactly what I want. It's not
exactly the paragon of efficiency, but it works, and it's fast enough
for my needs:
(when (and window-bottom-mode
(equal (point-max)
(window-end nil t)))
(save-excursion
(goto-char (point-max))
(recenter -1)))
My problem is that I do not have a place where I can actually put this.
`window-scroll-functions' works excellently with only minor performance
problems in large buffers. But since Emacs 24, the docstring of that
variable explicitly says not to do this. As a law-abiding Emacs
citizen, I am trying to fix my code now.
`post-command-hook', as used by ERC, is a very problematic choice.
There, you need to walk through all windows, in all frames, go to the
respective buffer, and then run the code above - after each command.
That's incredibly bad performance. (ERC gets away with it because it
doesn't use `window-end', but it's own input mark; that's not exactly
the behavior I want. I've also seen complaints about that being slower
than the old solution in ERC, but I have no first-hand experience.)
So, now with the request not to use `window-scroll-functions', and
`post-command-hook' being a very bad choice, where would I hook my code
into Emacs?
Regards,
-- Jorgen
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: (Not) scrolling past the end of a buffer
2012-10-20 9:52 ` Jorgen Schaefer
@ 2012-10-23 16:25 ` Stefan Monnier
0 siblings, 0 replies; 6+ messages in thread
From: Stefan Monnier @ 2012-10-23 16:25 UTC (permalink / raw)
To: Jorgen Schaefer; +Cc: emacs-devel
> (when (and window-bottom-mode
> (equal (point-max)
> (window-end nil t)))
> (save-excursion
> (goto-char (point-max))
> (recenter -1)))
I guess it would be useful for window-end (or some other function) to
return not just `point-max' when the EOB is displayed, but additionally
indicate where that EOB is displayed (so you can avoid calling
`recenter' if EOB is already at the bottom).
> My problem is that I do not have a place where I can actually put this.
Yup. I think a good place would be a new `after-redisplay-functions'.
Those functions would be called with one argument (the redisplayed
window) right after rebuilding the glyph matrix of a window (and only
if that matrix has changed).
I believe this hook shouldn't be too difficult to add.
A related hook would be `before-redisplay-functions' which I'd also like
to see added. This one is a bit trickier, because we don't want to call
it for every existing window, but only for those which actually require
a redisplay. I would *really* like to see such a hook (reveal-mode
could use it, the region-highlighting code could use it).
Stefan
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: (Not) scrolling past the end of a buffer
2012-10-19 22:34 (Not) scrolling past the end of a buffer Jorgen Schaefer
2012-10-20 2:07 ` Stefan Monnier
@ 2012-10-20 16:31 ` Romain Francoise
2012-10-20 16:45 ` Jorgen Schaefer
1 sibling, 1 reply; 6+ messages in thread
From: Romain Francoise @ 2012-10-20 16:31 UTC (permalink / raw)
To: Jorgen Schaefer; +Cc: emacs-devel
Jorgen Schaefer <forcer@forcix.cx> writes:
> Emacs' scrolling behavior allows for a window to move past the end of a
> buffer up to the point where the last line of a buffer is the only
> thing displayed. This can be useful for editing, but it is unexpected
> behavior for modes that interact with other programs.
> Based on the behavior of terminals, the expectation and preference
> there is that the input line would remain at the bottom edge of a
> window as long as there is enough data to be displayed.
That's a matter of taste. One of the strengths of Emacs is that it
provides a unified user interface for many different activities, and some
people find it annoying when modes go out of their way to make their
buffers behave differently.
Personally I don't want my shell-mode buffers to start behaving like
terminals, because they're not. The whole point of shell-mode is to allow
users to interact with shell input/output as if it were normal buffer
text.
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: (Not) scrolling past the end of a buffer
2012-10-20 16:31 ` Romain Francoise
@ 2012-10-20 16:45 ` Jorgen Schaefer
0 siblings, 0 replies; 6+ messages in thread
From: Jorgen Schaefer @ 2012-10-20 16:45 UTC (permalink / raw)
To: Romain Francoise; +Cc: emacs-devel
On Sat, 20 Oct 2012 18:31:52 +0200
Romain Francoise <romain@orebokech.com> wrote:
> Jorgen Schaefer <forcer@forcix.cx> writes:
>
> > Emacs' scrolling behavior allows for a window to move past the end
> > of a buffer up to the point where the last line of a buffer is the
> > only thing displayed. This can be useful for editing, but it is
> > unexpected behavior for modes that interact with other programs.
>
> > Based on the behavior of terminals, the expectation and preference
> > there is that the input line would remain at the bottom edge of a
> > window as long as there is enough data to be displayed.
>
> That's a matter of taste.
Indeed, that is why I was talking about a configuration option. :-)
Sorry if this came across badly.
comint.el already tries to imitate this behavior by setting
`comint-scroll-show-maximum-output' to t, but this only achieves this
behavior after output from the process.
Regards,
-- Jorgen
^ permalink raw reply [flat|nested] 6+ messages in thread
end of thread, other threads:[~2012-10-23 16:25 UTC | newest]
Thread overview: 6+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2012-10-19 22:34 (Not) scrolling past the end of a buffer Jorgen Schaefer
2012-10-20 2:07 ` Stefan Monnier
2012-10-20 9:52 ` Jorgen Schaefer
2012-10-23 16:25 ` Stefan Monnier
2012-10-20 16:31 ` Romain Francoise
2012-10-20 16:45 ` Jorgen Schaefer
Code repositories for project(s) associated with this external index
https://git.savannah.gnu.org/cgit/emacs.git
https://git.savannah.gnu.org/cgit/emacs/org-mode.git
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.