emacs-devel
[Top][All Lists]
Advanced

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

Re: recenter-top-bottom


From: Stefan Monnier
Subject: Re: recenter-top-bottom
Date: Thu, 15 Nov 2007 10:16:27 -0500
User-agent: Gnus/5.13 (Gnus v5.13) Emacs/23.0.50 (gnu/linux)

> (defun recenter-top-bottom (&optional arg)
>   "Move current line to window center, top, and bottom, successively.
> 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 move current line to window center on first call, and to
> top, middle, or bottom on successive calls.

> The starting position of the window determines the cycling order:
>  If initially in the top or middle third: top -> middle -> bottom.
>  If initially in the bottom third: bottom -> middle -> top.

> Top and bottom destinations are actually `scroll-conservatively' lines
> from true window top and bottom."
>   (interactive "P")
>   (if arg ; Always respect ARG.
>       (recenter arg)
>     (case last-command
>       (recenter-tb-top ; Top -> middle -> bottom
>        (setq this-command 'recenter-tb-middle)
>        (recenter))
>       (recenter-tb-middle
>        (setq this-command 'recenter-tb-bottom)
>        (recenter (1- (- scroll-conservatively))))
>       (recenter-tb-bottom
>        (setq this-command 'recenter-tb-top)
>        (recenter scroll-conservatively))
>       (recenter-tb-bottom-1 ; Bottom -> middle -> top
>        (setq this-command 'recenter-tb-middle-1)
>        (recenter))
>       (recenter-tb-middle-1
>        (setq this-command 'recenter-tb-top-1)
>        (recenter scroll-conservatively))
>       (recenter-tb-top-1
>        (setq this-command 'recenter-tb-bottom-1)
>        (recenter (1- (- scroll-conservatively))))
>       (otherwise ; First time - save mode and recenter.
>        (let ((bottom (1+ (count-lines 1 (window-end))))
>              (current (1+ (count-lines 1 (point))))
>              (total (window-height)))
>          (if (< (- bottom current) (/ total 3))
>              (setq this-command 'recenter-tb-middle-1)
>            (setq this-command 'recenter-tb-middle)))
>        (recenter)))))

Looks OK, except I'd rather not fool around with last-command and
this-command:

(defvar recenter-last-op nil)

(defun recenter-top-bottom (&optional arg)
  "Move current line to window center, top, and bottom, successively.
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 move current line to window center on first call, and to
top, middle, or bottom on successive calls.

The starting position of the window determines the cycling order:
 If initially in the top or middle third: top -> middle -> bottom.
 If initially in the bottom third: bottom -> middle -> top.

Top and bottom destinations are actually `scroll-conservatively' lines
from true window top and bottom."
  (interactive "P")
  (cond
  (arg (recenter arg)) ; Always respect ARG.
  ((not (eq this-command last-command))
   ;; First time - save mode and recenter.
   (let ((bottom (1+ (count-lines 1 (window-end))))
         (current (1+ (count-lines 1 (point))))
         (total (window-height)))
     (setq recenter-last-op (if (< (- bottom current) (/ total 3))
                                'recenter-tb-middle-1)
                              'recenter-tb-middle)
     (recenter)))
  (t ;; repeat: loop through various options.
   (ecase recenter-last-op
     (recenter-tb-top ; Top -> middle -> bottom
      (setq recenter-last-op 'recenter-tb-middle)
      (recenter))
     (recenter-tb-middle
      (setq recenter-last-op 'recenter-tb-bottom)
      (recenter (1- (- scroll-conservatively))))
     (recenter-tb-bottom
      (setq recenter-last-op 'recenter-tb-top)
      (recenter scroll-conservatively))
     (recenter-tb-bottom-1 ; Bottom -> middle -> top
      (setq recenter-last-op 'recenter-tb-middle-1)
      (recenter))
     (recenter-tb-middle-1
      (setq recenter-last-op 'recenter-tb-top-1)
      (recenter scroll-conservatively))
     (recenter-tb-top-1
      (setq recenter-last-op 'recenter-tb-bottom-1)
      (recenter (1- (- scroll-conservatively))))))))


-- Stefan




reply via email to

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