Mercurial > emacs
comparison lisp/window.el @ 95590:9a4b27c8feec
* window.el (display-buffer-function, special-display-p)
(special-display-buffer-names, special-display-regexps)
(special-display-function, same-window-p, same-window-buffer-names)
(same-window-regexps, pop-up-frames, display-buffer-reuse-frames)
(pop-up-frame-function, pop-up-windows)
(split-window-preferred-function, split-height-threshold)
(split-width-threshold, window--splittable-p)
(window--try-to-split-window, window--frame-usable-p)
(even-window-heights, window--even-window-heights)
(window--display-buffer-1, window--display-buffer-2, display-buffer)
(pop-to-buffer): Move from window.c and buffer.c.
(split-window-preferred-horizontally): Remove.
* cus-start.el: Remove corresponding declarations.
* window.c (pop_up_windows, pop_up_frames)
(display_buffer_reuse_frames, Vpop_up_frame_function)
(Vdisplay_buffer_function, Veven_window_heights)
(Vspecial_display_buffer_names, Vspecial_display_regexps)
(Vspecial_display_function, Vsame_window_buffer_names)
(Vsame_window_regexps, split_height_threshold)
(Vsplit_window_preferred_function): Move those vars to window.el.
(display_buffer_1, Fspecial_display_p, Fsame_window_p)
(Fdisplay_buffer): Move those functions to window.el.
(syms_of_window): Remove corresponding declarations.
(display_buffer): New function.
(temp_output_buffer_show, Fother_window_for_scrolling): Use it.
* dispnew.c (Flast_nonminibuf_frame): New function.
* buffer.c (Fpop_to_buffer): Move to window.el.
author | Stefan Monnier <monnier@iro.umontreal.ca> |
---|---|
date | Thu, 05 Jun 2008 18:00:36 +0000 |
parents | 0fc821738484 |
children | b406f55ccc12 |
comparison
equal
deleted
inserted
replaced
95589:4f530a89d1ee | 95590:9a4b27c8feec |
---|---|
191 default)) | 191 default)) |
192 | 192 |
193 (defalias 'some-window 'get-window-with-predicate) | 193 (defalias 'some-window 'get-window-with-predicate) |
194 | 194 |
195 ;; This should probably be written in C (i.e., without using `walk-windows'). | 195 ;; This should probably be written in C (i.e., without using `walk-windows'). |
196 (defun get-buffer-window-list (buffer &optional minibuf frame) | 196 (defun get-buffer-window-list (buffer &optional minibuf all-frames) |
197 "Return list of all windows displaying BUFFER, or nil if none. | 197 "Return list of all windows displaying BUFFER, or nil if none. |
198 BUFFER can be a buffer or a buffer name. | 198 BUFFER can be a buffer or a buffer name. |
199 See `walk-windows' for the meaning of MINIBUF and FRAME." | 199 See `walk-windows' for the meaning of MINIBUF and ALL-FRAMES." |
200 (let ((buffer (if (bufferp buffer) buffer (get-buffer buffer))) windows) | 200 (let ((buffer (if (bufferp buffer) buffer (get-buffer buffer))) windows) |
201 (walk-windows (function (lambda (window) | 201 (walk-windows (function (lambda (window) |
202 (if (eq (window-buffer window) buffer) | 202 (if (eq (window-buffer window) buffer) |
203 (setq windows (cons window windows))))) | 203 (setq windows (cons window windows))))) |
204 minibuf frame) | 204 minibuf all-frames) |
205 windows)) | 205 windows)) |
206 | 206 |
207 (defun minibuffer-window-active-p (window) | 207 (defun minibuffer-window-active-p (window) |
208 "Return t if WINDOW (a minibuffer window) is now active." | 208 "Return t if WINDOW (a minibuffer window) is now active." |
209 (eq window (active-minibuffer-window))) | 209 (eq window (active-minibuffer-window))) |
515 ;; so let's do some fine tuning. | 515 ;; so let's do some fine tuning. |
516 ;; (bw-finetune wins) | 516 ;; (bw-finetune wins) |
517 ;; (message "Done in %d rounds" round) | 517 ;; (message "Done in %d rounds" round) |
518 )) | 518 )) |
519 | 519 |
520 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; | |
521 | 520 |
521 (defcustom display-buffer-function nil | |
522 "If non-nil, function to call to handle `display-buffer'. | |
523 It will receive two args, the buffer and a flag which if non-nil | |
524 means that the currently selected window is not acceptable. It | |
525 should choose or create a window, display the specified buffer in | |
526 it, and return the window. | |
527 | |
528 Commands such as `switch-to-buffer-other-window' and | |
529 `find-file-other-window' work using this function." | |
530 :type '(choice | |
531 (const nil) | |
532 (function :tag "function")) | |
533 :group 'windows) | |
534 | |
535 (defun special-display-p (buffer-name) | |
536 "Return non-nil if a buffer named BUFFER-NAME gets a special frame. | |
537 If the value is t, `display-buffer' or `pop-to-buffer' would | |
538 create a special frame for that buffer using the default frame | |
539 parameters. | |
540 | |
541 If the value is a list, it is a list of frame parameters that | |
542 would be used to make a frame for that buffer. The variables | |
543 `special-display-buffer-names' and `special-display-regexps' | |
544 control this." | |
545 (cond | |
546 ((not (stringp buffer-name))) | |
547 ;; Make sure to return t in the following two cases. | |
548 ((member buffer-name special-display-buffer-names) t) | |
549 ((assoc buffer-name special-display-buffer-names) t) | |
550 ((catch 'found | |
551 (dolist (regexp special-display-regexps) | |
552 (cond | |
553 ((stringp regexp) | |
554 (when (string-match-p regexp buffer-name) | |
555 (throw 'found t))) | |
556 ((and (consp regexp) (stringp (car regexp)) | |
557 (string-match-p (car regexp) buffer-name)) | |
558 (throw 'found (cdr regexp))))))))) | |
559 | |
560 (defcustom special-display-buffer-names nil | |
561 "List of buffer names that should have their own special frames. | |
562 Displaying a buffer with `display-buffer' or `pop-to-buffer', if | |
563 its name is in this list, makes a special frame for it using | |
564 `special-display-function'. See also `special-display-regexps'. | |
565 | |
566 An element of the list can be a list instead of just a string. | |
567 There are two ways to use a list as an element: | |
568 (BUFFER FRAME-PARAMETERS...) (BUFFER FUNCTION OTHER-ARGS...) | |
569 In the first case, the FRAME-PARAMETERS are pairs of the form | |
570 \(PARAMETER . VALUE); these parameter values are used to create | |
571 the frame. In the second case, FUNCTION is called with BUFFER as | |
572 the first argument, followed by the OTHER-ARGS--it can display | |
573 BUFFER in any way it likes. All this is done by the function | |
574 found in `special-display-function'. | |
575 | |
576 If the specified frame parameters include (same-buffer . t), the | |
577 buffer is displayed in the currently selected window. Otherwise, if | |
578 they include (same-frame . t), the buffer is displayed in a new window | |
579 in the currently selected frame. | |
580 | |
581 If this variable appears \"not to work\", because you add a name to it | |
582 but that buffer still appears in the selected window, look at the | |
583 values of `same-window-buffer-names' and `same-window-regexps'. | |
584 Those variables take precedence over this one." | |
585 :type '(repeat (choice :tag "Buffer" | |
586 :value "" | |
587 (string :format "%v") | |
588 (cons :tag "With attributes" | |
589 :format "%v" | |
590 :value ("" . nil) | |
591 (string :format "%v") | |
592 (repeat :tag "Attributes" | |
593 (cons :format "%v" | |
594 (symbol :tag "Parameter") | |
595 (sexp :tag "Value")))))) | |
596 :group 'frames) | |
597 | |
598 (defcustom special-display-regexps nil | |
599 "List of regexps saying which buffers should have their own special frames. | |
600 When displaying a buffer with `display-buffer' or | |
601 `pop-to-buffer', if any regexp in this list matches the buffer | |
602 name, it makes a special frame for the buffer by calling | |
603 `special-display-function'. | |
604 | |
605 An element of the list can be a list instead of just a string. | |
606 There are two ways to use a list as an element: | |
607 (REGEXP FRAME-PARAMETERS...) (REGEXP FUNCTION OTHER-ARGS...) | |
608 In the first case, the FRAME-PARAMETERS are pairs of the form | |
609 \(PARAMETER . VALUE); these parameter values are used to create | |
610 the frame. In the second case, FUNCTION is called with BUFFER as | |
611 the first argument, followed by the OTHER-ARGS--it can display | |
612 the buffer in any way it likes. All this is done by the function | |
613 found in `special-display-function'. | |
614 | |
615 If the specified frame parameters include (same-buffer . t), the | |
616 buffer is displayed in the currently selected window. Otherwise, | |
617 if they include (same-frame . t), the buffer is displayed in a | |
618 new window in the currently selected frame. | |
619 | |
620 If this variable appears \"not to work\", because you add a | |
621 regexp to it but the matching buffers still appear in the | |
622 selected window, look at the values of `same-window-buffer-names' | |
623 and `same-window-regexps'. Those variables take precedence over | |
624 this one." | |
625 :type '(repeat (choice :tag "Buffer" | |
626 :value "" | |
627 (regexp :format "%v") | |
628 (cons :tag "With attributes" | |
629 :format "%v" | |
630 :value ("" . nil) | |
631 (regexp :format "%v") | |
632 (repeat :tag "Attributes" | |
633 (cons :format "%v" | |
634 (symbol :tag "Parameter") | |
635 (sexp :tag "Value")))))) | |
636 :group 'frames) | |
637 | |
638 (defcustom special-display-function 'special-display-popup-frame | |
639 "Function to call to make a new frame for a special buffer. | |
640 It is called with two arguments, the buffer and optional buffer | |
641 specific data, and should return a window displaying that buffer. | |
642 The default value normally makes a separate frame for the buffer, | |
643 using `special-display-frame-alist' to specify the frame | |
644 parameters. | |
645 | |
646 But if the buffer specific data includes (same-buffer . t) then | |
647 the buffer is displayed in the current selected window. | |
648 Otherwise if it includes (same-frame . t) then the buffer is | |
649 displayed in a new window in the currently selected frame. | |
650 | |
651 A buffer is special if it is listed in | |
652 `special-display-buffer-names' or matches a regexp in | |
653 `special-display-regexps'." | |
654 :type 'function | |
655 :group 'frames) | |
656 | |
657 (defun same-window-p (buffer-name) | |
658 "Return non-nil if a buffer named BUFFER-NAME would be shown in the \"same\" window. | |
659 This function returns non-nil if `display-buffer' or | |
660 `pop-to-buffer' would show a buffer named BUFFER-NAME in the | |
661 selected rather than \(as usual\) some other window. See | |
662 `same-window-buffer-names' and `same-window-regexps'." | |
663 (cond | |
664 ((not (stringp buffer-name))) | |
665 ;; The elements of `same-window-buffer-names' can be buffer | |
666 ;; names or cons cells whose cars are buffer names. | |
667 ((member buffer-name same-window-buffer-names)) | |
668 ((assoc buffer-name same-window-buffer-names)) | |
669 ((catch 'found | |
670 (dolist (regexp same-window-regexps) | |
671 ;; The elements of `same-window-regexps' can be regexps | |
672 ;; or cons cells whose cars are regexps. | |
673 (when (or (and (stringp regexp) | |
674 (string-match regexp buffer-name)) | |
675 (and (consp regexp) (stringp (car regexp)) | |
676 (string-match-p (car regexp) buffer-name))) | |
677 (throw 'found t))))))) | |
678 | |
679 (defcustom same-window-buffer-names nil | |
680 "List of names of buffers that should appear in the \"same\" window. | |
681 `display-buffer' and `pop-to-buffer' show a buffer whose name is | |
682 on this list in the selected rather than some other window. | |
683 | |
684 An element of this list can be a cons cell instead of just a | |
685 string. In that case the car must be a string specifying the | |
686 buffer name. This is for compatibility with | |
687 `special-display-buffer-names'; the cdr of the cons cell is | |
688 ignored. | |
689 | |
690 See also `same-window-regexps'." | |
691 :type '(repeat (string :format "%v")) | |
692 :group 'windows) | |
693 | |
694 (defcustom same-window-regexps nil | |
695 "List of regexps saying which buffers should appear in the \"same\" window. | |
696 `display-buffer' and `pop-to-buffer' show a buffer whose name | |
697 matches a regexp on this list in the selected rather than some | |
698 other window. | |
699 | |
700 An element of this list can be a cons cell instead of just a | |
701 string. In that case the car must be a string, which specifies | |
702 the buffer name. This is for compatibility with | |
703 `special-display-buffer-names'; the cdr of the cons cell is | |
704 ignored. | |
705 | |
706 See also `same-window-buffer-names'." | |
707 :type '(repeat (regexp :format "%v")) | |
708 :group 'windows) | |
709 | |
710 (defcustom pop-up-frames nil | |
711 "Non-nil means `display-buffer' should make a separate frame." | |
712 :type 'boolean | |
713 :group 'windows) | |
714 | |
715 (defcustom display-buffer-reuse-frames nil | |
716 "Non-nil means `display-buffer' should reuse frames. | |
717 If the buffer in question is already displayed in a frame, raise | |
718 that frame." | |
719 :type 'boolean | |
720 :version "21.1" | |
721 :group 'windows) | |
722 | |
723 (defcustom pop-up-frame-function nil | |
724 "Function to call to handle automatic new frame creation. | |
725 It is called with no arguments and should return a newly created frame. | |
726 | |
727 A typical value might be | |
728 | |
729 `(lambda () (new-frame pop-up-frame-alist))' | |
730 | |
731 where `pop-up-frame-alist' would hold the default frame | |
732 parameters." | |
733 :type '(choice | |
734 (const nil) | |
735 (function :tag "function")) | |
736 :group 'windows) | |
737 | |
738 (defcustom pop-up-windows t | |
739 "Non-nil means `display-buffer' should make a new window." | |
740 :type 'boolean | |
741 :group 'windows) | |
742 | |
743 (defcustom split-window-preferred-function nil | |
744 "How `display-buffer' shall split windows. | |
745 Choices are `Vertically', `Horizontally', and `Sensibly' where | |
746 the latter attempts to split wide windows horizontally, narrow | |
747 ones vertically. Alternatively, you can set this to a function | |
748 called with a window as single argument to split that window in | |
749 two and return the new window." | |
750 :type '(choice | |
751 (const :tag "Vertically" nil) | |
752 (const :tag "Horizontally" horizontally) | |
753 (const :tag "Sensibly" sensibly) | |
754 (function :tag "Function")) | |
755 :version "23.1" | |
756 :group 'windows) | |
757 | |
758 (defcustom split-height-threshold 80 | |
759 "Minimum height of window to be split vertically by `display-buffer'. | |
760 If there is only one window, it can be split regardless of this." | |
761 :type 'number | |
762 :version "23.1" | |
763 :group 'windows) | |
764 | |
765 (defcustom split-width-threshold 160 | |
766 "Minimum width of window to be split horizontally by `display-buffer'. | |
767 If there is only one window, it can be split regardless of this." | |
768 :type 'number | |
769 :version "23.1" | |
770 :group 'windows) | |
771 | |
772 (defun window--splittable-p (window &optional horizontal) | |
773 "Return non-nil if window WINDOW can be split evenly. | |
774 Optional argument HORIZONTAL non-nil means check whether WINDOW | |
775 can be split horizontally. | |
776 | |
777 WINDOW can be split vertically when the following conditions | |
778 hold: | |
779 | |
780 - `window-size-fixed' is either nil or equals `width' for the buffer of | |
781 WINDOW. | |
782 | |
783 - WINDOW is at least as high as `split-height-threshold' or it is | |
784 the only window on its frame. | |
785 | |
786 - When WINDOW is split evenly, the emanating windows are at least | |
787 `window-min-height' lines tall and can accomodate at least one | |
788 line plus - if WINDOW has one - a modeline. | |
789 | |
790 WINDOW can be split horizontally when the following conditions | |
791 hold: | |
792 | |
793 - `window-size-fixed' is either nil or equals `height' for the | |
794 buffer of WINDOW. | |
795 | |
796 - WINDOW is at least as wide as `split-width-threshold'. | |
797 | |
798 - When WINDOW is split evenly, the emanating windows are at least | |
799 `window-min-width' or two (whichever is larger) columns wide." | |
800 (when (window-live-p window) | |
801 (with-selected-window window | |
802 (if horizontal | |
803 ;; A window can be split horizontally when its width is not | |
804 ;; fixed, it is at least `split-width-threshold' columns wide | |
805 ;; and at least twice as wide as `window-min-width' and 2 (the | |
806 ;; latter value is hardcoded). | |
807 (and (memq window-size-fixed '(nil height)) | |
808 (>= (window-width window) | |
809 (max split-width-threshold | |
810 (* 2 (max window-min-width 2))))) | |
811 ;; A window can be split vertically when its height is not | |
812 ;; fixed, it is at least `split-height-threshold' lines high or | |
813 ;; the only window on its frame, and it is at least twice as | |
814 ;; high as `window-min-height' and 2 if it has a modeline or 1. | |
815 (and (memq window-size-fixed '(nil width)) | |
816 (>= (window-height window) | |
817 (max (if (one-window-p 'nomini) 0 split-height-threshold) | |
818 (* 2 (max window-min-height | |
819 (if mode-line-format 2 1)))))))))) | |
820 | |
821 (defun window--try-to-split-window (window) | |
822 "Split window WINDOW if it is splittable. | |
823 See `split-window-preferred-function' for how WINDOW shall be | |
824 split. See `window--splittable-p' for how to determine whether a | |
825 window is splittable. If WINDOW can be split, return the value | |
826 returned by `split-window' or `split-window-preferred-function'." | |
827 (when (and (window-live-p window) | |
828 ;; Testing `window-full-width-p' here hardly makes any | |
829 ;; sense nowadays. This can be done more intuitively by | |
830 ;; setting up `split-width-threshold' appropriately. | |
831 (not (frame-parameter (window-frame window) 'unsplittable))) | |
832 (or (and (not split-window-preferred-function) | |
833 (window--splittable-p window) | |
834 (split-window window)) | |
835 (and (eq split-window-preferred-function 'horizontally) | |
836 (window--splittable-p window t) | |
837 (split-window window nil t)) | |
838 (and (eq split-window-preferred-function 'sensibly) | |
839 ;; The following naive aspect-ratio test should become | |
840 ;; more sensible. | |
841 (or (and (> (window-width window) (window-height window)) | |
842 (window--splittable-p window t) | |
843 (split-window window nil t)) | |
844 (and (window--splittable-p window) | |
845 (split-window window)))) | |
846 (and (functionp split-window-preferred-function) | |
847 (funcall split-window-preferred-function window))))) | |
848 | |
849 (defun window--frame-usable-p (frame) | |
850 "Return frame FRAME if it can be used to display another buffer." | |
851 (let ((window (frame-root-window frame))) | |
852 (when (or (not (window-live-p window)) | |
853 (and (not (window-minibuffer-p window)) | |
854 (not (window-dedicated-p window)))) | |
855 frame))) | |
856 | |
857 (defcustom even-window-heights t | |
858 "If non-nil `display-buffer' will try to even window heights. | |
859 Otherwise `display-buffer' will leave the window configuration | |
860 alone. Heights are evened only when `display-buffer' chooses a | |
861 window that appears above or below the selected window." | |
862 :type 'boolean | |
863 :group 'windows) | |
864 | |
865 (defun window--even-window-heights (window) | |
866 "Even heights of window WINDOW and selected window. | |
867 Do this only if these windows are vertically adjacent to each | |
868 other and `even-window-heights' is non-nil." | |
869 (when (and even-window-heights | |
870 (not (eq window (selected-window))) | |
871 ;; Don't resize minibuffer windows. | |
872 (not (window-minibuffer-p (selected-window))) | |
873 (/= (window-height (selected-window)) (window-height window)) | |
874 (eq (window-frame window) (window-frame (selected-window))) | |
875 (let ((sel-edges (window-edges (selected-window))) | |
876 (win-edges (window-edges window))) | |
877 (and (= (nth 0 sel-edges) (nth 0 win-edges)) | |
878 (= (nth 2 sel-edges) (nth 2 win-edges)) | |
879 (or (= (nth 1 sel-edges) (nth 3 win-edges)) | |
880 (= (nth 3 sel-edges) (nth 1 win-edges)))))) | |
881 (let ((window-min-height 1)) | |
882 ;; Don't throw an error if we can't even window heights for | |
883 ;; whatever reason. | |
884 (condition-case nil | |
885 (enlarge-window (/ (- (window-height window) (window-height)) 2)) | |
886 (error nil))))) | |
887 | |
888 (defun window--display-buffer-1 (window) | |
889 "Deiconify the frame containing the window WINDOW. | |
890 Do not deiconify the selected frame. Return WINDOW." | |
891 (let* ((frame (window-frame window)) | |
892 (visible (frame-visible-p frame))) | |
893 (unless (or (not visible) | |
894 ;; Assume the selected frame is already visible enough. | |
895 (eq frame (selected-frame)) | |
896 ;; Assume the frame from which we invoked the minibuffer | |
897 ;; is visible. | |
898 (and (minibuffer-window-active-p (selected-window)) | |
899 (eq frame (window-frame (minibuffer-selected-window))))) | |
900 (when (eq visible 'icon) | |
901 (make-frame-visible frame)) | |
902 (raise-frame frame)) | |
903 window)) | |
904 | |
905 (defun window--display-buffer-2 (buffer window) | |
906 "Display buffer BUFFER in window WINDOW and make its frame visible. | |
907 Return WINDOW." | |
908 (when (and (buffer-live-p buffer) (window-live-p window)) | |
909 (set-window-buffer window buffer) | |
910 (window--display-buffer-1 window))) | |
911 | |
912 (defun display-buffer (buffer-or-name &optional not-this-window frame) | |
913 "Make buffer BUFFER-OR-NAME appear in some window but don't select it. | |
914 BUFFER-OR-NAME must be a buffer or the name of an existing | |
915 buffer. Return the window chosen to display BUFFER-OR-NAME or | |
916 nil is no such window is found. | |
917 | |
918 Optional argument NOT-THIS-WINDOW non-nil means display the | |
919 buffer in a window other than the selected one, even if it is | |
920 already displayed in the selected window. | |
921 | |
922 Optional argument FRAME specifies which frames to investigate | |
923 when the specified buffer is already displayed. If the buffer is | |
924 already displayed in some window on one of these frames simply | |
925 return that window. Possible values of FRAME are: | |
926 | |
927 `visible' - consider windows on all visible frames. | |
928 | |
929 0 - consider windows on all visible or iconified frames. | |
930 | |
931 `t' - consider windows on all frames. | |
932 | |
933 A specific frame - consider windows on that frame only. | |
934 | |
935 `nil' - consider windows on the selected frame \(actually the | |
936 last non-minibuffer frame\) only. If, however, either | |
937 `display-buffer-reuse-frames' or `pop-up-frames' is non-nil, | |
938 consider all visible or iconified frames." | |
939 (interactive "BDisplay buffer:\nP") | |
940 (let* ((can-use-selected-window | |
941 ;; The selected window is usable unless either NOT-THIS-WINDOW | |
942 ;; is non-nil, it is dedicated to its buffer, or it is the | |
943 ;; `minibuffer-window'. | |
944 (not (or not-this-window | |
945 (window-dedicated-p (selected-window)) | |
946 (window-minibuffer-p)))) | |
947 (buffer (if (bufferp buffer-or-name) | |
948 buffer-or-name | |
949 (get-buffer buffer-or-name))) | |
950 (name-of-buffer (buffer-name buffer)) | |
951 ;; `frame-to-use' is the frame where to show `buffer' - either | |
952 ;; the selected frame or the last nonminibuffer frame. | |
953 (frame-to-use | |
954 (or (window--frame-usable-p (selected-frame)) | |
955 (window--frame-usable-p (last-nonminibuffer-frame)))) | |
956 ;; `window-to-use' is the window we use for showing `buffer'. | |
957 window-to-use) | |
958 (cond | |
959 ((not (buffer-live-p buffer)) | |
960 (error "No such buffer %s" buffer)) | |
961 (display-buffer-function | |
962 ;; Let `display-buffer-function' do the job. | |
963 (funcall display-buffer-function buffer not-this-window)) | |
964 ((and (not not-this-window) | |
965 (eq (window-buffer (selected-window)) buffer)) | |
966 ;; The selected window already displays BUFFER and | |
967 ;; `not-this-window' is nil, so use it. | |
968 (window--display-buffer-1 (selected-window))) | |
969 ((and can-use-selected-window (same-window-p name-of-buffer)) | |
970 ;; If the buffer's name tells us to use the selected window do so. | |
971 (window--display-buffer-2 buffer (selected-window))) | |
972 ((let ((frames (or frame | |
973 (and (or pop-up-frames display-buffer-reuse-frames | |
974 (not (last-nonminibuffer-frame))) | |
975 0) | |
976 (last-nonminibuffer-frame)))) | |
977 (and (setq window-to-use (get-buffer-window buffer frames)) | |
978 (or can-use-selected-window | |
979 (not (eq (selected-window) window-to-use))))) | |
980 ;; If the buffer is already displayed in some window use that. | |
981 (window--display-buffer-1 window-to-use)) | |
982 ((and special-display-function | |
983 ;; `special-display-p' returns either t or a list of frame | |
984 ;; parameters to pass to `special-display-function'. | |
985 (let ((pars (special-display-p name-of-buffer))) | |
986 (when pars | |
987 (funcall special-display-function | |
988 (if (eq pars t) buffer pars)))))) | |
989 ((or pop-up-frames (not frame-to-use)) | |
990 ;; We want or need a new frame. | |
991 (window--display-buffer-2 | |
992 buffer (frame-selected-window (funcall pop-up-frame-function)))) | |
993 ((and pop-up-windows | |
994 ;; Make a new window. | |
995 (or (not (frame-parameter frame-to-use 'unsplittable)) | |
996 ;; If the selected frame cannot be split look at | |
997 ;; `last-nonminibuffer-frame'. | |
998 (and (eq frame-to-use (selected-frame)) | |
999 (setq frame-to-use (last-nonminibuffer-frame)) | |
1000 (window--frame-usable-p frame-to-use) | |
1001 (not (frame-parameter frame-to-use 'unsplittable)))) | |
1002 ;; Attempt to split largest or most recently used window. | |
1003 (setq window-to-use | |
1004 (or (window--try-to-split-window | |
1005 (get-largest-window frame-to-use t)) | |
1006 (window--try-to-split-window | |
1007 (get-lru-window frame-to-use t)))) | |
1008 (window--display-buffer-2 buffer window-to-use))) | |
1009 ((setq window-to-use | |
1010 ;; Reuse an existing window. | |
1011 (or (get-buffer-window buffer 'visible) | |
1012 (get-largest-window 'visible nil) | |
1013 (get-buffer-window buffer 0) | |
1014 (get-largest-window 0 nil) | |
1015 (frame-selected-window (funcall pop-up-frame-function)) | |
1016 (get-lru-window t t))) | |
1017 (window--even-window-heights window-to-use) | |
1018 (window--display-buffer-2 buffer window-to-use))))) | |
1019 | |
1020 (defun pop-to-buffer (buffer-or-name &optional other-window norecord) | |
1021 "Select buffer BUFFER-OR-NAME in some window, preferably a different one. | |
1022 BUFFER-OR-NAME may be a buffer, a string \(a buffer name), or | |
1023 nil. If BUFFER-OR-NAME is a string not naming an existent | |
1024 buffer, create a buffer with that name. If BUFFER-OR-NAME is | |
1025 nil, choose some other buffer. | |
1026 | |
1027 If `pop-up-windows' is non-nil, windows can be split to display | |
1028 the buffer. If optional second arg OTHER-WINDOW is non-nil, | |
1029 insist on finding another window even if the specified buffer is | |
1030 already visible in the selected window, and ignore | |
1031 `same-window-regexps' and `same-window-buffer-names'. | |
1032 | |
1033 This function returns the buffer it switched to. This uses the | |
1034 function `display-buffer' as a subroutine; see the documentation | |
1035 of `display-buffer' for additional customization information. | |
1036 | |
1037 Optional third arg NORECORD non-nil means do not put this buffer | |
1038 at the front of the list of recently selected ones." | |
1039 (let ((buffer | |
1040 ;; FIXME: This behavior is carried over from the previous C version | |
1041 ;; of pop-to-buffer, but really we should use just | |
1042 ;; `get-buffer' here. | |
1043 (if (null buffer-or-name) (other-buffer (current-buffer)) | |
1044 (or (get-buffer buffer-or-name) | |
1045 (let ((buf (get-buffer-create buffer-or-name))) | |
1046 (set-buffer-major-mode buf) | |
1047 buf))))) | |
1048 (set-buffer buffer) | |
1049 (select-window (display-buffer buffer other-window) norecord) | |
1050 buffer)) | |
1051 | |
522 ;; I think this should be the default; I think people will prefer it--rms. | 1052 ;; I think this should be the default; I think people will prefer it--rms. |
523 (defcustom split-window-keep-point t | 1053 (defcustom split-window-keep-point t |
524 "*If non-nil, \\[split-window-vertically] keeps the original point \ | 1054 "*If non-nil, \\[split-window-vertically] keeps the original point \ |
525 in both children. | 1055 in both children. |
526 This is often more convenient for editing. | 1056 This is often more convenient for editing. |
611 (let ((old-w (selected-window)) | 1141 (let ((old-w (selected-window)) |
612 (size (and arg (prefix-numeric-value arg)))) | 1142 (size (and arg (prefix-numeric-value arg)))) |
613 (and size (< size 0) | 1143 (and size (< size 0) |
614 (setq size (+ (window-width) size))) | 1144 (setq size (+ (window-width) size))) |
615 (split-window-save-restore-data (split-window nil size t) old-w))) | 1145 (split-window-save-restore-data (split-window nil size t) old-w))) |
616 | |
617 (defun split-window-preferred-horizontally (window) | |
618 "Split WINDOW horizontally or select an appropriate existing window. | |
619 It is called by `display-buffer' to split windows horizontally | |
620 when the option `split-window-preferred-function' is set to \"horizontally\". | |
621 This function tries to match the implementation of vertical splitting | |
622 in `display-buffer' as close as possible but with the logic of | |
623 horizontal splitting. It returns a new window or an appropriate | |
624 existing window if splitting is not eligible." | |
625 (interactive) | |
626 ;; If the largest window is wide enough, eligible for splitting, | |
627 ;; and the only window, split it horizontally. | |
628 (if (and window | |
629 (not (frame-parameter (window-frame window) 'unsplittable)) | |
630 (one-window-p (window-frame window)) | |
631 (>= (window-width window) (* 2 window-min-width))) | |
632 (split-window window nil t) | |
633 ;; Otherwise, if the LRU window is wide enough, eligible for | |
634 ;; splitting and selected or the only window, split it horizontally. | |
635 (setq window (get-lru-window nil t)) | |
636 (if (and window | |
637 (not (frame-parameter (window-frame window) 'unsplittable)) | |
638 (or (eq window (selected-window)) | |
639 (one-window-p (window-frame window))) | |
640 (>= (window-width window) (* 2 window-min-width))) | |
641 (split-window window nil t) | |
642 ;; Otherwise, if get-lru-window returns nil, try other approaches. | |
643 (or | |
644 (get-lru-window nil nil) | |
645 ;; Try visible frames first. | |
646 (get-buffer-window (current-buffer) 'visible) | |
647 (get-largest-window 'visible) | |
648 ;; If that didn't work, try iconified frames. | |
649 (get-buffer-window (current-buffer) 0) | |
650 (get-largest-window 0) | |
651 ;; As a last resort, make a new frame. | |
652 (frame-selected-window (funcall pop-up-frame-function)))))) | |
653 | 1146 |
654 | 1147 |
655 (defun set-window-text-height (window height) | 1148 (defun set-window-text-height (window height) |
656 "Sets the height in lines of the text display area of WINDOW to HEIGHT. | 1149 "Sets the height in lines of the text display area of WINDOW to HEIGHT. |
657 This doesn't include the mode-line (or header-line if any) or any | 1150 This doesn't include the mode-line (or header-line if any) or any |