all messages for Emacs-related lists mirrored at yhetil.org
 help / color / mirror / code / Atom feed
From: martin rudalics <rudalics@gmx.at>
To: Stefan Monnier <monnier@iro.umontreal.ca>
Cc: 3142@emacsbugs.donarmstrong.com
Subject: bug#3142: 23.0.92; split-window-prefered-function should be able to use split-window-horizontally/split-window-vertically
Date: Tue, 05 May 2009 09:02:31 +0200	[thread overview]
Message-ID: <49FFE487.5000106@gmx.at> (raw)
In-Reply-To: <jwv3abrwkfl.fsf-monnier+emacsbugreports@gnu.org>

[-- Attachment #1: Type: text/plain, Size: 1322 bytes --]

 >> Remains the question whether `split-window-preferred-function' should
 >> always operate on the selected window or have a window argument.  AFAICT
 >> nothing speaks for the window argument but the fact that people may have
 >> customized this already.  Omitting the window argument would allow users
 >> to put `split-window-vertically' directly as value of
 >> `split-window-preferred-function' without having to delve any deeper.
 >
 > I agree it would make sense to operate on the selected-window rather
 > than pass an explicit window argument.

Unfortunately, this will create the following problem: Suppose a user
wants to

(1) always split the selected window instead of the largest or LRU one,

(2) never split the selected window (as Drew points out in another
thread), or

(3) base her decision on whether a window shall be split on which window
was selected at the time `display-buffer' was called.

In any of these cases calling `split-window-preferred-function' with the
window to split selected will obscure the identity of the selected
window and make the desired customization impossible.  So we should
probably leave the current behavior alone.  The attached patch just
makes sure that `split-window-preferred-function' gets always called and
provides the standard options requested earlier.

martin

[-- Attachment #2: window.el.diff --]
[-- Type: text/plain, Size: 8685 bytes --]

*** window.el.~1.179.~	2009-04-29 07:50:42.078125000 +0200
--- window.el	2009-05-05 08:46:08.390625000 +0200
***************
*** 794,832 ****
    :type 'boolean
    :group 'windows)
  
  (defcustom split-height-threshold 80
    "Minimum height of window to be split vertically.
! If the value is a number, `display-buffer' can split a window
! only if it has at least as many lines.  If the value is nil,
! `display-buffer' cannot split a window vertically.
! 
! If the window is the only window on its frame, `display-buffer'
! can split it regardless of this value."
    :type '(choice (const nil) (number :tag "lines"))
    :version "23.1"
    :group 'windows)
  
  (defcustom split-width-threshold 160
    "Minimum width of window to be split horizontally.
! If the value is a number, `display-buffer' can split a window
! only if it has at least as many columns.  If the value is nil,
! `display-buffer' cannot split a window horizontally."
    :type '(choice (const nil) (number :tag "columns"))
    :version "23.1"
    :group 'windows)
  
- (defcustom split-window-preferred-function nil
-   "Function used by `display-buffer' to split windows.
- If non-nil, a function called with a window as single argument
- supposed to split that window and return the new window.  If the
- function returns nil the window is not split.
- 
- If nil, `display-buffer' will split the window respecting the
- values of `split-height-threshold' and `split-width-threshold'."
-   :type '(choice (const nil) (function :tag "Function"))
-   :version "23.1"
-   :group 'windows)
- 
  (defun window--splittable-p (window &optional horizontal)
    "Return non-nil if WINDOW can be split evenly.
  Optional argument HORIZONTAL non-nil means check whether WINDOW
--- 794,865 ----
    :type 'boolean
    :group 'windows)
  
+ (defcustom split-window-preferred-function 'split-window-sensibly
+   "Function called by `display-buffer' to split a window.
+ The function is called with a window as single argument and is
+ supposed to either split that window and return the new window or
+ return nil if the window can (or shall) not be split.
+ 
+ The default is to split the window \"sensibly\".  This calls the
+ function `split-window-sensibly' which tries to split the window
+ in a way which seems most suitable.  A second standard option is
+ \"vertically\" to split the window into two windows one above the
+ other.  The third standard option is \"horizontally\" which tries
+ to split the window into two windows side by side.  All three
+ standard options examine the values of `split-height-threshold'
+ and/or `split-width-threshold' before they apply the split.
+ 
+ If you set this to any other function, bear in mind that it may
+ be called two times: The argument of the first call is the
+ largest window on its frame.  If that call fails to provide a
+ suitable window, it gets called again with the least recently
+ used window as argument.  If neither of these calls produces a
+ suitable window, `display-buffer' will use an existing one to
+ display its buffer.
+ 
+ The window selected at the time `display-buffer' was invoked is
+ selected when `split-window-preferred-function' gets called.
+ Hence you can compare WINDOW with the value of `selected-window'
+ if you always want to split the selected window instead of WINDOW
+ or if you never want to split the currently selected window."
+   :type '(choice
+ 	  (const :tag "sensibly" split-window-sensibly)
+ 	  (const :tag "vertically"
+ 		 (lambda (window)
+ 		   (when (window--splittable-p window)
+ 		     (with-selected-window window
+ 		       (split-window-vertically)))))
+ 	  (const :tag "horizontally"
+ 		 (lambda (window)
+ 		   (when (window--splittable-p window t)
+ 		     (with-selected-window window
+ 		       (split-window-horizontally)))))
+ 	  (function :tag "Function"))
+   :version "23.1"
+   :group 'windows)
+ 
  (defcustom split-height-threshold 80
    "Minimum height of window to be split vertically.
! If the value is a number, the standard functions specified for
! `split-window-preferred-function' are allowed to split a window
! vertically only if it has at least this many lines.  If the value
! is nil, they do not split a window vertically.  If a window is
! the only window on its frame, they can split it disregarding the
! value of this variable."
    :type '(choice (const nil) (number :tag "lines"))
    :version "23.1"
    :group 'windows)
  
  (defcustom split-width-threshold 160
    "Minimum width of window to be split horizontally.
! If the value is a number, the standard functions specified for
! `split-window-preferred-function' are allowed to split a window
! horizontally only if it has at least this many columns.  If the
! value is nil, they do not split a window horizontally."
    :type '(choice (const nil) (number :tag "columns"))
    :version "23.1"
    :group 'windows)
  
  (defun window--splittable-p (window &optional horizontal)
    "Return non-nil if WINDOW can be split evenly.
  Optional argument HORIZONTAL non-nil means check whether WINDOW
***************
*** 882,911 ****
  		      (* 2 (max window-min-height
  				(if mode-line-format 2 1))))))))))
  
  (defun window--try-to-split-window (window)
!   "Split WINDOW if it is splittable.
! See `window--splittable-p' for how to determine whether a window
! is splittable.  If WINDOW can be split, return the value returned
! by `split-window' (or `split-window-preferred-function')."
!   (when (and (window-live-p window)
! 	     (not (frame-parameter (window-frame window) 'unsplittable)))
!     (if (functionp split-window-preferred-function)
! 	;; `split-window-preferred-function' is specified, so use it.
! 	(funcall split-window-preferred-function window)
!       (or (and (window--splittable-p window)
! 	       ;; Split window vertically.
! 	       (split-window window))
! 	  (and (window--splittable-p window t)
! 	       ;; Split window horizontally.
! 	       (split-window window nil t))
! 	  (and (eq window (frame-root-window (window-frame window)))
! 	       (not (window-minibuffer-p window))
! 	       ;; If WINDOW is the only window on its frame and not the
! 	       ;; minibuffer window, attempt to split it vertically
! 	       ;; disregarding the value of `split-height-threshold'.
! 	       (let ((split-height-threshold 0))
! 		 (and (window--splittable-p window)
! 		      (split-window window))))))))
  
  (defun window--frame-usable-p (frame)
    "Return FRAME if it can be used to display a buffer."
--- 915,964 ----
  		      (* 2 (max window-min-height
  				(if mode-line-format 2 1))))))))))
  
