mirror of
https://github.com/vim/vim.git
synced 2025-09-24 03:44:06 -04:00
patch 9.0.0980: the keyboard state response may end up in a shell command
Problem: The keyboard state response may end up in a shell command. Solution: Only request the keyboard protocol state when the typeahead is empty, no more commands are following and not exiting. Add the t_RK termcap entry for this.
This commit is contained in:
@@ -1001,10 +1001,15 @@ mapping, see |map-bar|.
|
||||
WARNING: if you map <C-[> you may very well break any key codes that start
|
||||
with Esc. Make sure it comes AFTER other mappings.
|
||||
|
||||
Vim automatically detects if the modifyOtherKeys mode was enabled when it
|
||||
spots an escape sequence that must have been created by it. To see if Vim
|
||||
detected such an escape sequence use `:verbose map`, the first line will then
|
||||
show "Seen modifyOtherKeys: true" (possibly translated).
|
||||
Starting with xterm version 377 Vim can detect the modifyOtherKeys state by
|
||||
requesting it. For this the 't_RK' termcap entry is used. When the response
|
||||
is found then Vim will know whether modifyOtherKeys level 2 is enabled, and
|
||||
handle mappings accordingly.
|
||||
|
||||
Before version 377 Vim automatically detects if the modifyOtherKeys mode was
|
||||
enabled when it spots an escape sequence that must have been created by it.
|
||||
To see if Vim detected such an escape sequence use `:verbose map`, the first
|
||||
line will then show "Seen modifyOtherKeys: true" (possibly translated).
|
||||
|
||||
This automatic detection depends on receiving an escape code starting with
|
||||
"<1b>[27;". This is the normal way xterm sends these key codes. However, if
|
||||
@@ -1016,6 +1021,9 @@ after the CTRL-V key. This can be used to check whether modifyOtherKeys is
|
||||
enabled: In Insert mode type CTRL-SHIFT-V CTRL-V, if you get one byte then
|
||||
modifyOtherKeys is off, if you get <1b>[27;5;118~ then it is on.
|
||||
|
||||
Note that xterm up to version 376 has a bug that makes Shift-Esc send a
|
||||
regular Esc code, the Shift modifier is dropped.
|
||||
|
||||
When the 'esckeys' option is off, then modifyOtherKeys will be disabled in
|
||||
Insert mode to avoid every key with a modifier causing Insert mode to end.
|
||||
|
||||
|
@@ -90,6 +90,11 @@ Note: When 't_ti' is not empty, Vim assumes that it causes switching to the
|
||||
alternate screen. This may slightly change what happens when executing a
|
||||
shell command or exiting Vim. To avoid this use 't_TI' and 't_TE'.
|
||||
|
||||
Vim will try to detect what keyboard protocol the terminal is using with the
|
||||
't_RK' termcap entry. This is sent after 't_TI', but only when there is no
|
||||
work to do (no typeahead and no pending commands). That is to avoid the
|
||||
response to end up in a shell command or arrive after Vim exits.
|
||||
|
||||
*xterm-bracketed-paste*
|
||||
When the 't_BE' option is set then 't_BE' will be sent to the
|
||||
terminal when entering "raw" mode and 't_BD' when leaving "raw" mode. The
|
||||
@@ -388,6 +393,8 @@ Added by Vim (there are no standard codes for these):
|
||||
xterm and other terminal emulators) The
|
||||
response is stored in |v:termresponse| |xterm-8bit|
|
||||
|'ttymouse'| |xterm-codes|
|
||||
t_RK request terminal keyboard protocol state; *t_RK* *'t_RK'*
|
||||
sent after |t_TI|
|
||||
t_u7 request cursor position (for xterm) *t_u7* *'t_u7'*
|
||||
see |'ambiwidth'|
|
||||
The response is stored in |v:termu7resp|
|
||||
|
11
src/edit.c
11
src/edit.c
@@ -571,6 +571,8 @@ edit(
|
||||
#ifdef USE_ON_FLY_SCROLL
|
||||
dont_scroll = FALSE; // allow scrolling here
|
||||
#endif
|
||||
// May request the keyboard protocol state now.
|
||||
may_send_t_RK();
|
||||
|
||||
/*
|
||||
* Get a character for Insert mode. Ignore K_IGNORE and K_NOP.
|
||||
@@ -1479,7 +1481,8 @@ ins_redraw(int ready) // not busy with something
|
||||
aco_save_T aco;
|
||||
varnumber_T tick = CHANGEDTICK(curbuf);
|
||||
|
||||
// save and restore curwin and curbuf, in case the autocmd changes them
|
||||
// Save and restore curwin and curbuf, in case the autocmd changes
|
||||
// them.
|
||||
aucmd_prepbuf(&aco, curbuf);
|
||||
apply_autocmds(EVENT_TEXTCHANGEDI, NULL, NULL, FALSE, curbuf);
|
||||
aucmd_restbuf(&aco);
|
||||
@@ -1499,7 +1502,8 @@ ins_redraw(int ready) // not busy with something
|
||||
aco_save_T aco;
|
||||
varnumber_T tick = CHANGEDTICK(curbuf);
|
||||
|
||||
// save and restore curwin and curbuf, in case the autocmd changes them
|
||||
// Save and restore curwin and curbuf, in case the autocmd changes
|
||||
// them.
|
||||
aucmd_prepbuf(&aco, curbuf);
|
||||
apply_autocmds(EVENT_TEXTCHANGEDP, NULL, NULL, FALSE, curbuf);
|
||||
aucmd_restbuf(&aco);
|
||||
@@ -3706,7 +3710,7 @@ ins_esc(
|
||||
out_str(T_BE);
|
||||
|
||||
// Re-enable modifyOtherKeys.
|
||||
out_str(T_CTI);
|
||||
out_str_t_TI();
|
||||
}
|
||||
#ifdef FEAT_CONCEAL
|
||||
// Check if the cursor line needs redrawing after changing State. If
|
||||
@@ -4384,6 +4388,7 @@ bracketed_paste(paste_mode_T mode, int drop, garray_T *gap)
|
||||
do
|
||||
c = vgetc();
|
||||
while (c == K_IGNORE || c == K_VER_SCROLLBAR || c == K_HOR_SCROLLBAR);
|
||||
|
||||
if (c == NUL || got_int || (ex_normal_busy > 0 && c == Ctrl_C))
|
||||
// When CTRL-C was encountered the typeahead will be flushed and we
|
||||
// won't get the end sequence. Except when using ":normal".
|
||||
|
@@ -2908,6 +2908,9 @@ getexmodeline(
|
||||
long sw;
|
||||
char_u *s;
|
||||
|
||||
// May request the keyboard protocol state now.
|
||||
may_send_t_RK();
|
||||
|
||||
if (ga_grow(&line_ga, 40) == FAIL)
|
||||
break;
|
||||
|
||||
|
18
src/main.c
18
src/main.c
@@ -1162,6 +1162,15 @@ may_trigger_safestateagain(void)
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Return TRUE if there is any typeahead, pending operator or command.
|
||||
*/
|
||||
int
|
||||
work_pending(void)
|
||||
{
|
||||
return op_pending() || !is_safe_now();
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Main loop: Execute Normal mode commands until exiting Vim.
|
||||
@@ -1477,10 +1486,11 @@ main_loop(
|
||||
gui_mouse_correct();
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Update w_curswant if w_set_curswant has been set.
|
||||
* Postponed until here to avoid computing w_virtcol too often.
|
||||
*/
|
||||
// May request the keyboard protocol state now.
|
||||
may_send_t_RK();
|
||||
|
||||
// Update w_curswant if w_set_curswant has been set.
|
||||
// Postponed until here to avoid computing w_virtcol too often.
|
||||
update_curswant();
|
||||
|
||||
#ifdef FEAT_EVAL
|
||||
|
@@ -455,7 +455,7 @@ normal_cmd_get_more_chars(
|
||||
|
||||
// Re-enable bracketed paste mode and modifyOtherKeys
|
||||
out_str(T_BE);
|
||||
out_str(T_CTI);
|
||||
out_str_t_TI();
|
||||
}
|
||||
|
||||
if (langmap_active)
|
||||
|
@@ -5379,7 +5379,7 @@ finished:
|
||||
|
||||
if (tmode == TMODE_RAW)
|
||||
// possibly enables modifyOtherKeys again
|
||||
out_str(T_CTI);
|
||||
out_str_t_TI();
|
||||
}
|
||||
# endif
|
||||
|
||||
|
@@ -9,6 +9,7 @@ void may_trigger_safestate(int safe);
|
||||
void state_no_longer_safe(char *reason);
|
||||
int get_was_safe_state(void);
|
||||
void may_trigger_safestateagain(void);
|
||||
int work_pending(void);
|
||||
void main_loop(int cmdwin, int noexmode);
|
||||
void getout_preserve_modified(int exitval);
|
||||
void getout(int exitval);
|
||||
|
@@ -48,6 +48,8 @@ void shell_resized(void);
|
||||
void shell_resized_check(void);
|
||||
void set_shellsize(int width, int height, int mustset);
|
||||
void out_str_t_TE(void);
|
||||
void out_str_t_TI(void);
|
||||
void may_send_t_RK(void);
|
||||
void settmode(tmode_T tmode);
|
||||
void starttermcap(void);
|
||||
void stoptermcap(void);
|
||||
|
60
src/term.c
60
src/term.c
@@ -452,7 +452,8 @@ static tcap_entry_T builtin_xterm[] = {
|
||||
{(int)KS_TI, "\0337\033[?47h"},
|
||||
{(int)KS_TE, "\033[?47l\0338"},
|
||||
# endif
|
||||
{(int)KS_CTI, "\033[>4;2m\033[?4m"}, // see "builtin_mok2"
|
||||
{(int)KS_CTI, "\033[>4;2m"},
|
||||
{(int)KS_CRK, "\033[?4m"}, // see "builtin_mok2"
|
||||
{(int)KS_CTE, "\033[>4;m"},
|
||||
{(int)KS_CIS, "\033]1;"},
|
||||
{(int)KS_CIE, "\007"},
|
||||
@@ -593,10 +594,15 @@ static tcap_entry_T builtin_xterm[] = {
|
||||
* xterm.
|
||||
*/
|
||||
static tcap_entry_T builtin_mok2[] = {
|
||||
// t_TI enables modifyOtherKeys level 2
|
||||
{(int)KS_CTI, "\033[>4;2m"},
|
||||
|
||||
// XTQMODKEYS was added in xterm version 377: "CSI ? 4 m" which should
|
||||
// return "{lead} > 4 ; Pv m". Before version 377 we expect it to have no
|
||||
// effect.
|
||||
{(int)KS_CTI, "\033[>4;2m\033[?4m"},
|
||||
{(int)KS_CRK, "\033[?4m"},
|
||||
|
||||
// t_TE disables modifyOtherKeys
|
||||
{(int)KS_CTE, "\033[>4;m"},
|
||||
|
||||
{(int)KS_NAME, NULL} // end marker
|
||||
@@ -606,11 +612,13 @@ static tcap_entry_T builtin_mok2[] = {
|
||||
* Additions for using the Kitty keyboard protocol.
|
||||
*/
|
||||
static tcap_entry_T builtin_kitty[] = {
|
||||
// t_TI enables the kitty keyboard protocol, requests the kitty keyboard
|
||||
// protocol state and requests the version response.
|
||||
{(int)KS_CTI, "\033[=1;1u\033[?u\033[>c"},
|
||||
// t_TI enables the kitty keyboard protocol.
|
||||
{(int)KS_CTI, "\033[=1;1u"},
|
||||
|
||||
// t_TE also disabled modifyOtherKeys, because t_TI from xterm may already
|
||||
// t_RK requests the kitty keyboard protocol state
|
||||
{(int)KS_CRK, "\033[?u"},
|
||||
|
||||
// t_TE also disables modifyOtherKeys, because t_TI from xterm may already
|
||||
// have been used.
|
||||
{(int)KS_CTE, "\033[>4;m\033[=0;1u"},
|
||||
|
||||
@@ -1685,7 +1693,7 @@ get_term_entries(int *height, int *width)
|
||||
{KS_CM, "cm"}, {KS_SR, "sr"},
|
||||
{KS_CRI,"RI"}, {KS_VB, "vb"}, {KS_KS, "ks"},
|
||||
{KS_KE, "ke"}, {KS_TI, "ti"}, {KS_TE, "te"},
|
||||
{KS_CTI, "TI"}, {KS_CTE, "TE"},
|
||||
{KS_CTI, "TI"}, {KS_CRK, "RK"}, {KS_CTE, "TE"},
|
||||
{KS_BC, "bc"}, {KS_CSB,"Sb"}, {KS_CSF,"Sf"},
|
||||
{KS_CAB,"AB"}, {KS_CAF,"AF"}, {KS_CAU,"AU"},
|
||||
{KS_LE, "le"},
|
||||
@@ -3693,6 +3701,40 @@ out_str_t_TE(void)
|
||||
kitty_protocol_state = KKPS_AFTER_T_KE;
|
||||
}
|
||||
|
||||
static int send_t_RK = FALSE;
|
||||
|
||||
/*
|
||||
* Output T_TI and setup for what follows.
|
||||
*/
|
||||
void
|
||||
out_str_t_TI(void)
|
||||
{
|
||||
out_str(T_CTI);
|
||||
|
||||
// Send t_RK when there is no more work to do.
|
||||
send_t_RK = TRUE;
|
||||
}
|
||||
|
||||
/*
|
||||
* If t_TI was recently sent and there is no typeahead or work to do, now send
|
||||
* t_RK. This is postponed to avoid the response arriving in a shell command
|
||||
* or after Vim exits.
|
||||
*/
|
||||
void
|
||||
may_send_t_RK(void)
|
||||
{
|
||||
if (send_t_RK
|
||||
&& !work_pending()
|
||||
&& !ex_normal_busy
|
||||
&& !in_feedkeys
|
||||
&& !exiting)
|
||||
{
|
||||
send_t_RK = FALSE;
|
||||
out_str(T_CRK);
|
||||
out_flush();
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Set the terminal to TMODE_RAW (for Normal mode) or TMODE_COOK (for external
|
||||
* commands and Ex mode).
|
||||
@@ -3751,7 +3793,7 @@ settmode(tmode_T tmode)
|
||||
{
|
||||
out_str(T_BE); // enable bracketed paste mode (should
|
||||
// be before mch_settmode().
|
||||
out_str(T_CTI); // possibly enables modifyOtherKeys
|
||||
out_str_t_TI(); // possibly enables modifyOtherKeys
|
||||
}
|
||||
}
|
||||
out_flush();
|
||||
@@ -3775,7 +3817,7 @@ starttermcap(void)
|
||||
MAY_WANT_TO_LOG_THIS;
|
||||
|
||||
out_str(T_TI); // start termcap mode
|
||||
out_str(T_CTI); // start "raw" mode
|
||||
out_str_t_TI(); // start "raw" mode
|
||||
out_str(T_KS); // start "keypad transmit" mode
|
||||
out_str(T_BE); // enable bracketed paste mode
|
||||
|
||||
|
@@ -69,6 +69,7 @@ enum SpecialKey
|
||||
KS_KE, // out of "keypad transmit" mode
|
||||
KS_TI, // put terminal in termcap mode
|
||||
KS_CTI, // put terminal in "raw" mode
|
||||
KS_CRK, // request keyboard protocol state
|
||||
KS_TE, // end of termcap mode
|
||||
KS_CTE, // end of "raw" mode
|
||||
KS_BC, // backspace character (cursor left)
|
||||
@@ -177,6 +178,7 @@ extern char_u *(term_strings[]); // current terminal strings
|
||||
#define T_KE (TERM_STR(KS_KE)) // out of "keypad transmit" mode
|
||||
#define T_TI (TERM_STR(KS_TI)) // put terminal in termcap mode
|
||||
#define T_CTI (TERM_STR(KS_CTI)) // put terminal in "raw" mode
|
||||
#define T_CRK (TERM_STR(KS_CRK)) // request keyboard protocol status
|
||||
#define T_TE (TERM_STR(KS_TE)) // end of termcap mode
|
||||
#define T_CTE (TERM_STR(KS_CTE)) // end of "raw" mode
|
||||
#define T_BC (TERM_STR(KS_BC)) // backspace character
|
||||
|
@@ -695,6 +695,8 @@ static char *(features[]) =
|
||||
|
||||
static int included_patches[] =
|
||||
{ /* Add new patch number below this line */
|
||||
/**/
|
||||
980,
|
||||
/**/
|
||||
979,
|
||||
/**/
|
||||
|
Reference in New Issue
Block a user