mirror of
				https://github.com/neovim/neovim.git
				synced 2025-10-26 12:27:24 +00:00 
			
		
		
		
	channels: move away term code from eval.c
This commit is contained in:
		| @@ -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'}, | ||||
|   | ||||
		Reference in New Issue
	
	Block a user
	 Björn Linse
					Björn Linse