From 0116abbdeb4ab81438d90bda45b753ec8dd0a7e9 Mon Sep 17 00:00:00 2001 From: Juri Linkov Date: Sun, 29 Nov 2009 23:34:05 +0000 Subject: [PATCH] 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'. --- etc/NEWS | 3 ++ lisp/ChangeLog | 10 ++++++ lisp/window.el | 86 ++++++++++++++++++++++++++++++++------------------ 3 files changed, 69 insertions(+), 30 deletions(-) diff --git a/etc/NEWS b/etc/NEWS index fed8ea18670..9fcea9b23ef 100644 --- a/etc/NEWS +++ b/etc/NEWS @@ -159,6 +159,9 @@ operate on several directories (copy, rename, diff). ** 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 --git a/lisp/ChangeLog b/lisp/ChangeLog index 03d63d96b69..234d50442d4 100644 --- a/lisp/ChangeLog +++ b/lisp/ChangeLog @@ -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 --git a/lisp/window.el b/lisp/window.el index ed4cfb5653e..e1b2000844c 100644 --- a/lisp/window.el +++ b/lisp/window.el @@ -1618,38 +1618,59 @@ Otherwise, bury WINDOW's buffer, see `bury-buffer'." (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 @@ Top and bottom destinations are actually `scroll-margin' lines 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) -- 2.39.5