unofficial mirror of bug-gnu-emacs@gnu.org 
 help / color / mirror / code / Atom feed
* bug#3142: 23.0.92; split-window-prefered-function should be able to use split-window-horizontally/split-window-vertically
@ 2009-04-28  1:16 Jared Finder
  2009-04-28  6:29 ` martin rudalics
  0 siblings, 1 reply; 26+ messages in thread
From: Jared Finder @ 2009-04-28  1:16 UTC (permalink / raw)
  To: emacs-pretest-bug@gnu.org

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

I would expect that split-window-preferred-function would accept split-window-horizontally and split-window-vertically.  At the very least, there should be an easy way to set this to "always split vertically", "always split horizontally", and "intelligently split".



  -- MJF



In GNU Emacs 23.0.92.1 (i386-mingw-nt6.0.6001)

 of 2009-03-30 on SOFT-MJASON

Windowing system distributor `Microsoft Corp.', version 6.0.6001

configured using `configure --with-gcc (3.4)'



Important settings:

  value of $LC_ALL: nil

  value of $LC_COLLATE: nil

  value of $LC_CTYPE: nil

  value of $LC_MESSAGES: nil

  value of $LC_MONETARY: nil

  value of $LC_NUMERIC: nil

  value of $LC_TIME: nil

  value of $LANG: ENU

  value of $XMODIFIERS: nil

  locale-coding-system: cp1252

  default-enable-multibyte-characters: t



Major mode: Custom/lw



Minor modes in effect:

  global-balanced-mode: t

  balanced-mode: t

  hrule-mode: t

  global-hi-lock-mode: t

  hi-lock-mode: t

  c-subword-mode: t

  url-handler-mode: t

  show-paren-mode: t

  recentf-mode: t

  global-reveal-mode: t

  reveal-mode: t

  global-c-subword-mode: t

  shell-dirtrack-mode: t

  cua-mode: t

  tooltip-mode: t

  mouse-wheel-mode: t

  menu-bar-mode: t

  file-name-shadow-mode: t

  global-font-lock-mode: t

  font-lock-mode: t

  blink-cursor-mode: t

  global-auto-composition-mode: t

  auto-composition-mode: t

  auto-encryption-mode: t

  auto-compression-mode: t

  column-number-mode: t

  line-number-mode: t

  transient-mark-mode: t



Recent input:

<help-echo> <select-window> <switch-frame> <switch-frame>

<switch-frame> <switch-frame> <select-window> <down-mouse-1>

<mouse-movement> <mouse-1> <apps> <up> <up> c u s t

o m i z e SPC v a r <tab> <return> <up> s p l i t SPC

w i n <tab> p <tab> <return> <help-echo> <help-echo>

<help-echo> <help-echo> <down-mouse-1> <mouse-2> <help-echo>

<wheel-down> <double-wheel-down> <wheel-down> <down-mouse-1>

<drag-mouse-1> <down-mouse-1> <mouse-1> <help-echo>

<down-mouse-1> <mouse-1> <help-echo> <down-mouse-1>

<mouse-1> <down-mouse-1> <mouse-1> <help-echo> <help-echo>

<wheel-down> <double-wheel-down> <wheel-down> <double-wheel-down>

<triple-wheel-down> <wheel-down> <double-wheel-down>

<wheel-down> <double-wheel-down> <wheel-down> <double-wheel-down>

<wheel-down> <wheel-down> <help-echo> <down-mouse-1>

<mouse-1> <help-echo> <wheel-down> <double-wheel-down>

<triple-wheel-down> <wheel-down> <wheel-down> <wheel-down>

<wheel-up> <wheel-up> <wheel-up> <help-echo> <help-echo>

<down-mouse-1> <mouse-1> <help-echo> C-x o C-x o C-h

f <return> C-x o C-x o <left> <S-end> <home> <S-end>

n i l <help-echo> <help-echo> <down-mouse-1> <help-echo>

<down-mouse-1> <help-echo> <help-echo> <down-mouse-1>

<down-mouse-1> <mouse-1> C-h f s p l i t SPC w i n

<tab> SPC v <tab> <return> <help-echo> <help-echo>

<wheel-down> <wheel-down> <wheel-down> <double-wheel-down>

<triple-wheel-down> <wheel-up> <double-wheel-up> <triple-wheel-up>

<triple-wheel-up> <triple-wheel-up> <select-window>

<help-echo> C-h f s l <backspace> p l i t SPC w i n

<tab> <return> <down-mouse-1> <help-echo> <down-mouse-1>

<mouse-1> <double-down-mouse-1> <double-mouse-1> s

p l i t - w i n <C-tab> C-x C-s y C-x 1 C-x 2 C-x 1

C-x 4 b <return> C-x 0 <down> <down> <down> <down>

<down> <down> <up> <up> <up> <up> <up> <help-echo>

<C-f7> <return> <help-echo> <up> <up> C-x 1 <up> <help-echo>

<help-echo> <help-echo> <help-echo> <help-echo> <help-echo>

<help-echo> <help-echo> <help-echo> <help-echo> <help-echo>

<help-echo> <help-echo> <help-echo> <help-echo> <help-echo>

<help-echo> <help-echo> <help-echo> <help-echo> <help-echo>

<help-echo> <help-echo> <help-echo> <help-echo> <help-echo>

<help-echo> <help-echo> <help-echo> <help-echo> <help-echo>

<help-echo> <help-echo> <help-echo> <help-echo> <help-echo>

<help-echo> <help-echo> <help-echo> <help-echo> <menu-bar>

<help-menu> <send-emacs-bug-report>



Recent messages:

split-window-vertically: Window height 1 too small (after splitting)

custom-variable-set: Invalid function: nil

To install your edits, invoke [State] and choose the Set operation

Type "q" to delete this window, <next> to scroll help.

To install your edits, invoke [State] and choose the Set operation

Save all settings in this buffer? (y or n)

Loading vc-cvs...done

Saving file c:/Users/jfinder/Desktop/.emacs.d/custom.el...

Wrote c:/Users/jfinder/Desktop/.emacs.d/custom.el

(No files need saving)

[-- Attachment #2: Type: text/html, Size: 15998 bytes --]

^ permalink raw reply	[flat|nested] 26+ messages in thread

* bug#3142: 23.0.92; split-window-prefered-function should be able to use split-window-horizontally/split-window-vertically
  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
  0 siblings, 1 reply; 26+ messages in thread
From: martin rudalics @ 2009-04-28  6:29 UTC (permalink / raw)
  To: Jared Finder; +Cc: 3142

 > I would expect that split-window-preferred-function would accept
 > split-window-horizontally and split-window-vertically.

`split-window-preferred-function', if non-nil, must be a function called
with a WINDOW as single argument.  `split-window-vertically' and
`split-window-horizontally' are functions that split the selected window
and take a SIZE argument.  Hence, when you set
`split-window-preferred-function' to `split-window-vertically' as you
did you will get a

