bug-gnu-emacs
[Top][All Lists]
Advanced

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

bug#1806: dired-pop-to-buffer in wrong place


From: martin rudalics
Subject: bug#1806: dired-pop-to-buffer in wrong place
Date: Tue, 20 Jan 2009 16:59:17 +0100
User-agent: Thunderbird 2.0.0.16 (Windows/20080708)

Please have a look at the attached (only lightly tested) patch.  I
didn't provide a similar service for `special-display-buffer-names' and
`special-display-regexps' yet.

`display-buffer' and `pop-to-buffer' behave "as usual" as long as the
default values for `pop-up-windows', NOT-THIS-WINDOW, and OTHER-WINDOW
are used.  An application calling `display-buffer' or `pop-to-buffer'
can specify the preferable window to split by setting NOT-THIS-WINDOW or
OTHER-WINDOW appropriately.  Users can specify their preferences (and
override the application) by setting `pop-up-windows' appropriately.

martin


*** window.el.~1.179.~  2009-01-16 17:41:41.046875000 +0100
--- window.el   2009-01-20 16:58:01.062500000 +0100
***************
*** 789,797 ****
    :version "21.1"
    :group 'windows)
  
  (defcustom pop-up-windows t
!   "Non-nil means `display-buffer' should make a new window."
!   :type 'boolean
    :group 'windows)
  
  (defcustom split-height-threshold 80
--- 789,843 ----
    :version "21.1"
    :group 'windows)
  
+ ;; Make sure the following two variables always use the same values
+ ;; (sans `t').
+ (defconst pop-up-windows-values
+   '(largest lru selected below right bottom-left top-left)
+   "List of preferences supported by `pop-up-windows'.")
+ 
  (defcustom pop-up-windows t
!   "Non-nil means `display-buffer' is allowed to make a new window.
! A non-empty list specifies the windows `display-buffer' will
! consider for splitting on the respective frame.  The following
! entries are supported:
! 
!  largest ...... largest window
!  lru .......... least recently used window
!  selected ..... the frame's selected window
!  below ........ window below frame's selected window
!  right ........ window right of frame's selected window
!  bottom-left .. window in lower left corner of frame
!  top-left ..... window in upper left corner of frame
!  t ............ window specified by application
! 
! Note that when `display-buffer' finds the value t, it will use
! the value specified by the function that called `display-buffer'
! provided there is one, and ignore this entry otherwise.  If the
! entire list equals `(t)', `display-buffer' will pop up a new
! window if and only if the application specified value produces
! one.  If this list does not contain the value t, `display-buffer'
! will ignore any value specified by an application.
! 
! The default value t stands for the list `(t largest lru)'.  This
! means that Emacs will first try a value specified by the
! application that called `display-buffer'.  If there's no such
! value, or the window specified by that value doesn't exist, or
! that window can't be split, `display-buffer' will try to split
! the largest window and, if that fails too, the least recently
! used window."
!   :type '(choice
!         (const :tag "Disallow" nil)
!         (const :tag "Allow" t)
!         (repeat :tag "Preferences"
!                 (choice
!                  (const :tag "Largest" largest)
!                  (const :tag "Least Recently Used" lru)
!                  (const :tag "Selected" selected)
!                  (const :tag "Below Selected" below)
!                  (const :tag "Right of Selected" right)
!                  (const :tag "Bottom Left" bottom-left)
!                  (const :tag "Top Left" top-left)
!                  (const :tag "Application Specified" t))))
    :group 'windows)
  
  (defcustom split-height-threshold 80
***************
*** 957,962 ****
--- 1003,1099 ----
          (enlarge-window (/ (- (window-height window) (window-height)) 2))
        (error nil)))))
  
