diff src/terminal.c @ 13700:b28d679b1843 v8.0.1722

patch 8.0.1722: cannot specify a minimal size for a terminal window commit https://github.com/vim/vim/commit/498c2562e1bcc72492fe8da8a76504f893e9b5fe Author: Bram Moolenaar <Bram@vim.org> Date: Sun Apr 15 23:45:15 2018 +0200 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'.
author Christian Brabandt <cb@256bit.org>
date Mon, 16 Apr 2018 00:00:07 +0200
parents 3b1cfbc70b43
children 7d2039b2ecc8
line wrap: on
line diff
--- 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))
+    minsize = parse_termsize(wp, &rows, &cols);
+
+    newrows = 99999;
+    newcols = 99999;
+    FOR_ALL_WINDOWS(twp)
     {
-	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;
-
-	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. */