Skip to content

Commit 20e6cd0

Browse files
committed
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.
1 parent 65cedb2 commit 20e6cd0

4 files changed

Lines changed: 44 additions & 12 deletions

File tree

src/option.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8228,7 +8228,8 @@ set_bool_option(
82288228
{
82298229
# ifdef FEAT_TERMINAL
82308230
/* Cannot set 'modifiable' when in Terminal mode. */
8231-
if (term_in_terminal_mode())
8231+
if (term_in_terminal_mode()
8232+
|| (bt_terminal(curbuf) && !term_is_finished(curbuf)))
82328233
{
82338234
curbuf->b_p_ma = FALSE;
82348235
return (char_u *)N_("E946: Cannot make a terminal with running job modifiable");

src/terminal.c

Lines changed: 20 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -36,9 +36,14 @@
3636
* that buffer, attributes come from the scrollback buffer tl_scrollback.
3737
*
3838
* TODO:
39-
* - Add StatusLineTerm highlighting
39+
* - When closing a window with a terminal buffer where the job has ended, wipe
40+
* out the buffer. Like 'bufhidden' is "wipe".
41+
* - When a buffer with a terminal is wiped out, kill the job and close the
42+
* channel.
4043
* - in bash mouse clicks are inserting characters.
4144
* - mouse scroll: when over other window, scroll that window.
45+
* - typing CTRL-C is not sent to the terminal. need to setup controlling tty?
46+
* #1910
4247
* - For the scrollback buffer store lines in the buffer, only attributes in
4348
* tl_scrollback.
4449
* - When the job ends:
@@ -221,17 +226,19 @@ ex_terminal(exarg_T *eap)
221226
if (cmd == NULL || *cmd == NUL)
222227
cmd = p_sh;
223228

224-
if (buflist_findname(cmd) == NULL)
225-
curbuf->b_ffname = vim_strsave(cmd);
226-
else
227229
{
228230
int i;
229231
size_t len = STRLEN(cmd) + 10;
230232
char_u *p = alloc((int)len);
231233

232-
for (i = 1; p != NULL; ++i)
234+
for (i = 0; p != NULL; ++i)
233235
{
234-
vim_snprintf((char *)p, len, "%s (%d)", cmd, i);
236+
/* Prepend a ! to the command name to avoid the buffer name equals
237+
* the executable, otherwise ":w!" would overwrite it. */
238+
if (i == 0)
239+
vim_snprintf((char *)p, len, "!%s", cmd);
240+
else
241+
vim_snprintf((char *)p, len, "!%s (%d)", cmd, i);
235242
if (buflist_findname(p) == NULL)
236243
{
237244
curbuf->b_ffname = p;
@@ -241,8 +248,8 @@ ex_terminal(exarg_T *eap)
241248
}
242249
curbuf->b_fname = curbuf->b_ffname;
243250

244-
/* Mark the buffer as changed, so that it's not easy to abandon the job. */
245-
curbuf->b_changed = TRUE;
251+
/* Mark the buffer as not modifiable. It can only be made modifiable after
252+
* the job finished. */
246253
curbuf->b_p_ma = FALSE;
247254
set_string_option_direct((char_u *)"buftype", -1,
248255
(char_u *)"terminal", OPT_FREE|OPT_LOCAL, 0);
@@ -263,8 +270,6 @@ ex_terminal(exarg_T *eap)
263270
* free_terminal(). */
264271
do_buffer(DOBUF_WIPE, DOBUF_CURRENT, FORWARD, 0, TRUE);
265272
}
266-
267-
/* TODO: Setup pty, see mch_call_shell(). */
268273
}
269274

270275
/*
@@ -1571,6 +1576,11 @@ term_change_in_curbuf(void)
15711576
{
15721577
free_scrollback(term);
15731578
redraw_buf_later(term->tl_buffer, NOT_VALID);
1579+
1580+
/* The buffer is now like a normal buffer, it cannot be easily
1581+
* abandoned when changed. */
1582+
set_string_option_direct((char_u *)"buftype", -1,
1583+
(char_u *)"", OPT_FREE|OPT_LOCAL, 0);
15741584
}
15751585
}
15761586

src/testdir/test_terminal.vim

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ endif
66

77
source shared.vim
88

9-
func Test_terminal_basic()
9+
func Run_shell_in_terminal()
1010
let buf = term_start(&shell)
1111

1212
let termlist = term_list()
@@ -20,6 +20,25 @@ func Test_terminal_basic()
2020
call WaitFor('job_status(g:job) == "dead"')
2121
call assert_equal('dead', job_status(g:job))
2222

23+
return buf
24+
endfunc
25+
26+
func Test_terminal_basic()
27+
let buf = Run_shell_in_terminal()
28+
29+
exe buf . 'bwipe'
30+
unlet g:job
31+
endfunc
32+
33+
func Test_terminal_make_change()
34+
let buf = Run_shell_in_terminal()
35+
call term_wait(buf)
36+
37+
setlocal modifiable
38+
exe "normal Axxx\<Esc>"
39+
call assert_fails(buf . 'bwipe', 'E517')
40+
undo
41+
2342
exe buf . 'bwipe'
2443
unlet g:job
2544
endfunc

src/version.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -769,6 +769,8 @@ static char *(features[]) =
769769

770770
static int included_patches[] =
771771
{ /* Add new patch number below this line */
772+
/**/
773+
836,
772774
/**/
773775
835,
774776
/**/

0 commit comments

Comments
 (0)