From: AstroSnail Date: Sun, 22 Mar 2026 20:21:50 +0000 (+0000) Subject: patch 9.2.0229: keypad keys may overwrite keycode for another key X-Git-Tag: v9.2.0229^0 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=1fe0d1e8f5d50061c7dc8a867fc010abdd0af2e9;p=thirdparty%2Fvim.git patch 9.2.0229: keypad keys may overwrite keycode for another key Problem: In XTerm, with 'xtermcodes' enabled (default), vim will request keypad keys after editing pad keys, and will remove the latter when they're duplicates of the former. Solution: When a termcode reply is a keypad key and it would replace a different key, skip it. fixes: #19182 (case 2) related: #19643 closes: #19644 Signed-off-by: AstroSnail Signed-off-by: Christian Brabandt --- diff --git a/src/term.c b/src/term.c index 853ff861d9..64eff178f6 100644 --- a/src/term.c +++ b/src/term.c @@ -7594,6 +7594,14 @@ got_code_from_term(char_u *code, int len) # ifdef FEAT_EVAL ch_log(NULL, "got_code_from_term(): Entry %c%c did not change", name[0], name[1]); +# endif + } + else if (i >= 0 && name[0] == 'K' && VIM_ISDIGIT(name[1])) + { + // Would replace existing entry with keypad key - skip. +# ifdef FEAT_EVAL + ch_log(NULL, "got_code_from_term(): Skipping entry %c%c in favor of %c%c with matching keys %s", + name[0], name[1], termcodes[i].name[0], termcodes[i].name[1], str); # endif } else diff --git a/src/testdir/test_termcodes.vim b/src/testdir/test_termcodes.vim index c40e41a6e4..edf64d2830 100644 --- a/src/testdir/test_termcodes.vim +++ b/src/testdir/test_termcodes.vim @@ -2815,6 +2815,60 @@ func Test_raw_codes_in_mappings() unmap X endfunc +func Test_avoid_keypad_if_ambiguous() + let save_kh = exists('&t_kh') ? &t_kh : '' + let save_K1 = exists('&t_K1') ? &t_K1 : '' + let save_at7 = exists('&t_@7') ? &t_@7 : '' + let save_K4 = exists('&t_K4') ? &t_K4 : '' + let save_kP = exists('&t_kP') ? &t_kP : '' + let save_K3 = exists('&t_K3') ? &t_K3 : '' + let save_kN = exists('&t_kN') ? &t_kN : '' + let save_K5 = exists('&t_K5') ? &t_K5 : '' + + let &t_kh = "\[@;*H" + let &t_K1 = "\[1;*~" + let &t_@7 = "\[@;*F" + let &t_K4 = "\[4;*~" + let &t_kP = "\[5;*~" + let &t_K3 = "\Oy" + let &t_kN = "\[6;*~" + let &t_K5 = "\Os" + + call feedkeys("\P1+r6b68=1B4F48\\\", 't') " kh OH + call feedkeys("\P1+r4b31=1B4F48\\\", 't') " K1 OH + call feedkeys("\P1+r4037=1B4F46\\\", 't') " @7 OF + call feedkeys("\P1+r4b34=1B4F46\\\", 't') " K4 OF + call feedkeys("\P1+r6b50=1B5B357E\\\", 't') " kP [5~ + call feedkeys("\P1+r4b33=1B5B357E\\\", 't') " K3 [5~ + call feedkeys("\P1+r6b4e=1B5B367E\\\", 't') " kN [6~ + call feedkeys("\P1+r4b35=1B5B367E\\\", 'tx') " K5 [6~ + + let test_kh = exists('&t_kh') ? &t_kh : '' + let test_K1 = exists('&t_K1') ? &t_K1 : '' + let test_at7 = exists('&t_@7') ? &t_@7 : '' + let test_K4 = exists('&t_K4') ? &t_K4 : '' + let test_kP = exists('&t_kP') ? &t_kP : '' + let test_K3 = exists('&t_K3') ? &t_K3 : '' + let test_kN = exists('&t_kN') ? &t_kN : '' + let test_K5 = exists('&t_K5') ? &t_K5 : '' + + call assert_equal( + \ ["\OH", "\[1;*~", "\OF", "\[4;*~", + \ "\[5;*~", "\Oy", "\[6;*~", "\Os"], + \ [test_kh, test_K1, test_at7, test_K4, + \ test_kP, test_K3, test_kN, test_K5]) + + bwipe! + let &t_kh = save_kh + let &t_K1 = save_K1 + let &t_@7 = save_at7 + let &t_K4 = save_K4 + let &t_kP = save_kP + let &t_K3 = save_K3 + let &t_kN = save_kN + let &t_K5 = save_K5 +endfunc + func Test_terminal_builtin_without_gui() CheckNotMSWindows diff --git a/src/version.c b/src/version.c index 0c801dd2ed..fd702323c1 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 */ +/**/ + 229, /**/ 228, /**/