+ (defun window--probe-windows (frame windows probe)
+   "Find window in WINDOWS satisfying PROBE on FRAME.
+ To be called by `window--pop-up-window' exclusively."
+   (cond
+    ((eq probe 'selected)
+     (let ((window (frame-selected-window frame)))
+       (car (member window windows))))
+    ((eq probe 'largest)
+     (get-largest-window frame t))
+    ((eq probe 'lru)
+     (get-lru-window frame t))
+    ((memq probe '(below right bottom-left top-left))
+     (let ((this-edges
+          (window-edges
+           (cond
+            ((memq probe '(below right))
+             (frame-selected-window frame))
+            ((memq probe '(top-left bottom-left))
+             (frame-root-window frame)))))
+         edges)
+       (catch 'found
+       (dolist (window windows)
+         (setq edges (window-edges window))
+         (when (or (and (eq probe 'below)
+                        (= (nth 1 edges) (nth 3 this-edges))
+                        (= (nth 2 edges) (nth 2 this-edges)))
+                   (and (eq probe 'right)
+                        (= (nth 0 edges) (nth 2 this-edges))
+                        (= (nth 1 edges) (nth 1 this-edges)))
+                   (and (eq probe 'top-left)
+                        (= (nth 0 edges) (nth 0 this-edges))
+                        (= (nth 1 edges) (nth 1 this-edges)))
+                   (and (eq probe 'bottom-left)
+                        (= (nth 0 edges) (nth 0 this-edges))
+                        (= (nth 3 edges) (nth 3 this-edges))))
+           (throw 'found window))))))))
+ 
+ (defun window--pop-up-window (buffer frame user system)
+   "Pop up a new window for BUFFER on FRAME.
+ FRAME nil means the selected frame.  If FRAME cannot be split,
+ try to split a window on the last nonminibuffer frame instead.
+ 
+ USER, if not nil and not t, is a list specifying the user's
+ preferences for finding the window to split.  For a list of
+ supported values see the variable `pop-up-windows-values'.  The
+ special value t means to use SYSTEM, if applicable, instead.  For
+ the meaning of all values, consult the documentation of the
+ variable `pop-up-windows'.  If USER equals t, this means to use
+ the list `(t largest lru)' instead.
+ 
+ SYSTEM, provided it is any of `pop-up-windows-values',
+ substitutes an occurence of t within USER."
+   ;; FRAME nil means use the selected frame.
+   (setq frame (or frame (selected-frame)))
+   ;; But make sure our frame is not a minibuffer frame.
+   (when (window-minibuffer-p (frame-selected-window frame))
+     (setq frame (last-nonminibuffer-frame)))
+   (unless (and (frame-parameter frame 'unsplittable)
+              ;; If the frame cannot be split have a look at
+              ;; `last-nonminibuffer-frame'.
+              (or (not (eq frame (selected-frame)))
+                  (not (setq frame (last-nonminibuffer-frame)))
+                  (not (window--frame-usable-p frame))
+                  (frame-parameter frame 'unsplittable)))
+     (when (eq user t)
+       ;; USER t means use '(t largest lru) instead.
+       (setq user '(t largest lru)))
+     (let* ((this-window (frame-selected-window frame))
+          (windows (window-list frame 'nomini this-window))
+          (probe (car user))
+          window window-to-use)
+       ;; While we have not yet found a usable window, scan `windows' for
+       ;; a windows satisfying `probe'.
+       (while (and (not window-to-use) windows probe)
+       (setq window
+             (if (eq probe t)
+                 ;; SYSTEM overrides t in USER.
+                 (when (memq system pop-up-windows-values)
+                   ;; SYSTEM is a valid value, so use it.
+                   (window--probe-windows frame windows system))
+               (window--probe-windows frame windows probe)))
+       (when window
+         (setq window-to-use (window--try-to-split-window window)))
+       (unless window-to-use
+         ;; Don't consider `window' again.
+         (setq windows (remove window windows))
+         (setq user (cdr user))
+         (setq probe (car user))))
+       (when window-to-use
+       (window--display-buffer-2 buffer window-to-use)))))
+ 
  (defun window--display-buffer-1 (window)
    "Raise the frame containing WINDOW.
  Do not raise the selected frame.  Return WINDOW."
***************
*** 987,993 ****
  
  Optional argument NOT-THIS-WINDOW non-nil means display the
  buffer in a window other than the selected one, even if it is
! already displayed in the selected window.
  
  Optional argument FRAME specifies which frames to investigate
  when the specified buffer is already displayed.  If the buffer is
--- 1124,1135 ----
  
  Optional argument NOT-THIS-WINDOW non-nil means display the
  buffer in a window other than the selected one, even if it is
! already displayed in the selected window.  As a special case, if
! NOT-THIS-WINDOW is any of the values in `pop-up-windows-values',
! this means to use that for finding a window to split.  The
! documentation of the variable `pop-up-windows' contains an
! explanation of what these values mean as well as when such a
! value is applied.
  
  Optional argument FRAME specifies which frames to investigate
  when the specified buffer is already displayed.  If the buffer is
***************
*** 1009,1017 ****
  consider all visible or iconified frames."
    (interactive "BDisplay buffer:\nP")
    (let* ((can-use-selected-window
!         ;; The selected window is usable unless either NOT-THIS-WINDOW
!         ;; is non-nil, it is dedicated to its buffer, or it is the
!         ;; `minibuffer-window'.
          (not (or not-this-window
                   (window-dedicated-p (selected-window))
                   (window-minibuffer-p))))
--- 1151,1159 ----
  consider all visible or iconified frames."
    (interactive "BDisplay buffer:\nP")
    (let* ((can-use-selected-window
!         ;; The selected window is usable unless either
!         ;; NOT-THIS-WINDOW is non-nil, it is dedicated to its
!         ;; buffer, or it is the `minibuffer-window'.
          (not (or not-this-window
                   (window-dedicated-p (selected-window))
                   (window-minibuffer-p))))
***************
*** 1039,1046 ****
        (funcall display-buffer-function buffer not-this-window))
       ((and (not not-this-window)
           (eq (window-buffer (selected-window)) buffer))
!       ;; The selected window already displays BUFFER and
!       ;; `not-this-window' is nil, so use it.
        (window--display-buffer-1 (selected-window)))
       ((and can-use-selected-window (same-window-p name-of-buffer))
        ;; If the buffer's name tells us to use the selected window do so.
--- 1181,1188 ----
        (funcall display-buffer-function buffer not-this-window))
       ((and (not not-this-window)
           (eq (window-buffer (selected-window)) buffer))
!       ;; The selected window already displays BUFFER and NOT-THIS-WINDOW
!       ;; is nil, so use it.
        (window--display-buffer-1 (selected-window)))
       ((and can-use-selected-window (same-window-p name-of-buffer))
        ;; If the buffer's name tells us to use the selected window do so.
***************
*** 1073,1093 ****
        (window--display-buffer-2
         buffer (frame-selected-window (funcall pop-up-frame-function))))
       ((and pop-up-windows
!          ;; Make a new window.
!          (or (not (frame-parameter frame-to-use 'unsplittable))
!              ;; If the selected frame cannot be split look at
!              ;; `last-nonminibuffer-frame'.
!              (and (eq frame-to-use (selected-frame))
!                   (setq frame-to-use (last-nonminibuffer-frame))
!                   (window--frame-usable-p frame-to-use)
!                   (not (frame-parameter frame-to-use 'unsplittable))))
!          ;; Attempt to split largest or least recently used window.
!          (setq window-to-use
!                (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)))
       ((let ((window-to-undedicate
             ;; When NOT-THIS-WINDOW is non-nil, temporarily dedicate
             ;; the selected window to its buffer, to avoid that some of
--- 1215,1222 ----
        (window--display-buffer-2
         buffer (frame-selected-window (funcall pop-up-frame-function))))
       ((and pop-up-windows
!          (window--pop-up-window
!           buffer frame-to-use pop-up-windows not-this-window)))
       ((let ((window-to-undedicate
             ;; When NOT-THIS-WINDOW is non-nil, temporarily dedicate
             ;; the selected window to its buffer, to avoid that some of
***************
*** 1129,1134 ****
--- 1258,1269 ----
  already visible in the selected window, and ignore
  `same-window-regexps' and `same-window-buffer-names'.
  
+ As a special case, if OTHER-WINDOW is any of the values in
+ `pop-up-windows-values', this means to use that value for finding
+ a suitable window to split.  The documentation of the variable
+ `pop-up-windows' contains an explanation of what these values
+ mean as well as when such a value is applied.
+ 
  If the window to show BUFFER-OR-NAME is not on the selected
  frame, raise that window's frame and give it input focus.
  

reply via email to

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