To: vim_dev@googlegroups.com Subject: Patch 9.0.1516 Fcc: outbox From: Bram Moolenaar Mime-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ------------ Patch 9.0.1516 Problem: Cannot use special keys in mapping. Solution: Do allow for special keys in and mappings. (closes #12326) Files: runtime/doc/map.txt, src/errors.h, src/getchar.c, src/proto/getchar.pro, src/ops.c, src/testdir/test_mapping.vim *** ../vim-9.0.1515/runtime/doc/map.txt 2023-02-03 12:28:00.299287568 +0000 --- runtime/doc/map.txt 2023-05-06 16:14:43.522945467 +0100 *************** *** 406,415 **** by in the {rhs} of the mapping definition. |Command-line| mode is never entered. - *E1137* - and commands can have only normal characters and cannot - contain special characters like function keys. - 1.3 MAPPING AND MODES *:map-modes* *mapmode-nvo* *mapmode-n* *mapmode-v* *mapmode-o* --- 408,413 ---- *** ../vim-9.0.1515/src/errors.h 2023-05-05 22:58:30.805061562 +0100 --- src/errors.h 2023-05-06 16:14:43.522945467 +0100 *************** *** 2894,2901 **** #endif EXTERN char e_cmd_mapping_must_end_with_cr_before_second_cmd[] INIT(= N_("E1136: mapping must end with before second ")); ! EXTERN char e_cmd_mapping_must_not_include_str_key[] ! INIT(= N_("E1137: mapping must not include %s key")); #ifdef FEAT_EVAL EXTERN char e_using_bool_as_number[] INIT(= N_("E1138: Using a Bool as a Number")); --- 2894,2900 ---- #endif EXTERN char e_cmd_mapping_must_end_with_cr_before_second_cmd[] INIT(= N_("E1136: mapping must end with before second ")); ! // E1137 unused #ifdef FEAT_EVAL EXTERN char e_using_bool_as_number[] INIT(= N_("E1138: Using a Bool as a Number")); *** ../vim-9.0.1515/src/getchar.c 2023-04-22 22:54:28.049802336 +0100 --- src/getchar.c 2023-05-06 16:20:06.574629402 +0100 *************** *** 603,608 **** --- 603,628 ---- } /* + * Append "s" to the redo buffer, leaving 3-byte special key codes unmodified + * and escaping other K_SPECIAL and CSI bytes. + */ + void + AppendToRedobuffSpec(char_u *s) + { + while (*s != NUL) + { + if (*s == K_SPECIAL && s[1] != NUL && s[2] != NUL) + { + // insert special key literally + add_buff(&redobuff, s, 3L); + s += 3; + } + else + add_char_buff(&redobuff, mb_cptr2char_adv(&s)); + } + } + + /* * Append a character to the redo buffer. * Translates special keys, NUL, CSI, K_SPECIAL and multibyte characters. */ *************** *** 3941,3954 **** if (c1 == K_ESC) c1 = ESC; } - if (c1 == Ctrl_V) - { - // CTRL-V is followed by octal, hex or other characters, reverses - // what AppendToRedobuffLit() does. - ++no_reduce_keys; // don't merge modifyOtherKeys - c1 = get_literal(TRUE); - --no_reduce_keys; - } if (got_int) aborted = TRUE; --- 3961,3966 ---- *************** *** 3962,3980 **** emsg(_(e_cmd_mapping_must_end_with_cr_before_second_cmd)); aborted = TRUE; } ! else if (IS_SPECIAL(c1)) { ! if (c1 == K_SNR) ! ga_concat(&line_ga, (char_u *)""); ! else { ! semsg(e_cmd_mapping_must_not_include_str_key, ! get_special_key_name(c1, cmod)); ! aborted = TRUE; } } - else - ga_append(&line_ga, c1); cmod = 0; } --- 3974,4000 ---- emsg(_(e_cmd_mapping_must_end_with_cr_before_second_cmd)); aborted = TRUE; } ! else if (c1 == K_SNR) { ! ga_concat(&line_ga, (char_u *)""); ! } ! else ! { ! if (cmod != 0) ! { ! ga_append(&line_ga, K_SPECIAL); ! ga_append(&line_ga, KS_MODIFIER); ! ga_append(&line_ga, cmod); ! } ! if (IS_SPECIAL(c1)) { ! ga_append(&line_ga, K_SPECIAL); ! ga_append(&line_ga, K_SECOND(c1)); ! ga_append(&line_ga, K_THIRD(c1)); } + else + ga_append(&line_ga, c1); } cmod = 0; } *** ../vim-9.0.1515/src/proto/getchar.pro 2022-09-05 16:53:17.115566769 +0100 --- src/proto/getchar.pro 2023-05-06 16:17:49.110752774 +0100 *************** *** 11,16 **** --- 11,17 ---- void restoreRedobuff(save_redo_T *save_redo); void AppendToRedobuff(char_u *s); void AppendToRedobuffLit(char_u *str, int len); + void AppendToRedobuffSpec(char_u *s); void AppendCharToRedobuff(int c); void AppendNumberToRedobuff(long n); void stuffReadbuff(char_u *s); *** ../vim-9.0.1515/src/ops.c 2023-03-04 20:47:32.304617857 +0000 --- src/ops.c 2023-05-06 16:14:43.522945467 +0100 *************** *** 3701,3707 **** ResetRedobuff(); else { ! AppendToRedobuffLit(repeat_cmdline, -1); AppendToRedobuff(NL_STR); VIM_CLEAR(repeat_cmdline); } --- 3701,3707 ---- ResetRedobuff(); else { ! AppendToRedobuffSpec(repeat_cmdline); AppendToRedobuff(NL_STR); VIM_CLEAR(repeat_cmdline); } *** ../vim-9.0.1515/src/testdir/test_mapping.vim 2023-04-16 17:17:33.052497158 +0100 --- src/testdir/test_mapping.vim 2023-05-06 16:14:43.526945461 +0100 *************** *** 1001,1010 **** call assert_fails('call feedkeys("\", "xt")', 'E1136:') call assert_equal(0, x) - noremap let x = 2 - call assert_fails('call feedkeys("\", "xt")', 'E1137:') - call assert_equal(0, x) - noremap let x = 3 call assert_fails('call feedkeys("\", "xt!")', 'E1255:') call assert_equal(0, x) --- 1001,1006 ---- *************** *** 1104,1114 **** unmap unmap! %bw! - - " command line ending in "0" is handled without errors - onoremap ix eval 0 - call feedkeys('dix.', 'xt') - ounmap ix endfunc " text object enters visual mode --- 1100,1105 ---- *************** *** 1495,1500 **** --- 1486,1509 ---- call delete('Xcmdtext') delfunc SelectDash ounmap i- + + new + call setline(1, 'aaa bbb ccc ddd') + + " command can contain special keys + onoremap ix let g:foo ..= '…'normal! + let g:foo = '' + call feedkeys('0dix.', 'xt') + call assert_equal('……', g:foo) + call assert_equal('ccc ddd', getline(1)) + unlet g:foo + + " command line ending in "0" is handled without errors + onoremap ix eval 0 + call feedkeys('dix.', 'xt') + + ounmap ix + bwipe! endfunc func Test_map_script_cmd_restore() *** ../vim-9.0.1515/src/version.c 2023-05-06 14:08:10.143045044 +0100 --- src/version.c 2023-05-06 16:16:10.290851058 +0100 *************** *** 697,698 **** --- 697,700 ---- { /* Add new patch number below this line */ + /**/ + 1516, /**/ -- A)bort, R)etry, D)o it right this time /// 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 ///