]> granicus.if.org Git - vim/commitdiff
patch 8.0.0838: buffer hangs around whem terminal window is closed v8.0.0838
authorBram Moolenaar <Bram@vim.org>
Tue, 1 Aug 2017 19:44:33 +0000 (21:44 +0200)
committerBram Moolenaar <Bram@vim.org>
Tue, 1 Aug 2017 19:44:33 +0000 (21:44 +0200)
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.

src/buffer.c
src/proto/terminal.pro
src/terminal.c
src/testdir/test_terminal.vim
src/version.c

index e4b3b04f41081e4af02aa4008b93b6e3165ec4c1..dd72b1ff7bb9850accd387e1011c4fc2ca99a072 100644 (file)
@@ -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
index 24789293dfefa5bcb72a266c01d48aad38b8ab24..556f9dd61fda6046fb5fe99647f7219ef0b34679 100644 (file)
@@ -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);
index 7f486dd4f65bcf5aeeda900c538400b9cb8df3c6..0ef7ae2aca517fa693c7fab0267af2d542e71a0b 100644 (file)
  * 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?
  * - 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
index 154aab95000836a92336b1e349c43ab3cb04b83b..97f7d5c2d90d9582ecf93a84ad75a7de95f06af9 100644 (file)
@@ -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)
index d6f08bb966facec4e09342a6dcd5c497c1a8fa2e..25c39f192b96a09d6e5c07fdad66025df5a8f50d 100644 (file)
@@ -769,6 +769,8 @@ static char *(features[]) =
 
 static int included_patches[] =
 {   /* Add new patch number below this line */
+/**/
+    838,
 /**/
     837,
 /**/