0
0
mirror of https://github.com/vim/vim.git synced 2025-09-24 03:44:06 -04:00

patch 8.0.0836: can abandon a terminal buffer after making a change

Problem:    When a terminal buffer is changed it can still be accidentally
            abandoned.
Solution:   When making a change reset the 'buftype' option.
This commit is contained in:
Bram Moolenaar
2017-08-01 20:25:22 +02:00
parent 65cedb2074
commit 20e6cd07ba
4 changed files with 44 additions and 12 deletions

View File

@@ -8228,7 +8228,8 @@ set_bool_option(
{ {
# ifdef FEAT_TERMINAL # ifdef FEAT_TERMINAL
/* Cannot set 'modifiable' when in Terminal mode. */ /* 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; curbuf->b_p_ma = FALSE;
return (char_u *)N_("E946: Cannot make a terminal with running job modifiable"); return (char_u *)N_("E946: Cannot make a terminal with running job modifiable");

View File

@@ -36,9 +36,14 @@
* that buffer, attributes come from the scrollback buffer tl_scrollback. * that buffer, attributes come from the scrollback buffer tl_scrollback.
* *
* TODO: * 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. * - in bash mouse clicks are inserting characters.
* - mouse scroll: when over other window, scroll that window. * - 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 * - For the scrollback buffer store lines in the buffer, only attributes in
* tl_scrollback. * tl_scrollback.
* - When the job ends: * - When the job ends:
@@ -221,17 +226,19 @@ ex_terminal(exarg_T *eap)
if (cmd == NULL || *cmd == NUL) if (cmd == NULL || *cmd == NUL)
cmd = p_sh; cmd = p_sh;
if (buflist_findname(cmd) == NULL)
curbuf->b_ffname = vim_strsave(cmd);
else
{ {
int i; int i;
size_t len = STRLEN(cmd) + 10; size_t len = STRLEN(cmd) + 10;
char_u *p = alloc((int)len); 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) if (buflist_findname(p) == NULL)
{ {
curbuf->b_ffname = p; curbuf->b_ffname = p;
@@ -241,8 +248,8 @@ ex_terminal(exarg_T *eap)
} }
curbuf->b_fname = curbuf->b_ffname; curbuf->b_fname = curbuf->b_ffname;
/* Mark the buffer as changed, so that it's not easy to abandon the job. */ /* Mark the buffer as not modifiable. It can only be made modifiable after
curbuf->b_changed = TRUE; * the job finished. */
curbuf->b_p_ma = FALSE; curbuf->b_p_ma = FALSE;
set_string_option_direct((char_u *)"buftype", -1, set_string_option_direct((char_u *)"buftype", -1,
(char_u *)"terminal", OPT_FREE|OPT_LOCAL, 0); (char_u *)"terminal", OPT_FREE|OPT_LOCAL, 0);
@@ -263,8 +270,6 @@ ex_terminal(exarg_T *eap)
* free_terminal(). */ * free_terminal(). */
do_buffer(DOBUF_WIPE, DOBUF_CURRENT, FORWARD, 0, TRUE); 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); free_scrollback(term);
redraw_buf_later(term->tl_buffer, NOT_VALID); 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);
} }
} }

View File

@@ -6,7 +6,7 @@ endif
source shared.vim source shared.vim
func Test_terminal_basic() func Run_shell_in_terminal()
let buf = term_start(&shell) let buf = term_start(&shell)
let termlist = term_list() let termlist = term_list()
@@ -20,6 +20,25 @@ func Test_terminal_basic()
call WaitFor('job_status(g:job) == "dead"') call WaitFor('job_status(g:job) == "dead"')
call assert_equal('dead', job_status(g:job)) 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' exe buf . 'bwipe'
unlet g:job unlet g:job
endfunc endfunc

View File

@@ -769,6 +769,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 */
/**/
836,
/**/ /**/
835, 835,
/**/ /**/