# HG changeset patch # User Christian Brabandt # Date 1491338705 -7200 # Node ID 0c091a7c588cca4b008424681050ba972e88d6d2 # Parent 2808577a0260ecf34ac1d9b49d78d6f7ceb2148d patch 8.0.0543: test_edit causes older xfce4-terminal to close commit https://github.com/vim/vim/commit/ba6ec182973af726ce9b7b7eb3753fc3a7ae7d1b Author: Bram Moolenaar 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. diff --git a/src/evalfunc.c b/src/evalfunc.c --- 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 } /* diff --git a/src/proto/term.pro b/src/proto/term.pro --- 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); diff --git a/src/term.c b/src/term.c --- 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: [{row};{col}R * The final byte must be 'R'. It is used for checking the * ambiguous-width character state. + * + * - window position reply: [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: diff --git a/src/term.h b/src/term.h --- 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 */ diff --git a/src/testdir/test_edit.vim b/src/testdir/test_edit.vim --- 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 diff --git a/src/version.c b/src/version.c --- 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,