mirror of
https://github.com/vim/vim.git
synced 2025-07-26 11:04:33 -04:00
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.
This commit is contained in:
parent
1a735d6c9b
commit
3c518400d1
@ -3692,13 +3692,10 @@ channel_send(
|
|||||||
{
|
{
|
||||||
res = fd_write(fd, (char *)buf, len);
|
res = fd_write(fd, (char *)buf, len);
|
||||||
#ifdef WIN32
|
#ifdef WIN32
|
||||||
if (channel->ch_named_pipe)
|
if (channel->ch_named_pipe && res < 0)
|
||||||
{
|
{
|
||||||
if (res < 0)
|
DisconnectNamedPipe((HANDLE)fd);
|
||||||
{
|
ConnectNamedPipe((HANDLE)fd, NULL);
|
||||||
DisconnectNamedPipe((HANDLE)fd);
|
|
||||||
ConnectNamedPipe((HANDLE)fd, NULL);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@ -4084,6 +4081,7 @@ channel_select_check(int ret_in, void *rfds_in, void *wfds_in)
|
|||||||
if (ret > 0 && fd != INVALID_FD && FD_ISSET(fd, rfds))
|
if (ret > 0 && fd != INVALID_FD && FD_ISSET(fd, rfds))
|
||||||
{
|
{
|
||||||
channel_read(channel, part, "channel_select_check");
|
channel_read(channel, part, "channel_select_check");
|
||||||
|
FD_CLR(fd, rfds);
|
||||||
--ret;
|
--ret;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -4093,6 +4091,7 @@ channel_select_check(int ret_in, void *rfds_in, void *wfds_in)
|
|||||||
&& FD_ISSET(in_part->ch_fd, wfds))
|
&& FD_ISSET(in_part->ch_fd, wfds))
|
||||||
{
|
{
|
||||||
channel_write_input(channel);
|
channel_write_input(channel);
|
||||||
|
FD_CLR(in_part->ch_fd, wfds);
|
||||||
--ret;
|
--ret;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -3,6 +3,7 @@ void ex_terminal(exarg_T *eap);
|
|||||||
void free_terminal(buf_T *buf);
|
void free_terminal(buf_T *buf);
|
||||||
void write_to_term(buf_T *buffer, char_u *msg, channel_T *channel);
|
void write_to_term(buf_T *buffer, char_u *msg, channel_T *channel);
|
||||||
int term_job_running(term_T *term);
|
int term_job_running(term_T *term);
|
||||||
|
int term_none_open(term_T *term);
|
||||||
int term_in_normal_mode(void);
|
int term_in_normal_mode(void);
|
||||||
void term_enter_job_mode(void);
|
void term_enter_job_mode(void);
|
||||||
int send_keys_to_term(term_T *term, int c, int typed);
|
int send_keys_to_term(term_T *term, int c, int typed);
|
||||||
@ -16,7 +17,6 @@ int term_update_window(win_T *wp);
|
|||||||
int term_is_finished(buf_T *buf);
|
int term_is_finished(buf_T *buf);
|
||||||
int term_show_buffer(buf_T *buf);
|
int term_show_buffer(buf_T *buf);
|
||||||
void term_change_in_curbuf(void);
|
void term_change_in_curbuf(void);
|
||||||
void term_send_eof(channel_T *ch);
|
|
||||||
int term_get_attr(buf_T *buf, linenr_T lnum, int col);
|
int term_get_attr(buf_T *buf, linenr_T lnum, int col);
|
||||||
char_u *term_get_status_text(term_T *term);
|
char_u *term_get_status_text(term_T *term);
|
||||||
int set_ref_in_term(int copyID);
|
int set_ref_in_term(int copyID);
|
||||||
@ -35,5 +35,6 @@ void f_term_scrape(typval_T *argvars, typval_T *rettv);
|
|||||||
void f_term_sendkeys(typval_T *argvars, typval_T *rettv);
|
void f_term_sendkeys(typval_T *argvars, typval_T *rettv);
|
||||||
void f_term_start(typval_T *argvars, typval_T *rettv);
|
void f_term_start(typval_T *argvars, typval_T *rettv);
|
||||||
void f_term_wait(typval_T *argvars, typval_T *rettv);
|
void f_term_wait(typval_T *argvars, typval_T *rettv);
|
||||||
|
void term_send_eof(channel_T *ch);
|
||||||
int terminal_enabled(void);
|
int terminal_enabled(void);
|
||||||
/* vim: set ft=c : */
|
/* vim: set ft=c : */
|
||||||
|
@ -245,7 +245,11 @@ setup_job_options(jobopt_T *opt, int rows, int cols)
|
|||||||
opt->jo_term_cols = cols;
|
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)
|
term_start(typval_T *argvar, jobopt_T *opt, int forceit)
|
||||||
{
|
{
|
||||||
exarg_T split_ea;
|
exarg_T split_ea;
|
||||||
@ -253,9 +257,10 @@ term_start(typval_T *argvar, jobopt_T *opt, int forceit)
|
|||||||
term_T *term;
|
term_T *term;
|
||||||
buf_T *old_curbuf = NULL;
|
buf_T *old_curbuf = NULL;
|
||||||
int res;
|
int res;
|
||||||
|
buf_T *newbuf;
|
||||||
|
|
||||||
if (check_restricted() || check_secure())
|
if (check_restricted() || check_secure())
|
||||||
return;
|
return NULL;
|
||||||
|
|
||||||
if ((opt->jo_set & (JO_IN_IO + JO_OUT_IO + JO_ERR_IO))
|
if ((opt->jo_set & (JO_IN_IO + JO_OUT_IO + JO_ERR_IO))
|
||||||
== (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 *opt, int forceit)
|
|||||||
|| (!(opt->jo_set & JO_ERR_IO) && (opt->jo_set & JO_ERR_BUF)))
|
|| (!(opt->jo_set & JO_ERR_IO) && (opt->jo_set & JO_ERR_BUF)))
|
||||||
{
|
{
|
||||||
EMSG(_(e_invarg));
|
EMSG(_(e_invarg));
|
||||||
return;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
term = (term_T *)alloc_clear(sizeof(term_T));
|
term = (term_T *)alloc_clear(sizeof(term_T));
|
||||||
if (term == NULL)
|
if (term == NULL)
|
||||||
return;
|
return NULL;
|
||||||
term->tl_dirty_row_end = MAX_ROW;
|
term->tl_dirty_row_end = MAX_ROW;
|
||||||
term->tl_cursor_visible = TRUE;
|
term->tl_cursor_visible = TRUE;
|
||||||
term->tl_cursor_shape = VTERM_PROP_CURSORSHAPE_BLOCK;
|
term->tl_cursor_shape = VTERM_PROP_CURSORSHAPE_BLOCK;
|
||||||
@ -283,13 +288,13 @@ term_start(typval_T *argvar, jobopt_T *opt, int forceit)
|
|||||||
{
|
{
|
||||||
no_write_message();
|
no_write_message();
|
||||||
vim_free(term);
|
vim_free(term);
|
||||||
return;
|
return NULL;
|
||||||
}
|
}
|
||||||
if (do_ecmd(0, NULL, NULL, &split_ea, ECMD_ONE,
|
if (do_ecmd(0, NULL, NULL, &split_ea, ECMD_ONE,
|
||||||
ECMD_HIDE + (forceit ? ECMD_FORCEIT : 0), curwin) == FAIL)
|
ECMD_HIDE + (forceit ? ECMD_FORCEIT : 0), curwin) == FAIL)
|
||||||
{
|
{
|
||||||
vim_free(term);
|
vim_free(term);
|
||||||
return;
|
return NULL;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (opt->jo_hidden)
|
else if (opt->jo_hidden)
|
||||||
@ -303,7 +308,7 @@ term_start(typval_T *argvar, jobopt_T *opt, int forceit)
|
|||||||
if (buf == NULL || ml_open(buf) == FAIL)
|
if (buf == NULL || ml_open(buf) == FAIL)
|
||||||
{
|
{
|
||||||
vim_free(term);
|
vim_free(term);
|
||||||
return;
|
return NULL;
|
||||||
}
|
}
|
||||||
old_curbuf = curbuf;
|
old_curbuf = curbuf;
|
||||||
--curbuf->b_nwindows;
|
--curbuf->b_nwindows;
|
||||||
@ -333,7 +338,7 @@ term_start(typval_T *argvar, jobopt_T *opt, int forceit)
|
|||||||
{
|
{
|
||||||
/* split failed */
|
/* split failed */
|
||||||
vim_free(term);
|
vim_free(term);
|
||||||
return;
|
return NULL;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
term->tl_buffer = curbuf;
|
term->tl_buffer = curbuf;
|
||||||
@ -419,6 +424,7 @@ term_start(typval_T *argvar, jobopt_T *opt, int forceit)
|
|||||||
else
|
else
|
||||||
res = term_and_job_init(term, argvar, opt);
|
res = term_and_job_init(term, argvar, opt);
|
||||||
|
|
||||||
|
newbuf = curbuf;
|
||||||
if (res == OK)
|
if (res == OK)
|
||||||
{
|
{
|
||||||
/* Get and remember the size we ended up with. Update the pty. */
|
/* Get and remember the size we ended up with. Update the pty. */
|
||||||
@ -453,7 +459,9 @@ term_start(typval_T *argvar, jobopt_T *opt, int forceit)
|
|||||||
/* Wiping out the buffer will also close the window and call
|
/* Wiping out the buffer will also close the window and call
|
||||||
* free_terminal(). */
|
* free_terminal(). */
|
||||||
do_buffer(DOBUF_WIPE, DOBUF_FIRST, FORWARD, buf->b_fnum, TRUE);
|
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, channel_T *channel)
|
|||||||
update_screen(0);
|
update_screen(0);
|
||||||
update_cursor(term, TRUE);
|
update_cursor(term, TRUE);
|
||||||
}
|
}
|
||||||
else
|
else if (buffer->b_nwindows > 0)
|
||||||
redraw_after_callback(TRUE);
|
redraw_after_callback(TRUE);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -878,6 +886,20 @@ term_job_running(term_T *term)
|
|||||||
|| term->tl_job->jv_channel->ch_keep_open);
|
|| term->tl_job->jv_channel->ch_keep_open);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* 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.
|
* Add the last line of the scrollback buffer to the buffer in the window.
|
||||||
*/
|
*/
|
||||||
@ -2379,6 +2401,8 @@ term_get_status_text(term_T *term)
|
|||||||
}
|
}
|
||||||
else if (term->tl_title != NULL)
|
else if (term->tl_title != NULL)
|
||||||
txt = term->tl_title;
|
txt = term->tl_title;
|
||||||
|
else if (term_none_open(term))
|
||||||
|
txt = (char_u *)_("active");
|
||||||
else if (term_job_running(term))
|
else if (term_job_running(term))
|
||||||
txt = (char_u *)_("running");
|
txt = (char_u *)_("running");
|
||||||
else
|
else
|
||||||
@ -2858,11 +2882,13 @@ f_term_sendkeys(typval_T *argvars, typval_T *rettv)
|
|||||||
f_term_start(typval_T *argvars, typval_T *rettv)
|
f_term_start(typval_T *argvars, typval_T *rettv)
|
||||||
{
|
{
|
||||||
jobopt_T opt;
|
jobopt_T opt;
|
||||||
|
buf_T *buf;
|
||||||
|
|
||||||
init_job_options(&opt);
|
init_job_options(&opt);
|
||||||
if (argvars[1].v_type != VAR_UNKNOWN
|
if (argvars[1].v_type != VAR_UNKNOWN
|
||||||
&& get_job_options(&argvars[1], &opt,
|
&& get_job_options(&argvars[1], &opt,
|
||||||
JO_TIMEOUT_ALL + JO_STOPONEXIT
|
JO_TIMEOUT_ALL + JO_STOPONEXIT
|
||||||
|
+ JO_CALLBACK + JO_OUT_CALLBACK + JO_ERR_CALLBACK
|
||||||
+ JO_EXIT_CB + JO_CLOSE_CALLBACK + JO_OUT_IO,
|
+ JO_EXIT_CB + JO_CLOSE_CALLBACK + JO_OUT_IO,
|
||||||
JO2_TERM_NAME + JO2_TERM_FINISH + JO2_HIDDEN + JO2_TERM_OPENCMD
|
JO2_TERM_NAME + JO2_TERM_FINISH + JO2_HIDDEN + JO2_TERM_OPENCMD
|
||||||
+ JO2_TERM_COLS + JO2_TERM_ROWS + JO2_VERTICAL + JO2_CURWIN
|
+ JO2_TERM_COLS + JO2_TERM_ROWS + JO2_VERTICAL + JO2_CURWIN
|
||||||
@ -2871,10 +2897,10 @@ f_term_start(typval_T *argvars, typval_T *rettv)
|
|||||||
|
|
||||||
if (opt.jo_vertical)
|
if (opt.jo_vertical)
|
||||||
cmdmod.split = WSP_VERT;
|
cmdmod.split = WSP_VERT;
|
||||||
term_start(&argvars[0], &opt, FALSE);
|
buf = term_start(&argvars[0], &opt, FALSE);
|
||||||
|
|
||||||
if (curbuf->b_term != NULL)
|
if (buf != NULL && buf->b_term != NULL)
|
||||||
rettv->vval.v_number = curbuf->b_fnum;
|
rettv->vval.v_number = buf->b_fnum;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -3359,8 +3385,6 @@ term_and_job_init(
|
|||||||
static int
|
static int
|
||||||
create_pty_only(term_T *term, jobopt_T *opt)
|
create_pty_only(term_T *term, jobopt_T *opt)
|
||||||
{
|
{
|
||||||
int ret;
|
|
||||||
|
|
||||||
create_vterm(term, term->tl_rows, term->tl_cols);
|
create_vterm(term, term->tl_rows, term->tl_cols);
|
||||||
|
|
||||||
term->tl_job = job_alloc();
|
term->tl_job = job_alloc();
|
||||||
@ -3371,9 +3395,7 @@ create_pty_only(term_T *term, jobopt_T *opt)
|
|||||||
/* behave like the job is already finished */
|
/* behave like the job is already finished */
|
||||||
term->tl_job->jv_status = JOB_FINISHED;
|
term->tl_job->jv_status = JOB_FINISHED;
|
||||||
|
|
||||||
ret = mch_create_pty_channel(term->tl_job, opt);
|
return mch_create_pty_channel(term->tl_job, opt);
|
||||||
|
|
||||||
return ret;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -769,6 +769,8 @@ static char *(features[]) =
|
|||||||
|
|
||||||
static int included_patches[] =
|
static int included_patches[] =
|
||||||
{ /* Add new patch number below this line */
|
{ /* Add new patch number below this line */
|
||||||
|
/**/
|
||||||
|
1076,
|
||||||
/**/
|
/**/
|
||||||
1075,
|
1075,
|
||||||
/**/
|
/**/
|
||||||
|
Loading…
x
Reference in New Issue
Block a user