emacs-devel
[Top][All Lists]
Advanced

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

RE: recenter-top-bottom


From: Drew Adams
Subject: RE: recenter-top-bottom
Date: Sun, 11 Nov 2007 12:16:46 -0800

I don't care what happens with the `recenter-top-bottom' suggestion I made -
feel free to adapt it or ignore it.

There was some interest and some feedback, however, and no one has adapted
the code and installed it, so I'll respond a bit. Again, from here on in,
please do whatever you like with the idea.

It sounds, BTW, as if it might be difficult to please everyone: Juri wants
an option to specify the "center" target (e.g. 1/3 vs 1/2 height). Juri
wants a toggle between the new behavior and plain `recenter', for redrawing
purposes. Alan wants an option (not a toggle) to choose this or plain
`recenter'... (Wrt the last: Users can just rebind `C-l' to `recenter' - no
need for such an option, IMO.)

Below is a new definition that responds to some of the feedback, but not
all. I didn't add any options or toggles - feel free to do so.

With the new definition:

1. The current window line determines the destination: If within the top
third, move to window bottom. If within the middle third, move to top. If
within the bottom third, move to center.

2. The `last-command' is no longer relevant. Only the current window
position decides the destination.

3. Destinations "top" and "bottom" are in fact `scroll-conservatively' and
bottom-minus-`scroll-conservatively', respectively, so you can control how
much is kept on screen. The default value of 0 means use absolute top and
bottom. I don't think it is worthwhile to have a new, separate option for
this, since the purpose of `scroll-conservatively' is about the same - it
seems like a good fit.

Like the previous definition I sent, an explicit ARG (either plain `C-u' or
numeric) always calls `(recenter ARG)'.

Alan:

> I've had defuns bound to C-S-<right>/<left> for years,
> which move point directly to the top/bottom of the window
> without passing Go or collecting $200. If I want to zap
> point to BOW, I want it done NOW, atomically, not as a
> triple key-sequence.

So if you already have a command bound that does that, use it. I don't see
your problem with a command that you don't use. The benefit of this
suggestion is to get 3 destinations with the same key (C-l). If you prefer
to have 3 separate keys for those destinations, go for it.

Alan:

> Having thought about it, I very rarely use a bare C-l.

So, IIUC, (1) you use your own keys/commands to move "NOW" to top or bottom,
and (2) you "very rarely use a bare C-l", which moves to the center. So
`recenter-top-bottom' should "very rarely" have any effect at all on you.
You will remain happy using `C-u C-l' and your C-S-<right>/<left> commands,
as usual. (`C-l' with a prefix arg is the same for `recenter-top-bottom' as
for `recenter'.)

Alan:

> any further functionality on C-l should be optional.

>From what you say, you hardly ever use plain `C-l'. If you use `C-l' only
with a prefix arg, then you are not affected at all. However, such an option
could easily be accommodated, if others agree that it is useful. Personally,
I think it's enough for a user to rebind `C-l' to `recenter' - why have an
option for that?

Alan:

> Perhaps its behaviour could be changed so that the
> current window line is the criterion for where to go,

Good idea. I've done that in the new version, below.

Concerning frame redrawing:

The Emacs manual says that frame redisplay occurs only for a text terminal.
If redrawing for plain `C-l' is an important consideration here ("in case
the screen is garbled", which I imagine happens less nowadays), then I
propose that `recenter-top-bottom' be bound to `C-l' only when a window
manager is used. If redisplay for plain `C-l' is not an obstacle, then I
propose that we always bind `C-l' to `recenter-top-bottom'.

Alternatively, to allow for redisplay with no movement, we could add an
option, as Alan suggested, or a toggle, as Juri suggested. Or we could let
plain `C-u' call `(recenter)' to redisplay - in that case, the effect of
`C-u' would be opposite what it is for `recenter'. If there is still a need
for redisplay without movement but the need is rare, then `C-u C-l' is not
too much to ask of users, IMO. And any users who need that often could
simply bind `C-l' to `recenter'.

BTW, the doc string for `recenter' seems to contradict the Emacs manual
(node Scrolling). The manual says that `C-l' with a prefix arg does not
redraw the frame - and that is mentioned specifically in the context of a
numeric arg. The doc string says that redrawing is inhibited for plain
`C-u'; it suggests that redrawing occurs for numeric ARG.

Here's the new definition I'd propose:

(defun recenter-top-bottom (&optional arg)
  "Move current line to line ARG, window center, top, or bottom.
With a prefix argument, this is the same as `recenter':
 With numeric prefix ARG, move current line to window-line ARG.
 With plain `C-u', move current line to window center.

Otherwise, the window starting position determines the next position:
 If in the top third, move to bottom.
 If in middle third,  move to top.
 If in bottom third,  move tocenter.

Top and bottom destinations are actually `scroll-conservatively' lines
from true top and bottom."
  (interactive "P")
  (cond (arg (recenter arg))
        (t
         (let* ((top (1+ (count-lines 1 (window-start))))
                (bottom (1+ (count-lines 1 (window-end))))
                (current (1+ (count-lines 1 (point))))
                (total (window-height)))
           (cond ((< (- current top) (/ total 3))
                  (recenter (1- (- scroll-conservatively))))
                 ((< (- bottom current) (/ total 3)) (recenter))
                 (t (recenter scroll-conservatively)))))))

Note that this code could be optimized by replacing the multiple
`count-lines' calls with a single-traversal pickup of top, bottom and
current values. I don't think such optimization is needed here, however.






reply via email to

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