emacs-diffs
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Emacs-diffs] /srv/bzr/emacs/trunk r104559: Move/add window-buffer-relat


From: martin rudalics
Subject: [Emacs-diffs] /srv/bzr/emacs/trunk r104559: Move/add window-buffer-related functions to window.el.
Date: Sat, 11 Jun 2011 11:50:37 +0200
User-agent: Bazaar (2.3.1)

------------------------------------------------------------
revno: 104559
committer: martin rudalics <address@hidden>
branch nick: trunk
timestamp: Sat 2011-06-11 11:50:37 +0200
message:
  Move/add window-buffer-related functions to window.el.
  
  * buffer.c: New Lisp objects Qbuffer_list_update_hook and
  Qclone_number.  Remove external declaration of Qdelete_window.
  (Fbuffer_list): Rewrite doc-string.  Minor restructuring of
  code.
  (Fget_buffer_create, Fmake_indirect_buffer, Frename_buffer): Run
  Qbuffer_list_update_hook if allowed.
  (Fother_buffer): Rewrite doc-string.  Major rewrite for new
  buffer list implementation.
  (other_buffer_safely): New function.
  (Fkill_buffer): Replace call to replace_buffer_in_all_windows by
  calls to replace_buffer_in_windows and
  replace_buffer_in_windows_safely.  Run Qbuffer_list_update_hook
  if allowed.
  (record_buffer): Inhibit quitting and rewrite using quittable
  functions.  Run Qbuffer_list_update_hook if allowed.
  (Frecord_buffer, Funrecord_buffer): New functions.
  (switch_to_buffer_1, Fswitch_to_buffer): Remove.  Move
  switch-to-buffer to window.el.
  (bury-buffer): Move to window.el.
  (Vbuffer_list_update_hook): New variable.
  
  * lisp.h (other_buffer_safely): Add prototype in buffer.c
  section.
  
  * window.h (resize_frame_windows): Move up in code.
  (Fwindow_frame): Remove EXFUN.
  (replace_buffer_in_all_windows): Remove prototype.
  (replace_buffer_in_windows_safely): Add prototype.
  
  * window.c: Declare Qdelete_window static again.  Move down
  declaration of select_count.
  (Fnext_window, Fprevious_window): Rewrite doc-strings.
  (Fother_window): Move to window.el.
  (window_loop): Remove DELETE_BUFFER_WINDOWS and UNSHOW_BUFFER
  cases.  Add REPLACE_BUFFER_IN_WINDOWS_SAFELY case.
  (Fdelete_windows_on, Freplace_buffer_in_windows): Move to
  window.el.
  (replace_buffer_in_windows): Implement by calling
  Qreplace_buffer_in_windows.
  (replace_buffer_in_all_windows): Remove with some functionality
  moved into replace_buffer_in_windows_safely.
  (replace_buffer_in_windows_safely): New function.
  (select_window_norecord, select_frame_norecord): Move in front
  of run_window_configuration_change_hook.  Remove now obsolete
  declarations.
  (Fset_window_buffer): Rewrite doc-string.  Call
  Qrecord_window_buffer.
  (keys_of_window): Move binding for other-window to window.el.
  
  * loadup.el (top-level): Load window before files for the sake
  of replace-buffer-in-windows.
  
  * files.el (read-buffer-to-switch)
  (switch-to-buffer-other-window)
  (switch-to-buffer-other-frame, display-buffer-other-frame): Move
  to window.el.
  
  * simple.el (get-next-valid-buffer, last-buffer, next-buffer)
  (previous-buffer): Move to window.el.
  
  * bindings.el (unbury-buffer): Move to window.el.
  
  * window.el (delete-other-windows-vertically): Move after
  definition of delete-other-windows.
  (other-window, delete-windows-on, replace-buffer-in-windows):
  Move here from window.c.
  (record-window-buffer, unrecord-window-buffer)
  (set-window-buffer-start-and-point, switch-to-prev-buffer)
  (switch-to-next-buffer): New functions.
  (get-next-valid-buffer, last-buffer, next-buffer): Move here
  from simple.el.  Call switch-to-next-buffer.
  (previous-buffer): Move here from simple.el.  Call
  switch-to-prev-buffer.
  (bury-buffer): Move here from buffer.c.  Switch to previous
  buffer when window cannot be deleted.
  (unbury-buffer): Move here from bindings.el.
  (ctl-x-map): Move binding for other-window from window.c to
  here.
  (read-buffer-to-switch, switch-to-buffer-other-window)
  (switch-to-buffer-other-frame): Move here from files.el.
  (normalize-buffer-to-switch-to): New functions.
  (switch-to-buffer): Move here from buffer.c.  Use
  read-buffer-to-switch and normalize-buffer-to-switch-to.
modified:
  lisp/ChangeLog
  lisp/bindings.el
  lisp/files.el
  lisp/loadup.el
  lisp/simple.el
  lisp/window.el
  src/ChangeLog
  src/buffer.c
  src/lisp.h
  src/window.c
  src/window.h
=== modified file 'lisp/ChangeLog'
--- a/lisp/ChangeLog    2011-06-10 06:55:18 +0000
+++ b/lisp/ChangeLog    2011-06-11 09:50:37 +0000
@@ -1,5 +1,42 @@
 2011-06-10  Martin Rudalics  <address@hidden>
 
+       * loadup.el (top-level): Load window before files for the sake
+       of replace-buffer-in-windows.
+
+       * files.el (read-buffer-to-switch)
+       (switch-to-buffer-other-window)
+       (switch-to-buffer-other-frame, display-buffer-other-frame): Move
+       to window.el.
+
+       * simple.el (get-next-valid-buffer, last-buffer, next-buffer)
+       (previous-buffer): Move to window.el.
+
+       * bindings.el (unbury-buffer): Move to window.el.
+
+       * window.el (delete-other-windows-vertically): Move after
+       definition of delete-other-windows.
+       (other-window, delete-windows-on, replace-buffer-in-windows):
+       Move here from window.c.
+       (record-window-buffer, unrecord-window-buffer)
+       (set-window-buffer-start-and-point, switch-to-prev-buffer)
+       (switch-to-next-buffer): New functions.
+       (get-next-valid-buffer, last-buffer, next-buffer): Move here
+       from simple.el.  Call switch-to-next-buffer.
+       (previous-buffer): Move here from simple.el.  Call
+       switch-to-prev-buffer.
+       (bury-buffer): Move here from buffer.c.  Switch to previous
+       buffer when window cannot be deleted.
+       (unbury-buffer): Move here from bindings.el.
+       (ctl-x-map): Move binding for other-window from window.c to
+       here.
+       (read-buffer-to-switch, switch-to-buffer-other-window)
+       (switch-to-buffer-other-frame): Move here from files.el.
+       (normalize-buffer-to-switch-to): New functions.
+       (switch-to-buffer): Move here from buffer.c.  Use
+       read-buffer-to-switch and normalize-buffer-to-switch-to.
+
+2011-06-10  Martin Rudalics  <address@hidden>
+
        * window.el (window-min-height, window-min-width): Move here
        from window.c.  Add defcustoms and rewrite doc-strings.
        (resize-mini-window, resize-window): New functions.

=== modified file 'lisp/bindings.el'
--- a/lisp/bindings.el  2011-05-28 23:43:11 +0000
+++ b/lisp/bindings.el  2011-06-11 09:50:37 +0000
@@ -454,11 +454,6 @@
 (put 'mode-line-buffer-identification 'risky-local-variable t)
 (make-variable-buffer-local 'mode-line-buffer-identification)
 
-(defun unbury-buffer () "\
-Switch to the last buffer in the buffer list."
-  (interactive)
-  (switch-to-buffer (last-buffer)))
-
 (defun mode-line-unbury-buffer (event) "\
 Call `unbury-buffer' in this window."
   (interactive "e")

=== modified file 'lisp/files.el'
--- a/lisp/files.el     2011-06-09 20:22:06 +0000
+++ b/lisp/files.el     2011-06-11 09:50:37 +0000
@@ -1288,100 +1288,6 @@
         'confirm)
        (t nil)))
 
-(defun read-buffer-to-switch (prompt)
-  "Read the name of a buffer to switch to and return as a string.
-It is intended for `switch-to-buffer' family of commands since they
-need to omit the name of current buffer from the list of completions
-and default values."
-  (let ((rbts-completion-table (internal-complete-buffer-except)))
-    (minibuffer-with-setup-hook
-        (lambda ()
-          (setq minibuffer-completion-table rbts-completion-table)
-          ;; Since rbts-completion-table is built dynamically, we
-          ;; can't just add it to the default value of
-          ;; icomplete-with-completion-tables, so we add it
-          ;; here manually.
-          (if (and (boundp 'icomplete-with-completion-tables)
-                   (listp icomplete-with-completion-tables))
-              (set (make-local-variable 'icomplete-with-completion-tables)
-                   (cons rbts-completion-table
-                         icomplete-with-completion-tables))))
-      (read-buffer prompt (other-buffer (current-buffer))
-                   (confirm-nonexistent-file-or-buffer)))))
-
-(defun switch-to-buffer-other-window (buffer-or-name &optional norecord)
-  "Select the buffer specified by BUFFER-OR-NAME in another window.
-BUFFER-OR-NAME may be a buffer, a string \(a buffer name), or
-nil.  Return the buffer switched to.
-
-If called interactively, prompt for the buffer name using the
-minibuffer.  The variable `confirm-nonexistent-file-or-buffer'
-determines whether to request confirmation before creating a new
-buffer.
-
-If BUFFER-OR-NAME is a string and does not identify an existing
-buffer, create a new buffer with that name.  If BUFFER-OR-NAME is
-nil, switch to the buffer returned by `other-buffer'.
-
-Optional second argument NORECORD non-nil means do not put this
-buffer at the front of the list of recently selected ones.
-
-This uses the function `display-buffer' as a subroutine; see its
-documentation for additional customization information."
-  (interactive
-   (list (read-buffer-to-switch "Switch to buffer in other window: ")))
-  (let ((pop-up-windows t)
-       same-window-buffer-names same-window-regexps)
-    (pop-to-buffer buffer-or-name t norecord)))
-
-(defun switch-to-buffer-other-frame (buffer-or-name &optional norecord)
-  "Switch to buffer BUFFER-OR-NAME in another frame.
-BUFFER-OR-NAME may be a buffer, a string \(a buffer name), or
-nil.  Return the buffer switched to.
-
-If called interactively, prompt for the buffer name using the
-minibuffer.  The variable `confirm-nonexistent-file-or-buffer'
-determines whether to request confirmation before creating a new
-buffer.
-
-If BUFFER-OR-NAME is a string and does not identify an existing
-buffer, create a new buffer with that name.  If BUFFER-OR-NAME is
-nil, switch to the buffer returned by `other-buffer'.
-
-Optional second arg NORECORD non-nil means do not put this
-buffer at the front of the list of recently selected ones.
-
-This uses the function `display-buffer' as a subroutine; see its
-documentation for additional customization information."
-  (interactive
-   (list (read-buffer-to-switch "Switch to buffer in other frame: ")))
-  (let ((pop-up-frames t)
-       same-window-buffer-names same-window-regexps)
-    (pop-to-buffer buffer-or-name t norecord)))
-
-(defun display-buffer-other-frame (buffer)
-  "Display buffer BUFFER in another frame.
-This uses the function `display-buffer' as a subroutine; see
-its documentation for additional customization information."
-  (interactive "BDisplay buffer in other frame: ")
-  (let ((pop-up-frames t)
-       same-window-buffer-names same-window-regexps
-        ;;(old-window (selected-window))
-       new-window)
-    (setq new-window (display-buffer buffer t))
-    ;; This may have been here in order to prevent the new frame from hiding
-    ;; the old frame.  But it does more harm than good.
-    ;; Maybe we should call `raise-window' on the old-frame instead?  --Stef
-    ;;(lower-frame (window-frame new-window))
-
-    ;; This may have been here in order to make sure the old-frame gets the
-    ;; focus.  But not only can it cause an annoying flicker, with some
-    ;; window-managers it just makes the window invisible, with no easy
-    ;; way to recover it.  --Stef
-    ;;(make-frame-invisible (window-frame old-window))
-    ;;(make-frame-visible (window-frame old-window))
-    ))
-
 (defmacro minibuffer-with-setup-hook (fun &rest body)
   "Temporarily add FUN to `minibuffer-setup-hook' while executing BODY.
 BODY should use the minibuffer at most once.

=== modified file 'lisp/loadup.el'
--- a/lisp/loadup.el    2011-05-23 17:57:17 +0000
+++ b/lisp/loadup.el    2011-06-11 09:50:37 +0000
@@ -95,6 +95,7 @@
 (load "env")
 (load "format")
 (load "bindings")
+(load "window")  ; Needed here for `replace-buffer-in-windows'.
 (setq load-source-file-function 'load-with-code-conversion)
 (load "files")
 
@@ -156,7 +157,6 @@
 (load "language/cham")
 
 (load "indent")
-(load "window")
 (load "frame")
 (load "term/tty-colors")
 (load "font-core")

=== modified file 'lisp/simple.el'
--- a/lisp/simple.el    2011-06-01 19:32:04 +0000
+++ b/lisp/simple.el    2011-06-11 09:50:37 +0000
@@ -52,60 +52,6 @@
 (defgroup paren-matching nil
   "Highlight (un)matching of parens and expressions."
   :group 'matching)
-
-(defun get-next-valid-buffer (list &optional buffer visible-ok frame)
-  "Search LIST for a valid buffer to display in FRAME.
-Return nil when all buffers in LIST are undesirable for display,
-otherwise return the first suitable buffer in LIST.
-
-Buffers not visible in windows are preferred to visible buffers,
-unless VISIBLE-OK is non-nil.
-If the optional argument FRAME is nil, it defaults to the selected frame.
-If BUFFER is non-nil, ignore occurrences of that buffer in LIST."
-  ;; This logic is more or less copied from other-buffer.
-  (setq frame (or frame (selected-frame)))
-  (let ((pred (frame-parameter frame 'buffer-predicate))
-       found buf)
-    (while (and (not found) list)
-      (setq buf (car list))
-      (if (and (not (eq buffer buf))
-              (buffer-live-p buf)
-              (or (null pred) (funcall pred buf))
-              (not (eq (aref (buffer-name buf) 0) ?\s))
-              (or visible-ok (null (get-buffer-window buf 'visible))))
-         (setq found buf)
-       (setq list (cdr list))))
-    (car list)))
-
-(defun last-buffer (&optional buffer visible-ok frame)
-  "Return the last buffer in FRAME's buffer list.
-If BUFFER is the last buffer, return the preceding buffer instead.
-Buffers not visible in windows are preferred to visible buffers,
-unless optional argument VISIBLE-OK is non-nil.
-Optional third argument FRAME nil or omitted means use the
-selected frame's buffer list.
-If no such buffer exists, return the buffer `*scratch*', creating
-it if necessary."
-  (setq frame (or frame (selected-frame)))
-  (or (get-next-valid-buffer (nreverse (buffer-list frame))
-                            buffer visible-ok frame)
-      (get-buffer "*scratch*")
-      (let ((scratch (get-buffer-create "*scratch*")))
-       (set-buffer-major-mode scratch)
-       scratch)))
-
-(defun next-buffer ()
-  "Switch to the next buffer in cyclic order."
-  (interactive)
-  (let ((buffer (current-buffer)))
-    (switch-to-buffer (other-buffer buffer t))
-    (bury-buffer buffer)))
-
-(defun previous-buffer ()
-  "Switch to the previous buffer in cyclic order."
-  (interactive)
-  (switch-to-buffer (last-buffer (current-buffer) t)))
-
 
 ;;; next-error support framework
 

=== modified file 'lisp/window.el'
--- a/lisp/window.el    2011-06-10 06:55:18 +0000
+++ b/lisp/window.el    2011-06-11 09:50:37 +0000
@@ -2078,6 +2078,74 @@
   "Return non-nil if WINDOW is the root window of its frame."
   (eq window (frame-root-window window)))
 
