To: vim_dev@googlegroups.com Subject: Patch 8.0.0728 Fcc: outbox From: Bram Moolenaar Mime-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ------------ Patch 8.0.0728 Problem: The terminal structure is never freed. Solution: Free the structure and unreference what it contains. Files: src/terminal.c, src/buffer.c, src/proto/terminal.pro, src/channel.c, src/proto/channel.pro, src/evalfunc.c *** ../vim-8.0.0727/src/terminal.c 2017-07-16 20:13:22.265843572 +0200 --- src/terminal.c 2017-07-17 23:02:01.568182115 +0200 *************** *** 25,35 **** * * TODO: * - pressing Enter sends two CR and/or NL characters to "bash -i"? ! * - free b_term when closing terminal. ! * - remove term from first_term list when closing terminal. * - set buffer options to be scratch, hidden, nomodifiable, etc. * - set buffer name to command, add (1) to avoid duplicates. ! * - if buffer is wiped, cleanup terminal, may stop job. * - if the job ends, write "-- JOB ENDED --" in the terminal * - when closing window and job ended, delete the terminal * - when closing window and job has not ended, make terminal hidden? --- 25,34 ---- * * TODO: * - pressing Enter sends two CR and/or NL characters to "bash -i"? ! * Passing Enter as NL seems to work. * - set buffer options to be scratch, hidden, nomodifiable, etc. * - set buffer name to command, add (1) to avoid duplicates. ! * - If [command] is not given the 'shell' option is used. * - if the job ends, write "-- JOB ENDED --" in the terminal * - when closing window and job ended, delete the terminal * - when closing window and job has not ended, make terminal hidden? *************** *** 43,55 **** * - support minimal size when 'termsize' is "rows*cols". * - support minimal size when 'termsize' is empty. * - implement ":buf {term-buf-name}" ! * - implement term_getsize() ! * - implement term_setsize() ! * - implement term_sendkeys() send keystrokes to a terminal ! * - implement term_wait() wait for screen to be updated ! * - implement term_scrape() inspect terminal screen ! * - implement term_open() open terminal window ! * - implement term_getjob() * - implement 'termkey' */ --- 42,55 ---- * - support minimal size when 'termsize' is "rows*cols". * - support minimal size when 'termsize' is empty. * - implement ":buf {term-buf-name}" ! * - implement term_list() list of buffers with a terminal ! * - implement term_getsize(buf) ! * - implement term_setsize(buf) ! * - implement term_sendkeys(buf, keys) send keystrokes to a terminal ! * - implement term_wait(buf) wait for screen to be updated ! * - implement term_scrape(buf, row) inspect terminal screen ! * - implement term_open(command, options) open terminal window ! * - implement term_getjob(buf) * - implement 'termkey' */ *************** *** 165,171 **** vterm_screen_reset(screen, 1 /* hard */); /* By default NL means CR-NL. */ - /* TODO: this causes two prompts when using ":term bash -i". */ vterm_input_write(vterm, "\x1b[20h", 5); argvars[0].v_type = VAR_STRING; --- 165,170 ---- *************** *** 185,195 **** term->tl_job = job_start(argvars, &opt); ! /* TODO: setup channel to job */ /* Setup pty, see mch_call_shell(). */ } /* * Invoked when "msg" output from a job was received. Write it to the terminal * of "buffer". */ --- 184,230 ---- term->tl_job = job_start(argvars, &opt); ! if (term->tl_job == NULL) ! /* Wiping out the buffer will also close the window. */ ! do_buffer(DOBUF_WIPE, DOBUF_CURRENT, FORWARD, 0, TRUE); ! /* Setup pty, see mch_call_shell(). */ } /* + * Free a terminal and everything it refers to. + * Kills the job if there is one. + * Called when wiping out a buffer. + */ + void + free_terminal(term_T *term) + { + term_T *tp; + + if (term == NULL) + return; + if (first_term == term) + first_term = term->tl_next; + else + for (tp = first_term; tp->tl_next != NULL; tp = tp->tl_next) + if (tp->tl_next == term) + { + tp->tl_next = term->tl_next; + break; + } + + if (term->tl_job != NULL) + { + if (term->tl_job->jv_status != JOB_ENDED) + job_stop(term->tl_job, NULL, "kill"); + job_unref(term->tl_job); + } + + vterm_free(term->tl_vterm); + vim_free(term); + } + + /* * Invoked when "msg" output from a job was received. Write it to the terminal * of "buffer". */ *************** *** 340,346 **** --- 375,386 ---- stuffcharReadbuff(Ctrl_W); return; + /* TODO: which of these two should be used? */ + #if 0 case CAR: key = VTERM_KEY_ENTER; break; + #else + case CAR: c = NL; break; + #endif case ESC: key = VTERM_KEY_ESCAPE; break; case K_BS: key = VTERM_KEY_BACKSPACE; break; case K_DEL: key = VTERM_KEY_DEL; break; *** ../vim-8.0.0727/src/buffer.c 2017-06-19 20:35:28.423401990 +0200 --- src/buffer.c 2017-07-17 22:43:49.212491624 +0200 *************** *** 859,864 **** --- 859,867 ---- #ifdef FEAT_JOB_CHANNEL channel_buffer_free(buf); #endif + #ifdef FEAT_TERMINAL + free_terminal(buf->b_term); + #endif buf_hashtab_remove(buf); *************** *** 1771,1777 **** #endif #ifdef FEAT_SYN_HL ! curwin->w_s = &(buf->b_s); #endif /* Cursor on first line by default. */ --- 1774,1780 ---- #endif #ifdef FEAT_SYN_HL ! curwin->w_s = &(curbuf->b_s); #endif /* Cursor on first line by default. */ *** ../vim-8.0.0727/src/proto/terminal.pro 2017-07-16 20:13:22.265843572 +0200 --- src/proto/terminal.pro 2017-07-17 22:42:52.028931333 +0200 *************** *** 1,5 **** --- 1,6 ---- /* terminal.c */ void ex_terminal(exarg_T *eap); + void free_terminal(term_T *term); void write_to_term(buf_T *buffer, char_u *msg, channel_T *channel); void term_update_window(win_T *wp); void terminal_loop(void); *** ../vim-8.0.0727/src/channel.c 2017-07-16 14:04:24.974836858 +0200 --- src/channel.c 2017-07-17 22:42:41.625011343 +0200 *************** *** 4893,4899 **** } /* ! * "job_start()" function */ job_T * job_start(typval_T *argvars, jobopt_T *opt_arg) --- 4893,4901 ---- } /* ! * Create a job and return it. Implements job_start(). ! * The returned job has a refcount of one. ! * Returns NULL when out of memory. */ job_T * job_start(typval_T *argvars, jobopt_T *opt_arg) *************** *** 5149,5160 **** dict_add_nr_str(dict, "stoponexit", 0L, job->jv_stoponexit); } int ! job_stop(job_T *job, typval_T *argvars) { char_u *arg; ! if (argvars[1].v_type == VAR_UNKNOWN) arg = (char_u *)""; else { --- 5151,5169 ---- dict_add_nr_str(dict, "stoponexit", 0L, job->jv_stoponexit); } + /* + * Send a signal to "job". Implements job_stop(). + * When "type" is not NULL use this for the type. + * Otherwise use argvars[1] for the type. + */ int ! job_stop(job_T *job, typval_T *argvars, char *type) { char_u *arg; ! if (type != NULL) ! arg = (char_u *)type; ! else if (argvars[1].v_type == VAR_UNKNOWN) arg = (char_u *)""; else { *** ../vim-8.0.0727/src/proto/channel.pro 2017-07-16 13:48:18.190107174 +0200 --- src/proto/channel.pro 2017-07-17 22:42:44.712987595 +0200 *************** *** 67,71 **** job_T *job_start(typval_T *argvars, jobopt_T *opt_arg); char *job_status(job_T *job); void job_info(job_T *job, dict_T *dict); ! int job_stop(job_T *job, typval_T *argvars); /* vim: set ft=c : */ --- 67,71 ---- job_T *job_start(typval_T *argvars, jobopt_T *opt_arg); char *job_status(job_T *job); void job_info(job_T *job, dict_T *dict); ! int job_stop(job_T *job, typval_T *argvars, char *type); /* vim: set ft=c : */ *** ../vim-8.0.0727/src/evalfunc.c 2017-07-16 13:48:18.194107145 +0200 --- src/evalfunc.c 2017-07-17 22:40:51.225860521 +0200 *************** *** 6772,6778 **** job_T *job = get_job_arg(&argvars[0]); if (job != NULL) ! rettv->vval.v_number = job_stop(job, argvars); } #endif --- 6772,6778 ---- job_T *job = get_job_arg(&argvars[0]); if (job != NULL) ! rettv->vval.v_number = job_stop(job, argvars, NULL); } #endif *** ../vim-8.0.0727/src/version.c 2017-07-16 20:54:29.646786469 +0200 --- src/version.c 2017-07-17 23:18:35.328680407 +0200 *************** *** 771,772 **** --- 771,774 ---- { /* Add new patch number below this line */ + /**/ + 728, /**/ -- If Microsoft would build a car... ... Occasionally, executing a maneuver such as a left turn would cause your car to shut down and refuse to restart, in which case you would have to reinstall the engine. /// 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 ///