split-window-vertically: Window height 1 too small (after splitting)

error because you call `split-window-vertically' with a window as
argument, and `prefix-numeric-value' when called with a window as
argument returns 1, a SIZE argument disliked by `split-window'.
Sounds contrived, but I don't have a better explanation.

If you really need `split-window-preferred-function' use
`split-window-vertically' you have to write a wrapper like

(defun my-split-window-function (window)
   (with-selected-window window
     (split-window-vertically)))

 > At the very
 > least, there should be an easy way to set this to "always split
 > vertically", "always split horizontally", and "intelligently split".

Setting `split-width-threshold' nil for "always split vertically" and
`split-height-threshold' nil for "always split horizontally" should
accomplish that.  Can't you use these directly?

martin







^ permalink raw reply	[flat|nested] 26+ messages in thread

* bug#3142: 23.0.92; split-window-prefered-function should be able to use split-window-horizontally/split-window-vertically
  2009-04-28  6:29 ` martin rudalics
@ 2009-04-28 17:21   ` Jared Finder
  2009-04-28 22:48     ` Juri Linkov
  0 siblings, 1 reply; 26+ messages in thread
From: Jared Finder @ 2009-04-28 17:21 UTC (permalink / raw)
  To: martin rudalics; +Cc: 3142@emacsbugs.donarmstrong.com

That's not obvious!  I like the idea of the split window thresholds, but it needs to be a lot more obvious how to use them.  What's wrong with my suggestion to change the customize interface to have two more options "Always split vertical" and "Always split horizontal" that calls the appropriate functions?

  -- MJF

-----Original Message-----
From: martin rudalics [mailto:rudalics@gmx.at] 
Sent: Monday, April 27, 2009 11:30 PM
To: Jared Finder
Cc: 3142@emacsbugs.donarmstrong.com
Subject: Re: bug#3142: 23.0.92; split-window-prefered-function should be able to use split-window-horizontally/split-window-vertically

 > I would expect that split-window-preferred-function would accept
 > split-window-horizontally and split-window-vertically.

`split-window-preferred-function', if non-nil, must be a function called
with a WINDOW as single argument.  `split-window-vertically' and
`split-window-horizontally' are functions that split the selected window
and take a SIZE argument.  Hence, when you set
`split-window-preferred-function' to `split-window-vertically' as you
did you will get a

split-window-vertically: Window height 1 too small (after splitting)

