1
0
forked from aniani/vim

patch 8.0.0896: cannot close a terminal window when the job ends

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.
This commit is contained in:
Bram Moolenaar
2017-08-10 23:15:19 +02:00
parent 8ab3c1dc6b
commit dd693ce28b
7 changed files with 160 additions and 37 deletions

View File

@@ -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);