mirror of
https://github.com/neovim/neovim.git
synced 2025-02-25 18:55:25 -06:00
channels: move away term code from eval.c
This commit is contained in:
parent
1ebc96fe10
commit
3e59c1e20d
@ -1213,6 +1213,12 @@ A jump table for the options with a short description can be found at |Q_op|.
|
|||||||
< |Nvi| also has this option, but it only uses the first character.
|
< |Nvi| also has this option, but it only uses the first character.
|
||||||
See |cmdwin|.
|
See |cmdwin|.
|
||||||
|
|
||||||
|
*'channel'*
|
||||||
|
'channel' number (default: 0)
|
||||||
|
local to buffer
|
||||||
|
|Channel| connected to the buffer. Currently only used by
|
||||||
|
|terminal-emulator|. Is 0 if no terminal is open. Cannot be changed.
|
||||||
|
|
||||||
*'charconvert'* *'ccv'* *E202* *E214* *E513*
|
*'charconvert'* *'ccv'* *E202* *E214* *E513*
|
||||||
'charconvert' 'ccv' string (default "")
|
'charconvert' 'ccv' string (default "")
|
||||||
global
|
global
|
||||||
|
@ -603,6 +603,7 @@ struct file_buffer {
|
|||||||
char_u *b_p_bt; ///< 'buftype'
|
char_u *b_p_bt; ///< 'buftype'
|
||||||
int b_has_qf_entry; ///< quickfix exists for buffer
|
int b_has_qf_entry; ///< quickfix exists for buffer
|
||||||
int b_p_bl; ///< 'buflisted'
|
int b_p_bl; ///< 'buflisted'
|
||||||
|
long b_p_channel; ///< 'channel'
|
||||||
int b_p_cin; ///< 'cindent'
|
int b_p_cin; ///< 'cindent'
|
||||||
char_u *b_p_cino; ///< 'cinoptions'
|
char_u *b_p_cino; ///< 'cinoptions'
|
||||||
char_u *b_p_cink; ///< 'cinkeys'
|
char_u *b_p_cink; ///< 'cinkeys'
|
||||||
|
@ -421,12 +421,12 @@ static void on_channel_output(Stream *stream, Channel *chan, RBuffer *buf,
|
|||||||
static void channel_process_exit_cb(Process *proc, int status, void *data)
|
static void channel_process_exit_cb(Process *proc, int status, void *data)
|
||||||
{
|
{
|
||||||
Channel *chan = data;
|
Channel *chan = data;
|
||||||
if (chan->term && !chan->stream.proc.exited) {
|
if (chan->term) {
|
||||||
chan->stream.proc.exited = true;
|
|
||||||
char msg[sizeof("\r\n[Process exited ]") + NUMBUFLEN];
|
char msg[sizeof("\r\n[Process exited ]") + NUMBUFLEN];
|
||||||
snprintf(msg, sizeof msg, "\r\n[Process exited %d]", proc->status);
|
snprintf(msg, sizeof msg, "\r\n[Process exited %d]", proc->status);
|
||||||
terminal_close(chan->term, msg);
|
terminal_close(chan->term, msg);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (chan->is_rpc) {
|
if (chan->is_rpc) {
|
||||||
channel_process_exit(chan->id, status);
|
channel_process_exit(chan->id, status);
|
||||||
}
|
}
|
||||||
@ -472,3 +472,62 @@ static void on_channel_event(ChannelEvent *ev)
|
|||||||
tv_clear(&rettv);
|
tv_clear(&rettv);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/// Open terminal for channel
|
||||||
|
///
|
||||||
|
/// Channel `chan` is assumed to be an open pty channel,
|
||||||
|
/// and curbuf is assumed to be a new, unmodified buffer.
|
||||||
|
void channel_terminal_open(Channel *chan)
|
||||||
|
{
|
||||||
|
TerminalOptions topts;
|
||||||
|
topts.data = chan;
|
||||||
|
topts.width = chan->stream.pty.width;
|
||||||
|
topts.height = chan->stream.pty.height;
|
||||||
|
topts.write_cb = term_write;
|
||||||
|
topts.resize_cb = term_resize;
|
||||||
|
topts.close_cb = term_close;
|
||||||
|
curbuf->b_p_channel = (long)chan->id; // 'channel' option
|
||||||
|
Terminal *term = terminal_open(topts);
|
||||||
|
chan->term = term;
|
||||||
|
channel_incref(chan);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void term_write(char *buf, size_t size, void *data)
|
||||||
|
{
|
||||||
|
Channel *chan = data;
|
||||||
|
if (chan->stream.proc.in.closed) {
|
||||||
|
// If the backing stream was closed abruptly, there may be write events
|
||||||
|
// ahead of the terminal close event. Just ignore the writes.
|
||||||
|
ILOG("write failed: stream is closed");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
WBuffer *wbuf = wstream_new_buffer(xmemdup(buf, size), size, 1, xfree);
|
||||||
|
wstream_write(&chan->stream.proc.in, wbuf);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void term_resize(uint16_t width, uint16_t height, void *data)
|
||||||
|
{
|
||||||
|
Channel *chan = data;
|
||||||
|
pty_process_resize(&chan->stream.pty, width, height);
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void term_delayed_free(void **argv)
|
||||||
|
{
|
||||||
|
Channel *chan = argv[0];
|
||||||
|
if (chan->stream.proc.in.pending_reqs || chan->stream.proc.out.pending_reqs) {
|
||||||
|
multiqueue_put(chan->events, term_delayed_free, 1, chan);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
terminal_destroy(chan->term);
|
||||||
|
chan->term = NULL;
|
||||||
|
channel_decref(chan);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void term_close(void *data)
|
||||||
|
{
|
||||||
|
Channel *chan = data;
|
||||||
|
process_stop(&chan->stream.proc);
|
||||||
|
multiqueue_put(chan->events, term_delayed_free, 1, data);
|
||||||
|
}
|
||||||
|
|
||||||
|
@ -11550,7 +11550,8 @@ static void f_jobresize(typval_T *argvars, typval_T *rettv, FunPtr fptr)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
pty_process_resize(&data->stream.pty, argvars[1].vval.v_number, argvars[2].vval.v_number);
|
pty_process_resize(&data->stream.pty, argvars[1].vval.v_number,
|
||||||
|
argvars[2].vval.v_number);
|
||||||
rettv->vval.v_number = 1;
|
rettv->vval.v_number = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -16680,13 +16681,6 @@ static void f_termopen(typval_T *argvars, typval_T *rettv, FunPtr fptr)
|
|||||||
if (rettv->vval.v_number <= 0) {
|
if (rettv->vval.v_number <= 0) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
TerminalOptions topts;
|
|
||||||
topts.data = chan;
|
|
||||||
topts.width = term_width;
|
|
||||||
topts.height = curwin->w_height;
|
|
||||||
topts.write_cb = term_write;
|
|
||||||
topts.resize_cb = term_resize;
|
|
||||||
topts.close_cb = term_close;
|
|
||||||
|
|
||||||
int pid = chan->stream.pty.process.pid;
|
int pid = chan->stream.pty.process.pid;
|
||||||
|
|
||||||
@ -16699,9 +16693,7 @@ static void f_termopen(typval_T *argvars, typval_T *rettv, FunPtr fptr)
|
|||||||
(void)setfname(curbuf, (char_u *)buf, NULL, true);
|
(void)setfname(curbuf, (char_u *)buf, NULL, true);
|
||||||
// Save the job id and pid in b:terminal_job_{id,pid}
|
// Save the job id and pid in b:terminal_job_{id,pid}
|
||||||
Error err = ERROR_INIT;
|
Error err = ERROR_INIT;
|
||||||
dict_set_var(curbuf->b_vars, cstr_as_string("terminal_channel_id"),
|
// deprecated: use 'channel' buffer option
|
||||||
INTEGER_OBJ(chan->id), false, false, &err);
|
|
||||||
// deprecated name:
|
|
||||||
dict_set_var(curbuf->b_vars, cstr_as_string("terminal_job_id"),
|
dict_set_var(curbuf->b_vars, cstr_as_string("terminal_job_id"),
|
||||||
INTEGER_OBJ(chan->id), false, false, &err);
|
INTEGER_OBJ(chan->id), false, false, &err);
|
||||||
api_clear_error(&err);
|
api_clear_error(&err);
|
||||||
@ -16709,11 +16701,7 @@ static void f_termopen(typval_T *argvars, typval_T *rettv, FunPtr fptr)
|
|||||||
INTEGER_OBJ(pid), false, false, &err);
|
INTEGER_OBJ(pid), false, false, &err);
|
||||||
api_clear_error(&err);
|
api_clear_error(&err);
|
||||||
|
|
||||||
Terminal *term = terminal_open(topts);
|
channel_terminal_open(chan);
|
||||||
chan->term = term;
|
|
||||||
channel_incref(chan);
|
|
||||||
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// "test_garbagecollect_now()" function
|
// "test_garbagecollect_now()" function
|
||||||
@ -22395,47 +22383,6 @@ static inline bool common_job_callbacks(dict_T *vopts,
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void term_write(char *buf, size_t size, void *d)
|
|
||||||
{
|
|
||||||
Channel *job = d;
|
|
||||||
if (job->stream.proc.in.closed) {
|
|
||||||
// If the backing stream was closed abruptly, there may be write events
|
|
||||||
// ahead of the terminal close event. Just ignore the writes.
|
|
||||||
ILOG("write failed: stream is closed");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
WBuffer *wbuf = wstream_new_buffer(xmemdup(buf, size), size, 1, xfree);
|
|
||||||
wstream_write(&job->stream.proc.in, wbuf);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void term_resize(uint16_t width, uint16_t height, void *d)
|
|
||||||
{
|
|
||||||
Channel *data = d;
|
|
||||||
pty_process_resize(&data->stream.pty, width, height);
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline void term_delayed_free(void **argv)
|
|
||||||
{
|
|
||||||
Channel *j = argv[0];
|
|
||||||
if (j->stream.proc.in.pending_reqs || j->stream.proc.out.pending_reqs) {
|
|
||||||
multiqueue_put(j->events, term_delayed_free, 1, j);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
terminal_destroy(j->term);
|
|
||||||
channel_decref(j);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void term_close(void *d)
|
|
||||||
{
|
|
||||||
Channel *data = d;
|
|
||||||
if (!data->stream.proc.exited) {
|
|
||||||
data->stream.proc.exited = true;
|
|
||||||
process_stop((Process *)&data->stream.proc);
|
|
||||||
}
|
|
||||||
multiqueue_put(data->events, term_delayed_free, 1, data);
|
|
||||||
}
|
|
||||||
|
|
||||||
static Channel *find_job(uint64_t id, bool show_error)
|
static Channel *find_job(uint64_t id, bool show_error)
|
||||||
{
|
{
|
||||||
Channel *data = find_channel(id);
|
Channel *data = find_channel(id);
|
||||||
|
@ -26,7 +26,6 @@ struct process {
|
|||||||
Stream in, out, err;
|
Stream in, out, err;
|
||||||
process_exit_cb cb;
|
process_exit_cb cb;
|
||||||
internal_process_cb internal_exit_cb, internal_close_cb;
|
internal_process_cb internal_exit_cb, internal_close_cb;
|
||||||
bool exited; // TODO: redundant
|
|
||||||
bool closed, detach;
|
bool closed, detach;
|
||||||
MultiQueue *events;
|
MultiQueue *events;
|
||||||
};
|
};
|
||||||
|
@ -115,6 +115,7 @@ static int p_bomb;
|
|||||||
static char_u *p_bh;
|
static char_u *p_bh;
|
||||||
static char_u *p_bt;
|
static char_u *p_bt;
|
||||||
static int p_bl;
|
static int p_bl;
|
||||||
|
static long p_channel;
|
||||||
static int p_ci;
|
static int p_ci;
|
||||||
static int p_cin;
|
static int p_cin;
|
||||||
static char_u *p_cink;
|
static char_u *p_cink;
|
||||||
@ -4193,6 +4194,9 @@ static char *set_num_option(int opt_idx, char_u *varp, long value,
|
|||||||
curbuf->b_p_imsearch = B_IMODE_NONE;
|
curbuf->b_p_imsearch = B_IMODE_NONE;
|
||||||
}
|
}
|
||||||
p_imsearch = curbuf->b_p_imsearch;
|
p_imsearch = curbuf->b_p_imsearch;
|
||||||
|
} else if (pp == &p_channel || pp == &curbuf->b_p_channel) {
|
||||||
|
errmsg = e_invarg;
|
||||||
|
*pp = old_value;
|
||||||
}
|
}
|
||||||
/* if 'titlelen' has changed, redraw the title */
|
/* if 'titlelen' has changed, redraw the title */
|
||||||
else if (pp == &p_titlelen) {
|
else if (pp == &p_titlelen) {
|
||||||
@ -5472,6 +5476,7 @@ static char_u *get_varp(vimoption_T *p)
|
|||||||
case PV_BH: return (char_u *)&(curbuf->b_p_bh);
|
case PV_BH: return (char_u *)&(curbuf->b_p_bh);
|
||||||
case PV_BT: return (char_u *)&(curbuf->b_p_bt);
|
case PV_BT: return (char_u *)&(curbuf->b_p_bt);
|
||||||
case PV_BL: return (char_u *)&(curbuf->b_p_bl);
|
case PV_BL: return (char_u *)&(curbuf->b_p_bl);
|
||||||
|
case PV_CHANNEL:return (char_u *)&(curbuf->b_p_channel);
|
||||||
case PV_CI: return (char_u *)&(curbuf->b_p_ci);
|
case PV_CI: return (char_u *)&(curbuf->b_p_ci);
|
||||||
case PV_CIN: return (char_u *)&(curbuf->b_p_cin);
|
case PV_CIN: return (char_u *)&(curbuf->b_p_cin);
|
||||||
case PV_CINK: return (char_u *)&(curbuf->b_p_cink);
|
case PV_CINK: return (char_u *)&(curbuf->b_p_cink);
|
||||||
@ -5773,6 +5778,7 @@ void buf_copy_options(buf_T *buf, int flags)
|
|||||||
buf->b_p_nf = vim_strsave(p_nf);
|
buf->b_p_nf = vim_strsave(p_nf);
|
||||||
buf->b_p_mps = vim_strsave(p_mps);
|
buf->b_p_mps = vim_strsave(p_mps);
|
||||||
buf->b_p_si = p_si;
|
buf->b_p_si = p_si;
|
||||||
|
buf->b_p_channel = 0;
|
||||||
buf->b_p_ci = p_ci;
|
buf->b_p_ci = p_ci;
|
||||||
buf->b_p_cin = p_cin;
|
buf->b_p_cin = p_cin;
|
||||||
buf->b_p_cink = vim_strsave(p_cink);
|
buf->b_p_cink = vim_strsave(p_cink);
|
||||||
|
@ -695,6 +695,7 @@ enum {
|
|||||||
, BV_BIN
|
, BV_BIN
|
||||||
, BV_BL
|
, BV_BL
|
||||||
, BV_BOMB
|
, BV_BOMB
|
||||||
|
, BV_CHANNEL
|
||||||
, BV_CI
|
, BV_CI
|
||||||
, BV_CIN
|
, BV_CIN
|
||||||
, BV_CINK
|
, BV_CINK
|
||||||
|
@ -294,6 +294,14 @@ return {
|
|||||||
varname='p_cedit',
|
varname='p_cedit',
|
||||||
defaults={if_true={vi="", vim=macros('CTRL_F_STR')}}
|
defaults={if_true={vi="", vim=macros('CTRL_F_STR')}}
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
full_name='channel',
|
||||||
|
type='number', scope={'buffer'},
|
||||||
|
no_mkrc=true,
|
||||||
|
nodefault=true,
|
||||||
|
varname='p_channel',
|
||||||
|
defaults={if_true={vi=0}}
|
||||||
|
},
|
||||||
{
|
{
|
||||||
full_name='charconvert', abbreviation='ccv',
|
full_name='charconvert', abbreviation='ccv',
|
||||||
type='string', scope={'global'},
|
type='string', scope={'global'},
|
||||||
|
Loading…
Reference in New Issue
Block a user