;; 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 do-minibuf)
- "Record WINDOW's buffer.
+(defun push-window-buffer-onto-prev (&optional window)
+ "Push entry for WINDOW's buffer onto WINDOW's prev-buffers list.
WINDOW must be a live window and defaults to the selected one.
-If WINDOW is a minibuffer, it will only be recorded if DO-MINIBUF
-is non-nil."
+Any duplicate entries for the buffer in the list are removed."
(let* ((window (window-normalize-window window t))
- (buffer (window-buffer window))
- (entry (assq buffer (window-prev-buffers window))))
+ (buffer (window-buffer window))
+ (w-list (window-prev-buffers window))
+ (entry (assq buffer w-list)))
+ (when entry
+ (setq w-list (assq-delete-all buffer w-list)))
+ (let ((start (window-start window))
+ (point (window-point window)))
+ (setq entry
+ (cons buffer
+ (with-current-buffer buffer
+ (if entry
+ ;; We have an entry, update marker positions.
+ (list (set-marker (nth 1 entry) start)
+ (set-marker (nth 2 entry) point))
+ (list (copy-marker start)
+ (copy-marker
+ ;; Preserve window-point-insertion-type
+ ;; (Bug#12855)
+ point window-point-insertion-type))))))
+ (set-window-prev-buffers window (cons entry w-list)))))
+
+(defun record-window-buffer (&optional window)
+ "Record WINDOW's buffer.
+WINDOW must be a live window and defaults to the selected one."
+ (let* ((window (window-normalize-window window t))
+ (buffer (window-buffer 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)
;; Don't record insignificant buffers.
- (when (or (not (eq (aref (buffer-name buffer) 0) ?\s))
- (and do-minibuf (minibufferp buffer)))
- (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))))
- ;; 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
- ;; Preserve window-point-insertion-type
- ;; (Bug#12855).
- point window-point-insertion-type)))))
- (set-window-prev-buffers
- window (cons entry (window-prev-buffers window)))))
-
+ (when (not (eq (aref (buffer-name buffer) 0) ?\s))
+ (push-window-buffer-onto-prev window)
(run-hooks 'buffer-list-update-hook))))
(defun unrecord-window-buffer (&optional window buffer)
Fset_window_start (dest_window, Fwindow_start (source_window), Qnil);
Fset_window_point (dest_window, Fwindow_point (source_window));
dw->prev_buffers = sw->prev_buffers;
- set_window_buffer (source_window, get_minibuffer (0), 0, 0);
+ set_window_buffer (source_window, nth_minibuffer (0), 0, 0);
sw->prev_buffers = Qnil;
return;
}
if (live_minibuffer_p (dw->contents))
- call2 (Qrecord_window_buffer, dest_window, Qt);
+ call1 (Qpush_window_buffer_onto_prev, dest_window);
if (live_minibuffer_p (sw->contents))
- call2 (Qrecord_window_buffer, source_window, Qt);
-
+ call1 (Qpush_window_buffer_onto_prev, source_window);
acc = merge_c (dw->prev_buffers, sw->prev_buffers, minibuffer_ent_greater);
if (!NILP (acc))
}
dw->prev_buffers = acc;
sw->prev_buffers = Qnil;
- set_window_buffer (source_window, get_minibuffer (0), 0, 0);
+ set_window_buffer (source_window, nth_minibuffer (0), 0, 0);
}
/* If `minibuffer_follows_selected_frame' is t, or we're about to
return Qnil;
innermost_MB = nth_minibuffer (minibuf_level);
+ if (NILP (innermost_MB))
+ emacs_abort ();
FOR_EACH_FRAME (frames, frame)
{
f = XFRAME (frame);
}
minibuf_level++; /* Before calling choose_minibuf_frame. */
+ /* Ensure now that the latest minibuffer has been created, in case
+ anything happens which depends on MINNIBUF_LEVEL and
+ Vminibuffer_list being consistent with eachother. */
+ minibuffer = get_minibuffer (minibuf_level);
/* Choose the minibuffer window and frame, and take action on them. */
}
MB_frame = XWINDOW (XFRAME (selected_frame)->minibuffer_window)->frame;
if (live_minibuffer_p (XWINDOW (minibuf_window)->contents))
- call2 (Qrecord_window_buffer, minibuf_window, Qt);
+ call1 (Qpush_window_buffer_onto_prev, minibuf_window);
record_unwind_protect_void (minibuffer_unwind);
record_unwind_protect (restore_window_configuration,
/* Switch to the minibuffer. */
- minibuffer = get_minibuffer (minibuf_level);
set_minibuffer_mode (minibuffer, minibuf_level);
Fset_buffer (minibuffer);
/* Empty out the minibuffers of all frames, except those frames
where there is an active minibuffer.
Set them to point to ` *Minibuf-0*', which is always empty. */
- empty_minibuf = get_minibuffer (0);
+ empty_minibuf = nth_minibuffer (0);
set_minibuffer_mode (empty_minibuf, 0);
/* Display this minibuffer in the proper window. */
nth_minibuffer (EMACS_INT depth)
{
Lisp_Object tail = Fnthcdr (make_fixnum (depth), Vminibuffer_list);
- if (NILP (tail))
- return Qnil;
- return XCAR (tail);
+ return Fcar (tail);
}
/* Set the major mode of the minibuffer BUF, depending on DEPTH, the
Lisp_Object future_mini_window;
Lisp_Object saved_selected_frame = selected_frame;
Lisp_Object window, frames;
+ Lisp_Object expired_MB = nth_minibuffer (minibuf_level);
struct window *w;
struct frame *f;
+ if (NILP (expired_MB))
+ emacs_abort ();
+
/* Locate the expired minibuffer. */
FOR_EACH_FRAME (frames, exp_MB_frame)
{
{
w = XWINDOW (window);
if (EQ (w->frame, exp_MB_frame)
- && EQ (w->contents, nth_minibuffer (minibuf_level)))
+ && EQ (w->contents, expired_MB))
goto found;
}
}
minibuffer when we reset the relevant variables. Don't depend on
`minibuf_window' here. This could by now be the mini-window of any
frame. */
- Fset_buffer (nth_minibuffer (minibuf_level));
+ Fset_buffer (expired_MB);
minibuf_level--;
/* Restore prompt, etc, from outer minibuffer level. */
staticpro (&Vminibuffer_list);
staticpro (&Vcommand_loop_level_list);
pdumper_do_now_and_after_load (init_minibuf_once_for_pdumper);
+ /* Ensure our inactive minibuffer exists. */
+ get_minibuffer (0);
}
static void
DEFSYM (Qminibuffer_completing_file_name, "minibuffer-completing-file-name");
DEFSYM (Qselect_frame_set_input_focus, "select-frame-set-input-focus");
DEFSYM (Qadd_to_history, "add-to-history");
+ DEFSYM (Qpush_window_buffer_onto_prev, "push-window-buffer-onto-prev");
DEFVAR_LISP ("read-expression-history", Vread_expression_history,
doc: /* A history list for arguments that are Lisp expressions to evaluate.