error because you call `split-window-vertically' with a window as
argument, and `prefix-numeric-value' when called with a window as
argument returns 1, a SIZE argument disliked by `split-window'.
Sounds contrived, but I don't have a better explanation.

If you really need `split-window-preferred-function' use
`split-window-vertically' you have to write a wrapper like

(defun my-split-window-function (window)
   (with-selected-window window
     (split-window-vertically)))

 > At the very
 > least, there should be an easy way to set this to "always split
 > vertically", "always split horizontally", and "intelligently split".

Setting `split-width-threshold' nil for "always split vertically" and
`split-height-threshold' nil for "always split horizontally" should
accomplish that.  Can't you use these directly?

martin







^ permalink raw reply	[flat|nested] 26+ messages in thread

* bug#3142: 23.0.92; split-window-prefered-function should be able to use split-window-horizontally/split-window-vertically
  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
  0 siblings, 2 replies; 26+ messages in thread
From: Juri Linkov @ 2009-04-28 22:48 UTC (permalink / raw)
  To: Jared Finder; +Cc: 3142

> That's not obvious!  I like the idea of the split window thresholds,
> but it needs to be a lot more obvious how to use them.  What's wrong
> with my suggestion to change the customize interface to have two more
> options "Always split vertical" and "Always split horizontal" that
> calls the appropriate functions?

I remember we once considered creating a default function with
"intelligently splitting" logic (IOW, moving the `else' part of `if'
in `window--try-to-split-window' to a separate function)
and setting the default value of `split-window-preferred-function'
to the name of this function.

This will allow defining three const values in defcustom:
- the default function name;
- vertically splitting function;
- horizontally splitting function;

- and user-defined function's name.

-- 
Juri Linkov
http://www.jurta.org/emacs/






^ permalink raw reply	[flat|nested] 26+ messages in thread

* bug#3142: 23.0.92; split-window-prefered-function should be able to use split-window-horizontally/split-window-vertically
  2009-04-28 22:48     ` Juri Linkov
@ 2009-04-29  1:29       ` Stefan Monnier
  2009-04-29  7:13       ` martin rudalics
  1 sibling, 0 replies; 26+ messages in thread
From: Stefan Monnier @ 2009-04-29  1:29 UTC (permalink / raw)
  To: Juri Linkov; +Cc: 3142, Jared Finder

> I remember we once considered creating a default function with
> "intelligently splitting" logic (IOW, moving the `else' part of `if'
> in `window--try-to-split-window' to a separate function)
> and setting the default value of `split-window-preferred-function'
> to the name of this function.

Indeed.  IMO, `foo-function' should not accept nil as value and
should be unconditionally called.


        Stefan






^ permalink raw reply	[flat|nested] 26+ messages in thread

* bug#3142: 23.0.92; split-window-prefered-function should be able to use split-window-horizontally/split-window-vertically
  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
                           ` (2 more replies)
  1 sibling, 3 replies; 26+ messages in thread
