mirror of
https://github.com/vim/vim.git
synced 2025-07-26 11:04:33 -04:00
patch 8.0.1722: cannot specify a minimal size for a terminal window
Problem: Cannot specify a minimal size for a terminal window. Solution: Support the "rows*cols" format for 'winsize'.
This commit is contained in:
parent
a7eef3d87f
commit
498c2562e1
@ -7960,15 +7960,23 @@ A jump table for the options with a short description can be found at |Q_op|.
|
||||
'termsize' 'tms' string (default "")
|
||||
local to window
|
||||
{not in Vi}
|
||||
Size of the |terminal| window. Format: {rows}x{columns}.
|
||||
Size of the |terminal| window. Format: {rows}x{columns} or
|
||||
{rows}*{columns}.
|
||||
- When empty the terminal gets the size from the window.
|
||||
- When set (e.g., "24x80") the terminal size is not adjusted to the
|
||||
window size. If the window is smaller only the top-left part is
|
||||
displayed.
|
||||
When rows is zero then use the height of the window.
|
||||
When columns is zero then use the width of the window.
|
||||
For example: "30x0" uses 30 rows with the current window width.
|
||||
Using "0x0" is the same as empty.
|
||||
- When set with a "x" (e.g., "24x80") the terminal size is not
|
||||
adjusted to the window size. If the window is smaller only the
|
||||
top-left part is displayed.
|
||||
- When set with a "*" (e.g., "10*50") the terminal size follows the
|
||||
window size, but will not be smaller than the specified rows and/or
|
||||
columns.
|
||||
- When rows is zero then use the height of the window.
|
||||
- When columns is zero then use the width of the window.
|
||||
- Using "0x0" or "0*0" is the same as empty.
|
||||
|
||||
Examples:
|
||||
"30x0" uses 30 rows and the current window width.
|
||||
"20*0" uses at least 20 rows and the current window width.
|
||||
"0*40" uses the current window height and at least 40 columns.
|
||||
Note that the command running in the terminal window may still change
|
||||
the size of the terminal. In that case the Vim window will be
|
||||
adjusted to that size, if possible.
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
109
src/terminal.c
109
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 */
|
||||
@ -207,9 +198,38 @@ static int desired_cursor_blink = -1;
|
||||
* 1. Generic code for all systems.
|
||||
*/
|
||||
|
||||
/*
|
||||
* 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. */
|
||||
|
@ -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
|
||||
|
@ -762,6 +762,8 @@ static char *(features[]) =
|
||||
|
||||
static int included_patches[] =
|
||||
{ /* Add new patch number below this line */
|
||||
/**/
|
||||
1722,
|
||||
/**/
|
||||
1721,
|
||||
/**/
|
||||
|
Loading…
x
Reference in New Issue
Block a user