changeset 11315:0c091a7c588c v8.0.0543

patch 8.0.0543: test_edit causes older xfce4-terminal to close commit https://github.com/vim/vim/commit/ba6ec182973af726ce9b7b7eb3753fc3a7ae7d1b Author: Bram Moolenaar <Bram@vim.org> Date: Tue Apr 4 22:41:10 2017 +0200 patch 8.0.0543: test_edit causes older xfce4-terminal to close Problem: Test_edit causes older xfce4-terminal to close. (Dominique Pelle) Solution: Reduce number of columns to 2000. Try to restore the window position.
author Christian Brabandt <cb@256bit.org>
date Tue, 04 Apr 2017 22:45:05 +0200
parents 2808577a0260
children f7365ae4d326
files src/evalfunc.c src/proto/term.pro src/term.c src/term.h src/testdir/test_edit.vim src/version.c
diffstat 6 files changed, 148 insertions(+), 45 deletions(-) [+]
line wrap: on
line diff
--- a/src/evalfunc.c
+++ b/src/evalfunc.c
@@ -5242,24 +5242,6 @@ f_getwininfo(typval_T *argvars, typval_T
 }
 
 /*
- * "getwinposx()" function
- */
-    static void
-f_getwinposx(typval_T *argvars UNUSED, typval_T *rettv)
-{
-    rettv->vval.v_number = -1;
-#ifdef FEAT_GUI
-    if (gui.in_use)
-    {
-	int	    x, y;
-
-	if (gui_mch_get_winpos(&x, &y) == OK)
-	    rettv->vval.v_number = x;
-    }
-#endif
-}
-
-/*
  * "win_findbuf()" function
  */
     static void
@@ -5307,6 +5289,32 @@ f_win_id2win(typval_T *argvars, typval_T
 }
 
 /*
+ * "getwinposx()" function
+ */
+    static void
+f_getwinposx(typval_T *argvars UNUSED, typval_T *rettv)
+{
+    rettv->vval.v_number = -1;
+#ifdef FEAT_GUI
+    if (gui.in_use)
+    {
+	int	    x, y;
+
+	if (gui_mch_get_winpos(&x, &y) == OK)
+	    rettv->vval.v_number = x;
+    }
+#endif
+#if defined(HAVE_TGETENT) && defined(FEAT_TERMRESPONSE)
+    {
+	int	    x, y;
+
+	if (term_get_winpos(&x, &y) == OK)
+	    rettv->vval.v_number = x;
+    }
+#endif
+}
+
+/*
  * "getwinposy()" function
  */
     static void
@@ -5322,6 +5330,14 @@ f_getwinposy(typval_T *argvars UNUSED, t
 	    rettv->vval.v_number = y;
     }
 #endif