From: martin rudalics @ 2009-04-29  7:13 UTC (permalink / raw)
  To: Juri Linkov; +Cc: Jared Finder, 3142

 >> That's not obvious!  I like the idea of the split window thresholds,
 >> but it needs to be a lot more obvious how to use them.  What's wrong
 >> with my suggestion to change the customize interface to have two more
 >> options "Always split vertical" and "Always split horizontal" that
 >> calls the appropriate functions?
 >
 > I remember we once considered creating a default function with
 > "intelligently splitting" logic (IOW, moving the `else' part of `if'
 > in `window--try-to-split-window' to a separate function)
 > and setting the default value of `split-window-preferred-function'
 > to the name of this function.
 >
 > This will allow defining three const values in defcustom:
 > - the default function name;
 > - vertically splitting function;
 > - horizontally splitting function;
 >
 > - and user-defined function's name.

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.

martin







^ permalink raw reply	[flat|nested] 26+ messages in thread

* bug#3142: 23.0.92; split-window-prefered-function should be able to use split-window-horizontally/split-window-vertically
  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-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
  2 siblings, 1 reply; 26+ messages in thread
From: Juri Linkov @ 2009-04-29  9:59 UTC (permalink / raw)
  To: martin rudalics; +Cc: Jared Finder, 3142

> 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.

How about adding two wrapper functions?

  (split-window-preferred-vertically &optional window)
  that calls split-window-vertically

  (split-window-preferred-horizontally &optional window)
  that calls split-window-horizontally

-- 
Juri Linkov
http://www.jurta.org/emacs/






^ permalink raw reply	[flat|nested] 26+ messages in thread

* bug#3142: 23.0.92; split-window-prefered-function should be able to use split-window-horizontally/split-window-vertically
  2009-04-29  9:59         ` Juri Linkov
@ 2009-04-29 12:40           ` martin rudalics
  0 siblings, 0 replies; 26+ messages in thread
From: martin rudalics @ 2009-04-29 12:40 UTC (permalink / raw)
  To: Juri Linkov; +Cc: Jared Finder, 3142

 > How about adding two wrapper functions?
 >
 >   (split-window-preferred-vertically &optional window)
 >   that calls split-window-vertically
 >
 >   (split-window-preferred-horizontally &optional window)
 >   that calls split-window-horizontally

I can't really comment that because the current behavior seems already
confusing enough.  At least that's the impression I got from Jared's
mail.  Personally, I'm always confused by -window (-buffer) functions
that do not have a window (or buffer) as first argument :-(

martin






^ permalink raw reply	[flat|nested] 26+ messages in thread

* bug#3142: 23.0.92; split-window-prefered-function should be able to usesplit-window-horizontally/split-window-vertically
  2009-04-29  7:13       ` martin rudalics
  2009-04-29  9:59         ` Juri Linkov
@ 2009-04-29 13:50         ` Drew Adams
  2009-04-30  9:05           ` martin rudalics
  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
  2 siblings, 1 reply; 26+ messages in thread
From: Drew Adams @ 2009-04-29 13:50 UTC (permalink / raw)
  To: 'martin rudalics', 3142, 'Juri Linkov'
  Cc: 'Jared Finder'

> 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 haven't followed this thread, and I'm not familiar with the commands in
question.

But if you have a choice between defining foo to be unary or nullary, consider
defining it with &optional: (defun foo (&optional window)...)

That allows use of foo as an object method for windows. That is, given a window,
`foo' is one of the functions that can be applied to it. If defined as nullary,
this is not possible.







^ permalink raw reply	[flat|nested] 26+ messages in thread

* bug#3142: 23.0.92; split-window-prefered-function should be able to use split-window-horizontally/split-window-vertically
  2009-04-29  7:13       ` martin rudalics
  2009-04-29  9:59         ` Juri Linkov
  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-29 15:26         ` Stefan Monnier
  2009-04-30  8:54           ` martin rudalics
  2009-05-05  7:02           ` martin rudalics
  2 siblings, 2 replies; 26+ messages in thread
From: Stefan Monnier @ 2009-04-29 15:26 UTC (permalink / raw)
  To: martin rudalics; +Cc: 3142, Jared Finder

> 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.


        Stefan








^ permalink raw reply	[flat|nested] 26+ messages in thread

* bug#3142: 23.0.92; split-window-prefered-function should be able to use split-window-horizontally/split-window-vertically
  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-05-05  7:02           ` martin rudalics
  1 sibling, 1 reply; 26+ messages in thread
From: martin rudalics @ 2009-04-30  8:54 UTC (permalink / raw)
  To: Stefan Monnier; +Cc: 3142, Jared Finder

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

 > I agree it would make sense to operate on the selected-window rather
 > than pass an explicit window argument.

Please have a look at the attached patch.

martin

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

*** window.el.~1.179.~	2009-04-29 07:50:42.078125000 +0200
--- window.el	2009-04-30 10:48:18.875000000 +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,828 ----
    :type 'boolean
    :group 'windows)
  
+ (defcustom split-window-preferred-function 'split-selected-window
+   "Function called by `display-buffer' to split a window.
+ The window that shall be split is selected when this function is
+ called.  The function is supposed to either return the new window
+ or nil if the window can (or shall) not be split."
+   :type '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, `split-selected-window' splits a window
! vertically only if it has at least as many lines.  If the value
! is nil, it does not split a window vertically.  If a window is
! the only window on its frame, it can be split regardless of 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, `split-selected-window' splits a window
! only if it has at least as many columns.  If the value is nil, it
! does 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."
--- 878,913 ----
  		      (* 2 (max window-min-height
  				(if mode-line-format 2 1))))))))))
  
+ (defun split-selected-window ()
+   "Split selected window.
+ Return the new window if the selected window can be split either
+ vertically or horizontally.  If the selected window is the only
+ window on its frame try to split it disregarding the value of
+ `split-height-threshold'.  Return nil if the selected window
+ can't be split.  This function provides the default value for
+ `split-window-preferred-function'."
+   (or (and (window--splittable-p (selected-window))
+ 	   ;; Split window vertically.
+ 	   (split-window))
+       (and (window--splittable-p (selected-window) t)
+ 	   ;; Split window horizontally.
+ 	   (split-window nil nil t))
+       (and (eq (selected-window) (frame-root-window))
+ 	   (not (window-minibuffer-p))
+ 	   ;; If the selected 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))
+ 	     (and (window--splittable-p (selected-window))
+ 		  (split-window))))))
+ 
  (defun window--try-to-split-window (window)
!   "Split WINDOW if it can be split.
! Return value returned by `split-window-preferred-function'."
!   (and (window-live-p window)
!        (not (frame-parameter (window-frame window) 'unsplittable))
!        (with-selected-window window
! 	 (funcall split-window-preferred-function))))
  
  (defun window--frame-usable-p (frame)
    "Return FRAME if it can be used to display a buffer."

^ permalink raw reply	[flat|nested] 26+ messages in thread

* bug#3142: 23.0.92; split-window-prefered-function should be able to usesplit-window-horizontally/split-window-vertically
  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
  0 siblings, 1 reply; 26+ messages in thread
From: martin rudalics @ 2009-04-30  9:05 UTC (permalink / raw)
  To: Drew Adams; +Cc: 3142, 'Jared Finder'

 > But if you have a choice between defining foo to be unary or nullary, consider
 > defining it with &optional: (defun foo (&optional window)...)
 >
 > That allows use of foo as an object method for windows. That is, given a window,
 > `foo' is one of the functions that can be applied to it. If defined as nullary,
 > this is not possible.

Yes.  But I don't want to burden customizers with the problem in the
first place.  For example, Jared wants to use `split-window-vertically'
as value for this variable and that function has an optional SIZE
argument but no WINDOW argument.

martin







^ permalink raw reply	[flat|nested] 26+ messages in thread

* bug#3142: 23.0.92; split-window-prefered-function should be able to use split-window-horizontally/split-window-vertically
  2009-04-30  8:54           ` martin rudalics
@ 2009-04-30 11:47             ` Juri Linkov
  2009-04-30 18:20               ` Stefan Monnier
  2009-05-01  8:33               ` martin rudalics
  0 siblings, 2 replies; 26+ messages in thread
From: Juri Linkov @ 2009-04-30 11:47 UTC (permalink / raw)
  To: martin rudalics; +Cc: 3142, Jared Finder

> + (defcustom split-window-preferred-function 'split-selected-window
> +   "Function called by `display-buffer' to split a window.
> + The window that shall be split is selected when this function is
> + called.  The function is supposed to either return the new window
> + or nil if the window can (or shall) not be split."
> +   :type 'function
> +   :version "23.1"
> +   :group 'windows)

If setting this option to `split-window-horizontally' and
`split-window-vertically' is possible and it works correctly
with these value, then I suggest adding them as constants,
e.g. "Always split horizontally" and "Always split vertically".

Also I suggest keeping the common function name prefix "split-window-",
i.e. instead of `split-selected-window' to name it something like
"split-window-sensibly" or "split-window-with-thresholds".

-- 
Juri Linkov
http://www.jurta.org/emacs/






^ permalink raw reply	[flat|nested] 26+ messages in thread

* bug#3142: 23.0.92; split-window-prefered-function should be able to use split-window-horizontally/split-window-vertically
  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
  1 sibling, 1 reply; 26+ messages in thread
From: Stefan Monnier @ 2009-04-30 18:20 UTC (permalink / raw)
  To: Juri Linkov; +Cc: 3142, Jared Finder

>> + (defcustom split-window-preferred-function 'split-selected-window
>> +   "Function called by `display-buffer' to split a window.
>> + The window that shall be split is selected when this function is
>> + called.  The function is supposed to either return the new window
>> + or nil if the window can (or shall) not be split."
>> +   :type 'function
>> +   :version "23.1"
>> +   :group 'windows)

> If setting this option to `split-window-horizontally' and
> `split-window-vertically' is possible and it works correctly
> with these value, then I suggest adding them as constants,
> e.g. "Always split horizontally" and "Always split vertically".

Agreed (does :options work in such a case?).

> Also I suggest keeping the common function name prefix
> "split-window-",

Yes, please.

> i.e. instead of `split-selected-window' to name it something like
> "split-window-sensibly" or "split-window-with-thresholds".

Or split-window-dwim, split-window-somehow.


        Stefan


PS: Other than that, the code looks fine.






^ permalink raw reply	[flat|nested] 26+ messages in thread

* bug#3142: 23.0.92; split-window-prefered-function should be able to use split-window-horizontally/split-window-vertically
  2009-04-30 11:47             ` Juri Linkov
  2009-04-30 18:20               ` Stefan Monnier
@ 2009-05-01  8:33               ` martin rudalics
  2009-05-01 11:52                 ` Juri Linkov
  1 sibling, 1 reply; 26+ messages in thread
From: martin rudalics @ 2009-05-01  8:33 UTC (permalink / raw)
  To: Juri Linkov; +Cc: 3142, Jared Finder

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

 >> + (defcustom split-window-preferred-function 'split-selected-window
 >> +   "Function called by `display-buffer' to split a window.
 >> + The window that shall be split is selected when this function is
 >> + called.  The function is supposed to either return the new window
 >> + or nil if the window can (or shall) not be split."
 >> +   :type 'function
 >> +   :version "23.1"
 >> +   :group 'windows)
 >
 > If setting this option to `split-window-horizontally' and
 > `split-window-vertically' is possible and it works correctly
 > with these value, then I suggest adding them as constants,
 > e.g. "Always split horizontally" and "Always split vertically".

Done.  But note that a function like `split-window-vertically' is suited
for interactive use and thus may throw an error when the window is too
small.  I can't allow an error in `display-buffer' so I have to wrap
that call in a `condition-case'.

 > Also I suggest keeping the common function name prefix "split-window-",
 > i.e. instead of `split-selected-window' to name it something like
 > "split-window-sensibly" or "split-window-with-thresholds".

I've chosen `split-window-sensibly'.  It also calls
`split-window-vertically' and `split-window-horizontally' now.

Please try the new patch - we're in pretest and I don't want to take too
many chances.

martin

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

*** window.el.~1.179.~	2009-04-29 07:50:42.078125000 +0200
--- window.el	2009-05-01 10:19:20.625000000 +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,831 ----
    :type 'boolean
    :group 'windows)
  
+ (defcustom split-window-preferred-function 'split-window-sensibly
+   "Function called by `display-buffer' to split a window.
+ The window that shall be split is selected when this function is
+ called.  The function is supposed to either return the new window
+ or nil if the window can (or shall) not be split."
+   :type '(choice
+ 	  (function :tag "Function")
+ 	  (const :tag "Split vertically" split-window-vertically)
+ 	  (const :tag "Split horizontally" split-window-horizontally))
+   :version "23.1"
+   :group 'windows)
+ 
  (defcustom split-height-threshold 80
    "Minimum height of window to be split vertically.
! If the value is a number, `split-window-sensibly' splits a window
! vertically only if it has at least as many lines.  If the value
! is nil, it does not split a window vertically.  If a window is
! the only window on its frame, it can be split regardless of 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, `split-window-sensibly' splits a window
! only if it has at least as many columns.  If the value is nil, it
! does 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."
--- 881,922 ----
  		      (* 2 (max window-min-height
  				(if mode-line-format 2 1))))))))))
  
