]> code.delx.au - gnu-emacs/blobdiff - lisp/window.el
Merge from trunk.
[gnu-emacs] / lisp / window.el
index 999e408bdb112a800ae58404a84b66f85151f949..7e666af6abf490912705e56f0b58b277f9c2059c 100644 (file)
@@ -3272,7 +3272,7 @@ window."
 (defun split-window-side-by-side (&optional size)
   "Split selected window into two windows side by side.
 The selected window becomes the left one and gets SIZE columns.
-SIZE negative means the right window gets -SIZE lines.
+SIZE negative means the right window gets -SIZE columns.
 
 SIZE includes the width of the window's scroll bar; if there are
 no scroll bars, it includes the width of the divider column to
@@ -4715,15 +4715,12 @@ documentation of `display-buffer-alist' for a description."
   (setq window (window-normalize-live-window window))
   (let* ((old-frame (selected-frame))
         (new-frame (window-frame window))
-        (dedicate (cdr (assq 'dedicate specifiers)))
         (no-other-window (cdr (assq 'no-other-window specifiers))))
     ;; Show BUFFER in WINDOW.
     (unless (eq buffer (window-buffer window))
       ;; If we show another buffer in WINDOW, undedicate it first.
       (set-window-dedicated-p window nil))
     (set-window-buffer window buffer)
-    (when dedicate
-      (set-window-dedicated-p window dedicate))
     (when no-other-window
       (set-window-parameter window 'no-other-window t))
     (unless (or (eq old-frame new-frame)
@@ -4965,7 +4962,7 @@ Return the new window, nil if it could not be created."
        (selected-window (selected-window))
        root new new-parent)
 
-      ;; We are in an atomic window.
+    ;; We are in an atomic window.
     (when (and (window-parameter window 'window-atom) (not nest))
       ;; Split the root window.
       (setq window (window-atom-root window)))
@@ -5051,14 +5048,26 @@ description."
                      (funcall side window)))))
 
            (when (window-live-p window)
-             ;; Adjust sizes if asked for.
-             (display-buffer-set-height window specifiers)
-             (display-buffer-set-width window specifiers)
+             ;; In `quit-restore' parameter record that we popped up
+             ;; this window, its buffer and which window was selected.
              (set-window-parameter
               window 'quit-restore (list 'new-window buffer selected-window))
+             ;; For `display-buffer-window' mark window as new.
              (setq display-buffer-window (cons window 'new-window))
+             ;; Install BUFFER in the new window.
              (display-buffer-in-window buffer window specifiers)
+             (let ((dedicate (cdr (assq 'dedicate specifiers))))
+               (when dedicate
+                 ;; Dedicate window to buffer.
+                 (set-window-dedicated-p window dedicate)))
+             ;; Adjust sizes if asked for (for `fit-window-to-buffer'
+             ;; and friends BUFFER must be already shown in the new
+             ;; window).
+             (display-buffer-set-height window specifiers)
+             (display-buffer-set-width window specifiers)
+             ;; Reset list of window's previous buffers to nil.
              (set-window-prev-buffers window nil)
