summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorBram Moolenaar <Bram@vim.org>2018-04-15 23:45:15 +0200
committerBram Moolenaar <Bram@vim.org>2018-04-15 23:45:15 +0200
commit498c2562e1bcc72492fe8da8a76504f893e9b5fe (patch)
tree90ff3fa6dc3937d2af2027e93c11d25485032726 /src
parenta7eef3d87fa36d527d1cfc749b400df1e69dcb3d (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.c4
-rw-r--r--src/terminal.c109
-rw-r--r--src/testdir/test_terminal.vim68
-rw-r--r--src/version.c2
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,