+ (defun split-window-sensibly ()
+   "\"Sensibly\" split the selected window.
+ Split selected window vertically or horizontally respecting the
+ values of `split-height-threshold' and `split-width-threshold'.
+ If the selected window is the only window on its frame, it may be
+ split disregarding the value of `split-height-threshold'.  If the
+ window can be split, return the new window, nil otherwise.
+ 
+ The default value of `split-window-preferred-function' is set to
+ this function."
+   (or (and (window--splittable-p (selected-window))
+ 	   ;; Split window vertically.
+ 	   (split-window-vertically))
+       (and (window--splittable-p (selected-window) t)
+ 	   ;; Split window horizontally.
+ 	   (split-window-horizontally))
+       (and (eq (selected-window) (frame-root-window))
+ 	   (not (window-minibuffer-p))
+ 	   ;; If the selected 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))
+ 	     (and (window--splittable-p (selected-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'."
!   ;; Use `condition-case' since `split-window-preferred-function' might
!   ;; throw an error.
!   (condition-case nil
!       (and (window-live-p window)
! 	   (not (frame-parameter (window-frame window) 'unsplittable))
! 	   (with-selected-window window
! 	     (funcall split-window-preferred-function)))
!     (error nil)))
  
  (defun window--frame-usable-p (frame)
    "Return FRAME if it can be used to display a buffer."

^ permalink raw reply	[flat|nested] 26+ messages in thread

* bug#3142: 23.0.92; split-window-prefered-function should be able to use split-window-horizontally/split-window-vertically
  2009-05-01  8:33               ` martin rudalics
@ 2009-05-01 11:52                 ` Juri Linkov
  2009-05-02  8:40                   ` martin rudalics
  0 siblings, 1 reply; 26+ messages in thread
From: Juri Linkov @ 2009-05-01 11:52 UTC (permalink / raw)
  To: martin rudalics; +Cc: 3142, Jared Finder

> Done.  But note that a function like `split-window-vertically' is suited
> for interactive use and thus may throw an error when the window is too
> small.  I can't allow an error in `display-buffer' so I have to wrap
> that call in a `condition-case'.

Thanks, the only thing to fix I noticed is the missing const option for
the default value split-window-sensibly in split-window-preferred-function.

-- 
Juri Linkov
http://www.jurta.org/emacs/






^ permalink raw reply	[flat|nested] 26+ messages in thread

* bug#3142: 23.0.92; split-window-prefered-function should be able to use split-window-horizontally/split-window-vertically
  2009-04-30 18:20               ` Stefan Monnier
@ 2009-05-01 11:54                 ` Juri Linkov
  0 siblings, 0 replies; 26+ messages in thread
From: Juri Linkov @ 2009-05-01 11:54 UTC (permalink / raw)
  To: Stefan Monnier; +Cc: 3142, Jared Finder

>> If setting this option to `split-window-horizontally' and
>> `split-window-vertically' is possible and it works correctly
>> with these value, then I suggest adding them as constants,
>> e.g. "Always split horizontally" and "Always split vertically".
>
> Agreed (does :options work in such a case?).

It seems `:options' is suitable only for the `hook' type
since it allow multiple choices.

-- 
Juri Linkov
http://www.jurta.org/emacs/






^ permalink raw reply	[flat|nested] 26+ messages in thread

* bug#3142: 23.0.92; split-window-prefered-function should be able to use split-window-horizontally/split-window-vertically
  2009-05-01 11:52                 ` Juri Linkov
@ 2009-05-02  8:40                   ` martin rudalics
  0 siblings, 0 replies; 26+ messages in thread
From: martin rudalics @ 2009-05-02  8:40 UTC (permalink / raw)
  To: Juri Linkov; +Cc: 3142, Jared Finder

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

 > Thanks, the only thing to fix I noticed is the missing const option for
 > the default value split-window-sensibly in split-window-preferred-function.

I added the const option, rewrote some doc-strings, and narrowed the
scope of the condition-case.  If no one objects I shall commit that.

Thanks, martin

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

*** window.el.~1.179.~	2009-04-29 07:50:42.078125000 +0200
--- window.el	2009-05-01 17:28:24.125000000 +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,848 ----
    :type 'boolean
    :group 'windows)
  
+ (defcustom split-window-preferred-function 'split-window-sensibly
+   "Function called by `display-buffer' to split a window.
+ The window that shall be split is selected when this function is
+ called.  The function is supposed to either return the new window
+ or nil if the selected 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\" which calls the function `split-window-vertically'
+ to split the window into two windows one above the other.  The
+ third standard option is \"horizontally\" which calls the
+ function `split-window-horizontally' to split the window into two
+ windows side by side.
+ 
+ If you set this to any other function, observe that it may be
+ called two times: A first time with the largest window selected
+ and, if that call fails to provide a suitable window, a second
+ time with the least recently used window selected.  If neither of
+ these calls produces a suitable window, `display-buffer' will use
+ an existing one to display its buffer."
+   :type '(choice
+ 	  (const :tag "Split sensibly" split-window-sensibly)
+ 	  (const :tag "Split vertically" split-window-vertically)
+ 	  (const :tag "Split horizontally" 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, `split-window-sensibly' splits a window
! vertically only if it has at least as many lines.  If the value
! is nil, it does not split a window vertically.  If a window is
! the only window on its frame, it can be split regardless of 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, `split-window-sensibly' splits a window
! only if it has at least as many columns.  If the value is nil, it
! does 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."
--- 898,945 ----
  		      (* 2 (max window-min-height
  				(if mode-line-format 2 1))))))))))
  
+ (defun split-window-sensibly ()
+   "\"Sensibly\" split the selected window.
+ If the selected window has at least `split-height-threshold'
+ lines, split it into two windows one above the other and return
+ the lower one.  Otherwise, if the selected 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 the selected window is the
+ only one on its frame, try to split that 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 (selected-window))
+ 	   ;; Split window vertically.
+ 	   (split-window-vertically))
+       (and (window--splittable-p (selected-window) t)
+ 	   ;; Split window horizontally.
+ 	   (split-window-horizontally))
+       (and (eq (selected-window) (frame-root-window))
+ 	   (not (window-minibuffer-p))
+ 	   ;; If the selected 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))
+ 	     (and (window--splittable-p (selected-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))
! 	   (with-selected-window window
! 	     (let ((new-window
! 		    ;; Since `split-window-preferred-function' might
! 		    ;; throw an error use `condition-case'.
! 		    (condition-case nil
! 			(funcall split-window-preferred-function)
! 		      (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."

^ permalink raw reply	[flat|nested] 26+ messages in thread

* bug#3142: 23.0.92; split-window-prefered-function should be able to use split-window-horizontally/split-window-vertically
  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-05-05  7:02           ` martin rudalics
  2009-05-05 11:03             ` Juri Linkov
  2009-05-06  1:41             ` Stefan Monnier
  1 sibling, 2 replies; 26+ messages in thread
From: martin rudalics @ 2009-05-05  7:02 UTC (permalink / raw)
  To: Stefan Monnier; +Cc: 3142

[-- 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."

^ permalink raw reply	[flat|nested] 26+ messages in thread

* bug#3142: 23.0.92; split-window-prefered-function should be able to use split-window-horizontally/split-window-vertically
  2009-05-05  7:02           ` martin rudalics
@ 2009-05-05 11:03             ` Juri Linkov
  2009-05-06  1:41             ` Stefan Monnier
  1 sibling, 0 replies; 26+ messages in thread
From: Juri Linkov @ 2009-05-05 11:03 UTC (permalink / raw)
  To: martin rudalics; +Cc: 3142

> +   :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)))))

Using lambdas in defcustoms is too ugly: it will put this long lambda code
to custom-set-variables in .emacs, and cause other problems.

I suggest defining new functions with the prefix `split-window-preferred-'
that will provide a hint for the user where they are intended to be used:

split-window-preferred-sensibly (window)
split-window-preferred-vertically (window)
split-window-preferred-horizontally (window)

-- 
Juri Linkov
http://www.jurta.org/emacs/






^ permalink raw reply	[flat|nested] 26+ messages in thread

* bug#3142: 23.0.92; split-window-prefered-function should be able to use split-window-horizontally/split-window-vertically
  2009-05-05  7:02           ` martin rudalics
  2009-05-05 11:03             ` Juri Linkov
@ 2009-05-06  1:41             ` Stefan Monnier
  2009-05-06 16:21               ` martin rudalics
  1 sibling, 1 reply; 26+ messages in thread
From: Stefan Monnier @ 2009-05-06  1:41 UTC (permalink / raw)
  To: martin rudalics; +Cc: 3142

> 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.

Good call.

> + 	  (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)))))

