GNU bug report logs - #1806
dired-pop-to-buffer in wrong place

Previous Next

Package: emacs;

Reported by: Juri Linkov <juri <at> jurta.org>

Date: Tue, 6 Jan 2009 15:40:04 UTC

Severity: normal

Done: Juri Linkov <juri <at> jurta.org>

Bug is archived. No further changes may be made.

Full log


Message #230 received at 1806 <at> emacsbugs.donarmstrong.com (full text, mbox):

From: martin rudalics <rudalics <at> gmx.at>
To: Stefan Monnier <monnier <at> iro.umontreal.ca>
Cc: Juri Linkov <juri <at> jurta.org>, 1806 <at> debbugs.gnu.org
Subject: Re: bug#1806: dired-pop-to-buffer in wrong place
Date: Tue, 20 Jan 2009 16:59:17 +0100
[Message part 1 (text/plain, inline)]
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.diff (text/plain, inline)]
*** 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.
  

This bug report was last modified 12 years and 236 days ago.

Previous Next


GNU bug tracking system
Copyright (C) 1999 Darren O. Benham, 1997,2003 nCipher Corporation Ltd, 1994-97 Ian Jackson.