]> code.delx.au - gnu-emacs/blobdiff - lisp/window.el
Merge from origin/emacs-25
[gnu-emacs] / lisp / window.el
index ce0256f1fff3a4f66aeb2fbbb95f099d75d6da07..1d41d821dc467b84c1cc39630fe5130b7386cf2a 100644 (file)
@@ -1,6 +1,6 @@
 ;;; window.el --- GNU Emacs window commands aside from those written in C
 
-;; Copyright (C) 1985, 1989, 1992-1994, 2000-2015 Free Software
+;; Copyright (C) 1985, 1989, 1992-1994, 2000-2016 Free Software
 ;; Foundation, Inc.
 
 ;; Maintainer: emacs-devel@gnu.org
@@ -2005,7 +2005,7 @@ SIDE can be any of the symbols `left', `top', `right' or
 
 ;; Predecessors to the below have been devised by Julian Assange in
 ;; change-windows-intuitively.el and Hovav Shacham in windmove.el.
-;; Neither of these allow to selectively ignore specific windows
+;; Neither of these allow one to selectively ignore specific windows
 ;; (windows whose `no-other-window' parameter is non-nil) as targets of
 ;; the movement.
 (defun window-in-direction (direction &optional window ignore sign wrap mini)
@@ -2034,7 +2034,7 @@ has one, and a window at the bottom of the frame otherwise.
 Optional argument MINI nil means to return the minibuffer window
 if and only if it is currently active.  MINI non-nil means to
 return the minibuffer window even when it's not active.  However,
-if WRAP non-nil, always act as if MINI were nil.
+if WRAP is non-nil, always act as if MINI were nil.
 
 Return nil if no suitable window can be found."
   (setq window (window-normalize-window window t))
@@ -2473,8 +2473,6 @@ windows."
   (when (window-right window)
     (window--resize-reset-1 (window-right window) horizontal)))
 
-;; The following routine is used to manually resize the minibuffer
-;; window and is currently used, for example, by ispell.el.
 (defun window--resize-mini-window (window delta)
   "Resize minibuffer window WINDOW by DELTA pixels.
 If WINDOW cannot be resized by DELTA pixels make it as large (or
@@ -3241,9 +3239,9 @@ move it as far as possible in the desired direction."
        (setq ignore 'preserved)
        (setq right first-right)
        (while (and right
-                   (or (window-size-fixed-p right horizontal 'preserved))
-                   (<= (window-size right horizontal t)
-                       (window-min-size right horizontal 'preserved t)))
+                   (or (window-size-fixed-p right horizontal 'preserved)
+                        (<= (window-size right horizontal t)
+                            (window-min-size right horizontal 'preserved t))))
          (setq right
                (or (window-right right)
                    (progn
@@ -3338,20 +3336,29 @@ negative, shrink selected window by -DELTA lines or columns."
     (cond
      ((zerop delta))
      ((window-size-fixed-p nil horizontal)
-      (error "Selected window has fixed size"))
+      (user-error "Selected window has fixed size"))
      ((window-minibuffer-p)
       (if horizontal
-         (error "Cannot resize minibuffer window horizontally")
-       (window--resize-mini-window (selected-window) delta)))
+         (user-error "Cannot resize minibuffer window horizontally")
+       (window--resize-mini-window
+         (selected-window) (* delta (frame-char-height)))))
      ((and (not horizontal)
           (window-full-height-p)
           (eq (window-frame minibuffer-window) (selected-frame))
           (not resize-mini-windows))
       ;; If the selected window is full height and `resize-mini-windows'
       ;; is nil, resize the minibuffer window.
-      (window--resize-mini-window minibuffer-window (- delta)))
+      (window--resize-mini-window
+       minibuffer-window (* (- delta) (frame-char-height))))
      ((window--resizable-p nil delta horizontal)
       (window-resize nil delta horizontal))
