summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBram Moolenaar <Bram@vim.org>2017-08-01 20:25:22 +0200
committerBram Moolenaar <Bram@vim.org>2017-08-01 20:25:22 +0200
commit20e6cd07baed8992e7a509ccef7f111ffcded44d (patch)
treed680d52faa65211fde63b2e7c63df7fd8b62f8a0
parent65cedb2074ce550d20a3069c200e2a5d4061d3f6 (diff)
downloadvim-git-20e6cd07baed8992e7a509ccef7f111ffcded44d.tar.gz
patch 8.0.0836: can abandon a terminal buffer after making a changev8.0.0836
Problem: When a terminal buffer is changed it can still be accidentally abandoned. Solution: When making a change reset the 'buftype' option.
-rw-r--r--src/option.c3
-rw-r--r--src/terminal.c30
-rw-r--r--src/testdir/test_terminal.vim21
-rw-r--r--src/version.c2
4 files changed, 44 insertions, 12 deletions
diff --git a/src/option.c b/src/option.c
index 23474617c..d937d02ce 100644
--- a/src/option.c
+++ b/src/option.c
@@ -8228,7 +8228,8 @@ set_bool_option(
{
# ifdef FEAT_TERMINAL
/* Cannot set 'modifiable' when in Terminal mode. */
- if (term_in_terminal_mode())
+ if (term_in_terminal_mode()
+ || (bt_terminal(curbuf) && !term_is_finished(curbuf)))
{
curbuf->b_p_ma = FALSE;
return (char_u *)N_("E946: Cannot make a terminal with running job modifiable");
diff --git a/src/terminal.c b/src/terminal.c
index 9dc2d3202..7f486dd4f 100644
--- a/src/terminal.c
+++ b/src/terminal.c
@@ -36,9 +36,14 @@
* that buffer, attributes come from the scrollback buffer tl_scrollback.
*
* TODO:
- * - Add StatusLineTerm highlighting
+ * - 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.
* - 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?
+ * #1910
* - For the scrollback buffer store lines in the buffer, only attributes in
* tl_scrollback.
* - When the job ends:
@@ -221,17 +226,19 @@ ex_terminal(exarg_T *eap)
if (cmd == NULL || *cmd == NUL)
cmd = p_sh;
- if (buflist_findname(cmd) == NULL)
- curbuf->b_ffname = vim_strsave(cmd);
- else
{
int i;
size_t len = STRLEN(cmd) + 10;
char_u *p = alloc((int)len);
- for (i = 1; p != NULL; ++i)
+ for (i = 0; p != NULL; ++i)
{
- vim_snprintf((char *)p, len, "%s (%d)", cmd, i);
+ /* Prepend a ! to the command name to avoid the buffer name equals
+ * the executable, otherwise ":w!" would overwrite it. */
+ if (i == 0)
+ vim_snprintf((char *)p, len, "!%s", cmd);
+ else
+ vim_snprintf((char *)p, len, "!%s (%d)", cmd, i);
if (buflist_findname(p) == NULL)
{
curbuf->b_ffname = p;
@@ -241,8 +248,8 @@ ex_terminal(exarg_T *eap)
}
curbuf->b_fname = curbuf->b_ffname;
- /* Mark the buffer as changed, so that it's not easy to abandon the job. */
- curbuf->b_changed = TRUE;
+ /* Mark the buffer as not modifiable. It can only be made modifiable after
+ * the job finished. */
curbuf->b_p_ma = FALSE;
set_string_option_direct((char_u *)"buftype", -1,
(char_u *)"terminal", OPT_FREE|OPT_LOCAL, 0);
@@ -263,8 +270,6 @@ ex_terminal(exarg_T *eap)
* free_terminal(). */
do_buffer(DOBUF_WIPE, DOBUF_CURRENT, FORWARD, 0, TRUE);
}
-
- /* TODO: Setup pty, see mch_call_shell(). */
}
/*
@@ -1571,6 +1576,11 @@ term_change_in_curbuf(void)
{
free_scrollback(term);
redraw_buf_later(term->tl_buffer, NOT_VALID);
+
+ /* The buffer is now like a normal buffer, it cannot be easily
+ * abandoned when changed. */
+ set_string_option_direct((char_u *)"buftype", -1,
+ (char_u *)"", OPT_FREE|OPT_LOCAL, 0);
}
}
diff --git a/src/testdir/test_terminal.vim b/src/testdir/test_terminal.vim
index 8df690c3c..154aab950 100644
--- a/src/testdir/test_terminal.vim
+++ b/src/testdir/test_terminal.vim
@@ -6,7 +6,7 @@ endif
source shared.vim
-func Test_terminal_basic()
+func Run_shell_in_terminal()
let buf = term_start(&shell)
let termlist = term_list()
@@ -20,6 +20,25 @@ func Test_terminal_basic()
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()
+
+ exe buf . 'bwipe'
+ unlet g:job
+endfunc
+
+func Test_terminal_make_change()
+ let buf = Run_shell_in_terminal()
+ call term_wait(buf)
+
+ setlocal modifiable
+ exe "normal Axxx\<Esc>"
+ call assert_fails(buf . 'bwipe', 'E517')
+ undo
+
exe buf . 'bwipe'
unlet g:job
endfunc
diff --git a/src/version.c b/src/version.c
index 88d7e76c1..3aab4d39b 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 */
/**/
+ 836,
+/**/
835,
/**/
834,