summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBram Moolenaar <Bram@vim.org>2017-08-11 22:27:50 +0200
committerBram Moolenaar <Bram@vim.org>2017-08-11 22:27:50 +0200
commitda43b61dddcf81439a6f1716956a4e8d9046e68f (patch)
treec7433cdf21bc7e992efb60e5fda531140df395c6
parent8ed54007399f968aab447ae6cb46623b1bdbc75e (diff)
downloadvim-da43b61dddcf81439a6f1716956a4e8d9046e68f.zip
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.
-rw-r--r--runtime/doc/eval.txt3
-rw-r--r--src/channel.c7
-rw-r--r--src/ex_cmds.h2
-rw-r--r--src/structs.h4
-rw-r--r--src/terminal.c60
-rw-r--r--src/testdir/test_terminal.vim32
-rw-r--r--src/version.c2
7 files changed, 86 insertions, 24 deletions
diff --git a/runtime/doc/eval.txt b/runtime/doc/eval.txt
index b5bc10028..bd92b3dc2 100644
--- a/runtime/doc/eval.txt
+++ b/runtime/doc/eval.txt
@@ -8077,6 +8077,9 @@ term_start({cmd}, {options}) *term_start()*
"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
index 58b0b0c9a..9476276ac 100644
--- a/src/channel.c
+++ b/src/channel.c
@@ -4455,6 +4455,13 @@ get_job_options(typval_T *tv, jobopt_T *opt, int supported, int supported2)
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
index 977b01a8c..6fb528d58 100644
--- 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
index 67b4a9b20..9e2bfa6ee 100644
--- 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
index bab2a5ba4..5281ef31d 100644
--- a/src/terminal.c
+++ b/src/terminal.c
@@ -244,7 +244,7 @@ setup_job_options(jobopt_T *opt, int rows, int cols)
}
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 *rettv)
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
index d58575149..38fbbd9db 100644
--- 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
index 741c4a235..d88001de4 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 */
/**/
+ 910,
+/**/
909,
/**/
908,