+     ((window--resizable-p nil delta horizontal 'preserved)
+      (window-resize nil delta horizontal 'preserved))
+     ((eq this-command
+         (if horizontal 'enlarge-window-horizontally 'enlarge-window))
+      ;; For backward compatibility don't signal an error unless this
+      ;; command is `enlarge-window(-horizontally)'.
+      (user-error "Cannot enlarge selected window"))
      (t
       (window-resize
        nil (if (> delta 0)
@@ -3364,8 +3371,7 @@ negative, shrink selected window by -DELTA lines or columns."
 Interactively, if no argument is given, make the selected window
 one line smaller.  If optional argument HORIZONTAL is non-nil,
 make selected window narrower by DELTA columns.  If DELTA is
-negative, enlarge selected window by -DELTA lines or columns.
-Also see the `window-min-height' variable."
+negative, enlarge selected window by -DELTA lines or columns."
   (interactive "p")
   (let ((minibuffer-window (minibuffer-window)))
     (when (window-preserved-size nil horizontal)
@@ -3373,20 +3379,29 @@ Also see the `window-min-height' variable."
     (cond
      ((zerop delta))
      ((window-size-fixed-p nil horizontal)
-      (error "Selected window has fixed size"))
+      (user-error "Selected window has fixed size"))
      ((window-minibuffer-p)
       (if horizontal
-         (error "Cannot resize minibuffer window horizontally")
-       (window--resize-mini-window (selected-window) (- delta))))
+         (user-error "Cannot resize minibuffer window horizontally")
+       (window--resize-mini-window
+         (selected-window) (* (- delta) (frame-char-height)))))
      ((and (not horizontal)
           (window-full-height-p)
           (eq (window-frame minibuffer-window) (selected-frame))
           (not resize-mini-windows))
       ;; If the selected window is full height and `resize-mini-windows'
       ;; is nil, resize the minibuffer window.
-      (window--resize-mini-window minibuffer-window delta))
+      (window--resize-mini-window
+       minibuffer-window (* delta (frame-char-height))))
      ((window--resizable-p nil (- delta) horizontal)
       (window-resize nil (- delta) horizontal))
+     ((window--resizable-p nil (- delta) horizontal 'preserved)
+      (window-resize nil (- delta) horizontal 'preserved))
+     ((eq this-command
+         (if horizontal 'shrink-window-horizontally 'shrink-window))
+      ;; For backward compatibility don't signal an error unless this
+      ;; command is `shrink-window(-horizontally)'.
+      (user-error "Cannot shrink selected window"))
      (t
       (window-resize
        nil (if (> delta 0)
@@ -6721,6 +6736,71 @@ that frame."
        (unless (cdr (assq 'inhibit-switch-frame alist))
          (window--maybe-raise-frame (window-frame window)))))))
 
+(defun display-buffer-reuse-mode-window (buffer alist)
+  "Return a window based on the mode of the buffer it displays.
+Display BUFFER in the returned window.  Return nil if no usable
+window is found.
+
+If ALIST contains a `mode' entry, its value is a major mode (a
+symbol) or a list of modes.  A window is a candidate if it
+displays a buffer that derives from one of the given modes.  When
+ALIST contains no `mode' entry, the current major mode of BUFFER
+is used.
+
+The behaviour is also controlled by entries for
+`inhibit-same-window', `reusable-frames' and
+`inhibit-switch-frame' as is done in the function
+`display-buffer-reuse-window'."
+  (let* ((alist-entry (assq 'reusable-frames alist))
+         (alist-mode-entry (assq 'mode alist))
+        (frames (cond (alist-entry (cdr alist-entry))
+                      ((if (eq pop-up-frames 'graphic-only)
+                           (display-graphic-p)
+                         pop-up-frames)
+                       0)
+                      (display-buffer-reuse-frames 0)
+                      (t (last-nonminibuffer-frame))))
+         (inhibit-same-window-p (cdr (assq 'inhibit-same-window alist)))
+        (windows (window-list-1 nil 'nomini frames))
+         (buffer-mode (with-current-buffer buffer major-mode))
+         (allowed-modes (if alist-mode-entry
+                            (cdr alist-mode-entry)
+                          buffer-mode))
+         (curwin (selected-window))
+         (curframe (selected-frame)))
+    (unless (listp allowed-modes)
+      (setq allowed-modes (list allowed-modes)))
+    (let (same-mode-same-frame
+          same-mode-other-frame
+          derived-mode-same-frame
+          derived-mode-other-frame)
+      (dolist (window windows)
+        (let (mode? frame?)
+          (with-current-buffer (window-buffer window)
+            (setq mode?
+                  (cond ((memq major-mode allowed-modes)
+                         'same)
+                        ((derived-mode-p allowed-modes)
+                         'derived))))
+          (when (and mode?
+                     (not (and inhibit-same-window-p
+                               (eq window curwin))))
+            (if (eq curframe (window-frame window))
+                (if (eq mode? 'same)
+                    (push window same-mode-same-frame)
+                  (push window derived-mode-same-frame))
+              (if (eq mode? 'same)
+                  (push window same-mode-other-frame)
+                (push window derived-mode-other-frame))))))
+      (let ((window (car (nconc same-mode-same-frame
+                                same-mode-other-frame
+                                derived-mode-same-frame
+                                derived-mode-other-frame))))
+        (when (window-live-p window)
+          (prog1 (window--display-buffer buffer window 'reuse alist)
+            (unless (cdr (assq 'inhibit-switch-frame alist))
+              (window--maybe-raise-frame (window-frame window)))))))))
+
 (defun display-buffer--special-action (buffer)
   "Return special display action for BUFFER, if any.
 If `special-display-p' returns non-nil for BUFFER, return an
@@ -7874,7 +7954,7 @@ Return non-nil if the window was shrunk, nil otherwise."
 ;; Groups of windows (Follow Mode).
 ;;
 ;; This section of functions extends the functionality of some window
-;; manipulating commands to groups of windows co-operatively
+;; manipulating commands to groups of windows cooperatively
 ;; displaying a buffer, typically with Follow Mode.
 ;;
 ;; The xxx-function variables are permanent locals so that their local
@@ -7930,10 +8010,10 @@ overriding motion of point in order to display at this exact start."
       (funcall set-window-group-start-function window pos noforce)
     (set-window-start window pos noforce)))
 
-(defvar recenter-group-function nil)
-(make-variable-buffer-local 'recenter-group-function)
-(put 'recenter-group-function 'permanent-local t)
-(defun recenter-group (&optional arg)
+(defvar recenter-window-group-function nil)
+(make-variable-buffer-local 'recenter-window-group-function)
+(put 'recenter-window-group-function 'permanent-local t)
+(defun recenter-window-group (&optional arg)
   "Center point in the group of windows containing the selected window
 and maybe redisplay frame.  When a grouping mode (such as Follow Mode)
 is not active, this function is identical to `recenter'.
@@ -7953,8 +8033,8 @@ are redrawn.
 
 Just C-u as prefix means put point in the center of the window
 and redisplay normally--don't erase and redraw the frame."
-  (if (functionp recenter-group-function)
-      (funcall recenter-group-function arg)
+  (if (functionp recenter-window-group-function)
+      (funcall recenter-window-group-function arg)
     (recenter arg)))
 
 (defvar pos-visible-in-window-group-p-function nil)