Commit: patch 9.2.0015: Vim gets confused by OSC handling

1 view
Skip to first unread message

Christian Brabandt

unread,
Feb 17, 2026, 2:16:44 PM (2 days ago) Feb 17
to vim...@googlegroups.com
patch 9.2.0015: Vim gets confused by OSC handling

Commit: https://github.com/vim/vim/commit/b3e57895211c31c9aaa083af46ce0ba96b9841a3
Author: Foxe Chen <chen...@gmail.com>
Date: Mon Feb 16 22:26:57 2026 +0000

patch 9.2.0015: Vim gets confused by OSC handling

Problem: Vim gets confused by OSC handling, causing Vim to start in
search mode (Shane Harper, after v9.1.1703)
Solution: In handle_mapping(), check if we are handling OSC sequences
and if yes go straight to check_termcode() (Foxe Chen)

fixes: #19426
closes: #19435

Signed-off-by: Foxe Chen <chen...@gmail.com>
Signed-off-by: Christian Brabandt <c...@256bit.org>

diff --git a/src/getchar.c b/src/getchar.c
index c7eb7dda4..bbd84c6f9 100644
--- a/src/getchar.c
+++ b/src/getchar.c
@@ -2833,9 +2833,13 @@ handle_mapping(
int i;
int local_State = get_real_state();
int is_plug_map = FALSE;
+ bool in_osc = in_osc_sequence(); // If we are in an OSC sequence,
+ // then go straight to
+ // check_termcode() in order to
+ // consume chars.

// If typeahead starts with <Plug> then remap, even for a "noremap" mapping.
- if (typebuf.tb_len >= 3
+ if (!in_osc && typebuf.tb_len >= 3
&& typebuf.tb_buf[typebuf.tb_off] == K_SPECIAL
&& typebuf.tb_buf[typebuf.tb_off + 1] == KS_EXTRA
&& typebuf.tb_buf[typebuf.tb_off + 2] == KE_PLUG)
@@ -2853,9 +2857,10 @@ handle_mapping(
* - waiting for "hit return to continue" and CR or SPACE typed
* - waiting for a char with --more--
* - in Ctrl-X mode, and we get a valid char for that mode
+ * - currently receiving OSC sequence
*/
tb_c1 = typebuf.tb_buf[typebuf.tb_off];
- if (no_mapping == 0 && is_maphash_valid()
+ if (!in_osc && no_mapping == 0 && is_maphash_valid()
&& (no_zero_mapping == 0 || tb_c1 != '0')
&& (typebuf.tb_maplen == 0 || is_plug_map
|| (p_remap
@@ -3043,7 +3048,8 @@ handle_mapping(
/*
* Check for match with 'pastetoggle'
*/
- if (*p_pt != NUL && mp == NULL && (State & (MODE_INSERT | MODE_NORMAL)))
+ if (!in_osc && *p_pt != NUL && mp == NULL &&
+ (State & (MODE_INSERT | MODE_NORMAL)))
{
for (mlen = 0; mlen < typebuf.tb_len && p_pt[mlen]; ++mlen)
if (p_pt[mlen] != typebuf.tb_buf[typebuf.tb_off + mlen])
@@ -3082,9 +3088,9 @@ handle_mapping(
// May check for a terminal code when there is no mapping or only a partial
// mapping. Also check if there is a full mapping with <Esc>, unless timed
// out, since that is nearly always a partial match with a terminal code.
- if ((mp == NULL || max_mlen + want_termcode > mp_match_len
+ if (in_osc || ((mp == NULL || max_mlen + want_termcode > mp_match_len
|| (mp_match_len == 1 && *mp->m_keys == ESC && !*timedout))
- && keylen != KEYLEN_PART_MAP)
+ && keylen != KEYLEN_PART_MAP))
{
int save_keylen = keylen;

@@ -3097,12 +3103,12 @@ handle_mapping(
* - and not an ESC sequence, not in insert mode or p_ek is on,
* - and when not timed out,
*/
- if (no_mapping == 0 || allow_keys != 0)
+ if (in_osc || no_mapping == 0 || allow_keys != 0)
{
- if ((typebuf.tb_maplen == 0
+ if (in_osc || ((typebuf.tb_maplen == 0
|| (p_remap && typebuf.tb_noremap[
typebuf.tb_off] == RM_YES))
- && !*timedout)
+ && !*timedout))
keylen = check_termcode(max_mlen + 1, NULL, 0, NULL);
else
keylen = 0;
diff --git a/src/proto/term.pro b/src/proto/term.pro
index c76acabbf..b831bc181 100644
--- a/src/proto/term.pro
+++ b/src/proto/term.pro
@@ -84,6 +84,7 @@ void set_mouse_topline(win_T *wp);
int is_mouse_topline(win_T *wp);
int put_string_in_typebuf(int offset, int slen, char_u *string, int new_slen, char_u *buf, int bufsize, int *buflen);
int decode_modifiers(int n);
+bool in_osc_sequence(void);
int check_termcode(int max_offset, char_u *buf, int bufsize, int *buflen);
void term_get_fg_color(char_u *r, char_u *g, char_u *b);
void term_get_bg_color(char_u *r, char_u *g, char_u *b);
diff --git a/src/term.c b/src/term.c
index 86d570a6d..69130481d 100644
--- a/src/term.c
+++ b/src/term.c
@@ -5900,9 +5900,17 @@ check_for_color_response(char_u *resp, int len)
static oscstate_T osc_state;

/*
- * Handles any OSC sequence and places the result in "v:termosc". Note that the
- * OSC identifier and terminator character(s) will not be placed in the final
- * result. Returns OK on success and FAIL on failure.
+ * Return true if currently receiving an OSC response.
+ */
+ bool
+in_osc_sequence(void)
+{
+ return osc_state.processing;
+}
+
+/*
+ * Handles any OSC sequence and places the result in "v:termosc". Returns OK on
+ * success and FAIL on failure.
*/
static int
handle_osc(char_u *tp, int len, char_u *key_name, int *slen)
diff --git a/src/version.c b/src/version.c
index 8db19f9a4..82487d6f8 100644
--- a/src/version.c
+++ b/src/version.c
@@ -734,6 +734,8 @@ static char *(features[]) =

static int included_patches[] =
{ /* Add new patch number below this line */
+/**/
+ 15,
/**/
14,
/**/
Reply all
Reply to author
Forward
0 new messages