0
0
mirror of https://github.com/vim/vim.git synced 2025-09-25 03:54:15 -04:00

patch 9.0.0710: quitting/unloading/hiding a terminal does not work properly

Problem:    Quitting/unloading/hiding a terminal buffer does not always work
            properly.
Solution:   Avoid that ":q!" leaves an empty buffer behind.  ":bunload!" also
            kills the job and unloads the buffer.  ":hide" does not unload the
            buffer. (Yee Cheng Chin, closes #11323)
This commit is contained in:
Yee Cheng Chin
2022-10-10 11:46:16 +01:00
committed by Bram Moolenaar
parent f167c7b424
commit 4282633ba6
4 changed files with 46 additions and 11 deletions

View File

@@ -288,9 +288,8 @@ way to kill or interrupt the job. For example: >
So long as the job is running the window behaves like it contains a modified So long as the job is running the window behaves like it contains a modified
buffer. Trying to close the window with `CTRL-W :quit` fails. When using buffer. Trying to close the window with `CTRL-W :quit` fails. When using
`CTRL-W :quit!` the job is ended. The text in the window is lost. The buffer `CTRL-W :quit!` the job is ended. The text in the window is lost, the buffer
still exists, but getting it in a window with `:buffer` will show an empty is deleted. With `CTRL-W :bunload!` the buffer remains but will be empty.
buffer.
Trying to close the window with `CTRL-W :close` also fails. Using Trying to close the window with `CTRL-W :close` also fails. Using
`CTRL-W :close!` will close the window and make the buffer hidden. `CTRL-W :close!` will close the window and make the buffer hidden.

View File

@@ -538,7 +538,8 @@ close_buffer(
unload_buf = TRUE; unload_buf = TRUE;
#ifdef FEAT_TERMINAL #ifdef FEAT_TERMINAL
if (bt_terminal(buf) && (buf->b_nwindows == 1 || del_buf)) // depending on how we get here b_nwindows may already be zero
if (bt_terminal(buf) && (buf->b_nwindows <= 1 || del_buf))
{ {
CHECK_CURBUF; CHECK_CURBUF;
if (term_job_running(buf->b_term)) if (term_job_running(buf->b_term))
@@ -550,6 +551,11 @@ close_buffer(
// Wiping out or unloading a terminal buffer kills the job. // Wiping out or unloading a terminal buffer kills the job.
free_terminal(buf); free_terminal(buf);
// A terminal buffer is wiped out when job has finished.
del_buf = TRUE;
unload_buf = TRUE;
wipe_buf = TRUE;
} }
else else
{ {
@@ -564,12 +570,18 @@ close_buffer(
unload_buf = FALSE; unload_buf = FALSE;
} }
else else
{
if (del_buf || unload_buf)
{ {
// A terminal buffer is wiped out if the job has finished. // A terminal buffer is wiped out if the job has finished.
// We only do this when there's an intention to unload the
// buffer. This way, :hide and other similar commands won't
// wipe the buffer.
del_buf = TRUE; del_buf = TRUE;
unload_buf = TRUE; unload_buf = TRUE;
wipe_buf = TRUE; wipe_buf = TRUE;
} }
}
CHECK_CURBUF; CHECK_CURBUF;
} }
#endif #endif

View File

@@ -96,6 +96,16 @@ func Test_terminal_paste_register()
unlet g:job unlet g:job
endfunc endfunc
func Test_terminal_unload_buffer()
let buf = Run_shell_in_terminal({})
call assert_fails(buf . 'bunload', 'E948:')
exe buf . 'bunload!'
call WaitForAssert({-> assert_equal('dead', job_status(g:job))})
call assert_equal("", bufname(buf))
unlet g:job
endfunc
func Test_terminal_wipe_buffer() func Test_terminal_wipe_buffer()
let buf = Run_shell_in_terminal({}) let buf = Run_shell_in_terminal({})
call assert_fails(buf . 'bwipe', 'E948:') call assert_fails(buf . 'bwipe', 'E948:')
@@ -202,7 +212,7 @@ func Test_terminal_quit()
quit! quit!
call assert_notequal(buf, bufnr()) call assert_notequal(buf, bufnr())
call WaitForAssert({-> assert_equal('dead', job_status(g:job))}) call WaitForAssert({-> assert_equal('dead', job_status(g:job))})
exec buf .. 'bwipe!' call assert_equal("", bufname(buf))
unlet g:job unlet g:job
endfunc endfunc
@@ -237,7 +247,7 @@ func Test_terminal_split_quit()
quit! quit!
call WaitForAssert({-> assert_equal('dead', job_status(g:job))}) call WaitForAssert({-> assert_equal('dead', job_status(g:job))})
exe buf . 'bwipe' call assert_equal("", bufname(buf))
unlet g:job unlet g:job
endfunc endfunc
@@ -261,16 +271,28 @@ endfunc
func Test_terminal_hide_buffer_job_finished() func Test_terminal_hide_buffer_job_finished()
term echo hello term echo hello
let buf = bufnr() let buf = bufnr()
setlocal bufhidden=hide
call WaitForAssert({-> assert_equal('finished', term_getstatus(buf))}) call WaitForAssert({-> assert_equal('finished', term_getstatus(buf))})
call assert_true(bufloaded(buf)) call assert_true(bufloaded(buf))
call assert_true(buflisted(buf)) call assert_true(buflisted(buf))
" Test :hide
hide
call assert_true(bufloaded(buf))
call assert_true(buflisted(buf))
split
exe buf .. 'buf'
call assert_equal(buf, bufnr())
" Test bufhidden, which exercises a different code path
setlocal bufhidden=hide
edit Xasdfasdf edit Xasdfasdf
call assert_true(bufloaded(buf)) call assert_true(bufloaded(buf))
call assert_true(buflisted(buf)) call assert_true(buflisted(buf))
exe buf .. 'buf' exe buf .. 'buf'
call assert_equal(buf, bufnr()) call assert_equal(buf, bufnr())
setlocal bufhidden= setlocal bufhidden=
edit Xasdfasdf edit Xasdfasdf
call assert_false(bufloaded(buf)) call assert_false(bufloaded(buf))
call assert_false(buflisted(buf)) call assert_false(buflisted(buf))

View File

@@ -699,6 +699,8 @@ static char *(features[]) =
static int included_patches[] = static int included_patches[] =
{ /* Add new patch number below this line */ { /* Add new patch number below this line */
/**/
710,
/**/ /**/
709, 709,
/**/ /**/