To: vim_dev@googlegroups.com Subject: Patch 8.0.1076 Fcc: outbox From: Bram Moolenaar Mime-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ------------ Patch 8.0.1076 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. Files: src/terminal.c, src/proto/terminal.pro, src/channel.c, *** ../vim-8.0.1075/src/terminal.c 2017-09-08 16:25:49.864776293 +0200 --- src/terminal.c 2017-09-08 20:38:03.161664708 +0200 *************** *** 245,251 **** opt->jo_term_cols = cols; } ! static void term_start(typval_T *argvar, jobopt_T *opt, int forceit) { exarg_T split_ea; --- 245,255 ---- opt->jo_term_cols = cols; } ! /* ! * 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) { exarg_T split_ea; *************** *** 253,261 **** term_T *term; buf_T *old_curbuf = NULL; int res; if (check_restricted() || check_secure()) ! return; if ((opt->jo_set & (JO_IN_IO + JO_OUT_IO + JO_ERR_IO)) == (JO_IN_IO + JO_OUT_IO + JO_ERR_IO) --- 257,266 ---- term_T *term; buf_T *old_curbuf = NULL; int res; + buf_T *newbuf; if (check_restricted() || check_secure()) ! return NULL; if ((opt->jo_set & (JO_IN_IO + JO_OUT_IO + JO_ERR_IO)) == (JO_IN_IO + JO_OUT_IO + JO_ERR_IO) *************** *** 263,274 **** || (!(opt->jo_set & JO_ERR_IO) && (opt->jo_set & JO_ERR_BUF))) { EMSG(_(e_invarg)); ! return; } term = (term_T *)alloc_clear(sizeof(term_T)); if (term == NULL) ! return; term->tl_dirty_row_end = MAX_ROW; term->tl_cursor_visible = TRUE; term->tl_cursor_shape = VTERM_PROP_CURSORSHAPE_BLOCK; --- 268,279 ---- || (!(opt->jo_set & JO_ERR_IO) && (opt->jo_set & JO_ERR_BUF))) { EMSG(_(e_invarg)); ! return NULL; } term = (term_T *)alloc_clear(sizeof(term_T)); if (term == NULL) ! return NULL; term->tl_dirty_row_end = MAX_ROW; term->tl_cursor_visible = TRUE; term->tl_cursor_shape = VTERM_PROP_CURSORSHAPE_BLOCK; *************** *** 283,295 **** { no_write_message(); vim_free(term); ! return; } if (do_ecmd(0, NULL, NULL, &split_ea, ECMD_ONE, ECMD_HIDE + (forceit ? ECMD_FORCEIT : 0), curwin) == FAIL) { vim_free(term); ! return; } } else if (opt->jo_hidden) --- 288,300 ---- { no_write_message(); vim_free(term); ! return NULL; } if (do_ecmd(0, NULL, NULL, &split_ea, ECMD_ONE, ECMD_HIDE + (forceit ? ECMD_FORCEIT : 0), curwin) == FAIL) { vim_free(term); ! return NULL; } } else if (opt->jo_hidden) *************** *** 303,309 **** if (buf == NULL || ml_open(buf) == FAIL) { vim_free(term); ! return; } old_curbuf = curbuf; --curbuf->b_nwindows; --- 308,314 ---- if (buf == NULL || ml_open(buf) == FAIL) { vim_free(term); ! return NULL; } old_curbuf = curbuf; --curbuf->b_nwindows; *************** *** 333,339 **** { /* split failed */ vim_free(term); ! return; } } term->tl_buffer = curbuf; --- 338,344 ---- { /* split failed */ vim_free(term); ! return NULL; } } term->tl_buffer = curbuf; *************** *** 419,424 **** --- 424,430 ---- else res = term_and_job_init(term, argvar, opt); + newbuf = curbuf; if (res == OK) { /* Get and remember the size we ended up with. Update the pty. */ *************** *** 453,459 **** --- 459,467 ---- /* Wiping out the buffer will also close the window and call * free_terminal(). */ do_buffer(DOBUF_WIPE, DOBUF_FIRST, FORWARD, buf->b_fnum, TRUE); + return NULL; } + return newbuf; } /* *************** *** 688,694 **** update_screen(0); update_cursor(term, TRUE); } ! else redraw_after_callback(TRUE); } } --- 696,702 ---- update_screen(0); update_cursor(term, TRUE); } ! else if (buffer->b_nwindows > 0) redraw_after_callback(TRUE); } } *************** *** 879,884 **** --- 887,906 ---- } /* + * 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. */ static void *************** *** 2379,2384 **** --- 2401,2408 ---- } else if (term->tl_title != NULL) txt = term->tl_title; + else if (term_none_open(term)) + txt = (char_u *)_("active"); else if (term_job_running(term)) txt = (char_u *)_("running"); else *************** *** 2858,2868 **** --- 2882,2894 ---- f_term_start(typval_T *argvars, typval_T *rettv) { jobopt_T opt; + buf_T *buf; init_job_options(&opt); if (argvars[1].v_type != VAR_UNKNOWN && get_job_options(&argvars[1], &opt, JO_TIMEOUT_ALL + JO_STOPONEXIT + + JO_CALLBACK + JO_OUT_CALLBACK + JO_ERR_CALLBACK + JO_EXIT_CB + JO_CLOSE_CALLBACK + JO_OUT_IO, JO2_TERM_NAME + JO2_TERM_FINISH + JO2_HIDDEN + JO2_TERM_OPENCMD + JO2_TERM_COLS + JO2_TERM_ROWS + JO2_VERTICAL + JO2_CURWIN *************** *** 2871,2880 **** if (opt.jo_vertical) cmdmod.split = WSP_VERT; ! term_start(&argvars[0], &opt, FALSE); ! if (curbuf->b_term != NULL) ! rettv->vval.v_number = curbuf->b_fnum; } /* --- 2897,2906 ---- if (opt.jo_vertical) cmdmod.split = WSP_VERT; ! buf = term_start(&argvars[0], &opt, FALSE); ! if (buf != NULL && buf->b_term != NULL) ! rettv->vval.v_number = buf->b_fnum; } /* *************** *** 3359,3366 **** static int create_pty_only(term_T *term, jobopt_T *opt) { - int ret; - create_vterm(term, term->tl_rows, term->tl_cols); term->tl_job = job_alloc(); --- 3385,3390 ---- *************** *** 3371,3379 **** /* behave like the job is already finished */ term->tl_job->jv_status = JOB_FINISHED; ! ret = mch_create_pty_channel(term->tl_job, opt); ! ! return ret; } /* --- 3395,3401 ---- /* behave like the job is already finished */ term->tl_job->jv_status = JOB_FINISHED; ! return mch_create_pty_channel(term->tl_job, opt); } /* *** ../vim-8.0.1075/src/proto/terminal.pro 2017-09-02 14:54:16.380533155 +0200 --- src/proto/terminal.pro 2017-09-08 19:58:28.757407950 +0200 *************** *** 3,8 **** --- 3,9 ---- void free_terminal(buf_T *buf); void write_to_term(buf_T *buffer, char_u *msg, channel_T *channel); int term_job_running(term_T *term); + int term_none_open(term_T *term); int term_in_normal_mode(void); void term_enter_job_mode(void); int send_keys_to_term(term_T *term, int c, int typed); *************** *** 16,22 **** int term_is_finished(buf_T *buf); int term_show_buffer(buf_T *buf); 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); char_u *term_get_status_text(term_T *term); int set_ref_in_term(int copyID); --- 17,22 ---- *************** *** 35,39 **** --- 35,40 ---- void f_term_sendkeys(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 term_send_eof(channel_T *ch); int terminal_enabled(void); /* vim: set ft=c : */ *** ../vim-8.0.1075/src/channel.c 2017-09-08 14:39:25.638102889 +0200 --- src/channel.c 2017-09-08 17:43:56.634079364 +0200 *************** *** 3692,3704 **** { res = fd_write(fd, (char *)buf, len); #ifdef WIN32 ! if (channel->ch_named_pipe) { ! if (res < 0) ! { ! DisconnectNamedPipe((HANDLE)fd); ! ConnectNamedPipe((HANDLE)fd, NULL); ! } } #endif --- 3692,3701 ---- { res = fd_write(fd, (char *)buf, len); #ifdef WIN32 ! if (channel->ch_named_pipe && res < 0) { ! DisconnectNamedPipe((HANDLE)fd); ! ConnectNamedPipe((HANDLE)fd, NULL); } #endif *************** *** 4084,4089 **** --- 4081,4087 ---- if (ret > 0 && fd != INVALID_FD && FD_ISSET(fd, rfds)) { channel_read(channel, part, "channel_select_check"); + FD_CLR(fd, rfds); --ret; } } *************** *** 4093,4098 **** --- 4091,4097 ---- && FD_ISSET(in_part->ch_fd, wfds)) { channel_write_input(channel); + FD_CLR(in_part->ch_fd, wfds); --ret; } } *** ../vim-8.0.1075/src/version.c 2017-09-08 16:25:49.868776266 +0200 --- src/version.c 2017-09-08 17:03:13.470137745 +0200 *************** *** 771,772 **** --- 771,774 ---- { /* Add new patch number below this line */ + /**/ + 1076, /**/ -- From "know your smileys": :-D Big smile /// Bram Moolenaar -- Bram@Moolenaar.net -- http://www.Moolenaar.net \\\ /// sponsor Vim, vote for features -- http://www.Vim.org/sponsor/ \\\ \\\ an exciting new programming language -- http://www.Zimbu.org /// \\\ help me help AIDS victims -- http://ICCF-Holland.org ///