Skip to content

Commit 89894aa

Browse files
committed
patch 8.0.1573: getwinpos(1) may cause response to be handled as command
Problem: getwinpos(1) may cause response to be handled as command. Solution: Handle any cursor position report once one was request. (partly by Hirohito Higashi)
1 parent 362dc33 commit 89894aa

File tree

2 files changed

+35
-11
lines changed

2 files changed

+35
-11
lines changed

src/term.c

Lines changed: 33 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -143,6 +143,9 @@ static int rbm_status = STATUS_GET;
143143

144144
/* Request cursor style report: */
145145
static int rcs_status = STATUS_GET;
146+
147+
/* Request windos position report: */
148+
static int winpos_status = STATUS_GET;
146149
# endif
147150

148151
/*
@@ -2778,9 +2781,9 @@ can_get_termresponse()
27782781
&& p_ek;
27792782
}
27802783

2781-
static int winpos_x;
2782-
static int winpos_y;
2783-
static int waiting_for_winpos = FALSE;
2784+
static int winpos_x = -1;
2785+
static int winpos_y = -1;
2786+
static int did_request_winpos = 0;
27842787

27852788
/*
27862789
* Try getting the Vim window position from the terminal.
@@ -2790,29 +2793,43 @@ static int waiting_for_winpos = FALSE;
27902793
term_get_winpos(int *x, int *y, varnumber_T timeout)
27912794
{
27922795
int count = 0;
2796+
int prev_winpos_x = winpos_x;
2797+
int prev_winpos_y = winpos_y;
27932798

27942799
if (*T_CGP == NUL || !can_get_termresponse())
27952800
return FAIL;
27962801
winpos_x = -1;
27972802
winpos_y = -1;
2798-
waiting_for_winpos = TRUE;
2803+
++did_request_winpos;
2804+
winpos_status = STATUS_SENT;
27992805
OUT_STR(T_CGP);
28002806
out_flush();
28012807

28022808
/* Try reading the result for "timeout" msec. */
2803-
while (count++ < timeout / 10)
2809+
while (count++ <= timeout / 10 && !got_int)
28042810
{
28052811
(void)vpeekc_nomap();
28062812
if (winpos_x >= 0 && winpos_y >= 0)
28072813
{
28082814
*x = winpos_x;
28092815
*y = winpos_y;
2810-
waiting_for_winpos = FALSE;
28112816
return OK;
28122817
}
28132818
ui_delay(10, FALSE);
28142819
}
2815-
waiting_for_winpos = FALSE;
2820+
/* Do not reset "did_request_winpos", if we timed out the response might
2821+
* still come later and we must consume it. */
2822+
2823+
winpos_x = prev_winpos_x;
2824+
winpos_y = prev_winpos_y;
2825+
if (timeout < 10 && prev_winpos_y >= 0 && prev_winpos_y >= 0)
2826+
{
2827+
/* Polling: return previous values if we have them. */
2828+
*x = winpos_x;
2829+
*y = winpos_y;
2830+
return OK;
2831+
}
2832+
28162833
return FALSE;
28172834
}
28182835
# endif
@@ -3365,7 +3382,8 @@ settmode(int tmode)
33653382
#endif
33663383
|| rbg_status == STATUS_SENT
33673384
|| rbm_status == STATUS_SENT
3368-
|| rcs_status == STATUS_SENT))
3385+
|| rcs_status == STATUS_SENT
3386+
|| winpos_status == STATUS_SENT))
33693387
(void)vpeekc_nomap();
33703388
check_for_codes_from_term();
33713389
}
@@ -3439,7 +3457,8 @@ stoptermcap(void)
34393457
# endif
34403458
|| rbg_status == STATUS_SENT
34413459
|| rbm_status == STATUS_SENT
3442-
|| rcs_status == STATUS_SENT)
3460+
|| rcs_status == STATUS_SENT
3461+
|| winpos_status == STATUS_SENT)
34433462
{
34443463
# ifdef UNIX
34453464
/* Give the terminal a chance to respond. */
@@ -4468,7 +4487,7 @@ check_termcode(
44684487
*/
44694488
char_u *argp = tp[0] == ESC ? tp + 2 : tp + 1;
44704489

4471-
if ((*T_CRV != NUL || *T_U7 != NUL || waiting_for_winpos)
4490+
if ((*T_CRV != NUL || *T_U7 != NUL || did_request_winpos)
44724491
&& ((tp[0] == ESC && len >= 3 && tp[1] == '[')
44734492
|| (tp[0] == CSI && len >= 2))
44744493
&& (VIM_ISDIGIT(*argp) || *argp == '>' || *argp == '?'))
@@ -4730,7 +4749,7 @@ check_termcode(
47304749
* Check for a window position response from the terminal:
47314750
* {lead}3;{x}:{y}t
47324751
*/
4733-
else if (waiting_for_winpos
4752+
else if (did_request_winpos
47344753
&& ((len >= 4 && tp[0] == ESC && tp[1] == '[')
47354754
|| (len >= 3 && tp[0] == CSI))
47364755
&& tp[(j = 1 + (tp[0] == ESC))] == '3'
@@ -4752,6 +4771,9 @@ check_termcode(
47524771
key_name[0] = (int)KS_EXTRA;
47534772
key_name[1] = (int)KE_IGNORE;
47544773
slen = i + 1;
4774+
4775+
if (--did_request_winpos <= 0)
4776+
winpos_status = STATUS_GOT;
47554777
}
47564778
}
47574779
if (i == len)

src/version.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -766,6 +766,8 @@ static char *(features[]) =
766766

767767
static int included_patches[] =
768768
{ /* Add new patch number below this line */
769+
/**/
770+
1573,
769771
/**/
770772
1572,
771773
/**/

0 commit comments

Comments
 (0)