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 -- [email protected] -- 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 ///
--
--
You received this message from the "vim_dev" maillist.
Do not top-post! Type your reply below the text you are replying to.
For more information, visit http://www.vim.org/maillist.php
---
You received this message because you are subscribed to the Google Groups
"vim_dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email
to [email protected].
For more options, visit https://groups.google.com/d/optout.