summaryrefslogtreecommitdiff
path: root/src/terminal.c
diff options
context:
space:
mode:
authorBram Moolenaar <Bram@vim.org>2017-08-10 23:15:19 +0200
committerBram Moolenaar <Bram@vim.org>2017-08-10 23:15:19 +0200
commitdd693ce28b158ff573129ee30fe5b886544a03c2 (patch)
tree0ec7629d6fc498db9f7b6880e121bdba6467a7d6 /src/terminal.c
parent8ab3c1dc6bf70021f89e6e614b202606863bc168 (diff)
downloadvim-git-dd693ce28b158ff573129ee30fe5b886544a03c2.tar.gz
patch 8.0.0896: cannot close a terminal window when the job endsv8.0.0896
Problem: Cannot automaticlaly close a terminal window when the job ends. Solution: Add the ++close argument to :term. Add the term_finish option to term_start(). (Yasuhiro Matsumoto, closes #1950) Also add ++open.
Diffstat (limited to 'src/terminal.c')
-rw-r--r--src/terminal.c65
1 files changed, 53 insertions, 12 deletions
diff --git a/src/terminal.c b/src/terminal.c
index 36d5cf15d..b1cb61fc0 100644
--- a/src/terminal.c
+++ b/src/terminal.c
@@ -36,18 +36,14 @@
* that buffer, attributes come from the scrollback buffer tl_scrollback.
*
* TODO:
- * - When the job ends:
- * - Need an option or argument to drop the window+buffer right away, to be
- * used for a shell or Vim. 'termfinish'; "close", "open" (open window when
- * job finishes).
- * patch by Yasuhiro: #1950
* - add option values to the command:
- * :term <24x80> <close> vim notes.txt
- * or use:
* :term ++24x80 ++close vim notes.txt
+ * - When using term_finish "open" have a way to specify how the window is to
+ * be opened. E.g. term_opencmd "10split buffer %d".
* - support different cursor shapes, colors and attributes
* - make term_getcursor() return type (none/block/bar/underline) and
* attributes (color, blink, etc.)
+ * - Make argument list work on MS-Windows. #1954
* - MS-Windows: no redraw for 'updatetime' #1915
* - To set BS correctly, check get_stty(); Pass the fd of the pty.
* For the GUI fill termios with default values, perhaps like pangoterm:
@@ -124,6 +120,7 @@ struct terminal_S {
int tl_normal_mode; /* TRUE: Terminal-Normal mode */
int tl_channel_closed;
+ int tl_finish; /* 'c' for ++close, 'o' for ++open */
#ifdef WIN3264
void *tl_winpty_config;
@@ -257,6 +254,7 @@ term_start(char_u *cmd, jobopt_T *opt)
return;
term->tl_dirty_row_end = MAX_ROW;
term->tl_cursor_visible = TRUE;
+ term->tl_finish = opt->jo_term_finish;
ga_init2(&term->tl_scrollback, sizeof(sb_line_T), 300);
/* Open a new window or tab. */
@@ -360,10 +358,32 @@ term_start(char_u *cmd, jobopt_T *opt)
void
ex_terminal(exarg_T *eap)
{
- jobopt_T opt;
+ jobopt_T opt;
+ char_u *cmd;
init_job_options(&opt);
+ cmd = eap->arg;
+ while (*cmd && *cmd == '+' && *(cmd + 1) == '+')
+ {
+ char_u *p;
+
+ cmd += 2;
+ p = skiptowhite(cmd);
+ if ((int)(p - cmd) == 5 && STRNICMP(cmd, "close", 5) == 0)
+ opt.jo_term_finish = 'c';
+ else if ((int)(p - cmd) == 4 && STRNICMP(cmd, "open", 4) == 0)
+ opt.jo_term_finish = 'o';
+ else
+ {
+ if (*p)
+ *p = NUL;
+ EMSG2(_("E181: Invalid attribute: %s"), cmd);
+ return;
+ }
+ cmd = skipwhite(p);
+ }
+
if (eap->addr_count == 2)
{
opt.jo_term_rows = eap->line1;
@@ -378,7 +398,7 @@ ex_terminal(exarg_T *eap)
}
/* TODO: get more options from before the command */
- term_start(eap->arg, &opt);
+ term_start(cmd, &opt);
}
/*
@@ -846,7 +866,8 @@ set_terminal_mode(term_T *term, int normal_mode)
static void
cleanup_vterm(term_T *term)
{
- move_terminal_to_buffer(term);
+ if (term->tl_finish == 0)
+ move_terminal_to_buffer(term);
term_free_vterm(term);
set_terminal_mode(term, FALSE);
}
@@ -1415,6 +1436,7 @@ term_channel_closed(channel_T *ch)
if (term->tl_job == ch->ch_job)
{
term->tl_channel_closed = TRUE;
+ did_one = TRUE;
vim_free(term->tl_title);
term->tl_title = NULL;
@@ -1423,10 +1445,29 @@ term_channel_closed(channel_T *ch)
/* Unless in Terminal-Normal mode: clear the vterm. */
if (!term->tl_normal_mode)
+ {
+ int fnum = term->tl_buffer->b_fnum;
+
cleanup_vterm(term);
+ if (term->tl_finish == 'c')
+ {
+ /* ++close or term_finish == "close" */
+ curbuf = term->tl_buffer;
+ do_bufdel(DOBUF_WIPE, (char_u *)"", 1, fnum, fnum, FALSE);
+ break;
+ }
+ if (term->tl_finish == 'o' && term->tl_buffer->b_nwindows == 0)
+ {
+ char buf[50];
+
+ /* TODO: use term_opencmd */
+ vim_snprintf(buf, sizeof(buf), "botright sbuf %d", fnum);
+ do_cmdline_cmd((char_u *)buf);
+ }
+ }
+
redraw_buf_and_status_later(term->tl_buffer, NOT_VALID);
- did_one = TRUE;
}
if (did_one)
{
@@ -2298,7 +2339,7 @@ f_term_start(typval_T *argvars, typval_T *rettv)
&& get_job_options(&argvars[1], &opt,
JO_TIMEOUT_ALL + JO_STOPONEXIT
+ JO_EXIT_CB + JO_CLOSE_CALLBACK
- + JO2_TERM_NAME) == FAIL)
+ + JO2_TERM_NAME + JO2_TERM_FINISH) == FAIL)
return;
term_start(cmd, &opt);