+ (defun split-window-sensibly (window)
+   "Split WINDOW \"sensibly\".
+ If WINDOW has at least `split-height-threshold' lines, split it
+ into two windows one above the other and return the lower one.
+ Otherwise, if WINDOW is at least `split-width-threshold' columns
+ wide, split it into two windows side by side and return the one
+ on the right.  If this does not produce a suitable window either
+ and WINDOW is the only window on its frame, try to split WINDOW
+ vertically and return the lower one.  Return nil if that fails as
+ well.
+ 
+ The default value of `split-window-preferred-function' is set to
+ this function."
+   (or (and (window--splittable-p window)
+ 	   ;; Split window vertically.
+ 	   (with-selected-window window
+ 	     (split-window-vertically)))
+       (and (window--splittable-p window t)
+ 	   ;; Split window horizontally.
+ 	   (with-selected-window window
+ 	     (split-window-horizontally)))
+       (and (eq window (frame-root-window (window-frame window)))
+ 	   (not (window-minibuffer-p window))
+ 	   ;; If WINDOW is the only window on its frame and is not the
+ 	   ;; minibuffer window, try to split it vertically disregarding
+ 	   ;; the value of `split-height-threshold'.
+ 	   (let ((split-height-threshold 0))
+ 	     (when (window--splittable-p window)
+ 	       (with-selected-window window
+ 		 (split-window-vertically)))))))
+ 
  (defun window--try-to-split-window (window)
!   "Split WINDOW if it can be split.
! Return value returned by `split-window-preferred-function' if it
! represents a live window, nil otherwise."
!       (and (window-live-p window)
! 	   (not (frame-parameter (window-frame window) 'unsplittable))
! 	   (let ((new-window
! 		  ;; Since `split-window-preferred-function' might
! 		  ;; throw an error use `condition-case'.
! 		  (condition-case nil
! 		      (funcall split-window-preferred-function window)
! 		    (error nil))))
! 	     (and (window-live-p new-window) new-window))))
  
  (defun window--frame-usable-p (frame)
    "Return FRAME if it can be used to display a buffer."

  parent reply	other threads:[~2009-05-05  7:02 UTC|newest]

Thread overview: 26+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2009-04-28  1:16 bug#3142: 23.0.92; split-window-prefered-function should be able to use split-window-horizontally/split-window-vertically Jared Finder
2009-04-28  6:29 ` martin rudalics
2009-04-28 17:21   ` Jared Finder
2009-04-28 22:48     ` Juri Linkov
2009-04-29  1:29       ` Stefan Monnier
2009-04-29  7:13       ` martin rudalics
2009-04-29  9:59         ` Juri Linkov
2009-04-29 12:40           ` martin rudalics
2009-04-29 13:50         ` bug#3142: 23.0.92; split-window-prefered-function should be able to usesplit-window-horizontally/split-window-vertically Drew Adams
2009-04-30  9:05           ` martin rudalics
2011-10-05 18:49             ` Glenn Morris
2011-10-05 22:11               ` Stefan Monnier
2009-04-29 15:26         ` bug#3142: 23.0.92; split-window-prefered-function should be able to use split-window-horizontally/split-window-vertically Stefan Monnier
2009-04-30  8:54           ` martin rudalics
2009-04-30 11:47             ` Juri Linkov
2009-04-30 18:20               ` Stefan Monnier
2009-05-01 11:54                 ` Juri Linkov
2009-05-01  8:33               ` martin rudalics
2009-05-01 11:52                 ` Juri Linkov
2009-05-02  8:40                   ` martin rudalics
2009-05-05  7:02           ` martin rudalics [this message]
2009-05-05 11:03             ` Juri Linkov
2009-05-06  1:41             ` Stefan Monnier
2009-05-06 16:21               ` martin rudalics
2009-05-06 19:04                 ` Stefan Monnier
2009-05-07  9:36                   ` martin rudalics

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=49FFE487.5000106@gmx.at \
    --to=rudalics@gmx.at \
    --cc=3142@emacsbugs.donarmstrong.com \
    --cc=monnier@iro.umontreal.ca \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
Code repositories for project(s) associated with this external index

	https://git.savannah.gnu.org/cgit/emacs.git
	https://git.savannah.gnu.org/cgit/emacs/org-mode.git

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.