summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBram Moolenaar <Bram@vim.org>2017-08-03 22:44:55 +0200
committerBram Moolenaar <Bram@vim.org>2017-08-03 22:44:55 +0200
commiteb44a68b42eda207a5bc4def9ea8fc4d38acb650 (patch)
tree6fae22aba3c4f1eaad8e6d5e4d74df201c78a65e
parent620d064b0b0bca2268574abdec2d8eac3384cfdf (diff)
patch 8.0.0858: can exit while a terminal is still running a jobv8.0.0858
Problem: Can exit while a terminal is still running a job. Solution: Consider a buffer with a running job like a changed file.
-rw-r--r--src/buffer.c14
-rw-r--r--src/ex_cmds.c6
-rw-r--r--src/ex_cmds2.c21
-rw-r--r--src/ex_docmd.c20
-rw-r--r--src/normal.c4
-rw-r--r--src/option.h7
-rw-r--r--src/terminal.c10
-rw-r--r--src/testdir/test_terminal.vim3
-rw-r--r--src/undo.c15
-rw-r--r--src/version.c2
-rw-r--r--src/window.c3
11 files changed, 55 insertions, 50 deletions
diff --git a/src/buffer.c b/src/buffer.c
index dd72b1ff7b..181145d42c 100644
--- a/src/buffer.c
+++ b/src/buffer.c
@@ -1736,7 +1736,7 @@ set_curbuf(buf_T *buf, int action)
u_sync(FALSE);
close_buffer(prevbuf == curwin->w_buffer ? curwin : NULL, prevbuf,
unload ? action : (action == DOBUF_GOTO
- && !P_HID(prevbuf)
+ && !buf_hide(prevbuf)
&& !bufIsChanged(prevbuf)) ? DOBUF_UNLOAD : 0, FALSE);
#ifdef FEAT_WINDOWS
if (curwin != previouswin && win_valid(previouswin))
@@ -4986,12 +4986,12 @@ do_arg_all(
if (i == opened_len && !keep_tabs)/* close this window */
{
- if (P_HID(buf) || forceit || buf->b_nwindows > 1
+ if (buf_hide(buf) || forceit || buf->b_nwindows > 1
|| !bufIsChanged(buf))
{
/* If the buffer was changed, and we would like to hide it,
* try autowriting. */
- if (!P_HID(buf) && buf->b_nwindows <= 1
+ if (!buf_hide(buf) && buf->b_nwindows <= 1
&& bufIsChanged(buf))
{
#ifdef FEAT_AUTOCMD
@@ -5018,7 +5018,7 @@ do_arg_all(
#ifdef FEAT_WINDOWS
else
{
- win_close(wp, !P_HID(buf) && !bufIsChanged(buf));
+ win_close(wp, !buf_hide(buf) && !bufIsChanged(buf));
# ifdef FEAT_AUTOCMD
/* check if autocommands removed the next window */
if (!win_valid(wpnext))
@@ -5117,7 +5117,7 @@ do_arg_all(
}
(void)do_ecmd(0, alist_name(&AARGLIST(alist)[i]), NULL, NULL,
ECMD_ONE,
- ((P_HID(curwin->w_buffer)
+ ((buf_hide(curwin->w_buffer)
|| bufIsChanged(curwin->w_buffer)) ? ECMD_HIDE : 0)
+ ECMD_OLDBUF, curwin);
#ifdef FEAT_AUTOCMD
@@ -5372,7 +5372,7 @@ ex_buffer_all(exarg_T *eap)
*/
for (wp = lastwin; open_wins > count; )
{
- r = (P_HID(wp->w_buffer) || !bufIsChanged(wp->w_buffer)
+ r = (buf_hide(wp->w_buffer) || !bufIsChanged(wp->w_buffer)
|| autowrite(wp->w_buffer, FALSE) == OK);
#ifdef FEAT_AUTOCMD
if (!win_valid(wp))
@@ -5384,7 +5384,7 @@ ex_buffer_all(exarg_T *eap)
#endif
if (r)
{
- win_close(wp, !P_HID(wp->w_buffer));
+ win_close(wp, !buf_hide(wp->w_buffer));
--open_wins;
wp = lastwin;
}
diff --git a/src/ex_cmds.c b/src/ex_cmds.c
index 6ec3ded90b..61c85a917f 100644
--- a/src/ex_cmds.c
+++ b/src/ex_cmds.c
@@ -3561,7 +3561,7 @@ getfile(
if (other)
++no_wait_return; /* don't wait for autowrite message */
- if (other && !forceit && curbuf->b_nwindows == 1 && !P_HID(curbuf)
+ if (other && !forceit && curbuf->b_nwindows == 1 && !buf_hide(curbuf)
&& curbufIsChanged() && autowrite(curbuf, forceit) == FAIL)
{
#if defined(FEAT_GUI_DIALOG) || defined(FEAT_CON_DIALOG)
@@ -3590,7 +3590,7 @@ getfile(
retval = GETFILE_SAME_FILE; /* it's in the same file */
}
else if (do_ecmd(fnum, ffname, sfname, NULL, lnum,
- (P_HID(curbuf) ? ECMD_HIDE : 0) + (forceit ? ECMD_FORCEIT : 0),
+ (buf_hide(curbuf) ? ECMD_HIDE : 0) + (forceit ? ECMD_FORCEIT : 0),
curwin) == OK)
retval = GETFILE_OPEN_OTHER; /* opened another file */
else
@@ -8401,7 +8401,7 @@ ex_drop(exarg_T *eap)
* Skip the check if the 'hidden' option is set, as in this case the
* buffer won't be lost.
*/
- if (!P_HID(curbuf))
+ if (!buf_hide(curbuf))
{
# ifdef FEAT_WINDOWS
++emsg_off;
diff --git a/src/ex_cmds2.c b/src/ex_cmds2.c
index 381c5d1c25..26b588c650 100644
--- a/src/ex_cmds2.c
+++ b/src/ex_cmds2.c
@@ -2064,7 +2064,7 @@ dialog_changed(
int
can_abandon(buf_T *buf, int forceit)
{
- return ( P_HID(buf)
+ return ( buf_hide(buf)
|| !bufIsChanged(buf)
|| buf->b_nwindows > 1
|| autowrite(buf, forceit) == OK
@@ -2180,7 +2180,14 @@ check_changed_any(
msg_col = 0;
msg_didout = FALSE;
}
- if (EMSG2(_("E162: No write since last change for buffer \"%s\""),
+ if (
+#ifdef FEAT_TERMINAL
+ term_job_running(buf->b_term)
+ ? EMSG2(_("E947: Job still running in buffer \"%s\""),
+ buf->b_fname)
+ :
+#endif
+ EMSG2(_("E162: No write since last change for buffer \"%s\""),
buf_spname(buf) != NULL ? buf_spname(buf) : buf->b_fname))
{
save = no_wait_return;
@@ -2734,13 +2741,13 @@ do_argfile(exarg_T *eap, int argn)
* the same buffer
*/
other = TRUE;
- if (P_HID(curbuf))
+ if (buf_hide(curbuf))
{
p = fix_fname(alist_name(&ARGLIST[argn]));
other = otherfile(p);
vim_free(p);
}
- if ((!P_HID(curbuf) || !other)
+ if ((!buf_hide(curbuf) || !other)
&& check_changed(curbuf, CCGD_AW
| (other ? 0 : CCGD_MULTWIN)
| (eap->forceit ? CCGD_FORCEIT : 0)
@@ -2761,7 +2768,7 @@ do_argfile(exarg_T *eap, int argn)
* argument index. */
if (do_ecmd(0, alist_name(&ARGLIST[curwin->w_arg_idx]), NULL,
eap, ECMD_LAST,
- (P_HID(curwin->w_buffer) ? ECMD_HIDE : 0)
+ (buf_hide(curwin->w_buffer) ? ECMD_HIDE : 0)
+ (eap->forceit ? ECMD_FORCEIT : 0), curwin) == FAIL)
curwin->w_arg_idx = old_arg_idx;
/* like Vi: set the mark where the cursor is in the file. */
@@ -2782,7 +2789,7 @@ ex_next(exarg_T *eap)
* check for changed buffer now, if this fails the argument list is not
* redefined.
*/
- if ( P_HID(curbuf)
+ if ( buf_hide(curbuf)
|| eap->cmdidx == CMD_snext
|| !check_changed(curbuf, CCGD_AW
| (eap->forceit ? CCGD_FORCEIT : 0)
@@ -2937,7 +2944,7 @@ ex_listdo(exarg_T *eap)
if (eap->cmdidx == CMD_windo
|| eap->cmdidx == CMD_tabdo
- || P_HID(curbuf)
+ || buf_hide(curbuf)
|| !check_changed(curbuf, CCGD_AW
| (eap->forceit ? CCGD_FORCEIT : 0)
| CCGD_EXCMD))
diff --git a/src/ex_docmd.c b/src/ex_docmd.c
index f913b19cdf..c61cd2e955 100644
--- a/src/ex_docmd.c
+++ b/src/ex_docmd.c
@@ -7291,7 +7291,7 @@ ex_quit(exarg_T *eap)
*/
if (check_more(FALSE, eap->forceit) == OK && only_one_window())
exiting = TRUE;
- if ((!P_HID(curbuf)
+ if ((!buf_hide(curbuf)
&& check_changed(curbuf, (p_awa ? CCGD_AW : 0)
| (eap->forceit ? CCGD_FORCEIT : 0)
| CCGD_EXCMD))
@@ -7318,7 +7318,7 @@ ex_quit(exarg_T *eap)
need_mouse_correct = TRUE;
# endif
/* close window; may free buffer */
- win_close(wp, !P_HID(wp->w_buffer) || eap->forceit);
+ win_close(wp, !buf_hide(wp->w_buffer) || eap->forceit);
#endif
}
}
@@ -7438,7 +7438,7 @@ ex_win_close(
buf_T *buf = win->w_buffer;
need_hide = (bufIsChanged(buf) && buf->b_nwindows <= 1);
- if (need_hide && !P_HID(buf) && !forceit)
+ if (need_hide && !buf_hide(buf) && !forceit)
{
# if defined(FEAT_GUI_DIALOG) || defined(FEAT_CON_DIALOG)
if ((p_confirm || cmdmod.confirm) && p_write)
@@ -7465,9 +7465,9 @@ ex_win_close(
/* free buffer when not hiding it or when it's a scratch buffer */
if (tp == NULL)
- win_close(win, !need_hide && !P_HID(buf));
+ win_close(win, !need_hide && !buf_hide(buf));
else
- win_close_othertab(win, !need_hide && !P_HID(buf), tp);
+ win_close_othertab(win, !need_hide && !buf_hide(buf), tp);
}
/*
@@ -7864,7 +7864,7 @@ ex_exit(exarg_T *eap)
need_mouse_correct = TRUE;
# endif
/* Quit current window, may free the buffer. */
- win_close(curwin, !P_HID(curwin->w_buffer));
+ win_close(curwin, !buf_hide(curwin->w_buffer));
#endif
}
}
@@ -7960,7 +7960,7 @@ handle_drop(
* We don't need to check if the 'hidden' option is set, as in this
* case the buffer won't be lost.
*/
- if (!P_HID(curbuf) && !split)
+ if (!buf_hide(curbuf) && !split)
{
++emsg_off;
split = check_changed(curbuf, CCGD_AW);
@@ -8747,7 +8747,7 @@ do_exedit(
(*eap->arg == NUL && eap->do_ecmd_lnum == 0
&& vim_strchr(p_cpo, CPO_GOTO1) != NULL)
? ECMD_ONE : eap->do_ecmd_lnum,
- (P_HID(curbuf) ? ECMD_HIDE : 0)
+ (buf_hide(curbuf) ? ECMD_HIDE : 0)
+ (eap->forceit ? ECMD_FORCEIT : 0)
/* after a split we can use an existing buffer */
+ (old_curwin != NULL ? ECMD_OLDBUF : 0)
@@ -8761,7 +8761,7 @@ do_exedit(
if (old_curwin != NULL)
{
need_hide = (curbufIsChanged() && curbuf->b_nwindows <= 1);
- if (!need_hide || P_HID(curbuf))
+ if (!need_hide || buf_hide(curbuf))
{
# if defined(FEAT_AUTOCMD) && defined(FEAT_EVAL)
cleanup_T cs;
@@ -8773,7 +8773,7 @@ do_exedit(
# ifdef FEAT_GUI
need_mouse_correct = TRUE;
# endif
- win_close(curwin, !need_hide && !P_HID(curbuf));
+ win_close(curwin, !need_hide && !buf_hide(curbuf));
# if defined(FEAT_AUTOCMD) && defined(FEAT_EVAL)
/* Restore the error/interrupt/exception state if not
diff --git a/src/normal.c b/src/normal.c
index d655c74677..16f9f0ea5a 100644
--- a/src/normal.c
+++ b/src/normal.c
@@ -6255,11 +6255,11 @@ nv_gotofile(cmdarg_T *cap)
if (ptr != NULL)
{
/* do autowrite if necessary */
- if (curbufIsChanged() && curbuf->b_nwindows <= 1 && !P_HID(curbuf))
+ if (curbufIsChanged() && curbuf->b_nwindows <= 1 && !buf_hide(curbuf))
(void)autowrite(curbuf, FALSE);
setpcmark();
if (do_ecmd(0, ptr, NULL, NULL, ECMD_LAST,
- P_HID(curbuf) ? ECMD_HIDE : 0, curwin) == OK
+ buf_hide(curbuf) ? ECMD_HIDE : 0, curwin) == OK
&& cap->nchar == 'F' && lnum >= 0)
{
curwin->w_cursor.lnum = lnum;
diff --git a/src/option.h b/src/option.h
index 89c7922050..9b7e88f0d2 100644
--- a/src/option.h
+++ b/src/option.h
@@ -558,13 +558,6 @@ EXTERN long p_hh; /* 'helpheight' */
EXTERN char_u *p_hlg; /* 'helplang' */
#endif
EXTERN int p_hid; /* 'hidden' */
-/* Use P_HID to check if a buffer is to be hidden when it is no longer
- * visible in a window. */
-#ifndef FEAT_QUICKFIX
-# define P_HID(dummy) (p_hid || cmdmod.hide)
-#else
-# define P_HID(buf) (buf_hide(buf))
-#endif
EXTERN char_u *p_hl; /* 'highlight' */
EXTERN int p_hls; /* 'hlsearch' */
EXTERN long p_hi; /* 'history' */
diff --git a/src/terminal.c b/src/terminal.c
index d153187999..a4120b39c6 100644
--- a/src/terminal.c
+++ b/src/terminal.c
@@ -36,7 +36,6 @@
* that buffer, attributes come from the scrollback buffer tl_scrollback.
*
* TODO:
- * - don't allow exiting Vim when a terminal is still running a job
* - MS-Windows: no redraw for 'updatetime' #1915
* - in bash mouse clicks are inserting characters.
* - mouse scroll: when over other window, scroll that window.
@@ -284,11 +283,16 @@ term_start(char_u *cmd, jobopt_T *opt)
}
curbuf->b_fname = curbuf->b_ffname;
+ set_string_option_direct((char_u *)"buftype", -1,
+ (char_u *)"terminal", OPT_FREE|OPT_LOCAL, 0);
+
/* 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);
+
+ /* Set 'bufhidden' to "hide": allow closing the window. */
+ set_string_option_direct((char_u *)"bufhidden", -1,
+ (char_u *)"hide", OPT_FREE|OPT_LOCAL, 0);
set_term_and_win_size(term);
setup_job_options(opt, term->tl_rows, term->tl_cols);
diff --git a/src/testdir/test_terminal.vim b/src/testdir/test_terminal.vim
index 3f5e268b5b..98bc75843e 100644
--- a/src/testdir/test_terminal.vim
+++ b/src/testdir/test_terminal.vim
@@ -63,7 +63,8 @@ endfunc
func Test_terminal_wipe_buffer()
let buf = Run_shell_in_terminal()
- exe buf . 'bwipe'
+ call assert_fails(buf . 'bwipe', 'E517')
+ exe buf . 'bwipe!'
call WaitFor('job_status(g:job) == "dead"')
call assert_equal('dead', job_status(g:job))
call assert_equal("", bufname(buf))
diff --git a/src/undo.c b/src/undo.c
index 6ab8572aa0..b913841f70 100644
--- a/src/undo.c
+++ b/src/undo.c
@@ -3522,21 +3522,18 @@ u_save_line(linenr_T lnum)
int
bufIsChanged(buf_T *buf)
{
- return
-#ifdef FEAT_QUICKFIX
- !bt_dontwrite(buf) &&
+#ifdef FEAT_TERMINAL
+ if (term_job_running(buf->b_term))
+ return TRUE;
#endif
- (buf->b_changed || file_ff_differs(buf, TRUE));
+ return !bt_dontwrite(buf)
+ && (buf->b_changed || file_ff_differs(buf, TRUE));
}
int
curbufIsChanged(void)
{
- return
-#ifdef FEAT_QUICKFIX
- !bt_dontwrite(curbuf) &&
-#endif
- (curbuf->b_changed || file_ff_differs(curbuf, TRUE));
+ return bufIsChanged(curbuf);
}
#if defined(FEAT_EVAL) || defined(PROTO)
diff --git a/src/version.c b/src/version.c
index 1c01f4f041..e50eeaf637 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 */
/**/
+ 858,
+/**/
857,
/**/
856,
diff --git a/src/window.c b/src/window.c
index 948303c093..311009837c 100644
--- a/src/window.c
+++ b/src/window.c
@@ -3379,7 +3379,8 @@ close_others(
#endif
continue;
}
- win_close(wp, !P_HID(wp->w_buffer) && !bufIsChanged(wp->w_buffer));
+ win_close(wp, !buf_hide(wp->w_buffer)
+ && !bufIsChanged(wp->w_buffer));
}
}