diff options
author | Bram Moolenaar <Bram@vim.org> | 2018-04-15 23:45:15 +0200 |
---|---|---|
committer | Bram Moolenaar <Bram@vim.org> | 2018-04-15 23:45:15 +0200 |
commit | 498c2562e1bcc72492fe8da8a76504f893e9b5fe (patch) | |
tree | 90ff3fa6dc3937d2af2027e93c11d25485032726 /src | |
parent | a7eef3d87fa36d527d1cfc749b400df1e69dcb3d (diff) |
patch 8.0.1722: cannot specify a minimal size for a terminal windowv8.0.1722
Problem: Cannot specify a minimal size for a terminal window.
Solution: Support the "rows*cols" format for 'winsize'.
Diffstat (limited to 'src')
-rw-r--r-- | src/option.c | 4 | ||||
-rw-r--r-- | src/terminal.c | 109 | ||||
-rw-r--r-- | src/testdir/test_terminal.vim | 68 | ||||
-rw-r--r-- | src/version.c | 2 |
4 files changed, 136 insertions, 47 deletions
diff --git a/src/option.c b/src/option.c index 9ebc511833..ea8c6af9bb 100644 --- a/src/option.c +++ b/src/option.c @@ -7464,7 +7464,9 @@ did_set_string_option( if (*curwin->w_p_tms != NUL) { p = skipdigits(curwin->w_p_tms); - if (p == curwin->w_p_tms || *p != 'x' || *skipdigits(p + 1) != NUL) + if (p == curwin->w_p_tms + || (*p != 'x' && *p != '*') + || *skipdigits(p + 1) != NUL) errmsg = e_invarg; } } diff --git a/src/terminal.c b/src/terminal.c index 0d2dab8ab7..9a551a7844 100644 --- a/src/terminal.c +++ b/src/terminal.c @@ -42,26 +42,20 @@ * redirection. Probably in call to channel_set_pipes(). * - Win32: Redirecting output does not work, Test_terminal_redir_file() * is disabled. - * - Copy text in the vterm to the Vim buffer once in a while, so that - * completion works. * - When starting terminal window with shell in terminal, then using :gui to * switch to GUI, shell stops working. Scrollback seems wrong, command * running in shell is still running. - * - in GUI vertical split causes problems. Cursor is flickering. (Hirohito - * Higashi, 2017 Sep 19) - * - after resizing windows overlap. (Boris Staletic, #2164) - * - cursor blinks in terminal on widows with a timer. (xtal8, #2142) - * - Termdebug does not work when Vim build with mzscheme. gdb hangs. - * - After executing a shell command the status line isn't redraw. - * - add test for giving error for invalid 'termsize' value. - * - support minimal size when 'termsize' is "rows*cols". - * - support minimal size when 'termsize' is empty? * - GUI: when using tabs, focus in terminal, click on tab does not work. + * - Copy text in the vterm to the Vim buffer once in a while, so that + * completion works. * - Redrawing is slow with Athena and Motif. Also other GUI? (Ramel Eshed) * - For the GUI fill termios with default values, perhaps like pangoterm: * http://bazaar.launchpad.net/~leonerd/pangoterm/trunk/view/head:/main.c#L134 * - When 'encoding' is not utf-8, or the job is using another encoding, setup * conversions. + * - Termdebug does not work when Vim build with mzscheme: gdb hangs just after + * "run". Everything else works, including communication channel. Not + * initializing mzscheme avoid the problem, thus it's not some #ifdef. */ #include "vim.h" @@ -133,9 +127,6 @@ struct terminal_S { /* last known vterm size */ int tl_rows; int tl_cols; - /* vterm size does not follow window size */ - int tl_rows_fixed; - int tl_cols_fixed; char_u *tl_title; /* NULL or allocated */ char_u *tl_status_text; /* NULL or allocated */ @@ -208,8 +199,37 @@ static int desired_cursor_blink = -1; */ /* + * Parse 'termsize' and set "rows" and "cols" for the terminal size in the + * current window. + * Sets "rows" and/or "cols" to zero when it should follow the window size. + * Return TRUE if the size is the minimum size: "24*80". + */ + static int +parse_termsize(win_T *wp, int *rows, int *cols) +{ + int minsize = FALSE; + + *rows = 0; + *cols = 0; + + if (*wp->w_p_tms != NUL) + { + char_u *p = vim_strchr(wp->w_p_tms, 'x'); + + /* Syntax of value was already checked when it's set. */ + if (p == NULL) + { + minsize = TRUE; + p = vim_strchr(wp->w_p_tms, '*'); + } + *rows = atoi((char *)wp->w_p_tms); + *cols = atoi((char *)p + 1); + } + return minsize; +} + +/* * Determine the terminal size from 'termsize' and the current window. - * Assumes term->tl_rows and term->tl_cols are zero. */ static void set_term_and_win_size(term_T *term) @@ -224,27 +244,21 @@ set_term_and_win_size(term_T *term) return; } #endif - if (*curwin->w_p_tms != NUL) + if (parse_termsize(curwin, &term->tl_rows, &term->tl_cols)) { - char_u *p = vim_strchr(curwin->w_p_tms, 'x') + 1; - - term->tl_rows = atoi((char *)curwin->w_p_tms); - term->tl_cols = atoi((char *)p); + if (term->tl_rows != 0) + term->tl_rows = MAX(term->tl_rows, curwin->w_height); + if (term->tl_cols != 0) + term->tl_cols = MAX(term->tl_cols, curwin->w_width); } if (term->tl_rows == 0) term->tl_rows = curwin->w_height; else - { win_setheight_win(term->tl_rows, curwin); - term->tl_rows_fixed = TRUE; - } if (term->tl_cols == 0) term->tl_cols = curwin->w_width; else - { win_setwidth_win(term->tl_cols, curwin); - term->tl_cols_fixed = TRUE; - } } /* @@ -2853,6 +2867,10 @@ term_update_window(win_T *wp) VTermScreen *screen; VTermState *state; VTermPos pos; + int rows, cols; + int newrows, newcols; + int minsize; + win_T *twp; if (term == NULL || term->tl_vterm == NULL || term->tl_normal_mode) return FAIL; @@ -2871,31 +2889,32 @@ term_update_window(win_T *wp) * If the window was resized a redraw will be triggered and we get here. * Adjust the size of the vterm unless 'termsize' specifies a fixed size. */ - if ((!term->tl_rows_fixed && term->tl_rows != wp->w_height) - || (!term->tl_cols_fixed && term->tl_cols != wp->w_width)) - { - int rows = term->tl_rows_fixed ? term->tl_rows : wp->w_height; - int cols = term->tl_cols_fixed ? term->tl_cols : wp->w_width; - win_T *twp; + minsize = parse_termsize(wp, &rows, &cols); - FOR_ALL_WINDOWS(twp) + newrows = 99999; + newcols = 99999; + FOR_ALL_WINDOWS(twp) + { + /* When more than one window shows the same terminal, use the + * smallest size. */ + if (twp->w_buffer == term->tl_buffer) { - /* When more than one window shows the same terminal, use the - * smallest size. */ - if (twp->w_buffer == term->tl_buffer) - { - if (!term->tl_rows_fixed && rows > twp->w_height) - rows = twp->w_height; - if (!term->tl_cols_fixed && cols > twp->w_width) - cols = twp->w_width; - } + newrows = MIN(newrows, twp->w_height); + newcols = MIN(newcols, twp->w_width); } + } + newrows = rows == 0 ? newrows : minsize ? MAX(rows, newrows) : rows; + newcols = cols == 0 ? newcols : minsize ? MAX(cols, newcols) : cols; + + if (term->tl_rows != newrows || term->tl_cols != newcols) + { + term->tl_vterm_size_changed = TRUE; - vterm_set_size(vterm, rows, cols); + vterm_set_size(vterm, newrows, newcols); ch_log(term->tl_job->jv_channel, "Resizing terminal to %d lines", - rows); - term_report_winsize(term, rows, cols); + newrows); + term_report_winsize(term, newrows, newcols); } /* The cursor may have been moved when resizing. */ diff --git a/src/testdir/test_terminal.vim b/src/testdir/test_terminal.vim index eb22b0f0c9..5aa7597e37 100644 --- a/src/testdir/test_terminal.vim +++ b/src/testdir/test_terminal.vim @@ -1357,7 +1357,7 @@ func Test_terminal_ansicolors_func() exe buf . 'bwipe' endfunc -func Test_terminal_termsize_option() +func Test_terminal_termsize_option_fixed() if !CanRunVimInTerminal() return endif @@ -1389,3 +1389,69 @@ func Test_terminal_termsize_option() set termsize= endfunc + +func Test_terminal_termsize_option_zero() + set termsize=0x0 + let buf = Run_shell_in_terminal({}) + let win = bufwinid(buf) + call assert_equal([winheight(win), winwidth(win)], term_getsize(buf)) + call Stop_shell_in_terminal(buf) + call term_wait(buf) + exe buf . 'bwipe' + + set termsize=7x0 + let buf = Run_shell_in_terminal({}) + let win = bufwinid(buf) + call assert_equal([7, winwidth(win)], term_getsize(buf)) + call Stop_shell_in_terminal(buf) + call term_wait(buf) + exe buf . 'bwipe' + + set termsize=0x33 + let buf = Run_shell_in_terminal({}) + let win = bufwinid(buf) + call assert_equal([winheight(win), 33], term_getsize(buf)) + call Stop_shell_in_terminal(buf) + call term_wait(buf) + exe buf . 'bwipe' + + set termsize= +endfunc + +func Test_terminal_termsize_mininmum() + set termsize=10*50 + vsplit + let buf = Run_shell_in_terminal({}) + let win = bufwinid(buf) + call assert_inrange(10, 1000, winheight(win)) + call assert_inrange(50, 1000, winwidth(win)) + call assert_equal([winheight(win), winwidth(win)], term_getsize(buf)) + + resize 15 + vertical resize 60 + redraw + call assert_equal([15, 60], term_getsize(buf)) + call assert_equal(15, winheight(win)) + call assert_equal(60, winwidth(win)) + + resize 7 + vertical resize 30 + redraw + call assert_equal([10, 50], term_getsize(buf)) + call assert_equal(7, winheight(win)) + call assert_equal(30, winwidth(win)) + + call Stop_shell_in_terminal(buf) + call term_wait(buf) + exe buf . 'bwipe' + + set termsize=0*0 + let buf = Run_shell_in_terminal({}) + let win = bufwinid(buf) + call assert_equal([winheight(win), winwidth(win)], term_getsize(buf)) + call Stop_shell_in_terminal(buf) + call term_wait(buf) + exe buf . 'bwipe' + + set termsize= +endfunc diff --git a/src/version.c b/src/version.c index 851f050220..9989f9fdb6 100644 --- a/src/version.c +++ b/src/version.c @@ -763,6 +763,8 @@ static char *(features[]) = static int included_patches[] = { /* Add new patch number below this line */ /**/ + 1722, +/**/ 1721, /**/ 1720, |