To: vim_dev@googlegroups.com Subject: Patch 8.2.2246 Fcc: outbox From: Bram Moolenaar Mime-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ------------ Patch 8.2.2246 Problem: Cursor keys not recognized at the hit-Enter prompt after executing an external command. Solution: Change the codes for the extra cursor keys. (closes #7562) Tune the delays to avoid test flakyness. Files: runtime/doc/term.txt, src/term.c, src/testdir/test_terminal3.vim *** ../vim-8.2.2245/runtime/doc/term.txt 2020-05-31 16:41:04.646603340 +0200 --- runtime/doc/term.txt 2020-12-29 20:30:29.501741164 +0100 *************** *** 216,221 **** --- 217,226 ---- Another speciality about these codes is that they are not overwritten by another code. That is to avoid that the codes obtained from xterm directly |t_RV| overwrite them. + + Another special value is a termcap entry ending in "@;*X". This is for cursor + keys, which either use "CSI X" or "CSI 1 ; modifier X". Thus the "@" + stands for either "1" if a modifier follows, or nothing. *xterm-scroll-region* The default termcap entry for xterm on Sun and other platforms does not contain the entry for scroll regions. Add ":cs=\E[%i%d;%dr:" to the xterm *** ../vim-8.2.2245/src/term.c 2020-12-18 19:49:52.345571854 +0100 --- src/term.c 2020-12-29 20:36:56.040562730 +0100 *************** *** 914,923 **** {K_RIGHT, IF_EB("\033O*C", ESC_STR "O*C")}, {K_LEFT, IF_EB("\033O*D", ESC_STR "O*D")}, // An extra set of cursor keys for vt100 mode ! {K_XUP, IF_EB("\033[1;*A", ESC_STR "[1;*A")}, ! {K_XDOWN, IF_EB("\033[1;*B", ESC_STR "[1;*B")}, ! {K_XRIGHT, IF_EB("\033[1;*C", ESC_STR "[1;*C")}, ! {K_XLEFT, IF_EB("\033[1;*D", ESC_STR "[1;*D")}, // An extra set of function keys for vt100 mode {K_XF1, IF_EB("\033O*P", ESC_STR "O*P")}, {K_XF2, IF_EB("\033O*Q", ESC_STR "O*Q")}, --- 914,923 ---- {K_RIGHT, IF_EB("\033O*C", ESC_STR "O*C")}, {K_LEFT, IF_EB("\033O*D", ESC_STR "O*D")}, // An extra set of cursor keys for vt100 mode ! {K_XUP, IF_EB("\033[@;*A", ESC_STR "[@;*A")}, ! {K_XDOWN, IF_EB("\033[@;*B", ESC_STR "[@;*B")}, ! {K_XRIGHT, IF_EB("\033[@;*C", ESC_STR "[@;*C")}, ! {K_XLEFT, IF_EB("\033[@;*D", ESC_STR "[@;*D")}, // An extra set of function keys for vt100 mode {K_XF1, IF_EB("\033O*P", ESC_STR "O*P")}, {K_XF2, IF_EB("\033O*Q", ESC_STR "O*Q")}, *************** *** 4230,4236 **** --- 4230,4241 ---- termcodes[i].modlen = 0; j = termcode_star(s, len); if (j > 0) + { termcodes[i].modlen = len - 1 - j; + // For "CSI[@;X" the "@" is not included in "modlen". + if (termcodes[i].code[termcodes[i].modlen - 1] == '@') + --termcodes[i].modlen; + } ++tc_len; } *************** *** 4242,4248 **** static int termcode_star(char_u *code, int len) { ! // Shortest is *X. With ; shortest is 1;*X if (len >= 3 && code[len - 2] == '*') { if (len >= 5 && code[len - 3] == ';') --- 4247,4253 ---- static int termcode_star(char_u *code, int len) { ! // Shortest is *X. With ; shortest is @;*X if (len >= 3 && code[len - 2] == '*') { if (len >= 5 && code[len - 3] == ';') *************** *** 5329,5343 **** --- 5334,5352 ---- /* * Check for code with modifier, like xterm uses: * [123;*X (modslen == slen - 3) + * [@;*X (matches [X and [1;9X ) * Also O*X and *X (modslen == slen - 2). * When there is a modifier the * matches a number. * When there is no modifier the ;* or * is omitted. */ if (termcodes[idx].modlen > 0) { + int at_code; + modslen = termcodes[idx].modlen; if (cpo_koffset && offset && len < modslen) continue; + at_code = termcodes[idx].code[modslen] == '@'; if (STRNCMP(termcodes[idx].code, tp, (size_t)(modslen > len ? len : modslen)) == 0) { *************** *** 5347,5355 **** return -1; // need to get more chars if (tp[modslen] == termcodes[idx].code[slen - 1]) ! slen = modslen + 1; // no modifiers else if (tp[modslen] != ';' && modslen == slen - 3) ! continue; // no match else { // Skip over the digits, the final char must --- 5356,5369 ---- return -1; // need to get more chars if (tp[modslen] == termcodes[idx].code[slen - 1]) ! // no modifiers ! slen = modslen + 1; else if (tp[modslen] != ';' && modslen == slen - 3) ! // no match for "code;*X" with "code;" ! continue; ! else if (at_code && tp[modslen] != '1') ! // no match for "[@" with "[1" ! continue; else { // Skip over the digits, the final char must *** ../vim-8.2.2245/src/testdir/test_terminal3.vim 2020-12-18 19:49:52.349571840 +0100 --- src/testdir/test_terminal3.vim 2020-12-29 20:49:51.304428037 +0100 *************** *** 101,107 **** let buf = RunVimInTerminal('-S XtermPopup', #{rows: 15}) call TermWait(buf, 100) call term_sendkeys(buf, ":call OpenTerm(0)\") ! call TermWait(buf, 100) call term_sendkeys(buf, ":\") call TermWait(buf, 100) call term_sendkeys(buf, "\:echo getwinvar(g:winid, \"&buftype\") win_gettype(g:winid)\") --- 101,107 ---- let buf = RunVimInTerminal('-S XtermPopup', #{rows: 15}) call TermWait(buf, 100) call term_sendkeys(buf, ":call OpenTerm(0)\") ! call TermWait(buf, 500) call term_sendkeys(buf, ":\") call TermWait(buf, 100) call term_sendkeys(buf, "\:echo getwinvar(g:winid, \"&buftype\") win_gettype(g:winid)\") *************** *** 111,117 **** call VerifyScreenDump(buf, 'Test_terminal_popup_2', {}) call term_sendkeys(buf, ":call OpenTerm(1)\") ! call TermWait(buf, 150) call term_sendkeys(buf, ":set hlsearch\") call TermWait(buf, 100) call term_sendkeys(buf, "/edit\") --- 111,117 ---- call VerifyScreenDump(buf, 'Test_terminal_popup_2', {}) call term_sendkeys(buf, ":call OpenTerm(1)\") ! call TermWait(buf, 500) call term_sendkeys(buf, ":set hlsearch\") call TermWait(buf, 100) call term_sendkeys(buf, "/edit\") *************** *** 138,144 **** call TermWait(buf, 50) call term_sendkeys(buf, ":q\") ! call TermWait(buf, 150) " wait for terminal to vanish call StopVimInTerminal(buf) call delete('Xtext') --- 138,144 ---- call TermWait(buf, 50) call term_sendkeys(buf, ":q\") ! call TermWait(buf, 250) " wait for terminal to vanish call StopVimInTerminal(buf) call delete('Xtext') *************** *** 309,314 **** --- 309,315 ---- let buf = RunVimInTerminal('', {}) call term_sendkeys(buf, ":set nocompatible\") + call term_sendkeys(buf, ":set timeoutlen=20\") let keys = ["\", "\", "\", "\", "\", "\", "\", \ "\", "\", "\", "\", "\", "\", *************** *** 325,331 **** call term_sendkeys(buf, "i") for i in range(len(keys)) call term_sendkeys(buf, "\\" .. keys[i]) ! call WaitForAssert({-> assert_equal(output[i], term_getline(buf, 1))}) endfor let keypad_keys = ["\", "\", "\", "\", "\", "\", --- 326,332 ---- call term_sendkeys(buf, "i") for i in range(len(keys)) call term_sendkeys(buf, "\\" .. keys[i]) ! call WaitForAssert({-> assert_equal(output[i], term_getline(buf, 1))}, 200) endfor let keypad_keys = ["\", "\", "\", "\", "\", "\", *************** *** 340,346 **** continue endif call term_sendkeys(buf, "\" .. keypad_keys[i]) ! call WaitForAssert({-> assert_equal(keypad_output[i], term_getline(buf, 1))}) endfor call feedkeys("\\\one\.two", 'xt') --- 341,347 ---- continue endif call term_sendkeys(buf, "\" .. keypad_keys[i]) ! call WaitForAssert({-> assert_equal(keypad_output[i], term_getline(buf, 1))}, 100) endfor call feedkeys("\\\one\.two", 'xt') *** ../vim-8.2.2245/src/version.c 2020-12-29 20:25:16.470694750 +0100 --- src/version.c 2020-12-29 20:52:30.151667127 +0100 *************** *** 752,753 **** --- 752,755 ---- { /* Add new patch number below this line */ + /**/ + 2246, /**/ -- Don't believe everything you hear or anything you say. /// Bram Moolenaar -- Bram@Moolenaar.net -- http://www.Moolenaar.net \\\ /// sponsor Vim, vote for features -- http://www.Vim.org/sponsor/ \\\ \\\ an exciting new programming language -- http://www.Zimbu.org /// \\\ help me help AIDS victims -- http://ICCF-Holland.org ///