I'd rather try to better advertise the use of (setq
split-width-threshold nil) and friends then bother with lambdas here or
defining new functions.


        Stefan






^ permalink raw reply	[flat|nested] 26+ messages in thread

* bug#3142: 23.0.92; split-window-prefered-function should be able to use split-window-horizontally/split-window-vertically
  2009-05-06  1:41             ` Stefan Monnier
@ 2009-05-06 16:21               ` martin rudalics
  2009-05-06 19:04                 ` Stefan Monnier
  0 siblings, 1 reply; 26+ messages in thread
From: martin rudalics @ 2009-05-06 16:21 UTC (permalink / raw)
  To: Stefan Monnier; +Cc: 3142

 > I'd rather try to better advertise the use of (setq
 > split-width-threshold nil) and friends then bother with lambdas here or
 > defining new functions.

Agreed.  But then why did you want me to define a function like
`split-window-sensibly' in the first place?

martin







^ permalink raw reply	[flat|nested] 26+ messages in thread

* bug#3142: 23.0.92; split-window-prefered-function should be able to use split-window-horizontally/split-window-vertically
  2009-05-06 16:21               ` martin rudalics
@ 2009-05-06 19:04                 ` Stefan Monnier
  2009-05-07  9:36                   ` martin rudalics
  0 siblings, 1 reply; 26+ messages in thread
From: Stefan Monnier @ 2009-05-06 19:04 UTC (permalink / raw)
  To: martin rudalics; +Cc: 3142

>> I'd rather try to better advertise the use of (setq
>> split-width-threshold nil) and friends then bother with lambdas here or
>> defining new functions.

> Agreed.  But then why did you want me to define a function like
> `split-window-sensibly' in the first place?

