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.
|
||||
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' string (default "")
|
||||
global
|
||||
|
@ -603,6 +603,7 @@ struct file_buffer {
|
||||
char_u *b_p_bt; ///< 'buftype'
|
||||
int b_has_qf_entry; ///< quickfix exists for buffer
|
||||
int b_p_bl; ///< 'buflisted'
|
||||
long b_p_channel; ///< 'channel'
|
||||
int b_p_cin; ///< 'cindent'
|
||||
char_u *b_p_cino; ///< 'cinoptions'
|
||||
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)
|
||||
{
|
||||
Channel *chan = data;
|
||||
if (chan->term && !chan->stream.proc.exited) {
|
||||
chan->stream.proc.exited = true;
|
||||
if (chan->term) {
|
||||
char msg[sizeof("\r\n[Process exited ]") + NUMBUFLEN];
|
||||
snprintf(msg, sizeof msg, "\r\n[Process exited %d]", proc->status);
|
||||
terminal_close(chan->term, msg);
|
||||
}
|
||||
|
||||
if (chan->is_rpc) {
|
||||
channel_process_exit(chan->id, status);
|
||||
}
|
||||
@ -472,3 +472,62 @@ static void on_channel_event(ChannelEvent *ev)
|
||||
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;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
@ -16680,13 +16681,6 @@ static void f_termopen(typval_T *argvars, typval_T *rettv, FunPtr fptr)
|
||||
if (rettv->vval.v_number <= 0) {
|
||||
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;
|
||||
|
||||
@ -16699,9 +16693,7 @@ static void f_termopen(typval_T *argvars, typval_T *rettv, FunPtr fptr)
|
||||
(void)setfname(curbuf, (char_u *)buf, NULL, true);
|
||||
// Save the job id and pid in b:terminal_job_{id,pid}
|
||||
Error err = ERROR_INIT;
|
||||
dict_set_var(curbuf->b_vars, cstr_as_string("terminal_channel_id"),
|
||||
INTEGER_OBJ(chan->id), false, false, &err);
|
||||
// deprecated name:
|
||||
// deprecated: use 'channel' buffer option
|
||||
dict_set_var(curbuf->b_vars, cstr_as_string("terminal_job_id"),
|
||||
INTEGER_OBJ(chan->id), false, false, &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);
|
||||
api_clear_error(&err);
|
||||
|
||||
Terminal *term = terminal_open(topts);
|
||||
chan->term = term;
|
||||
channel_incref(chan);
|
||||
|
||||
return;
|
||||
channel_terminal_open(chan);
|
||||
}
|
||||
|
||||
// "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)
|
||||
{
|
||||
Channel *data = find_channel(id);
|
||||
|
@ -26,7 +26,6 @@ struct process {
|
||||
Stream in, out, err;
|
||||
process_exit_cb cb;
|
||||
internal_process_cb internal_exit_cb, internal_close_cb;
|
||||
bool exited; // TODO: redundant
|
||||
bool closed, detach;
|
||||
MultiQueue *events;
|
||||
};
|
||||
|
@ -115,6 +115,7 @@ static int p_bomb;
|
||||
static char_u *p_bh;
|
||||
static char_u *p_bt;
|
||||
static int p_bl;
|
||||
static long p_channel;
|
||||
static int p_ci;
|
||||
static int p_cin;
|
||||
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;
|
||||
}
|
||||
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 */
|
||||
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_BT: return (char_u *)&(curbuf->b_p_bt);
|
||||
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_CIN: return (char_u *)&(curbuf->b_p_cin);
|
||||
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_mps = vim_strsave(p_mps);
|
||||
buf->b_p_si = p_si;
|
||||
buf->b_p_channel = 0;
|
||||
buf->b_p_ci = p_ci;
|
||||
buf->b_p_cin = p_cin;
|
||||
buf->b_p_cink = vim_strsave(p_cink);
|
||||
|
@ -695,6 +695,7 @@ enum {
|
||||
, BV_BIN
|
||||
, BV_BL
|
||||
, BV_BOMB
|
||||
, BV_CHANNEL
|
||||
, BV_CI
|
||||
, BV_CIN
|
||||
, BV_CINK
|
||||
|
@ -294,6 +294,14 @@ return {
|
||||
varname='p_cedit',
|
||||
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',
|
||||
type='string', scope={'global'},
|
||||
|
Loading…
Reference in New Issue
Block a user