To: vim_dev@googlegroups.com Subject: Patch 9.0.0710 Fcc: outbox From: Bram Moolenaar Mime-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ------------ Patch 9.0.0710 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) Files: runtime/doc/terminal.txt, src/buffer.c, src/testdir/test_terminal.vim *** ../vim-9.0.0709/runtime/doc/terminal.txt 2022-06-28 11:21:06.000000000 +0100 --- runtime/doc/terminal.txt 2022-10-10 11:41:36.766702704 +0100 *************** *** 288,296 **** 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 ! `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 ! buffer. Trying to close the window with `CTRL-W :close` also fails. Using `CTRL-W :close!` will close the window and make the buffer hidden. --- 288,295 ---- 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 ! `CTRL-W :quit!` the job is ended. The text in the window is lost, the buffer ! is deleted. With `CTRL-W :bunload!` the buffer remains but will be empty. Trying to close the window with `CTRL-W :close` also fails. Using `CTRL-W :close!` will close the window and make the buffer hidden. *** ../vim-9.0.0709/src/buffer.c 2022-10-09 18:53:29.020591194 +0100 --- src/buffer.c 2022-10-10 11:42:12.886653780 +0100 *************** *** 538,544 **** unload_buf = TRUE; #ifdef FEAT_TERMINAL ! if (bt_terminal(buf) && (buf->b_nwindows == 1 || del_buf)) { CHECK_CURBUF; if (term_job_running(buf->b_term)) --- 538,545 ---- unload_buf = TRUE; #ifdef FEAT_TERMINAL ! // depending on how we get here b_nwindows may already be zero ! if (bt_terminal(buf) && (buf->b_nwindows <= 1 || del_buf)) { CHECK_CURBUF; if (term_job_running(buf->b_term)) *************** *** 550,555 **** --- 551,561 ---- // Wiping out or unloading a terminal buffer kills the job. free_terminal(buf); + + // A terminal buffer is wiped out when job has finished. + del_buf = TRUE; + unload_buf = TRUE; + wipe_buf = TRUE; } else { *************** *** 565,574 **** } else { ! // A terminal buffer is wiped out if the job has finished. ! del_buf = TRUE; ! unload_buf = TRUE; ! wipe_buf = TRUE; } CHECK_CURBUF; } --- 571,586 ---- } else { ! if (del_buf || unload_buf) ! { ! // 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; ! unload_buf = TRUE; ! wipe_buf = TRUE; ! } } CHECK_CURBUF; } *** ../vim-9.0.0709/src/testdir/test_terminal.vim 2022-10-09 18:53:29.024591198 +0100 --- src/testdir/test_terminal.vim 2022-10-10 11:36:01.663167849 +0100 *************** *** 96,101 **** --- 96,111 ---- unlet g:job 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() let buf = Run_shell_in_terminal({}) call assert_fails(buf . 'bwipe', 'E948:') *************** *** 202,208 **** quit! call assert_notequal(buf, bufnr()) call WaitForAssert({-> assert_equal('dead', job_status(g:job))}) ! exec buf .. 'bwipe!' unlet g:job endfunc --- 212,218 ---- quit! call assert_notequal(buf, bufnr()) call WaitForAssert({-> assert_equal('dead', job_status(g:job))}) ! call assert_equal("", bufname(buf)) unlet g:job endfunc *************** *** 237,243 **** quit! call WaitForAssert({-> assert_equal('dead', job_status(g:job))}) ! exe buf . 'bwipe' unlet g:job endfunc --- 247,253 ---- quit! call WaitForAssert({-> assert_equal('dead', job_status(g:job))}) ! call assert_equal("", bufname(buf)) unlet g:job endfunc *************** *** 261,276 **** func Test_terminal_hide_buffer_job_finished() term echo hello let buf = bufnr() - setlocal bufhidden=hide call WaitForAssert({-> assert_equal('finished', term_getstatus(buf))}) call assert_true(bufloaded(buf)) call assert_true(buflisted(buf)) edit Xasdfasdf call assert_true(bufloaded(buf)) call assert_true(buflisted(buf)) exe buf .. 'buf' call assert_equal(buf, bufnr()) setlocal bufhidden= edit Xasdfasdf call assert_false(bufloaded(buf)) call assert_false(buflisted(buf)) --- 271,298 ---- func Test_terminal_hide_buffer_job_finished() term echo hello let buf = bufnr() call WaitForAssert({-> assert_equal('finished', term_getstatus(buf))}) + + call assert_true(bufloaded(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 call assert_true(bufloaded(buf)) call assert_true(buflisted(buf)) exe buf .. 'buf' call assert_equal(buf, bufnr()) setlocal bufhidden= + edit Xasdfasdf call assert_false(bufloaded(buf)) call assert_false(buflisted(buf)) *** ../vim-9.0.0709/src/version.c 2022-10-09 21:53:35.323363028 +0100 --- src/version.c 2022-10-10 11:45:15.202409411 +0100 *************** *** 701,702 **** --- 701,704 ---- { /* Add new patch number below this line */ + /**/ + 710, /**/ -- Have you heard about the new Barbie doll? It's called Divorce Barbie. It comes with most of Ken's stuff. /// Bram Moolenaar -- Bram@Moolenaar.net -- http://www.Moolenaar.net \\\ /// \\\ \\\ sponsor Vim, vote for features -- http://www.Vim.org/sponsor/ /// \\\ help me help AIDS victims -- http://ICCF-Holland.org ///