+#if defined(HAVE_TGETENT) && defined(FEAT_TERMRESPONSE)
+    {
+	int	    x, y;
+
+	if (term_get_winpos(&x, &y) == OK)
+	    rettv->vval.v_number = y;
+    }
+#endif
 }
 
 /*
--- a/src/proto/term.pro
+++ b/src/proto/term.pro
@@ -22,6 +22,7 @@ void term_cursor_right(int i);
 void term_append_lines(int line_count);
 void term_delete_lines(int line_count);
 void term_set_winpos(int x, int y);
+int term_get_winpos(int *x, int *y);
 void term_set_winsize(int width, int height);
 void term_fg_color(int n);
 void term_bg_color(int n);
--- a/src/term.c
+++ b/src/term.c
@@ -845,9 +845,11 @@ static struct builtin_term builtin_termc
 						  ESC_STR "[8;%p1%d;%p2%dt")},
     {(int)KS_CWP,	IF_EB("\033[3;%p1%d;%p2%dt",
 						  ESC_STR "[3;%p1%d;%p2%dt")},
+    {(int)KS_CGP,	IF_EB("\033[13t", ESC_STR "[13t")},
 #  else
     {(int)KS_CWS,	IF_EB("\033[8;%d;%dt", ESC_STR "[8;%d;%dt")},
     {(int)KS_CWP,	IF_EB("\033[3;%d;%dt", ESC_STR "[3;%d;%dt")},
+    {(int)KS_CGP,	IF_EB("\033[13t", ESC_STR "[13t")},
 #  endif
     {(int)KS_CRV,	IF_EB("\033[>c", ESC_STR "[>c")},
     {(int)KS_RBG,	IF_EB("\033]11;?\007", ESC_STR "]11;?\007")},
@@ -2581,6 +2583,60 @@ term_set_winpos(int x, int y)
     OUT_STR(tgoto((char *)T_CWP, y, x));
 }
 
+# if defined(FEAT_TERMRESPONSE) || defined(PROTO)
+/*
+ * Return TRUE if we can request the terminal for a response.
+ */
+    static int
+can_get_termresponse()
+{
+    return cur_tmode == TMODE_RAW
+	    && termcap_active
+# ifdef UNIX
+	    && (is_not_a_term() || (isatty(1) && isatty(read_cmd_fd)))
+# endif
+	    && p_ek;
+}
+
+static int winpos_x;
+static int winpos_y;
+static int waiting_for_winpos = FALSE;
+
+/*
+ * Try getting the Vim window position from the terminal.
+ * Returns OK or FAIL.
+ */
+    int
+term_get_winpos(int *x, int *y)
+{
+    int count = 0;
+
+    if (*T_CGP == NUL || !can_get_termresponse())
+	return FAIL;
+    winpos_x = -1;
+    winpos_y = -1;
+    waiting_for_winpos = TRUE;
+    OUT_STR(T_CGP);
+    out_flush();
+
+    /* Try reading the result for 100 msec. */
+    while (count++ < 10)
+    {
+	(void)vpeekc_nomap();
+	if (winpos_x >= 0 && winpos_y >= 0)
+	{
+	    *x = winpos_x;
+	    *y = winpos_y;
+	    waiting_for_winpos = FALSE;
+	    return OK;
+	}
+	ui_delay(10, FALSE);
+    }
+    waiting_for_winpos = FALSE;
+    return FALSE;
+}
+# endif
+
     void
 term_set_winsize(int width, int height)
 {
@@ -3229,14 +3285,8 @@ stoptermcap(void)
 may_req_termresponse(void)
 {
     if (crv_status == CRV_GET
-	    && cur_tmode == TMODE_RAW
+	    && can_get_termresponse()
 	    && starting == 0
-	    && termcap_active
-	    && p_ek
-# ifdef UNIX
-	    && isatty(1)
-	    && isatty(read_cmd_fd)
-# endif
 	    && *T_CRV != NUL)
     {
 	LOG_TR("Sending CRV");
@@ -3263,13 +3313,8 @@ may_req_termresponse(void)
 may_req_ambiguous_char_width(void)
 {
     if (u7_status == U7_GET
-	    && cur_tmode == TMODE_RAW
-	    && termcap_active
-	    && p_ek
-#  ifdef UNIX
-	    && isatty(1)
-	    && isatty(read_cmd_fd)
-#  endif
+	    && can_get_termresponse()
+	    && starting == 0
 	    && *T_U7 != NUL
 	    && !option_was_set((char_u *)"ambiwidth"))
     {
@@ -3295,7 +3340,6 @@ may_req_ambiguous_char_width(void)
 }
 # endif
 
-#if defined(FEAT_TERMRESPONSE) || defined(PROTO)
 /*
  * Similar to requesting the version string: Request the terminal background
  * color when it is the right moment.
@@ -3304,13 +3348,8 @@ may_req_ambiguous_char_width(void)
 may_req_bg_color(void)
 {
     if (rbg_status == RBG_GET
-	    && cur_tmode == TMODE_RAW
-	    && termcap_active
-	    && p_ek
-#  ifdef UNIX
-	    && isatty(1)
-	    && isatty(read_cmd_fd)
-#  endif
+	    && can_get_termresponse()
+	    && starting == 0
 	    && *T_RBG != NUL
 	    && !option_was_set((char_u *)"bg"))
     {
@@ -3323,7 +3362,6 @@ may_req_bg_color(void)
 	(void)vpeekc_nomap();
     }
 }
-# endif
 
 # ifdef DEBUG_TERMRESPONSE
     static void
@@ -4136,10 +4174,12 @@ check_termcode(
 	     * - Cursor position report: <Esc>[{row};{col}R
 	     *   The final byte must be 'R'. It is used for checking the
 	     *   ambiguous-width character state.
+	     *
+	     * - window position reply: <Esc>[3;{x};{y}t
 	     */
 	    char_u *argp = tp[0] == ESC ? tp + 2 : tp + 1;
 
-	    if ((*T_CRV != NUL || *T_U7 != NUL)
+	    if ((*T_CRV != NUL || *T_U7 != NUL || waiting_for_winpos)
 			&& ((tp[0] == ESC && len >= 3 && tp[1] == '[')
 			    || (tp[0] == CSI && len >= 2))
 			&& (VIM_ISDIGIT(*argp) || *argp == '>' || *argp == '?'))
@@ -4278,6 +4318,41 @@ check_termcode(
 		    key_name[1] = (int)KE_IGNORE;
 		    slen = i + 1;
 		}
+
+		/*
+		 * Check for a window position response from the terminal:
+		 *       {lead}3;{x}:{y}t
+		 */
+		else if (waiting_for_winpos
+			    && ((len >= 4 && tp[0] == ESC && tp[1] == '[')
+				|| (len >= 3 && tp[0] == CSI))
+			    && tp[(j = 1 + (tp[0] == ESC))] == '3'
+			    && tp[j + 1] == ';')
+		{
+		    j += 2;
+		    for (i = j; i < len && vim_isdigit(tp[i]); ++i)
+			;
+		    if (i < len && tp[i] == ';')
+		    {
+			winpos_x = atoi((char *)tp + j);
+			j = i + 1;
+			for (i = j; i < len && vim_isdigit(tp[i]); ++i)
+			    ;
+			if (i < len && tp[i] == 't')
+			{
+			    winpos_y = atoi((char *)tp + j);
+			    /* got finished code: consume it */
+			    key_name[0] = (int)KS_EXTRA;
+			    key_name[1] = (int)KE_IGNORE;
+			    slen = i + 1;
+			}
+		    }
+		    if (i == len)
+		    {
+			LOG_TR("not enough characters for winpos");
+			return -1;
+		    }
+		}
 	    }
 
 	    /* Check for background color response from the terminal:
--- a/src/term.h
+++ b/src/term.h
@@ -77,6 +77,7 @@ enum SpecialKey
     KS_TS,	/* set window title start (to status line)*/
     KS_FS,	/* set window title end (from status line) */
     KS_CWP,	/* set window position in pixels */
+    KS_CGP,	/* get window position */
     KS_CWS,	/* set window size in characters */
     KS_CRV,	/* request version string */
     KS_RBG,	/* request background color */
@@ -163,7 +164,8 @@ extern char_u *(term_strings[]);    /* c
 #define T_CIE	(TERM_STR(KS_CIE))	/* set icon text end */
 #define T_TS	(TERM_STR(KS_TS))	/* set window title start */
 #define T_FS	(TERM_STR(KS_FS))	/* set window title end */
-#define T_CWP	(TERM_STR(KS_CWP))	/* window position */
+#define T_CWP	(TERM_STR(KS_CWP))	/* set window position */
+#define T_CGP	(TERM_STR(KS_CGP))	/* get window position */
 #define T_CWS	(TERM_STR(KS_CWS))	/* window size */
 #define T_CSI	(TERM_STR(KS_CSI))	/* start insert mode */
 #define T_CEI	(TERM_STR(KS_CEI))	/* end insert mode */
--- a/src/testdir/test_edit.vim
+++ b/src/testdir/test_edit.vim
@@ -1328,10 +1328,14 @@ func Test_edit_complete_very_long_name()
     " Long directory names only work on Unix.
     return
   endif
+  " Try to get the Vim window position before setting 'columns'.
+  let winposx = getwinposx()
+  let winposy = getwinposy()
   let save_columns = &columns
-  set columns=5000
-  call assert_equal(5000, &columns)
+  set columns=2000
+  call assert_equal(2000, &columns)
   set noswapfile
+
   let dirname = getcwd() . "/Xdir"
   let longdirname = dirname . repeat('/' . repeat('d', 255), 4)
   let longfilename = longdirname . '/' . repeat('a', 255)
@@ -1345,5 +1349,8 @@ func Test_edit_complete_very_long_name()
   exe 'bwipe! ' . longfilename
   call delete(dirname, 'rf')
   let &columns = save_columns
+  if winposx >= 0 && winposy >= 0
+    exe 'winpos ' . winposx . ' ' . winposy
+  endif
   set swapfile&
 endfunc
--- a/src/version.c
+++ b/src/version.c
@@ -765,6 +765,8 @@ static char *(features[]) =
 static int included_patches[] =
 {   /* Add new patch number below this line */
 /**/
+    543,
+/**/
     542,
 /**/
     541,