X-Git-Url: https://code.delx.au/gnu-emacs/blobdiff_plain/ac549fa5e4f9e81fc080a267cf81bdad204db0ae..38fe4016d4ff317499eaf66b242e19db3da4a23f:/lisp/window.el diff --git a/lisp/window.el b/lisp/window.el index 1c77795d09..e8e1c6149f 100644 --- a/lisp/window.el +++ b/lisp/window.el @@ -1,7 +1,8 @@ ;;; window.el --- GNU Emacs window commands aside from those written in C ;; Copyright (C) 1985, 1989, 1992, 1993, 1994, 2000, 2001, 2002, -;; 2003, 2004, 2005, 2006, 2007, 2008, 2009 Free Software Foundation, Inc. +;; 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 +;; Free Software Foundation, Inc. ;; Maintainer: FSF ;; Keywords: internal @@ -76,9 +77,9 @@ WINDOW defaults to the selected window. The return value does not include the mode line or the header line, if any. If a line at the bottom of the window is only -partially visible, that line is included in the return value. If -you do not want to include a partially visible bottom line in the -return value, use `window-text-height' instead." +partially visible, that line is included in the return value. +If you do not want to include a partially visible bottom line +in the return value, use `window-text-height' instead." (or window (setq window (selected-window))) (if (window-minibuffer-p window) (window-height window) @@ -159,8 +160,8 @@ counts, `walk-windows' includes the windows in the frame from which you entered the minibuffer, as well as the minibuffer window. -ALL-FRAMES nil or omitted means cycle through all windows on - WINDOW's frame, plus the minibuffer window if specified by the +ALL-FRAMES nil or omitted means cycle through all windows on the + selected frame, plus the minibuffer window if specified by the MINIBUF argument, see above. If the minibuffer counts, cycle through all windows on all frames that share that minibuffer too. @@ -172,8 +173,8 @@ ALL-FRAMES 0 means cycle through all windows on all visible and iconified frames. ALL-FRAMES a frame means cycle through all windows on that frame only. -Anything else means cycle through all windows on WINDOW's frame - and no others. +Anything else means cycle through all windows on the selected + frame and no others. This function changes neither the order of recently selected windows nor the buffer list." @@ -784,7 +785,7 @@ selected rather than \(as usual\) some other window. See (defcustom pop-up-frames nil "Whether `display-buffer' should make a separate frame. -If nil, never make a seperate frame. +If nil, never make a separate frame. If the value is `graphic-only', make a separate frame on graphic displays only. Any other non-nil value means always make a separate frame." @@ -1005,7 +1006,7 @@ is higher than WINDOW." (not (eq window (selected-window))) ;; Don't resize minibuffer windows. (not (window-minibuffer-p (selected-window))) - (> (window-height (selected-window)) (window-height window)) + (> (window-height (selected-window)) (window-height window)) (eq (window-frame window) (window-frame (selected-window))) (let ((sel-edges (window-edges (selected-window))) (win-edges (window-edges window))) @@ -1035,13 +1036,21 @@ Do not raise the selected frame. Return WINDOW." (raise-frame frame)) window)) -(defun window--display-buffer-2 (buffer window) +(defun window--display-buffer-2 (buffer window &optional dedicated) "Display BUFFER in WINDOW and make its frame visible. +Set `window-dedicated-p' to DEDICATED if non-nil. Return WINDOW." (when (and (buffer-live-p buffer) (window-live-p window)) (set-window-buffer window buffer) + (when dedicated + (set-window-dedicated-p window dedicated)) (window--display-buffer-1 window))) +(defvar display-buffer-mark-dedicated nil + "If non-nil, `display-buffer' marks the windows it creates as dedicated. +The actual non-nil value of this variable will be copied to the +`window-dedicated-p' flag.") + (defun display-buffer (buffer-or-name &optional not-this-window frame) "Make buffer BUFFER-OR-NAME appear in some window but don't select it. BUFFER-OR-NAME must be a buffer or the name of an existing @@ -1133,8 +1142,8 @@ consider all visible or iconified frames." buffer (if (listp pars) pars)))))) ((or use-pop-up-frames (not frame-to-use)) ;; We want or need a new frame. - (window--display-buffer-2 - buffer (frame-selected-window (funcall pop-up-frame-function)))) + (let ((win (frame-selected-window (funcall pop-up-frame-function)))) + (window--display-buffer-2 buffer win display-buffer-mark-dedicated))) ((and pop-up-windows ;; Make a new window. (or (not (frame-parameter frame-to-use 'unsplittable)) @@ -1149,8 +1158,9 @@ consider all visible or iconified frames." (or (window--try-to-split-window (get-largest-window frame-to-use t)) (window--try-to-split-window - (get-lru-window frame-to-use t)))) - (window--display-buffer-2 buffer window-to-use))) + (get-lru-window frame-to-use t))))) + (window--display-buffer-2 buffer window-to-use + display-buffer-mark-dedicated)) ((let ((window-to-undedicate ;; When NOT-THIS-WINDOW is non-nil, temporarily dedicate ;; the selected window to its buffer, to avoid that some of @@ -1270,8 +1280,7 @@ window." (setq size (+ (window-height) size))) (setq new-window (split-window nil size)) (unless split-window-keep-point - (save-excursion - (set-buffer (window-buffer)) + (with-current-buffer (window-buffer) (goto-char (window-start)) (setq moved (vertical-motion (window-height))) (set-window-start new-window (point)) @@ -1610,40 +1619,95 @@ 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) + +(defun move-to-window-line-top-bottom (&optional arg) + "Position point relative to window. + +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 positions defined +by `recenter-positions'." + (interactive "P") + (cond + (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) + (call-interactively 'move-to-window-line)) + ((eq recenter-last-op 'top) + (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) + (defvar mouse-autoselect-window-timer nil "Timer used by delayed window autoselection.")