Mercurial > vim
diff src/terminal.c @ 13435:fa198b71bab2 v8.0.1592
patch 8.0.1592: terminal windows in a session are not properly restored
commit https://github.com/vim/vim/commit/4d8bac8bf593ff087517ff79090c2d224325aae6
Author: Bram Moolenaar <Bram@vim.org>
Date: Fri Mar 9 21:33:34 2018 +0100
patch 8.0.1592: terminal windows in a session are not properly restored
Problem: Terminal windows in a session are not properly restored.
Solution: Add "terminal" in 'sessionoptions'. When possible restore the
command running in a terminal.
author | Christian Brabandt <cb@256bit.org> |
---|---|
date | Fri, 09 Mar 2018 21:45:06 +0100 |
parents | 69517d67421f |
children | 33eea5ce5415 |
line wrap: on
line diff
--- a/src/terminal.c +++ b/src/terminal.c @@ -38,11 +38,10 @@ * in tl_scrollback are no longer used. * * TODO: - * - What to store in a session file? Shell at the prompt would be OK to - * restore, but others may not. Open the window and let the user start the - * command? Also see #2650. + * - Add a flag to kill the job when Vim is exiting. Useful when it's showing + * a logfile. Or send keys there to make it quit: "exit\r" for a shell. + * - When using 'termguicolors' still use the 16 ANSI colors as-is. Helps for * - Adding WinBar to terminal window doesn't display, text isn't shifted down. - * - When using 'termguicolors' still use the 16 ANSI colors as-is. Helps for * a job that uses 16 colors while Vim is using > 256. * - in GUI vertical split causes problems. Cursor is flickering. (Hirohito * Higashi, 2017 Sep 19) @@ -135,6 +134,9 @@ struct terminal_S { void *tl_winpty_config; void *tl_winpty; #endif +#if defined(FEAT_SESSION) + char_u *tl_command; +#endif /* last known vterm size */ int tl_rows; @@ -487,6 +489,52 @@ term_start(typval_T *argvar, jobopt_T *o if (without_job) return curbuf; +#if defined(FEAT_SESSION) + /* Remember the command for the session file. */ + if (opt->jo_term_norestore) + { + term->tl_command = vim_strsave((char_u *)"NONE"); + } + else if (argvar->v_type == VAR_STRING) + { + char_u *cmd = argvar->vval.v_string; + + if (cmd != NULL && STRCMP(cmd, p_sh) != 0) + term->tl_command = vim_strsave(cmd); + } + else if (argvar->v_type == VAR_LIST + && argvar->vval.v_list != NULL + && argvar->vval.v_list->lv_len > 0) + { + garray_T ga; + listitem_T *item; + + ga_init2(&ga, 1, 100); + for (item = argvar->vval.v_list->lv_first; + item != NULL; item = item->li_next) + { + char_u *s = get_tv_string_chk(&item->li_tv); + char_u *p; + + if (s == NULL) + break; + p = vim_strsave_fnameescape(s, FALSE); + if (p == NULL) + break; + ga_concat(&ga, p); + vim_free(p); + ga_append(&ga, ' '); + } + if (item == NULL) + { + ga_append(&ga, NUL); + term->tl_command = ga.ga_data; + } + else + ga_clear(&ga); + } +#endif + /* System dependent: setup the vterm and maybe start the job in it. */ if (argvar->v_type == VAR_STRING && argvar->vval.v_string != NULL @@ -561,6 +609,8 @@ ex_terminal(exarg_T *eap) opt.jo_curwin = 1; else if ((int)(p - cmd) == 6 && STRNICMP(cmd, "hidden", 6) == 0) opt.jo_hidden = 1; + else if ((int)(p - cmd) == 9 && STRNICMP(cmd, "norestore", 9) == 0) + opt.jo_term_norestore = 1; else if ((int)(p - cmd) == 4 && STRNICMP(cmd, "rows", 4) == 0 && ep != NULL && isdigit(ep[1])) { @@ -620,6 +670,42 @@ ex_terminal(exarg_T *eap) vim_free(opt.jo_eof_chars); } +#if defined(FEAT_SESSION) || defined(PROTO) +/* + * Write a :terminal command to the session file to restore the terminal in + * window "wp". + * Return FAIL if writing fails. + */ + int +term_write_session(FILE *fd, win_T *wp) +{ + term_T *term = wp->w_buffer->b_term; + + /* Create the terminal and run the command. This is not without + * risk, but let's assume the user only creates a session when this + * will be OK. */ + if (fprintf(fd, "terminal ++curwin ++cols=%d ++rows=%d ", + term->tl_cols, term->tl_rows) < 0) + return FAIL; + if (term->tl_command != NULL && fputs((char *)term->tl_command, fd) < 0) + return FAIL; + + return put_eol(fd); +} + +/* + * Return TRUE if "buf" has a terminal that should be restored. + */ + int +term_should_restore(buf_T *buf) +{ + term_T *term = buf->b_term; + + return term != NULL && (term->tl_command == NULL + || STRCMP(term->tl_command, "NONE") != 0); +} +#endif + /* * Free the scrollback buffer for "term". */ @@ -669,6 +755,9 @@ free_terminal(buf_T *buf) term_free_vterm(term); vim_free(term->tl_title); +#ifdef FEAT_SESSION + vim_free(term->tl_command); +#endif vim_free(term->tl_status_text); vim_free(term->tl_opencmd); vim_free(term->tl_eof_chars); @@ -4048,6 +4137,29 @@ f_term_sendkeys(typval_T *argvars, typva } /* + * "term_setrestore(buf, command)" function + */ + void +f_term_setrestore(typval_T *argvars UNUSED, typval_T *rettv UNUSED) +{ +#if defined(FEAT_SESSION) + buf_T *buf = term_get_buf(argvars); + term_T *term; + char_u *cmd; + + if (buf == NULL) + return; + term = buf->b_term; + vim_free(term->tl_command); + cmd = get_tv_string_chk(&argvars[1]); + if (cmd != NULL) + term->tl_command = vim_strsave(cmd); + else + term->tl_command = NULL; +#endif +} + +/* * "term_start(command, options)" function */ void @@ -4064,7 +4176,8 @@ f_term_start(typval_T *argvars, typval_T + 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 - + JO2_CWD + JO2_ENV + JO2_EOF_CHARS) == FAIL) + + JO2_CWD + JO2_ENV + JO2_EOF_CHARS + + JO2_NORESTORE) == FAIL) return; if (opt.jo_vertical) @@ -4566,6 +4679,7 @@ term_and_job_init( { create_vterm(term, term->tl_rows, term->tl_cols); + /* This will change a string in "argvar". */ term->tl_job = job_start(argvar, opt); if (term->tl_job != NULL) ++term->tl_job->jv_refcount;