# HG changeset patch # User Christian Brabandt # Date 1502481605 -7200 # Node ID 0498547dace07fdde057b40db26700bcf9565f41 # Parent 8dce424b095b6941d41d75ca948d09d57ac35a33 patch 8.0.0908: cannot set terminal size with options commit https://github.com/vim/vim/commit/08d384ff3aa0366c18fb87ed215b1b4bdf9b1745 Author: Bram Moolenaar Date: Fri Aug 11 21:51:23 2017 +0200 patch 8.0.0908: cannot set terminal size with options Problem: Cannot set terminal size with options. Solution: Add "term_rows", "term_cols" and "vertical". diff --git a/runtime/doc/eval.txt b/runtime/doc/eval.txt --- a/runtime/doc/eval.txt +++ b/runtime/doc/eval.txt @@ -8050,8 +8050,10 @@ term_sendkeys({buf}, {keys}) *term_se term_start({cmd}, {options}) *term_start()* Open a terminal window and run {cmd} in it. - Returns the buffer number of the terminal window. - When opening the window fails zero is returned. + Returns the buffer number of the terminal window. If {cmd} + cannot be executed the window does open and shows an error + message. + If opening the window fails zero is returned. {options} are similar to what is used for |job_start()|, see |job-options|. However, not all options can be used. These @@ -8067,10 +8069,15 @@ term_start({cmd}, {options}) *term_st connected to the terminal. When I/O is connected to the terminal then the callback function for that part is not used. - There are two extra options: + There are extra options: "term_name" name to use for the buffer name, instead of the command name. - "term_finish" What todo when the job is finished: + "term_rows" vertical size to use for the terminal, + instead of using 'termsize' + "term_cols" horizontal size to use for the terminal, + instead of using 'termsize' + "vertical" split the window vertically + "term_finish" What to do when the job is finished: "close": close any windows "open": open window if needed Note that "open" can be interruptive. diff --git a/src/channel.c b/src/channel.c --- a/src/channel.c +++ b/src/channel.c @@ -927,7 +927,7 @@ channel_open_func(typval_T *argvars) opt.jo_mode = MODE_JSON; opt.jo_timeout = 2000; if (get_job_options(&argvars[1], &opt, - JO_MODE_ALL + JO_CB_ALL + JO_WAITTIME + JO_TIMEOUT_ALL) == FAIL) + JO_MODE_ALL + JO_CB_ALL + JO_WAITTIME + JO_TIMEOUT_ALL, 0) == FAIL) goto theend; if (opt.jo_timeout < 0) { @@ -3429,7 +3429,7 @@ common_channel_read(typval_T *argvars, t rettv->vval.v_string = NULL; clear_job_options(&opt); - if (get_job_options(&argvars[1], &opt, JO_TIMEOUT + JO_PART + JO_ID) + if (get_job_options(&argvars[1], &opt, JO_TIMEOUT + JO_PART + JO_ID, 0) == FAIL) goto theend; @@ -3612,7 +3612,7 @@ send_common( part_send = channel_part_send(channel); *part_read = channel_part_read(channel); - if (get_job_options(&argvars[2], opt, JO_CALLBACK + JO_TIMEOUT) == FAIL) + if (get_job_options(&argvars[2], opt, JO_CALLBACK + JO_TIMEOUT, 0) == FAIL) return NULL; /* Set the callback. An empty callback means no callback and not reading @@ -4169,11 +4169,11 @@ part_from_char(int c) /* * Get the option entries from the dict in "tv", parse them and put the result * in "opt". - * Only accept options in "supported". + * Only accept JO_ options in "supported" and JO2_ options in "supported2". * If an option value is invalid return FAIL. */ int -get_job_options(typval_T *tv, jobopt_T *opt, int supported) +get_job_options(typval_T *tv, jobopt_T *opt, int supported, int supported2) { typval_T *item; char_u *val; @@ -4411,7 +4411,7 @@ get_job_options(typval_T *tv, jobopt_T * #ifdef FEAT_TERMINAL else if (STRCMP(hi->hi_key, "term_name") == 0) { - if (!(supported & JO2_TERM_NAME)) + if (!(supported2 & JO2_TERM_NAME)) break; opt->jo_set2 |= JO2_TERM_NAME; opt->jo_term_name = get_tv_string_chk(item); @@ -4423,7 +4423,7 @@ get_job_options(typval_T *tv, jobopt_T * } else if (STRCMP(hi->hi_key, "term_finish") == 0) { - if (!(supported & JO2_TERM_FINISH)) + if (!(supported2 & JO2_TERM_FINISH)) break; val = get_tv_string(item); if (STRCMP(val, "open") != 0 && STRCMP(val, "close") != 0) @@ -4434,10 +4434,31 @@ get_job_options(typval_T *tv, jobopt_T * opt->jo_set2 |= JO2_TERM_FINISH; opt->jo_term_finish = *val; } + else if (STRCMP(hi->hi_key, "term_rows") == 0) + { + if (!(supported2 & JO2_TERM_ROWS)) + break; + opt->jo_set |= JO2_TERM_ROWS; + opt->jo_term_rows = get_tv_number(item); + } + else if (STRCMP(hi->hi_key, "term_cols") == 0) + { + if (!(supported2 & JO2_TERM_COLS)) + break; + opt->jo_set |= JO2_TERM_COLS; + opt->jo_term_cols = get_tv_number(item); + } + else if (STRCMP(hi->hi_key, "vertical") == 0) + { + if (!(supported2 & JO2_VERTICAL)) + break; + opt->jo_set |= JO2_VERTICAL; + opt->jo_vertical = get_tv_number(item); + } #endif else if (STRCMP(hi->hi_key, "env") == 0) { - if (!(supported & JO2_ENV)) + if (!(supported2 & JO2_ENV)) break; opt->jo_set |= JO2_ENV; opt->jo_env = item->vval.v_dict; @@ -4445,7 +4466,7 @@ get_job_options(typval_T *tv, jobopt_T * } else if (STRCMP(hi->hi_key, "cwd") == 0) { - if (!(supported & JO2_CWD)) + if (!(supported2 & JO2_CWD)) break; opt->jo_cwd = get_tv_string_buf_chk(item, opt->jo_cwd_buf); if (opt->jo_cwd == NULL || !mch_isdir(opt->jo_cwd)) @@ -4956,7 +4977,7 @@ job_start(typval_T *argvars, jobopt_T *o opt.jo_mode = MODE_NL; if (get_job_options(&argvars[1], &opt, JO_MODE_ALL + JO_CB_ALL + JO_TIMEOUT_ALL + JO_STOPONEXIT - + JO_EXIT_CB + JO_OUT_IO + JO_BLOCK_WRITE) == FAIL) + + JO_EXIT_CB + JO_OUT_IO + JO_BLOCK_WRITE, 0) == FAIL) goto theend; } diff --git a/src/evalfunc.c b/src/evalfunc.c --- a/src/evalfunc.c +++ b/src/evalfunc.c @@ -2021,7 +2021,7 @@ f_ch_setoptions(typval_T *argvars, typva return; clear_job_options(&opt); if (get_job_options(&argvars[1], &opt, - JO_CB_ALL + JO_TIMEOUT_ALL + JO_MODE_ALL) == OK) + JO_CB_ALL + JO_TIMEOUT_ALL + JO_MODE_ALL, 0) == OK) channel_set_options(channel, &opt); free_job_options(&opt); } @@ -2045,7 +2045,7 @@ f_ch_status(typval_T *argvars, typval_T if (argvars[1].v_type != VAR_UNKNOWN) { clear_job_options(&opt); - if (get_job_options(&argvars[1], &opt, JO_PART) == OK + if (get_job_options(&argvars[1], &opt, JO_PART, 0) == OK && (opt.jo_set & JO_PART)) part = opt.jo_part; } @@ -6783,7 +6783,7 @@ f_job_setoptions(typval_T *argvars, typv if (job == NULL) return; clear_job_options(&opt); - if (get_job_options(&argvars[1], &opt, JO_STOPONEXIT + JO_EXIT_CB) == OK) + if (get_job_options(&argvars[1], &opt, JO_STOPONEXIT + JO_EXIT_CB, 0) == OK) job_set_options(job, &opt); free_job_options(&opt); } diff --git a/src/proto/channel.pro b/src/proto/channel.pro --- a/src/proto/channel.pro +++ b/src/proto/channel.pro @@ -51,15 +51,15 @@ ch_mode_T channel_get_mode(channel_T *ch int channel_get_timeout(channel_T *channel, ch_part_T part); void clear_job_options(jobopt_T *opt); void free_job_options(jobopt_T *opt); -int get_job_options(typval_T *tv, jobopt_T *opt, int supported); +int get_job_options(typval_T *tv, jobopt_T *opt, int supported, int supported2); channel_T *get_channel_arg(typval_T *tv, int check_open, int reading, ch_part_T part); -job_T *job_alloc(void); +void job_free_all(void); void job_cleanup(job_T *job); -void job_free_all(void); int set_ref_in_job(int copyID); void job_unref(job_T *job); int free_unused_jobs_contents(int copyID, int mask); void free_unused_jobs(int copyID, int mask); +job_T *job_alloc(void); void job_set_options(job_T *job, jobopt_T *opt); void job_stop_on_exit(void); int has_pending_job(void); diff --git a/src/structs.h b/src/structs.h --- a/src/structs.h +++ b/src/structs.h @@ -1688,7 +1688,10 @@ struct channel_S { #define JO2_TERM_FINISH 0x0008 /* "term_finish" */ #define JO2_ENV 0x0010 /* "env" */ #define JO2_CWD 0x0020 /* "cwd" */ -#define JO2_ALL 0x003F +#define JO2_TERM_ROWS 0x0040 /* "term_rows" */ +#define JO2_TERM_COLS 0x0080 /* "term_cols" */ +#define JO2_VERTICAL 0x0100 /* "vertical" */ +#define JO2_ALL 0x01FF #define JO_MODE_ALL (JO_MODE + JO_IN_MODE + JO_OUT_MODE + JO_ERR_MODE) #define JO_CB_ALL \ @@ -1748,6 +1751,7 @@ typedef struct /* when non-zero run the job in a terminal window of this size */ int jo_term_rows; int jo_term_cols; + int jo_vertical; char_u *jo_term_name; int jo_term_finish; #endif diff --git a/src/terminal.c b/src/terminal.c --- a/src/terminal.c +++ b/src/terminal.c @@ -237,8 +237,10 @@ setup_job_options(jobopt_T *opt, int row opt->jo_io_buf[PART_OUT] = curbuf->b_fnum; opt->jo_io_buf[PART_ERR] = curbuf->b_fnum; opt->jo_pty = TRUE; - opt->jo_term_rows = rows; - opt->jo_term_cols = cols; + if ((opt->jo_set2 & JO2_TERM_ROWS) == 0) + opt->jo_term_rows = rows; + if ((opt->jo_set2 & JO2_TERM_COLS) == 0) + opt->jo_term_cols = cols; } static void @@ -2361,11 +2363,14 @@ f_term_start(typval_T *argvars, typval_T if (argvars[1].v_type != VAR_UNKNOWN && get_job_options(&argvars[1], &opt, JO_TIMEOUT_ALL + JO_STOPONEXIT - + JO_EXIT_CB + JO_CLOSE_CALLBACK - + JO2_TERM_NAME + JO2_TERM_FINISH - + JO2_CWD + JO2_ENV) == FAIL) + + JO_EXIT_CB + JO_CLOSE_CALLBACK, + JO2_TERM_NAME + JO2_TERM_FINISH + + JO2_TERM_COLS + JO2_TERM_ROWS + JO2_VERTICAL + + JO2_CWD + JO2_ENV) == FAIL) return; + if (opt.jo_vertical) + cmdmod.split = WSP_VERT; term_start(cmd, &opt); if (curbuf->b_term != NULL) diff --git a/src/testdir/test_terminal.vim b/src/testdir/test_terminal.vim --- a/src/testdir/test_terminal.vim +++ b/src/testdir/test_terminal.vim @@ -247,22 +247,43 @@ func Test_terminal_size() bwipe! call assert_equal(5, size[0]) + call term_start(cmd, {'term_rows': 6}) + let size = term_getsize('') + bwipe! + call assert_equal(6, size[0]) + vsplit exe '5,33terminal ' . cmd let size = term_getsize('') bwipe! call assert_equal([5, 33], size) + call term_start(cmd, {'term_rows': 6, 'term_cols': 36}) + let size = term_getsize('') + bwipe! + call assert_equal([6, 36], size) + exe 'vertical 20terminal ' . cmd let size = term_getsize('') bwipe! call assert_equal(20, size[1]) + call term_start(cmd, {'vertical': 1, 'term_cols': 26}) + let size = term_getsize('') + bwipe! + call assert_equal(26, size[1]) + split exe 'vertical 6,20terminal ' . cmd let size = term_getsize('') bwipe! call assert_equal([6, 20], size) + + call term_start(cmd, {'vertical': 1, 'term_rows': 7, 'term_cols': 27}) + let size = term_getsize('') + bwipe! + call assert_equal([7, 27], size) + endfunc func Test_finish_close() diff --git a/src/version.c b/src/version.c --- a/src/version.c +++ b/src/version.c @@ -770,6 +770,8 @@ static char *(features[]) = static int included_patches[] = { /* Add new patch number below this line */ /**/ + 908, +/**/ 907, /**/ 906,