[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
master 8469894: Fix unclean "can't happen" error handling in read_minibu
From: |
Alan Mackenzie |
Subject: |
master 8469894: Fix unclean "can't happen" error handling in read_minibuf_unwind |
Date: |
Thu, 22 Apr 2021 08:08:46 -0400 (EDT) |
branch: master
commit 846989498b66f94739e78ca274c8d1176c137591
Author: Alan Mackenzie <acm@muc.de>
Commit: Alan Mackenzie <acm@muc.de>
Fix unclean "can't happen" error handling in read_minibuf_unwind
Also fix a bug where, with minibuffer-follows-selected-frame neither nil nor
t, a minibuffer could appear in two frames at the same time.
* src/window.c (Fset_window_configuration): Add a new &optional parameter
DONT-SET-MINIWINDOW, which inhibits the minibuffer from being restored from
the supplied window configuration.
(restore_window_configuration): Enhance to match the above.
* src/minibuf.c (read_minibuf): Enhance the argument list to the
restore_window_configuration calls to match the above. In the main case,
restoring the minibuffer is inhibited.
(read_minibuf_unwind): Should the frame with the expired minibuffer not be
found ("can't happen"), unwind the stacked data nevertheless, rather than
just
exiting.
* src/keyboard.c (read_char_help_form_unwind): Amend a call of
Fset_window_configuration.
* doc/lispref/windows.texi (Window Configurations): Document the new form of
set-window-configuration.
* etc/NEWS (Lisp Changes in Emacs 28.1): Amend the entry for
set-window-configuration.
---
doc/lispref/windows.texi | 10 +++++++---
etc/NEWS | 8 +++++---
src/keyboard.c | 2 +-
src/minibuf.c | 21 ++++++++++-----------
src/window.c | 21 ++++++++++++++-------
5 files changed, 37 insertions(+), 25 deletions(-)
diff --git a/doc/lispref/windows.texi b/doc/lispref/windows.texi
index c32d711..82d2ce4 100644
--- a/doc/lispref/windows.texi
+++ b/doc/lispref/windows.texi
@@ -5877,7 +5877,7 @@ which window parameters (if any) are saved by this
function.
@xref{Window Parameters}.
@end defun
-@defun set-window-configuration configuration &optional dont-set-frame
+@defun set-window-configuration configuration &optional dont-set-frame
dont-set-miniwindow
This function restores the configuration of windows and buffers as
specified by @var{configuration}, for the frame that
@var{configuration} was created for, regardless of whether that frame
@@ -5885,8 +5885,12 @@ is selected or not. The argument @var{configuration}
must be a value
that was previously returned by @code{current-window-configuration}
for that frame. Normally the function also selects the frame which is
recorded in the configuration, but if @var{dont-set-frame} is
-non-@code{nil}, it leaves selected the frame which was current at the
-start of the function.
+non-@code{nil}, it leaves selected the frame which was already
+selected at the start of the function.
+
+Normally the function restores the saved minibuffer (if any), but if
+@var{dont-set-miniwindow} is non-@code{nil}, the minibuffer current
+at the start of the function (if any) remains in the mini-window.
If the frame from which @var{configuration} was saved is dead, all
this function does is to restore the value of the variable
diff --git a/etc/NEWS b/etc/NEWS
index 559ffd6d..e7258f1 100644
--- a/etc/NEWS
+++ b/etc/NEWS
@@ -2674,9 +2674,11 @@ one to another in the init file. The same user option
also controls
whether the function 'read-answer' accepts short answers.
+++
-** 'set-window-configuration' now takes an optional 'dont-set-frame'
-parameter which, when non-nil, instructs the function not to select
-the frame recorded in the configuration.
+** 'set-window-configuration' now takes two optional parameters,
+'dont-set-frame' and 'dont-set-miniwindow'. The first of these, when
+non-nil, instructs the function not to select the frame recorded in
+the configuration. The second prevents the current minibuffer being
+replaced by the one stored in the configuration.
+++
** 'define-globalized-minor-mode' now takes a ':predicate' parameter.
diff --git a/src/keyboard.c b/src/keyboard.c
index 266ebaa..5db45ce 100644
--- a/src/keyboard.c
+++ b/src/keyboard.c
@@ -2121,7 +2121,7 @@ read_char_help_form_unwind (void)
Lisp_Object window_config = XCAR (help_form_saved_window_configs);
help_form_saved_window_configs = XCDR (help_form_saved_window_configs);
if (!NILP (window_config))
- Fset_window_configuration (window_config, Qnil);
+ Fset_window_configuration (window_config, Qnil, Qnil);
}
#define STOP_POLLING \
diff --git a/src/minibuf.c b/src/minibuf.c
index 1a637c8..c4482d7 100644
--- a/src/minibuf.c
+++ b/src/minibuf.c
@@ -660,17 +660,14 @@ read_minibuf (Lisp_Object map, Lisp_Object initial,
Lisp_Object prompt,
record_unwind_protect_void (minibuffer_unwind);
record_unwind_protect (restore_window_configuration,
- Fcons (Qt, Fcurrent_window_configuration (Qnil)));
+ list3 (Fcurrent_window_configuration (Qnil), Qt, Qt));
/* If the minibuffer window is on a different frame, save that
frame's configuration too. */
if (!EQ (mini_frame, selected_frame))
record_unwind_protect (restore_window_configuration,
- Fcons (/* Arrange for the frame later to be
- switched back to the calling
- frame. */
- Qnil,
- Fcurrent_window_configuration (mini_frame)));
+ list3 (Fcurrent_window_configuration (mini_frame),
+ Qnil, Qt));
/* If the minibuffer is on an iconified or invisible frame,
make it visible now. */
@@ -1069,13 +1066,13 @@ read_minibuf_unwind (void)
goto found;
}
}
- return; /* expired minibuffer not found. Maybe we should output an
- error, here. */
+ exp_MB_frame = Qnil; /* "Can't happen." */
found:
- if (!EQ (exp_MB_frame, saved_selected_frame))
+ if (!EQ (exp_MB_frame, saved_selected_frame)
+ && !NILP (exp_MB_frame))
do_switch_frame (exp_MB_frame, 0, 0, Qt); /* This also sets
- minibuff_window */
+ minibuf_window */
/* To keep things predictable, in case it matters, let's be in the
minibuffer when we reset the relevant variables. Don't depend on
@@ -1185,7 +1182,8 @@ read_minibuf_unwind (void)
}
/* Restore the selected frame. */
- if (!EQ (exp_MB_frame, saved_selected_frame))
+ if (!EQ (exp_MB_frame, saved_selected_frame)
+ && !NILP (exp_MB_frame))
do_switch_frame (saved_selected_frame, 0, 0, Qt);
}
@@ -1200,6 +1198,7 @@ minibuffer_unwind (void)
Lisp_Object window;
Lisp_Object entry;
+ if (NILP (exp_MB_frame)) return; /* "Can't happen." */
f = XFRAME (exp_MB_frame);
window = f->minibuffer_window;
w = XWINDOW (window);
diff --git a/src/window.c b/src/window.c
index a22fab2..5134c3d 100644
--- a/src/window.c
+++ b/src/window.c
@@ -6881,19 +6881,22 @@ DEFUN ("window-configuration-frame",
Fwindow_configuration_frame, Swindow_config
}
DEFUN ("set-window-configuration", Fset_window_configuration,
- Sset_window_configuration, 1, 2, 0,
+ Sset_window_configuration, 1, 3, 0,
doc: /* Set the configuration of windows and buffers as specified by
CONFIGURATION.
CONFIGURATION must be a value previously returned
by `current-window-configuration' (which see).
Normally, this function selects the frame of the CONFIGURATION, but if
DONT-SET-FRAME is non-nil, it leaves selected the frame which was
-current at the start of the function.
+current at the start of the function. If DONT-SET-MINIWINDOW is non-nil,
+the mini-window of the frame doesn't get set to the corresponding element
+of CONFIGURATION.
If CONFIGURATION was made from a frame that is now deleted,
only frame-independent values can be restored. In this case,
the return value is nil. Otherwise the value is t. */)
- (Lisp_Object configuration, Lisp_Object dont_set_frame)
+ (Lisp_Object configuration, Lisp_Object dont_set_frame,
+ Lisp_Object dont_set_miniwindow)
{
register struct save_window_data *data;
struct Lisp_Vector *saved_windows;
@@ -7104,8 +7107,10 @@ the return value is nil. Otherwise the value is t. */)
}
}
- if (BUFFERP (p->buffer) && BUFFER_LIVE_P (XBUFFER (p->buffer)))
- /* If saved buffer is alive, install it. */
+ if ((NILP (dont_set_miniwindow) || !MINI_WINDOW_P (w))
+ && BUFFERP (p->buffer) && BUFFER_LIVE_P (XBUFFER (p->buffer)))
+ /* If saved buffer is alive, install it, unless it's a
+ minibuffer we explicitly prohibit. */
{
wset_buffer (w, p->buffer);
w->start_at_line_beg = !NILP (p->start_at_line_beg);
@@ -7258,9 +7263,11 @@ void
restore_window_configuration (Lisp_Object configuration)
{
if (CONSP (configuration))
- Fset_window_configuration (XCDR (configuration), XCAR (configuration));
+ Fset_window_configuration (XCAR (configuration),
+ XCAR (XCDR (configuration)),
+ XCAR (XCDR (XCDR (configuration))));
else
- Fset_window_configuration (configuration, Qnil);
+ Fset_window_configuration (configuration, Qnil, Qnil);
}
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- master 8469894: Fix unclean "can't happen" error handling in read_minibuf_unwind,
Alan Mackenzie <=