forked from aniani/vim
patch 8.0.0728: the terminal structure is never freed
Problem: The terminal structure is never freed. Solution: Free the structure and unreference what it contains.
This commit is contained in:
parent
60d0e97497
commit
96ca27a0ee
@ -859,6 +859,9 @@ free_buffer(buf_T *buf)
|
||||
#ifdef FEAT_JOB_CHANNEL
|
||||
channel_buffer_free(buf);
|
||||
#endif
|
||||
#ifdef FEAT_TERMINAL
|
||||
free_terminal(buf->b_term);
|
||||
#endif
|
||||
|
||||
buf_hashtab_remove(buf);
|
||||
|
||||
@ -1771,7 +1774,7 @@ enter_buffer(buf_T *buf)
|
||||
#endif
|
||||
|
||||
#ifdef FEAT_SYN_HL
|
||||
curwin->w_s = &(buf->b_s);
|
||||
curwin->w_s = &(curbuf->b_s);
|
||||
#endif
|
||||
|
||||
/* Cursor on first line by default. */
|
||||
|
@ -4893,7 +4893,9 @@ job_check_ended(void)
|
||||
}
|
||||
|
||||
/*
|
||||
* "job_start()" function
|
||||
* 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,12 +5151,19 @@ job_info(job_T *job, dict_T *dict)
|
||||
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)
|
||||
job_stop(job_T *job, typval_T *argvars, char *type)
|
||||
{
|
||||
char_u *arg;
|
||||
|
||||
if (argvars[1].v_type == VAR_UNKNOWN)
|
||||
if (type != NULL)
|
||||
arg = (char_u *)type;
|
||||
else if (argvars[1].v_type == VAR_UNKNOWN)
|
||||
arg = (char_u *)"";
|
||||
else
|
||||
{
|
||||
|
@ -6772,7 +6772,7 @@ f_job_stop(typval_T *argvars, typval_T *rettv)
|
||||
job_T *job = get_job_arg(&argvars[0]);
|
||||
|
||||
if (job != NULL)
|
||||
rettv->vval.v_number = job_stop(job, argvars);
|
||||
rettv->vval.v_number = job_stop(job, argvars, NULL);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
@ -67,5 +67,5 @@ void job_check_ended(void);
|
||||
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);
|
||||
int job_stop(job_T *job, typval_T *argvars, char *type);
|
||||
/* vim: set ft=c : */
|
||||
|
@ -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);
|
||||
|
@ -25,11 +25,10 @@
|
||||
*
|
||||
* 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.
|
||||
* 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 buffer is wiped, cleanup terminal, may stop job.
|
||||
* - 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,13 +42,14 @@
|
||||
* - 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 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,7 +165,6 @@ ex_terminal(exarg_T *eap)
|
||||
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;
|
||||
@ -185,10 +184,46 @@ ex_terminal(exarg_T *eap)
|
||||
|
||||
term->tl_job = job_start(argvars, &opt);
|
||||
|
||||
/* TODO: setup channel to job */
|
||||
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,7 +375,12 @@ terminal_loop(void)
|
||||
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;
|
||||
|
@ -769,6 +769,8 @@ static char *(features[]) =
|
||||
|
||||
static int included_patches[] =
|
||||
{ /* Add new patch number below this line */
|
||||
/**/
|
||||
728,
|
||||
/**/
|
||||
727,
|
||||
/**/
|
||||
|
Loading…
x
Reference in New Issue
Block a user