Skip to content

Commit 4d14bac

Browse files
committed
patch 8.1.2195: Vim does not exit when the terminal window is last window
Problem: Vim does not exit when closing a terminal window and it is the last window. Solution: Exit Vim if the closed terminal window is the last one. (closes #4539)
1 parent 4b57018 commit 4d14bac

6 files changed

Lines changed: 51 additions & 7 deletions

File tree

runtime/doc/terminal.txt

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -193,6 +193,7 @@ Command syntax ~
193193
Supported [options] are:
194194
++close The terminal window will close
195195
automatically when the job terminates.
196+
|terminal-close|
196197
++noclose The terminal window will NOT close
197198
automatically when the job terminates.
198199
++open When the job terminates and no window
@@ -267,6 +268,12 @@ hidden, the job keeps running. The `:buffer` command can be used to turn the
267268
current window into a terminal window. If there are unsaved changes this
268269
fails, use ! to force, as usual.
269270

271+
*terminal-close*
272+
When the terminal window is closed, e.g. when the shell exits and "++close"
273+
argument was used, and this is the last normal Vim window, then Vim will exit.
274+
This is like using |:quit| in a normal window. Help and preview windows are
275+
not counted.
276+
270277
To have a background job run without a window, and open the window when it's
271278
done, use options like this: >
272279
:term ++hidden ++open make

src/ex_docmd.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -87,7 +87,6 @@ static char_u *replace_makeprg(exarg_T *eap, char_u *p, char_u **cmdlinep);
8787
static char_u *repl_cmdline(exarg_T *eap, char_u *src, int srclen, char_u *repl, char_u **cmdlinep);
8888
static void ex_highlight(exarg_T *eap);
8989
static void ex_colorscheme(exarg_T *eap);
90-
static void ex_quit(exarg_T *eap);
9190
static void ex_cquit(exarg_T *eap);
9291
static void ex_quit_all(exarg_T *eap);
9392
static void ex_close(exarg_T *eap);
@@ -4842,8 +4841,9 @@ before_quit_autocmds(win_T *wp, int quit_all, int forceit)
48424841
/*
48434842
* ":quit": quit current window, quit Vim if the last window is closed.
48444843
* ":{nr}quit": quit window {nr}
4844+
* Also used when closing a terminal window that's the last one.
48454845
*/
4846-
static void
4846+
void
48474847
ex_quit(exarg_T *eap)
48484848
{
48494849
win_T *wp;

src/proto/ex_docmd.pro

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -15,13 +15,14 @@ char_u *skip_range(char_u *cmd, int *ctx);
1515
void ex_ni(exarg_T *eap);
1616
int expand_filename(exarg_T *eap, char_u **cmdlinep, char **errormsgp);
1717
void separate_nextcmd(exarg_T *eap);
18-
char_u *skip_cmd_arg( char_u *p, int rembs);
18+
char_u *skip_cmd_arg(char_u *p, int rembs);
1919
int get_bad_opt(char_u *p, exarg_T *eap);
2020
int ends_excmd(int c);
2121
char_u *find_nextcmd(char_u *p);
2222
char_u *check_nextcmd(char_u *p);
2323
char_u *get_command_name(expand_T *xp, int idx);
2424
void not_exiting(void);
25+
void ex_quit(exarg_T *eap);
2526
void tabpage_close(int forceit);
2627
void tabpage_close_other(tabpage_T *tp, int forceit);
2728
void handle_drop(int filec, char_u **filev, int split, void (*callback)(void *), void *cookie);
@@ -30,8 +31,8 @@ void ex_splitview(exarg_T *eap);
3031
void tabpage_new(void);
3132
void do_exedit(exarg_T *eap, win_T *old_curwin);
3233
void free_cd_dir(void);
33-
void post_chdir(cdscope_T cdscope);
34-
int changedir_func(char_u *new_dir, int forceit, cdscope_T cdscope);
34+
void post_chdir(cdscope_T scope);
35+
int changedir_func(char_u *new_dir, int forceit, cdscope_T scope);
3536
void ex_cd(exarg_T *eap);
3637
void do_sleep(long msec);
3738
void ex_may_print(exarg_T *eap);
@@ -47,8 +48,6 @@ void exec_normal(int was_typed, int use_vpeekc, int may_use_terminal_loop);
4748
int find_cmdline_var(char_u *src, int *usedlen);
4849
char_u *eval_vars(char_u *src, char_u *srcstart, int *usedlen, linenr_T *lnump, char **errormsg, int *escaped);
4950
char_u *expand_sfile(char_u *arg);
50-
int put_eol(FILE *fd);
51-
int put_line(FILE *fd, char *s);
5251
void dialog_msg(char_u *buff, char *format, char_u *fname);
5352
void set_no_hlsearch(int flag);
5453
int is_loclist_cmd(int cmdidx);

src/terminal.c

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3073,6 +3073,16 @@ term_after_channel_closed(term_T *term)
30733073
aco_save_T aco;
30743074
int do_set_w_closing = term->tl_buffer->b_nwindows == 0;
30753075

3076+
// If this is the last normal window: exit Vim.
3077+
if (term->tl_buffer->b_nwindows > 0 && only_one_window())
3078+
{
3079+
exarg_T ea;
3080+
3081+
vim_memset(&ea, 0, sizeof(ea));
3082+
ex_quit(&ea);
3083+
return TRUE;
3084+
}
3085+
30763086
// ++close or term_finish == "close"
30773087
ch_log(NULL, "terminal job finished, closing window");
30783088
aucmd_prepbuf(&aco, term->tl_buffer);

src/testdir/test_terminal.vim

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1051,6 +1051,32 @@ func Test_terminal_qall_prompt()
10511051
quit
10521052
endfunc
10531053

1054+
" Run Vim in a terminal, then start a terminal window with a shell and check
1055+
" that Vim exits if it is closed.
1056+
func Test_terminal_exit()
1057+
CheckRunVimInTerminal
1058+
1059+
let lines =<< trim END
1060+
let winid = win_getid()
1061+
help
1062+
term
1063+
let termid = win_getid()
1064+
call win_gotoid(winid)
1065+
close
1066+
call win_gotoid(termid)
1067+
END
1068+
call writefile(lines, 'XtermExit')
1069+
let buf = RunVimInTerminal('-S XtermExit', #{rows: 10})
1070+
let job = term_getjob(buf)
1071+
call WaitForAssert({-> assert_equal("run", job_status(job))})
1072+
1073+
" quit the shell, it will make Vim exit
1074+
call term_sendkeys(buf, "exit\<CR>")
1075+
call WaitForAssert({-> assert_equal("dead", job_status(job))})
1076+
1077+
call delete('XtermExit')
1078+
endfunc
1079+
10541080
func Test_terminal_open_autocmd()
10551081
augroup repro
10561082
au!

src/version.c

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

742742
static int included_patches[] =
743743
{ /* Add new patch number below this line */
744+
/**/
745+
2195,
744746
/**/
745747
2194,
746748
/**/

0 commit comments

Comments
 (0)