To: vim_dev@googlegroups.com Subject: Patch 9.0.0748 Fcc: outbox From: Bram Moolenaar Mime-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ------------ Patch 9.0.0748 Problem: Kitty may send key without modifiers with CSI u code. Solution: Handle CSI u code without modifiers. (Trygve Aaberge, closes #11364) Files: src/term.c, src/testdir/test_termcodes.vim *** ../vim-9.0.0747/src/term.c 2022-10-04 13:17:27.496307898 +0100 --- src/term.c 2022-10-14 11:55:05.731706603 +0100 *************** *** 4807,4812 **** --- 4807,4834 ---- } /* + * Add "key" to "buf" and return the number of bytes used. + * Handles special keys and multi-byte characters. + */ + static int + add_key_to_buf(int key, char_u *buf) + { + int idx = 0; + + if (IS_SPECIAL(key)) + { + buf[idx++] = K_SPECIAL; + buf[idx++] = KEY2TERMCAP0(key); + buf[idx++] = KEY2TERMCAP1(key); + } + else if (has_mbyte) + idx += (*mb_char2bytes)(key, buf + idx); + else + buf[idx++] = key; + return idx; + } + + /* * Handle a sequence with key and modifier, one of: * {lead}27;{modifier};{key}~ * {lead}{key};{modifier}u *************** *** 4824,4830 **** { int key; int modifiers; - int new_slen; char_u string[MAX_KEY_CODE_LEN + 1]; seenModifyOtherKeys = TRUE; --- 4846,4851 ---- *************** *** 4842,4859 **** modifiers = may_remove_shift_modifier(modifiers, key); // insert modifiers with KS_MODIFIER ! new_slen = modifiers2keycode(modifiers, &key, string); ! if (IS_SPECIAL(key)) ! { ! string[new_slen++] = K_SPECIAL; ! string[new_slen++] = KEY2TERMCAP0(key); ! string[new_slen++] = KEY2TERMCAP1(key); ! } ! else if (has_mbyte) ! new_slen += (*mb_char2bytes)(key, string + new_slen); ! else ! string[new_slen++] = key; if (put_string_in_typebuf(offset, csi_len, string, new_slen, buf, bufsize, buflen) == FAIL) --- 4863,4895 ---- modifiers = may_remove_shift_modifier(modifiers, key); // insert modifiers with KS_MODIFIER ! int new_slen = modifiers2keycode(modifiers, &key, string); ! // add the bytes for the key ! new_slen += add_key_to_buf(key, string + new_slen); ! ! if (put_string_in_typebuf(offset, csi_len, string, new_slen, ! buf, bufsize, buflen) == FAIL) ! return -1; ! return new_slen - csi_len + offset; ! } ! ! /* ! * Handle a sequence with key without a modifier: ! * {lead}{key}u ! * Returns the difference in length. ! */ ! static int ! handle_key_without_modifier( ! int *arg, ! int csi_len, ! int offset, ! char_u *buf, ! int bufsize, ! int *buflen) ! { ! char_u string[MAX_KEY_CODE_LEN + 1]; ! int new_slen = add_key_to_buf(arg[0], string); if (put_string_in_typebuf(offset, csi_len, string, new_slen, buf, bufsize, buflen) == FAIL) *************** *** 5016,5021 **** --- 5052,5065 ---- csi_len, offset, buf, bufsize, buflen); } + // Key without modifier (bad Kitty may send this): + // {lead}{key}u + else if (argc == 1 && trail == 'u') + { + return len + handle_key_without_modifier(arg, + csi_len, offset, buf, bufsize, buflen); + } + // else: Unknown CSI sequence. We could drop it, but then the // user can't create a map for it. return 0; *** ../vim-9.0.0747/src/testdir/test_termcodes.vim 2022-10-13 13:17:37.519640382 +0100 --- src/testdir/test_termcodes.vim 2022-10-14 11:44:16.896463844 +0100 *************** *** 1992,1997 **** --- 1992,2002 ---- return "\[" .. key .. ';' .. mod .. 'u' endfunc + func GetEscCodeCSIuWithoutModifier(key) + let key = printf("%d", char2nr(a:key)) + return "\[" .. key .. 'u' + endfunc + " This checks the CSI sequences when in modifyOtherKeys mode. " The mode doesn't need to be enabled, the codes are always detected. func RunTest_modifyOtherKeys(func) *************** *** 2080,2085 **** --- 2085,2103 ---- set timeoutlen& endfunc + func Test_CSIu_keys_without_modifiers() + " Escape sent as `CSI 27 u` should act as normal escape and not undo + call setline(1, 'a') + call feedkeys('a' .. GetEscCodeCSIuWithoutModifier("\e"), 'Lx!') + call assert_equal('n', mode()) + call assert_equal('a', getline(1)) + + " Tab sent as `CSI 9 u` should work + call setline(1, '') + call feedkeys('a' .. GetEscCodeCSIuWithoutModifier("\t") .. "\", 'Lx!') + call assert_equal("\t", getline(1)) + endfunc + " Check that when DEC mouse codes are recognized a special key is handled. func Test_ignore_dec_mouse() silent !infocmp gnome >/dev/null 2>&1 *** ../vim-9.0.0747/src/version.c 2022-10-13 22:12:07.172673790 +0100 --- src/version.c 2022-10-14 12:07:34.676926417 +0100 *************** *** 697,698 **** --- 697,700 ---- { /* Add new patch number below this line */ + /**/ + 748, /**/ -- The war between Emacs and Vi is over. Vi has won with 3 to 1. http://m.linuxjournal.com/files/linuxjournal.com/linuxjournal/articles/030/3044/3044s1.html /// Bram Moolenaar -- Bram@Moolenaar.net -- http://www.Moolenaar.net \\\ /// \\\ \\\ sponsor Vim, vote for features -- http://www.Vim.org/sponsor/ /// \\\ help me help AIDS victims -- http://ICCF-Holland.org ///