aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/nvim/buffer_defs.h1
-rw-r--r--src/nvim/channel.c63
-rw-r--r--src/nvim/eval.c61
-rw-r--r--src/nvim/event/process.h1
-rw-r--r--src/nvim/option.c6
-rw-r--r--src/nvim/option_defs.h1
-rw-r--r--src/nvim/options.lua8
7 files changed, 81 insertions, 60 deletions
diff --git a/src/nvim/buffer_defs.h b/src/nvim/buffer_defs.h
index 559dffb945..f1cbcb2627 100644
--- a/src/nvim/buffer_defs.h
+++ b/src/nvim/buffer_defs.h
@@ -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'
diff --git a/src/nvim/channel.c b/src/nvim/channel.c
index 5ee4e5be09..c6db2b7b7a 100644
--- a/src/nvim/channel.c
+++ b/src/nvim/channel.c
@@ -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);
+}
+
diff --git a/src/nvim/eval.c b/src/nvim/eval.c
index c2fd7ac19c..6899474577 100644
--- a/src/nvim/eval.c
+++ b/src/nvim/eval.c
@@ -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);
diff --git a/src/nvim/event/process.h b/src/nvim/event/process.h
index 0897563c83..a8d066c291 100644
--- a/src/nvim/event/process.h
+++ b/src/nvim/event/process.h
@@ -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;
};
diff --git a/src/nvim/option.c b/src/nvim/option.c
index f6f334f432..65ab7a54a6 100644
--- a/src/nvim/option.c
+++ b/src/nvim/option.c
@@ -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);
diff --git a/src/nvim/option_defs.h b/src/nvim/option_defs.h
index 1f62490ab9..b16f222705 100644
--- a/src/nvim/option_defs.h
+++ b/src/nvim/option_defs.h
@@ -695,6 +695,7 @@ enum {
, BV_BIN
, BV_BL
, BV_BOMB
+ , BV_CHANNEL
, BV_CI
, BV_CIN
, BV_CINK
diff --git a/src/nvim/options.lua b/src/nvim/options.lua
index cb3e5ad856..dd28a765fd 100644
--- a/src/nvim/options.lua
+++ b/src/nvim/options.lua
@@ -295,6 +295,14 @@ return {
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'},
secure=true,