+(defun other-window (count &optional all-frames)
+  "Select another window in cyclic ordering of windows.
+COUNT specifies the number of windows to skip, starting with the
+selected window, before making the selection.  If COUNT is
+positive, skip COUNT windows forwards.  If COUNT is negative,
+skip -COUNT windows backwards.  COUNT zero means do not skip any
+window, so select the selected window.  In an interactive call,
+COUNT is the numeric prefix argument.  Return nil.
+
+If the `other-window' parameter of WINDOW is a function and
+`ignore-window-parameters' is nil, call that function with the
+arguments COUNT and ALL-FRAMES.
+
+This function does not select a window whose `no-other-window'
+window parameter is non-nil.
+
+This function uses `next-window' for finding the window to
+select.  The argument ALL-FRAMES has the same meaning as in
+`next-window', but the MINIBUF argument of `next-window' is
+always effectively nil."
+  (interactive "p")
+  (let* ((window (selected-window))
+        (function (and (not ignore-window-parameters)
+                       (window-parameter window 'other-window)))
+        old-window old-count)
+    (if (functionp function)
+       (funcall function count all-frames)
+      ;; `next-window' and `previous-window' may return a window we are
+      ;; not allowed to select.  Hence we need an exit strategy in case
+      ;; all windows are non-selectable.
+      (catch 'exit
+       (while (> count 0)
+         (setq window (next-window window nil all-frames))
+         (cond
+          ((eq window old-window)
+           (when (= count old-count)
+             ;; Keep out of infinite loops.  When COUNT has not changed
+             ;; since we last looked at `window' we're probably in one.
+             (throw 'exit nil)))
+          ((window-parameter window 'no-other-window)
+           (unless old-window
+             ;; The first non-selectable window `next-window' got us:
+             ;; Remember it and the current value of COUNT.
+             (setq old-window window)
+             (setq old-count count)))
+          (t
+           (setq count (1- count)))))
+       (while (< count 0)
+         (setq window (previous-window window nil all-frames))
+         (cond
+          ((eq window old-window)
+           (when (= count old-count)
+             ;; Keep out of infinite loops.  When COUNT has not changed
+             ;; since we last looked at `window' we're probably in one.
+             (throw 'exit nil)))
+          ((window-parameter window 'no-other-window)
+           (unless old-window
+             ;; The first non-selectable window `previous-window' got
+             ;; us: Remember it and the current value of COUNT.
+             (setq old-window window)
+             (setq old-count count)))
+          (t
+           (setq count (1+ count)))))
+
+       (select-window window)
+       ;; Always return nil.
+       nil))))
+
 ;; This should probably return non-nil when the selected window is part
 ;; of an atomic window whose root is the frame's root window.
 (defun one-window-p (&optional nomini all-frames)
@@ -2285,6 +2353,518 @@
        (window-check frame))
       ;; Always return nil.
       nil)))
