Mercurial > vim
diff src/terminal.c @ 12393:128cd982c7b8 v8.0.1076
patch 8.0.1076: term_start() does not take callbacks
commit https://github.com/vim/vim/commit/3c518400d1a51929572dd9fcf77dba94d78d7545
Author: Bram Moolenaar <Bram@vim.org>
Date: Fri Sep 8 20:47:00 2017 +0200
patch 8.0.1076: term_start() does not take callbacks
Problem: term_start() does not take callbacks. When using two terminals
without a job only one is read from. A terminal without a window
returns the wrong pty.
Solution: Support "callback", "out_cb" and "err_cb". Fix terminal without a
window. Fix reading from multiple channels.
author | Christian Brabandt <cb@256bit.org> |
---|---|
date | Fri, 08 Sep 2017 21:00:04 +0200 |
parents | 438c64b76eef |
children | eb8d5c4936f1 |
line wrap: on
line diff
--- a/src/terminal.c +++ b/src/terminal.c @@ -245,7 +245,11 @@ setup_job_options(jobopt_T *opt, int row opt->jo_term_cols = cols; } - static void +/* + * Start a terminal window and return its buffer. + * Returns NULL when failed. + */ + static buf_T * term_start(typval_T *argvar, jobopt_T *opt, int forceit) { exarg_T split_ea; @@ -253,9 +257,10 @@ term_start(typval_T *argvar, jobopt_T *o term_T *term; buf_T *old_curbuf = NULL; int res; + buf_T *newbuf; if (check_restricted() || check_secure()) - return; + return NULL; if ((opt->jo_set & (JO_IN_IO + JO_OUT_IO + JO_ERR_IO)) == (JO_IN_IO + JO_OUT_IO + JO_ERR_IO) @@ -263,12 +268,12 @@ term_start(typval_T *argvar, jobopt_T *o || (!(opt->jo_set & JO_ERR_IO) && (opt->jo_set & JO_ERR_BUF))) { EMSG(_(e_invarg)); - return; + return NULL; } term = (term_T *)alloc_clear(sizeof(term_T)); if (term == NULL) - return; + return NULL; term->tl_dirty_row_end = MAX_ROW; term->tl_cursor_visible = TRUE; term->tl_cursor_shape = VTERM_PROP_CURSORSHAPE_BLOCK; @@ -283,13 +288,13 @@ term_start(typval_T *argvar, jobopt_T *o { no_write_message(); vim_free(term); - return; + return NULL; } if (do_ecmd(0, NULL, NULL, &split_ea, ECMD_ONE, ECMD_HIDE + (forceit ? ECMD_FORCEIT : 0), curwin) == FAIL) { vim_free(term); - return; + return NULL; } } else if (opt->jo_hidden) @@ -303,7 +308,7 @@ term_start(typval_T *argvar, jobopt_T *o if (buf == NULL || ml_open(buf) == FAIL) { vim_free(term); - return; + return NULL; } old_curbuf = curbuf; --curbuf->b_nwindows; @@ -333,7 +338,7 @@ term_start(typval_T *argvar, jobopt_T *o { /* split failed */ vim_free(term); - return; + return NULL; } } term->tl_buffer = curbuf; @@ -419,6 +424,7 @@ term_start(typval_T *argvar, jobopt_T *o else res = term_and_job_init(term, argvar, opt); + newbuf = curbuf; if (res == OK) { /* Get and remember the size we ended up with. Update the pty. */ @@ -453,7 +459,9 @@ term_start(typval_T *argvar, jobopt_T *o /* Wiping out the buffer will also close the window and call * free_terminal(). */ do_buffer(DOBUF_WIPE, DOBUF_FIRST, FORWARD, buf->b_fnum, TRUE); + return NULL; } + return newbuf; } /* @@ -688,7 +696,7 @@ write_to_term(buf_T *buffer, char_u *msg update_screen(0); update_cursor(term, TRUE); } - else + else if (buffer->b_nwindows > 0) redraw_after_callback(TRUE); } } @@ -879,6 +887,20 @@ term_job_running(term_T *term) } /* + * Return TRUE if "term" has an active channel and used ":term NONE". + */ + int +term_none_open(term_T *term) +{ + /* Also consider the job finished when the channel is closed, to avoid a + * race condition when updating the title. */ + return term != NULL + && term->tl_job != NULL + && channel_is_open(term->tl_job->jv_channel) + && term->tl_job->jv_channel->ch_keep_open; +} + +/* * Add the last line of the scrollback buffer to the buffer in the window. */ static void @@ -2379,6 +2401,8 @@ term_get_status_text(term_T *term) } else if (term->tl_title != NULL) txt = term->tl_title; + else if (term_none_open(term)) + txt = (char_u *)_("active"); else if (term_job_running(term)) txt = (char_u *)_("running"); else @@ -2858,11 +2882,13 @@ f_term_sendkeys(typval_T *argvars, typva f_term_start(typval_T *argvars, typval_T *rettv) { jobopt_T opt; + buf_T *buf; init_job_options(&opt); if (argvars[1].v_type != VAR_UNKNOWN && get_job_options(&argvars[1], &opt, JO_TIMEOUT_ALL + JO_STOPONEXIT + + JO_CALLBACK + JO_OUT_CALLBACK + JO_ERR_CALLBACK + JO_EXIT_CB + JO_CLOSE_CALLBACK + JO_OUT_IO, JO2_TERM_NAME + JO2_TERM_FINISH + JO2_HIDDEN + JO2_TERM_OPENCMD + JO2_TERM_COLS + JO2_TERM_ROWS + JO2_VERTICAL + JO2_CURWIN @@ -2871,10 +2897,10 @@ f_term_start(typval_T *argvars, typval_T if (opt.jo_vertical) cmdmod.split = WSP_VERT; - term_start(&argvars[0], &opt, FALSE); - - if (curbuf->b_term != NULL) - rettv->vval.v_number = curbuf->b_fnum; + buf = term_start(&argvars[0], &opt, FALSE); + + if (buf != NULL && buf->b_term != NULL) + rettv->vval.v_number = buf->b_fnum; } /* @@ -3359,8 +3385,6 @@ term_and_job_init( static int create_pty_only(term_T *term, jobopt_T *opt) { - int ret; - create_vterm(term, term->tl_rows, term->tl_cols); term->tl_job = job_alloc(); @@ -3371,9 +3395,7 @@ create_pty_only(term_T *term, jobopt_T * /* behave like the job is already finished */ term->tl_job->jv_status = JOB_FINISHED; - ret = mch_create_pty_channel(term->tl_job, opt); - - return ret; + return mch_create_pty_channel(term->tl_job, opt); } /*