Mercurial > emacs
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))) |