Because we need it as default value of split-window-prefered-function.
Or am I misunderstanding your question?


        Stefan






^ permalink raw reply	[flat|nested] 26+ messages in thread

* bug#3142: 23.0.92; split-window-prefered-function should be able to use split-window-horizontally/split-window-vertically
  2009-05-06 19:04                 ` Stefan Monnier
@ 2009-05-07  9:36                   ` martin rudalics
  0 siblings, 0 replies; 26+ messages in thread
From: martin rudalics @ 2009-05-07  9:36 UTC (permalink / raw)
  To: Stefan Monnier; +Cc: 3142

 >> Agreed.  But then why did you want me to define a function like
 >> `split-window-sensibly' in the first place?
 >
 > Because we need it as default value of split-window-prefered-function.
 > Or am I misunderstanding your question?

No.  I just wanted to make sure whether I should go on with this change.

martin






^ permalink raw reply	[flat|nested] 26+ messages in thread

* bug#3142: 23.0.92; split-window-prefered-function should be able to usesplit-window-horizontally/split-window-vertically
  2009-04-30  9:05           ` martin rudalics
@ 2011-10-05 18:49             ` Glenn Morris
  2011-10-05 22:11               ` Stefan Monnier
  0 siblings, 1 reply; 26+ messages in thread
From: Glenn Morris @ 2011-10-05 18:49 UTC (permalink / raw)
  To: 3142


As with many bug reports about window handling, this became rather long.
What actually needs to be done to close this?

AFAICS, the actual bug report was "I would like a way to tell
split-window-preferred-function to always split vertically, or always
horizontally".

Surely there is such a way, and it is documented in that variable's
documentation:

   You can customize the options `split-height-threshold' and/or
   `split-width-threshold' in order to have `split-window-sensibly'
   prefer either vertical or horizontal splitting.





^ permalink raw reply	[flat|nested] 26+ messages in thread

* bug#3142: 23.0.92; split-window-prefered-function should be able to usesplit-window-horizontally/split-window-vertically
  2011-10-05 18:49             ` Glenn Morris
@ 2011-10-05 22:11               ` Stefan Monnier
  0 siblings, 0 replies; 26+ messages in thread
From: Stefan Monnier @ 2011-10-05 22:11 UTC (permalink / raw)
  To: Glenn Morris; +Cc: 3142-done

> What actually needs to be done to close this?

I think this email will do ;-)


        Stefan





^ permalink raw reply	[flat|nested] 26+ messages in thread

end of thread, other threads:[~2011-10-05 22:11 UTC | newest]

Thread overview: 26+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
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
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

Code repositories for project(s) associated with this public inbox

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

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).