comparison lisp/window.el @ 103174:27ea4d4a56a4

(split-window-sensibly): New function. (split-height-threshold, split-width-threshold): State in doc-string that these affect split-window-sensibly. Change customization subtype from number to integer. (window--splittable-p): Rename to window-splittable-p since it's referred to in doc-string of split-window-sensibly. Update doc-string. (window--try-to-split-window): Unconditionally call split-window-preferred-function and move splitting functionality to split-window-sensibly (Bug#3142). (split-window-preferred-function): Rewrite doc-string. Don't allow nil as customization type.
author Martin Rudalics <rudalics@gmx.at>
date Thu, 07 May 2009 09:21:23 +0000
parents b8ae7a4c9154
children c220a29e75fd
comparison
equal deleted inserted replaced
103173:80d012abe015 103174:27ea4d4a56a4
792 (defcustom pop-up-windows t 792 (defcustom pop-up-windows t
793 "Non-nil means `display-buffer' should make a new window." 793 "Non-nil means `display-buffer' should make a new window."
794 :type 'boolean 794 :type 'boolean
795 :group 'windows) 795 :group 'windows)
796 796
797 (defcustom split-height-threshold 80 797 (defcustom split-window-preferred-function 'split-window-sensibly
798 "Minimum height of window to be split vertically. 798 "Function called by `display-buffer' routines to split a window.
799 If the value is a number, `display-buffer' can split a window 799 This function is called with a window as single argument and is
800 only if it has at least as many lines. If the value is nil, 800 supposed to split that window and return the new window. If the
801 `display-buffer' cannot split a window vertically. 801 window can (or shall) not be split, it is supposed to return nil.
802 802 The default is to call the function `split-window-sensibly' which
803 If the window is the only window on its frame, `display-buffer' 803 tries to split the window in a way which seems most suitable.
804 can split it regardless of this value." 804 You can customize the options `split-height-threshold' and/or
805 :type '(choice (const nil) (number :tag "lines")) 805 `split-width-threshold' in order to have `split-window-sensibly'
806 prefer either vertical or horizontal splitting.
807
808 If you set this to any other function, bear in mind that the
809 `display-buffer' routines may call this function two times. The
810 argument of the first call is the largest window on its frame.
811 If that call fails to return a live window, the function is
812 called again with the least recently used window as argument. If
813 that call fails too, `display-buffer' will use an existing window
814 to display its buffer.
815
816 The window selected at the time `display-buffer' was invoked is
817 still selected when this function is called. Hence you can
818 compare the window argument with the value of `selected-window'
819 if you intend to split the selected window instead or if you do
820 not want to split the selected window."
821 :type 'function
806 :version "23.1" 822 :version "23.1"
807 :group 'windows) 823 :group 'windows)
808 824
809 (defcustom split-width-threshold 160 825 (defcustom split-height-threshold 80
810 "Minimum width of window to be split horizontally. 826 "Minimum height for splitting windows sensibly.
811 If the value is a number, `display-buffer' can split a window 827 If this is an integer, `split-window-sensibly' may split a window
812 only if it has at least as many columns. If the value is nil, 828 vertically only if it has at least this many lines. If this is
813 `display-buffer' cannot split a window horizontally." 829 nil, `split-window-sensibly' is not allowed to split a window
814 :type '(choice (const nil) (number :tag "columns")) 830 vertically. If, however, a window is the only window on its
831 frame, `split-window-sensibly' may split it vertically
832 disregarding the value of this variable."
833 :type '(choice (const nil) (integer :tag "lines"))
815 :version "23.1" 834 :version "23.1"
816 :group 'windows) 835 :group 'windows)
817 836
818 (defcustom split-window-preferred-function nil 837 (defcustom split-width-threshold 160
819 "Function used by `display-buffer' to split windows. 838 "Minimum width for splitting windows sensibly.
820 If non-nil, a function called with a window as single argument 839 If this is an integer, `split-window-sensibly' may split a window
821 supposed to split that window and return the new window. If the 840 horizontally only if it has at least this many columns. If this
822 function returns nil the window is not split. 841 is nil, `split-window-sensibly' is not allowed to split a window
823 842 horizontally."
824 If nil, `display-buffer' will split the window respecting the 843 :type '(choice (const nil) (integer :tag "columns"))
825 values of `split-height-threshold' and `split-width-threshold'."
826 :type '(choice (const nil) (function :tag "Function"))
827 :version "23.1" 844 :version "23.1"
828 :group 'windows) 845 :group 'windows)
829 846
830 (defun window--splittable-p (window &optional horizontal) 847 (defun window-splittable-p (window &optional horizontal)
831 "Return non-nil if WINDOW can be split evenly. 848 "Return non-nil if `split-window-sensibly' may split WINDOW.
832 Optional argument HORIZONTAL non-nil means check whether WINDOW 849 Optional argument HORIZONTAL nil or omitted means check whether
833 can be split horizontally. 850 `split-window-sensibly' may split WINDOW vertically. HORIZONTAL
834 851 non-nil means check whether WINDOW may be split horizontally.
835 WINDOW can be split vertically when the following conditions 852
853 WINDOW may be split vertically when the following conditions
836 hold: 854 hold:
837
838 - `window-size-fixed' is either nil or equals `width' for the 855 - `window-size-fixed' is either nil or equals `width' for the
839 buffer of WINDOW. 856 buffer of WINDOW.
840 857 - `split-height-threshold' is an integer and WINDOW is at least as
841 - `split-height-threshold' is a number and WINDOW is at least as
842 high as `split-height-threshold'. 858 high as `split-height-threshold'.
843
844 - When WINDOW is split evenly, the emanating windows are at least 859 - When WINDOW is split evenly, the emanating windows are at least
845 `window-min-height' lines tall and can accommodate at least one 860 `window-min-height' lines tall and can accommodate at least one
846 line plus - if WINDOW has one - a mode line. 861 line plus - if WINDOW has one - a mode line.
847 862
848 WINDOW can be split horizontally when the following conditions 863 WINDOW may be split horizontally when the following conditions
849 hold: 864 hold:
850
851 - `window-size-fixed' is either nil or equals `height' for the 865 - `window-size-fixed' is either nil or equals `height' for the
852 buffer of WINDOW. 866 buffer of WINDOW.
853 867 - `split-width-threshold' is an integer and WINDOW is at least as
854 - `split-width-threshold' is a number and WINDOW is at least as
855 wide as `split-width-threshold'. 868 wide as `split-width-threshold'.
856
857 - When WINDOW is split evenly, the emanating windows are at least 869 - When WINDOW is split evenly, the emanating windows are at least
858 `window-min-width' or two (whichever is larger) columns wide." 870 `window-min-width' or two (whichever is larger) columns wide."
859 (when (window-live-p window) 871 (when (window-live-p window)
860 (with-current-buffer (window-buffer window) 872 (with-current-buffer (window-buffer window)
861 (if horizontal 873 (if horizontal
880 (>= (window-height window) 892 (>= (window-height window)
881 (max split-height-threshold 893 (max split-height-threshold
882 (* 2 (max window-min-height 894 (* 2 (max window-min-height
883 (if mode-line-format 2 1)))))))))) 895 (if mode-line-format 2 1))))))))))
884 896
897 (defun split-window-sensibly (window)
898 "Split WINDOW in a way suitable for `display-buffer'.
899 If `split-height-threshold' specifies an integer, WINDOW is at
900 least `split-height-threshold' lines tall and can be split
901 vertically, split WINDOW into two windows one above the other and
902 return the lower window. Otherwise, if `split-width-threshold'
903 specifies an integer, WINDOW is at least `split-width-threshold'
904 columns wide and can be split horizontally, split WINDOW into two
905 windows side by side and return the window on the right. If this
906 can't be done either and WINDOW is the only window on its frame,
907 try to split WINDOW vertically disregarding any value specified
908 by `split-height-threshold'. If that succeeds, return the lower
909 window. Return nil otherwise.
910
911 By default `display-buffer' routines call this function to split
912 the largest or least recently used window. To change the default
913 customize the option `split-window-preferred-function'.
914
915 You can enforce this function to not split WINDOW horizontally,
916 by setting \(or binding) the variable `split-width-threshold' to
917 nil. If, in addition, you set `split-height-threshold' to zero,
918 chances increase that this function does split WINDOW vertically.
919
920 In order to not split WINDOW vertically, set \(or bind) the
921 variable `split-height-threshold' to nil. Additionally, you can
922 set `split-width-threshold' to zero to make a horizontal split
923 more likely to occur.
924
925 Have a look at the function `window-splittable-p' if you want to
926 know how `split-window-sensibly' determines whether WINDOW can be
927 split."
928 (or (and (window-splittable-p window)
929 ;; Split window vertically.
930 (with-selected-window window
931 (split-window-vertically)))
932 (and (window-splittable-p window t)
933 ;; Split window horizontally.
934 (with-selected-window window
935 (split-window-horizontally)))
936 (and (eq window (frame-root-window (window-frame window)))
937 (not (window-minibuffer-p window))
938 ;; If WINDOW is the only window on its frame and is not the
939 ;; minibuffer window, try to split it vertically disregarding
940 ;; the value of `split-height-threshold'.
941 (let ((split-height-threshold 0))
942 (when (window-splittable-p window)
943 (with-selected-window window
944 (split-window-vertically)))))))
945
885 (defun window--try-to-split-window (window) 946 (defun window--try-to-split-window (window)
886 "Split WINDOW if it is splittable. 947 "Try to split WINDOW.
887 See `window--splittable-p' for how to determine whether a window 948 Return value returned by `split-window-preferred-function' if it
888 is splittable. If WINDOW can be split, return the value returned 949 represents a live window, nil otherwise."
889 by `split-window' (or `split-window-preferred-function')." 950 (and (window-live-p window)
890 (when (and (window-live-p window) 951 (not (frame-parameter (window-frame window) 'unsplittable))
891 (not (frame-parameter (window-frame window) 'unsplittable))) 952 (let ((new-window
892 (if (functionp split-window-preferred-function) 953 ;; Since `split-window-preferred-function' might
893 ;; `split-window-preferred-function' is specified, so use it. 954 ;; throw an error use `condition-case'.
894 (funcall split-window-preferred-function window) 955 (condition-case nil
895 (or (and (window--splittable-p window) 956 (funcall split-window-preferred-function window)
896 ;; Split window vertically. 957 (error nil))))
897 (split-window window)) 958 (and (window-live-p new-window) new-window))))
898 (and (window--splittable-p window t)
899 ;; Split window horizontally.
900 (split-window window nil t))
901 (and (eq window (frame-root-window (window-frame window)))
902 (not (window-minibuffer-p window))
903 ;; If WINDOW is the only window on its frame and not the
904 ;; minibuffer window, attempt to split it vertically
905 ;; disregarding the value of `split-height-threshold'.
906 (let ((split-height-threshold 0))
907 (and (window--splittable-p window)
908 (split-window window))))))))
909 959
910 (defun window--frame-usable-p (frame) 960 (defun window--frame-usable-p (frame)
911 "Return FRAME if it can be used to display a buffer." 961 "Return FRAME if it can be used to display a buffer."
912 (when (frame-live-p frame) 962 (when (frame-live-p frame)
913 (let ((window (frame-root-window frame))) 963 (let ((window (frame-root-window frame)))