summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBram Moolenaar <Bram@vim.org>2017-08-01 21:44:33 +0200
committerBram Moolenaar <Bram@vim.org>2017-08-01 21:44:33 +0200
commit94053a51255121713f51c122eb0dbb46c120e6d4 (patch)
tree3e2e3a361ebd94d218551e337450005bf55d8d3e
parent0792048842493f224bbd7a5dfb348d834f61b205 (diff)
patch 8.0.0838: buffer hangs around whem terminal window is closedv8.0.0838
Problem: Buffer hangs around whem terminal window is closed. Solution: When the job has ended wipe out a terminal buffer when the window is closed.
-rw-r--r--src/buffer.c25
-rw-r--r--src/proto/terminal.pro1
-rw-r--r--src/terminal.c13
-rw-r--r--src/testdir/test_terminal.vim45
-rw-r--r--src/version.c2
5 files changed, 72 insertions, 14 deletions
diff --git a/src/buffer.c b/src/buffer.c
index e4b3b04f41..dd72b1ff7b 100644
--- a/src/buffer.c
+++ b/src/buffer.c
@@ -468,6 +468,31 @@ close_buffer(
int del_buf = (action == DOBUF_DEL || action == DOBUF_WIPE);
int wipe_buf = (action == DOBUF_WIPE);
+#ifdef FEAT_TERMINAL
+ if (bt_terminal(buf))
+ {
+ if (term_job_running(buf->b_term))
+ {
+ if (wipe_buf)
+ /* Wiping out a terminal buffer kills the job. */
+ free_terminal(buf);
+ else
+ {
+ /* The job keeps running, hide the buffer. */
+ del_buf = FALSE;
+ unload_buf = FALSE;
+ }
+ }
+ else
+ {
+ /* A terminal buffer is wiped out if the job has finished. */
+ del_buf = TRUE;
+ unload_buf = TRUE;
+ wipe_buf = TRUE;
+ }
+ }
+ else
+#endif
/*
* Force unloading or deleting when 'bufhidden' says so.
* The caller must take care of NOT deleting/freeing when 'bufhidden' is
diff --git a/src/proto/terminal.pro b/src/proto/terminal.pro
index 24789293df..556f9dd61f 100644
--- a/src/proto/terminal.pro
+++ b/src/proto/terminal.pro
@@ -2,6 +2,7 @@
void ex_terminal(exarg_T *eap);
void free_terminal(buf_T *buf);
void write_to_term(buf_T *buffer, char_u *msg, channel_T *channel);
+int term_job_running(term_T *term);
int term_in_terminal_mode(void);
void term_leave_terminal_mode(void);
int term_use_loop(void);
diff --git a/src/terminal.c b/src/terminal.c
index 7f486dd4f6..0ef7ae2aca 100644
--- a/src/terminal.c
+++ b/src/terminal.c
@@ -36,10 +36,7 @@
* that buffer, attributes come from the scrollback buffer tl_scrollback.
*
* TODO:
- * - When closing a window with a terminal buffer where the job has ended, wipe
- * out the buffer. Like 'bufhidden' is "wipe".
- * - When a buffer with a terminal is wiped out, kill the job and close the
- * channel.
+ * - don't allow exiting Vim when a terminal is still running a job
* - in bash mouse clicks are inserting characters.
* - mouse scroll: when over other window, scroll that window.
* - typing CTRL-C is not sent to the terminal. need to setup controlling tty?
@@ -59,12 +56,8 @@
* - do not store terminal window in viminfo. Or prefix term:// ?
* - add a character in :ls output
* - add 't' to mode()
- * - When making a change after the job has ended, make the buffer a normal
- * buffer; needs to be written.
- * - when closing window and job has not ended, make terminal hidden?
- * - when closing window and job has ended, make buffer hidden?
- * - don't allow exiting Vim when a terminal is still running a job
* - use win_del_lines() to make scroll-up efficient.
+ * - implement term_setsize()
* - add test for giving error for invalid 'termsize' value.
* - support minimal size when 'termsize' is "rows*cols".
* - support minimal size when 'termsize' is empty?
@@ -573,7 +566,7 @@ term_convert_key(term_T *term, int c, char *buf)
/*
* Return TRUE if the job for "term" is still running.
*/
- static int
+ int
term_job_running(term_T *term)
{
/* Also consider the job finished when the channel is closed, to avoid a
diff --git a/src/testdir/test_terminal.vim b/src/testdir/test_terminal.vim
index 154aab9500..97f7d5c2d9 100644
--- a/src/testdir/test_terminal.vim
+++ b/src/testdir/test_terminal.vim
@@ -6,6 +6,8 @@ endif
source shared.vim
+" Open a terminal with a shell, assign the job to g:job and return the buffer
+" number.
func Run_shell_in_terminal()
let buf = term_start(&shell)
@@ -16,22 +18,31 @@ func Run_shell_in_terminal()
let g:job = term_getjob(buf)
call assert_equal(v:t_job, type(g:job))
- call term_sendkeys(buf, "exit\r")
+ return buf
+endfunc
+
+" Stops the shell started by Run_shell_in_terminal().
+func Stop_shell_in_terminal(buf)
+ call term_sendkeys(a:buf, "exit\r")
call WaitFor('job_status(g:job) == "dead"')
call assert_equal('dead', job_status(g:job))
-
- return buf
endfunc
func Test_terminal_basic()
let buf = Run_shell_in_terminal()
+ call Stop_shell_in_terminal(buf)
+ call term_wait(buf)
+
+ " closing window wipes out the terminal buffer a with finished job
+ close
+ call assert_equal("", bufname(buf))
- exe buf . 'bwipe'
unlet g:job
endfunc
func Test_terminal_make_change()
let buf = Run_shell_in_terminal()
+ call Stop_shell_in_terminal(buf)
call term_wait(buf)
setlocal modifiable
@@ -43,6 +54,32 @@ func Test_terminal_make_change()
unlet g:job
endfunc
+func Test_terminal_wipe_buffer()
+ let buf = Run_shell_in_terminal()
+ exe buf . 'bwipe'
+ call WaitFor('job_status(g:job) == "dead"')
+ call assert_equal('dead', job_status(g:job))
+ call assert_equal("", bufname(buf))
+
+ unlet g:job
+endfunc
+
+func Test_terminal_hide_buffer()
+ let buf = Run_shell_in_terminal()
+ quit
+ for nr in range(1, winnr('$'))
+ call assert_notequal(winbufnr(nr), buf)
+ endfor
+ call assert_true(bufloaded(buf))
+ call assert_true(buflisted(buf))
+
+ exe 'split ' . buf . 'buf'
+ call Stop_shell_in_terminal(buf)
+ exe buf . 'bwipe'
+
+ unlet g:job
+endfunc
+
func Check_123(buf)
let l = term_scrape(a:buf, 1)
call assert_true(len(l) > 0)
diff --git a/src/version.c b/src/version.c
index d6f08bb966..25c39f192b 100644
--- a/src/version.c
+++ b/src/version.c
@@ -770,6 +770,8 @@ static char *(features[]) =
static int included_patches[] =
{ /* Add new patch number below this line */
/**/
+ 838,
+/**/
837,
/**/
836,