+             ;; Return the new window.
              (throw 'done window))))))))
 
 (defun display-buffer-pop-up-frame (buffer &optional graphic-only specifiers)
@@ -5086,7 +5095,12 @@ documentation of `display-buffer-alist' for a description."
          (set-window-parameter
           window 'quit-restore (list 'new-frame buffer selected-window))
          (setq display-buffer-window (cons window 'new-frame))
-         (display-buffer-in-window buffer window specifiers))))))
+         (display-buffer-in-window buffer window specifiers)
+         (let ((dedicate (cdr (assq 'dedicate specifiers))))
+           (when dedicate
+             ;; Dedicate window to buffer.
+             (set-window-dedicated-p window dedicate)))
+         window)))))
 
 (defun display-buffer-pop-up-side-window (buffer side slot &optional specifiers)
   "Display BUFFER in a new window on SIDE of the selected frame.
@@ -5113,26 +5127,37 @@ failed."
          (display-buffer-split-window main-or-root on-side specifiers))
         fun)
     (when window
+      ;; We were able to split off a new window.
       (unless main
        (walk-window-subtree
         (lambda (window)
           ;; Make all main-or-root subwindows main windows.
           (set-window-parameter window 'window-side 'none))
         main-or-root t))
-      ;; Make sure that parent's window-side is nil.
+      ;; Reset window-side parameter of new window's parent to nil.
       (set-window-parameter (window-parent window) 'window-side nil)
-      ;; Initialize side.
+      ;; Initialize window-side parameter of new window to SIDE.
       (set-window-parameter window 'window-side side)
-      ;; Adjust sizes if asked for.
-      (display-buffer-set-height window specifiers)
-      (display-buffer-set-width window specifiers)
-      ;; Set window parameters.
+      ;; Install window-slot parameter of new window.
+      (set-window-parameter window 'window-slot slot)
+      ;; In `quit-restore' parameter record that we popped up a new
+      ;; window.
       (set-window-parameter
        window 'quit-restore (list 'new-window buffer selected-window))
+      ;; For `display-buffer-window' mark window as new.
       (setq display-buffer-window (cons window 'new-window))
-      (set-window-parameter window 'window-slot slot)
+      ;; Install BUFFER in new window.
       (display-buffer-in-window buffer window specifiers)
+      (let ((dedicate (cdr (assq 'dedicate specifiers))))
+       (when dedicate
+         ;; Dedicate window to buffer.
+         (set-window-dedicated-p window dedicate)))
+      ;; Adjust sizes of new window if asked for.
+      (display-buffer-set-height window specifiers)
+      (display-buffer-set-width window specifiers)
+      ;; Reset list of new window's previous buffers to nil.
       (set-window-prev-buffers window nil)
+      ;; Return the new window.
       window)))
 
 (defun display-buffer-in-side-window (buffer side &optional slot specifiers)
@@ -5160,7 +5185,7 @@ SPECIFIERS must be a list of buffer display specifiers."
                window-sides-slots))
         (selected-window (selected-window))
         window this-window this-slot prev-window next-window
-        best-window best-slot abs-slot dedicated)
+        best-window best-slot abs-slot dedicated new-window)
 
     (unless (numberp slot)
       (setq slot 0))
@@ -5233,13 +5258,16 @@ SPECIFIERS must be a list of buffer display specifiers."
                          (setq window (display-buffer-split-window
                                        prev-window prev-side specifiers)))))
               (progn
-                (display-buffer-set-height window specifiers)
-                (display-buffer-set-width window specifiers)
+                ;; In `quit-restore' parameter record that we popped up
+                ;; this window, its buffer and the old selected window.
                 (set-window-parameter
                  window 'quit-restore
                  (list 'new-window buffer selected-window))
+                ;; For `display-buffer-window' mark window as new.
                 (setq display-buffer-window (cons window 'new-window))
-                window))
+                ;; Record that window is new, we need this for
+                ;; adjusting sizes below.
+                (setq new-window window)))
          (and best-window
               (setq window best-window)
               ;; Reuse best window (the window nearest to SLOT).
@@ -5262,7 +5290,21 @@ SPECIFIERS must be a list of buffer display specifiers."
        (unless (window-parameter window 'window-slot)
          ;; Don't change exisiting slot value.
          (set-window-parameter window 'window-slot slot))
-       (display-buffer-in-window buffer window specifiers)))))
+       ;; Install BUFFER in the window.
+       (display-buffer-in-window buffer window specifiers)
+       (let ((dedicate (cdr (assq 'dedicate specifiers))))
+         (when dedicate
+           ;; Dedicate window to buffer.
+           (set-window-dedicated-p window dedicate)))
+       (when new-window
+         ;; Adjust sizes if asked for (for `fit-window-to-buffer' and
+         ;; friends BUFFER must be already shown in the new window).
+         (display-buffer-set-height window specifiers)
+         (display-buffer-set-width window specifiers)
+         ;; Reset list of new window's previous buffers to nil.
+         (set-window-prev-buffers window nil))
+       ;; Return the window used.
+       window))))
 
 (defun window-normalize-buffer-to-display (buffer-or-name)
   "Normalize BUFFER-OR-NAME argument for buffer display functions.
@@ -5317,12 +5359,12 @@ user preferences expressed in `display-buffer-alist'."
        (unless display-buffer-mark-dedicated
         ;; Don't make anything created above dedicated unless requested.
         ;; Otherwise the dedication request below gets in our way.
-        '((dedicated . nil)))
+        '((dedicate . nil)))
        `((pop-up-frame t)
         ,(append '(pop-up-frame-alist)
                  (when (listp args) args)
                  special-display-frame-alist)
-        (dedicated . t))))))
+        (dedicate . t))))))
 
 (defun display-buffer-normalize-default (buffer-or-name)
   "Subroutine of `display-buffer-normalize-specifiers'.
@@ -5754,7 +5796,7 @@ this list as arguments."
          ;; regardless of graphic-only restrictions.
          (display-buffer-pop-up-frame buffer)))))
 
