mirror of
https://git.savannah.gnu.org/git/emacs.git
synced 2025-01-29 19:48:19 +00:00
Handle cases where buffer gets killed while running Fkill_buffer (Bug#11665).
* buffer.c (Fkill_buffer): Don't throw an error when the buffer gets killed during executing of this function (Bug#11665). Try to always return Qt when the buffer has been actually killed. (Vkill_buffer_query_functions): In doc-string say that functions run by this hook should not change the current buffer.
This commit is contained in:
parent
7ea2b33947
commit
b7e8d08167
@ -1,3 +1,11 @@
|
|||||||
|
2012-06-18 Martin Rudalics <rudalics@gmx.at>
|
||||||
|
|
||||||
|
* buffer.c (Fkill_buffer): Don't throw an error when the buffer
|
||||||
|
gets killed during executing of this function (Bug#11665). Try
|
||||||
|
to always return Qt when the buffer has been actually killed.
|
||||||
|
(Vkill_buffer_query_functions): In doc-string say that functions
|
||||||
|
run by this hook should not change the current buffer.
|
||||||
|
|
||||||
2012-06-18 Paul Eggert <eggert@cs.ucla.edu>
|
2012-06-18 Paul Eggert <eggert@cs.ucla.edu>
|
||||||
|
|
||||||
Fix recently-introduced process.c problems found by static checking.
|
Fix recently-introduced process.c problems found by static checking.
|
||||||
|
75
src/buffer.c
75
src/buffer.c
@ -1434,24 +1434,26 @@ No argument or nil as argument means do this for the current buffer. */)
|
|||||||
DEFVAR_LISP ("kill-buffer-hook", ..., "\
|
DEFVAR_LISP ("kill-buffer-hook", ..., "\
|
||||||
Hook to be run (by `run-hooks', which see) when a buffer is killed.\n\
|
Hook to be run (by `run-hooks', which see) when a buffer is killed.\n\
|
||||||
The buffer being killed will be current while the hook is running.\n\
|
The buffer being killed will be current while the hook is running.\n\
|
||||||
See `kill-buffer'."
|
|
||||||
*/
|
Functions run by this hook are supposed to not change the current
|
||||||
|
buffer. See `kill-buffer'."
|
||||||
|
*/
|
||||||
DEFUN ("kill-buffer", Fkill_buffer, Skill_buffer, 0, 1, "bKill buffer: ",
|
DEFUN ("kill-buffer", Fkill_buffer, Skill_buffer, 0, 1, "bKill buffer: ",
|
||||||
doc: /* Kill buffer BUFFER-OR-NAME.
|
doc: /* Kill the buffer specified by BUFFER-OR-NAME.
|
||||||
The argument may be a buffer or the name of an existing buffer.
|
The argument may be a buffer or the name of an existing buffer.
|
||||||
Argument nil or omitted means kill the current buffer. Return t if the
|
Argument nil or omitted means kill the current buffer. Return t if the
|
||||||
buffer is actually killed, nil otherwise.
|
buffer is actually killed, nil otherwise.
|
||||||
|
|
||||||
This function calls `replace-buffer-in-windows' for cleaning up all
|
The functions in `kill-buffer-query-functions' are called with the
|
||||||
windows currently displaying the buffer to be killed. The functions in
|
buffer to be killed as the current buffer. If any of them returns nil,
|
||||||
`kill-buffer-query-functions' are called with the buffer to be killed as
|
the buffer is not killed. The hook `kill-buffer-hook' is run before the
|
||||||
the current buffer. If any of them returns nil, the buffer is not
|
buffer is actually killed. The buffer being killed will be current
|
||||||
killed. The hook `kill-buffer-hook' is run before the buffer is
|
while the hook is running. Functions called by any of these hooks are
|
||||||
actually killed. The buffer being killed will be current while the hook
|
supposed to not change the current buffer.
|
||||||
is running.
|
|
||||||
|
|
||||||
Any processes that have this buffer as the `process-buffer' are killed
|
Any processes that have this buffer as the `process-buffer' are killed
|
||||||
with SIGHUP. */)
|
with SIGHUP. This function calls `replace-buffer-in-windows' for
|
||||||
|
cleaning up all windows currently displaying the buffer to be killed. */)
|
||||||
(Lisp_Object buffer_or_name)
|
(Lisp_Object buffer_or_name)
|
||||||
{
|
{
|
||||||
Lisp_Object buffer;
|
Lisp_Object buffer;
|
||||||
@ -1505,6 +1507,10 @@ with SIGHUP. */)
|
|||||||
unbind_to (count, Qnil);
|
unbind_to (count, Qnil);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* If the hooks have killed the buffer, exit now. */
|
||||||
|
if (NILP (BVAR (b, name)))
|
||||||
|
return Qt;
|
||||||
|
|
||||||
/* We have no more questions to ask. Verify that it is valid
|
/* We have no more questions to ask. Verify that it is valid
|
||||||
to kill the buffer. This must be done after the questions
|
to kill the buffer. This must be done after the questions
|
||||||
since anything can happen within do_yes_or_no_p. */
|
since anything can happen within do_yes_or_no_p. */
|
||||||
@ -1513,9 +1519,6 @@ with SIGHUP. */)
|
|||||||
if (EQ (buffer, XWINDOW (minibuf_window)->buffer))
|
if (EQ (buffer, XWINDOW (minibuf_window)->buffer))
|
||||||
return Qnil;
|
return Qnil;
|
||||||
|
|
||||||
if (NILP (BVAR (b, name)))
|
|
||||||
return Qnil;
|
|
||||||
|
|
||||||
/* When we kill a base buffer, kill all its indirect buffers.
|
/* When we kill a base buffer, kill all its indirect buffers.
|
||||||
We do it at this stage so nothing terrible happens if they
|
We do it at this stage so nothing terrible happens if they
|
||||||
ask questions or their hooks get errors. */
|
ask questions or their hooks get errors. */
|
||||||
@ -1536,6 +1539,10 @@ with SIGHUP. */)
|
|||||||
}
|
}
|
||||||
|
|
||||||
UNGCPRO;
|
UNGCPRO;
|
||||||
|
|
||||||
|
/* Exit if we now have killed the base buffer (Bug#11665). */
|
||||||
|
if (NILP (BVAR (b, name)))
|
||||||
|
return Qt;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Run replace_buffer_in_windows before making another buffer current
|
/* Run replace_buffer_in_windows before making another buffer current
|
||||||
@ -1544,9 +1551,12 @@ with SIGHUP. */)
|
|||||||
buffer. (Bug#10114) */
|
buffer. (Bug#10114) */
|
||||||
replace_buffer_in_windows (buffer);
|
replace_buffer_in_windows (buffer);
|
||||||
|
|
||||||
/* Make this buffer not be current.
|
/* Exit if replacing the buffer in windows has killed our buffer. */
|
||||||
In the process, notice if this is the sole visible buffer
|
if (NILP (BVAR (b, name)))
|
||||||
and give up if so. */
|
return Qt;
|
||||||
|
|
||||||
|
/* Make this buffer not be current. Exit if it is the sole visible
|
||||||
|
buffer. */
|
||||||
if (b == current_buffer)
|
if (b == current_buffer)
|
||||||
{
|
{
|
||||||
tem = Fother_buffer (buffer, Qnil, Qnil);
|
tem = Fother_buffer (buffer, Qnil, Qnil);
|
||||||
@ -1555,15 +1565,12 @@ with SIGHUP. */)
|
|||||||
return Qnil;
|
return Qnil;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Notice if the buffer to kill is the sole visible buffer
|
/* If the buffer now current is shown in the minibuffer and our buffer
|
||||||
when we're currently in the mini-buffer, and give up if so. */
|
is the sole other buffer give up. */
|
||||||
XSETBUFFER (tem, current_buffer);
|
XSETBUFFER (tem, current_buffer);
|
||||||
if (EQ (tem, XWINDOW (minibuf_window)->buffer))
|
if (EQ (tem, XWINDOW (minibuf_window)->buffer)
|
||||||
{
|
&& EQ (buffer, Fother_buffer (buffer, Qnil, Qnil)))
|
||||||
tem = Fother_buffer (buffer, Qnil, Qnil);
|
return Qnil;
|
||||||
if (EQ (buffer, tem))
|
|
||||||
return Qnil;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Now there is no question: we can kill the buffer. */
|
/* Now there is no question: we can kill the buffer. */
|
||||||
|
|
||||||
@ -1576,11 +1583,10 @@ with SIGHUP. */)
|
|||||||
kill_buffer_processes (buffer);
|
kill_buffer_processes (buffer);
|
||||||
UNGCPRO;
|
UNGCPRO;
|
||||||
|
|
||||||
/* Killing buffer processes may run sentinels which may
|
/* Killing buffer processes may run sentinels which may have killed
|
||||||
have called kill-buffer. */
|
our buffer. */
|
||||||
|
|
||||||
if (NILP (BVAR (b, name)))
|
if (NILP (BVAR (b, name)))
|
||||||
return Qnil;
|
return Qt;
|
||||||
|
|
||||||
/* These may run Lisp code and into infinite loops (if someone
|
/* These may run Lisp code and into infinite loops (if someone
|
||||||
insisted on circular lists) so allow quitting here. */
|
insisted on circular lists) so allow quitting here. */
|
||||||
@ -1592,8 +1598,7 @@ with SIGHUP. */)
|
|||||||
Vinhibit_quit = Qt;
|
Vinhibit_quit = Qt;
|
||||||
/* Remove the buffer from the list of all buffers. */
|
/* Remove the buffer from the list of all buffers. */
|
||||||
Vbuffer_alist = Fdelq (Frassq (buffer, Vbuffer_alist), Vbuffer_alist);
|
Vbuffer_alist = Fdelq (Frassq (buffer, Vbuffer_alist), Vbuffer_alist);
|
||||||
/* If replace_buffer_in_windows didn't do its job correctly fix that
|
/* If replace_buffer_in_windows didn't do its job fix that now. */
|
||||||
now. */
|
|
||||||
replace_buffer_in_windows_safely (buffer);
|
replace_buffer_in_windows_safely (buffer);
|
||||||
Vinhibit_quit = tem;
|
Vinhibit_quit = tem;
|
||||||
|
|
||||||
@ -1611,6 +1616,10 @@ with SIGHUP. */)
|
|||||||
internal_delete_file (BVAR (b, auto_save_file_name));
|
internal_delete_file (BVAR (b, auto_save_file_name));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Deleting an auto-save file could have killed our buffer. */
|
||||||
|
if (NILP (BVAR (b, name)))
|
||||||
|
return Qt;
|
||||||
|
|
||||||
if (b->base_buffer)
|
if (b->base_buffer)
|
||||||
{
|
{
|
||||||
/* Unchain all markers that belong to this indirect buffer.
|
/* Unchain all markers that belong to this indirect buffer.
|
||||||
@ -5991,7 +6000,9 @@ Use Custom to set this variable and update the display." */);
|
|||||||
DEFVAR_LISP ("kill-buffer-query-functions", Vkill_buffer_query_functions,
|
DEFVAR_LISP ("kill-buffer-query-functions", Vkill_buffer_query_functions,
|
||||||
doc: /* List of functions called with no args to query before killing a buffer.
|
doc: /* List of functions called with no args to query before killing a buffer.
|
||||||
The buffer being killed will be current while the functions are running.
|
The buffer being killed will be current while the functions are running.
|
||||||
If any of them returns nil, the buffer is not killed. */);
|
|
||||||
|
If any of them returns nil, the buffer is not killed. Functions run by
|
||||||
|
this hook are supposed to not change the current buffer. */);
|
||||||
Vkill_buffer_query_functions = Qnil;
|
Vkill_buffer_query_functions = Qnil;
|
||||||
|
|
||||||
DEFVAR_LISP ("change-major-mode-hook", Vchange_major_mode_hook,
|
DEFVAR_LISP ("change-major-mode-hook", Vchange_major_mode_hook,
|
||||||
|
Loading…
Reference in New Issue
Block a user