# HG changeset patch # User Christian Brabandt # Date 1502483406 -7200 # Node ID a879814b8a3737b2559448194c94c362c4f73174 # Parent 4ee89f4c6b2580dc028ebeb4fa3220d5c01b25b2 patch 8.0.0910: cannot create a terminal in the current window commit https://github.com/vim/vim/commit/da43b61dddcf81439a6f1716956a4e8d9046e68f Author: Bram Moolenaar Date: Fri Aug 11 22:27:50 2017 +0200 patch 8.0.0910: cannot create a terminal in the current window Problem: Cannot create a terminal in the current window. Solution: Add option "curwin" and ++curwin. diff --git a/runtime/doc/eval.txt b/runtime/doc/eval.txt --- a/runtime/doc/eval.txt +++ b/runtime/doc/eval.txt @@ -8077,6 +8077,9 @@ term_start({cmd}, {options}) *term_st "term_cols" horizontal size to use for the terminal, instead of using 'termsize' "vertical" split the window vertically + "curwin" use the current window, do not split the + window; fails if the current buffer + cannot be |abandon|ed "term_finish" What to do when the job is finished: "close": close any windows "open": open window if needed diff --git a/src/channel.c b/src/channel.c --- a/src/channel.c +++ b/src/channel.c @@ -4455,6 +4455,13 @@ get_job_options(typval_T *tv, jobopt_T * opt->jo_set |= JO2_VERTICAL; opt->jo_vertical = get_tv_number(item); } + else if (STRCMP(hi->hi_key, "curwin") == 0) + { + if (!(supported2 & JO2_CURWIN)) + break; + opt->jo_set |= JO2_CURWIN; + opt->jo_curwin = get_tv_number(item); + } #endif else if (STRCMP(hi->hi_key, "env") == 0) { diff --git a/src/ex_cmds.h b/src/ex_cmds.h --- a/src/ex_cmds.h +++ b/src/ex_cmds.h @@ -1484,7 +1484,7 @@ EX(CMD_tearoff, "tearoff", ex_tearoff, NEEDARG|EXTRA|TRLBAR|NOTRLCOM|CMDWIN, ADDR_LINES), EX(CMD_terminal, "terminal", ex_terminal, - RANGE|NOTADR|FILES|TRLBAR|CMDWIN, + RANGE|NOTADR|BANG|FILES|TRLBAR|CMDWIN, ADDR_OTHER), EX(CMD_tfirst, "tfirst", ex_tag, RANGE|NOTADR|BANG|TRLBAR|ZEROR, diff --git a/src/structs.h b/src/structs.h --- a/src/structs.h +++ b/src/structs.h @@ -1691,7 +1691,8 @@ struct channel_S { #define JO2_TERM_ROWS 0x0040 /* "term_rows" */ #define JO2_TERM_COLS 0x0080 /* "term_cols" */ #define JO2_VERTICAL 0x0100 /* "vertical" */ -#define JO2_ALL 0x01FF +#define JO2_CURWIN 0x0200 /* "curwin" */ +#define JO2_ALL 0x03FF #define JO_MODE_ALL (JO_MODE + JO_IN_MODE + JO_OUT_MODE + JO_ERR_MODE) #define JO_CB_ALL \ @@ -1752,6 +1753,7 @@ typedef struct int jo_term_rows; int jo_term_cols; int jo_vertical; + int jo_curwin; char_u *jo_term_name; int jo_term_finish; #endif diff --git a/src/terminal.c b/src/terminal.c --- a/src/terminal.c +++ b/src/terminal.c @@ -244,7 +244,7 @@ setup_job_options(jobopt_T *opt, int row } static void -term_start(char_u *cmd, jobopt_T *opt) +term_start(char_u *cmd, jobopt_T *opt, int forceit) { exarg_T split_ea; win_T *old_curwin = curwin; @@ -261,28 +261,43 @@ term_start(char_u *cmd, jobopt_T *opt) term->tl_finish = opt->jo_term_finish; ga_init2(&term->tl_scrollback, sizeof(sb_line_T), 300); - /* Open a new window or tab. */ vim_memset(&split_ea, 0, sizeof(split_ea)); - split_ea.cmdidx = CMD_new; - split_ea.cmd = (char_u *)"new"; - split_ea.arg = (char_u *)""; - if (opt->jo_term_rows > 0 && !(cmdmod.split & WSP_VERT)) + if (opt->jo_curwin) { - split_ea.line2 = opt->jo_term_rows; - split_ea.addr_count = 1; + /* Create a new buffer in the current window. */ + if (!can_abandon(curbuf, forceit)) + { + EMSG(_(e_nowrtmsg)); + return; + } + if (do_ecmd(0, NULL, NULL, &split_ea, ECMD_ONE, + ECMD_HIDE + (forceit ? ECMD_FORCEIT : 0), curwin) == FAIL) + return; } - if (opt->jo_term_cols > 0 && (cmdmod.split & WSP_VERT)) + else { - split_ea.line2 = opt->jo_term_cols; - split_ea.addr_count = 1; - } + /* Open a new window or tab. */ + split_ea.cmdidx = CMD_new; + split_ea.cmd = (char_u *)"new"; + split_ea.arg = (char_u *)""; + if (opt->jo_term_rows > 0 && !(cmdmod.split & WSP_VERT)) + { + split_ea.line2 = opt->jo_term_rows; + split_ea.addr_count = 1; + } + if (opt->jo_term_cols > 0 && (cmdmod.split & WSP_VERT)) + { + split_ea.line2 = opt->jo_term_cols; + split_ea.addr_count = 1; + } - ex_splitview(&split_ea); - if (curwin == old_curwin) - { - /* split failed */ - vim_free(term); - return; + ex_splitview(&split_ea); + if (curwin == old_curwin) + { + /* split failed */ + vim_free(term); + return; + } } term->tl_buffer = curbuf; curbuf->b_term = term; @@ -378,6 +393,8 @@ ex_terminal(exarg_T *eap) opt.jo_term_finish = 'c'; else if ((int)(p - cmd) == 4 && STRNICMP(cmd, "open", 4) == 0) opt.jo_term_finish = 'o'; + else if ((int)(p - cmd) == 6 && STRNICMP(cmd, "curwin", 6) == 0) + opt.jo_curwin = 1; else { if (*p) @@ -400,9 +417,8 @@ ex_terminal(exarg_T *eap) else opt.jo_term_rows = eap->line2; } - /* TODO: get more options from before the command */ - term_start(cmd, &opt); + term_start(cmd, &opt, eap->forceit); } /* @@ -2365,13 +2381,13 @@ f_term_start(typval_T *argvars, typval_T JO_TIMEOUT_ALL + JO_STOPONEXIT + JO_EXIT_CB + JO_CLOSE_CALLBACK, JO2_TERM_NAME + JO2_TERM_FINISH - + JO2_TERM_COLS + JO2_TERM_ROWS + JO2_VERTICAL + + JO2_TERM_COLS + JO2_TERM_ROWS + JO2_VERTICAL + JO2_CURWIN + JO2_CWD + JO2_ENV) == FAIL) return; if (opt.jo_vertical) cmdmod.split = WSP_VERT; - term_start(cmd, &opt); + term_start(cmd, &opt, FALSE); if (curbuf->b_term != NULL) rettv->vval.v_number = curbuf->b_fnum; diff --git a/src/testdir/test_terminal.vim b/src/testdir/test_terminal.vim --- a/src/testdir/test_terminal.vim +++ b/src/testdir/test_terminal.vim @@ -283,6 +283,38 @@ func Test_terminal_size() let size = term_getsize('') bwipe! call assert_equal([7, 27], size) +endfunc + +func Test_terminal_curwin() + let cmd = Get_cat_123_cmd() + call assert_equal(1, winnr('$')) + + split dummy + exe 'terminal ++curwin ' . cmd + call assert_equal(2, winnr('$')) + bwipe! + + split dummy + call term_start(cmd, {'curwin': 1}) + call assert_equal(2, winnr('$')) + bwipe! + + split dummy + call setline(1, 'change') + call assert_fails('terminal ++curwin ' . cmd, 'E37:') + call assert_equal(2, winnr('$')) + exe 'terminal! ++curwin ' . cmd + call assert_equal(2, winnr('$')) + bwipe! + + split dummy + call setline(1, 'change') + call assert_fails("call term_start(cmd, {'curwin': 1})", 'E37:') + call assert_equal(2, winnr('$')) + bwipe! + + split dummy + bwipe! endfunc diff --git a/src/version.c b/src/version.c --- 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 */ /**/ + 910, +/**/ 909, /**/ 908,