-(defsubst display-buffer-same-window (&optional buffer-or-name label)
+(defun display-buffer-same-window (&optional buffer-or-name label)
   "Display buffer specified by BUFFER-OR-NAME in the selected window.
 Another window will be used only if the buffer can't be shown in
 the selected window, usually because it is dedicated to another
@@ -5763,7 +5805,7 @@ buffer.  Optional argument BUFFER-OR-NAME and LABEL are as for
   (interactive "BDisplay buffer in same window:\nP")
   (display-buffer buffer-or-name 'same-window label))
 
-(defsubst display-buffer-same-frame (&optional buffer-or-name label)
+(defun display-buffer-same-frame (&optional buffer-or-name label)
   "Display buffer specified by BUFFER-OR-NAME in a window on the same frame.
 Another frame will be used only if there is no other choice.
 Optional argument BUFFER-OR-NAME and LABEL are as for
@@ -5771,7 +5813,7 @@ Optional argument BUFFER-OR-NAME and LABEL are as for
   (interactive "BDisplay buffer on same frame:\nP")
   (display-buffer buffer-or-name 'same-frame label))
 
-(defsubst display-buffer-other-window (&optional buffer-or-name label)
+(defun display-buffer-other-window (&optional buffer-or-name label)
   "Display buffer specified by BUFFER-OR-NAME in another window.
 The selected window will be used only if there is no other
 choice.  Windows on the selected frame are preferred to windows
@@ -5836,18 +5878,16 @@ additional information."
        new-window new-frame)
     (set-buffer buffer)
     (setq new-window (display-buffer buffer specifiers label))
-    (unless (eq new-window old-window)
-      ;; `display-buffer' has chosen another window, select it.
-      (select-window new-window norecord)
-      (setq new-frame (window-frame new-window))
-      (unless (eq new-frame old-frame)
-       ;; `display-buffer' has chosen another frame, make sure it gets
-       ;; input focus and is risen.
-       (select-frame-set-input-focus new-frame)))
-
+    (setq new-frame (window-frame new-window))
+    (if (eq old-frame new-frame)
+       ;; Make sure new-window gets selected (Bug#8615), (Bug#6954).
+       (select-window new-window norecord)
+      ;; `display-buffer' has chosen another frame, make sure it gets
+      ;; input focus and is risen.
+      (select-frame-set-input-focus new-frame norecord))
     buffer))
 
-(defsubst pop-to-buffer-same-window (&optional buffer-or-name norecord label)
+(defun pop-to-buffer-same-window (&optional buffer-or-name norecord label)
   "Pop to buffer specified by BUFFER-OR-NAME in the selected window.
 Another window will be used only if the buffer can't be shown in
 the selected window, usually because it is dedicated to another
@@ -5856,7 +5896,7 @@ as for `pop-to-buffer'."
   (interactive "BPop to buffer in selected window:\nP")
   (pop-to-buffer buffer-or-name 'same-window norecord label))
 
-(defsubst pop-to-buffer-same-frame (&optional buffer-or-name norecord label)
+(defun pop-to-buffer-same-frame (&optional buffer-or-name norecord label)
   "Pop to buffer specified by BUFFER-OR-NAME in a window on the selected frame.
 Another frame will be used only if there is no other choice.
 Optional arguments BUFFER-OR-NAME, NORECORD and LABEL are as for
@@ -5864,7 +5904,7 @@ Optional arguments BUFFER-OR-NAME, NORECORD and LABEL are as for
   (interactive "BPop to buffer on same frame:\nP")
   (pop-to-buffer buffer-or-name 'same-frame norecord label))
 
-(defsubst pop-to-buffer-other-window (&optional buffer-or-name norecord label)
+(defun pop-to-buffer-other-window (&optional buffer-or-name norecord label)
   "Pop to buffer specified by BUFFER-OR-NAME in another window.
 The selected window will be used only if there is no other
 choice.  Windows on the selected frame are preferred to windows
@@ -5873,7 +5913,7 @@ LABEL are as for `pop-to-buffer'."
   (interactive "BPop to buffer in another window:\nP")
   (pop-to-buffer buffer-or-name 'other-window norecord))
 
-(defsubst pop-to-buffer-same-frame-other-window (&optional buffer-or-name norecord label)
+(defun pop-to-buffer-same-frame-other-window (&optional buffer-or-name norecord label)
   "Pop to buffer specified by BUFFER-OR-NAME in another window on the selected frame.
 The selected window or another frame will be used only if there
 is no other choice.  Optional arguments BUFFER-OR-NAME, NORECORD
@@ -5881,7 +5921,7 @@ and LABEL are as for `pop-to-buffer'."
   (interactive "BPop to buffer in another window on same frame:\nP")
   (pop-to-buffer buffer-or-name 'same-frame-other-window norecord label))
 
-(defsubst pop-to-buffer-other-frame (&optional buffer-or-name norecord label)
+(defun pop-to-buffer-other-frame (&optional buffer-or-name norecord label)
   "Pop to buffer specified by BUFFER-OR-NAME on another frame.
 The selected frame will be used only if there's no other choice.
 Optional arguments BUFFER-OR-NAME, NORECORD and LABEL are as for
@@ -5925,7 +5965,7 @@ buffer with the name BUFFER-OR-NAME and return that buffer."
            buffer))
     (other-buffer)))
 
-(defun switch-to-buffer (buffer-or-name &optional norecord)
+(defun switch-to-buffer (buffer-or-name &optional norecord force-same-window)
   "Switch to buffer BUFFER-OR-NAME in the selected window.
 If called interactively, prompt for the buffer name using the
 minibuffer.  The variable `confirm-nonexistent-file-or-buffer'
@@ -5941,25 +5981,33 @@ BUFFER-OR-NAME is nil, switch to the buffer returned by
 Optional argument NORECORD non-nil means do not put the buffer
 specified by BUFFER-OR-NAME at the front of the buffer list and
 do not make the window displaying it the most recently selected
-one.  Return the buffer switched to.
+one.
 
-This function is intended for interactive use only.  Lisp
-functions should call `pop-to-buffer-same-window' instead."
+If FORCE-SAME-WINDOW is non-nil, BUFFER-OR-NAME must be displayed
+in the currently selected window; signal an error if that is
+impossible (e.g. if the selected window is minibuffer-only).
+If non-nil, BUFFER-OR-NAME may be displayed in another window.
+
+Return the buffer switched to."
   (interactive
-   (list (read-buffer-to-switch "Switch to buffer: ")))
+   (list (read-buffer-to-switch "Switch to buffer: ") nil nil))
   (let ((buffer (window-normalize-buffer-to-switch-to buffer-or-name)))
-    (cond
-     ;; Don't call set-window-buffer if it's not needed since it
-     ;; might signal an error (e.g. if the window is dedicated).
-     ((eq buffer (window-buffer)) nil)
-     ((window-minibuffer-p)
-      (error "Cannot switch buffers in minibuffer window"))
-     ((eq (window-dedicated-p) t)
-      (error "Cannot switch buffers in a dedicated window"))
-     (t (set-window-buffer nil buffer)))
-    (unless norecord
-      (select-window (selected-window)))
-    (set-buffer buffer)))
+    (if (null force-same-window)
+       (pop-to-buffer
+        buffer '(same-window (reuse-window-dedicated . weak)) norecord)
+      (cond
+       ;; Don't call set-window-buffer if it's not needed since it
+       ;; might signal an error (e.g. if the window is dedicated).
+       ((eq buffer (window-buffer)))
+       ((window-minibuffer-p)
+       (error "Cannot switch buffers in minibuffer window"))
+       ((eq (window-dedicated-p) t)
+       (error "Cannot switch buffers in a dedicated window"))
+       (t (set-window-buffer nil buffer)))
+
+      (unless norecord
+       (select-window (selected-window)))
+      (set-buffer buffer))))
 
 (defun switch-to-buffer-same-frame (buffer-or-name &optional norecord)
   "Switch to buffer BUFFER-OR-NAME in a window on the selected frame.
@@ -6582,6 +6630,15 @@ split."
 
 ;; Functions for converting Emacs 23 buffer display options to buffer
 ;; display specifiers.
+(defun display-buffer-alist-of-strings-p (list)
+  "Return t if LIST is a non-empty list of strings."
+  (when list
+    (catch 'failed
+      (dolist (item list)
+       (unless (stringp item)
+         (throw 'failed nil)))
+      t)))
+
 (defun display-buffer-alist-add (identifiers specifiers &optional no-custom)
   "Helper function for `display-buffer-alist-set'."
   (unless identifiers
@@ -6596,6 +6653,40 @@ split."
      'display-buffer-alist
      (cons (cons identifiers specifiers) display-buffer-alist))))
 
+(defun display-buffer-alist-set-1 ()
+  "Helper function for `display-buffer-alist-set'."
+  (progn ;; with-no-warnings
+    (append
+     '(reuse-window (reuse-window nil same 0))
+     `(pop-up-frame (pop-up-frame t)
+                   ,(append '(pop-up-frame-alist)
+                            special-display-frame-alist))
+     '((dedicate . weak)))))
+
+(defun display-buffer-alist-set-2 (args)
+  "Helper function for `display-buffer-alist-set'."
+  (progn ;; with-no-warnings
+    (if (and (listp args) (symbolp (car args)))
+       `(function (function ,(car args) ,(cdr args)))
+      (append
+       '(reuse-window (reuse-window nil same 0))
+       (when (and (listp args) (cdr (assq 'same-window args)))
+        '(reuse-window
+          (reuse-window same nil nil) (reuse-window-dedicated . weak)))
+       (when (and (listp args)
+                 (or (cdr (assq 'same-frame args))
+                     (cdr (assq 'same-window args))))
+        '(pop-up-window (pop-up-window (largest . nil) (lru . nil))))
+       (when (and (listp args)
+                 (or (cdr (assq 'same-frame args))
+                     (cdr (assq 'same-window args))))
+        '(reuse-window (reuse-window nil nil nil)))
+       `(pop-up-frame (pop-up-frame t)
+                     ,(append '(pop-up-frame-alist)
+                              (when (listp args) args)
+                              special-display-frame-alist))
+       '((dedicate . weak))))))
+
 (defun display-buffer-alist-set (&optional no-custom add)
   "Set `display-buffer-alist' from Emacs 23 buffer display options.
 Optional argument NO-CUSTOM nil means use `customize-set-variable'
@@ -6605,201 +6696,164 @@ means to use `setq' instead.
 Optional argument ADD nil means to replace the actual value of
 `display-buffer-alist' with the value calculated here.  ADD
 non-nil means prepend the value calculated here to the current
-value of `display-buffer-alist'."
+value of `display-buffer-alist'.  Return `display-buffer-alist'."
   (unless add
     (if no-custom
        (setq display-buffer-alist nil)
       (customize-set-variable 'display-buffer-alist nil)))
 
   ;; Disable warnings, there are too many obsolete options here.
-  (with-no-warnings
-    ;; `pop-up-windows'
-    (display-buffer-alist-add
-     nil
-     (let ((fun (unless (eq split-window-preferred-function
-                           'split-window-sensibly)
-                 ;; `split-window-sensibly' has been merged into the
-                 ;; `display-buffer-split-window' code as `nil'.
-                 split-window-preferred-function))
-          (min-height
-           (if (numberp split-height-threshold)
-               (/ split-height-threshold 2)
-             ;; Undocumented hack.
-             1.0))
-          (min-width
-           (if (numberp split-width-threshold)
-               (/ split-width-threshold 2)
-             ;; Undocumented hack.
-             1.0)))
-       (list
-       'pop-up-window
-       (when pop-up-windows
-         (list
-          'pop-up-window
-          (cons 'largest fun)
-          (cons 'lru fun)))
-       (cons 'pop-up-window-min-height min-height)
-       (cons 'pop-up-window-min-width min-width)))
-     no-custom)
+  (progn ;; with-no-warnings
+    `other-window-means-other-frame'
+    (when pop-up-frames
+      (display-buffer-alist-add
+       nil '(pop-up-frame
+            (other-window-means-other-frame . t)) no-custom))
 
-    ;; `pop-up-frames'
-    (display-buffer-alist-add
-     nil
-     (list
-      'pop-up-frame
-      (when pop-up-frames
-       (list 'pop-up-frame pop-up-frames))
-      (when pop-up-frame-function
-       (cons 'pop-up-frame-function pop-up-frame-function))
-      (when pop-up-frame-alist
-       (cons 'pop-up-frame-alist pop-up-frame-alist)))
-     no-custom)
+    ;; `reuse-window-even-sizes'
+    (when even-window-heights
+      (display-buffer-alist-add
+       nil '(reuse-window (reuse-window-even-sizes . t)) no-custom))
+
+    ;; `dedicate'
+    (when display-buffer-mark-dedicated
+      (display-buffer-alist-add
+       nil '(dedicate (display-buffer-mark-dedicated . t)) no-custom))
+
+    ;; `pop-up-window' group
+    (let ((fun (unless (eq split-window-preferred-function
+                          'split-window-sensibly)
+                split-window-preferred-function))
+         (min-height
+          (if (numberp split-height-threshold)
+              (/ split-height-threshold 2)
+            1.0))
+         (min-width
+          (if (numberp split-width-threshold)
+              (/ split-width-threshold 2)
+            1.0)))
+      (display-buffer-alist-add
+       nil
+       (list
+       'pop-up-window
+       ;; `pop-up-window'
+       (when pop-up-windows
+         (list 'pop-up-window (cons 'largest fun) (cons 'lru fun)))
+       ;; `pop-up-window-min-height'
+       (cons 'pop-up-window-min-height min-height)
+       ;; `pop-up-window-min-width'
+       (cons 'pop-up-window-min-width min-width))
+       no-custom))
+
+    ;; `pop-up-frame' group
+    (when (or pop-up-frames
+             (not (equal pop-up-frame-function
+                         '(lambda nil
+                            (make-frame pop-up-frame-alist))))
+             pop-up-frame-alist)
+      (display-buffer-alist-add
+       nil
+       (list
+       'pop-up-frame
+       (when pop-up-frames
+         ;; `pop-up-frame'
+         (list 'pop-up-frame
+               (when (eq pop-up-frames 'graphic-only)
+                 t)))
+       (unless (equal pop-up-frame-function
+                      '(lambda nil
+                         (make-frame pop-up-frame-alist)))
+         ;; `pop-up-frame-function'
+         (cons 'pop-up-frame-function pop-up-frame-function))
+       (when pop-up-frame-alist
+         ;; `pop-up-frame-alist'
+         (cons 'pop-up-frame-alist pop-up-frame-alist)))
+       no-custom))
 
     ;; `special-display-regexps'
-    (dolist (entry special-display-regexps)
-      (cond
-       ((stringp entry)
-       ;; Plain string.
-       (display-buffer-alist-add
-        `((regexp . ,entry))
-        (list
-         'function
-         (list 'function special-display-function
-               special-display-frame-alist))
-        no-custom))
-       ((consp entry)
-       (let ((name (car entry))
-             (rest (cdr entry)))
-         (cond
-          ((functionp (car rest))
-           ;; A function.
-           (display-buffer-alist-add
-            `((name . ,name))
-            (list
-             'function
-             ;; Weary.
-             (list 'function (car rest) (cadr rest)))
-            no-custom))
-          ((listp rest)
-           ;; A list of parameters.
-           (cond
-            ((assq 'same-window rest)
-             (display-buffer-alist-add
-              `((name . ,name))
-              (list 'reuse-window
-                    (list 'reuse-window 'same)
-                    (list 'reuse-window-dedicated 'weak))
-              no-custom))
-            ((assq 'same-frame rest)
-             (display-buffer-alist-add
-              `((name . ,name)) (list 'same-frame) no-custom))
-            (t
-             (display-buffer-alist-add
-              `((name . ,name))
-              (list
-               'function
-               (list 'function special-display-function
-                     special-display-frame-alist))
-              no-custom)))))))))
+    (if (display-buffer-alist-of-strings-p special-display-regexps)
+       ;; Handle case where `special-display-regexps' is a plain list
+       ;; of strings specially.
+       (let (list)
+         (dolist (regexp special-display-regexps)
+           (setq list (cons (cons 'regexp regexp) list)))
+         (setq list (nreverse list))
+         (display-buffer-alist-add
+          list (display-buffer-alist-set-1) no-custom))
+      ;; Else iterate over the entries.
+      (dolist (item special-display-regexps)
+       (if (stringp item)
+           (display-buffer-alist-add
+            `((regexp . ,item)) (display-buffer-alist-set-1)
+            no-custom)
+         (display-buffer-alist-add
+          `((regexp . ,(car item)))
+          (display-buffer-alist-set-2 (cdr item))
+          no-custom))))
 
     ;; `special-display-buffer-names'
-    (dolist (entry special-display-buffer-names)
-      (cond
-       ((stringp entry)
-       ;; Plain string.
-       (display-buffer-alist-add
-        `((name . ,entry))
-        (list
-         'function
-         (list 'function special-display-function
-               special-display-frame-alist))
-        no-custom))
-       ((consp entry)
-       (let ((name (car entry))
-             (rest (cdr entry)))
-         (cond
-          ((functionp (car rest))
-           ;; A function.
-           (display-buffer-alist-add
-            `((name . ,name))
-            (list
-             'function
-             ;; Weary.
-             (list 'function (car rest) (cadr rest)))
-            no-custom))
-          ((listp rest)
-           ;; A list of parameters.
-           (cond
-            ((assq 'same-window rest)
-             (display-buffer-alist-add
-              `((name . ,name))
-              (list 'reuse-window
-                    (list 'reuse-window 'same)
-                    (list 'reuse-window-dedicated 'weak))
-              no-custom))
-            ((assq 'same-frame rest)
-             (display-buffer-alist-add
-              `((name . ,name)) (list 'same-frame) no-custom))
-            (t
-             (display-buffer-alist-add
-              `((name . ,name))
-              (list
-               'function
-               (list 'function special-display-function
-                     special-display-frame-alist))
-              no-custom)))))))))
+    (if (display-buffer-alist-of-strings-p special-display-buffer-names)
+       ;; Handle case where `special-display-buffer-names' is a plain
+       ;; list of strings specially.
+       (let (list)
+         (dolist (name special-display-buffer-names)
+           (setq list (cons (cons 'name name) list)))
+         (setq list (nreverse list))
+         (display-buffer-alist-add
+          list (display-buffer-alist-set-1) no-custom))
+      ;; Else iterate over the entries.
+      (dolist (item special-display-buffer-names)
+       (if (stringp item)
+           (display-buffer-alist-add
+            `((name . ,item)) (display-buffer-alist-set-1)
+            no-custom)
+         (display-buffer-alist-add
+          `((name . ,(car item)))
+          (display-buffer-alist-set-2 (cdr item))
+          no-custom))))
 
     ;; `same-window-regexps'
-    (dolist (entry same-window-regexps)
-      (cond
-       ((stringp entry)
+    (if (display-buffer-alist-of-strings-p same-window-regexps)
+       ;; Handle case where `same-window-regexps' is a plain list of
+       ;; strings specially.
+       (let (list)
+         (dolist (regexp same-window-regexps)
+           (setq list (cons (cons 'regexp regexp) list)))
+         (setq list (nreverse list))
+         (display-buffer-alist-add
+          list '(reuse-window (reuse-window same nil nil)) no-custom))
+      (dolist (entry same-window-regexps)
        (display-buffer-alist-add
-        `((regexp . ,entry))
-        (list 'reuse-window (list 'reuse-window 'same))
-        no-custom))
-       ((consp entry)
-       (display-buffer-alist-add
-        `((regexp . ,(car entry)))
-        (list 'reuse-window (list 'reuse-window 'same))
-        no-custom))))
+        `((regexp . ,(if (stringp entry) entry (car entry))))
+        '(reuse-window (reuse-window same nil nil)) no-custom)))
 
     ;; `same-window-buffer-names'
-    (dolist (entry same-window-buffer-names)
-      (cond
-       ((stringp entry)
+    (if (display-buffer-alist-of-strings-p same-window-buffer-names)
+       ;; Handle case where `same-window-buffer-names' is a plain list
+       ;; of strings specially.
+       (let (list)
+         (dolist (name same-window-buffer-names)
+           (setq list (cons (cons 'name name) list)))
+         (setq list (nreverse list))
+         (display-buffer-alist-add
+          list '(reuse-window (reuse-window same nil nil)) no-custom))
+      (dolist (entry same-window-buffer-names)
        (display-buffer-alist-add
-        `((name . ,entry))
-        (list 'reuse-window (list 'reuse-window 'same))
-        no-custom))
-       ((consp entry)
-       (display-buffer-alist-add
-        `((name . ,(car entry)))
-        (list 'reuse-window (list 'reuse-window 'same))
-        no-custom))))
+        `((name . ,(if (stringp entry) entry (car entry))))
+        '(reuse-window (reuse-window same nil nil)) no-custom)))
 
     ;; `reuse-window'
     (display-buffer-alist-add
-     nil
-     (list
-      'reuse-window
-      (list 'reuse-window nil 'same
-           (when (or display-buffer-reuse-frames pop-up-frames)
-             ;; "0" (all visible and iconified frames) is hardcoded in
-             ;; Emacs 23.
-             0))
-      (when even-window-heights
-       (cons 'reuse-window-even-sizes t)))
+     nil `(reuse-window
+          (reuse-window
+           nil same
+           ,(when (or display-buffer-reuse-frames pop-up-frames)
+              ;; "0" (all visible and iconified frames) is
+              ;; hardcoded in Emacs 23.
+              0)))
      no-custom)
 
-    ;; `display-buffer-mark-dedicated'
-    (when display-buffer-mark-dedicated
-      (display-buffer-alist-add
-       nil
-       (list
-       (cons 'dedicate display-buffer-mark-dedicated))
-       no-custom)))
-
-  display-buffer-alist)
+    display-buffer-alist))
 \f
 (defun set-window-text-height (window height)
   "Set the height in lines of the text display area of WINDOW to HEIGHT.
@@ -6914,7 +6968,7 @@ WINDOW was scrolled."
     ;; `with-selected-window' should orderly restore the current buffer.
     (with-selected-window window
       ;; We are in WINDOW's buffer now.
-      (let* ( ;; Adjust MIN-HEIGHT.
+      (let* (;; Adjust MIN-HEIGHT.
             (min-height
              (if override
                  (window-min-size window nil window)