]> granicus.if.org Git - vim/commitdiff
patch 8.0.0543: test_edit causes older xfce4-terminal to close v8.0.0543
authorBram Moolenaar <Bram@vim.org>
Tue, 4 Apr 2017 20:41:10 +0000 (22:41 +0200)
committerBram Moolenaar <Bram@vim.org>
Tue, 4 Apr 2017 20:41:10 +0000 (22:41 +0200)
Problem:    Test_edit causes older xfce4-terminal to close. (Dominique Pelle)
Solution:   Reduce number of columns to 2000.  Try to restore the window
            position.

src/evalfunc.c
src/proto/term.pro
src/term.c
src/term.h
src/testdir/test_edit.vim
src/version.c

index 6f330162b4a273af363225e82d905d691d18d733..08f0a41af8d70960587b2fb350074eda32469402 100644 (file)
@@ -5241,24 +5241,6 @@ f_getwininfo(typval_T *argvars, typval_T *rettv)
 #endif
 }
 
-/*
- * "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
  */
@@ -5306,6 +5288,32 @@ f_win_id2win(typval_T *argvars, typval_T *rettv)
     rettv->vval.v_number = win_id2win(argvars);
 }
 
+/*
+ * "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
  */
@@ -5322,6 +5330,14 @@ f_getwinposy(typval_T *argvars UNUSED, typval_T *rettv)
            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
 }
 
 /*
index 0c238d3d84fb02e363711fd9eef848f8f8d454f7..7d9fc6ae71ee0489eb5cd91627f6cdc5c8053098 100644 (file)
@@ -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);
index cac47da06f1984a2128d42763daccabecee63dfb..85b1ff515cf67419b192e40f1e8ac1703110bdb3 100644 (file)
@@ -845,9 +845,11 @@ static struct builtin_term builtin_termcaps[] =
                                                  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:
index e67ed4f74ae797f804eccfd511cecc59fabf659a..be01cb5ad6413cf0b5e876d87ee4b8a69920203a 100644 (file)
@@ -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[]);    /* current terminal strings */
 #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 */
index 4db7bcf3a5d3580a85715686bda59ce0815777ee..2df0d6f24213e6c7e17b487e26e574ec40c94ddc 100644 (file)
@@ -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
index d22f1655324ae4c1d34aa7e305010bcf456dcb28..4e37cf31068a4a8696b3626d8e53ec203f723ef0 100644 (file)
@@ -764,6 +764,8 @@ static char *(features[]) =
 
 static int included_patches[] =
 {   /* Add new patch number below this line */
+/**/
+    543,
 /**/
     542,
 /**/