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)
This commit is contained in:
44
src/term.c
44
src/term.c
@ -143,6 +143,9 @@ static int rbm_status = STATUS_GET;
|
|||||||
|
|
||||||
/* Request cursor style report: */
|
/* Request cursor style report: */
|
||||||
static int rcs_status = STATUS_GET;
|
static int rcs_status = STATUS_GET;
|
||||||
|
|
||||||
|
/* Request windos position report: */
|
||||||
|
static int winpos_status = STATUS_GET;
|
||||||
# endif
|
# endif
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -2778,9 +2781,9 @@ can_get_termresponse()
|
|||||||
&& p_ek;
|
&& p_ek;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int winpos_x;
|
static int winpos_x = -1;
|
||||||
static int winpos_y;
|
static int winpos_y = -1;
|
||||||
static int waiting_for_winpos = FALSE;
|
static int did_request_winpos = 0;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Try getting the Vim window position from the terminal.
|
* Try getting the Vim window position from the terminal.
|
||||||
@ -2790,29 +2793,43 @@ static int waiting_for_winpos = FALSE;
|
|||||||
term_get_winpos(int *x, int *y, varnumber_T timeout)
|
term_get_winpos(int *x, int *y, varnumber_T timeout)
|
||||||
{
|
{
|
||||||
int count = 0;
|
int count = 0;
|
||||||
|
int prev_winpos_x = winpos_x;
|
||||||
|
int prev_winpos_y = winpos_y;
|
||||||
|
|
||||||
if (*T_CGP == NUL || !can_get_termresponse())
|
if (*T_CGP == NUL || !can_get_termresponse())
|
||||||
return FAIL;
|
return FAIL;
|
||||||
winpos_x = -1;
|
winpos_x = -1;
|
||||||
winpos_y = -1;
|
winpos_y = -1;
|
||||||
waiting_for_winpos = TRUE;
|
++did_request_winpos;
|
||||||
|
winpos_status = STATUS_SENT;
|
||||||
OUT_STR(T_CGP);
|
OUT_STR(T_CGP);
|
||||||
out_flush();
|
out_flush();
|
||||||
|
|
||||||
/* Try reading the result for "timeout" msec. */
|
/* Try reading the result for "timeout" msec. */
|
||||||
while (count++ < timeout / 10)
|
while (count++ <= timeout / 10 && !got_int)
|
||||||
{
|
{
|
||||||
(void)vpeekc_nomap();
|
(void)vpeekc_nomap();
|
||||||
if (winpos_x >= 0 && winpos_y >= 0)
|
if (winpos_x >= 0 && winpos_y >= 0)
|
||||||
{
|
{
|
||||||
*x = winpos_x;
|
*x = winpos_x;
|
||||||
*y = winpos_y;
|
*y = winpos_y;
|
||||||
waiting_for_winpos = FALSE;
|
|
||||||
return OK;
|
return OK;
|
||||||
}
|
}
|
||||||
ui_delay(10, FALSE);
|
ui_delay(10, FALSE);
|
||||||
}
|
}
|
||||||
waiting_for_winpos = FALSE;
|
/* Do not reset "did_request_winpos", if we timed out the response might
|
||||||
|
* still come later and we must consume it. */
|
||||||
|
|
||||||
|
winpos_x = prev_winpos_x;
|
||||||
|
winpos_y = prev_winpos_y;
|
||||||
|
if (timeout < 10 && prev_winpos_y >= 0 && prev_winpos_y >= 0)
|
||||||
|
{
|
||||||
|
/* Polling: return previous values if we have them. */
|
||||||
|
*x = winpos_x;
|
||||||
|
*y = winpos_y;
|
||||||
|
return OK;
|
||||||
|
}
|
||||||
|
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
# endif
|
# endif
|
||||||
@ -3365,7 +3382,8 @@ settmode(int tmode)
|
|||||||
#endif
|
#endif
|
||||||
|| rbg_status == STATUS_SENT
|
|| rbg_status == STATUS_SENT
|
||||||
|| rbm_status == STATUS_SENT
|
|| rbm_status == STATUS_SENT
|
||||||
|| rcs_status == STATUS_SENT))
|
|| rcs_status == STATUS_SENT
|
||||||
|
|| winpos_status == STATUS_SENT))
|
||||||
(void)vpeekc_nomap();
|
(void)vpeekc_nomap();
|
||||||
check_for_codes_from_term();
|
check_for_codes_from_term();
|
||||||
}
|
}
|
||||||
@ -3439,7 +3457,8 @@ stoptermcap(void)
|
|||||||
# endif
|
# endif
|
||||||
|| rbg_status == STATUS_SENT
|
|| rbg_status == STATUS_SENT
|
||||||
|| rbm_status == STATUS_SENT
|
|| rbm_status == STATUS_SENT
|
||||||
|| rcs_status == STATUS_SENT)
|
|| rcs_status == STATUS_SENT
|
||||||
|
|| winpos_status == STATUS_SENT)
|
||||||
{
|
{
|
||||||
# ifdef UNIX
|
# ifdef UNIX
|
||||||
/* Give the terminal a chance to respond. */
|
/* Give the terminal a chance to respond. */
|
||||||
@ -4468,7 +4487,7 @@ check_termcode(
|
|||||||
*/
|
*/
|
||||||
char_u *argp = tp[0] == ESC ? tp + 2 : tp + 1;
|
char_u *argp = tp[0] == ESC ? tp + 2 : tp + 1;
|
||||||
|
|
||||||
if ((*T_CRV != NUL || *T_U7 != NUL || waiting_for_winpos)
|
if ((*T_CRV != NUL || *T_U7 != NUL || did_request_winpos)
|
||||||
&& ((tp[0] == ESC && len >= 3 && tp[1] == '[')
|
&& ((tp[0] == ESC && len >= 3 && tp[1] == '[')
|
||||||
|| (tp[0] == CSI && len >= 2))
|
|| (tp[0] == CSI && len >= 2))
|
||||||
&& (VIM_ISDIGIT(*argp) || *argp == '>' || *argp == '?'))
|
&& (VIM_ISDIGIT(*argp) || *argp == '>' || *argp == '?'))
|
||||||
@ -4730,7 +4749,7 @@ check_termcode(
|
|||||||
* Check for a window position response from the terminal:
|
* Check for a window position response from the terminal:
|
||||||
* {lead}3;{x}:{y}t
|
* {lead}3;{x}:{y}t
|
||||||
*/
|
*/
|
||||||
else if (waiting_for_winpos
|
else if (did_request_winpos
|
||||||
&& ((len >= 4 && tp[0] == ESC && tp[1] == '[')
|
&& ((len >= 4 && tp[0] == ESC && tp[1] == '[')
|
||||||
|| (len >= 3 && tp[0] == CSI))
|
|| (len >= 3 && tp[0] == CSI))
|
||||||
&& tp[(j = 1 + (tp[0] == ESC))] == '3'
|
&& tp[(j = 1 + (tp[0] == ESC))] == '3'
|
||||||
@ -4752,6 +4771,9 @@ check_termcode(
|
|||||||
key_name[0] = (int)KS_EXTRA;
|
key_name[0] = (int)KS_EXTRA;
|
||||||
key_name[1] = (int)KE_IGNORE;
|
key_name[1] = (int)KE_IGNORE;
|
||||||
slen = i + 1;
|
slen = i + 1;
|
||||||
|
|
||||||
|
if (--did_request_winpos <= 0)
|
||||||
|
winpos_status = STATUS_GOT;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (i == len)
|
if (i == len)
|
||||||
|
|||||||
@ -766,6 +766,8 @@ static char *(features[]) =
|
|||||||
|
|
||||||
static int included_patches[] =
|
static int included_patches[] =
|
||||||
{ /* Add new patch number below this line */
|
{ /* Add new patch number below this line */
|
||||||
|
/**/
|
||||||
|
1573,
|
||||||
/**/
|
/**/
|
||||||
1572,
|
1572,
|
||||||
/**/
|
/**/
|
||||||
|
|||||||
Reference in New Issue
Block a user