aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPaul Eggert2011-06-13 17:58:31 -0700
committerPaul Eggert2011-06-13 17:58:31 -0700
commit3c3a05dfb70656c56f60666a8c32a28d85f072fb (patch)
treef8e2901e63318bf0cd7299f54f4901ea11b9eeb5
parenta690a978ec42934c3f9d29c15cddd0240ab7a009 (diff)
parentd647b7c44e4205c50b29d1533880e9ae7ce0bea6 (diff)
downloademacs-3c3a05dfb70656c56f60666a8c32a28d85f072fb.tar.gz
emacs-3c3a05dfb70656c56f60666a8c32a28d85f072fb.zip
Merge from trunk.
-rw-r--r--lisp/ChangeLog78
-rw-r--r--lisp/cus-dep.el7
-rw-r--r--lisp/help-mode.el17
-rw-r--r--lisp/help.el318
-rw-r--r--lisp/view.el247
-rw-r--r--lisp/window.el3130
6 files changed, 2859 insertions, 938 deletions
diff --git a/lisp/ChangeLog b/lisp/ChangeLog
index 6f7afeb2af3..7dac139c295 100644
--- a/lisp/ChangeLog
+++ b/lisp/ChangeLog
@@ -1,3 +1,81 @@
12011-06-13 Glenn Morris <rgm@gnu.org>
2
3 * cus-dep.el (custom-make-dependencies): Use up command-line-args-left.
4
52011-06-13 Martin Rudalics <rudalics@gmx.at>
6
7 * help.el (help-window): Remove variable.
8 (help-window-point-marker, temp-buffer-max-height)
9 (temp-buffer-resize-mode, help-window-select): Rewrite doc-strings.
10 (help-print-return-message): Don't set help-window.
11 (resize-temp-buffer-window): Rewrite cod eand doc-string.
12 (help-window-setup-finish): Remove.
13 (help-window-display-message, help-window-setup)
14 (with-help-window): Major rewrite based on new
15 display-buffer-window variable.
16
17 * help-mode.el (help-mode-finish): Remove help-window related
18 code.
19
20 * view.el (view-exits-all-viewing-windows): Remove reference to
21 view-return-to-alist in doc-string.
22 (view-return-to-alist): Make obsolete.
23 (view-buffer): Call pop-to-buffer-same-window and remove
24 undo-window code.
25 (view-buffer-other-window): Call pop-to-buffer-other-window and
26 simplify code. Ignore second argument.
27 (view-buffer-other-frame): Call pop-to-buffer-other-frame and
28 simplify code. Ignore second argument.
29 (view-return-to-alist-update): Make obsolete.
30 (view-mode-enter): Rename second argument to QUIT-RESTORE.
31 Rewrite using quit-restore window parameters.
32 (view-mode-exit): Rename second argument to EXIT-ONLY. Rewrite
33 using quit-restore-window.
34 (View-exit, View-exit-and-edit, View-leave, View-quit)
35 (View-quit-all, View-kill-and-leave): Call view-mode-exit with
36 appropriate arguments.
37 (view-end-message): Use quit-restore window parameter.
38
39 * window.el (display-buffer-function): Rewrite doc-string.
40 (display-buffer-window, display-buffer-alist): New variables.
41 (display-buffer-split-specifiers)
42 (display-buffer-side-specifiers)
43 (display-buffer-macro-specifiers): New constants.
44 (display-buffer-even-window-sizes, display-buffer-set-height)
45 (display-buffer-set-width, display-buffer-select-window)
46 (display-buffer-in-window, display-buffer-reuse-window)
47 (display-buffer-split-window-1, display-buffer-split-window)
48 (display-buffer-split-atom-window, display-buffer-pop-up-window)
49 (display-buffer-pop-up-frame, display-buffer-pop-up-side-window)
50 (display-buffer-in-side-window, normalize-buffer-to-display)
51 (display-buffer-normalize-specifiers-1)
52 (display-buffer-normalize-specifiers-2)
53 (display-buffer-normalize-specifiers, display-buffer-frame): New
54 functions.
55 (display-buffer): Major rewrite.
56 (display-buffer-other-window, display-buffer-other-frame)
57 (pop-to-buffer, switch-to-buffer-other-window)
58 (switch-to-buffer-other-frame): Rewrite.
59 (display-buffer-same-window, display-buffer-same-frame)
60 (display-buffer-same-frame-other-window)
61 (pop-to-buffer-same-window, pop-to-buffer-same-frame)
62 (pop-to-buffer-other-window)
63 (pop-to-buffer-same-frame-other-window)
64 (pop-to-buffer-other-frame, switch-to-buffer-same-frame)
65 (switch-to-buffer-other-window-same-frame): New functions.
66 (same-window-p, special-display-p): Rewrite disabling warnings.
67 Make obsolete.
68 (pop-up-frames, display-buffer-reuse-frames, pop-up-windows)
69 (display-buffer-mark-dedicated): Initialize to symbol 'unset.
70 Make obsolete
71 (same-window-buffer-names, same-window-regexps)
72 (special-display-frame-alist, special-display-popup-frame)
73 (special-display-function, special-display-buffer-names)
74 (special-display-regexps, pop-up-frame-alist)
75 (pop-up-frame-function, split-window-preferred-function)
76 (split-height-threshold, split-width-threshold)
77 (even-window-heights): Make obsolete.
78
12011-06-12 Glenn Morris <rgm@gnu.org> 792011-06-12 Glenn Morris <rgm@gnu.org>
2 80
3 * term/xterm.el (terminal-init-xterm): `version' may be nil. (Bug#8838) 81 * term/xterm.el (terminal-init-xterm): `version' may be nil. (Bug#8838)
diff --git a/lisp/cus-dep.el b/lisp/cus-dep.el
index 5e74c68978f..091f832c092 100644
--- a/lisp/cus-dep.el
+++ b/lisp/cus-dep.el
@@ -42,9 +42,12 @@ ldefs-boot\\|cus-load\\|finder-inf\\|esh-groups\\|subdirs\\)\\.el$\\)"
42(defun custom-make-dependencies () 42(defun custom-make-dependencies ()
43 "Batch function to extract custom dependencies from .el files. 43 "Batch function to extract custom dependencies from .el files.
44Usage: emacs -batch -l ./cus-dep.el -f custom-make-dependencies DIRS" 44Usage: emacs -batch -l ./cus-dep.el -f custom-make-dependencies DIRS"
45 (let ((enable-local-eval nil)) 45 (let ((enable-local-eval nil)
46 subdir)
46 (with-temp-buffer 47 (with-temp-buffer
47 (dolist (subdir command-line-args-left) 48 ;; Use up command-line-args-left else Emacs can try to open
49 ;; the args as directories after we are done.
50 (while (setq subdir (pop command-line-args-left))
48 (message "Directory %s" subdir) 51 (message "Directory %s" subdir)
49 (let ((files (directory-files subdir nil "\\`[^=].*\\.el\\'")) 52 (let ((files (directory-files subdir nil "\\`[^=].*\\.el\\'"))
50 (default-directory (expand-file-name subdir)) 53 (default-directory (expand-file-name subdir))
diff --git a/lisp/help-mode.el b/lisp/help-mode.el
index 642dac71ba6..1a96f29c4cc 100644
--- a/lisp/help-mode.el
+++ b/lisp/help-mode.el
@@ -305,23 +305,6 @@ Commands:
305 305
306;;;###autoload 306;;;###autoload
307(defun help-mode-finish () 307(defun help-mode-finish ()
308 (if (eq help-window t)
309 ;; If `help-window' is t, `view-return-to-alist' is handled by
310 ;; `with-help-window'. In this case set `help-window' to the
311 ;; selected window since now is the only moment where we can
312 ;; unambiguously identify it.
313 (setq help-window (selected-window))
314 (let ((entry (assq (selected-window) view-return-to-alist)))
315 (if entry
316 ;; When entering Help mode from the Help window,
317 ;; such as by following a link, preserve the same
318 ;; meaning for the q command.
319 ;; (setcdr entry (cons (selected-window) help-return-method))
320 nil
321 (setq view-return-to-alist
322 (cons (cons (selected-window) help-return-method)
323 view-return-to-alist)))))
324
325 (when (eq major-mode 'help-mode) 308 (when (eq major-mode 'help-mode)
326 ;; View mode's read-only status of existing *Help* buffer is lost 309 ;; View mode's read-only status of existing *Help* buffer is lost
327 ;; by with-output-to-temp-buffer. 310 ;; by with-output-to-temp-buffer.
diff --git a/lisp/help.el b/lisp/help.el
index 3a943274a14..e6496f625d1 100644
--- a/lisp/help.el
+++ b/lisp/help.el
@@ -55,7 +55,7 @@
55;; nowhere before exiting. Currently used by `view-lossage' to assert 55;; nowhere before exiting. Currently used by `view-lossage' to assert
56;; that the last keystrokes are always visible. 56;; that the last keystrokes are always visible.
57(defvar help-window-point-marker (make-marker) 57(defvar help-window-point-marker (make-marker)
58 "Marker to override default `window-point' of `help-window'.") 58 "Marker to override default `window-point' in help windows.")
59 59
60(defvar help-map 60(defvar help-map
61 (let ((map (make-sparse-keymap))) 61 (let ((map (make-sparse-keymap)))
@@ -144,8 +144,6 @@ It computes a message, and applies the optional argument FUNCTION to it.
144If FUNCTION is nil, it applies `message', thus displaying the message. 144If FUNCTION is nil, it applies `message', thus displaying the message.
145In addition, this function sets up `help-return-method', which see, that 145In addition, this function sets up `help-return-method', which see, that
146specifies what to do when the user exits the help buffer." 146specifies what to do when the user exits the help buffer."
147 ;; Reset `help-window' here to avoid confusing `help-mode-finish'.
148 (setq help-window nil)
149 (and (not (get-buffer-window standard-output)) 147 (and (not (get-buffer-window standard-output))
150 (let ((first-message 148 (let ((first-message
151 (cond ((or 149 (cond ((or
@@ -914,6 +912,7 @@ appeared on the mode-line."
914 ;; In order to list up all minor modes, minor-mode-list 912 ;; In order to list up all minor modes, minor-mode-list
915 ;; is used here instead of minor-mode-alist. 913 ;; is used here instead of minor-mode-alist.
916 (delq nil (mapcar 'symbol-name minor-mode-list))) 914 (delq nil (mapcar 'symbol-name minor-mode-list)))
915
917(defun describe-minor-mode-from-symbol (symbol) 916(defun describe-minor-mode-from-symbol (symbol)
918 "Display documentation of a minor mode given as a symbol, SYMBOL" 917 "Display documentation of a minor mode given as a symbol, SYMBOL"
919 (interactive (list (intern (completing-read 918 (interactive (list (intern (completing-read
@@ -937,6 +936,7 @@ appeared on the mode-line."
937 (t 936 (t
938 i)))) 937 i))))
939 minor-mode-alist))) 938 minor-mode-alist)))
939
940(defun describe-minor-mode-from-indicator (indicator) 940(defun describe-minor-mode-from-indicator (indicator)
941 "Display documentation of a minor mode specified by INDICATOR. 941 "Display documentation of a minor mode specified by INDICATOR.
942If you call this function interactively, you can give indicator which 942If you call this function interactively, you can give indicator which
@@ -972,28 +972,32 @@ is currently activated with completion."
972 minor-modes nil) 972 minor-modes nil)
973 (setq minor-modes (cdr minor-modes))))) 973 (setq minor-modes (cdr minor-modes)))))
974 result)) 974 result))
975
976 975
977;;; Automatic resizing of temporary buffers. 976;;; Automatic resizing of temporary buffers.
978
979(defcustom temp-buffer-max-height (lambda (buffer) (/ (- (frame-height) 2) 2)) 977(defcustom temp-buffer-max-height (lambda (buffer) (/ (- (frame-height) 2) 2))
980 "Maximum height of a window displaying a temporary buffer. 978 "Maximum height of a window displaying a temporary buffer.
981This is effective only when Temp Buffer Resize mode is enabled. 979This is effective only when Temp Buffer Resize mode is enabled.
982The value is the maximum height (in lines) which `resize-temp-buffer-window' 980The value is the maximum height (in lines) which
983will give to a window displaying a temporary buffer. 981`resize-temp-buffer-window' will give to a window displaying a
984It can also be a function to be called to choose the height for such a buffer. 982temporary buffer. It can also be a function to be called to
985It gets one argumemt, the buffer, and should return a positive integer." 983choose the height for such a buffer. It gets one argumemt, the
984buffer, and should return a positive integer. At the time the
985function is called, the window to be resized is selected."
986 :type '(choice integer function) 986 :type '(choice integer function)
987 :group 'help 987 :group 'help
988 :version "20.4") 988 :version "20.4")
989 989
990(define-minor-mode temp-buffer-resize-mode 990(define-minor-mode temp-buffer-resize-mode
991 "Toggle the mode which makes windows smaller for temporary buffers. 991 "Toggle mode which makes windows smaller for temporary buffers.
992With prefix argument ARG, turn the resizing of windows displaying temporary 992With prefix argument ARG, turn the resizing of windows displaying
993buffers on if ARG is positive or off otherwise. 993temporary buffers on if ARG is positive or off otherwise.
994This makes the window the right height for its contents, but never 994
995more than `temp-buffer-max-height' nor less than `window-min-height'. 995This mode makes a window the right height for its contents, but
996This applies to `help', `apropos' and `completion' buffers, and some others." 996never more than `temp-buffer-max-height' nor less than
997`window-min-height'.
998
999This mode is used by `help', `apropos' and `completion' buffers,
1000and some others."
997 :global t :group 'help 1001 :global t :group 'help
998 (if temp-buffer-resize-mode 1002 (if temp-buffer-resize-mode
999 ;; `help-make-xrefs' may add a `back' button and thus increase the 1003 ;; `help-make-xrefs' may add a `back' button and thus increase the
@@ -1003,29 +1007,26 @@ This applies to `help', `apropos' and `completion' buffers, and some others."
1003 1007
1004(defun resize-temp-buffer-window () 1008(defun resize-temp-buffer-window ()
1005 "Resize the selected window to fit its contents. 1009 "Resize the selected window to fit its contents.
1006Will not make it higher than `temp-buffer-max-height' nor smaller than 1010Will not make it higher than `temp-buffer-max-height' nor smaller
1007`window-min-height'. Do nothing if it is the only window on its frame, if it 1011than `window-min-height'. Do nothing if the selected window is
1008is not as wide as the frame or if some of the window's contents are scrolled 1012not vertically combined or some of its contents are scrolled out
1009out of view." 1013of view."
1010 (unless (or (one-window-p 'nomini) 1014 (when (and (pos-visible-in-window-p (point-min))
1011 (not (pos-visible-in-window-p (point-min))) 1015 (window-iso-combined-p))
1012 (not (window-full-width-p)))
1013 (fit-window-to-buffer 1016 (fit-window-to-buffer
1014 (selected-window) 1017 nil
1015 (if (functionp temp-buffer-max-height) 1018 (if (functionp temp-buffer-max-height)
1016 (funcall temp-buffer-max-height (current-buffer)) 1019 (funcall temp-buffer-max-height (window-buffer))
1017 temp-buffer-max-height)))) 1020 temp-buffer-max-height))))
1018 1021
1019 1022;;; Help windows.
1020;;; help-window
1021
1022(defcustom help-window-select 'other 1023(defcustom help-window-select 'other
1023 "Non-nil means select help window for viewing. 1024 "Non-nil means select help window for viewing.
1024Choices are: 1025Choices are:
1025 never (nil) Select help window only if there is no other window 1026 never (nil) Select help window only if there is no other window
1026 on its frame. 1027 on its frame.
1027 other Select help window unless the selected window is the 1028 other Select help window unless the selected window is the
1028 only other window on its frame. 1029 only other window on the help window's frame.
1029 always (t) Always select the help window. 1030 always (t) Always select the help window.
1030 1031
1031This option has effect if and only if the help window was created 1032This option has effect if and only if the help window was created
@@ -1036,175 +1037,79 @@ by `with-help-window'"
1036 :group 'help 1037 :group 'help
1037 :version "23.1") 1038 :version "23.1")
1038 1039
1039(defun help-window-display-message (quit-part window &optional other) 1040(defun help-window-display-message (quit-part window &optional scroll)
1040 "Display message telling how to quit and scroll help window. 1041 "Display message telling how to quit and scroll help window.
1041QUIT-PART is a string telling how to quit the help window WINDOW. 1042QUIT-PART is a string telling how to quit the help window WINDOW.
1042Optional argument OTHER non-nil means return text telling how to 1043Optional argument SCROLL non-nil means tell how to scroll WINDOW.
1043scroll the \"other\" window." 1044SCROLL equal `other' means tell how to scroll the \"other\"
1045window."
1044 (let ((scroll-part 1046 (let ((scroll-part
1045 (cond 1047 (cond
1048 ;; If we don't have QUIT-PART we probably reuse a window
1049 ;; showing the same buffer so we don't show any message.
1050 ((not quit-part) nil)
1046 ((pos-visible-in-window-p 1051 ((pos-visible-in-window-p
1047 (with-current-buffer (window-buffer window) 1052 (with-current-buffer (window-buffer window)
1048 (point-max)) window) 1053 (point-max)) window t)
1049 ;; Buffer end is visible. 1054 ;; Buffer end is at least partially visible, no need to talk
1055 ;; about scrolling.
1050 ".") 1056 ".")
1051 (other ", \\[scroll-other-window] to scroll help.") 1057 ((eq scroll 'other)
1052 (t ", \\[scroll-up] to scroll help.")))) 1058 ", \\[scroll-other-window] to scroll help.")
1059 (scroll ", \\[scroll-up] to scroll help."))))
1053 (message "%s" 1060 (message "%s"
1054 (substitute-command-keys (concat quit-part scroll-part))))) 1061 (substitute-command-keys (concat quit-part scroll-part)))))
1055 1062
1056(defun help-window-setup-finish (window &optional reuse keep-frame) 1063(defun help-window-setup ()
1057 "Finish setting up help window WINDOW. 1064 "Set up help window for `with-help-window'.
1058Select WINDOW according to the value of `help-window-select'. 1065This relies on `display-buffer-window' being correctly set up by
1059Display message telling how to scroll and eventually quit WINDOW. 1066`display-buffer'."
1060 1067 (let* ((help-window (car-safe display-buffer-window))
1061Optional argument REUSE non-nil means WINDOW has been reused by 1068 (help-buffer (when (window-live-p help-window)
1062`display-buffer'. Optional argument KEEP-FRAME non-nil means 1069 (window-buffer help-window)))
1063that quitting should not delete WINDOW's frame." 1070 (help-value (cdr-safe display-buffer-window)))
1064 (let ((number-of-windows 1071 (when help-buffer
1065 (length (window-list (window-frame window) 'no-mini window)))) 1072 ;; Handle `help-window-point-marker'.
1066 (cond 1073 (when (eq (marker-buffer help-window-point-marker) help-buffer)
1067 ((eq window (selected-window)) 1074 (set-window-point help-window help-window-point-marker)
1068 ;; The help window is the selected window, probably the 1075 ;; Reset `help-window-point-marker'.
1069 ;; `pop-up-windows' nil case. 1076 (set-marker help-window-point-marker nil))
1070 (help-window-display-message
1071 (if reuse
1072 "Type \"q\" to restore this window"
1073 ;; This should not be taken.
1074 "Type \"q\" to quit") window))
1075 ((= number-of-windows 1)
1076 ;; The help window is alone on a frame and not the selected
1077 ;; window, could be the `pop-up-frames' t case.
1078 (help-window-display-message
1079 (cond
1080 (keep-frame "Type \"q\" to delete this window")
1081 (reuse "Type \"q\" to restore this window")
1082 (view-remove-frame-by-deleting "Type \"q\" to delete this frame")
1083 (t "Type \"q\" to iconify this frame"))
1084 window))
1085 ((and (= number-of-windows 2)
1086 (eq (window-frame window) (window-frame (selected-window))))
1087 ;; There are two windows on the help window's frame and the other
1088 ;; window is the selected one.
1089 (if (memq help-window-select '(nil other))
1090 ;; Do not select the help window.
1091 (help-window-display-message
1092 (if reuse
1093 ;; Offer `display-buffer' for consistency with
1094 ;; `help-print-return-message'. This is hardly TRT when
1095 ;; the other window and the selected window display the
1096 ;; same buffer but has been handled this way ever since.
1097 "Type \\[display-buffer] RET to restore the other window"
1098 ;; The classic "two windows" configuration.
1099 "Type \\[delete-other-windows] to delete the help window")
1100 window t)
1101 ;; Select help window and tell how to quit.
1102 (select-window window)
1103 (help-window-display-message
1104 (if reuse
1105 "Type \"q\" to restore this window"
1106 "Type \"q\" to delete this window") window)))
1107 (help-window-select
1108 ;; Issuing a message with 3 or more windows on the same frame
1109 ;; without selecting the help window doesn't make any sense.
1110 (select-window window)
1111 (help-window-display-message
1112 (if reuse
1113 "Type \"q\" to restore this window"
1114 "Type \"q\" to delete this window") window)))))
1115
1116(defun help-window-setup (list-of-frames list-of-window-tuples)
1117 "Set up help window.
1118LIST-OF-FRAMES and LIST-OF-WINDOW-TUPLES are the lists of frames
1119and window quadruples built by `with-help-window'. The help
1120window itself is specified by the variable `help-window'."
1121 (let* ((help-buffer (window-buffer help-window))
1122 ;; `help-buffer' now denotes the help window's buffer.
1123 (view-entry
1124 (assq help-window
1125 (buffer-local-value 'view-return-to-alist help-buffer)))
1126 (help-entry (assq help-window list-of-window-tuples)))
1127
1128 ;; Handle `help-window-point-marker'.
1129 (when (eq (marker-buffer help-window-point-marker) help-buffer)
1130 (set-window-point help-window help-window-point-marker)
1131 ;; Reset `help-window-point-marker'.
1132 (set-marker help-window-point-marker nil))
1133 1077
1134 (cond
1135 (view-entry
1136 ;; `view-return-to-alist' has an entry for the help window.
1137 (cond 1078 (cond
1138 ((eq help-window (selected-window)) 1079 ((or (eq help-window (selected-window))
1139 ;; The help window is the selected window, probably because the 1080 (and (or (eq help-window-select t)
1140 ;; user followed a backward/forward button or a cross reference. 1081 (and (eq help-window-select 'other)
1141 ;; In this case just purge stale entries from 1082 (eq (window-frame help-window) (selected-frame))
1142 ;; `view-return-to-alist' but leave the entry alone and don't 1083 (> (length (window-list nil 'no-mini)) 2)))
1143 ;; display a message. 1084 (select-window help-window)))
1144 (view-return-to-alist-update help-buffer)) 1085 ;; The help window is or gets selected ...
1145 ((and help-entry (eq (cadr help-entry) help-buffer)) 1086 (help-window-display-message
1146 ;; The help window was not selected but displayed the help 1087 (cond
1147 ;; buffer. In this case reuse existing exit information but try 1088 ((eq help-value 'new-window)
1148 ;; to get back to the selected window when quitting. Don't 1089 ;; ... and is new, ...
1149 ;; display a message since the user must have seen one before. 1090 "Type \"q\" to delete this window")
1150 (view-return-to-alist-update 1091 ((eq help-value 'new-frame)
1151 help-buffer (cons help-window 1092 ;; ... is on a new frame ...
1152 (cons (selected-window) (cddr view-entry))))) 1093 "Type \"q\" to delete this frame")
1153 (help-entry 1094 ((eq help-value 'reuse-other-window)
1154 ;; The help window was not selected, did display the help buffer 1095 ;; ... or displayed some other buffer before.
1155 ;; earlier, but displayed another buffer when help was invoked. 1096 "Type \"q\" to restore previous buffer"))
1156 ;; Set up things so that quitting will show that buffer again. 1097 help-window t))
1157 (view-return-to-alist-update 1098 ((and (eq (window-frame help-window) (selected-frame))
1158 help-buffer (cons help-window 1099 (= (length (window-list nil 'no-mini)) 2))
1159 (cons (selected-window) (cdr help-entry)))) 1100 ;; There are two windows on the help window's frame and the
1160 (help-window-setup-finish help-window t)) 1101 ;; other one is the selected one.
1102 (help-window-display-message
1103 (cond
1104 ((eq help-value 'new-window)
1105 "Type \\[delete-other-windows] to delete the help window")
1106 ((eq help-value 'reuse-other-window)
1107 "Type \\[switch-to-prev-buffer] RET to restore previous buffer"))
1108 help-window 'other))
1161 (t 1109 (t
1162 ;; The help window is new but `view-return-to-alist' had an 1110 ;; Not much to say here.
1163 ;; entry for it. This should never happen. 1111 (help-window-display-message
1164 (view-return-to-alist-update 1112 "Type \"q\" in help window to quit" help-window))))))
1165 help-buffer (cons help-window
1166 (cons (selected-window) 'quit-window)))
1167 (help-window-setup-finish help-window t))))
1168 (help-entry
1169 ;; `view-return-to-alist' does not have an entry for help window
1170 ;; but `list-of-window-tuples' does. Hence `display-buffer' must
1171 ;; have reused an existing window.
1172 (if (eq (cadr help-entry) help-buffer)
1173 ;; The help window displayed `help-buffer' before but no
1174 ;; `view-return-to-alist' entry was found probably because the
1175 ;; user manually switched to the help buffer. Set up things
1176 ;; for `quit-window' although `view-exit-action' should be
1177 ;; able to handle this case all by itself.
1178 (progn
1179 (view-return-to-alist-update
1180 help-buffer (cons help-window
1181 (cons (selected-window) 'quit-window)))
1182 (help-window-setup-finish help-window t))
1183 ;; The help window displayed another buffer before. Set up
1184 ;; things in a way that quitting can orderly show that buffer
1185 ;; again. The window-start and window-point information from
1186 ;; `list-of-window-tuples' provide the necessary information.
1187 (view-return-to-alist-update
1188 help-buffer (cons help-window
1189 (cons (selected-window) (cdr help-entry))))
1190 (help-window-setup-finish help-window t)))
1191 ((memq (window-frame help-window) list-of-frames)
1192 ;; The help window is a new window on an existing frame. This
1193 ;; case must be handled specially by `help-window-setup-finish'
1194 ;; and `view-mode-exit' to ascertain that quitting does _not_
1195 ;; inadvertently delete the frame.
1196 (view-return-to-alist-update
1197 help-buffer (cons help-window
1198 (cons (selected-window) 'keep-frame)))
1199 (help-window-setup-finish help-window nil t))
1200 (t
1201 ;; The help window is shown on a new frame. In this case quitting
1202 ;; shall handle both, the help window _and_ its frame. We changed
1203 ;; the default of `view-remove-frame-by-deleting' to t in order to
1204 ;; intuitively DTRT here.
1205 (view-return-to-alist-update
1206 help-buffer (cons help-window (cons (selected-window) t)))
1207 (help-window-setup-finish help-window)))))
1208 1113
1209;; `with-help-window' is a wrapper for `with-output-to-temp-buffer' 1114;; `with-help-window' is a wrapper for `with-output-to-temp-buffer'
1210;; providing the following additional twists: 1115;; providing the following additional twists:
@@ -1212,50 +1117,35 @@ window itself is specified by the variable `help-window'."
1212;; (1) Issue more accurate messages telling how to scroll and quit the 1117;; (1) Issue more accurate messages telling how to scroll and quit the
1213;; help window. 1118;; help window.
1214 1119
1215;; (2) Make `view-mode-exit' DTRT in more cases. 1120;; (2) An option (customizable via `help-window-select') to select the
1216
1217;; (3) An option (customizable via `help-window-select') to select the
1218;; help window automatically. 1121;; help window automatically.
1219 1122
1220;; (4) A marker (`help-window-point-marker') to move point in the help 1123;; (3) A marker (`help-window-point-marker') to move point in the help
1221;; window to an arbitrary buffer position. 1124;; window to an arbitrary buffer position.
1222 1125
1223;; Note: It's usually always wrong to use `help-print-return-message' in 1126;; Note: It's usually always wrong to use `help-print-return-message' in
1224;; the body of `with-help-window'. 1127;; the body of `with-help-window'.
1225(defmacro with-help-window (buffer-name &rest body) 1128(defmacro with-help-window (buffer-name &rest body)
1226 "Display buffer BUFFER-NAME in a help window evaluating BODY. 1129 "Display buffer with name BUFFER-NAME in a help window evaluating BODY.
1227Select help window if the actual value of the user option 1130Select help window if the actual value of the user option
1228`help-window-select' says so. Return last value in BODY." 1131`help-window-select' says so. Return last value in BODY.
1132
1133You can specify where and how to show the buffer by binding the
1134variable `temp-buffer-show-specifiers' to an appropriate value."
1229 (declare (indent 1) (debug t)) 1135 (declare (indent 1) (debug t))
1230 ;; Bind list-of-frames to `frame-list' and list-of-window-tuples to a 1136 `(progn
1231 ;; list of one <window window-buffer window-start window-point> tuple 1137 ;; Reset `display-buffer-window': `display-buffer' is
1232 ;; for each live window. 1138 ;; supposed to set this to the window displaying the buffer plus
1233 `(let ((list-of-frames (frame-list)) 1139 ;; some additional information.
1234 (list-of-window-tuples 1140 (setq display-buffer-window nil)
1235 (let (list) 1141 ;; Make `help-window-point-marker' point nowhere. The only place
1236 (walk-windows 1142 ;; where this should be set to a buffer position is within BODY.
1237 (lambda (window)
1238 (push (list window (window-buffer window)
1239 (window-start window) (window-point window))
1240 list))
1241 'no-mini t)
1242 list)))
1243 ;; Make `help-window' t to trigger `help-mode-finish' to set
1244 ;; `help-window' to the actual help window.
1245 (setq help-window t)
1246 ;; Make `help-window-point-marker' point nowhere (the only place
1247 ;; where this should be set to a buffer position is within BODY).
1248 (set-marker help-window-point-marker nil) 1143 (set-marker help-window-point-marker nil)
1249 (prog1 1144 (prog1
1250 ;; Return value returned by `with-output-to-temp-buffer'. 1145 ;; Return value returned by `with-output-to-temp-buffer'.
1251 (with-output-to-temp-buffer ,buffer-name 1146 (with-output-to-temp-buffer ,buffer-name
1252 (progn ,@body)) 1147 (progn ,@body))
1253 (when (windowp help-window) 1148 (when display-buffer-window (help-window-setup)))))
1254 ;; Set up help window.
1255 (help-window-setup list-of-frames list-of-window-tuples))
1256 ;; Reset `help-window' to nil to avoid confusing future calls of
1257 ;; `help-mode-finish' with plain `with-output-to-temp-buffer'.
1258 (setq help-window nil))))
1259 1149
1260;; Called from C, on encountering `help-char' when reading a char. 1150;; Called from C, on encountering `help-char' when reading a char.
1261;; Don't print to *Help*; that would clobber Help history. 1151;; Don't print to *Help*; that would clobber Help history.
diff --git a/lisp/view.el b/lisp/view.el
index e91c4dd175c..ee85b4e7823 100644
--- a/lisp/view.el
+++ b/lisp/view.el
@@ -55,10 +55,6 @@
55 :type 'face 55 :type 'face
56 :group 'view) 56 :group 'view)
57 57
58;; `view-mode-auto-exit' is replaced by the following option variable which
59;; only says if scrolling past buffer end should leave view mode or not, it
60;; doesn't say if leaving view mode should restore windows or not. The latter
61;; is now controlled by the presence of a value in `view-return-to-alist'.
62(defcustom view-scroll-auto-exit nil 58(defcustom view-scroll-auto-exit nil
63 "Non-nil means scrolling past the end of buffer exits View mode. 59 "Non-nil means scrolling past the end of buffer exits View mode.
64A value of nil means attempting to scroll past the end of the buffer, 60A value of nil means attempting to scroll past the end of the buffer,
@@ -80,17 +76,14 @@ for all scroll commands in view mode."
80If nil, make an icon of the frame. If non-nil, delete the frame." 76If nil, make an icon of the frame. If non-nil, delete the frame."
81 :type 'boolean 77 :type 'boolean
82 :group 'view 78 :group 'view
83 ;; Changed the default of this to t for Emacs 23. Users consider
84 ;; frame iconification annoying.
85 :version "23.1") 79 :version "23.1")
86 80
87(defcustom view-exits-all-viewing-windows nil 81(defcustom view-exits-all-viewing-windows nil
88 "Non-nil means restore all windows used to view buffer. 82 "Non-nil means restore all windows used to view buffer.
89Commands that restore windows when finished viewing a buffer, apply to all 83Commands that restore windows when finished viewing a buffer,
90windows that display the buffer and have restore information in 84apply to all windows that display the buffer and have restore
91`view-return-to-alist'. 85information. If `view-exits-all-viewing-windows' is nil, only
92If `view-exits-all-viewing-windows' is nil, only the selected window is 86the selected window is considered for restoring."
93considered for restoring."
94 :type 'boolean 87 :type 'boolean
95 :group 'view) 88 :group 'view)
96 89
@@ -140,6 +133,8 @@ subtracted from by `view-mode-exit' when finished viewing the buffer.
140 133
141See RETURN-TO-ALIST argument of function `view-mode-exit' for the format of 134See RETURN-TO-ALIST argument of function `view-mode-exit' for the format of
142`view-return-to-alist'.") 135`view-return-to-alist'.")
136(make-obsolete-variable
137 'view-return-to-alist "this variable is no more used." "24.1")
143(make-variable-buffer-local 'view-return-to-alist) 138(make-variable-buffer-local 'view-return-to-alist)
144(put 'view-return-to-alist 'permanent-local t) 139(put 'view-return-to-alist 'permanent-local t)
145 140
@@ -322,63 +317,48 @@ EXIT-ACTION to `kill-buffer-if-not-modified' avoids this."
322 (progn 317 (progn
323 (switch-to-buffer buffer) 318 (switch-to-buffer buffer)
324 (message "Not using View mode because the major mode is special")) 319 (message "Not using View mode because the major mode is special"))
325 (let ((undo-window (list (window-buffer) (window-start) (window-point)))) 320 (pop-to-buffer-same-window buffer)
326 (switch-to-buffer buffer) 321 (view-mode-enter nil exit-action)))
327 (view-mode-enter (cons (selected-window) (cons nil undo-window))
328 exit-action))))
329 322
330;;;###autoload 323;;;###autoload
331(defun view-buffer-other-window (buffer &optional not-return exit-action) 324(defun view-buffer-other-window (buffer &optional not-return exit-action)
332 "View BUFFER in View mode in another window. 325 "View BUFFER in View mode in another window.
333Return to previous buffer when done, unless optional NOT-RETURN is 326Emacs commands editing the buffer contents are not available;
334non-nil. Emacs commands editing the buffer contents are not available; 327instead, a special set of commands (mostly letters and
335instead, a special set of commands (mostly letters and punctuation) are 328punctuation) are defined for moving around in the buffer.
336defined for moving around in the buffer.
337Space scrolls forward, Delete scrolls backward. 329Space scrolls forward, Delete scrolls backward.
338For a list of all View commands, type H or h while viewing. 330For a list of all View commands, type H or h while viewing.
339 331
340This command runs the normal hook `view-mode-hook'. 332This command runs the normal hook `view-mode-hook'.
341 333
334Optional argument NOT-RETURN is ignored.
335
342Optional argument EXIT-ACTION is either nil or a function with buffer as 336Optional argument EXIT-ACTION is either nil or a function with buffer as
343argument. This function is called when finished viewing buffer. Use 337argument. This function is called when finished viewing buffer. Use
344this argument instead of explicitly setting `view-exit-action'." 338this argument instead of explicitly setting `view-exit-action'."
345 (interactive "bIn other window view buffer:\nP") 339 (interactive "bIn other window view buffer:\nP")
346 (let* ((win ; This window will be selected by 340 (pop-to-buffer-other-window buffer)
347 (get-lru-window)) ; switch-to-buffer-other-window below. 341 (view-mode-enter nil exit-action))
348 (return-to
349 (and (not not-return)
350 (cons (selected-window)
351 (if (eq win (selected-window))
352 t ; Has to make new window.
353 (list
354 (window-buffer win) ; Other windows old buffer.
355 (window-start win)
356 (window-point win)))))))
357 (switch-to-buffer-other-window buffer)
358 (view-mode-enter (and return-to (cons (selected-window) return-to))
359 exit-action)))
360 342
361;;;###autoload 343;;;###autoload
362(defun view-buffer-other-frame (buffer &optional not-return exit-action) 344(defun view-buffer-other-frame (buffer &optional not-return exit-action)
363 "View BUFFER in View mode in another frame. 345 "View BUFFER in View mode in another frame.
364Return to previous buffer when done, unless optional NOT-RETURN is 346Emacs commands editing the buffer contents are not available;
365non-nil. Emacs commands editing the buffer contents are not available; 347instead, a special set of commands (mostly letters and
366instead, a special set of commands (mostly letters and punctuation) are 348punctuation) are defined for moving around in the buffer.
367defined for moving around in the buffer.
368Space scrolls forward, Delete scrolls backward. 349Space scrolls forward, Delete scrolls backward.
369For a list of all View commands, type H or h while viewing. 350For a list of all View commands, type H or h while viewing.
370 351
371This command runs the normal hook `view-mode-hook'. 352This command runs the normal hook `view-mode-hook'.
372 353
354Optional argument NOT-RETURN is ignored.
355
373Optional argument EXIT-ACTION is either nil or a function with buffer as 356Optional argument EXIT-ACTION is either nil or a function with buffer as
374argument. This function is called when finished viewing buffer. Use 357argument. This function is called when finished viewing buffer. Use
375this argument instead of explicitly setting `view-exit-action'." 358this argument instead of explicitly setting `view-exit-action'."
376 (interactive "bView buffer in other frame: \nP") 359 (interactive "bView buffer in other frame: \nP")
377 (let ((return-to 360 (pop-to-buffer-other-frame buffer)
378 (and (not not-return) (cons (selected-window) t)))) ; Old window. 361 (view-mode-enter nil exit-action))
379 (switch-to-buffer-other-frame buffer)
380 (view-mode-enter (and return-to (cons (selected-window) return-to))
381 exit-action)))
382 362
383;;;###autoload 363;;;###autoload
384(define-minor-mode view-mode 364(define-minor-mode view-mode
@@ -536,38 +516,27 @@ entry for the selected window, purge that entry from
536 (when item 516 (when item
537 (setq view-return-to-alist 517 (setq view-return-to-alist
538 (cons item view-return-to-alist))))) 518 (cons item view-return-to-alist)))))
519(make-obsolete 'view-return-to-alist-update "this function has no effect." "24.1")
539 520
540;;;###autoload 521;;;###autoload
541(defun view-mode-enter (&optional return-to exit-action) 522(defun view-mode-enter (&optional quit-restore exit-action)
542 "Enter View mode and set up exit from view mode depending on optional arguments. 523 "Enter View mode and set up exit from view mode depending on optional arguments.
543RETURN-TO non-nil means add RETURN-TO as an element to the buffer 524Optional argument QUIT-RESTORE if non-nil must specify a valid
544local alist `view-return-to-alist'. Save EXIT-ACTION in buffer 525entry for quitting and restoring any window showing the current
545local variable `view-exit-action'. It should be either nil or a 526buffer. This entry replaces any parameter installed by
527`display-buffer' and is used by `view-mode-exit'.
528
529Optional argument EXIT-ACTION, if non-nil, must specify a
546function that takes a buffer as argument. This function will be 530function that takes a buffer as argument. This function will be
547called by `view-mode-exit'. 531called by `view-mode-exit'.
548 532
549RETURN-TO is either nil, meaning do nothing when exiting view
550mode, or must have the format (WINDOW OLD-WINDOW . OLD-BUF-INFO).
551WINDOW is the window used for viewing. OLD-WINDOW is nil or the
552window to select after viewing. OLD-BUF-INFO tells what to do
553with WINDOW when exiting. It is one of:
5541) nil Do nothing.
5552) t Delete WINDOW or, if it is the only window and
556 `view-remove-frame-by-deleting' is non-nil, its
557 frame.
5583) (OLD-BUFF START POINT) Display buffer OLD-BUFF with displayed text
559 starting at START and point at POINT in WINDOW.
5604) quit-window Do `quit-window' in WINDOW.
5615) keep-frame Like case 2) but do not delete the frame.
562
563For a list of all View commands, type H or h while viewing. 533For a list of all View commands, type H or h while viewing.
564 534
565This function runs the normal hook `view-mode-hook'." 535This function runs the normal hook `view-mode-hook'."
566 (when return-to 536 (when quit-restore
567 (let ((entry (assq (car return-to) view-return-to-alist))) 537 (dolist (window (get-buffer-window-list nil nil t))
568 (if entry 538 (set-window-parameter window 'quit-restore quit-restore)))
569 (setcdr entry (cdr return-to)) 539
570 (setq view-return-to-alist (cons return-to view-return-to-alist)))))
571 (when exit-action 540 (when exit-action
572 (setq view-exit-action exit-action)) 541 (setq view-exit-action exit-action))
573 542
@@ -579,115 +548,45 @@ This function runs the normal hook `view-mode-hook'."
579 (substitute-command-keys "\ 548 (substitute-command-keys "\
580View mode: type \\[help-command] for help, \\[describe-mode] for commands, \\[View-quit] to quit."))))) 549View mode: type \\[help-command] for help, \\[describe-mode] for commands, \\[View-quit] to quit.")))))
581 550
582(defun view-mode-exit (&optional return-to-alist exit-action all-win) 551;; This is awful because it assumes that the selected window shows the
583 "Exit View mode in various ways, depending on optional arguments. 552;; current buffer when this is called.
584RETURN-TO-ALIST, EXIT-ACTION and ALL-WIN determine what to do 553(defun view-mode-exit (&optional exit-only exit-action all-windows)
585after exit. EXIT-ACTION is nil or a function that is called with 554 "Exit View mode in various ways.
586current buffer as argument. 555If all arguments are nil, remove the current buffer from the
587 556selected window using the `quit-restore' information associated
588RETURN-TO-ALIST is an alist that, for some of the windows 557with the selected window. If optional argument ALL-WINDOWS or
589displaying the current buffer, maintains information on what to 558`view-exits-all-viewing-windows' are non-nil, remove the current
590do when exiting those windows. If ALL-WIN is non-nil or the 559buffer from all windows showing it.
591variable `view-exits-all-viewing-windows' is non-nil, 560
592view-mode-exit attempts to restore all windows showing the 561Optional argument EXIT-ONLY non-nil means just exit `view-mode'
593current buffer to their old state. Otherwise, only the selected 562\(unless `view-no-disable-on-exit' is non-nil) but do not change
594window is affected (provided it is on RETURN-TO-ALIST). 563the associations of any windows with the current buffer.
595 564
596Elements of RETURN-TO-ALIST must have the format 565EXIT-ACTION, if non-nil, must specify a function that is called
597 (WINDOW OLD-WINDOW . OLD-BUF-INFO) where 566with the current buffer as argument and is called after disabling
598 567`view-mode' and removing any associations of windows with the
599WINDOW is a window displaying the current buffer and OLD-WINDOW 568current buffer. "
600is either nil or a window to select after viewing. OLD-BUF-INFO 569 (when view-mode
601provides information on what to do with WINDOW and may be one of: 570 (let ((buffer (window-buffer)))
6021) nil Do nothing.
6032) t Delete WINDOW and, if it is the only window and
604 `view-remove-frame-by-deleting' is non-nil, its
605 frame.
6063) (OLD-BUF START POINT) Display buffer OLD-BUF with displayed text
607 starting at START and point at POINT in WINDOW.
6084) quit-window Do `quit-window' in WINDOW.
6095) keep-frame Like case 2) but do not delete the frame.
610
611If one of the WINDOW in RETURN-TO-ALIST is the selected window
612and the corresponding OLD-WINDOW is a live window, then select
613OLD-WINDOW."
614 (when view-mode ; Only do something if in view mode.
615 (setq all-win
616 (and return-to-alist
617 (or all-win view-exits-all-viewing-windows)))
618 (let* ((buffer (current-buffer))
619 window notlost
620 (sel-old (assq (selected-window) return-to-alist))
621 (alist (cond
622 (all-win ; Try to restore all windows.
623 (append return-to-alist nil)) ; Copy.
624 (sel-old ; Only selected window.
625 (list sel-old))))
626 (old-window (if sel-old (car (cdr sel-old)))))
627 (if all-win ; Follow chains of old-windows.
628 (let ((c (length alist)) a)
629 (while (and (> c 0) ; Safety if mutually refering windows.
630 (or (not (window-live-p old-window))
631 (eq buffer (window-buffer old-window)))
632 (setq a (assq old-window alist)))
633 (setq c (1- c))
634 (setq old-window (car (cdr a))))
635 (if (or (zerop c) (not (window-live-p old-window)))
636 (setq old-window (selected-window)))))
637 (unless view-no-disable-on-exit 571 (unless view-no-disable-on-exit
638 (view-mode-disable)) 572 (view-mode-disable))
639 (while alist ; Restore windows with info. 573
640 (setq notlost nil) 574 (unless exit-only
641 (when (and (window-live-p (setq window (car (car alist)))) 575 (cond
642 (eq buffer (window-buffer window))) 576 ((or all-windows view-exits-all-viewing-windows)
643 (let ((frame (window-frame window)) 577 (dolist (window (get-buffer-window-list))
644 (old-buf-info (cdr (cdr (car alist))))) 578 (quit-restore-window window)))
645 (if all-win (select-window window)) 579 ((eq (window-buffer) (current-buffer))
646 (cond 580 (quit-restore-window)))
647 ((consp old-buf-info) ; Case 3. 581
648 (if (buffer-live-p (car old-buf-info)) 582 (when exit-action
649 (progn 583 (funcall exit-action buffer))
650 (set-window-buffer window (car old-buf-info)) ; old-buf 584 (force-mode-line-update)))))
651 (set-window-start window (car (cdr old-buf-info)))
652 (set-window-point window (car (cdr (cdr old-buf-info)))))
653 (bury-buffer)))
654 ((eq old-buf-info 'quit-window)
655 (quit-window)) ; Case 4.
656 (old-buf-info ; Case 2 or 5.
657 (cond
658 ((not (one-window-p t)) ; Not only window.
659 (delete-window))
660 ((eq old-buf-info 'keep-frame) ; Case 5.
661 (bury-buffer))
662 ((not (eq frame (next-frame))) ; Case 2 and only window.
663 ;; Not the only frame, so can safely be removed.
664 (if view-remove-frame-by-deleting
665 (delete-frame frame)
666 (setq notlost t) ; Keep the window. See below.
667 (iconify-frame frame))))))))
668 ;; If a frame is removed by iconifying it, the window is not
669 ;; really lost. In this case we keep the entry in
670 ;; `view-return-to-alist' so that if the user deiconifies the
671 ;; frame and then hits q, the frame is iconified again.
672 (unless notlost
673 (with-current-buffer buffer
674 (setq view-return-to-alist
675 (delete (car alist) view-return-to-alist))))
676 (setq alist (cdr alist)))
677 (when (window-live-p old-window)
678 ;; old-window is still alive => select it.
679 (select-window old-window))
680 (when exit-action
681 ;; Don't do that: If the user wants to quit the *Help* buffer a
682 ;; second time it won't have any effect.
683 ;;(setq view-exit-action nil)
684 (funcall exit-action buffer))
685 (force-mode-line-update))))
686 585
687(defun View-exit () 586(defun View-exit ()
688 "Exit View mode but stay in current buffer." 587 "Exit View mode but stay in current buffer."
689 (interactive) 588 (interactive)
690 (view-mode-exit)) 589 (view-mode-exit t))
691 590
692;;;###autoload 591;;;###autoload
693(defun View-exit-and-edit () 592(defun View-exit-and-edit ()
@@ -695,31 +594,31 @@ OLD-WINDOW."
695 (interactive) 594 (interactive)
696 (let ((view-old-buffer-read-only nil) 595 (let ((view-old-buffer-read-only nil)
697 (view-no-disable-on-exit nil)) 596 (view-no-disable-on-exit nil))
698 (view-mode-exit))) 597 (view-mode-exit t)))
699 598
700(defun View-leave () 599(defun View-leave ()
701 "Quit View mode and maybe switch buffers, but don't kill this buffer." 600 "Quit View mode and maybe switch buffers, but don't kill this buffer."
702 (interactive) 601 (interactive)
703 (view-mode-exit view-return-to-alist)) 602 (view-mode-exit))
704 603
705(defun View-quit () 604(defun View-quit ()
706 "Quit View mode, trying to restore window and buffer to previous state. 605 "Quit View mode, trying to restore window and buffer to previous state.
707Maybe kill this buffer. Try to restore selected window to previous state 606Maybe kill this buffer. Try to restore selected window to previous state
708and go to previous buffer or window." 607and go to previous buffer or window."
709 (interactive) 608 (interactive)
710 (view-mode-exit view-return-to-alist view-exit-action)) 609 (view-mode-exit nil view-exit-action))
711 610
712(defun View-quit-all () 611(defun View-quit-all ()
713 "Quit View mode, trying to restore windows and buffers to previous state. 612 "Quit View mode, trying to restore windows and buffers to previous state.
714Maybe kill current buffer. Try to restore all windows viewing buffer to 613Maybe kill current buffer. Try to restore all windows viewing buffer to
715previous state and go to previous buffer or window." 614previous state and go to previous buffer or window."
716 (interactive) 615 (interactive)
717 (view-mode-exit view-return-to-alist view-exit-action t)) 616 (view-mode-exit nil view-exit-action t))
718 617
719(defun View-kill-and-leave () 618(defun View-kill-and-leave ()
720 "Quit View mode, kill current buffer and return to previous buffer." 619 "Quit View mode, kill current buffer and return to previous buffer."
721 (interactive) 620 (interactive)
722 (view-mode-exit view-return-to-alist (or view-exit-action 'kill-buffer) t)) 621 (view-mode-exit nil (or view-exit-action 'kill-buffer) t))
723 622
724 623
725;;; Some help routines. 624;;; Some help routines.
@@ -863,7 +762,7 @@ invocations return to earlier marks."
863(defun view-end-message () 762(defun view-end-message ()
864 ;; Tell that we are at end of buffer. 763 ;; Tell that we are at end of buffer.
865 (goto-char (point-max)) 764 (goto-char (point-max))
866 (if view-return-to-alist 765 (if (window-parameter nil 'quit-restore)
867 (message "End of buffer. Type %s to quit viewing." 766 (message "End of buffer. Type %s to quit viewing."
868 (substitute-command-keys 767 (substitute-command-keys
869 (if view-scroll-auto-exit "\\[View-scroll-page-forward]" 768 (if view-scroll-auto-exit "\\[View-scroll-page-forward]"
diff --git a/lisp/window.el b/lisp/window.el
index 94ac9143efd..cad4e15507d 100644
--- a/lisp/window.el
+++ b/lisp/window.el
@@ -3455,19 +3455,2266 @@ specific buffers."
3455 )) 3455 ))
3456 3456
3457 3457
3458
3459(defconst display-buffer-default-specifiers
3460 '((reuse-window nil same visible)
3461 (pop-up-window (largest . nil) (lru . nil))
3462 (pop-up-frame)
3463 (pop-up-frame-alist
3464 (height . 24) (width . 80) (unsplittable . t))
3465 (reuse-window nil other visible)
3466 (reuse-window-even-sizes . t))
3467 "Buffer display default specifiers.
3468The value specified here is used when no other specifiers have
3469been specified by the user or the application. Consult the
3470documentation of `display-buffer-alist' for a description of
3471buffer display specifiers.")
3472
3473(defconst display-buffer-macro-specifiers
3474 '((same-window
3475 ;; Use the same window.
3476 (reuse-window same nil nil))
3477 (same-frame
3478 ;; Avoid other frames.
3479 (reuse-window nil same nil)
3480 (pop-up-window (largest . nil) (lru . nil))
3481 (reuse-window nil other nil))
3482 (other-window
3483 ;; Avoid selected window.
3484 (reuse-window other same visible)
3485 (pop-up-window (largest . nil) (lru . nil))
3486 (pop-up-frame)
3487 (reuse-window other other visible))
3488 (same-frame-other-window
3489 ;; Avoid other frames and selected window.
3490 (reuse-window other same nil)
3491 (pop-up-window (largest . nil) (lru . nil))
3492 (reuse-window other other nil))
3493 (other-frame
3494 ;; Avoid selected frame.
3495 (reuse-window nil same other)
3496 (pop-up-frame)
3497 (reuse-window nil other other))
3498 (default
3499 ;; The default specifiers.
3500 display-buffer-default-specifiers))
3501 "Buffer display macro specifiers.")
3502
3503(defcustom display-buffer-alist
3504 '((((regexp . ".*"))
3505 reuse-window (reuse-window nil same visible)
3506 pop-up-window
3507 (pop-up-window (largest . nil) (lru . nil))
3508 pop-up-frame
3509 (pop-up-frame)
3510 reuse-window (reuse-window nil other visible)
3511 (reuse-window-even-sizes . t)))
3512 "List associating buffer identifiers with display specifiers.
3513The car of each element of this list is built from a set of cons
3514cells called buffer identifiers. `display-buffer' shows a buffer
3515according to the display specifiers in the element's cdr
3516\(elements are true lists) if at least one of the identifiers
3517matches the first or third argument of `display-buffer'. Such a
3518match occurs in one of the following three cases:
3519
3520- The car of the buffer identifier is the symbol `name' and its
3521 cdr is a string equalling the name of the buffer specified by
3522 the first \(BUFFER-OR-NAME) argument of `display-buffer'.
3523
3524- The car is the symbol `regexp' and the cdr is a regular
3525 expression matching the name of the buffer specified by the
3526 first \(BUFFER-OR-NAME) argument of `display-buffer'.
3527
3528- The car is the symbol `label' and the cdr is a symbol equalling
3529 the third \(LABEL) argument of `display-buffer'.
3530
3531Display specifiers are either symbols, cons cells, or lists.
3532Five specifiers have been reserved to indicate the basic method
3533for displaying the buffer: `reuse-window', `pop-up-window',
3534`pop-up-frame', `use-side-window', and `fun-with-args'.
3535
3536A list whose car is the symbol `reuse-window' indicates that an
3537existing window shall be reused for displaying the buffer. The
3538second element of this list specifies the window to use and can
3539be one of the following symbols:
3540
3541 nil stands for any window.
3542
3543 `same' stands for the selected window.
3544
3545 `other' stands for any but the selected window.
3546
3547The third element specifies whether the buffer shown in a window
3548that shall be reused must be the same buffer that shall be
3549displayed or another buffer and can be one of the following:
3550
3551 nil means to not care about the window's buffer.
3552
3553 `same' means the window must show the buffer already.
3554
3555 `other' means the window must not show the buffer yet.
3556
3557The fourth element specifies the set of frames to search for a
3558suitable window and can be one of the following:
3559
3560 nil to reuse a window on the selected frame.
3561
3562 `visible' to search visible frames on the current terminal.
3563
3564 `other' stands for any visible frame but the selected one.
3565
3566 0 \(the number zero) to search visible and iconified frames on
3567 the current terminal.
3568
3569 t to search arbitrary frames including invisible ones.
3570
3571If more than one window fits the constraints imposed by these
3572elements, the least recently used candidate is chosen. A side
3573window is never reused unless it already shows the buffer.
3574
3575The following two specifiers are useful when the method equals
3576`reuse-window':
3577
3578- A cons cell whose car is the symbol `reuse-window-even-sizes'
3579 and whose cdr is non-nil means to even out the sizes of a
3580 reused window and the selected window provided they (1) appear
3581 adjacent to each other and (2) the selected window is larger
3582 than the window chosen. If the cdr is nil, this means that the
3583 window sizes are left alone.
3584
3585- A cons cell whose car is the symbol `reuse-window-dedicated'
3586 and whose cdr is non-nil means that a window can be reused even
3587 if it's weakly dedicated to its buffer. If the cdr is t, a
3588 strongly dedicated window can be reused to show the buffer.
3589 Any other non-nil value means only weakly dedicated windows can
3590 be reused. If the cdr is nil, dedicated windows are not
3591 reused.
3592
3593 This specifier should be used in emergency cases only since
3594 windows are usually made dedicated in order to prevent
3595 `display-buffer' from reusing them.
3596
3597A list whose car is the symbol `pop-up-window' and whose cdr is
3598built from cons cells representing window/side tuples indicates
3599that a new window shall be made for displaying the buffer on the
3600selected frame.
3601
3602Window/side tuples are cons cells. The car of such a tuple
3603identifies the window that shall be split. Possible values are
3604`largest', `lru', `selected', and `root' to split the largest,
3605least recently used, selected or root window of the selected
3606frame.
3607
3608If the frame has side windows, these values do allow to split
3609only the selected frame's main window or one of its subwindows.
3610Setting the car to one of `left', `top', `right' and `bottom'
3611splits the corresponding side window, provided such a window
3612exists.
3613
3614The cdr of each pair specifies on which side of the window to
3615split the new window shall appear and can be one of `below',
3616`right', `above', or `left' with the obvious meanings. If the
3617cdr is nil, the window is split in a fashion suitable for its
3618current dimensions. If the cdr specifies a function, that
3619function is called with one argument - the window to split. The
3620function is supposed to split that window and return the new
3621window.
3622
3623`display-buffer' scans these tuples until it can either produce a
3624suitable window or fails. The default value for
3625`display-buffer-alist' contains the tuples \(largest . nil) and
3626\(lru . nil) in order to split the largest window first and, if
3627that fails, the least recently used one.
3628
3629The following specifiers are useful if the method specifier is
3630`pop-up-window'.
3631
3632- A cons cell whose car is the symbol `pop-up-window-min-height'
3633 specifiies the minimum height of the new window. If the cdr is
3634 an integer number, it specifies the minimum number of lines of
3635 the window. A floating point number gives the minimum fraction
3636 of the window height with respect to the height of the frame's
3637 root window. A new window is created only if it can be made at
3638 least as high as specified by the number. If the cdr is nil,
3639 this means to use the value of `window-min-height'.
3640
3641- A cons cell whose car is the symbol `pop-up-window-min-width'
3642 specifies the minimum width of the new window. If the cdr is
3643 an integer number, it specifies the minimum number of columns
3644 of the window. A floating point number gives the minimum
3645 fraction of the window width with respect to the width of the
3646 frame's root window. A new window is created only if it can be
3647 made at least as wide as specified by the number. If the cdr
3648 is nil, this means to use the value of `window-min-width'.
3649
3650- A cons cell whose car is `pop-up-window-set-height' with
3651 the following interpretations for the cdr:
3652
3653 - nil means leave the height of the new window alone.
3654
3655 - A number specifies the desired height of the new window. An
3656 integer number specifies the number of lines of the window.
3657 A floating point number gives the fraction of the window
3658 height with respect to the height of the frame's root window.
3659
3660 - If the cdr specifies a function, that function is called with
3661 one argument - the new window. The function is supposed to
3662 adjust the height of the window; its return value is ignored.
3663 Suitable functions are `shrink-window-if-larger-than-buffer'
3664 and `fit-window-to-buffer'.
3665
3666- A cons cell whose car equals `pop-up-window-set-width' with
3667 the following interpretations for the cdr:
3668
3669 - nil means leave the width of the new window alone.
3670
3671 - A number specifies the desired width of the new window. An
3672 integer number specifies the number of columns of the window.
3673 A floating point number gives the fraction of the window
3674 width with respect to the width of the frame's root window.
3675
3676 - If the cdr specifies a function, that function is called with
3677 one argument - the new window. The function is supposed to
3678 adjust the width of the window; its return value is ignored.
3679
3680 Observe that specifying `pop-up-window-set-height' or
3681 `pop-up-window-set-width' may override restrictions given by
3682 the `pop-up-window-min-height' and `pop-up-window-min-width'
3683 specifiers.
3684
3685- A cons cell whose car is `pop-up-window-split-unsplittable' and
3686 whose cdr is non-nil allows to make a new window on an
3687 unsplittable frame. If the cdr is nil, unsplittable frames are
3688 not split. This specifier should be used in special cases only
3689 since frames are usually made unsplittable in order to prevent
3690 `display-buffer' from splitting them.
3691
3692A list whose car is the symbol `pop-up-frame' specifies that a
3693new frame shall be made for displaying the buffer. The second
3694element, if non-nil, allows popping up a new frame on graphic
3695displays only.
3696
3697The following specifiers are useful if the method specifier is
3698`pop-up-frame'.
3699
3700- A list whose car is the symbol `pop-up-frame-function' together
3701 with a valid function as cdr specifies the function for
3702 creating a new frame. If the cdr is nil, the default function
3703 `make-frame' is called. The function is called with the
3704 parameters and values provided by the specifier described next.
3705
3706- A list whose car is the symbol `pop-up-frame-alist' followed by
3707 an arbitrary number of frame parameter/value tuples, each given
3708 as a cons cell, specifies the parameters passed to the pop-up
3709 frame function.
3710
3711A list of three elements whose car is the symbol
3712`use-side-window' specifies that the buffer shall be displayed in
3713a side window of the selected frame. The second element denotes
3714the side of the frame where the window appears or shall be made.
3715The third element denotes the slot used by the window. If a side
3716window with the specified slot exists already, that window is
3717reused. If no such window exists it is created.
3718
3719The following specifiers are useful in connection with the
3720`use-side-window' method specifier: `reuse-window-dedicated',
3721`pop-up-window-min-height', `pop-up-window-min-width',
3722`pop-up-window-set-height' and `pop-up-window-set-width'.
3723
3724A list whose car is the symbol `fun-with-args' specifies that the
3725function specified in the second element of the list is
3726responsible for displaying the buffer. `display-buffer' calls
3727this function with the buffer as first argument and the remaining
3728elements of the list as second argument.
3729
3730The function should choose or create a window, display the buffer
3731in it, and return the window. It is also responsible for giving
3732the variable `display-buffer-window' and the `quit-restore'
3733parameter of the window used a meaningful value.
3734
3735Within the body of this function avoid calling `display-buffer'
3736with the same buffer as argument since this may lead to endless
3737recursion.
3738
3739Instead of supplying basic method specifiers, it's sometimes more
3740convenient to use macro specifiers. They provide some commonly
3741used display methods but do not support the fine control provided
3742by the basic method specifiers. Macro specifiers are symbols.
3743The following macro specifiers are provided:
3744
3745 `same-window' to display the buffer in the selected window.
3746
3747 `same-frame' to display the buffer on the selected frame.
3748
3749 `other-window' to display the buffer in any window but the
3750 selected one.
3751
3752 `same-frame-other-window' as `other-window' but stay on the
3753 selected frame.
3754
3755 `other-frame' to display the buffer on another visible
3756 frame.
3757
3758 `default' to use the default value of `display-buffer-alist'.
3759
3760One specifier is useful with any method specifier: A list whose
3761car is the symbol `dedicate' and whose cdr is non-nil will
3762dedicate the window to its buffer. The following values are
3763supported:
3764
3765- nil to not dedicate the window to the buffer.
3766
3767- `weak' to weakly dedicate the window to the buffer.
3768
3769- t to strongly dedicate the window to the buffer.
3770
3771Usually, applications are free to override the specifiers of
3772`display-buffer-alist' by passing their own specifiers as second
3773argument of `display-buffer'. For every `display-buffer-alist'
3774entry you can, however, add a cons cell whose car is the symbol
3775`override' and whose cdr is non-nil, to explicitly override any
3776value supplied by the application.
3777
3778Overriding specifiers supplied by the calling application is, in
3779general, not advisable. It permits, for example, to change the
3780semantics of a function like `display-buffer-other-window' by
3781using the location specifiers `same-window' or `other-frame'."
3782 :risky t
3783 :type
3784 '(repeat
3785 :offset 9
3786 ;; Associations of buffer identifiers and display specifiers.
3787 (list
3788 :format "%v"
3789 ;; Buffer identifiers.
3790 (repeat
3791 :tag "Buffer identifiers"
3792 (choice
3793 :tag "Identifier"
3794 :format "%[%t%] %v" :size 15
3795 (cons
3796 :tag "Name"
3797 :format "%v"
3798 :help-echo "A buffer name."
3799 (const :format "" name)
3800 (string :format "Name: %v\n" :size 32))
3801 (cons
3802 :tag "Regexp"
3803 :format "%v"
3804 :help-echo "A regular expression matching buffer names."
3805 (const :format "" regexp)
3806 (string :format "Regexp: %v\n" :size 32))
3807 (cons
3808 :tag "Label"
3809 :format "%v"
3810 :help-echo "A symbol equalling the buffer display label."
3811 (const :format "" symbol)
3812 (symbol :format "Label: %v\n" :size 32))))
3813
3814 ;; Display specifiers.
3815 (repeat
3816 :offset 9
3817 :tag "Display specifiers"
3818 :inline t
3819 (list
3820 :inline t
3821 :format "%v"
3822 (choice
3823 :tag "Method"
3824 :value (reuse-window
3825 (reuse-window nil same nil)
3826 (reuse-window-even-sizes . t))
3827 :inline t
3828 :help-echo "Method for displaying the buffer."
3829 :format "%[Method%] %v" :size 15
3830
3831 ;; Reuse window specifiers.
3832 (list
3833 :tag "Reuse window"
3834 :value (reuse-window
3835 (reuse-window nil same nil)
3836 (reuse-window-even-sizes . t))
3837 :format "%t\n%v"
3838 :inline t
3839 ;; For customization purposes only.
3840 (const :format "" reuse-window)
3841 (set
3842 :format "%v"
3843 :inline t
3844 ;; The window to reuse.
3845 (list
3846 :format "%v\n"
3847 (const :format "" reuse-window)
3848 ;; The window type.
3849 (choice
3850 :tag "Window"
3851 :help-echo "Window to reuse."
3852 :value nil
3853 :format "%[Window%] %v" :size 15
3854 (const :tag "Any" :format "%t" nil)
3855 (const :tag "Selected only" :format "%t" same)
3856 (const :tag "Any but selected" :format "%t" other))
3857 ;; The window's buffer.
3858 (choice
3859 :tag "Buffer"
3860 :help-echo "Buffer shown by reused window."
3861 :value t
3862 :format " %[Buffer%] %v" :size 15
3863 (const :tag "Any buffer" :format "%t" nil)
3864 (const :tag "Same buffer" :format "%t" same)
3865 (const :tag "Other buffer" :format "%t" other))
3866 ;; The window's frame.
3867 (choice
3868 :help-echo "Frame to search for a window to reuse."
3869 :tag "Frame"
3870 :value nil
3871 :format " %[Frame%] %v" :size 15
3872 (const :tag "Selected frame only" :format "%t" nil)
3873 (const :tag "Visible frames" :format "%t" visible)
3874 (const :tag "Visible but unselected" :format "%t" other)
3875 (const :tag "Visible and iconified" :format "%t" 0)
3876 (const :tag "Any frame" :format "%t" t)))
3877 ;; Whether window sizes should be evened out.
3878 (cons
3879 :format "%v\n"
3880 :tag "Even window sizes"
3881 (const :format "" reuse-window-even-sizes)
3882 (choice
3883 :tag "Even window sizes"
3884 :help-echo "Whether to even sizes of selected and reused window."
3885 :value t
3886 :format "%[Even window sizes%] %v" :size 15
3887 (const :tag "Off" :format "%t" nil)
3888 (const :tag "Even window sizes" :format "%t" t)))
3889 ;; Whether to reuse a dedicated window
3890 (cons
3891 :format "%v\n"
3892 (const :format "" reuse-window-dedicated)
3893 (choice
3894 :tag "Reuse dedicated window" :value nil
3895 :help-echo "Reuse a window even if it is dedicated to its buffer."
3896 :format "%[Reuse dedicated window%] %v" :size 15
3897 (const :tag "Off" :format "%t" nil)
3898 (const :tag "Reuse weakly dedicated windows" :format "%t" weak)
3899 (const :tag "Reuse any dedicated window" :format "%t" t)))))
3900
3901 ;; Pop-up window specifiers.
3902 (list
3903 :tag "Pop-up window"
3904 :value (pop-up-window (pop-up-window (largest . nil) (lru . nil)))
3905 :format "%t\n%v"
3906 :inline t
3907 (const :format "" pop-up-window)
3908 (set
3909 :format "%v"
3910 :inline t
3911 ;; Pop-up window list.
3912 (list
3913 :format "%v"
3914 :value (pop-up-window (largest . nil) (lru . nil))
3915 (const :format "" pop-up-window)
3916 (repeat
3917 :tag "Window / Side tuples"
3918 :inline t
3919 (cons
3920 :format "%v\n"
3921 (choice
3922 :tag "Window"
3923 :help-echo "The window to split."
3924 :value largest
3925 :format "%[Window%] %v"
3926 (const :tag "Largest" :format "%t" largest)
3927 (const :tag "Least recently used" :format "%t" lru)
3928 (const :tag "Selected" :format "%t" selected)
3929 (const :tag "Root" :format "%t" root)
3930 (const :tag "Left" :format "%t" left)
3931 (const :tag "Top" :format "%t" top)
3932 (const :tag "Right" :format "%t" right)
3933 (const :tag "Bottom" :format "%t" bottom))
3934 (choice
3935 :tag "Side"
3936 :help-echo "The position of the new window with respect to the window to split."
3937 :value nil
3938 :format " %[Side%] %v"
3939 (const :tag "Dynamic" :format "%t" nil)
3940 (const :tag "Below" :format "%t" below)
3941 (const :tag "Right" :format "%t" right)
3942 (const :tag "Above" :format "%t" above)
3943 (const :tag "Left" :format "%t" left)
3944 (function
3945 :tag "Function" :format "%v" :size 25)))))
3946 ;; Minimum height of pop-up windows.
3947 (cons
3948 :format "%v\n"
3949 (const :format "" pop-up-window-min-height)
3950 (choice
3951 :help-echo "Minimum height of popped-up window."
3952 :format "%[Minimum height%] %v"
3953 (const :tag "Default" :format "%t" :value nil)
3954 (integer :tag "Number of lines" :value 12 :size 5)
3955 (float :tag "Fraction of frame height" :value .25 :size 5)))
3956 ;; Minimum width of pop-up windows.
3957 (cons
3958 :format "%v\n"
3959 (const :format "" pop-up-window-min-width)
3960 (choice
3961 :help-echo "Minimum width of popped-up window."
3962 :format "%[Minimum width%] %v"
3963 (const :tag "Default" :format "%t" :value nil)
3964 (integer :tag "Number of columns" :value 12 :size 5)
3965 (float :tag "Fraction of frame width" :value .25 :size 5)))
3966 ;; Desired height of pop-up windows.
3967 (cons
3968 :format "%v\n"
3969 (const :format "" pop-up-window-set-height)
3970 (choice
3971 :help-echo "Desired height of popped-up window."
3972 :format "%[Desired height%] %v"
3973 (const :tag "Default" :format "%t" :value nil)
3974 (integer :tag "Number of lines" :value 12 :size 5)
3975 (float :tag "Fraction of frame height" :value .25 :size 5)
3976 (function :tag "Function" :size 25)))
3977 ;; Desired width of pop-up windows.
3978 (cons
3979 :format "%v\n"
3980 (const :format "" pop-up-window-set-width)
3981 (choice
3982 :help-echo "Desired width of popped-up window."
3983 :format "%[Desired width%] %v"
3984 (const :tag "Default" :format "%t" :value nil)
3985 (integer :tag "Number of column" :value 12 :size 5)
3986 (float :tag "Fraction of frame width" :value .25 :size 5)
3987 (function :tag "Function" :size 25)))
3988 ;; Split unsplittable frames.
3989 (cons
3990 :format "%v\n"
3991 (const :format "" pop-up-window-unsplittable)
3992 (choice
3993 :help-echo "Allow popping up a window on \"unsplittable\" frames."
3994 :format "%[Split unsplittable frame%] %v"
3995 (const :tag "Off" :format "%t" nil)
3996 (const :tag "Allow" :format "%t" t)))))
3997
3998 ;; Pop-up frame specifiers.
3999 (list
4000 :tag "Pop-up frame"
4001 :value (pop-up-frame
4002 (pop-up-frame)
4003 (pop-up-frame-alist
4004 (height . 24) (width . 80) (unsplittable . t)))
4005 :format "%t\n%v"
4006 :inline t
4007 (const :format "" pop-up-frame)
4008 (set
4009 :format "%v"
4010 :inline t
4011 ;; Pop-up frame.
4012 (list
4013 :tag "Pop-up a new frame"
4014 :value (pop-up-frame)
4015 :format "%v"
4016 (const :format "" pop-up-frame)
4017 (choice
4018 :tag "Pop-up a new frame"
4019 :help-echo "Whether to pop-up a new frame on a display."
4020 :format "%[Display%] %v\n" :size 15
4021 (const :tag "On any display" :format "%t" nil)
4022 (const :tag "On graphic displays only" :format "%t" t)))
4023 ;; Pop-up frame function.
4024 (cons
4025 :format "%v\n"
4026 (const :format "" pop-up-frame-function)
4027 (choice
4028 :tag "Pop-up frame function"
4029 :value nil
4030 :help-echo "Function to use to pop-up a new frame."
4031 :format "%[Function%] %v" :size 15
4032 (const :tag "Default" :format "%t" nil)
4033 (function
4034 :value make-frame
4035 :format "%t: %v"
4036 :size 25)))
4037 ;; Pop-up frame alist.
4038 (list
4039 :format "%v"
4040 (const :format "" pop-up-frame-alist)
4041 (repeat
4042 :tag "Parameter / Value tuples"
4043 :inline t
4044 (cons
4045 :format "%v\n"
4046 (symbol
4047 :tag "Parameter"
4048 :format "Parameter: %v"
4049 :size 16)
4050 (sexp
4051 :tag "Value"
4052 :format " Value: %v"
4053 :size 8))))))
4054
4055 ;; Use side-window specifiers.
4056 (list
4057 :tag "Use side-window"
4058 :value (use-side-window (use-side-window bottom 0))
4059 :format "%t\n%v"
4060 :inline t
4061 ;; For customization purposes only.
4062 (const :format "" use-side-window)
4063 (set
4064 :format "%v"
4065 :inline t
4066 ;; Side and slot.
4067 (list
4068 :format "%v\n"
4069 :value (use-side-window bottom 0)
4070 (const :format "" use-side-window)
4071 ;; The side.
4072 (choice
4073 :tag "Side"
4074 :help-echo "Side of frame."
4075 :value bottom
4076 :format "%[Side%] %v" :size 15
4077 (const :tag "Left" :format "%t" left)
4078 (const :tag "Top" :format "%t" top)
4079 (const :tag "Right" :format "%t" right)
4080 (const :tag "Bottom" :format "%t" bottom))
4081 ;; The slot
4082 (number
4083 :tag "Slot"
4084 :help-echo "The slot (an arbitrary number, where 0 stands for the center slot)."
4085 :value 0
4086 :format " Slot: %v" :size 8))
4087 ;; Whether to reuse a dedicated side window
4088 (cons
4089 :format "%v\n"
4090 (const :format "" reuse-window-dedicated)
4091 (choice
4092 :tag "Reuse dedicated side window" :value nil
4093 :help-echo "Reuse a side window even if it is dedicated to its buffer."
4094 :format "%[Reuse dedicated side window%] %v" :size 15
4095 (const :tag "Off" :format "%t" nil)
4096 (const :tag "Reuse weakly dedicated side windows" :format "%t" weak)
4097 (const :tag "Reuse any dedicated side window" :format "%t" t)))
4098 ;; Minimum height of pop-up side windows.
4099 (cons
4100 :format "%v\n"
4101 (const :format "" pop-up-window-min-height)
4102 (choice
4103 :help-echo "Minimum height of popped-up side window."
4104 :format "%[Minimum height%] %v"
4105 (const :tag "Default" :format "%t" :value nil)
4106 (integer :tag "Number of lines" :value 12 :size 5)
4107 (float :tag "Fraction of frame height" :value .25 :size 5)))
4108 ;; Minimum width of pop-up windows.
4109 (cons
4110 :format "%v\n"
4111 (const :format "" pop-up-window-min-width)
4112 (choice
4113 :help-echo "Minimum width of popped-up side window."
4114 :format "%[Minimum width%] %v"
4115 (const :tag "Default" :format "%t" :value nil)
4116 (integer :tag "Number of columns" :value 12 :size 5)
4117 (float :tag "Fraction of frame width" :value .25 :size 5)))
4118 ;; Desired height of pop-up windows.
4119 (cons
4120 :format "%v\n"
4121 (const :format "" pop-up-window-set-height)
4122 (choice
4123 :help-echo "Desired height of popped-up side window."
4124 :format "%[Desired height%] %v"
4125 (const :tag "Default" :format "%t" :value nil)
4126 (integer :tag "Number of lines" :value 12 :size 5)
4127 (float :tag "Fraction of frame height" :value .25 :size 5)
4128 (function :tag "Function" :size 25)))
4129 ;; Desired width of pop-up windows.
4130 (cons
4131 :format "%v\n"
4132 (const :format "" pop-up-window-set-width)
4133 (choice
4134 :help-echo "Desired width of popped-up side window."
4135 :format "%[Desired width%] %v"
4136 (const :tag "Default" :format "%t" :value nil)
4137 (integer :tag "Number of column" :value 12 :size 5)
4138 (float :tag "Fraction of frame width" :value .25 :size 5)
4139 (function :tag "Function" :size 25)))))
4140
4141 ;; Function with argument specifiers.
4142 (list
4143 :tag "Function with arguments"
4144 :value (fun-with-args (fun-with-args 'ignore))
4145 :format "%t\n%v"
4146 :inline t
4147 ;; For customization purposes only.
4148 (const :format "" fun-with-args)
4149 (set
4150 :format "%v"
4151 :inline t
4152 (list
4153 :format "%v"
4154 :value (fun-with-args 'ignore)
4155 (const :format "" fun-with-args)
4156 (function :tag "Function" :format "%t: %v\n" :size 25)
4157 (list
4158 :format "%v"
4159 (repeat
4160 :tag "Arguments"
4161 :inline t
4162 (sexp
4163 :format "%v\n"
4164 :size 16))))))
4165
4166 ;; Macro specifiers.
4167 (list
4168 :tag "Same frame only"
4169 :format "%t%v"
4170 :inline t
4171 (const :format "\n" same-frame))
4172 (list
4173 :tag "Other window"
4174 :format "%t%v"
4175 :inline t
4176 (const :format "\n" other-window))
4177 (list
4178 :tag "Same frame other window"
4179 :format "%t%v"
4180 :inline t
4181 (const :format "\n" same-frame-other-window))
4182 (list
4183 :tag "Other frame only"
4184 :format "%t%v"
4185 :inline t
4186 (const :format "\n" other-frame))
4187 (list
4188 :tag "Default"
4189 :format "%t%v"
4190 :inline t
4191 (const :format "\n" default)))))
4192
4193 (set
4194 :format "%v"
4195 :inline t
4196 ;; Dedicate window to buffer.
4197 (cons
4198 :format "%v"
4199 (const :format "" dedicate)
4200 (choice
4201 :help-echo "Mark window as dedicated to its buffer."
4202 :format "%[Dedicate window to buffer%] %v\n" :size 15
4203 (const :tag "Off" :format "%t" nil)
4204 (const :tag "Weak" :format "%t" weak)
4205 (const :tag "Strong" :format "%t" t)))
4206 ;; No other window.
4207 (cons
4208 :format "%v"
4209 (const :format "" no-other-window)
4210 (choice
4211 :help-echo "Whether `other-window' shall ignore the window."
4212 :format "%[No other window%] %v\n" :size 15
4213 (const :tag "Off" :format "%t" nil)
4214 (const :tag "Ignore" :format "%t" t)))
4215 ;; Overriding.
4216 (cons
4217 :format "%v\n"
4218 (const :format "" override)
4219 (choice
4220 :help-echo "Override application supplied specifiers."
4221 :format "%[Override%] %v"
4222 (const :tag "Off" :format "%t" nil)
4223 (const :tag "Override" :format "%t" t))))))
4224 :group 'windows
4225 :group 'frames)
4226
3458(defcustom display-buffer-function nil 4227(defcustom display-buffer-function nil
3459 "If non-nil, function to call to handle `display-buffer'. 4228 "If non-nil, function to call to display a buffer.
3460It will receive two args, the buffer and a flag which if non-nil 4229`display-buffer' calls this function with two arguments, the
3461means that the currently selected window is not acceptable. It 4230buffer to display and a list of buffer display specifiers, see
3462should choose or create a window, display the specified buffer in 4231`display-buffer-alist'.
3463it, and return the window. 4232
3464 4233The function is supposed to choose or create a window, display
3465Commands such as `switch-to-buffer-other-window' and 4234the specified buffer in it, and return the window. It is also
3466`find-file-other-window' work using this function." 4235responsible for giving the variable `display-buffer-window' and
4236the `quit-restore' parameter of the window used a meaningful
4237value.
4238
4239The function specified here overrides all specifiers of the
4240variable `display-buffer-alist' any specifiers passed to
4241`display-buffer'.
4242
4243If you call `display-buffer' within the body of the function,
4244bind the value of `display-buffer-function' to nil around that
4245call to avoid that the function recursively calls itself."
3467 :type '(choice 4246 :type '(choice
3468 (const nil) 4247 (const nil)
3469 (function :tag "function")) 4248 (function :tag "Function"))
4249 :group 'windows)
4250
4251;; The following is a global variable which is used externally (by
4252;; help.el) to (1) know which window was used for displaying a buffer
4253;; and (2) whether the window was new or reused.
4254(defvar display-buffer-window nil
4255 "Window used by `display-buffer' and related information.
4256After `display-buffer' displays a buffer in some window this
4257variable is a cons cell whose car denotes the window used to
4258display the buffer. The cdr is supposed to be one of the symbols
4259`reuse-buffer-window', `reuse-other-window', `new-window' or
4260`new-frame'.
4261
4262If the buffer display location specifier is one of 'same-window,
4263'same-frame, or 'other-frame, the `display-buffer' routines
4264assign the value of this variable. If the location specifier is
4265a function, that function becomes responsible for assigning a
4266meaningful value to this variable. See the functions
4267`display-buffer-reuse-window', `display-buffer-pop-up-window' and
4268`display-buffer-pop-up-frame' for how this can be done.")
4269
4270(defun display-buffer-even-window-sizes (window specifiers)
4271 "Even sizes of WINDOW and selected window according to SPECIFIERS.
4272SPECIFIERS must be a list of buffer display specifiers, see the
4273documentation of `display-buffer-alist' for a description.
4274
4275Sizes are evened out if and only if WINDOW and the selected
4276window appear next to each other and the selected window is
4277larger than WINDOW."
4278 (cond
4279 ((or (not (cdr (assq 'reuse-window-even-sizes specifiers)))
4280 ;; Don't resize minibuffer windows.
4281 (window-minibuffer-p)
4282 ;; WINDOW must be adjacent to the selected one.
4283 (not (or (eq window (window-prev))
4284 (eq window (window-next))))))
4285 ((and (window-iso-combined-p window)
4286 ;; Resize iff the selected window is higher than WINDOW.
4287 (> (window-total-height) (window-total-height window)))
4288 ;; Don't throw an error if we can't even window heights for
4289 ;; whatever reason. In any case, enlarging the selected window
4290 ;; might fail anyway if there are other windows above or below
4291 ;; WINDOW and the selected one. But for a simple two windows
4292 ;; configuration the present behavior is good enough so why care?
4293 (ignore-errors
4294 (resize-window
4295 window (/ (- (window-total-height) (window-total-height window))
4296 2))))
4297 ((and (window-iso-combined-p window t)
4298 ;; Resize iff the selected window is wider than WINDOW.
4299 (> (window-total-width) (window-total-width window)))
4300 ;; Don't throw an error if we can't even window widths, see
4301 ;; comment above.
4302 (ignore-errors
4303 (resize-window
4304 window (/ (- (window-total-width) (window-total-width window))
4305 2) t)))))
4306
4307(defun display-buffer-set-height (window specifiers)
4308 "Adjust height of WINDOW according to SPECIFIERS.
4309SPECIFIERS must be a list of buffer display specifiers, see the
4310documentation of `display-buffer-alist' for a description."
4311 (let ((set-height (cdr (assq 'pop-up-window-set-height specifiers))))
4312 (cond
4313 ((numberp set-height)
4314 (let* ((height (if (integerp set-height)
4315 set-height
4316 (round
4317 (* (window-total-size (frame-root-window window))
4318 set-height))))
4319 (delta (- height (window-total-size window))))
4320 (when (and (window-resizable-p window delta nil 'safe)
4321 (window-iso-combined-p window))
4322 (resize-window window delta nil 'safe))))
4323 ((functionp set-height)
4324 (ignore-errors (funcall set-height window))))))
4325
4326(defun display-buffer-set-width (window specifiers)
4327 "Adjust width of WINDOW according to SPECIFIERS.
4328SPECIFIERS must be a list of buffer display specifiers, see the
4329documentation of `display-buffer-alist' for a description."
4330 (let ((set-width (cdr (assq 'pop-up-window-set-width specifiers))))
4331 (cond
4332 ((numberp set-width)
4333 (let* ((width (if (integerp set-width)
4334 set-width
4335 (round
4336 (* (window-total-size (frame-root-window window) t)
4337 set-width))))
4338 (delta (- width (window-total-size window t))))
4339 (when (and (window-resizable-p window delta t 'safe)
4340 (window-iso-combined-p window t))
4341 (resize-window window delta t 'safe))))
4342 ((functionp set-width)
4343 (ignore-errors (funcall set-width window))))))
4344
4345;; We have to work around the deficiency that the command loop does not
4346;; preserve the selected window when it is on a frame that hasn't been
4347;; raised or given input focus. So we have to (1) select the window
4348;; used for displaying a buffer and (2) raise its frame if necessary,
4349;; thus defeating one primary principle of `display-buffer' namely to
4350;; _not_ select the window chosen for displaying the buffer :-(
4351(defun display-buffer-select-window (window &optional norecord)
4352 "Select WINDOW and raise its frame if necessary."
4353 (let ((old-frame (selected-frame))
4354 (new-frame (window-frame window)))
4355 ;; Select WINDOW _before_ raising the frame to assure that the mouse
4356 ;; cursor moves into the correct window.
4357 (select-window window norecord)
4358 (unless (eq old-frame new-frame)
4359 (select-frame-set-input-focus new-frame))))
4360
4361(defun display-buffer-in-window (buffer window specifiers)
4362 "Display BUFFER in WINDOW and raise its frame if needed.
4363WINDOW must be a live window and defaults to the selected one.
4364Return WINDOW.
4365
4366SPECIFIERS must be a list of buffer display specifiers, see the
4367documentation of `display-buffer-alist' for a description."
4368 (setq buffer (normalize-live-buffer buffer))
4369 (setq window (normalize-live-window window))
4370 (let* ((old-frame (selected-frame))
4371 (new-frame (window-frame window))
4372 (dedicated (cdr (assq 'dedicated specifiers)))
4373 (no-other-window (cdr (assq 'no-other-window specifiers))))
4374 ;; Show BUFFER in WINDOW.
4375 (set-window-dedicated-p window nil)
4376 (set-window-buffer window buffer)
4377 (when dedicated
4378 (set-window-dedicated-p window dedicated))
4379 (when no-other-window
4380 (set-window-parameter window 'no-other-window t))
4381 (unless (eq old-frame new-frame)
4382 (display-buffer-select-window window))
4383 ;; Return window.
4384 window))
4385
4386(defun display-buffer-reuse-window (buffer method &optional specifiers)
4387 "Display BUFFER in an existing window.
4388METHOD must be a list in the form of the cdr of a `reuse-window'
4389buffer display specifier, see `display-buffer-alist' for an
4390explanation. The first element must specifiy the window to use,
4391and can be either nil, `same', `other', or a live window. The
4392second element must specify the window's buffer and can be either
4393nil, `same', `other', or a live buffer. The third element is the
4394frame to use - either nil, 0, `visible', `other', t, or a live
4395frame.
4396
4397Optional argument SPECIFIERS must be a list of valid display
4398specifiers. Return the window chosen to display BUFFER, nil if
4399none was found."
4400 (let* ((method-window (nth 0 method))
4401 (method-buffer (nth 1 method))
4402 (method-frame (nth 2 method))
4403 (reuse-dedicated (assq 'reuse-window-dedicated specifiers))
4404 windows other-frame dedicated time best-window best-time)
4405 (when (eq method-frame 'other)
4406 ;; `other' is not handled by `window-list-1'.
4407 (setq other-frame t)
4408 (setq method-frame t))
4409 (dolist (window (window-list-1 nil 'nomini method-frame))
4410 (let ((window-buffer (window-buffer window)))
4411 (when (and (not (window-minibuffer-p window))
4412 ;; Don't reuse a side window.
4413 (or (not (eq (window-parameter window 'window-side) 'side))
4414 (eq window-buffer buffer))
4415 (or (not method-window)
4416 (and (eq method-window 'same)
4417 (eq window (selected-window)))
4418 (and (eq method-window 'other)
4419 (not (eq window (selected-window))))
4420 ;; Special case for applications that specifiy
4421 ;; the window explicitly.
4422 (eq method-window window))
4423 (or (not method-buffer)
4424 (and (eq method-buffer 'same)
4425 (eq window-buffer buffer))
4426 (and (eq method-buffer 'other)
4427 (not (eq window-buffer buffer)))
4428 ;; Special case for applications that specifiy
4429 ;; the window's buffer explicitly.
4430 (eq method-buffer window-buffer))
4431 (or (not other-frame)
4432 (not (eq (window-frame window) (selected-frame))))
4433 ;; Handle dedicatedness.
4434 (or (eq window-buffer buffer)
4435 ;; The window does not show the same buffer.
4436 (not (setq dedicated (window-dedicated-p window)))
4437 ;; If the window is weakly dedicated to its
4438 ;; buffer, reuse-dedicated must be non-nil.
4439 (and (not (eq dedicated t)) reuse-dedicated)
4440 ;; If the window is strongly dedicated to its
4441 ;; buffer, reuse-dedicated must be t.
4442 (eq reuse-dedicated t)))
4443 (setq windows (cons window windows)))))
4444
4445 (if (eq method-buffer 'same)
4446 ;; When reusing a window on the same buffer use the lru one.
4447 (dolist (window windows)
4448 (setq time (window-use-time window))
4449 (when (or (not best-window) (< time best-time))
4450 (setq best-window window)
4451 (setq best-time time)))
4452 ;; Otherwise, sort windows according to their use-time.
4453 (setq windows
4454 (sort windows
4455 #'(lambda (window-1 window-2)
4456 (<= (window-use-time window-1)
4457 (window-use-time window-2)))))
4458 (setq best-window
4459 ;; Try to get a full-width window (this is silly and can
4460 ;; get us to another frame but let's ignore these issues
4461 ;; for the moment).
4462 (catch 'found
4463 (dolist (window windows)
4464 (when (window-full-width-p window)
4465 (throw 'found window)))
4466 ;; If there's no full-width window return the lru window.
4467 (car windows))))
4468
4469 (when best-window
4470 (display-buffer-even-window-sizes best-window specifiers)
4471 ;; Never change the quit-restore parameter of a window here.
4472 (if (eq (window-buffer best-window) buffer)
4473 (setq display-buffer-window
4474 (cons best-window 'reuse-buffer-window))
4475 (setq display-buffer-window
4476 (cons best-window 'reuse-other-window))
4477 (unless (window-parameter best-window 'quit-restore)
4478 ;; Don't overwrite an existing quit-restore entry.
4479 (set-window-parameter
4480 best-window 'quit-restore
4481 (list (window-buffer best-window) (window-start best-window)
4482 (window-point best-window) buffer
4483 (window-total-size best-window) (selected-window)))))
4484
4485 (display-buffer-in-window buffer best-window specifiers))))
4486
4487(defconst display-buffer-split-specifiers '(largest lru selected root left top right bottom)
4488 "List of symbols identifying window that shall be split.")
4489
4490(defconst display-buffer-side-specifiers '(below right above left nil)
4491 "List of symbols identifying side of split-off window.")
4492
4493(defun display-buffer-split-window-1 (window side min-size)
4494 "Subroutine of `display-buffer-split-window'."
4495 (let* ((horizontal (memq side '(left right)))
4496 (parent (window-parent window))
4497 (resize (and window-splits (window-iso-combined-p window horizontal)))
4498 (old-size
4499 ;; We either resize WINDOW or its parent.
4500 (window-total-size (if resize parent window) horizontal))
4501 new-size)
4502 ;; We don't call split-window-vertically/-horizontally any more
4503 ;; here. If for some reason it's needed we can always do so
4504 ;; (provided we give it an optional SIDE argument).
4505 (cond
4506 (resize
4507 ;; When we resize a combination, the new window must be at least
4508 ;; MIN-SIZE large after the split.
4509 (setq new-size
4510 (max min-size
4511 (min (- old-size (window-min-size parent horizontal))
4512 (/ old-size
4513 ;; Try to make the size of the new window
4514 ;; proportional to the number of iso-arranged
4515 ;; windows in the combination.
4516 (1+ (window-iso-combinations parent horizontal))))))
4517 (when (window-sizable-p parent (- new-size) horizontal)
4518 (split-window window (- new-size) side)))
4519 ((window-live-p window)
4520 (setq new-size (/ old-size 2))
4521 ;; When WINDOW is live, the old _and_ the new window must be at
4522 ;; least MIN-SIZE large after the split.
4523 (when (and (>= new-size min-size)
4524 (window-sizable-p window (- new-size) horizontal))
4525 ;; Do an even split to make Stepan happy.
4526 (split-window window nil side)))
4527 (t
4528 ;; When WINDOW is internal, the new window must be at least
4529 ;; MIN-SIZE large after the split.
4530 (setq new-size
4531 (max min-size
4532 (/ old-size
4533 ;; Try to make the size of the new window
4534 ;; proportional to the number of iso-arranged
4535 ;; subwindows of WINDOW.
4536 (1+ (window-iso-combinations window horizontal)))))
4537 (when (window-sizable-p window (- new-size) horizontal)
4538 (split-window window (- new-size) side))))))
4539
4540(defun display-buffer-split-window (window &optional side specifiers)
4541 "Split WINDOW in a way suitable for `display-buffer'.
4542Optional argument SIDE must be a side specifier \(one of the
4543symbols below, right, above, left, or nil). SPECIFIERS must be a
4544list of buffer display specifiers, see the documentation of
4545`display-buffer-alist' for a description.
4546
4547Return the new window, nil if it could not be created."
4548 (let ((min-height (cdr (assq 'pop-up-window-min-height specifiers)))
4549 (min-width (cdr (assq 'pop-up-window-min-width specifiers)))
4550 size)
4551 ;; Normalize min-height and min-width, we might need both.
4552 (setq min-height
4553 ;; If min-height is specified, it can be as small as
4554 ;; `window-safe-min-height'.
4555 (cond
4556 ((and (integerp min-height)
4557 (>= min-height window-safe-min-height))
4558 min-height)
4559 ((and (floatp min-height)
4560 (<= min-height 1)
4561 (let* ((root-height (window-total-height
4562 (frame-root-window
4563 (window-frame window))))
4564 (height (round (* min-height root-height))))
4565 (when (>= height window-safe-min-height)
4566 height))))
4567 (t window-min-height)))
4568 (setq min-width
4569 ;; If min-width is specified, it can be as small as
4570 ;; `window-safe-min-width'.
4571 (cond
4572 ((and (integerp min-width)
4573 (>= min-width window-safe-min-width))
4574 min-width)
4575 ((and (floatp min-width)
4576 (<= min-width 1)
4577 (let* ((root-width (window-total-width
4578 (frame-root-window
4579 (window-frame window))))
4580 (width (round (* min-width root-width))))
4581 (when (>= width window-safe-min-width)
4582 width))))
4583 (t window-min-width)))
4584
4585 (or (and (memq side '(nil above below))
4586 (display-buffer-split-window-1
4587 window (or side 'below) min-height))
4588 ;; If SIDE is nil and vertical splitting failed, we try again
4589 ;; splitting horizontally this time.
4590 (and (memq side '(nil left right))
4591 (display-buffer-split-window-1
4592 window (or side 'right) min-width))
4593 ;; If WINDOW is live and the root window of its frame, try once
4594 ;; more splitting vertically, disregarding the min-height
4595 ;; specifier this time and using `window-min-height' instead.
4596 (and (memq side '(nil above below))
4597 (<= window-min-height min-height)
4598 (window-live-p window)
4599 (eq window (frame-root-window window))
4600 (display-buffer-split-window-1
4601 window (or side 'below) window-min-height)))))
4602
4603(defun display-buffer-split-atom-window (window &optional side nest specifiers)
4604 "Make WINDOW part of an atomic window."
4605 (let ((ignore-window-parameters t)
4606 (window-nest t)
4607 (selected-window (selected-window))
4608 root new new-parent)
4609
4610 ;; We are in an atomic window.
4611 (when (and (window-parameter window 'window-atom) (not nest))
4612 ;; Split the root window.
4613 (setq window (window-atom-root window)))
4614
4615 (when (setq new (display-buffer-split-window window side specifiers))
4616 (setq new-parent (window-parent window))
4617 ;; WINDOW is or becomes atomic.
4618 (unless (window-parameter window 'window-atom)
4619 (walk-window-subtree
4620 (lambda (window)
4621 (set-window-parameter window 'window-atom t))
4622 window t))
4623 ;; New window and any new parent get their window-atom parameter
4624 ;; set too.
4625 (set-window-parameter new 'window-atom t)
4626 (set-window-parameter new-parent 'window-atom t)
4627 new)))
4628
4629(defun display-buffer-pop-up-window (buffer methods &optional specifiers)
4630 "Display BUFFER in a new window.
4631Return the window displaying BUFFER, nil if popping up the window
4632failed. METHODS must be a list of window/side tuples like those
4633forming the cdr of the `pop-up-window' buffer display specifier.
4634As a special case, the car of such a tuple can be also a live
4635window.
4636
4637Optional argument SPECIFIERS must be a list of buffer display
4638specifiers, see the doc-string of `display-buffer-alist' for a
4639description."
4640 (let* ((frame (display-buffer-frame))
4641 (selected-window (frame-selected-window frame))
4642 window side atomic)
4643 (unless (and (cdr (assq 'unsplittable (frame-parameters frame)))
4644 ;; Don't split an unsplittable frame unless
4645 ;; SPECIFIERS allow it.
4646 (not (cdr (assq 'split-unsplittable-frame specifiers))))
4647 (catch 'done
4648 (dolist (method methods)
4649 (setq window (car method))
4650 (setq side (cdr method))
4651 (and (setq window
4652 (cond
4653 ((eq window 'largest)
4654 (get-largest-window frame t))
4655 ((eq window 'lru)
4656 (get-lru-window frame t))
4657 ((eq window 'selected)
4658 (frame-selected-window frame))
4659 ((eq window 'root)
4660 ;; If there are side windows, split the main
4661 ;; window else the frame root window.
4662 (or (window-with-parameter 'window-side 'none nil t)
4663 (frame-root-window frame)))
4664 ((memq window window-sides)
4665 ;; This should gets us the "root" side
4666 ;; window if there exists more than one.
4667 (window-with-parameter 'window-side window nil t))
4668 ((windowp window)
4669 ;; A window, directly specified.
4670 window)))
4671 ;; The window must be on the selected frame,
4672 (eq (window-frame window) frame)
4673 ;; and must be neither a minibuffer window,
4674 (not (window-minibuffer-p window))
4675 ;; nor a side window.
4676 (not (eq (window-parameter window 'window-side) 'side))
4677 (setq window
4678 (cond
4679 ((memq side display-buffer-side-specifiers)
4680 (if (and (window-buffer window)
4681 (setq atomic (cdr (assq 'atomic specifiers))))
4682 (display-buffer-split-atom-window
4683 window side (eq atomic 'nest) specifiers)
4684 (display-buffer-split-window window side specifiers)))
4685 ((functionp side)
4686 (ignore-errors
4687 ;; Don't pass any specifiers to this function.
4688 (funcall side window)))))
4689 (throw 'done window))))
4690
4691 (when window
4692 ;; Adjust sizes if asked for.
4693 (display-buffer-set-height window specifiers)
4694 (display-buffer-set-width window specifiers)
4695 (set-window-parameter
4696 window 'quit-restore (list 'new-window buffer selected-window))
4697 (setq display-buffer-window (cons window 'new-window))
4698 (display-buffer-in-window buffer window specifiers)
4699 (set-window-prev-buffers window nil)
4700 window))))
4701
4702(defun display-buffer-pop-up-frame (buffer &optional graphic-only specifiers)
4703 "Make a new frame for displaying BUFFER.
4704Return the window displaying BUFFER if creating the new frame was
4705successful, nil otherwise. Optional argument GRAPHIC-ONLY
4706non-nil means to make a new frame on graphic displays only.
4707
4708SPECIFIERS must be a list of buffer display specifiers, see the
4709documentation of `display-buffer-alist' for a description."
4710 (unless (and graphic-only (not (display-graphic-p)))
4711 (let* ((selected-window (selected-window))
4712 (function (or (cdr (assq 'pop-up-frame-function specifiers))
4713 'make-frame))
4714 (parameters
4715 (when (symbolp function)
4716 (cdr (assq 'pop-up-frame-alist specifiers))))
4717 (frame
4718 (if (symbolp function)
4719 (funcall function parameters)
4720 (funcall function))))
4721 (when frame
4722 (let ((window (frame-selected-window frame)))
4723 (set-window-parameter
4724 window 'quit-restore (list 'new-frame buffer selected-window))
4725 (setq display-buffer-window (cons window 'new-frame))
4726 (display-buffer-in-window buffer window specifiers))))))
4727
4728(defun display-buffer-pop-up-side-window (buffer side slot &optional specifiers)
4729 "Display BUFFER in a new window on SIDE of the selected frame.
4730SLOT specifies the slot to use. SPECIFIERS must be a list of
4731buffer display specifiers.
4732
4733Return the window displaying BUFFER, nil if popping up the window
4734failed."
4735 (let* ((root (frame-root-window))
4736 (main (window-with-parameter 'window-side 'none nil t))
4737 (left-or-right (memq side '(left right)))
4738 (main-or-root
4739 (if (and main
4740 (or (and left-or-right (not window-sides-vertical))
4741 (and (not left-or-right) window-sides-vertical)))
4742 main
4743 root))
4744 (selected-window (selected-window))
4745 (on-side (cond
4746 ((eq side 'top) 'above)
4747 ((eq side 'bottom) 'below)
4748 (t side)))
4749 (window
4750 (display-buffer-split-window main-or-root on-side specifiers))
4751 fun)
4752 (when window
4753 (unless main
4754 (walk-window-subtree
4755 (lambda (window)
4756 ;; Make all main-or-root subwindows main windows.
4757 (set-window-parameter window 'window-side 'none))
4758 main-or-root t))
4759 ;; Make sure that parent's window-side is nil.
4760 (set-window-parameter (window-parent window) 'window-side nil)
4761 ;; Initialize side.
4762 (set-window-parameter window 'window-side side)
4763 ;; Adjust sizes if asked for.
4764 (display-buffer-set-height window specifiers)
4765 (display-buffer-set-width window specifiers)
4766 ;; Set window parameters.
4767 (set-window-parameter
4768 window 'quit-restore (list 'new-window buffer selected-window))
4769 (setq display-buffer-window (cons window 'new-window))
4770 (set-window-parameter window 'window-slot slot)
4771 (display-buffer-in-window buffer window specifiers)
4772 (set-window-prev-buffers window nil)
4773 window)))
4774
4775(defun display-buffer-in-side-window (buffer side &optional slot specifiers)
4776 "Display BUFFER in a window on SIDE of the selected frame.
4777SLOT, if non-nil, specifies the window slot where to display the
4778BUFFER. SLOT zero or nil means use the central slot on SIDE.
4779SLOT negative means use a slot preceding the central window.
4780SLOT positive means use a slot following the central window.
4781
4782SPECIFIERS must be a list of buffer display specifiers."
4783 (unless (memq side window-sides)
4784 (error "Invalid side %s specified" side))
4785 (let* ((major (window-with-parameter 'window-side side nil t))
4786 ;; `major' is the major window on SIDE, `windows' the life
4787 ;; windows on SIDE.
4788 (windows (when major (windows-with-parameter 'window-side side)))
4789 (slots (when major (window-child-count major)))
4790 (max-slots
4791 (nth (cond
4792 ((eq side 'left) 0)
4793 ((eq side 'top) 1)
4794 ((eq side 'right) 2)
4795 ((eq side 'bottom) 3))
4796 window-sides-slots))
4797 (selected-window (selected-window))
4798 window this-window this-slot prev-window next-window
4799 best-window best-slot abs-slot)
4800
4801 (unless (numberp slot)
4802 (setq slot 0))
4803 (if (not windows)
4804 ;; No suitable side window exists, make one.
4805 (display-buffer-pop-up-side-window buffer side slot specifiers)
4806 ;; Scan windows on SIDE.
4807 (catch 'found
4808 (dolist (window windows)
4809 (setq this-slot (window-parameter window 'window-slot))
4810 (cond
4811 ((not (numberp this-slot)))
4812 ((and (= this-slot slot)
4813 ;; Dedicatedness check.
4814 (or (not (window-dedicated-p window))
4815 (assq 'reuse-window-dedicated specifiers)))
4816 ;; Window with matching SLOT, use it.
4817 (setq this-window window)
4818 (throw 'found t))
4819 (t
4820 (setq abs-slot (abs (- (abs slot) (abs this-slot))))
4821 (unless (and best-slot (<= best-slot abs-slot))
4822 (setq best-window window)
4823 (setq best-slot abs-slot))
4824 (cond
4825 ((<= this-slot slot)
4826 (setq prev-window window))
4827 ((not next-window)
4828 (setq next-window window)))))))
4829
4830 ;; `this-window' is the first window with the same SLOT.
4831 ;; `prev-window' is the window with the largest slot < SLOT. A new
4832 ;; window will be created after it.
4833 ;; `next-window' is the window with the smallest slot > SLOT. A new
4834 ;; window will be created before it.
4835 ;; `best-window' is the window with the smallest absolute difference
4836 ;; of its slot and SLOT.
4837 (or (and this-window
4838 ;; Reuse this window.
4839 (prog1
4840 (setq window this-window)
4841 (if (eq (window-buffer window) buffer)
4842 (setq display-buffer-window
4843 (cons window 'reuse-buffer-window))
4844 (setq display-buffer-window
4845 (cons window 'reuse-other-window))
4846 (unless (window-parameter window 'quit-restore)
4847 ;; Don't overwrite an existing quit-restore entry.
4848 (set-window-parameter
4849 window 'quit-restore
4850 (list (window-buffer window) (window-start window)
4851 (window-point window) buffer
4852 (window-total-size window) (selected-window)))))))
4853 (and (or (not max-slots) (< slots max-slots))
4854 (or (and next-window
4855 ;; Make new window before next-window.
4856 (let ((next-side
4857 (if (memq side '(left right)) 'above 'left)))
4858 (setq window (display-buffer-split-window
4859 next-window next-side specifiers))))
4860 (and prev-window
4861 ;; Make new window after prev-window.
4862 (let ((prev-side
4863 (if (memq side '(left right)) 'below 'right)))
4864 (setq window (display-buffer-split-window
4865 prev-window prev-side specifiers)))))
4866 (progn
4867 (display-buffer-set-height window specifiers)
4868 (display-buffer-set-width window specifiers)
4869 (set-window-parameter
4870 window 'quit-restore
4871 (list 'new-window buffer selected-window))
4872 (setq display-buffer-window (cons window 'new-window))
4873 window))
4874 (and best-window
4875 (setq window best-window)
4876 ;; Reuse best window (the window nearest to SLOT).
4877 (if (eq (window-buffer window) buffer)
4878 (setq display-buffer-window
4879 (cons window 'reuse-buffer-window))
4880 (setq display-buffer-window
4881 (cons window 'reuse-other-window))
4882
4883 (unless (window-parameter window 'quit-restore)
4884 ;; Don't overwrite an existing quit-restore entry.
4885 (set-window-parameter
4886 window 'quit-restore
4887 (list (window-buffer window) (window-start window)
4888 (window-point window) buffer
4889 (window-total-size window) (selected-window)))))
4890 window))
4891
4892 (when window
4893 (unless (window-parameter window 'window-slot)
4894 ;; Don't change exisiting slot value.
4895 (set-window-parameter window 'window-slot slot))
4896 (display-buffer-in-window buffer window specifiers)))))
4897
4898(defun normalize-buffer-to-display (buffer-or-name)
4899 "Normalize BUFFER-OR-NAME argument for buffer display functions.
4900If BUFFER-OR-NAME is nil, return the curent buffer. Else, if a
4901buffer specified by BUFFER-OR-NAME exists, return that buffer.
4902If no such buffer exists, create a buffer with the name
4903BUFFER-OR-NAME and return that buffer."
4904 (if buffer-or-name
4905 (or (get-buffer buffer-or-name)
4906 (let ((buffer (get-buffer-create buffer-or-name)))
4907 (set-buffer-major-mode buffer)
4908 buffer))
4909 (current-buffer)))
4910
4911(defun display-buffer-normalize-specifiers-1 (specifiers)
4912 "Subroutine of `display-buffer-normalize-specifiers'.
4913SPECIFIERS is the SPECIFIERS argument of `display-buffer'."
4914 (let (normalized)
4915 (cond
4916 ((listp specifiers)
4917 (dolist (specifier specifiers)
4918 (cond
4919 ((consp specifier)
4920 (setq normalized (cons specifier normalized)))
4921 ((symbolp specifier)
4922 ;; Might be a macro specifier, try to expand it (the cdr is a
4923 ;; list and we have to reverse it later, so do it one at a
4924 ;; time).
4925 (let ((entry (assq specifier display-buffer-macro-specifiers)))
4926 (dolist (item (cdr entry))
4927 (setq normalized (cons item normalized)))))))
4928 ;; Reverse list.
4929 (setq normalized (nreverse normalized)))
4930 ;; The two cases below must come from the SPECIFIERS argument of
4931 ;; `display-buffer'.
4932 ((eq specifiers 't)
4933 ;; Historically t means "other window". Eventually we should get
4934 ;; rid of this.
4935 (setq normalized
4936 (cdr (assq 'other-window display-buffer-macro-specifiers))
4937 normalized))
4938 ((symbolp specifiers)
4939 ;; We allow scalar specifiers in calls of `display-buffer'.
4940 (let ((entry (assq specifiers display-buffer-macro-specifiers)))
4941 (when entry (setq normalized (cdr entry))))))
4942
4943 normalized))
4944
4945(defun display-buffer-normalize-specifiers-2 (&optional buffer-or-name)
4946 "Subroutine of `display-buffer-normalize-specifiers'.
4947BUFFER-OR-NAME is the buffer to display. This routine provides a
4948compatibility layer for the now obsolete Emacs 23 buffer display
4949options."
4950 (let* ((buffer (normalize-live-buffer buffer-or-name))
4951 (buffer-name (buffer-name buffer))
4952 specifiers)
4953 ;; Disable warnings, there are too many obsolete options here.
4954 (with-no-warnings
4955 ;; `display-buffer-mark-dedicated'
4956 (unless (memq display-buffer-mark-dedicated '(nil unset))
4957 (setq specifiers
4958 (cons (cons 'dedicate display-buffer-mark-dedicated)
4959 specifiers)))
4960
4961 ;; `pop-up-window' group. Anything is added here iff
4962 ;; `pop-up-windows' is neither nil nor unset.
4963 (let ((pop-up-window (not (memq pop-up-windows '(nil unset))))
4964 (fun (unless (eq split-window-preferred-function
4965 'split-window-sensibly)
4966 split-window-preferred-function))
4967 (min-height (if (numberp split-height-threshold)
4968 (/ split-height-threshold 2)
4969 1.0))
4970 (min-width (if (numberp split-width-threshold)
4971 (/ split-width-threshold 2)
4972 1.0)))
4973 (when pop-up-window
4974 ;; `split-height-threshold'
4975 (setq specifiers
4976 (cons (cons 'pop-up-window-min-height min-height)
4977 specifiers))
4978 ;; `split-width-threshold'
4979 (setq specifiers
4980 (cons (cons 'pop-up-window-min-width min-width)
4981 specifiers))
4982 ;; `pop-up-window'
4983 (setq specifiers
4984 (cons (list 'pop-up-window
4985 (cons 'largest fun) (cons 'lru fun))
4986 specifiers))))
4987
4988 ;; `pop-up-frame' group. Anything is added here iff
4989 ;; `pop-up-frames' is neither nil nor unset (we ignore the problem
4990 ;; that callers usually don't care about graphic-only).
4991 (unless (memq pop-up-frames '(nil unset))
4992 ;; `pop-up-frame-function'. If `pop-up-frame-function' uses the
4993 ;; now obsolete `pop-up-frame-alist' it will continue to do so.
4994 (setq specifiers
4995 (cons (cons 'pop-up-frame-function pop-up-frame-function)
4996 specifiers))
4997 ;; `pop-up-frame'
4998 (setq specifiers
4999 (cons (list 'pop-up-frame pop-up-frames) specifiers)))
5000
5001 ;; `special-display-regexps'
5002 (dolist (entry special-display-regexps)
5003 (cond
5004 ((stringp entry)
5005 ;; Plain string.
5006 (when (string-match-p entry buffer-name)
5007 (setq specifiers
5008 (cons
5009 (list 'fun-with-args special-display-function
5010 special-display-frame-alist)
5011 specifiers))))
5012 ((consp entry)
5013 (let ((name (car entry))
5014 (rest (cdr entry)))
5015 (cond
5016 ((not (string-match-p name buffer-name)))
5017 ((functionp (car rest))
5018 ;; A function.
5019 (setq specifiers
5020 (cons (list 'fun-with-args (car rest) (cadr rest))
5021 specifiers)))
5022 ((listp rest)
5023 ;; A list of parameters.
5024 (cond
5025 ((assq 'same-window rest)
5026 (setq specifiers
5027 (cons (list 'reuse-window 'same) specifiers))
5028 (setq specifiers
5029 (cons (list 'reuse-window-dedicated 'weak)
5030 specifiers)))
5031 ((assq 'same-frame rest)
5032 (setq specifiers
5033 (setq specifiers
5034 (cons (list 'same-frame) specifiers))))
5035 (t
5036 (setq specifiers
5037 (cons (list 'fun-with-args special-display-function
5038 special-display-frame-alist)
5039 specifiers))))))))))
5040
5041 ;; `special-display-buffer-names'
5042 (dolist (entry special-display-buffer-names)
5043 (cond
5044 ((stringp entry)
5045 ;; Plain string.
5046 (when (string-equal entry buffer-name)
5047 (setq specifiers
5048 (cons
5049 (list 'fun-with-args special-display-function
5050 special-display-frame-alist)
5051 specifiers))))
5052 ((consp entry)
5053 (let ((name (car entry))
5054 (rest (cdr entry)))
5055 (cond
5056 ((not (string-equal name buffer-name)))
5057 ((functionp (car rest))
5058 ;; A function.
5059 (setq specifiers
5060 (cons (list 'fun-with-args (car rest) (cadr rest))
5061 specifiers)))
5062 ((listp rest)
5063 ;; A list of parameters.
5064 (cond
5065 ((assq 'same-window rest)
5066 (setq specifiers
5067 (cons (list 'reuse-window 'same) specifiers))
5068 (setq specifiers
5069 (cons (list 'reuse-window-dedicated 'weak)
5070 specifiers)))
5071 ((assq 'same-frame rest)
5072 (setq specifiers
5073 (setq specifiers
5074 (cons (list 'same-frame) specifiers))))
5075 (t
5076 (setq specifiers
5077 (cons (list 'fun-with-args special-display-function
5078 special-display-frame-alist)
5079 specifiers))))))))))
5080
5081 ;; `same-window-regexps'
5082 (dolist (entry same-window-regexps)
5083 (cond
5084 ((stringp entry)
5085 (when (string-match-p entry buffer-name)
5086 (setq specifiers
5087 (cons (list 'reuse-window 'same) specifiers))))
5088 ((consp entry)
5089 (when (string-match-p (car entry) buffer-name)
5090 (setq specifiers
5091 (cons (list 'reuse-window 'same) specifiers))))))
5092
5093 ;; `same-window-buffer-names'
5094 (dolist (entry same-window-buffer-names)
5095 (cond
5096 ((stringp entry)
5097 (when (string-equal entry buffer-name)
5098 (setq specifiers
5099 (cons (list 'reuse-window 'same) specifiers))))
5100 ((consp entry)
5101 (when (string-equal (car entry) buffer-name)
5102 (setq specifiers
5103 (cons (list 'reuse-window 'same) specifiers))))))
5104
5105 ;; `pop-up-windows' and `pop-up-frames' nil means means we
5106 ;; are supposed to reuse any window (unless we find one showing
5107 ;; the same buffer already).
5108
5109 ;; This clause is needed because Emacs 23 options can be used to
5110 ;; suppress a certain behavior while `display-buffer-alist' can be
5111 ;; only used to enforce some behavior.
5112 (when (and (not pop-up-windows) (memq pop-up-frames '(nil unset)))
5113 ;; `even-window-heights'
5114 (when even-window-heights
5115 (setq specifiers
5116 (cons (cons 'reuse-window-even-sizes t) specifiers)))
5117 ;; `reuse-window' showing any buffer on same frame.
5118 (setq specifiers
5119 (cons (list 'reuse-window nil nil nil)
5120 specifiers)))
5121
5122 ;; `display-buffer-reuse-frames' or `pop-up-frames' set means we
5123 ;; are supposed to reuse a window showing the same buffer.
5124 (unless (and (memq display-buffer-reuse-frames '(nil unset))
5125 (memq pop-up-frames '(nil unset)))
5126 ;; `even-window-heights'
5127 (when even-window-heights
5128 (setq specifiers
5129 (cons (cons 'reuse-window-even-sizes t) specifiers)))
5130 ;; `reuse-window' showing same buffer on visible frame.
5131 (setq specifiers
5132 (cons (list 'reuse-window nil 'same 0)
5133 specifiers)))
5134
5135 specifiers)))
5136
5137(defun display-buffer-normalize-specifiers (buffer-name specifiers label)
5138 "Return normalized specifiers for a buffer matching BUFFER-NAME or LABEL.
5139BUFFER-NAME must be a string specifying a valid buffer name.
5140SPECIFIERS and LABEL are the homonymous arguments of
5141`display-buffer'.
5142
5143The method for displaying the buffer specified by BUFFER-NAME or
5144LABEL is established by appending the following four lists of
5145specifiers:
5146
5147- The specifiers in `display-buffer-alist' whose buffer
5148 identifier matches BUFFER-NAME or LABEL and whose 'override
5149 component is set.
5150
5151- SPECIFIERS.
5152
5153- The specifiers in `display-buffer-alist' whose buffer
5154 identifier matches BUFFER-NAME or LABEL and whose 'override
5155 component is not set.
5156
5157- `display-buffer-default-specifiers'."
5158 (let (list-1 list-2)
5159 (dolist (entry display-buffer-alist)
5160 (when (and (listp entry)
5161 (catch 'match
5162 (dolist (id (car entry))
5163 (when (consp id)
5164 (let ((type (car id))
5165 (value (cdr id)))
5166 (when (or (and (eq type 'name) (stringp value)
5167 (equal value buffer-name))
5168 (and (eq type 'regexp) (stringp value)
5169 (string-match-p value buffer-name))
5170 (and (eq type 'label) (eq value label)))
5171 (throw 'match t)))))))
5172 (let* ((raw (cdr entry))
5173 (normalized (display-buffer-normalize-specifiers-1 raw)))
5174 (if (assq 'override raw)
5175 (setq list-1
5176 (if list-1
5177 (append list-1 normalized)
5178 normalized))
5179 (setq list-2
5180 (if list-2
5181 (append list-2 normalized)
5182 normalized))))))
5183
5184 (append
5185 ;; Overriding user specifiers.
5186 list-1
5187 ;; Application specifiers.
5188 (display-buffer-normalize-specifiers-1 specifiers)
5189 ;; Emacs 23 compatibility specifiers.
5190 (display-buffer-normalize-specifiers-2 buffer-name)
5191 ;; Non-overriding user specifiers.
5192 list-2
5193 ;; Default specifiers.
5194 display-buffer-default-specifiers)))
5195
5196;; Minibuffer-only frames should be documented better. They really
5197;; deserve a separate section in the manual. Also
5198;; `last-nonminibuffer-frame' is nowhere documented in the manual.
5199(defun display-buffer-frame (&optional frame)
5200 "Return FRAME if it is live and not a minibuffer-only frame.
5201Return the value of `last-nonminibuffer-frame' otherwise."
5202 (setq frame (normalize-live-frame frame))
5203 (if (and (frame-live-p frame)
5204 ;; A not very nice way to get that information.
5205 (not (window-minibuffer-p (frame-root-window frame))))
5206 frame
5207 (last-nonminibuffer-frame)))
5208
5209(defun display-buffer (&optional buffer-or-name specifiers label)
5210 "Make the buffer specified by BUFFER-OR-NAME appear in some window.
5211Optional argument BUFFER-OR-NAME may be a buffer, a string \(a
5212buffer name), or nil. If BUFFER-OR-NAME is a string not naming
5213an existent buffer, create a buffer with that name. If
5214BUFFER-OR-NAME is nil or omitted, display the current buffer.
5215Interactively, prompt for the buffer name using the minibuffer.
5216
5217Return the window chosen to display the buffer or nil if no such
5218window is found. Do not change the selected window unless the
5219buffer is shown on a different frame than the selected one.
5220
5221Optional argument SPECIFIERS must be a list of buffer display
5222specifiers, see the documentation of `display-buffer-alist' for a
5223description.
5224
5225For convenience, SPECIFIERS may also consist of a single buffer
5226display location specifier or t, where the latter means to
5227display the buffer in any but the selected window. If SPECIFIERS
5228is nil or omitted, this means to exclusively use the specifiers
5229provided by `display-buffer-alist'. If the value of the latter
5230is nil too, all specifiers are provided by the constant
5231`display-buffer-default-specifiers'.
5232
5233As a special case, the `reuse-window' specifier allows to specify
5234as second element an arbitrary window, as third element an
5235arbitrary buffer, and as fourth element an arbitrary frame. As
5236first element of a window/side pair of the `pop-up-window'
5237specifier you can specifiy an arbitrary window.
5238
5239The optional third argument LABEL, if non-nil, must be a symbol
5240specifiying the buffer display label. Applications should set
5241this when the buffer shall be displayed in some special way but
5242BUFFER-OR-NAME does not identify the buffer as special. Typical
5243buffers that fit into this category are those whose names are
5244derived from the name of the file they are visiting. A user can
5245override SPECIFIERS by adding an entry to `display-buffer-alist'
5246whose car contains LABEL and whose cdr specifies the preferred
5247alternative display method.
5248
5249The method to display the buffer is derived by combining the
5250values of `display-buffer-alist' and SPECIFIERS. Highest
5251priority is given to overriding elements of
5252`display-buffer-alist'. Next come the elements specified by
5253SPECIFIERS, followed by the non-overriding elements of
5254`display-buffer-alist'.
5255
5256The result must be a list of valid buffer display specifiers. If
5257`display-buffer-function' is non-nil, call it with the buffer and
5258this list as arguments."
5259 (interactive "BDisplay buffer:\nP")
5260 (let* ((buffer (normalize-buffer-to-display buffer-or-name))
5261 (buffer-name (buffer-name buffer))
5262 (specifiers
5263 ;; Normalize specifiers.
5264 (display-buffer-normalize-specifiers buffer-name specifiers label))
5265 ;; Don't use a minibuffer frame.
5266 (frame (display-buffer-frame))
5267 ;; `window' is the window we use for showing `buffer'.
5268 window specifier method)
5269 ;; Reset this.
5270 (setq display-buffer-window nil)
5271 (if display-buffer-function
5272 ;; Let `display-buffer-function' do the job.
5273 (funcall display-buffer-function buffer specifiers)
5274 ;; Retrieve the next location specifier while there a specifiers
5275 ;; left and we don't have a valid window.
5276 (while (and specifiers (not (window-live-p window)))
5277 (setq specifier (car specifiers))
5278 (setq specifiers (cdr specifiers))
5279 (setq method (car specifier))
5280 (setq window
5281 (cond
5282 ((eq method 'reuse-window)
5283 (display-buffer-reuse-window
5284 buffer (cdr specifier) specifiers))
5285 ((eq method 'pop-up-window)
5286 (display-buffer-pop-up-window
5287 buffer (cdr specifier) specifiers))
5288 ((eq method 'pop-up-frame)
5289 (display-buffer-pop-up-frame
5290 buffer (cdr specifier) specifiers))
5291 ((eq method 'use-side-window)
5292 (display-buffer-in-side-window
5293 buffer (nth 1 specifier) (nth 2 specifier) specifiers))
5294 ((eq method 'fun-with-args)
5295 (apply (cadr specifier) buffer (cddr specifier))))))
5296
5297 ;; If we don't have a window yet, try a fallback method. All
5298 ;; specifiers have been used up by now.
5299 (or (and (window-live-p window) window)
5300 ;; Try reusing a window showing BUFFER on any visible or
5301 ;; iconfied frame.
5302 (display-buffer-reuse-window buffer '(nil buffer 0))
5303 ;; Try reusing a window not showing BUFFER on any visible or
5304 ;; iconified frame.
5305 (display-buffer-reuse-window buffer '(nil other 0))
5306 ;; Try making a new frame.
5307 (display-buffer-pop-up-frame buffer)
5308 ;; Try using weakly dedicated windows.
5309 (display-buffer-reuse-window
5310 buffer '(nil nil t) '((reuse-window-dedicated . weak)))
5311 ;; Try using strongly dedicated windows.
5312 (display-buffer-reuse-window
5313 buffer '(nil nil t) '((reuse-window-dedicated . t)))))))
5314
5315(defsubst display-buffer-same-window (&optional buffer-or-name label)
5316 "Display buffer specified by BUFFER-OR-NAME in the selected window.
5317Another window will be used only if the buffer can't be shown in
5318the selected window, usually because it is dedicated to another
5319buffer. Optional argument BUFFER-OR-NAME and LABEL are as for
5320`display-buffer'."
5321 (interactive "BDisplay buffer in same window:\nP")
5322 (display-buffer buffer-or-name 'same-window label))
5323
5324(defsubst display-buffer-same-frame (&optional buffer-or-name label)
5325 "Display buffer specified by BUFFER-OR-NAME in a window on the same frame.
5326Another frame will be used only if there is no other choice.
5327Optional argument BUFFER-OR-NAME and LABEL are as for
5328`display-buffer'."
5329 (interactive "BDisplay buffer on same frame:\nP")
5330 (display-buffer buffer-or-name 'same-frame label))
5331
5332(defsubst display-buffer-other-window (&optional buffer-or-name label)
5333 "Display buffer specified by BUFFER-OR-NAME in another window.
5334The selected window will be used only if there is no other
5335choice. Windows on the selected frame are preferred to windows
5336on other frames. Optional argument BUFFER-OR-NAME and LABEL are as
5337for `display-buffer'."
5338 (interactive "BDisplay buffer in another window:\nP")
5339 (display-buffer buffer-or-name 'other-window label))
5340
5341(defun display-buffer-same-frame-other-window (&optional buffer-or-name label)
5342 "Display buffer specified by BUFFER-OR-NAME in another window on the same frame.
5343The selected window or another frame will be used only if there
5344is no other choice. Optional argument BUFFER-OR-NAME and LABEL are
5345as for `display-buffer'."
5346 (interactive "BDisplay buffer in another window on same frame:\nP")
5347 (display-buffer buffer-or-name 'same-frame-other-window label))
5348
5349(defun display-buffer-other-frame (&optional buffer-or-name label)
5350 "Display buffer specified by BUFFER-OR-NAME on another frame.
5351The selected frame will be used only if there is no other choice.
5352Optional argument BUFFER-OR-NAME and LABEL are as for
5353`display-buffer'.
5354
5355If this command uses another frame, it will also select that frame."
5356 (interactive "BDisplay buffer in other frame: ")
5357 (display-buffer buffer-or-name 'other-frame label))
5358
5359(defun pop-to-buffer (&optional buffer-or-name specifiers norecord label)
5360 "Display buffer specified by BUFFER-OR-NAME and select the window used.
5361Optional argument BUFFER-OR-NAME may be a buffer, a string \(a
5362buffer name), or nil. If BUFFER-OR-NAME is a string not naming
5363an existent buffer, create a buffer with that name. If
5364BUFFER-OR-NAME is nil or omitted, display the current buffer.
5365Interactively, prompt for the buffer name using the minibuffer.
5366
5367Optional second argument SPECIFIERS must be a list of buffer
5368display specifiers, a single location specifier, `t' which means
5369the latter means to display the buffer in any but the selected
5370window, or nil which means to exclusively apply the specifiers
5371customized by the user.
5372
5373Optional argument NORECORD non-nil means do not put the buffer
5374specified by BUFFER-OR-NAME at the front of the buffer list and
5375do not make the window displaying it the most recently selected
5376one.
5377
5378The optional argument LABEL, if non-nil, is a symbol specifying the
5379display purpose. Applications should set this when the buffer
5380shall be displayed in a special way but BUFFER-OR-NAME does not
5381identify the buffer as special. Buffers that typically fit into
5382this category are those whose names have been derived from the
5383name of the file they are visiting.
5384
5385Return the buffer specified by BUFFER-OR-NAME or nil if
5386displaying the buffer failed.
5387
5388This uses the function `display-buffer' as a subroutine; see the
5389documentations of `display-buffer' and `display-buffer-alist' for
5390additional information."
5391 (interactive "BPop to buffer:\nP")
5392 (let ((buffer (normalize-buffer-to-display buffer-or-name))
5393 window)
5394 (set-buffer buffer)
5395 (when (setq window (display-buffer buffer specifiers label))
5396 (select-window window norecord)
5397 buffer)))
5398
5399(defsubst pop-to-buffer-same-window (&optional buffer-or-name norecord label)
5400 "Pop to buffer specified by BUFFER-OR-NAME in the selected window.
5401Another window will be used only if the buffer can't be shown in
5402the selected window, usually because it is dedicated to another
5403buffer. Optional arguments BUFFER-OR-NAME, NORECORD and LABEL are
5404as for `pop-to-buffer'."
5405 (interactive "BPop to buffer in selected window:\nP")
5406 (pop-to-buffer buffer-or-name 'same-window norecord label))
5407
5408(defsubst pop-to-buffer-same-frame (&optional buffer-or-name norecord label)
5409 "Pop to buffer specified by BUFFER-OR-NAME in a window on the selected frame.
5410Another frame will be used only if there is no other choice.
5411Optional arguments BUFFER-OR-NAME, NORECORD and LABEL are as for
5412`pop-to-buffer'."
5413 (interactive "BPop to buffer on same frame:\nP")
5414 (pop-to-buffer buffer-or-name 'same-frame norecord label))
5415
5416(defsubst pop-to-buffer-other-window (&optional buffer-or-name norecord label)
5417 "Pop to buffer specified by BUFFER-OR-NAME in another window.
5418The selected window will be used only if there is no other
5419choice. Windows on the selected frame are preferred to windows
5420on other frames. Optional arguments BUFFER-OR-NAME, NORECORD and
5421LABEL are as for `pop-to-buffer'."
5422 (interactive "BPop to buffer in another window:\nP")
5423 (pop-to-buffer buffer-or-name 'other-window norecord))
5424
5425(defsubst pop-to-buffer-same-frame-other-window (&optional buffer-or-name norecord label)
5426 "Pop to buffer specified by BUFFER-OR-NAME in another window on the selected frame.
5427The selected window or another frame will be used only if there
5428is no other choice. Optional arguments BUFFER-OR-NAME, NORECORD
5429and LABEL are as for `pop-to-buffer'."
5430 (interactive "BPop to buffer in another window on same frame:\nP")
5431 (pop-to-buffer buffer-or-name 'same-frame-other-window norecord label))
5432
5433(defsubst pop-to-buffer-other-frame (&optional buffer-or-name norecord label)
5434 "Pop to buffer specified by BUFFER-OR-NAME on another frame.
5435The selected frame will be used only if there's no other choice.
5436Optional arguments BUFFER-OR-NAME, NORECORD and LABEL are as for
5437`pop-to-buffer'."
5438 (interactive "BPop to buffer on another frame:\nP")
5439 (pop-to-buffer buffer-or-name 'other-frame norecord label))
5440
5441(defun read-buffer-to-switch (prompt)
5442 "Read the name of a buffer to switch to, prompting with PROMPT.
5443Return the neame of the buffer as a string.
5444
5445This function is intended for the `switch-to-buffer' family of
5446commands since these need to omit the name of the current buffer
5447from the list of completions and default values."
5448 (let ((rbts-completion-table (internal-complete-buffer-except)))
5449 (minibuffer-with-setup-hook
5450 (lambda ()
5451 (setq minibuffer-completion-table rbts-completion-table)
5452 ;; Since rbts-completion-table is built dynamically, we
5453 ;; can't just add it to the default value of
5454 ;; icomplete-with-completion-tables, so we add it
5455 ;; here manually.
5456 (if (and (boundp 'icomplete-with-completion-tables)
5457 (listp icomplete-with-completion-tables))
5458 (set (make-local-variable 'icomplete-with-completion-tables)
5459 (cons rbts-completion-table
5460 icomplete-with-completion-tables))))
5461 (read-buffer prompt (other-buffer (current-buffer))
5462 (confirm-nonexistent-file-or-buffer)))))
5463
5464(defun normalize-buffer-to-switch-to (buffer-or-name)
5465 "Normalize BUFFER-OR-NAME argument of buffer switching functions.
5466If BUFFER-OR-NAME is nil, return the buffer returned by
5467`other-buffer'. Else, if a buffer specified by BUFFER-OR-NAME
5468exists, return that buffer. If no such buffer exists, create a
5469buffer with the name BUFFER-OR-NAME and return that buffer."
5470 (if buffer-or-name
5471 (or (get-buffer buffer-or-name)
5472 (let ((buffer (get-buffer-create buffer-or-name)))
5473 (set-buffer-major-mode buffer)
5474 buffer))
5475 (other-buffer)))
5476
5477(defun switch-to-buffer (buffer-or-name &optional norecord)
5478 "Switch to buffer BUFFER-OR-NAME in the selected window.
5479If called interactively, prompt for the buffer name using the
5480minibuffer. The variable `confirm-nonexistent-file-or-buffer'
5481determines whether to request confirmation before creating a new
5482buffer.
5483
5484BUFFER-OR-NAME may be a buffer, a string \(a buffer name), or
5485nil. If BUFFER-OR-NAME is a string that does not identify an
5486existing buffer, create a buffer with that name. If
5487BUFFER-OR-NAME is nil, switch to the buffer returned by
5488`other-buffer'.
5489
5490Optional argument NORECORD non-nil means do not put the buffer
5491specified by BUFFER-OR-NAME at the front of the buffer list and
5492do not make the window displaying it the most recently selected
5493one. Return the buffer switched to.
5494
5495This function is intended for interactive use only. Lisp
5496functions should call `pop-to-buffer-same-window' instead."
5497 (interactive
5498 (list (read-buffer-to-switch "Switch to buffer: ")))
5499 (let ((buffer (normalize-buffer-to-switch-to buffer-or-name)))
5500 (if (and (or (window-minibuffer-p) (eq (window-dedicated-p) t))
5501 (not (eq buffer (window-buffer))))
5502 ;; Cannot switch to another buffer in a minibuffer or strongly
5503 ;; dedicated window that does not show the buffer already. Call
5504 ;; `pop-to-buffer' instead.
5505 (pop-to-buffer buffer 'same-window norecord)
5506 (unless (eq buffer (window-buffer))
5507 ;; I'm not sure why we should NOT call `set-window-buffer' here,
5508 ;; but let's keep things as they are (otherwise we could always
5509 ;; call `pop-to-buffer-same-window' here).
5510 (set-window-buffer nil buffer))
5511 (unless norecord
5512 (select-window (selected-window)))
5513 (set-buffer buffer))))
5514
5515(defun switch-to-buffer-same-frame (buffer-or-name &optional norecord)
5516 "Switch to buffer BUFFER-OR-NAME in a window on the selected frame.
5517Another frame will be used only if there is no other choice.
5518Optional arguments BUFFER-OR-NAME and NORECORD have the same
5519meaning as for `switch-to-buffer'.
5520
5521This function is intended for interactive use only. Lisp
5522functions should call `pop-to-buffer-same-frame' instead."
5523 (interactive
5524 (list (read-buffer-to-switch "Switch to buffer in other window: ")))
5525 (let ((buffer (normalize-buffer-to-switch-to buffer-or-name)))
5526 (pop-to-buffer buffer 'same-frame norecord)))
5527
5528(defun switch-to-buffer-other-window (buffer-or-name &optional norecord)
5529 "Switch to buffer BUFFER-OR-NAME in another window.
5530The selected window will be used only if there is no other
5531choice. Windows on the selected frame are preferred to windows
5532on other frames. Optional arguments BUFFER-OR-NAME and NORECORD
5533have the same meaning as for `switch-to-buffer'.
5534
5535This function is intended for interactive use only. Lisp
5536functions should call `pop-to-buffer-other-window' instead."
5537 (interactive
5538 (list (read-buffer-to-switch "Switch to buffer in other window: ")))
5539 (let ((buffer (normalize-buffer-to-switch-to buffer-or-name)))
5540 (pop-to-buffer buffer 'other-window norecord)))
5541
5542(defun switch-to-buffer-other-window-same-frame (buffer-or-name &optional norecord)
5543 "Switch to buffer BUFFER-OR-NAME in another window on the selected frame.
5544The selected window or another frame will be used only if there
5545is no other choice. Optional arguments BUFFER-OR-NAME and
5546NORECORD have the same meaning as for `switch-to-buffer'.
5547
5548This function is intended for interactive use only. Lisp
5549functions should call `pop-to-buffer-other-window-same-frame'
5550instead."
5551 (interactive
5552 (list (read-buffer-to-switch "Switch to buffer in other window: ")))
5553 (let ((buffer (normalize-buffer-to-switch-to buffer-or-name)))
5554 (pop-to-buffer buffer 'same-frame-other-window norecord)))
5555
5556(defun switch-to-buffer-other-frame (buffer-or-name &optional norecord)
5557 "Switch to buffer BUFFER-OR-NAME on another frame.
5558The same frame will be used only if there is no other choice.
5559Optional arguments BUFFER-OR-NAME and NORECORD have the same
5560meaning as for `switch-to-buffer'.
5561
5562This function is intended for interactive use only. Lisp
5563functions should call `pop-to-buffer-other-frame' instead."
5564 (interactive
5565 (list (read-buffer-to-switch "Switch to buffer in other frame: ")))
5566 (let ((buffer (normalize-buffer-to-switch-to buffer-or-name)))
5567 (pop-to-buffer buffer 'other-frame norecord)))
5568
5569;;; Obsolete definitions of `display-buffer' below.
5570(defcustom same-window-buffer-names nil
5571 "List of names of buffers that should appear in the \"same\" window.
5572`display-buffer' and `pop-to-buffer' show a buffer whose name is
5573on this list in the selected rather than some other window.
5574
5575An element of this list can be a cons cell instead of just a
5576string. In that case, the cell's car must be a string specifying
5577the buffer name. This is for compatibility with
5578`special-display-buffer-names'; the cdr of the cons cell is
5579ignored.
5580
5581See also `same-window-regexps'."
5582 :type '(repeat (string :format "%v"))
5583 :group 'windows)
5584(make-obsolete-variable
5585 'same-window-buffer-names
5586 "use `display-buffer-alist' or 2nd arg of `display-buffer' instead." "24.1")
5587
5588(defcustom same-window-regexps nil
5589 "List of regexps saying which buffers should appear in the \"same\" window.
5590`display-buffer' and `pop-to-buffer' show a buffer whose name
5591matches a regexp on this list in the selected rather than some
5592other window.
5593
5594An element of this list can be a cons cell instead of just a
5595string. In that case, the cell's car must be a regexp matching
5596the buffer name. This is for compatibility with
5597`special-display-regexps'; the cdr of the cons cell is ignored.
5598
5599See also `same-window-buffer-names'."
5600 :type '(repeat (regexp :format "%v"))
3470 :group 'windows) 5601 :group 'windows)
5602(make-obsolete-variable
5603 'same-window-regexps
5604 "use `display-buffer-alist' or 2nd arg of `display-buffer' instead." "24.1")
5605
5606(defun same-window-p (buffer-name)
5607 "Return non-nil if a buffer named BUFFER-NAME would be shown in the \"same\" window.
5608This function returns non-nil if `display-buffer' or
5609`pop-to-buffer' would show a buffer named BUFFER-NAME in the
5610selected rather than \(as usual\) some other window. See
5611`same-window-buffer-names' and `same-window-regexps'."
5612 (let ((buffer-names (with-no-warnings special-display-buffer-names))
5613 (regexps (with-no-warnings special-display-regexps)))
5614 (cond
5615 ((not (stringp buffer-name)))
5616 ;; The elements of `same-window-buffer-names' can be buffer
5617 ;; names or cons cells whose cars are buffer names.
5618 ((member buffer-name buffer-names))
5619 ((assoc buffer-name buffer-names))
5620 ((catch 'found
5621 (dolist (regexp regexps)
5622 ;; The elements of `same-window-regexps' can be regexps
5623 ;; or cons cells whose cars are regexps.
5624 (when (or (and (stringp regexp)
5625 (string-match regexp buffer-name))
5626 (and (consp regexp) (stringp (car regexp))
5627 (string-match-p (car regexp) buffer-name)))
5628 (throw 'found t))))))))
5629(make-obsolete
5630 'same-window-p "pass argument to buffer display function instead." "24.1")
5631
5632(defcustom special-display-frame-alist
5633 '((height . 14) (width . 80) (unsplittable . t))
5634 "Alist of parameters for special frames.
5635Special frames are used for buffers whose names are listed in
5636`special-display-buffer-names' and for buffers whose names match
5637one of the regular expressions in `special-display-regexps'.
5638
5639This variable can be set in your init file, like this:
5640
5641 (setq special-display-frame-alist '((width . 80) (height . 20)))
5642
5643These supersede the values given in `default-frame-alist'."
5644 :type '(repeat (cons :format "%v"
5645 (symbol :tag "Parameter")
5646 (sexp :tag "Value")))
5647 :group 'frames)
5648(make-obsolete-variable
5649 'special-display-frame-alist
5650 "use `display-buffer-alist' or 2nd arg of `display-buffer' instead." "24.1")
5651
5652(defun special-display-popup-frame (buffer &optional args)
5653 "Display BUFFER in a special frame and return the window chosen.
5654If BUFFER is already displayed in a visible or iconified frame,
5655raise that frame. Otherwise, display BUFFER in a way as
5656specified by optional argument ARGS.
5657
5658If ARGS is an alist, use it as a list of frame parameters. If
5659these parameters contain \(same-window . t), display BUFFER in
5660the selected window. If they contain \(same-frame . t), display
5661BUFFER in a window on the selected frame.
5662
5663If ARGS is a list whose car is a symbol, use (car ARGS) as a
5664function to do the work. Pass it BUFFER as first argument,
5665and (cdr ARGS) as second."
5666 (if (and args (symbolp (car args)))
5667 (apply (car args) buffer (cdr args))
5668 (let ((window (get-buffer-window buffer 0)))
5669 (or
5670 ;; If we have a window already, make it visible.
5671 (when window
5672 (let ((frame (window-frame window)))
5673 (make-frame-visible frame)
5674 (raise-frame frame)
5675 window))
5676 ;; Reuse the current window if the user requested it.
5677 (when (cdr (assq 'same-window args))
5678 (display-buffer-reuse-window
5679 buffer '(same nil nil) '((reuse-dedicated . 'weak))))
5680 ;; Stay on the same frame if requested.
5681 (when (or (cdr (assq 'same-frame args))
5682 (cdr (assq 'same-window args)))
5683 (or (display-buffer-pop-up-window
5684 buffer '((largest . nil) (lru . nil)))
5685 (display-buffer-reuse-window
5686 buffer '(nil nil nil))))
5687 ;; If no window yet, make one in a new frame.
5688 (let ((frame
5689 (with-current-buffer buffer
5690 (make-frame
5691 (append args (with-no-warnings
5692 special-display-frame-alist))))))
5693 (set-window-buffer (frame-selected-window frame) buffer)
5694 (set-window-dedicated-p (frame-selected-window frame) t)
5695 (frame-selected-window frame))))))
5696(make-obsolete
5697 'special-display-popup-frame
5698 "use `display-buffer-alist' or 2nd arg of `display-buffer' instead." "24.1")
5699
5700(defcustom special-display-function 'special-display-popup-frame
5701 "Function to call for displaying special buffers.
5702This function is called with two arguments - the buffer and,
5703optionally, a list - and should return a window displaying that
5704buffer. The default value usually makes a separate frame for the
5705buffer using `special-display-frame-alist' to specify the frame
5706parameters. See the definition of `special-display-popup-frame'
5707for how to specify such a function.
5708
5709A buffer is special when its name is either listed in
5710`special-display-buffer-names' or matches a regexp in
5711`special-display-regexps'."
5712 :type 'function
5713 :group 'windows
5714 :group 'frames)
5715(make-obsolete-variable
5716 'special-display-function
5717 "use `display-buffer-alist' or 2nd arg of `display-buffer' instead." "24.1")
3471 5718
3472(defcustom special-display-buffer-names nil 5719(defcustom special-display-buffer-names nil
3473 "List of names of buffers that should be displayed specially. 5720 "List of names of buffers that should be displayed specially.
@@ -3532,6 +5779,9 @@ See also `special-display-regexps'."
3532 (repeat :tag "Arguments" (sexp))))) 5779 (repeat :tag "Arguments" (sexp)))))
3533 :group 'windows 5780 :group 'windows
3534 :group 'frames) 5781 :group 'frames)
5782(make-obsolete-variable
5783 'special-display-buffer-names
5784 "use `display-buffer-alist' or 2nd arg of `display-buffer' instead." "24.1")
3535 5785
3536;;;###autoload 5786;;;###autoload
3537(put 'special-display-buffer-names 'risky-local-variable t) 5787(put 'special-display-buffer-names 'risky-local-variable t)
@@ -3600,6 +5850,9 @@ See also `special-display-buffer-names'."
3600 (repeat :tag "Arguments" (sexp))))) 5850 (repeat :tag "Arguments" (sexp)))))
3601 :group 'windows 5851 :group 'windows
3602 :group 'frames) 5852 :group 'frames)
5853(make-obsolete-variable
5854 'special-display-regexps
5855 "use `display-buffer-alist' or 2nd arg of `display-buffer' instead." "24.1")
3603 5856
3604(defun special-display-p (buffer-name) 5857(defun special-display-p (buffer-name)
3605 "Return non-nil if a buffer named BUFFER-NAME gets a special frame. 5858 "Return non-nil if a buffer named BUFFER-NAME gets a special frame.
@@ -3609,15 +5862,17 @@ matching BUFFER-NAME. If `special-display-buffer-names' or
3609`special-display-regexps' contain a list entry whose car equals 5862`special-display-regexps' contain a list entry whose car equals
3610or matches BUFFER-NAME, the return value is the cdr of that 5863or matches BUFFER-NAME, the return value is the cdr of that
3611entry." 5864entry."
3612 (let (tmp) 5865 (let ((buffer-names (with-no-warnings special-display-buffer-names))
5866 (regexps (with-no-warnings special-display-regexps))
5867 tmp)
3613 (cond 5868 (cond
3614 ((not (stringp buffer-name))) 5869 ((not (stringp buffer-name)))
3615 ((member buffer-name special-display-buffer-names) 5870 ((member buffer-name buffer-names)
3616 t) 5871 t)
3617 ((setq tmp (assoc buffer-name special-display-buffer-names)) 5872 ((setq tmp (assoc buffer-name buffer-names))
3618 (cdr tmp)) 5873 (cdr tmp))
3619 ((catch 'found 5874 ((catch 'found
3620 (dolist (regexp special-display-regexps) 5875 (dolist (regexp regexps)
3621 (cond 5876 (cond
3622 ((stringp regexp) 5877 ((stringp regexp)
3623 (when (string-match-p regexp buffer-name) 5878 (when (string-match-p regexp buffer-name)
@@ -3625,117 +5880,101 @@ entry."
3625 ((and (consp regexp) (stringp (car regexp)) 5880 ((and (consp regexp) (stringp (car regexp))
3626 (string-match-p (car regexp) buffer-name)) 5881 (string-match-p (car regexp) buffer-name))
3627 (throw 'found (cdr regexp)))))))))) 5882 (throw 'found (cdr regexp))))))))))
3628 5883(make-obsolete
3629(defcustom special-display-function 'special-display-popup-frame 5884 'special-display-p
3630 "Function to call for displaying special buffers. 5885 "pass argument to buffer display function instead." "24.1")
3631This function is called with two arguments - the buffer and, 5886
3632optionally, a list - and should return a window displaying that 5887(defcustom pop-up-frame-alist nil
3633buffer. The default value usually makes a separate frame for the 5888 "Alist of parameters for automatically generated new frames.
3634buffer using `special-display-frame-alist' to specify the frame 5889You can set this in your init file; for example,
3635parameters. See the definition of `special-display-popup-frame' 5890
3636for how to specify such a function. 5891 (setq pop-up-frame-alist '((width . 80) (height . 20)))
3637 5892
3638A buffer is special when its name is either listed in 5893If non-nil, the value you specify here is used by the default
3639`special-display-buffer-names' or matches a regexp in 5894`pop-up-frame-function' for the creation of new frames.
3640`special-display-regexps'." 5895
5896Since `pop-up-frame-function' is used by `display-buffer' for
5897making new frames, any value specified here by default affects
5898the automatic generation of new frames via `display-buffer' and
5899all functions based on it. The behavior of `make-frame' is not
5900affected by this variable."
5901 :type '(repeat (cons :format "%v"
5902 (symbol :tag "Parameter")
5903 (sexp :tag "Value")))
5904 :group 'frames)
5905(make-obsolete-variable
5906 'pop-up-frame-alist
5907 "use `display-buffer-alist' or 2nd arg of `display-buffer' instead." "24.1")
5908
5909(defcustom pop-up-frame-function
5910 (lambda () (make-frame pop-up-frame-alist))
5911 "Function used by `display-buffer' for creating a new frame.
5912This function is called with no arguments and should return a new
5913frame. The default value calls `make-frame' with the argument
5914`pop-up-frame-alist'."
3641 :type 'function 5915 :type 'function
3642 :group 'frames) 5916 :group 'frames)
5917(make-obsolete-variable
5918 'pop-up-frame-function
5919 "use `display-buffer-alist' or 2nd arg of `display-buffer' instead." "24.1")
3643 5920
3644(defcustom same-window-buffer-names nil 5921(defcustom pop-up-frames 'unset ; nil
3645 "List of names of buffers that should appear in the \"same\" window.
3646`display-buffer' and `pop-to-buffer' show a buffer whose name is
3647on this list in the selected rather than some other window.
3648
3649An element of this list can be a cons cell instead of just a
3650string. In that case, the cell's car must be a string specifying
3651the buffer name. This is for compatibility with
3652`special-display-buffer-names'; the cdr of the cons cell is
3653ignored.
3654
3655See also `same-window-regexps'."
3656 :type '(repeat (string :format "%v"))
3657 :group 'windows)
3658
3659(defcustom same-window-regexps nil
3660 "List of regexps saying which buffers should appear in the \"same\" window.
3661`display-buffer' and `pop-to-buffer' show a buffer whose name
3662matches a regexp on this list in the selected rather than some
3663other window.
3664
3665An element of this list can be a cons cell instead of just a
3666string. In that case, the cell's car must be a regexp matching
3667the buffer name. This is for compatibility with
3668`special-display-regexps'; the cdr of the cons cell is ignored.
3669
3670See also `same-window-buffer-names'."
3671 :type '(repeat (regexp :format "%v"))
3672 :group 'windows)
3673
3674(defun same-window-p (buffer-name)
3675 "Return non-nil if a buffer named BUFFER-NAME would be shown in the \"same\" window.
3676This function returns non-nil if `display-buffer' or
3677`pop-to-buffer' would show a buffer named BUFFER-NAME in the
3678selected rather than \(as usual\) some other window. See
3679`same-window-buffer-names' and `same-window-regexps'."
3680 (cond
3681 ((not (stringp buffer-name)))
3682 ;; The elements of `same-window-buffer-names' can be buffer
3683 ;; names or cons cells whose cars are buffer names.
3684 ((member buffer-name same-window-buffer-names))
3685 ((assoc buffer-name same-window-buffer-names))
3686 ((catch 'found
3687 (dolist (regexp same-window-regexps)
3688 ;; The elements of `same-window-regexps' can be regexps
3689 ;; or cons cells whose cars are regexps.
3690 (when (or (and (stringp regexp)
3691 (string-match regexp buffer-name))
3692 (and (consp regexp) (stringp (car regexp))
3693 (string-match-p (car regexp) buffer-name)))
3694 (throw 'found t)))))))
3695
3696(defcustom pop-up-frames nil
3697 "Whether `display-buffer' should make a separate frame. 5922 "Whether `display-buffer' should make a separate frame.
3698If nil, never make a separate frame. 5923If nil, never make a separate frame.
3699If the value is `graphic-only', make a separate frame 5924If the value is `graphic-only', make a separate frame
3700on graphic displays only. 5925on graphic displays only.
5926If this is the symbol unset, the option was not set and is
5927ignored.
3701Any other non-nil value means always make a separate frame." 5928Any other non-nil value means always make a separate frame."
3702 :type '(choice 5929 :type '(choice
5930 (const :tag "Unset" unset)
3703 (const :tag "Never" nil) 5931 (const :tag "Never" nil)
3704 (const :tag "On graphic displays only" graphic-only) 5932 (const :tag "On graphic displays only" graphic-only)
3705 (const :tag "Always" t)) 5933 (const :tag "Always" t))
3706 :group 'windows) 5934 :version "24.1"
5935 :group 'windows
5936 :group 'frames)
5937(make-obsolete-variable
5938 'pop-up-frames
5939 "use `display-buffer-alist' or 2nd arg of `display-buffer' instead." "24.1")
3707 5940
3708(defcustom display-buffer-reuse-frames nil 5941(defcustom display-buffer-reuse-frames 'unset ; nil
3709 "Non-nil means `display-buffer' should reuse frames. 5942 "Set and non-nil means `display-buffer' should reuse frames.
3710If the buffer in question is already displayed in a frame, raise 5943If the buffer in question is already displayed in a frame, raise
3711that frame." 5944that frame."
3712 :type 'boolean 5945 :type 'boolean
3713 :version "21.1" 5946 :version "24.1"
3714 :group 'windows) 5947 :group 'windows
5948 :group 'frames)
5949(make-obsolete-variable
5950 'display-buffer-reuse-frames
5951 "use `display-buffer-alist' or 2nd arg of `display-buffer' instead." "24.1")
3715 5952
3716(defcustom pop-up-windows t 5953(defcustom pop-up-windows 'unset ; t
3717 "Non-nil means `display-buffer' should make a new window." 5954 "Set and non-nil means `display-buffer' should make a new window."
3718 :type 'boolean 5955 :type 'boolean
5956 :version "24.1"
3719 :group 'windows) 5957 :group 'windows)
5958(make-obsolete-variable
5959 'pop-up-windows
5960 "use `display-buffer-alist' or 2nd arg of `display-buffer' instead." "24.1")
3720 5961
3721(defcustom split-window-preferred-function 'split-window-sensibly 5962(defcustom split-window-preferred-function 'split-window-sensibly
3722 "Function called by `display-buffer' routines to split a window. 5963 "Function called by `display-buffer' to split a window.
3723This function is called with a window as single argument and is 5964This function is called with a window as single argument and is
3724supposed to split that window and return the new window. If the 5965supposed to split that window and return the new window. If the
3725window can (or shall) not be split, it is supposed to return nil. 5966window can (or shall) not be split, it is supposed to return nil.
5967
3726The default is to call the function `split-window-sensibly' which 5968The default is to call the function `split-window-sensibly' which
3727tries to split the window in a way which seems most suitable. 5969tries to split the window in a way which seems most suitable.
3728You can customize the options `split-height-threshold' and/or 5970You can customize the options `split-height-threshold' and/or
3729`split-width-threshold' in order to have `split-window-sensibly' 5971`split-width-threshold' in order to have `split-window-sensibly'
3730prefer either vertical or horizontal splitting. 5972prefer either vertical or horizontal splitting.
3731 5973
3732If you set this to any other function, bear in mind that the 5974If you set this to any other function, bear in mind that
3733`display-buffer' routines may call this function two times. The 5975`display-buffer' may call that function repeatedly; the option
3734argument of the first call is the largest window on its frame. 5976`pop-up-windows' controls which windows may become the argument
3735If that call fails to return a live window, the function is 5977of this function.
3736called again with the least recently used window as argument. If
3737that call fails too, `display-buffer' will use an existing window
3738to display its buffer.
3739 5978
3740The window selected at the time `display-buffer' was invoked is 5979The window selected at the time `display-buffer' was invoked is
3741still selected when this function is called. Hence you can 5980still selected when this function is called. Hence you can
@@ -3745,28 +5984,55 @@ not want to split the selected window."
3745 :type 'function 5984 :type 'function
3746 :version "23.1" 5985 :version "23.1"
3747 :group 'windows) 5986 :group 'windows)
5987(make-obsolete-variable
5988 'split-window-preferred-function
5989 "use `display-buffer-alist' or 2nd arg of `display-buffer' instead." "24.1")
3748 5990
3749(defcustom split-height-threshold 80 5991(defcustom split-height-threshold 80
3750 "Minimum height for splitting windows sensibly. 5992 "Minimum height for splitting a window to display a buffer.
3751If this is an integer, `split-window-sensibly' may split a window 5993If this is an integer, `display-buffer' can split a window
3752vertically only if it has at least this many lines. If this is 5994vertically only if it has at least this many lines. If this is
3753nil, `split-window-sensibly' is not allowed to split a window 5995nil, `display-buffer' does not split windows vertically. If a
3754vertically. If, however, a window is the only window on its 5996window is the only window on its frame, `display-buffer' may
3755frame, `split-window-sensibly' may split it vertically 5997split it vertically disregarding the value of this variable."
3756disregarding the value of this variable."
3757 :type '(choice (const nil) (integer :tag "lines")) 5998 :type '(choice (const nil) (integer :tag "lines"))
3758 :version "23.1" 5999 :version "23.1"
3759 :group 'windows) 6000 :group 'windows)
6001(make-obsolete-variable
6002 'split-height-threshold
6003 "use `display-buffer-alist' or 2nd arg of `display-buffer' instead." "24.1")
3760 6004
3761(defcustom split-width-threshold 160 6005(defcustom split-width-threshold 160
3762 "Minimum width for splitting windows sensibly. 6006 "Minimum width for splitting a window to display a buffer.
3763If this is an integer, `split-window-sensibly' may split a window 6007If this is an integer, `display-buffer' can split a window
3764horizontally only if it has at least this many columns. If this 6008horizontally only if it has at least this many columns. If this
3765is nil, `split-window-sensibly' is not allowed to split a window 6009is nil, `display-buffer' cannot split windows horizontally."
3766horizontally."
3767 :type '(choice (const nil) (integer :tag "columns")) 6010 :type '(choice (const nil) (integer :tag "columns"))
3768 :version "23.1" 6011 :version "23.1"
3769 :group 'windows) 6012 :group 'windows)
6013(make-obsolete-variable
6014 'split-width-threshold
6015 "use `display-buffer-alist' or 2nd arg of `display-buffer' instead." "24.1")
6016
6017(defcustom even-window-heights t
6018 "If non-nil `display-buffer' will try to even window heights.
6019Otherwise `display-buffer' will leave the window configuration
6020alone. Heights are evened only when `display-buffer' reuses a
6021window that appears above or below the selected window."
6022 :type 'boolean
6023 :version "23.1"
6024 :group 'windows)
6025(make-obsolete-variable
6026 'even-window-heights
6027 "use `display-buffer-alist' or 2nd arg of `display-buffer' instead." "24.1")
6028
6029(defvar display-buffer-mark-dedicated 'unset ; nil
6030 "Set and non-nil means `display-buffer' marks the windows it creates as dedicated.
6031The actual non-nil value of this variable will be copied to the
6032`window-dedicated-p' flag.")
6033(make-obsolete-variable
6034 'display-buffer-mark-dedicated
6035 "use `display-buffer-alist' or 2nd arg of `display-buffer' instead." "24.1")
3770 6036
3771(defun window-splittable-p (window &optional horizontal) 6037(defun window-splittable-p (window &optional horizontal)
3772 "Return non-nil if `split-window-sensibly' may split WINDOW. 6038 "Return non-nil if `split-window-sensibly' may split WINDOW.
@@ -3817,6 +6083,8 @@ hold:
3817 (max split-height-threshold 6083 (max split-height-threshold
3818 (* 2 (max window-min-height 6084 (* 2 (max window-min-height
3819 (if mode-line-format 2 1)))))))))) 6085 (if mode-line-format 2 1))))))))))
6086(make-obsolete
6087 'window-splittable-p "use 2nd arg of `display-buffer' instead." "24.1")
3820 6088
3821(defun split-window-sensibly (window) 6089(defun split-window-sensibly (window)
3822 "Split WINDOW in a way suitable for `display-buffer'. 6090 "Split WINDOW in a way suitable for `display-buffer'.
@@ -3849,11 +6117,11 @@ more likely to occur.
3849Have a look at the function `window-splittable-p' if you want to 6117Have a look at the function `window-splittable-p' if you want to
3850know how `split-window-sensibly' determines whether WINDOW can be 6118know how `split-window-sensibly' determines whether WINDOW can be
3851split." 6119split."
3852 (or (and (window-splittable-p window) 6120 (or (and (with-no-warnings (window-splittable-p window))
3853 ;; Split window vertically. 6121 ;; Split window vertically.
3854 (with-selected-window window 6122 (with-selected-window window
3855 (split-window-vertically))) 6123 (split-window-vertically)))
3856 (and (window-splittable-p window t) 6124 (and (with-no-warnings (window-splittable-p window t))
3857 ;; Split window horizontally. 6125 ;; Split window horizontally.
3858 (with-selected-window window 6126 (with-selected-window window
3859 (split-window-horizontally))) 6127 (split-window-horizontally)))
@@ -3863,433 +6131,233 @@ split."
3863 ;; minibuffer window, try to split it vertically disregarding 6131 ;; minibuffer window, try to split it vertically disregarding
3864 ;; the value of `split-height-threshold'. 6132 ;; the value of `split-height-threshold'.
3865 (let ((split-height-threshold 0)) 6133 (let ((split-height-threshold 0))
3866 (when (window-splittable-p window) 6134 (when (with-no-warnings (window-splittable-p window))
3867 (with-selected-window window 6135 (with-selected-window window
3868 (split-window-vertically))))))) 6136 (split-window-vertically)))))))
3869 6137(make-obsolete
3870(defun window--try-to-split-window (window) 6138 'split-window-sensibly "use 2nd arg of `display-buffer' instead." "24.1")
3871 "Try to split WINDOW. 6139
3872Return value returned by `split-window-preferred-function' if it 6140;; Functions for converting Emacs 23 buffer display options to buffer
3873represents a live window, nil otherwise." 6141;; display specifiers.
3874 (and (window-live-p window) 6142(defun display-buffer-alist-add (identifiers specifiers &optional no-custom)
3875 (not (frame-parameter (window-frame window) 'unsplittable)) 6143 "Helper function for `display-buffer-alist-set'."
3876 (let ((new-window 6144 (unless identifiers
3877 ;; Since `split-window-preferred-function' might 6145 (setq identifiers '((regexp . ".*"))))
3878 ;; throw an error use `condition-case'. 6146 (unless (atom specifiers)
3879 (condition-case nil 6147 (setq specifiers (delq nil specifiers)))
3880 (funcall split-window-preferred-function window) 6148
3881 (error nil)))) 6149 (if no-custom
3882 (and (window-live-p new-window) new-window)))) 6150 (setq display-buffer-alist
3883 6151 (cons (cons identifiers specifiers) display-buffer-alist))
3884(defun window--frame-usable-p (frame) 6152 (customize-set-variable
3885 "Return FRAME if it can be used to display a buffer." 6153 'display-buffer-alist
3886 (when (frame-live-p frame) 6154 (cons (cons identifiers specifiers) display-buffer-alist))))
3887 (let ((window (frame-root-window frame))) 6155
3888 ;; `frame-root-window' may be an internal window which is considered 6156(defun display-buffer-alist-set (&optional no-custom add)
3889 ;; "dead" by `window-live-p'. Hence if `window' is not live we 6157 "Set `display-buffer-alist' from Emacs 23 buffer display options.
3890 ;; implicitly know that `frame' has a visible window we can use. 6158Optional argument NO-CUSTOM nil means use `customize-set-variable'
3891 (unless (and (window-live-p window) 6159to set the value of `display-buffer-alist'. NO-CUSTOM non-nil
3892 (or (window-minibuffer-p window) 6160means to use `setq' instead.
3893 ;; If the window is soft-dedicated, the frame is usable. 6161
3894 ;; Actually, even if the window is really dedicated, 6162Optional argument ADD nil means to replace the actual value of
3895 ;; the frame is still usable by splitting it. 6163`display-buffer-alist' with the value calculated here. ADD
3896 ;; At least Emacs-22 allowed it, and it is desirable 6164non-nil means prepend the value calculated here to the current
3897 ;; when displaying same-frame windows. 6165value of `display-buffer-alist'."
3898 nil ; (eq t (window-dedicated-p window)) 6166 (unless add
3899 )) 6167 (if no-custom
3900 frame)))) 6168 (setq display-buffer-alist nil)
3901 6169 (customize-set-variable 'display-buffer-alist nil)))
3902(defcustom even-window-heights t 6170
3903 "If non-nil `display-buffer' will try to even window heights. 6171 ;; Disable warnings, there are too many obsolete options here.
3904Otherwise `display-buffer' will leave the window configuration 6172 (with-no-warnings
3905alone. Heights are evened only when `display-buffer' chooses a 6173 ;; `pop-up-windows'
3906window that appears above or below the selected window." 6174 (display-buffer-alist-add
3907 :type 'boolean 6175 nil
3908 :group 'windows) 6176 (let ((fun (unless (eq split-window-preferred-function
3909 6177 'split-window-sensibly)
3910(defun window--even-window-heights (window) 6178 ;; `split-window-sensibly' has been merged into the
3911 "Even heights of WINDOW and selected window. 6179 ;; `display-buffer-split-window' code as `nil'.
3912Do this only if these windows are vertically adjacent to each 6180 split-window-preferred-function))
3913other, `even-window-heights' is non-nil, and the selected window 6181 (min-height
3914is higher than WINDOW." 6182 (if (numberp split-height-threshold)
3915 (when (and even-window-heights 6183 (/ split-height-threshold 2)
3916 (not (eq window (selected-window))) 6184 ;; Undocumented hack.
3917 ;; Don't resize minibuffer windows. 6185 1.0))
3918 (not (window-minibuffer-p (selected-window))) 6186 (min-width
3919 (> (window-height (selected-window)) (window-height window)) 6187 (if (numberp split-width-threshold)
3920 (eq (window-frame window) (window-frame (selected-window))) 6188 (/ split-width-threshold 2)
3921 (let ((sel-edges (window-edges (selected-window))) 6189 ;; Undocumented hack.
3922 (win-edges (window-edges window))) 6190 1.0)))
3923 (and (= (nth 0 sel-edges) (nth 0 win-edges)) 6191 (list
3924 (= (nth 2 sel-edges) (nth 2 win-edges)) 6192 'pop-up-window
3925 (or (= (nth 1 sel-edges) (nth 3 win-edges)) 6193 (when pop-up-windows ; unset qualifies as t
3926 (= (nth 3 sel-edges) (nth 1 win-edges)))))) 6194 (list
3927 (let ((window-min-height 1)) 6195 'pop-up-window
3928 ;; Don't throw an error if we can't even window heights for 6196 (cons 'largest fun)
3929 ;; whatever reason. 6197 (cons 'lru fun)))
3930 (condition-case nil 6198 (cons 'pop-up-window-min-height min-height)
3931 (enlarge-window (/ (- (window-height window) (window-height)) 2)) 6199 (cons 'pop-up-window-min-width min-width)))
3932 (error nil))))) 6200 no-custom)
3933 6201
3934(defun window--display-buffer-1 (window) 6202 ;; `pop-up-frames'
3935 "Raise the frame containing WINDOW. 6203 (display-buffer-alist-add
3936Do not raise the selected frame. Return WINDOW." 6204 nil
3937 (let* ((frame (window-frame window)) 6205 (list
3938 (visible (frame-visible-p frame))) 6206 'pop-up-frame
3939 (unless (or (not visible) 6207 (unless (memq pop-up-frames '(nil unset))
3940 ;; Assume the selected frame is already visible enough. 6208 (list 'pop-up-frame pop-up-frames))
3941 (eq frame (selected-frame)) 6209 (when pop-up-frame-function
3942 ;; Assume the frame from which we invoked the minibuffer 6210 (cons 'pop-up-frame-function pop-up-frame-function))
3943 ;; is visible. 6211 (when pop-up-frame-alist
3944 (and (minibuffer-window-active-p (selected-window)) 6212 (cons 'pop-up-frame-alist pop-up-frame-alist)))
3945 (eq frame (window-frame (minibuffer-selected-window))))) 6213 no-custom)
3946 (raise-frame frame)) 6214
3947 window)) 6215 ;; `special-display-regexps'
3948 6216 (dolist (entry special-display-regexps)
3949(defun window--display-buffer-2 (buffer window &optional dedicated) 6217 (cond
3950 "Display BUFFER in WINDOW and make its frame visible. 6218 ((stringp entry)
3951Set `window-dedicated-p' to DEDICATED if non-nil. 6219 ;; Plain string.
3952Return WINDOW." 6220 (display-buffer-alist-add
3953 (when (and (buffer-live-p buffer) (window-live-p window)) 6221 `((regexp . ,entry))
3954 (set-window-buffer window buffer) 6222 (list
3955 (when dedicated 6223 'fun-with-args
3956 (set-window-dedicated-p window dedicated)) 6224 (list 'fun-with-args special-display-function
3957 (window--display-buffer-1 window))) 6225 special-display-frame-alist))
3958 6226 no-custom))
3959(defvar display-buffer-mark-dedicated nil 6227 ((consp entry)
3960 "If non-nil, `display-buffer' marks the windows it creates as dedicated. 6228 (let ((name (car entry))
3961The actual non-nil value of this variable will be copied to the 6229 (rest (cdr entry)))
3962`window-dedicated-p' flag.") 6230 (cond
3963 6231 ((functionp (car rest))
3964(defun display-buffer (buffer-or-name &optional not-this-window frame) 6232 ;; A function.
3965 "Make buffer BUFFER-OR-NAME appear in some window but don't select it. 6233 (display-buffer-alist-add
3966BUFFER-OR-NAME must be a buffer or the name of an existing 6234 `((name . ,name))
3967buffer. Return the window chosen to display BUFFER-OR-NAME or 6235 (list
3968nil if no such window is found. 6236 'fun-with-args
3969 6237 ;; Weary.
3970Optional argument NOT-THIS-WINDOW non-nil means display the 6238 (list 'fun-with-args (car rest) (cadr rest)))
3971buffer in a window other than the selected one, even if it is 6239 no-custom))
3972already displayed in the selected window. 6240 ((listp rest)
3973 6241 ;; A list of parameters.
3974Optional argument FRAME specifies which frames to investigate 6242 (cond
3975when the specified buffer is already displayed. If the buffer is 6243 ((assq 'same-window rest)
3976already displayed in some window on one of these frames simply 6244 (display-buffer-alist-add
3977return that window. Possible values of FRAME are: 6245 `((name . ,name))
3978 6246 (list 'reuse-window
3979`visible' - consider windows on all visible frames on the current 6247 (list 'reuse-window 'same)
3980terminal. 6248 (list 'reuse-window-dedicated 'weak))
3981 6249 no-custom))
39820 - consider windows on all visible or iconified frames on the 6250 ((assq 'same-frame rest)
3983current terminal. 6251 (display-buffer-alist-add
3984 6252 `((name . ,name)) (list 'same-frame) no-custom))
3985t - consider windows on all frames. 6253 (t
3986 6254 (display-buffer-alist-add
3987A specific frame - consider windows on that frame only. 6255 `((name . ,name))
3988 6256 (list
3989nil - consider windows on the selected frame \(actually the 6257 'fun-with-args
3990last non-minibuffer frame\) only. If, however, either 6258 (list 'fun-with-args special-display-function
3991`display-buffer-reuse-frames' or `pop-up-frames' is non-nil 6259 special-display-frame-alist))
3992\(non-nil and not graphic-only on a text-only terminal), 6260 no-custom)))))))))
3993consider all visible or iconified frames on the current terminal." 6261
3994 (interactive "BDisplay buffer:\nP") 6262 ;; `special-display-buffer-names'
3995 (let* ((can-use-selected-window 6263 (dolist (entry special-display-buffer-names)
3996 ;; The selected window is usable unless either NOT-THIS-WINDOW 6264 (cond
3997 ;; is non-nil, it is dedicated to its buffer, or it is the 6265 ((stringp entry)
3998 ;; `minibuffer-window'. 6266 ;; Plain string.
3999 (not (or not-this-window 6267 (display-buffer-alist-add
4000 (window-dedicated-p (selected-window)) 6268 `((name . ,entry))
4001 (window-minibuffer-p)))) 6269 (list
4002 (buffer (if (bufferp buffer-or-name) 6270 'fun-with-args
4003 buffer-or-name 6271 (list 'fun-with-args special-display-function
4004 (get-buffer buffer-or-name))) 6272 special-display-frame-alist))
4005 (name-of-buffer (buffer-name buffer)) 6273 no-custom))
4006 ;; On text-only terminals do not pop up a new frame when 6274 ((consp entry)
4007 ;; `pop-up-frames' equals graphic-only. 6275 (let ((name (car entry))
4008 (use-pop-up-frames (if (eq pop-up-frames 'graphic-only) 6276 (rest (cdr entry)))
4009 (display-graphic-p) 6277 (cond
4010 pop-up-frames)) 6278 ((functionp (car rest))
4011 ;; `frame-to-use' is the frame where to show `buffer' - either 6279 ;; A function.
4012 ;; the selected frame or the last nonminibuffer frame. 6280 (display-buffer-alist-add
4013 (frame-to-use 6281 `((name . ,name))
4014 (or (window--frame-usable-p (selected-frame)) 6282 (list
4015 (window--frame-usable-p (last-nonminibuffer-frame)))) 6283 'fun-with-args
4016 ;; `window-to-use' is the window we use for showing `buffer'. 6284 ;; Weary.
4017 window-to-use) 6285 (list 'fun-with-args (car rest) (cadr rest)))
4018 (cond 6286 no-custom))
4019 ((not (buffer-live-p buffer)) 6287 ((listp rest)
4020 (error "No such buffer %s" buffer)) 6288 ;; A list of parameters.
4021 (display-buffer-function 6289 (cond
4022 ;; Let `display-buffer-function' do the job. 6290 ((assq 'same-window rest)
4023 (funcall display-buffer-function buffer not-this-window)) 6291 (display-buffer-alist-add
4024 ((and (not not-this-window) 6292 `((name . ,name))
4025 (eq (window-buffer (selected-window)) buffer)) 6293 (list 'reuse-window
4026 ;; The selected window already displays BUFFER and 6294 (list 'reuse-window 'same)
4027 ;; `not-this-window' is nil, so use it. 6295 (list 'reuse-window-dedicated 'weak))
4028 (window--display-buffer-1 (selected-window))) 6296 no-custom))
4029 ((and can-use-selected-window (same-window-p name-of-buffer)) 6297 ((assq 'same-frame rest)
4030 ;; If the buffer's name tells us to use the selected window do so. 6298 (display-buffer-alist-add
4031 (window--display-buffer-2 buffer (selected-window))) 6299 `((name . ,name)) (list 'same-frame) no-custom))
4032 ((let ((frames (or frame 6300 (t
4033 (and (or use-pop-up-frames 6301 (display-buffer-alist-add
4034 display-buffer-reuse-frames 6302 `((name . ,name))
4035 (not (last-nonminibuffer-frame))) 6303 (list
4036 0) 6304 'fun-with-args
4037 (last-nonminibuffer-frame)))) 6305 (list 'fun-with-args special-display-function
4038 (setq window-to-use 6306 special-display-frame-alist))
4039 (catch 'found 6307 no-custom)))))))))
4040 ;; Search frames for a window displaying BUFFER. Return 6308
4041 ;; the selected window only if we are allowed to do so. 6309 ;; `same-window-regexps'
4042 (dolist (window (get-buffer-window-list buffer 'nomini frames)) 6310 (dolist (entry same-window-regexps)
4043 (when (or can-use-selected-window 6311 (cond
4044 (not (eq (selected-window) window))) 6312 ((stringp entry)
4045 (throw 'found window)))))) 6313 (display-buffer-alist-add
4046 ;; The buffer is already displayed in some window; use that. 6314 `((regexp . ,entry))
4047 (window--display-buffer-1 window-to-use)) 6315 (list 'reuse-window (list 'reuse-window 'same))
4048 ((and special-display-function 6316 no-custom))
4049 ;; `special-display-p' returns either t or a list of frame 6317 ((consp entry)
4050 ;; parameters to pass to `special-display-function'. 6318 (display-buffer-alist-add
4051 (let ((pars (special-display-p name-of-buffer))) 6319 `((regexp . ,(car entry)))
4052 (when pars 6320 (list 'reuse-window (list 'reuse-window 'same))
4053 (funcall special-display-function 6321 no-custom))))
4054 buffer (if (listp pars) pars)))))) 6322
4055 ((or use-pop-up-frames (not frame-to-use)) 6323 ;; `same-window-buffer-names'
4056 ;; We want or need a new frame. 6324 (dolist (entry same-window-buffer-names)
4057 (let ((win (frame-selected-window (funcall pop-up-frame-function)))) 6325 (cond
4058 (window--display-buffer-2 buffer win display-buffer-mark-dedicated))) 6326 ((stringp entry)
4059 ((and pop-up-windows 6327 (display-buffer-alist-add
4060 ;; Make a new window. 6328 `((name . ,entry))
4061 (or (not (frame-parameter frame-to-use 'unsplittable)) 6329 (list 'reuse-window (list 'reuse-window 'same))
4062 ;; If the selected frame cannot be split look at 6330 no-custom))
4063 ;; `last-nonminibuffer-frame'. 6331 ((consp entry)
4064 (and (eq frame-to-use (selected-frame)) 6332 (display-buffer-alist-add
4065 (setq frame-to-use (last-nonminibuffer-frame)) 6333 `((name . ,(car entry)))
4066 (window--frame-usable-p frame-to-use) 6334 (list 'reuse-window (list 'reuse-window 'same))
4067 (not (frame-parameter frame-to-use 'unsplittable)))) 6335 no-custom))))
4068 ;; Attempt to split largest or least recently used window. 6336
4069 (setq window-to-use 6337 ;; `reuse-window'
4070 (or (window--try-to-split-window 6338 (display-buffer-alist-add
4071 (get-largest-window frame-to-use t)) 6339 nil
4072 (window--try-to-split-window 6340 (list
4073 (get-lru-window frame-to-use t))))) 6341 'reuse-window
4074 (window--display-buffer-2 buffer window-to-use 6342 (list 'reuse-window nil 'same
4075 display-buffer-mark-dedicated)) 6343 (unless (and (memq display-buffer-reuse-frames '(nil unset))
4076 ((let ((window-to-undedicate 6344 (memq pop-up-frames '(nil unset)))
4077 ;; When NOT-THIS-WINDOW is non-nil, temporarily dedicate 6345 ;; "0" (all visible and iconified frames) is hardcoded in
4078 ;; the selected window to its buffer, to avoid that some of 6346 ;; Emacs 23.
4079 ;; the `get-' routines below choose it. (Bug#1415) 6347 0))
4080 (and not-this-window (not (window-dedicated-p)) 6348 (when even-window-heights
4081 (set-window-dedicated-p (selected-window) t) 6349 (cons 'reuse-window-even-sizes t)))
4082 (selected-window)))) 6350 no-custom)
4083 (unwind-protect 6351
4084 (setq window-to-use 6352 ;; `display-buffer-mark-dedicated'
4085 ;; Reuse an existing window. 6353 (unless (memq display-buffer-mark-dedicated '(nil unset))
4086 (or (get-lru-window frame-to-use) 6354 (display-buffer-alist-add
4087 (let ((window (get-buffer-window buffer 'visible))) 6355 nil
4088 (unless (and not-this-window 6356 (list
4089 (eq window (selected-window))) 6357 (cons 'dedicated display-buffer-mark-dedicated))
4090 window)) 6358 no-custom)))
4091 (get-largest-window 'visible) 6359
4092 (let ((window (get-buffer-window buffer 0))) 6360 display-buffer-alist)
4093 (unless (and not-this-window
4094 (eq window (selected-window)))
4095 window))
4096 (get-largest-window 0)
4097 (frame-selected-window (funcall pop-up-frame-function))))
4098 (when (window-live-p window-to-undedicate)
4099 ;; Restore dedicated status of selected window.
4100 (set-window-dedicated-p window-to-undedicate nil))))
4101 (window--even-window-heights window-to-use)
4102 (window--display-buffer-2 buffer window-to-use)))))
4103
4104(defun display-buffer-other-frame (buffer)
4105 "Display buffer BUFFER in another frame.
4106This uses the function `display-buffer' as a subroutine; see
4107its documentation for additional customization information."
4108 (interactive "BDisplay buffer in other frame: ")
4109 (let ((pop-up-frames t)
4110 same-window-buffer-names same-window-regexps
4111 ;;(old-window (selected-window))
4112 new-window)
4113 (setq new-window (display-buffer buffer t))
4114 ;; This may have been here in order to prevent the new frame from hiding
4115 ;; the old frame. But it does more harm than good.
4116 ;; Maybe we should call `raise-window' on the old-frame instead? --Stef
4117 ;;(lower-frame (window-frame new-window))
4118
4119 ;; This may have been here in order to make sure the old-frame gets the
4120 ;; focus. But not only can it cause an annoying flicker, with some
4121 ;; window-managers it just makes the window invisible, with no easy
4122 ;; way to recover it. --Stef
4123 ;;(make-frame-invisible (window-frame old-window))
4124 ;;(make-frame-visible (window-frame old-window))
4125 ))
4126
4127(defun pop-to-buffer (buffer-or-name &optional other-window norecord)
4128 "Select buffer BUFFER-OR-NAME in some window, preferably a different one.
4129BUFFER-OR-NAME may be a buffer, a string \(a buffer name), or
4130nil. If BUFFER-OR-NAME is a string not naming an existent
4131buffer, create a buffer with that name. If BUFFER-OR-NAME is
4132nil, choose some other buffer.
4133
4134If `pop-up-windows' is non-nil, windows can be split to display
4135the buffer. If optional second arg OTHER-WINDOW is non-nil,
4136insist on finding another window even if the specified buffer is
4137already visible in the selected window, and ignore
4138`same-window-regexps' and `same-window-buffer-names'.
4139
4140If the window to show BUFFER-OR-NAME is not on the selected
4141frame, raise that window's frame and give it input focus.
4142
4143This function returns the buffer it switched to. This uses the
4144function `display-buffer' as a subroutine; see the documentation
4145of `display-buffer' for additional customization information.
4146
4147Optional third arg NORECORD non-nil means do not put this buffer
4148at the front of the list of recently selected ones."
4149 (let ((buffer
4150 ;; FIXME: This behavior is carried over from the previous C version
4151 ;; of pop-to-buffer, but really we should use just
4152 ;; `get-buffer' here.
4153 (if (null buffer-or-name) (other-buffer (current-buffer))
4154 (or (get-buffer buffer-or-name)
4155 (let ((buf (get-buffer-create buffer-or-name)))
4156 (set-buffer-major-mode buf)
4157 buf))))
4158 (old-frame (selected-frame))
4159 new-window new-frame)
4160 (set-buffer buffer)
4161 (setq new-window (display-buffer buffer other-window))
4162 (select-window new-window norecord)
4163 (setq new-frame (window-frame new-window))
4164 (unless (eq new-frame old-frame)
4165 ;; `display-buffer' has chosen another frame, make sure it gets
4166 ;; input focus and is risen.
4167 (select-frame-set-input-focus new-frame))
4168 buffer))
4169
4170(defun read-buffer-to-switch (prompt)
4171 "Read the name of a buffer to switch to, prompting with PROMPT.
4172Return the neame of the buffer as a string.
4173
4174This function is intended for the `switch-to-buffer' family of
4175commands since these need to omit the name of the current buffer
4176from the list of completions and default values."
4177 (let ((rbts-completion-table (internal-complete-buffer-except)))
4178 (minibuffer-with-setup-hook
4179 (lambda ()
4180 (setq minibuffer-completion-table rbts-completion-table)
4181 ;; Since rbts-completion-table is built dynamically, we
4182 ;; can't just add it to the default value of
4183 ;; icomplete-with-completion-tables, so we add it
4184 ;; here manually.
4185 (if (and (boundp 'icomplete-with-completion-tables)
4186 (listp icomplete-with-completion-tables))
4187 (set (make-local-variable 'icomplete-with-completion-tables)
4188 (cons rbts-completion-table
4189 icomplete-with-completion-tables))))
4190 (read-buffer prompt (other-buffer (current-buffer))
4191 (confirm-nonexistent-file-or-buffer)))))
4192
4193(defun normalize-buffer-to-switch-to (buffer-or-name)
4194 "Normalize BUFFER-OR-NAME argument of buffer switching functions.
4195If BUFFER-OR-NAME is nil, return the buffer returned by
4196`other-buffer'. Else, if a buffer specified by BUFFER-OR-NAME
4197exists, return that buffer. If no such buffer exists, create a
4198buffer with the name BUFFER-OR-NAME and return that buffer."
4199 (if buffer-or-name
4200 (or (get-buffer buffer-or-name)
4201 (let ((buffer (get-buffer-create buffer-or-name)))
4202 (set-buffer-major-mode buffer)
4203 buffer))
4204 (other-buffer)))
4205
4206(defun switch-to-buffer (buffer-or-name &optional norecord)
4207 "Switch to buffer BUFFER-OR-NAME in the selected window.
4208If called interactively, prompt for the buffer name using the
4209minibuffer. The variable `confirm-nonexistent-file-or-buffer'
4210determines whether to request confirmation before creating a new
4211buffer.
4212
4213BUFFER-OR-NAME may be a buffer, a string \(a buffer name), or
4214nil. If BUFFER-OR-NAME is a string that does not identify an
4215existing buffer, create a buffer with that name. If
4216BUFFER-OR-NAME is nil, switch to the buffer returned by
4217`other-buffer'.
4218
4219Optional argument NORECORD non-nil means do not put the buffer
4220specified by BUFFER-OR-NAME at the front of the buffer list and
4221do not make the window displaying it the most recently selected
4222one. Return the buffer switched to.
4223
4224This function is intended for interactive use only. Lisp
4225functions should call `pop-to-buffer-same-window' instead."
4226 (interactive
4227 (list (read-buffer-to-switch "Switch to buffer: ")))
4228 (let ((buffer (normalize-buffer-to-switch-to buffer-or-name)))
4229 (if (and (or (window-minibuffer-p) (eq (window-dedicated-p) t))
4230 (not (eq buffer (window-buffer))))
4231 ;; Cannot switch to another buffer in a minibuffer or strongly
4232 ;; dedicated window that does not show the buffer already. Call
4233 ;; `pop-to-buffer' instead.
4234 (pop-to-buffer buffer nil norecord)
4235 (unless (eq buffer (window-buffer))
4236 ;; I'm not sure why we should NOT call `set-window-buffer' here,
4237 ;; but let's keep things as they are (otherwise we could always
4238 ;; call `pop-to-buffer-same-window' here).
4239 (set-window-buffer nil buffer))
4240 (unless norecord
4241 (select-window (selected-window)))
4242 (set-buffer buffer))))
4243
4244(defun switch-to-buffer-other-window (buffer-or-name &optional norecord)
4245 "Select the buffer specified by BUFFER-OR-NAME in another window.
4246BUFFER-OR-NAME may be a buffer, a string \(a buffer name), or
4247nil. Return the buffer switched to.
4248
4249If called interactively, prompt for the buffer name using the
4250minibuffer. The variable `confirm-nonexistent-file-or-buffer'
4251determines whether to request confirmation before creating a new
4252buffer.
4253
4254If BUFFER-OR-NAME is a string and does not identify an existing
4255buffer, create a new buffer with that name. If BUFFER-OR-NAME is
4256nil, switch to the buffer returned by `other-buffer'.
4257
4258Optional second argument NORECORD non-nil means do not put this
4259buffer at the front of the list of recently selected ones.
4260
4261This uses the function `display-buffer' as a subroutine; see its
4262documentation for additional customization information."
4263 (interactive
4264 (list (read-buffer-to-switch "Switch to buffer in other window: ")))
4265 (let ((pop-up-windows t)
4266 same-window-buffer-names same-window-regexps)
4267 (pop-to-buffer buffer-or-name t norecord)))
4268
4269(defun switch-to-buffer-other-frame (buffer-or-name &optional norecord)
4270 "Switch to buffer BUFFER-OR-NAME in another frame.
4271BUFFER-OR-NAME may be a buffer, a string \(a buffer name), or
4272nil. Return the buffer switched to.
4273
4274If called interactively, prompt for the buffer name using the
4275minibuffer. The variable `confirm-nonexistent-file-or-buffer'
4276determines whether to request confirmation before creating a new
4277buffer.
4278
4279If BUFFER-OR-NAME is a string and does not identify an existing
4280buffer, create a new buffer with that name. If BUFFER-OR-NAME is
4281nil, switch to the buffer returned by `other-buffer'.
4282
4283Optional second arg NORECORD non-nil means do not put this
4284buffer at the front of the list of recently selected ones.
4285
4286This uses the function `display-buffer' as a subroutine; see its
4287documentation for additional customization information."
4288 (interactive
4289 (list (read-buffer-to-switch "Switch to buffer in other frame: ")))
4290 (let ((pop-up-frames t)
4291 same-window-buffer-names same-window-regexps)
4292 (pop-to-buffer buffer-or-name t norecord)))
4293 6361
4294(defun set-window-text-height (window height) 6362(defun set-window-text-height (window height)
4295 "Set the height in lines of the text display area of WINDOW to HEIGHT. 6363 "Set the height in lines of the text display area of WINDOW to HEIGHT.