# HG changeset patch # User Juri Linkov # Date 1259537645 0 # Node ID f4a3f47777f7ba14ac989e53955e64a3ff30d43b # Parent 19cd8aecf8bd9b1dc8f9e81c08e502d7d731efb4 Add defcustom to define the cycling order of `recenter-top-bottom'. (Bug#4981) * window.el (recenter-last-op): Doc fix. (recenter-positions): New defcustom. (recenter-top-bottom): Rewrite to use `recenter-positions'. (move-to-window-line-top-bottom): Rewrite to use `recenter-positions'. diff -r 19cd8aecf8bd -r f4a3f47777f7 etc/NEWS --- a/etc/NEWS Sun Nov 29 20:40:51 2009 +0000 +++ b/etc/NEWS Sun Nov 29 23:34:05 2009 +0000 @@ -159,6 +159,9 @@ ** M-r is bound to the new `move-to-window-line-top-bottom' to mirror the new behavior of C-l in Emacs-23.1. +** `recenter-positions' can redefine the default cycling order +of `recenter-top-bottom'. + * Changes in Specialized Modes and Packages in Emacs 23.2 diff -r 19cd8aecf8bd -r f4a3f47777f7 lisp/ChangeLog --- a/lisp/ChangeLog Sun Nov 29 20:40:51 2009 +0000 +++ b/lisp/ChangeLog Sun Nov 29 23:34:05 2009 +0000 @@ -1,3 +1,13 @@ +2009-11-29 Juri Linkov + + Add defcustom to define the cycling order of `recenter-top-bottom'. + (Bug#4981) + + * window.el (recenter-last-op): Doc fix. + (recenter-positions): New defcustom. + (recenter-top-bottom): Rewrite to use `recenter-positions'. + (move-to-window-line-top-bottom): Rewrite to use `recenter-positions'. + 2009-11-29 Michael Albinus Improve integration of Tramp and ange-ftp in eshell. diff -r 19cd8aecf8bd -r f4a3f47777f7 lisp/window.el --- a/lisp/window.el Sun Nov 29 20:40:51 2009 +0000 +++ b/lisp/window.el Sun Nov 29 23:34:05 2009 +0000 @@ -1618,38 +1618,59 @@ (defvar recenter-last-op nil "Indicates the last recenter operation performed. -Possible values: `top', `middle', `bottom'.") +Possible values: `top', `middle', `bottom', integer or float numbers.") + +(defcustom recenter-positions '(middle top bottom) + "Cycling order for `recenter-top-bottom'. +A list of elements with possible values `top', `middle', `bottom', +integer or float numbers that define the cycling order for +the command `recenter-top-bottom'. + +Top and bottom destinations are `scroll-margin' lines the from true +window top and bottom. Middle redraws the frame and centers point +vertically within the window. Integer number moves current line to +the specified absolute window-line. Float number between 0.0 and 1.0 +means the percentage of the screen space from the top. The default +cycling order is middle -> top -> bottom." + :type '(repeat (choice + (const :tag "Top" top) + (const :tag "Middle" middle) + (const :tag "Bottom" bottom) + (integer :tag "Line number") + (float :tag "Percentage"))) + :version "23.2" + :group 'windows) (defun recenter-top-bottom (&optional arg) - "Move current line to window center, top, and bottom, successively. -With no prefix argument, the first call redraws the frame and - centers point vertically within the window. Successive calls - scroll the window, placing point on the top, bottom, and middle - consecutively. The cycling order is middle -> top -> bottom. + "Move current buffer line to the specified window line. +With no prefix argument, successive calls place point according +to the cycling order defined by `recenter-positions'. A prefix argument is handled like `recenter': With numeric prefix ARG, move current line to window-line ARG. - With plain `C-u', move current line to window center. - -Top and bottom destinations are actually `scroll-margin' lines - the from true window top and bottom." + With plain `C-u', move current line to window center." (interactive "P") (cond - (arg (recenter arg)) ; Always respect ARG. - ((or (not (eq this-command last-command)) - (eq recenter-last-op 'bottom)) - (setq recenter-last-op 'middle) - (recenter)) + (arg (recenter arg)) ; Always respect ARG. (t + (setq recenter-last-op + (if (eq this-command last-command) + (car (or (cdr (member recenter-last-op recenter-positions)) + recenter-positions)) + (car recenter-positions))) (let ((this-scroll-margin (min (max 0 scroll-margin) (truncate (/ (window-body-height) 4.0))))) (cond ((eq recenter-last-op 'middle) - (setq recenter-last-op 'top) - (recenter this-scroll-margin)) + (recenter)) ((eq recenter-last-op 'top) - (setq recenter-last-op 'bottom) - (recenter (- -1 this-scroll-margin)))))))) + (recenter this-scroll-margin)) + ((eq recenter-last-op 'bottom) + (recenter (- -1 this-scroll-margin))) + ((integerp recenter-last-op) + (recenter recenter-last-op)) + ((floatp recenter-last-op) + (recenter (round (* recenter-last-op (window-height)))))))))) (define-key global-map [?\C-l] 'recenter-top-bottom) @@ -1659,25 +1680,30 @@ With a prefix argument ARG, acts like `move-to-window-line'. With no argument, positions point at center of window. -Successive calls position point at the top, the bottom and again -at the center of the window." +Successive calls position point at positions defined +by `recenter-positions'." (interactive "P") (cond - (arg (move-to-window-line arg)) ; Always respect ARG. - ((or (not (eq this-command last-command)) - (eq recenter-last-op 'bottom)) - (setq recenter-last-op 'middle) - (call-interactively 'move-to-window-line)) + (arg (move-to-window-line arg)) ; Always respect ARG. (t + (setq recenter-last-op + (if (eq this-command last-command) + (car (or (cdr (member recenter-last-op recenter-positions)) + recenter-positions)) + (car recenter-positions))) (let ((this-scroll-margin (min (max 0 scroll-margin) (truncate (/ (window-body-height) 4.0))))) (cond ((eq recenter-last-op 'middle) - (setq recenter-last-op 'top) - (move-to-window-line this-scroll-margin)) + (call-interactively 'move-to-window-line)) ((eq recenter-last-op 'top) - (setq recenter-last-op 'bottom) - (move-to-window-line (- -1 this-scroll-margin)))))))) + (move-to-window-line this-scroll-margin)) + ((eq recenter-last-op 'bottom) + (move-to-window-line (- -1 this-scroll-margin))) + ((integerp recenter-last-op) + (move-to-window-line recenter-last-op)) + ((floatp recenter-last-op) + (move-to-window-line (round (* recenter-last-op (window-height)))))))))) (define-key global-map [?\M-r] 'move-to-window-line-top-bottom)