+
+(defun delete-other-windows-vertically (&optional window)
+  "Delete the windows in the same column with WINDOW, but not WINDOW itself.
+This may be a useful alternative binding for \\[delete-other-windows]
+ if you often split windows horizontally."
+  (interactive)
+  (let* ((window (or window (selected-window)))
+         (edges (window-edges window))
+         (w window) delenda)
+    (while (not (eq (setq w (next-window w 1)) window))
+      (let ((e (window-edges w)))
+        (when (and (= (car e) (car edges))
+                   (= (caddr e) (caddr edges)))
+          (push w delenda))))
+    (mapc 'delete-window delenda)))
+
+;;; Windows and buffers.
+
+;; `prev-buffers' and `next-buffers' are two reserved window slots used
+;; for (1) determining which buffer to show in the window when its
+;; buffer shall be buried or killed and (2) which buffer to show for
+;; `switch-to-prev-buffer' and `switch-to-next-buffer'.
+
+;; `prev-buffers' consists of <buffer, window-start, window-point>
+;; triples.  The entries on this list are ordered by the time their
+;; buffer has been removed from the window, the most recently removed
+;; buffer's entry being first.  The window-start and window-point
+;; components are `window-start' and `window-point' at the time the
+;; buffer was removed from the window which implies that the entry must
+;; be added when `set-window-buffer' removes the buffer from the window.
+
+;; `next-buffers' is the list of buffers that have been replaced
+;; recently by `switch-to-prev-buffer'.  These buffers are the least
+;; preferred candidates of `switch-to-prev-buffer' and the preferred
+;; candidates of `switch-to-next-buffer' to switch to.  This list is
+;; reset to nil by any action changing the window's buffer with the
+;; exception of `switch-to-prev-buffer' and `switch-to-next-buffer'.
+;; `switch-to-prev-buffer' pushes the buffer it just replaced on it,
+;; `switch-to-next-buffer' pops the last pushed buffer from it.
+
+;; Both `prev-buffers' and `next-buffers' may reference killed buffers
+;; if such a buffer was killed while the window was hidden within a
+;; window configuration.  Such killed buffers get removed whenever
+;; `switch-to-prev-buffer' or `switch-to-next-buffer' encounter them.
+
+;; The following function is called by `set-window-buffer' _before_ it
+;; replaces the buffer of the argument window with the new buffer.
+(defun record-window-buffer (&optional window)
+  "Record WINDOW's buffer.
+WINDOW must be a live window and defaults to the selected one."
+  (let* ((window (normalize-live-window window))
+        (buffer (window-buffer window))
+        (entry (assq buffer (window-prev-buffers window))))
+    ;; Reset WINDOW's next buffers.  If needed, they are resurrected by
+    ;; `switch-to-prev-buffer' and `switch-to-next-buffer'.
+    (set-window-next-buffers window nil)
+
+    (when entry
+      ;; Remove all entries for BUFFER from WINDOW's previous buffers.
+      (set-window-prev-buffers
+       window (assq-delete-all buffer (window-prev-buffers window))))
+
+    ;; Don't record insignificant buffers.
+    (unless (eq (aref (buffer-name buffer) 0) ?\s)
+      ;; Add an entry for buffer to WINDOW's previous buffers.
+      (with-current-buffer buffer
+       (let ((start (window-start window))
+             (point (window-point window)))
+         (setq entry
+               (cons buffer
+                     (if entry
+                         ;; We have an entry, update marker positions.
+                         (list (set-marker (nth 1 entry) start)
+                               (set-marker (nth 2 entry) point))
+                       ;; Make new markers.
+                       (list (copy-marker start)
+                             (copy-marker point)))))
+
+         (set-window-prev-buffers
+          window (cons entry (window-prev-buffers window))))))))
+
+(defun unrecord-window-buffer (&optional window buffer)
+  "Unrecord BUFFER in WINDOW.
+WINDOW must be a live window and defaults to the selected one.
+BUFFER must be a live buffer and defaults to the buffer of
+WINDOW."
+  (let* ((window (normalize-live-window window))
+        (buffer (or buffer (window-buffer window))))
+    (set-window-prev-buffers
+     window (assq-delete-all buffer (window-prev-buffers window)))
+    (set-window-next-buffers
+     window (delq buffer (window-next-buffers window)))))
+
+(defun set-window-buffer-start-and-point (window buffer &optional start point)
+  "Set WINDOW's buffer to BUFFER.
+Optional argument START non-nil means set WINDOW's start position
+to START.  Optional argument POINT non-nil means set WINDOW's
+point to POINT.  If WINDOW is selected this also sets BUFFER's
+`point' to POINT.  If WINDOW is selected and the buffer it showed
+before was current this also makes BUFFER the current buffer."
+  (let ((selected (eq window (selected-window)))
+       (current (eq (window-buffer window) (current-buffer))))
+    (set-window-buffer window buffer)
+    (when (and selected current)
+      (set-buffer buffer))
+    (when start
+      (set-window-start window start))
+    (when point
+      (if selected
+         (with-current-buffer buffer
+           (goto-char point))
+       (set-window-point window point)))))
+
+(defun switch-to-prev-buffer (&optional window bury-or-kill)
+  "In WINDOW switch to previous buffer.
+WINDOW must be a live window and defaults to the selected one.
+
+Optional argument BURY-OR-KILL non-nil means the buffer currently
+shown in WINDOW is about to be buried or killed and consequently
+shall not be switched to in future invocations of this command."
+  (interactive)
+  (let* ((window (normalize-live-window window))
+        (old-buffer (window-buffer window))
+        ;; Save this since it's destroyed by `set-window-buffer'.
+        (next-buffers (window-next-buffers window))
+        entry new-buffer killed-buffers deletable visible)
+    (cond
+     ;; When BURY-OR-KILL is non-nil, there's no previous buffer for
+     ;; this window, and we can delete the window (or the frame) do
+     ;; that.
+     ((and bury-or-kill
+          (or (not (window-prev-buffers window))
+              (and (eq (caar (window-prev-buffers window)) old-buffer)
+                   (not (cdr (car (window-prev-buffers window))))))
+          (setq deletable (window-deletable-p window)))
+      (if (eq deletable 'frame)
+         (delete-frame (window-frame window))
+       (delete-window window)))
+     ((window-dedicated-p window)
+      (error "Window %s is dedicated to buffer %s" window old-buffer)))
+
+    (unless deletable
+      (catch 'found
+       ;; Scan WINDOW's previous buffers first, skipping entries of next
+       ;; buffers.
+       (dolist (entry (window-prev-buffers window))
+         (when (and (setq new-buffer (car entry))
+                    (or (buffer-live-p new-buffer)
+                        (not (setq killed-buffers
+                                   (cons new-buffer killed-buffers))))
+                    (not (eq new-buffer old-buffer))
+                    (or bury-or-kill
+                        (not (memq new-buffer next-buffers))))
+           (set-window-buffer-start-and-point
+            window new-buffer (nth 1 entry) (nth 2 entry))
+           (throw 'found t)))
+       ;; Scan reverted buffer list of WINDOW's frame next, skipping
+       ;; entries of next buffers.  Note that when we bury or kill a
+       ;; buffer we don't reverse the global buffer list to avoid showing
+       ;; a buried buffer instead.  Otherwise, we must reverse the global
+       ;; buffer list in order to make sure that switching to the
+       ;; previous/next buffer traverse it in opposite directions.
+       (dolist (buffer (if bury-or-kill
+                           (buffer-list (window-frame window))
+                         (nreverse (buffer-list (window-frame window)))))
+         (when (and (buffer-live-p buffer)
+                    (not (eq buffer old-buffer))
+                    (not (eq (aref (buffer-name buffer) 0) ?\s))
+                    (or bury-or-kill (not (memq buffer next-buffers))))
+           (if (get-buffer-window buffer)
+               ;; Try to avoid showing a buffer visible in some other window.
+               (setq visible buffer)
+           (setq new-buffer buffer)
+           (set-window-buffer-start-and-point window new-buffer)
+           (throw 'found t))))
+       (unless bury-or-kill
+         ;; Scan reverted next buffers last (must not use nreverse
+         ;; here!).
+         (dolist (buffer (reverse next-buffers))
+           ;; Actually, buffer _must_ be live here since otherwise it
+           ;; would have been caught in the scan of previous buffers.
+           (when (and (or (buffer-live-p buffer)
+                          (not (setq killed-buffers
+                                     (cons buffer killed-buffers))))
+                      (not (eq buffer old-buffer))
+                      (setq entry (assq buffer (window-prev-buffers window))))
+             (setq new-buffer buffer)
+             (set-window-buffer-start-and-point
+              window new-buffer (nth 1 entry) (nth 2 entry))
+             (throw 'found t))))
+
+       ;; Show a buffer visible in another window.
+       (when visible
+         (setq new-buffer visible)
+         (set-window-buffer-start-and-point window new-buffer)))
+
+      (if bury-or-kill
+         ;; Remove `old-buffer' from WINDOW's previous and (restored list
+         ;; of) next buffers.
+         (progn
+           (set-window-prev-buffers
+            window (assq-delete-all old-buffer (window-prev-buffers window)))
+           (set-window-next-buffers window (delq old-buffer next-buffers)))
+       ;; Move `old-buffer' to head of WINDOW's restored list of next
+       ;; buffers.
+       (set-window-next-buffers
+        window (cons old-buffer (delq old-buffer next-buffers)))))
+
+    ;; Remove killed buffers from WINDOW's previous and next buffers.
+    (when killed-buffers
+      (dolist (buffer killed-buffers)
+       (set-window-prev-buffers
+        window (assq-delete-all buffer (window-prev-buffers window)))
+       (set-window-next-buffers
+        window (delq buffer (window-next-buffers window)))))
+
+    ;; Return new-buffer.
+    new-buffer))
+
+(defun switch-to-next-buffer (&optional window)
+  "In WINDOW switch to next buffer.
+WINDOW must be a live window and defaults to the selected one."
+  (interactive)
+  (let* ((window (normalize-live-window window))
+        (old-buffer (window-buffer window))
+        (next-buffers (window-next-buffers window))
+        new-buffer entry killed-buffers visible)
+    (when (window-dedicated-p window)
+      (error "Window %s is dedicated to buffer %s" window old-buffer))
+
+    (catch 'found
+      ;; Scan WINDOW's next buffers first.
+      (dolist (buffer next-buffers)
+       (when (and (or (buffer-live-p buffer)
+                      (not (setq killed-buffers
+                                 (cons buffer killed-buffers))))
+                  (not (eq buffer old-buffer))
+                  (setq entry (assq buffer (window-prev-buffers window))))
+         (setq new-buffer buffer)
+         (set-window-buffer-start-and-point
+          window new-buffer (nth 1 entry) (nth 2 entry))
+         (throw 'found t)))
+      ;; Scan the buffer list of WINDOW's frame next, skipping previous
+      ;; buffers entries.
+      (dolist (buffer (buffer-list (window-frame window)))
+       (when (and (buffer-live-p buffer) (not (eq buffer old-buffer))
+                  (not (eq (aref (buffer-name buffer) 0) ?\s))
+                  (not (assq buffer (window-prev-buffers window))))
+         (if (get-buffer-window buffer)
+             ;; Try to avoid showing a buffer visible in some other window.
+             (setq visible buffer)
+           (setq new-buffer buffer)
+           (set-window-buffer-start-and-point window new-buffer)
+           (throw 'found t))))
+      ;; Scan WINDOW's reverted previous buffers last (must not use
+      ;; nreverse here!)
+      (dolist (entry (reverse (window-prev-buffers window)))
+       (when (and (setq new-buffer (car entry))
+                  (or (buffer-live-p new-buffer)
+                      (not (setq killed-buffers
+                                 (cons new-buffer killed-buffers))))
+                  (not (eq new-buffer old-buffer)))
+         (set-window-buffer-start-and-point
+          window new-buffer (nth 1 entry) (nth 2 entry))
+         (throw 'found t)))
+
+      ;; Show a buffer visible in another window.
+      (when visible
+       (setq new-buffer visible)
+       (set-window-buffer-start-and-point window new-buffer)))
+
+    ;; Remove `new-buffer' from and restore WINDOW's next buffers.
+    (set-window-next-buffers window (delq new-buffer next-buffers))
+
+    ;; Remove killed buffers from WINDOW's previous and next buffers.
+    (when killed-buffers
+      (dolist (buffer killed-buffers)
+       (set-window-prev-buffers
+        window (assq-delete-all buffer (window-prev-buffers window)))
+       (set-window-next-buffers
+        window (delq buffer (window-next-buffers window)))))
+
+    ;; Return new-buffer.
+    new-buffer))
+
+(defun get-next-valid-buffer (list &optional buffer visible-ok frame)
+  "Search LIST for a valid buffer to display in FRAME.
+Return nil when all buffers in LIST are undesirable for display,
+otherwise return the first suitable buffer in LIST.
+
+Buffers not visible in windows are preferred to visible buffers,
+unless VISIBLE-OK is non-nil.
+If the optional argument FRAME is nil, it defaults to the selected frame.
+If BUFFER is non-nil, ignore occurrences of that buffer in LIST."
+  ;; This logic is more or less copied from other-buffer.
+  (setq frame (or frame (selected-frame)))
+  (let ((pred (frame-parameter frame 'buffer-predicate))
+       found buf)
+    (while (and (not found) list)
+      (setq buf (car list))
+      (if (and (not (eq buffer buf))
+              (buffer-live-p buf)
+              (or (null pred) (funcall pred buf))
+              (not (eq (aref (buffer-name buf) 0) ?\s))
+              (or visible-ok (null (get-buffer-window buf 'visible))))
+         (setq found buf)
+       (setq list (cdr list))))
+    (car list)))
+
+(defun last-buffer (&optional buffer visible-ok frame)
+  "Return the last buffer in FRAME's buffer list.
+If BUFFER is the last buffer, return the preceding buffer
+instead.  Buffers not visible in windows are preferred to visible
+buffers, unless optional argument VISIBLE-OK is non-nil.
+Optional third argument FRAME nil or omitted means use the
+selected frame's buffer list.  If no such buffer exists, return
+the buffer `*scratch*', creating it if necessary."
+  (setq frame (or frame (selected-frame)))
+  (or (get-next-valid-buffer (nreverse (buffer-list frame))
+                            buffer visible-ok frame)
+      (get-buffer "*scratch*")
+      (let ((scratch (get-buffer-create "*scratch*")))
+       (set-buffer-major-mode scratch)
+       scratch)))
+
+(defun bury-buffer (&optional buffer-or-name)
+  "Put BUFFER-OR-NAME at the end of the list of all buffers.
+There it is the least likely candidate for `other-buffer' to
+return; thus, the least likely buffer for \\[switch-to-buffer] to
+select by default.
+
+You can specify a buffer name as BUFFER-OR-NAME, or an actual
+buffer object.  If BUFFER-OR-NAME is nil or omitted, bury the
+current buffer.  Also, if BUFFER-OR-NAME is nil or omitted,
+remove the current buffer from the selected window if it is
+displayed there."
+  (interactive)
+  (let* ((buffer (normalize-live-buffer buffer-or-name)))
+    ;; If `buffer-or-name' is not on the selected frame we unrecord it
+    ;; although it's not "here" (call it a feature).
+    (unrecord-buffer buffer)
+    ;; Handle case where `buffer-or-name' is nil and the current buffer
+    ;; is shown in the selected window.
+    (cond
+     ((or buffer-or-name (not (eq buffer (window-buffer)))))
+     ((not (window-dedicated-p))
+      (switch-to-prev-buffer nil 'bury))
+     ((frame-root-window-p (selected-window))
+      (iconify-frame (window-frame (selected-window))))
+     ((window-deletable-p)
+      (delete-window)))
+    ;; Always return nil.
+    nil))
+
+(defun unbury-buffer ()
+  "Switch to the last buffer in the buffer list."
+  (interactive)
+  (switch-to-buffer (last-buffer)))
+
+(defun next-buffer ()
+  "In selected window switch to next buffer."
+  (interactive)
+  (switch-to-next-buffer))
+
+(defun previous-buffer ()
+  "In selected window switch to previous buffer."
+  (interactive)
+  (switch-to-prev-buffer))
+
+(defun delete-windows-on (&optional buffer-or-name frame)
+  "Delete all windows showing BUFFER-OR-NAME.
+BUFFER-OR-NAME may be a buffer or the name of an existing buffer
+and defaults to the current buffer.
+
+The following non-nil values of the optional argument FRAME
+have special meanings:
+
+- t means consider all windows on the selected frame only.
+
+- `visible' means consider all windows on all visible frames on
+  the current terminal.
+
+- 0 (the number zero) means consider all windows on all visible
+  and iconified frames on the current terminal.
+
+- A frame means consider all windows on that frame only.
+
+Any other value of FRAME means consider all windows on all
+frames.
+
+When a window showing BUFFER-OR-NAME is dedicated and the only
+window of its frame, that frame is deleted when there are other
+frames left."
+  (interactive "BDelete windows on (buffer):\nP")
+  (let ((buffer (normalize-live-buffer buffer-or-name))
+       ;; Handle the "inverted" meaning of the FRAME argument wrt other
+       ;; `window-list-1' based function.
+       (all-frames (cond ((not frame) t) ((eq frame t) nil) (t frame))))
+    (dolist (window (window-list-1 nil nil all-frames))
+      (if (eq (window-buffer window) buffer)
+         (let ((deletable (window-deletable-p window)))
+           (cond
+            ((eq deletable 'frame)
+             ;; Delete frame.
+             (delete-frame (window-frame window)))
+            (deletable
+             ;; Delete window only.
+             (delete-window window))
+            (t
+             ;; In window switch to previous buffer.
+             (set-window-dedicated-p window nil)
+             (switch-to-prev-buffer window 'bury))))
+       ;; If a window doesn't show BUFFER, unrecord BUFFER in it.
+       (unrecord-window-buffer window buffer)))))
+
+(defun replace-buffer-in-windows (&optional buffer-or-name)
+  "Replace BUFFER-OR-NAME with some other buffer in all windows showing it.
+BUFFER-OR-NAME may be a buffer or the name of an existing buffer
+and defaults to the current buffer.
+
+When a window showing BUFFER-OR-NAME is either dedicated, or the
+window has no previous buffer, that window is deleted.  If that
+window is the only window on its frame, the frame is deleted too
+when there are other frames left.  If there are no other frames
+left, some other buffer is displayed in that window.
+
+This function removes the buffer denoted by BUFFER-OR-NAME from
+all window-local buffer lists."
+  (let ((buffer (normalize-live-buffer buffer-or-name)))
+    (dolist (window (window-list-1 nil nil t))
+      (if (eq (window-buffer window) buffer)
+         (let ((deletable (window-deletable-p window)))
+           (cond
+            ((eq deletable 'frame)
+             ;; Delete frame.
+             (delete-frame (window-frame window)))
+            ((and (window-dedicated-p window) deletable)
+             ;; Delete window.
+             (delete-window window))
+            (t
+             ;; Switch to another buffer in window.
+             (set-window-dedicated-p window nil)
+             (switch-to-prev-buffer window 'kill))))
+       ;; Unrecord BUFFER in WINDOW.
+       (unrecord-window-buffer window buffer)))))
+
+(defun quit-restore-window (&optional window kill)
+  "Quit WINDOW in some way.
+WINDOW must be a live window and defaults to the selected window.
+Return nil.
+
+According to information stored in WINDOW's `quit-restore' window
+parameter either \(1) delete WINDOW and its frame, \(2) delete
+WINDOW, \(3) restore the buffer previously displayed in WINDOW,
+or \(4) make WINDOW display some other buffer than the present
+one.  If non-nil, reset `quit-restore' parameter to nil.
+
+Optional argument KILL non-nil means in addition kill WINDOW's
+buffer.  If KILL is nil, put WINDOW's buffer at the end of the
+buffer list.  Interactively, KILL is the prefix argument."
+  (interactive "i\nP")
+  (setq window (normalize-live-window window))
+  (let ((buffer (window-buffer window))
+       (quit-restore (window-parameter window 'quit-restore))
+       deletable resize)
+    (cond
+     ((and (or (and (memq (car-safe quit-restore) '(new-window new-frame))
+                   ;; Check that WINDOW's buffer is still the same.
+                   (eq (window-buffer window) (nth 1 quit-restore)))
+              (window-dedicated-p window))
+          (setq deletable (window-deletable-p window)))
+      ;; WINDOW can be deleted.
+      (unrecord-buffer buffer)
+      (if (eq deletable 'frame)
+         ;; WINDOW's frame can be deleted.
+         (delete-frame (window-frame window))
+       ;; Just delete WINDOW.
+       (delete-window window))
+      ;; If the previously selected window is still alive, select it.
+      (when (window-live-p (nth 2 quit-restore))
+       (select-window (nth 2 quit-restore))))
+     ((and (buffer-live-p (nth 0 quit-restore))
+          ;; The buffer currently shown in WINDOW must still be the
+          ;; buffer shown when its `quit-restore' parameter was created
+          ;; in the first place.
+          (eq (window-buffer window) (nth 3 quit-restore)))
+      (setq resize (with-current-buffer buffer temp-buffer-resize-mode))
+      ;; Unrecord buffer.
+      (unrecord-buffer buffer)
+      (unrecord-window-buffer window buffer)
+      ;; Display buffer stored in the quit-restore parameter.
+      (set-window-dedicated-p window nil)
+      (set-window-buffer window (nth 0 quit-restore))
+      (set-window-start window (nth 1 quit-restore))
+      (set-window-point window (nth 2 quit-restore))
+      (when (and resize (/= (nth 4 quit-restore) (window-total-size window)))
+       (resize-window
+        window (- (nth 4 quit-restore) (window-total-size window))))
+      ;; Reset the quit-restore parameter.
+      (set-window-parameter window 'quit-restore nil)
+      (when (window-live-p (nth 5 quit-restore))
+       (select-window (nth 5 quit-restore))))
+     (t
+      ;; Otherwise, show another buffer in WINDOW and reset the
+      ;; quit-restore parameter.
+      (set-window-parameter window 'quit-restore nil)
+      (unrecord-buffer buffer)
+      (switch-to-prev-buffer window 'bury-or-kill)))
+
+    ;; Kill WINDOW's old-buffer if requested
+    (when kill (kill-buffer buffer))
+    nil))
 
 ;;; Splitting windows.
 (defsubst window-split-min-size (&optional horizontal)
@@ -2569,22 +3149,14 @@
           (<= (window-start new-window) old-point)
           (set-window-point new-window old-point)
           (select-window new-window)))
-    (split-window-save-restore-data new-window old-window)))
+    ;; Always copy quit-restore parameter in interactive use.
+    (let ((quit-restore (window-parameter old-window 'quit-restore)))
+      (when quit-restore
+       (set-window-parameter new-window 'quit-restore quit-restore)))
+    new-window))
 
 (defalias 'split-window-vertically 'split-window-above-each-other)
 
-;; This is to avoid compiler warnings.
-(defvar view-return-to-alist)
-
-(defun split-window-save-restore-data (new-window old-window)
-  (with-current-buffer (window-buffer)
-    (when view-mode
-      (let ((old-info (assq old-window view-return-to-alist)))
-       (when old-info
-         (push (cons new-window (cons (car (cdr old-info)) t))
-               view-return-to-alist))))
-    new-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.
@@ -2603,7 +3175,12 @@
     (when (and size (< size 0) (< (- size) window-min-width))
       ;; `split-window' would not signal an error here.
       (error "Size of new window too small"))
-    (split-window-save-restore-data (split-window nil size t) old-window)))
+    (setq new-window (split-window nil size t))
+    ;; Always copy quit-restore parameter in interactive use.
+    (let ((quit-restore (window-parameter old-window 'quit-restore)))
+      (when quit-restore
+       (set-window-parameter new-window 'quit-restore quit-restore)))
+    new-window))
 
 (defalias 'split-window-horizontally 'split-window-side-by-side)
 
@@ -3545,6 +4122,29 @@
       (window--even-window-heights window-to-use)
       (window--display-buffer-2 buffer window-to-use)))))
 
+(defun display-buffer-other-frame (buffer)
+  "Display buffer BUFFER in another frame.
+This uses the function `display-buffer' as a subroutine; see
+its documentation for additional customization information."
+  (interactive "BDisplay buffer in other frame: ")
+  (let ((pop-up-frames t)
+       same-window-buffer-names same-window-regexps
+        ;;(old-window (selected-window))
+       new-window)
+    (setq new-window (display-buffer buffer t))
+    ;; This may have been here in order to prevent the new frame from hiding
+    ;; the old frame.  But it does more harm than good.
+    ;; Maybe we should call `raise-window' on the old-frame instead?  --Stef
+    ;;(lower-frame (window-frame new-window))
+
+    ;; This may have been here in order to make sure the old-frame gets the
+    ;; focus.  But not only can it cause an annoying flicker, with some
+    ;; window-managers it just makes the window invisible, with no easy
+    ;; way to recover it.  --Stef
+    ;;(make-frame-invisible (window-frame old-window))
+    ;;(make-frame-visible (window-frame old-window))
+    ))
+
 (defun pop-to-buffer (buffer-or-name &optional other-window norecord)
   "Select buffer BUFFER-OR-NAME in some window, preferably a different one.
 BUFFER-OR-NAME may be a buffer, a string \(a buffer name), or
@@ -3587,6 +4187,130 @@
       ;; input focus and is risen.
       (select-frame-set-input-focus new-frame))
     buffer))
+
+(defun read-buffer-to-switch (prompt)
+  "Read the name of a buffer to switch to, prompting with PROMPT.
+Return the neame of the buffer as a string.
+
+This function is intended for the `switch-to-buffer' family of
+commands since these need to omit the name of the current buffer
+from the list of completions and default values."
+  (let ((rbts-completion-table (internal-complete-buffer-except)))
+    (minibuffer-with-setup-hook
+        (lambda ()
+          (setq minibuffer-completion-table rbts-completion-table)
+          ;; Since rbts-completion-table is built dynamically, we
+          ;; can't just add it to the default value of
+          ;; icomplete-with-completion-tables, so we add it
+          ;; here manually.
+          (if (and (boundp 'icomplete-with-completion-tables)
+                   (listp icomplete-with-completion-tables))
+              (set (make-local-variable 'icomplete-with-completion-tables)
+                   (cons rbts-completion-table
+                         icomplete-with-completion-tables))))
+      (read-buffer prompt (other-buffer (current-buffer))
+                   (confirm-nonexistent-file-or-buffer)))))
+
+(defun normalize-buffer-to-switch-to (buffer-or-name)
+  "Normalize BUFFER-OR-NAME argument of buffer switching functions.
+If BUFFER-OR-NAME is nil, return the buffer returned by
+`other-buffer'.  Else, if a buffer specified by BUFFER-OR-NAME
+exists, return that buffer.  If no such buffer exists, create a
+buffer with the name BUFFER-OR-NAME and return that buffer."
+  (if buffer-or-name
+      (or (get-buffer buffer-or-name)
+         (let ((buffer (get-buffer-create buffer-or-name)))
+           (set-buffer-major-mode buffer)
+           buffer))
+    (other-buffer)))
+
+(defun switch-to-buffer (buffer-or-name &optional norecord)
+  "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'
+determines whether to request confirmation before creating a new
+buffer.
+
+BUFFER-OR-NAME may be a buffer, a string \(a buffer name), or
+nil.  If BUFFER-OR-NAME is a string that does not identify an
+existing buffer, create a buffer with that name.  If
+BUFFER-OR-NAME is nil, switch to the buffer returned by
+`other-buffer'.
+
+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.
+
+This function is intended for interactive use only.  Lisp
+functions should call `pop-to-buffer-same-window' instead."
+  (interactive
+   (list (read-buffer-to-switch "Switch to buffer: ")))
+  (let ((buffer (normalize-buffer-to-switch-to buffer-or-name)))
+    (if (and (or (window-minibuffer-p) (eq (window-dedicated-p) t))
+            (not (eq buffer (window-buffer))))
+       ;; Cannot switch to another buffer in a minibuffer or strongly
+       ;; dedicated window that does not show the buffer already.  Call
+       ;; `pop-to-buffer' instead.
+       (pop-to-buffer buffer nil norecord)
+      (unless (eq buffer (window-buffer))
+       ;; I'm not sure why we should NOT call `set-window-buffer' here,
+       ;; but let's keep things as they are (otherwise we could always
+       ;; call `pop-to-buffer-same-window' here).
+       (set-window-buffer nil buffer))
+      (unless norecord
+       (select-window (selected-window)))
+      (set-buffer buffer))))
+
+(defun switch-to-buffer-other-window (buffer-or-name &optional norecord)
+  "Select the buffer specified by BUFFER-OR-NAME in another window.
+BUFFER-OR-NAME may be a buffer, a string \(a buffer name), or
+nil.  Return the buffer switched to.
+
+If called interactively, prompt for the buffer name using the
+minibuffer.  The variable `confirm-nonexistent-file-or-buffer'
+determines whether to request confirmation before creating a new
+buffer.
+
+If BUFFER-OR-NAME is a string and does not identify an existing
+buffer, create a new buffer with that name.  If BUFFER-OR-NAME is
+nil, switch to the buffer returned by `other-buffer'.
+
+Optional second argument NORECORD non-nil means do not put this
+buffer at the front of the list of recently selected ones.
+
+This uses the function `display-buffer' as a subroutine; see its
+documentation for additional customization information."
+  (interactive
+   (list (read-buffer-to-switch "Switch to buffer in other window: ")))
+  (let ((pop-up-windows t)
+       same-window-buffer-names same-window-regexps)
+    (pop-to-buffer buffer-or-name t norecord)))
+
+(defun switch-to-buffer-other-frame (buffer-or-name &optional norecord)
+  "Switch to buffer BUFFER-OR-NAME in another frame.
+BUFFER-OR-NAME may be a buffer, a string \(a buffer name), or
+nil.  Return the buffer switched to.
+
+If called interactively, prompt for the buffer name using the
+minibuffer.  The variable `confirm-nonexistent-file-or-buffer'
+determines whether to request confirmation before creating a new
+buffer.
+
+If BUFFER-OR-NAME is a string and does not identify an existing
+buffer, create a new buffer with that name.  If BUFFER-OR-NAME is
+nil, switch to the buffer returned by `other-buffer'.
+
+Optional second arg NORECORD non-nil means do not put this
+buffer at the front of the list of recently selected ones.
+
+This uses the function `display-buffer' as a subroutine; see its
+documentation for additional customization information."
+  (interactive
+   (list (read-buffer-to-switch "Switch to buffer in other frame: ")))
+  (let ((pop-up-frames t)
+       same-window-buffer-names same-window-regexps)
+    (pop-to-buffer buffer-or-name t norecord)))
 
 (defun set-window-text-height (window height)
   "Set the height in lines of the text display area of WINDOW to HEIGHT.
@@ -4258,21 +4982,6 @@
        (run-hooks 'mouse-leave-buffer-hook))
       (select-window window))))
 
-(defun delete-other-windows-vertically (&optional window)
-  "Delete the windows in the same column with WINDOW, but not WINDOW itself.
-This may be a useful alternative binding for \\[delete-other-windows]
- if you often split windows horizontally."
-  (interactive)
-  (let* ((window (or window (selected-window)))
-         (edges (window-edges window))
-         (w window) delenda)
-    (while (not (eq (setq w (next-window w 1)) window))
-      (let ((e (window-edges w)))
-        (when (and (= (car e) (car edges))
-                   (= (caddr e) (caddr edges)))
-          (push w delenda))))
-    (mapc 'delete-window delenda)))
-
 (defun truncated-partial-width-window-p (&optional window)
   "Return non-nil if lines in WINDOW are specifically truncated due to its 
width.
 WINDOW defaults to the selected window.
@@ -4293,6 +5002,7 @@
 (define-key ctl-x-map "1" 'delete-other-windows)
 (define-key ctl-x-map "2" 'split-window-above-each-other)
 (define-key ctl-x-map "3" 'split-window-side-by-side)
+(define-key ctl-x-map "o" 'other-window)
 (define-key ctl-x-map "^" 'enlarge-window)
 (define-key ctl-x-map "}" 'enlarge-window-horizontally)
 (define-key ctl-x-map "{" 'shrink-window-horizontally)

=== modified file 'src/ChangeLog'
--- a/src/ChangeLog     2011-06-11 01:48:59 +0000
+++ b/src/ChangeLog     2011-06-11 09:50:37 +0000
@@ -1,3 +1,54 @@
+2011-06-11  Martin Rudalics  <address@hidden>
+
+       * buffer.c: New Lisp objects Qbuffer_list_update_hook and
+       Qclone_number.  Remove external declaration of Qdelete_window.
+       (Fbuffer_list): Rewrite doc-string.  Minor restructuring of
+       code.
+       (Fget_buffer_create, Fmake_indirect_buffer, Frename_buffer): Run
+       Qbuffer_list_update_hook if allowed.
+       (Fother_buffer): Rewrite doc-string.  Major rewrite for new
+       buffer list implementation.
+       (other_buffer_safely): New function.
+       (Fkill_buffer): Replace call to replace_buffer_in_all_windows by
+       calls to replace_buffer_in_windows and
+       replace_buffer_in_windows_safely.  Run Qbuffer_list_update_hook
+       if allowed.
+       (record_buffer): Inhibit quitting and rewrite using quittable
+       functions.  Run Qbuffer_list_update_hook if allowed.
+       (Frecord_buffer, Funrecord_buffer): New functions.
+       (switch_to_buffer_1, Fswitch_to_buffer): Remove.  Move
+       switch-to-buffer to window.el.
+       (bury-buffer): Move to window.el.
+       (Vbuffer_list_update_hook): New variable.
+
+       * lisp.h (other_buffer_safely): Add prototype in buffer.c
+       section.
+
+       * window.h (resize_frame_windows): Move up in code.
+       (Fwindow_frame): Remove EXFUN.
+       (replace_buffer_in_all_windows): Remove prototype.
+       (replace_buffer_in_windows_safely): Add prototype.
+
+       * window.c: Declare Qdelete_window static again.  Move down
+       declaration of select_count.
+       (Fnext_window, Fprevious_window): Rewrite doc-strings.
+       (Fother_window): Move to window.el.
+       (window_loop): Remove DELETE_BUFFER_WINDOWS and UNSHOW_BUFFER
+       cases.  Add REPLACE_BUFFER_IN_WINDOWS_SAFELY case.
+       (Fdelete_windows_on, Freplace_buffer_in_windows): Move to
+       window.el.
+       (replace_buffer_in_windows): Implement by calling
+       Qreplace_buffer_in_windows.
+       (replace_buffer_in_all_windows): Remove with some functionality
+       moved into replace_buffer_in_windows_safely.
+       (replace_buffer_in_windows_safely): New function.
+       (select_window_norecord, select_frame_norecord): Move in front
+       of run_window_configuration_change_hook.  Remove now obsolete
+       declarations.
+       (Fset_window_buffer): Rewrite doc-string.  Call
+       Qrecord_window_buffer.
+       (keys_of_window): Move binding for other-window to window.el.
+
 2011-06-11  Chong Yidong  <address@hidden>
 
        * dispextern.h (struct image): Replace data member, whose int_val

=== modified file 'src/buffer.c'
--- a/src/buffer.c      2011-06-10 06:55:18 +0000
+++ b/src/buffer.c      2011-06-11 09:50:37 +0000
@@ -131,13 +131,15 @@
 static Lisp_Object QSFundamental;      /* A string "Fundamental" */
 
 static Lisp_Object Qkill_buffer_hook;
+static Lisp_Object Qbuffer_list_update_hook;
 
 static Lisp_Object Qget_file_buffer;
 
 static Lisp_Object Qoverlayp;
 
 Lisp_Object Qpriority, Qbefore_string, Qafter_string;
-static Lisp_Object Qevaporate;
+
+static Lisp_Object Qclone_number, Qevaporate;
 
 Lisp_Object Qmodification_hooks;
 Lisp_Object Qinsert_in_front_hooks;
@@ -171,9 +173,9 @@
 
 DEFUN ("buffer-list", Fbuffer_list, Sbuffer_list, 0, 1, 0,
        doc: /* Return a list of all existing live buffers.
-If the optional arg FRAME is a frame, we return the buffer list
-in the proper order for that frame: the buffers in FRAME's `buffer-list'
-frame parameter come first, followed by the rest of the buffers.  */)
+If the optional arg FRAME is a frame, we return the buffer list in the
+proper order for that frame: the buffers show in FRAME come first,
+followed by the rest of the buffers.  */)
   (Lisp_Object frame)
 {
   Lisp_Object general;
@@ -185,9 +187,9 @@
       Lisp_Object args[3];
 
       CHECK_FRAME (frame);
-
       framelist = Fcopy_sequence (XFRAME (frame)->buffer_list);
-      prevlist = Fnreverse (Fcopy_sequence (XFRAME 
(frame)->buried_buffer_list));
+      prevlist = Fnreverse (Fcopy_sequence
+                           (XFRAME (frame)->buried_buffer_list));
 
       /* Remove from GENERAL any buffer that duplicates one in
          FRAMELIST or PREVLIST.  */
@@ -209,8 +211,8 @@
       args[2] = prevlist;
       return Fnconc (3, args);
     }
-
-  return general;
+  else
+    return general;
 }
 
 /* Like Fassoc, but use Fstring_equal to compare
@@ -384,6 +386,9 @@
   /* Put this in the alist of all live buffers.  */
   XSETBUFFER (buffer, b);
   Vbuffer_alist = nconc2 (Vbuffer_alist, Fcons (Fcons (name, buffer), Qnil));
+  /* And run buffer-list-update-hook.  */
+  if (!NILP (Vrun_hooks))
+    call1 (Vrun_hooks, Qbuffer_list_update_hook);
 
   /* An error in calling the function here (should someone redefine it)
      can lead to infinite regress until you run out of stack.  rms
@@ -659,6 +664,10 @@
       set_buffer_internal_1 (old_b);
     }
 
+  /* Run buffer-list-update-hook.  */
+  if (!NILP (Vrun_hooks))
+    call1 (Vrun_hooks, Qbuffer_list_update_hook);
+
   return buf;
 }
 
@@ -1262,81 +1271,119 @@
   if (NILP (BVAR (current_buffer, filename))
       && !NILP (BVAR (current_buffer, auto_save_file_name)))
     call0 (intern ("rename-auto-save-file"));
+
+  /* Run buffer-list-update-hook.  */
+  if (!NILP (Vrun_hooks))
+    call1 (Vrun_hooks, Qbuffer_list_update_hook);
+
   /* Refetch since that last call may have done GC.  */
   return BVAR (current_buffer, name);
 }
 
 DEFUN ("other-buffer", Fother_buffer, Sother_buffer, 0, 3, 0,
        doc: /* Return most recently selected buffer other than BUFFER.
-Buffers not visible in windows are preferred to visible buffers,
-unless optional second argument VISIBLE-OK is non-nil.
-If the optional third argument FRAME is non-nil, use that frame's
-buffer list instead of the selected frame's buffer list.
-If no other buffer exists, the buffer `*scratch*' is returned.
-If BUFFER is omitted or nil, some interesting buffer is returned.  */)
+Buffers not visible in windows are preferred to visible buffers, unless
+optional second argument VISIBLE-OK is non-nil.  Ignore the argument
+BUFFER unless it denotes a live buffer.  If the optional third argument
+FRAME is non-nil, use that frame's buffer list instead of the selected
+frame's buffer list.
+
+The buffer is found by scanning the selected or specified frame's buffer
+list first, followed by the list of all buffers.  If no other buffer
+exists, return the buffer `*scratch*' (creating it if necessary).  */)
   (register Lisp_Object buffer, Lisp_Object visible_ok, Lisp_Object frame)
 {
-  register Lisp_Object tail, buf, notsogood, tem, pred, add_ons;
-  notsogood = Qnil;
+  Lisp_Object Fset_buffer_major_mode (Lisp_Object buffer);
+  Lisp_Object tail, buf, pred;
+  Lisp_Object notsogood = Qnil;
 
   if (NILP (frame))
     frame = selected_frame;
 
   CHECK_FRAME (frame);
 
-  tail = Vbuffer_alist;
   pred = frame_buffer_predicate (frame);
-
-  /* Consider buffers that have been seen in the selected frame
-     before other buffers.  */
-
-  tem = frame_buffer_list (frame);
-  add_ons = Qnil;
-  while (CONSP (tem))
+  /* Consider buffers that have been seen in the frame first.  */
+  tail = XFRAME (frame)->buffer_list;
+  for (; CONSP (tail); tail = XCDR (tail))
     {
-      if (BUFFERP (XCAR (tem)))
-       add_ons = Fcons (Fcons (Qnil, XCAR (tem)), add_ons);
-      tem = XCDR (tem);
+      buf = XCAR (tail);
+      if (BUFFERP (buf) && !EQ (buf, buffer)
+         && !NILP (BVAR (XBUFFER (buf), name))
+         && (SREF (BVAR (XBUFFER (buf), name), 0) != ' ')
+         /* If the frame has a buffer_predicate, disregard buffers that
+            don't fit the predicate.  */
+         && (NILP (pred) || !NILP (call1 (pred, buf))))
+       {
+         if (!NILP (visible_ok)
+             || NILP (Fget_buffer_window (buf, Qvisible)))
+           return buf;
+         else if (NILP (notsogood))
+           notsogood = buf;
+       }
     }
-  tail = nconc2 (Fnreverse (add_ons), tail);
 
+  /* Consider alist of all buffers next.  */
+  tail = Vbuffer_alist;
   for (; CONSP (tail); tail = XCDR (tail))
     {
       buf = Fcdr (XCAR (tail));
-      if (EQ (buf, buffer))
-       continue;
-      if (NILP (buf))
-       continue;
-      if (NILP (BVAR (XBUFFER (buf), name)))
-       continue;
-      if (SREF (BVAR (XBUFFER (buf), name), 0) == ' ')
-       continue;
-      /* If the selected frame has a buffer_predicate,
-        disregard buffers that don't fit the predicate.  */
-      if (!NILP (pred))
+      if (BUFFERP (buf) && !EQ (buf, buffer)
+         && !NILP (BVAR (XBUFFER (buf), name))
+         && (SREF (BVAR (XBUFFER (buf), name), 0) != ' ')
+         /* If the frame has a buffer_predicate, disregard buffers that
+            don't fit the predicate.  */
+         && (NILP (pred) || !NILP (call1 (pred, buf))))
        {
-         tem = call1 (pred, buf);
-         if (NILP (tem))
-           continue;
+         if (!NILP (visible_ok)
+             || NILP (Fget_buffer_window (buf, Qvisible)))
+           return buf;
+         else if (NILP (notsogood))
+           notsogood = buf;
        }
+    }
 
-      if (NILP (visible_ok))
-       tem = Fget_buffer_window (buf, Qvisible);
-      else
-       tem = Qnil;
-      if (NILP (tem))
-       return buf;
-      if (NILP (notsogood))
-       notsogood = buf;
-    }
   if (!NILP (notsogood))
     return notsogood;
+  else
+    {
+      buf = Fget_buffer (build_string ("*scratch*"));
+      if (NILP (buf))
+       {
+         buf = Fget_buffer_create (build_string ("*scratch*"));
+         Fset_buffer_major_mode (buf);
+       }
+      return buf;
+    }
+}
+
+/* The following function is a safe variant of Fother_buffer: It doesn't
+   pay attention to any frame-local buffer lists, doesn't care about
+   visibility of buffers, and doesn't evaluate any frame predicates.  */
+
+Lisp_Object
+other_buffer_safely (Lisp_Object buffer)
+{
+  Lisp_Object Fset_buffer_major_mode (Lisp_Object buffer);
+  Lisp_Object tail, buf;
+
+  tail = Vbuffer_alist;
+  for (; CONSP (tail); tail = XCDR (tail))
+    {
+      buf = Fcdr (XCAR (tail));
+      if (BUFFERP (buf) && !EQ (buf, buffer)
+         && !NILP (BVAR (XBUFFER (buf), name))
+         && (SREF (BVAR (XBUFFER (buf), name), 0) != ' '))
+       return buf;
+    }
+
   buf = Fget_buffer (build_string ("*scratch*"));
   if (NILP (buf))
     {
       buf = Fget_buffer_create (build_string ("*scratch*"));
       Fset_buffer_major_mode (buf);
     }
+
   return buf;
 }
 
@@ -1509,13 +1556,20 @@
   if (NILP (BVAR (b, name)))
     return Qnil;
 
+  /* These may run Lisp code and into infinite loops (if someone
+     insisted on circular lists) so allow quitting here.  */
+  replace_buffer_in_windows (buffer);
+  frames_discard_buffer (buffer);
+
   clear_charpos_cache (b);
 
   tem = Vinhibit_quit;
   Vinhibit_quit = Qt;
-  replace_buffer_in_all_windows (buffer);
+  /* Remove the buffer from the list of all buffers.  */
   Vbuffer_alist = Fdelq (Frassq (buffer, Vbuffer_alist), Vbuffer_alist);
-  frames_discard_buffer (buffer);
+  /* If replace_buffer_in_windows didn't do its job correctly fix that
+     now.  */
+  replace_buffer_in_windows_safely (buffer);
   Vinhibit_quit = tem;
 
   /* Delete any auto-save file, if we saved it in this session.
@@ -1589,83 +1643,103 @@
   UNBLOCK_INPUT;
   BVAR (b, undo_list) = Qnil;
 
+  /* Run buffer-list-update-hook.  */
+  if (!NILP (Vrun_hooks))
+    call1 (Vrun_hooks, Qbuffer_list_update_hook);
+
   return Qt;
 }
 
-/* Move the assoc for buffer BUF to the front of buffer-alist.  Since
-   we do this each time BUF is selected visibly, the more recently
-   selected buffers are always closer to the front of the list.  This
-   means that other_buffer is more likely to choose a relevant buffer.  */
+/* Move association for BUFFER to the front of buffer (a)lists.  Since
+   we do this each time BUFFER is selected visibly, the more recently
+   selected buffers are always closer to the front of those lists.  This
+   means that other_buffer is more likely to choose a relevant buffer.
+
+   Note that this moves BUFFER to the front of the buffer lists of the
+   selected frame even if BUFFER is not shown there.  If BUFFER is not
+   shown in the selected frame, consider the present behavior a feature.
+   `select-window' gets this right since it shows BUFFER in the selected
+   window when calling us.  */
 
 void
-record_buffer (Lisp_Object buf)
-{
-  register Lisp_Object list, prev;
-  Lisp_Object frame;
-  frame = selected_frame;
-
-  prev = Qnil;
-  for (list = Vbuffer_alist; CONSP (list); list = XCDR (list))
-    {
-      if (EQ (XCDR (XCAR (list)), buf))
-       break;
-      prev = list;
-    }
-
-  /* Effectively do Vbuffer_alist = Fdelq (list, Vbuffer_alist);
-     we cannot use Fdelq itself here because it allows quitting.  */
-
-  if (NILP (prev))
-    Vbuffer_alist = XCDR (Vbuffer_alist);
-  else
-    XSETCDR (prev, XCDR (XCDR (prev)));
-
-  XSETCDR (list, Vbuffer_alist);
-  Vbuffer_alist = list;
-
-  /* Effectively do a delq on buried_buffer_list.  */
-
-  prev = Qnil;
-  for (list = XFRAME (frame)->buried_buffer_list; CONSP (list);
-       list = XCDR (list))
-    {
-      if (EQ (XCAR (list), buf))
-        {
-          if (NILP (prev))
-            XFRAME (frame)->buried_buffer_list = XCDR (list);
-          else
-            XSETCDR (prev, XCDR (XCDR (prev)));
-          break;
-        }
-      prev = list;
-    }
-
-  /* Now move this buffer to the front of frame_buffer_list also.  */
-
-  prev = Qnil;
-  for (list = frame_buffer_list (frame); CONSP (list);
-       list = XCDR (list))
-    {
-      if (EQ (XCAR (list), buf))
-       break;
-      prev = list;
-    }
-
-  /* Effectively do delq.  */
-
-  if (CONSP (list))
-    {
-      if (NILP (prev))
-       set_frame_buffer_list (frame,
-                              XCDR (frame_buffer_list (frame)));
-      else
-       XSETCDR (prev, XCDR (XCDR (prev)));
-
-      XSETCDR (list, frame_buffer_list (frame));
-      set_frame_buffer_list (frame, list);
-    }
-  else
-    set_frame_buffer_list (frame, Fcons (buf, frame_buffer_list (frame)));
+record_buffer (Lisp_Object buffer)
+{
+  Lisp_Object aelt, link, tem;
+  register struct frame *f = XFRAME (selected_frame);
+  register struct window *w = XWINDOW (FRAME_SELECTED_WINDOW (f));
+
+  CHECK_BUFFER (buffer);
+
+  /* Update Vbuffer_alist (we know that it has an entry for BUFFER).
+     Don't allow quitting since this might leave the buffer list in an
+     inconsistent state.  */
+  tem = Vinhibit_quit;
+  Vinhibit_quit = Qt;
+  aelt = Frassq (buffer, Vbuffer_alist);
+  link = Fmemq (aelt, Vbuffer_alist);
+  Vbuffer_alist = Fdelq (aelt, Vbuffer_alist);
+  XSETCDR (link, Vbuffer_alist);
+  Vbuffer_alist = link;
+  Vinhibit_quit = tem;
+
+  /* Update buffer list of selected frame.  */
+  f->buffer_list = Fcons (buffer, Fdelq (buffer, f->buffer_list));
+  f->buried_buffer_list = Fdelq (buffer, f->buried_buffer_list);
+
+  /* Run buffer-list-update-hook.  */
+  if (!NILP (Vrun_hooks))
+    call1 (Vrun_hooks, Qbuffer_list_update_hook);
+}
+
+DEFUN ("record-buffer", Frecord_buffer, Srecord_buffer, 1, 1, 0,
+       doc: /* Move BUFFER to the front of the buffer list.
+Return BUFFER.  */)
+  (Lisp_Object buffer)
+{
+  CHECK_BUFFER (buffer);
+
+  record_buffer (buffer);
+
+  return buffer;
+}
+
+  /* Move BUFFER to the end of the buffer (a)lists.  Do nothing if the
+     buffer is killed.  For the selected frame's buffer list this moves
+     BUFFER to its end even if it was never shown in that frame.  If
+     this happens we have a feature, hence `unrecord-buffer' should be
+     called only when BUFFER was shown in the selected frame.  */
+
+DEFUN ("unrecord-buffer", Funrecord_buffer, Sunrecord_buffer, 1, 1, 0,
+       doc: /* Move BUFFER to the end of the buffer list.
+Return BUFFER.  */)
+  (Lisp_Object buffer)
+{
+  Lisp_Object aelt, link, tem;
+  register struct frame *f = XFRAME (selected_frame);
+
+  CHECK_BUFFER (buffer);
+
+  /* Update Vbuffer_alist (we know that it has an entry for BUFFER).
+     Don't allow quitting since this might leave the buffer list in an
+     inconsistent state.  */
+  tem = Vinhibit_quit;
+  Vinhibit_quit = Qt;
+  aelt = Frassq (buffer, Vbuffer_alist);
+  link = Fmemq (aelt, Vbuffer_alist);
+  Vbuffer_alist = Fdelq (aelt, Vbuffer_alist);
+  XSETCDR (link, Qnil);
+  Vbuffer_alist = nconc2 (Vbuffer_alist, link);
+  Vinhibit_quit = tem;
+
+  /* Update buffer lists of selected frame.  */
+  f->buffer_list = Fdelq (buffer, f->buffer_list);
+  f->buried_buffer_list = Fcons (buffer, Fdelq (buffer, 
f->buried_buffer_list));
+
+  /* Run buffer-list-update-hook.  */
+  if (!NILP (Vrun_hooks))
+    call1 (Vrun_hooks, Qbuffer_list_update_hook);
+
+  return buffer;
 }
 
 DEFUN ("set-buffer-major-mode", Fset_buffer_major_mode, 
Sset_buffer_major_mode, 1, 1, 0,
@@ -1708,86 +1782,6 @@
   return unbind_to (count, Qnil);
 }
 
-/* Switch to buffer BUFFER in the selected window.
-   If NORECORD is non-nil, don't call record_buffer.  */
-
-static Lisp_Object
-switch_to_buffer_1 (Lisp_Object buffer_or_name, Lisp_Object norecord)
-{
-  register Lisp_Object buffer;
-
-  if (NILP (buffer_or_name))
-    buffer = Fother_buffer (Fcurrent_buffer (), Qnil, Qnil);
-  else
-    {
-      buffer = Fget_buffer (buffer_or_name);
-      if (NILP (buffer))
-       {
-         buffer = Fget_buffer_create (buffer_or_name);
-         Fset_buffer_major_mode (buffer);
-       }
-    }
-  Fset_buffer (buffer);
-  if (NILP (norecord))
-    record_buffer (buffer);
-
-  Fset_window_buffer (EQ (selected_window, minibuf_window)
-                     ? Fnext_window (minibuf_window, Qnil, Qnil)
-                     : selected_window,
-                     buffer, Qnil);
-
-  return buffer;
-}
-
-DEFUN ("switch-to-buffer", Fswitch_to_buffer, Sswitch_to_buffer, 1, 2,
-       "(list (read-buffer-to-switch \"Switch to buffer: \"))",
-       doc: /* Make BUFFER-OR-NAME current and display it in selected window.
-BUFFER-OR-NAME may be a buffer, a string \(a buffer name), or
-nil.  Return the buffer switched to.
-
-If BUFFER-OR-NAME is a string and does not identify an existing
-buffer, create a new buffer with that name.  Interactively, if
-`confirm-nonexistent-file-or-buffer' is non-nil, request
-confirmation before creating a new buffer.  If BUFFER-OR-NAME is
-nil, switch to buffer returned by `other-buffer'.
-
-Optional second arg NORECORD non-nil means do not put this buffer
-at the front of the list of recently selected ones.  This
-function returns the buffer it switched to as a Lisp object.
-
-If the selected window is the minibuffer window or dedicated to
-its buffer, use `pop-to-buffer' for displaying the buffer.
-
-WARNING: This is NOT the way to work on another buffer temporarily
-within a Lisp program!  Use `set-buffer' instead.  That avoids
-messing with the window-buffer correspondences.  */)
-  (Lisp_Object buffer_or_name, Lisp_Object norecord)
-{
-  if (EQ (buffer_or_name, Fwindow_buffer (selected_window)))
-    {
-      /* Basically a NOP.  Avoid signalling an error in the case where
-        the selected window is dedicated, or a minibuffer.  */
-
-      /* But do put this buffer at the front of the buffer list, unless
-        that has been inhibited.  Note that even if BUFFER-OR-NAME is
-        at the front of the main buffer-list already, we still want to
-        move it to the front of the frame's buffer list.  */
-      if (NILP (norecord))
-       record_buffer (buffer_or_name);
-      return Fset_buffer (buffer_or_name);
-    }
-  else if (EQ (minibuf_window, selected_window)
-          /* If `dedicated' is neither nil nor t, it means it's
-             dedicatedness can be overridden by an explicit request
-             such as a call to switch-to-buffer.  */
-          || EQ (Fwindow_dedicated_p (selected_window), Qt))
-    /* We can't use the selected window so let `pop-to-buffer' try some
-       other window. */
-    return call3 (intern ("pop-to-buffer"), buffer_or_name, Qnil, norecord);
-  else
-    return switch_to_buffer_1 (buffer_or_name, norecord);
-}
-
 DEFUN ("current-buffer", Fcurrent_buffer, Scurrent_buffer, 0, 0, 0,
        doc: /* Return the current buffer as a Lisp object.  */)
   (void)
@@ -1937,70 +1931,6 @@
     xsignal1 (Qbuffer_read_only, Fcurrent_buffer ());
   return Qnil;
 }
-
-extern Lisp_Object Qdelete_window;
-
-DEFUN ("bury-buffer", Fbury_buffer, Sbury_buffer, 0, 1, "",
-       doc: /* Put BUFFER-OR-NAME at the end of the list of all buffers.
-There it is the least likely candidate for `other-buffer' to return;
-thus, the least likely buffer for \\[switch-to-buffer] to select by
-default.
-
-The argument may be a buffer name or an actual buffer object.  If
-BUFFER-OR-NAME is nil or omitted, bury the current buffer and remove it
-from the selected window if it is displayed there.  If the selected
-window is dedicated to its buffer, delete that window if there are other
-windows on the same frame.  If the selected window is the only window on
-its frame, iconify that frame.  */)
-  (register Lisp_Object buffer_or_name)
-{
-  Lisp_Object buffer;
-
-  /* Figure out what buffer we're going to bury.  */
-  if (NILP (buffer_or_name))
-    {
-      Lisp_Object tem;
-      XSETBUFFER (buffer, current_buffer);
-
-      tem = Fwindow_buffer (selected_window);
-      /* If we're burying the current buffer, unshow it.  */
-      if (EQ (buffer, tem))
-       {
-         if (NILP (Fwindow_dedicated_p (selected_window)))
-           Fswitch_to_buffer (Fother_buffer (buffer, Qnil, Qnil), Qnil);
-         else if (NILP (XWINDOW (selected_window)->parent))
-           Ficonify_frame (Fwindow_frame (selected_window));
-         else
-           call1 (Qdelete_window, selected_window);
-       }
-    }
-  else
-    {
-      buffer = Fget_buffer (buffer_or_name);
-      if (NILP (buffer))
-       nsberror (buffer_or_name);
-    }
-
-  /* Move buffer to the end of the buffer list.  Do nothing if the
-     buffer is killed.  */
-  if (!NILP (BVAR (XBUFFER (buffer), name)))
-    {
-      Lisp_Object aelt, list;
-
-      aelt = Frassq (buffer, Vbuffer_alist);
-      list = Fmemq (aelt, Vbuffer_alist);
-      Vbuffer_alist = Fdelq (aelt, Vbuffer_alist);
-      XSETCDR (list, Qnil);
-      Vbuffer_alist = nconc2 (Vbuffer_alist, list);
-
-      XFRAME (selected_frame)->buffer_list
-        = Fdelq (buffer, XFRAME (selected_frame)->buffer_list);
-      XFRAME (selected_frame)->buried_buffer_list
-        = Fcons (buffer, Fdelq (buffer, XFRAME 
(selected_frame)->buried_buffer_list));
-    }
-
-  return Qnil;
-}
 
 DEFUN ("erase-buffer", Ferase_buffer, Serase_buffer, 0, 0, "*",
        doc: /* Delete the entire contents of the current buffer.
@@ -6101,6 +6031,15 @@
   Qchange_major_mode_hook = intern_c_string ("change-major-mode-hook");
   staticpro (&Qchange_major_mode_hook);
 
+  DEFVAR_LISP ("buffer-list-update-hook", Vbuffer_list_update_hook,
+              doc: /* Hook run when the buffer list changes.
+Functions running this hook are `get-buffer-create',
+`make-indirect-buffer', `rename-buffer', `kill-buffer',
+`record-buffer' and `unrecord-buffer'.  */);
+  Vbuffer_list_update_hook = Qnil;
+  Qbuffer_list_update_hook = intern_c_string ("buffer-list-update-hook");
+  staticpro (&Qbuffer_list_update_hook);
+
   defsubr (&Sbuffer_live_p);
   defsubr (&Sbuffer_list);
   defsubr (&Sget_buffer);
@@ -6122,12 +6061,12 @@
   defsubr (&Sother_buffer);
   defsubr (&Sbuffer_enable_undo);
   defsubr (&Skill_buffer);
+  defsubr (&Srecord_buffer);
+  defsubr (&Sunrecord_buffer);
   defsubr (&Sset_buffer_major_mode);
-  defsubr (&Sswitch_to_buffer);
   defsubr (&Scurrent_buffer);
   defsubr (&Sset_buffer);
   defsubr (&Sbarf_if_buffer_read_only);
-  defsubr (&Sbury_buffer);
   defsubr (&Serase_buffer);
   defsubr (&Sbuffer_swap_text);
   defsubr (&Sset_buffer_multibyte);

=== modified file 'src/lisp.h'
--- a/src/lisp.h        2011-06-06 19:43:39 +0000
+++ b/src/lisp.h        2011-06-11 09:50:37 +0000
@@ -3011,6 +3011,7 @@
 EXFUN (Fbarf_if_buffer_read_only, 0);
 EXFUN (Fcurrent_buffer, 0);
 EXFUN (Fother_buffer, 3);
+extern Lisp_Object other_buffer_safely (Lisp_Object);
 EXFUN (Foverlay_get, 2);
 EXFUN (Fbuffer_modified_p, 1);
 EXFUN (Fset_buffer_modified_p, 1);

=== modified file 'src/window.c'
--- a/src/window.c      2011-06-10 20:05:21 +0000
+++ b/src/window.c      2011-06-11 09:50:37 +0000
@@ -50,9 +50,9 @@
 #include "nsterm.h"
 #endif
 
-Lisp_Object Qwindowp, Qwindow_live_p, Qdelete_window;
+Lisp_Object Qwindowp, Qwindow_live_p;
 static Lisp_Object Qwindow_configuration_p, Qrecord_window_buffer;
-static Lisp_Object Qwindow_deletable_p, Qdisplay_buffer;
+static Lisp_Object Qwindow_deletable_p, Qdelete_window, Qdisplay_buffer;
 static Lisp_Object Qreplace_buffer_in_windows, Qget_mru_window;
 static Lisp_Object Qresize_root_window, Qresize_root_window_vertically;
 static Lisp_Object Qscroll_up, Qscroll_down, Qscroll_command;
@@ -310,6 +310,8 @@
   return selected_window;
 }
 
+int window_select_count;
+
 /* If select_window is called with inhibit_point_swap non-zero it will
    not store point of the old selected window's buffer back into that
    window's pointm slot.  This is needed by Fset_window_configuration to
@@ -2210,35 +2212,32 @@
 
 DEFUN ("next-window", Fnext_window, Snext_window, 0, 3, 0,
        doc: /* Return window following WINDOW in cyclic ordering of windows.
-WINDOW defaults to the selected window. The optional arguments
-MINIBUF and ALL-FRAMES specify the set of windows to consider.
-
-MINIBUF t means consider the minibuffer window even if the
-minibuffer is not active.  MINIBUF nil or omitted means consider
-the minibuffer window only if the minibuffer is active.  Any
-other value means do not consider the minibuffer window even if
-the minibuffer is active.
-
-Several frames may share a single minibuffer; if the minibuffer
-is active, all windows on all frames that share that minibuffer
-are considered too.  Therefore, if you are using a separate
-minibuffer frame and the minibuffer is active and MINIBUF says it
-counts, `next-window' considers the windows in the frame from
-which you entered the minibuffer, as well as the minibuffer
-window.
-
-ALL-FRAMES nil or omitted means consider all windows on WINDOW's
- frame, plus the minibuffer window if specified by the MINIBUF
- argument, see above.  If the minibuffer counts, consider all
- windows on all frames that share that minibuffer too.
-ALL-FRAMES t means consider all windows on all existing frames.
-ALL-FRAMES `visible' means consider all windows on all visible
- frames on the current terminal.
-ALL-FRAMES 0 means consider all windows on all visible and
- iconified frames on the current terminal.
-ALL-FRAMES a frame means consider all windows on that frame only.
+WINDOW must be a live window and defaults to the selected one. The
+optional arguments MINIBUF and ALL-FRAMES specify the set of windows to
+consider.
+
+MINIBUF nil or omitted means consider the minibuffer window only if the
+minibuffer is active.  MINIBUF t means consider the minibuffer window
+even if the minibuffer is not active.  Any other value means do not
+consider the minibuffer window even if the minibuffer is active.
+
+ALL-FRAMES nil or omitted means consider all windows on WINDOW's frame,
+plus the minibuffer window if specified by the MINIBUF argument.  If the
+minibuffer counts, consider all windows on all frames that share that
+minibuffer too.  The following non-nil values of ALL-FRAMES have special
+meanings:
+
+- t means consider all windows on all existing frames.
+
+- `visible' means consider all windows on all visible frames.
+
+- 0 (the number zero) means consider all windows on all visible and
+  iconified frames.
+
+- A frame means consider all windows on that frame only.
+
 Anything else means consider all windows on WINDOW's frame and no
- others.
+others.
 
 If you use consistent values for MINIBUF and ALL-FRAMES, you can use
 `next-window' to iterate through the entire cycle of acceptable
@@ -2252,9 +2251,32 @@
 
 DEFUN ("previous-window", Fprevious_window, Sprevious_window, 0, 3, 0,
        doc: /* Return window preceding WINDOW in cyclic ordering of windows.
-WINDOW defaults to the selected window. The optional arguments
-MINIBUF and ALL-FRAMES specify the set of windows to consider.
-For the precise meaning of these arguments see `next-window'.
+WINDOW must be a live window and defaults to the selected one.  The
+optional arguments MINIBUF and ALL-FRAMES specify the set of windows to
+consider.
+
+MINIBUF nil or omitted means consider the minibuffer window only if the
+minibuffer is active.  MINIBUF t means consider the minibuffer window
+even if the minibuffer is not active.  Any other value means do not
+consider the minibuffer window even if the minibuffer is active.
+
+ALL-FRAMES nil or omitted means consider all windows on WINDOW's frame,
+plus the minibuffer window if specified by the MINIBUF argument.  If the
+minibuffer counts, consider all windows on all frames that share that
+minibuffer too.  The following non-nil values of ALL-FRAMES have special
+meanings:
+
+- t means consider all windows on all existing frames.
+
+- `visible' means consider all windows on all visible frames.
+
+- 0 (the number zero) means consider all windows on all visible and
+  iconified frames.
+
+- A frame means consider all windows on that frame only.
+
+Anything else means consider all windows on WINDOW's frame and no
+others.
 
 If you use consistent values for MINIBUF and ALL-FRAMES, you can
 use `previous-window' to iterate through the entire cycle of
@@ -2267,37 +2289,6 @@
 }
 
 
-DEFUN ("other-window", Fother_window, Sother_window, 1, 2, "p",
-       doc: /* Select another window in cyclic ordering of windows.
-COUNT specifies the number of windows to skip, starting with the
-selected window, before making the selection.  If COUNT is
-positive, skip COUNT windows forwards.  If COUNT is negative,
-skip -COUNT windows backwards.  COUNT zero means do not skip any
-window, so select the selected window.  In an interactive call,
-COUNT is the numeric prefix argument.  Return nil.
-
-This function uses `next-window' for finding the window to select.
-The argument ALL-FRAMES has the same meaning as in `next-window',
-but the MINIBUF argument of `next-window' is always effectively
-nil.  */)
-  (Lisp_Object count, Lisp_Object all_frames)
-{
-  Lisp_Object window;
-  int i;
-
-  CHECK_NUMBER (count);
-  window = selected_window;
-
-  for (i = XINT (count); i > 0; --i)
-    window = Fnext_window (window, Qnil, all_frames);
-  for (; i < 0; ++i)
-    window = Fprevious_window (window, Qnil, all_frames);
-
-  Fselect_window (window, Qnil);
-  return Qnil;
-}
-
-
 /* Return a list of windows in cyclic ordering.  Arguments are like
    for `next-window'.  */
 
@@ -2397,10 +2388,9 @@
 enum window_loop
 {
   WINDOW_LOOP_UNUSED,
-  GET_BUFFER_WINDOW,           /* Arg is buffer */
-  DELETE_BUFFER_WINDOWS,       /* Arg is buffer */
-  UNSHOW_BUFFER,               /* Arg is buffer */
-  REDISPLAY_BUFFER_WINDOWS,    /* Arg is buffer */
+  GET_BUFFER_WINDOW,               /* Arg is buffer */
+  REPLACE_BUFFER_IN_WINDOWS_SAFELY, /* Arg is buffer */
+  REDISPLAY_BUFFER_WINDOWS,        /* Arg is buffer */
   CHECK_ALL_WINDOWS
 };
 
@@ -2408,6 +2398,7 @@
 window_loop (enum window_loop type, Lisp_Object obj, int mini, Lisp_Object 
frames)
 {
   Lisp_Object window, windows, best_window, frame_arg;
+  int frame_best_window_flag = 0;
   struct frame *f;
   struct gcpro gcpro1;
 
@@ -2457,110 +2448,51 @@
         is visible, since Fwindow_list skips non-visible frames if
         that is desired, under the control of frame_arg.  */
       if (!MINI_WINDOW_P (w)
-         /* For UNSHOW_BUFFER, we must always consider all windows.  */
-         || type == UNSHOW_BUFFER
+         /* For REPLACE_BUFFER_IN_WINDOWS_SAFELY, we must always
+            consider all windows.  */
+         || type == REPLACE_BUFFER_IN_WINDOWS_SAFELY
          || (mini && minibuf_level > 0))
        switch (type)
          {
          case GET_BUFFER_WINDOW:
            if (EQ (w->buffer, obj)
-               /* Don't find any minibuffer window
-                  except the one that is currently in use.  */
-               && (MINI_WINDOW_P (w)
-                   ? EQ (window, minibuf_window)
-                   : 1))
+               /* Don't find any minibuffer window except the one that
+                  is currently in use.  */
+               && (MINI_WINDOW_P (w) ? EQ (window, minibuf_window) : 1))
              {
-               if (NILP (best_window))
-                 best_window = window;
-               else if (EQ (window, selected_window))
-                 /* Prefer to return selected-window.  */
+               if (EQ (window, selected_window))
+                 /* Preferably return the selected window.  */
                  RETURN_UNGCPRO (window);
-               else if (EQ (Fwindow_frame (window), selected_frame))
-                 /* Prefer windows on the current frame.  */
+               else if (EQ (XWINDOW (window)->frame, selected_frame)
+                        && !frame_best_window_flag)
+                 /* Prefer windows on the current frame (but don't
+                    choose another one if we have one already).  */
+                 {
+                   best_window = window;
+                   frame_best_window_flag = 1;
+                 }
+               else if (NILP (best_window))
                  best_window = window;
              }
            break;
 
-         case DELETE_BUFFER_WINDOWS:
-           if (EQ (w->buffer, obj))
-             {
-               struct frame *fr = XFRAME (WINDOW_FRAME (w));
-
-               /* If this window is dedicated, and in a frame of its own,
-                  kill the frame.  */
-               if (EQ (window, FRAME_ROOT_WINDOW (fr))
-                   && !NILP (w->dedicated)
-                   && other_visible_frames (fr))
-                 {
-                   /* Skip the other windows on this frame.
-                      There might be one, the minibuffer!  */
-                   while (CONSP (XCDR (windows))
-                          && EQ (XWINDOW (XCAR (windows))->frame,
-                                 XWINDOW (XCAR (XCDR (windows)))->frame))
-                     windows = XCDR (windows);
-
-                   /* Now we can safely delete the frame.  */
-                   delete_frame (w->frame, Qnil);
-                 }
-               else if (NILP (w->parent))
-                 {
-                   /* If we're deleting the buffer displayed in the
-                      only window on the frame, find a new buffer to
-                      display there.  */
-                   Lisp_Object buffer;
-                   buffer = Fother_buffer (obj, Qnil, w->frame);
-                   /* Reset dedicated state of window.  */
-                   w->dedicated = Qnil;
-                   Fset_window_buffer (window, buffer, Qnil);
-                   if (EQ (window, selected_window))
-                     Fset_buffer (w->buffer);
-                 }
-               else
-                 call1 (Qdelete_window, window);
-             }
-           break;
-
-         case UNSHOW_BUFFER:
-           if (EQ (w->buffer, obj))
-             {
-               Lisp_Object buffer;
-               struct frame *fr = XFRAME (w->frame);
-
-               /* Find another buffer to show in this window.  */
-               buffer = Fother_buffer (obj, Qnil, w->frame);
-
-               /* If this window is dedicated, and in a frame of its own,
-                  kill the frame.  */
-               if (EQ (window, FRAME_ROOT_WINDOW (fr))
-                   && !NILP (w->dedicated)
-                   && other_visible_frames (fr))
-                 {
-                   /* Skip the other windows on this frame.
-                      There might be one, the minibuffer!  */
-                   while (CONSP (XCDR (windows))
-                          && EQ (XWINDOW (XCAR (windows))->frame,
-                                 XWINDOW (XCAR (XCDR (windows)))->frame))
-                     windows = XCDR (windows);
-
-                   /* Now we can safely delete the frame.  */
-                   delete_frame (w->frame, Qnil);
-                 }
-               else if (!NILP (w->dedicated) && !NILP (w->parent))
-                 {
-                   Lisp_Object window_to_delete;
-                   XSETWINDOW (window_to_delete, w);
-                   /* If this window is dedicated and not the only window
-                      in its frame, then kill it.  */
-                       call1 (Qdelete_window, window_to_delete);
-                 }
-               else
-                 {
-                   /* Otherwise show a different buffer in the window.  */
-                   w->dedicated = Qnil;
-                   Fset_window_buffer (window, buffer, Qnil);
-                   if (EQ (window, selected_window))
-                     Fset_buffer (w->buffer);
-                 }
+         case REPLACE_BUFFER_IN_WINDOWS_SAFELY:
+           /* We could simply check whether the buffer shown by window
+              is live, and show another buffer in case it isn't.  */
+           if (EQ (w->buffer, obj))
+             {
+               /* Undedicate WINDOW.  */
+               w->dedicated = Qnil;
+               /* Make WINDOW show the buffer returned by
+                  other_buffer_safely, don't run any hooks.  */
+               set_window_buffer
+                 (window, other_buffer_safely (w->buffer), 0, 0);
+               /* If WINDOW is the selected window, make its buffer
+                  current.  But do so only if the window shows the
+                  current buffer (Bug#6454).  */
+               if (EQ (window, selected_window)
+                   && XBUFFER (w->buffer) == current_buffer)
+                 Fset_buffer (w->buffer);
              }
            break;
 
@@ -2875,85 +2807,26 @@
 }
 
 
-DEFUN ("delete-windows-on", Fdelete_windows_on, Sdelete_windows_on,
-       0, 2, "bDelete windows on (buffer): ",
-       doc: /* Delete all windows showing BUFFER-OR-NAME.
-BUFFER-OR-NAME may be a buffer or the name of an existing buffer and
-defaults to the current buffer.
-
-Optional second argument FRAME controls which frames are affected.
-If optional argument FRAME is `visible', search all visible frames.
-If FRAME is 0, search all visible and iconified frames.
-If FRAME is nil, search all frames.
-If FRAME is t, search only the selected frame.
-If FRAME is a frame, search only that frame.
-When a window showing BUFFER-OR-NAME is dedicated and the only window of
-its frame, that frame is deleted when there are other frames left.  */)
-  (Lisp_Object buffer_or_name, Lisp_Object frame)
-{
-  Lisp_Object buffer;
-
-  /* FRAME uses t and nil to mean the opposite of what window_loop
-     expects.  */
-  if (NILP (frame))
-    frame = Qt;
-  else if (EQ (frame, Qt))
-    frame = Qnil;
-
-  if (NILP (buffer_or_name))
-    buffer = Fcurrent_buffer ();
-  else
-    {
-      buffer = Fget_buffer (buffer_or_name);
-      CHECK_BUFFER (buffer);
-    }
-
-  window_loop (DELETE_BUFFER_WINDOWS, buffer, 0, frame);
-
-  return Qnil;
-}
-
-DEFUN ("replace-buffer-in-windows", Freplace_buffer_in_windows,
-       Sreplace_buffer_in_windows,
-       0, 1, "bReplace buffer in windows: ",
-       doc: /* Replace BUFFER-OR-NAME with some other buffer in all windows 
showing it.
-BUFFER-OR-NAME may be a buffer or the name of an existing buffer and
-defaults to the current buffer.
-
-When a window showing BUFFER-OR-NAME is dedicated that window is
-deleted.  If that window is the only window on its frame, that frame is
-deleted too when there are other frames left.  If there are no other
-frames left, some other buffer is displayed in that window.  */)
-  (Lisp_Object buffer_or_name)
-{
-  Lisp_Object buffer;
-
-  if (NILP (buffer_or_name))
-    buffer = Fcurrent_buffer ();
-  else
-    {
-      buffer = Fget_buffer (buffer_or_name);
-      CHECK_BUFFER (buffer);
-    }
-
-  window_loop (UNSHOW_BUFFER, buffer, 0, Qt);
-
-  return Qnil;
-}
-
-/* Replace BUFFER with some other buffer in all windows
-   of all frames, even those on other keyboards.  */
-
-void
-replace_buffer_in_all_windows (Lisp_Object buffer)
+void
+replace_buffer_in_windows (Lisp_Object buffer)
+{
+  call1 (Qreplace_buffer_in_windows, buffer);
+}
+
+
+/* Safely replace BUFFER with some other buffer in all windows of all
+   frames, even those on other keyboards.  */
+
+void
+replace_buffer_in_windows_safely (Lisp_Object buffer)
 {
   Lisp_Object tail, frame;
 
-  /* A single call to window_loop won't do the job
-     because it only considers frames on the current keyboard.
-     So loop manually over frames, and handle each one.  */
+  /* A single call to window_loop won't do the job because it only
+     considers frames on the current keyboard.  So loop manually over
+     frames, and handle each one.  */
   FOR_EACH_FRAME (tail, frame)
-    window_loop (UNSHOW_BUFFER, buffer, 1, frame);
+    window_loop (REPLACE_BUFFER_IN_WINDOWS_SAFELY, buffer, 1, frame);
 }
 
 /* If *ROWS or *COLS are too small a size for FRAME, set them to the
@@ -3014,8 +2887,6 @@
   return 1;
 }
 
-int window_select_count;
-
 static Lisp_Object Fset_window_margins (Lisp_Object, Lisp_Object, Lisp_Object);
 static Lisp_Object Fset_window_fringes (Lisp_Object, Lisp_Object, Lisp_Object,
                                        Lisp_Object);
@@ -3023,6 +2894,8 @@
                                            Lisp_Object, Lisp_Object);
 static Lisp_Object Fset_window_vscroll (Lisp_Object, Lisp_Object, Lisp_Object);
 
+/* The following three routines are needed for running a window's
+   configuration change hook.  */
 static void
 run_funs (Lisp_Object funs)
 {
@@ -3031,8 +2904,19 @@
       call0 (XCAR (funs));
 }
 
-static Lisp_Object select_window_norecord (Lisp_Object window);
-static Lisp_Object select_frame_norecord (Lisp_Object frame);
+static Lisp_Object
+select_window_norecord (Lisp_Object window)
+{
+  return WINDOW_LIVE_P (window)
+    ? Fselect_window (window, Qt) : selected_window;
+}
+
+static Lisp_Object
+select_frame_norecord (Lisp_Object frame)
+{
+  return FRAME_LIVE_P (XFRAME (frame))
+    ? Fselect_frame (frame, Qt) : selected_frame;
+}
 
 void
 run_window_configuration_change_hook (struct frame *f)
@@ -3209,11 +3093,13 @@
 
 DEFUN ("set-window-buffer", Fset_window_buffer, Sset_window_buffer, 2, 3, 0,
        doc: /* Make WINDOW display BUFFER-OR-NAME as its contents.
-WINDOW defaults to the selected window.  BUFFER-OR-NAME must be a buffer
-or the name of an existing buffer.  Optional third argument KEEP-MARGINS
-non-nil means that WINDOW's current display margins, fringe widths, and
-scroll bar settings are preserved; the default is to reset these from
-the local settings for BUFFER-OR-NAME or the frame defaults.  Return nil.
+WINDOW has to be a live window and defaults to the selected one.
+BUFFER-OR-NAME must be a buffer or the name of an existing buffer.
+
+Optional third argument KEEP-MARGINS non-nil means that WINDOW's current
+display margins, fringe widths, and scroll bar settings are preserved;
+the default is to reset these from the local settings for BUFFER-OR-NAME
+or the frame defaults.  Return nil.
 
 This function throws an error when WINDOW is strongly dedicated to its
 buffer (that is `window-dedicated-p' returns t for WINDOW) and does not
@@ -3238,33 +3124,27 @@
   else if (!EQ (tem, Qt))
     /* w->buffer is t when the window is first being set up.  */
     {
-      if (EQ (tem, buffer))
-       return Qnil;
-      else if (EQ (w->dedicated, Qt))
-       error ("Window is dedicated to `%s'", SDATA (BVAR (XBUFFER (tem), 
name)));
-      else
-       w->dedicated = Qnil;
+      if (!EQ (tem, buffer))
+       {
+         if (EQ (w->dedicated, Qt))
+           /* WINDOW is strongly dedicated to its buffer, signal an
+              error.  */
+           error ("Window is dedicated to `%s'", SDATA (BVAR (XBUFFER (tem), 
name)));
+         else
+           /* WINDOW is weakly dedicated to its buffer, reset
+              dedicatedness.  */
+           w->dedicated = Qnil;
+
+         call1 (Qrecord_window_buffer, window);
+       }
 
       unshow_buffer (w);
     }
 
   set_window_buffer (window, buffer, 1, !NILP (keep_margins));
+
   return Qnil;
 }
-
-static Lisp_Object
-select_window_norecord (Lisp_Object window)
-{
-  return WINDOW_LIVE_P (window)
-    ? Fselect_window (window, Qt) : selected_window;
-}
-
-static Lisp_Object
-select_frame_norecord (Lisp_Object frame)
-{
-  return FRAME_LIVE_P (XFRAME (frame))
-    ? Fselect_frame (frame, Qt) : selected_frame;
-}
 
 static Lisp_Object
 display_buffer (Lisp_Object buffer, Lisp_Object not_this_window_p, Lisp_Object 
override_frame)
@@ -3799,7 +3679,7 @@
 DEFUN ("split-window-internal", Fsplit_window_internal, 
Ssplit_window_internal, 4, 4, 0,
        doc: /* Split window OLD.
 Second argument TOTAL-SIZE specifies the number of lines or columns of the
-new window.  In any case TOTAL-SIZE must be a positive integer
+new window.  In any case TOTAL-SIZE must be a positive integer.
 
 Third argument SIDE nil (or `below') specifies that the new window shall
 be located below WINDOW.  SIDE `above' means the new window shall be
@@ -4280,7 +4160,6 @@
   else error ("Failed to resize minibuffer window");
 }
 
-
 /* Mark window cursors off for all windows in the window tree rooted
    at W by setting their phys_cursor_on_p flag to zero.  Called from
    xterm.c, e.g. when a frame is cleared and thereby all cursors on
@@ -5337,7 +5216,6 @@
   return Qnil;
 }
 
-
 DEFUN ("window-text-height", Fwindow_text_height, Swindow_text_height,
        0, 1, 0,
        doc: /* Return the height in lines of the text display area of WINDOW.
@@ -6865,10 +6743,7 @@
   defsubr (&Sset_window_display_table);
   defsubr (&Snext_window);
   defsubr (&Sprevious_window);
-  defsubr (&Sother_window);
   defsubr (&Sget_buffer_window);
-  defsubr (&Sdelete_windows_on);
-  defsubr (&Sreplace_buffer_in_windows);
   defsubr (&Sdelete_other_windows_internal);
   defsubr (&Sdelete_window_internal);
   defsubr (&Sresize_mini_window_internal);
@@ -6917,7 +6792,6 @@
 void
 keys_of_window (void)
 {
-  initial_define_key (control_x_map, 'o', "other-window");
   initial_define_key (control_x_map, '<', "scroll-left");
   initial_define_key (control_x_map, '>', "scroll-right");
 

=== modified file 'src/window.h'
--- a/src/window.h      2011-06-10 20:05:21 +0000
+++ b/src/window.h      2011-06-11 09:50:37 +0000
@@ -827,6 +827,7 @@
 extern Lisp_Object window_from_coordinates (struct frame *, int, int,
                                             enum window_part *, int);
 EXFUN (Fwindow_dedicated_p, 1);
+extern void resize_frame_windows (struct frame *, int, int);
 extern void delete_all_subwindows (Lisp_Object);
 extern void freeze_window_starts (struct frame *, int);
 extern void grow_mini_window (struct window *, int);
@@ -902,7 +903,6 @@
 extern Lisp_Object Vwindow_list;
 
 EXFUN (Fwindow_buffer, 1);
-EXFUN (Fwindow_frame, 1);
 EXFUN (Fget_buffer_window, 2);
 EXFUN (Fwindow_minibuffer_p, 1);
 EXFUN (Fselected_window, 0);
@@ -918,12 +918,10 @@
 extern int window_body_cols (struct window *w);
 EXFUN (Frecenter, 1);
 extern void temp_output_buffer_show (Lisp_Object);
-extern void replace_buffer_in_all_windows (Lisp_Object);
+extern void replace_buffer_in_windows_safely (Lisp_Object);
 extern void init_window_once (void);
 extern void init_window (void);
 extern void syms_of_window (void);
 extern void keys_of_window (void);
-extern void resize_frame_windows (struct frame *, int, int);
-
 
 #endif /* not WINDOW_H_INCLUDED */


reply via email to

[Prev in Thread] Current Thread [Next in Thread]