'cpoptions': remove "<" flag; ignore <special>

Closes #6937 "nvim_get_keymap output is unreliable"
This commit is contained in:
Justin M. Keyes
2017-07-02 13:21:38 +02:00
parent 78c5201234
commit 0ea7e45bc1
17 changed files with 58 additions and 88 deletions

View File

@@ -490,9 +490,6 @@ expression register: >
:amenu Insert.foobar "='foobar'<CR>P :amenu Insert.foobar "='foobar'<CR>P
Note that the '<' and 'k' flags in 'cpoptions' also apply here (when
included they make the <> form and raw key codes not being recognized).
Note that <Esc> in Cmdline mode executes the command, like in a mapping. This Note that <Esc> in Cmdline mode executes the command, like in a mapping. This
is Vi compatible. Use CTRL-C to quit Cmdline mode. is Vi compatible. Use CTRL-C to quit Cmdline mode.

View File

@@ -570,9 +570,9 @@ Since the '|' character is used to separate a map command from the next
command, you will have to do something special to include a '|' in {rhs}. command, you will have to do something special to include a '|' in {rhs}.
There are three methods: There are three methods:
use works when example ~ use works when example ~
<Bar> '<' is not in 'cpoptions' :map _l :!ls <Bar> more^M <Bar> always :map _l :!ls <Bar> more^M
\| 'b' is not in 'cpoptions' :map _l :!ls \| more^M \| 'b' is not in 'cpoptions' :map _l :!ls \| more^M
^V| always, in Vim and Vi :map _l :!ls ^V| more^M ^V| always :map _l :!ls ^V| more^M
(here ^V stands for CTRL-V; to get one CTRL-V you have to type it twice; you (here ^V stands for CTRL-V; to get one CTRL-V you have to type it twice; you
cannot use the <> notation "<C-V>" here). cannot use the <> notation "<C-V>" here).
@@ -627,8 +627,7 @@ out about, ^D is CTRL-D).
1.8 EXAMPLES *map-examples* 1.8 EXAMPLES *map-examples*
A few examples (given as you type them, for "<CR>" you type four characters; A few examples (as you type them: for "<CR>" you type four characters). >
the '<' flag must not be present in 'cpoptions' for this to work). >
:map <F3> o#include :map <F3> o#include
:map <M-g> /foo<CR>cwbar<Esc> :map <M-g> /foo<CR>cwbar<Esc>
@@ -880,7 +879,6 @@ character is mostly ignored otherwise.
It is possible to move the cursor after an abbreviation: > It is possible to move the cursor after an abbreviation: >
:iab if if ()<Left> :iab if if ()<Left>
This does not work if 'cpoptions' includes the '<' flag. |<>|
You can even do more complicated things. For example, to consume the space You can even do more complicated things. For example, to consume the space
typed after an abbreviation: > typed after an abbreviation: >

View File

@@ -1568,7 +1568,6 @@ A jump table for the options with a short description can be found at |Q_op|.
results in X being mapped to: results in X being mapped to:
'B' included: "\^[" (^[ is a real <Esc>) 'B' included: "\^[" (^[ is a real <Esc>)
'B' excluded: "<Esc>" (5 characters) 'B' excluded: "<Esc>" (5 characters)
('<' excluded in both cases)
*cpo-c* *cpo-c*
c Searching continues at the end of any match at the c Searching continues at the end of any match at the
cursor position, but not further than the start of the cursor position, but not further than the start of the
@@ -1751,14 +1750,6 @@ A jump table for the options with a short description can be found at |Q_op|.
+ When included, a ":write file" command will reset the + When included, a ":write file" command will reset the
'modified' flag of the buffer, even though the buffer 'modified' flag of the buffer, even though the buffer
itself may still be different from its file. itself may still be different from its file.
*cpo-<*
< Disable the recognition of special key codes in |<>|
form in mappings, abbreviations, and the "to" part of
menu commands. For example, the command
":map X <Tab>" results in X being mapped to:
'<' included: "<Tab>" (5 characters)
'<' excluded: "^I" (^I is a real <Tab>)
Also see the 'k' flag above.
*cpo->* *cpo->*
> When appending to a register, put a line break before > When appending to a register, put a line break before
the appended text. the appended text.

View File

@@ -282,9 +282,7 @@ For Emacs-style editing on the command-line: >
:cnoremap <Esc><C-B> <S-Left> :cnoremap <Esc><C-B> <S-Left>
" forward one word " forward one word
:cnoremap <Esc><C-F> <S-Right> :cnoremap <Esc><C-F> <S-Right>
<
NOTE: This requires that the '<' flag is excluded from 'cpoptions'. |<>|
*format-bullet-list* *format-bullet-list*
This mapping will format any bullet list. It requires that there is an empty This mapping will format any bullet list. It requires that there is an empty
line above and below each list entry. The expression commands are used to line above and below each list entry. The expression commands are used to
@@ -300,8 +298,7 @@ be able to give comments to the parts of the mapping. >
:execute m |" define the mapping :execute m |" define the mapping
(<> notation |<>|. Note that this is all typed literally. ^W is "^" "W", not (<> notation |<>|. Note that this is all typed literally. ^W is "^" "W", not
CTRL-W. You can copy/paste this into Vim if '<' is not included in CTRL-W.)
'cpoptions'.)
Note that the last comment starts with |", because the ":execute" command Note that the last comment starts with |", because the ":execute" command
doesn't accept a comment directly. doesn't accept a comment directly.

View File

@@ -332,7 +332,7 @@ Test functions:
Other options: Other options:
'antialias' 'antialias'
'cpoptions' (g j k H w * - and all POSIX flags were removed) 'cpoptions' (g j k H w < * - and all POSIX flags were removed)
'encoding' ("utf-8" is always used) 'encoding' ("utf-8" is always used)
'esckeys' 'esckeys'
'guioptions' "t" flag was removed 'guioptions' "t" flag was removed

View File

@@ -271,7 +271,7 @@ mode. For example, if you would like the "/" command not to extend the Visual
area, but instead take the highlighted text and search for that: > area, but instead take the highlighted text and search for that: >
:vmap / y/<C-R>"<CR> :vmap / y/<C-R>"<CR>
(In the <> notation |<>|, when typing it you should type it literally; you (In the <> notation |<>|, when typing it you should type it literally; you
need to remove the 'B' and '<' flags from 'cpoptions'.) need to remove the 'B' flag from 'cpoptions'.)
If you want to give a register name using the """ command, do this just before If you want to give a register name using the """ command, do this just before
typing the operator character: "v{move-around}"xd". typing the operator character: "v{move-around}"xd".
@@ -375,7 +375,7 @@ Here is an example, to replace the selected text with the output of "date": >
:vmap _a <Esc>`>a<CR><Esc>`<i<CR><Esc>!!date<CR>kJJ :vmap _a <Esc>`>a<CR><Esc>`<i<CR><Esc>!!date<CR>kJJ
(In the <> notation |<>|, when typing it you should type it literally; you (In the <> notation |<>|, when typing it you should type it literally; you
need to remove the 'B' and '<' flags from 'cpoptions') need to remove the 'B' flag from 'cpoptions')
What this does is: What this does is:
<Esc> stop Visual mode <Esc> stop Visual mode
@@ -392,7 +392,7 @@ selected text: >
:vmap X y/<C-R>"<CR> :vmap X y/<C-R>"<CR>
(In the <> notation |<>|, when typing it you should type it literally; you (In the <> notation |<>|, when typing it you should type it literally; you
need to remove the 'B' and '<' flags from 'cpoptions') need to remove the 'B' flag from 'cpoptions')
Note that special characters (like '.' and '*') will cause problems. Note that special characters (like '.' and '*') will cause problems.

View File

@@ -136,9 +136,13 @@ Integer nvim_input(String keys)
return (Integer)input_enqueue(keys); return (Integer)input_enqueue(keys);
} }
/// Replaces terminal codes and key codes (<CR>, <Esc>, ...) in a string with /// Replaces terminal codes and |keycodes| (<CR>, <Esc>, ...) in a string with
/// the internal representation. /// the internal representation.
/// ///
/// @param str String to be converted.
/// @param from_part Legacy Vim parameter. Usually true.
/// @param do_lt Also translate <lt>. Does nothing if `special` is false.
/// @param special Replace |keycodes|, e.g. <CR> becomes a "\n" char.
/// @see replace_termcodes /// @see replace_termcodes
/// @see cpoptions /// @see cpoptions
String nvim_replace_termcodes(String str, Boolean from_part, Boolean do_lt, String nvim_replace_termcodes(String str, Boolean from_part, Boolean do_lt,
@@ -151,11 +155,6 @@ String nvim_replace_termcodes(String str, Boolean from_part, Boolean do_lt,
} }
char *ptr = NULL; char *ptr = NULL;
// Set 'cpoptions' the way we want it.
// FLAG_CPO_BSLASH set - backslashes are *not* treated specially
// FLAG_CPO_SPECI unset - <Key> sequences *are* interpreted
// The third from end parameter of replace_termcodes() is true so that the
// <lt> sequence is recognised - needed for a real backslash.
replace_termcodes((char_u *)str.data, str.size, (char_u **)&ptr, replace_termcodes((char_u *)str.data, str.size, (char_u **)&ptr,
from_part, do_lt, special, CPO_TO_CPO_FLAGS); from_part, do_lt, special, CPO_TO_CPO_FLAGS);
return cstr_as_string(ptr); return cstr_as_string(ptr);

View File

@@ -12111,7 +12111,7 @@ static void get_maparg(typval_T *argvars, typval_T *rettv, int exact)
mode = get_map_mode((char_u **)&which, 0); mode = get_map_mode((char_u **)&which, 0);
keys = replace_termcodes(keys, STRLEN(keys), &keys_buf, true, true, false, keys = replace_termcodes(keys, STRLEN(keys), &keys_buf, true, true, true,
CPO_TO_CPO_FLAGS); CPO_TO_CPO_FLAGS);
rhs = check_map(keys, mode, exact, false, abbr, &mp, &buffer_local); rhs = check_map(keys, mode, exact, false, abbr, &mp, &buffer_local);
xfree(keys_buf); xfree(keys_buf);

View File

@@ -4747,7 +4747,7 @@ static int uc_add_command(char_u *name, size_t name_len, char_u *rep,
char_u *rep_buf = NULL; char_u *rep_buf = NULL;
garray_T *gap; garray_T *gap;
replace_termcodes(rep, STRLEN(rep), &rep_buf, false, false, false, replace_termcodes(rep, STRLEN(rep), &rep_buf, false, false, true,
CPO_TO_CPO_FLAGS); CPO_TO_CPO_FLAGS);
if (rep_buf == NULL) { if (rep_buf == NULL) {
/* Can't replace termcodes - try using the string as is */ /* Can't replace termcodes - try using the string as is */

View File

@@ -2537,7 +2537,6 @@ do_map (
bool unique = false; bool unique = false;
bool nowait = false; bool nowait = false;
bool silent = false; bool silent = false;
bool special = false;
bool expr = false; bool expr = false;
int noremap; int noremap;
char_u *orig_rhs; char_u *orig_rhs;
@@ -2583,12 +2582,9 @@ do_map (
continue; continue;
} }
/* // Ignore obsolete "<special>" modifier.
* Check for "<special>": accept special keys in <>
*/
if (STRNCMP(keys, "<special>", 9) == 0) { if (STRNCMP(keys, "<special>", 9) == 0) {
keys = skipwhite(keys + 9); keys = skipwhite(keys + 9);
special = true;
continue; continue;
} }
@@ -2657,7 +2653,7 @@ do_map (
// needs to be freed later (*keys_buf and *arg_buf). // needs to be freed later (*keys_buf and *arg_buf).
// replace_termcodes() also removes CTRL-Vs and sometimes backslashes. // replace_termcodes() also removes CTRL-Vs and sometimes backslashes.
if (haskey) { if (haskey) {
keys = replace_termcodes(keys, STRLEN(keys), &keys_buf, true, true, special, keys = replace_termcodes(keys, STRLEN(keys), &keys_buf, true, true, true,
CPO_TO_CPO_FLAGS); CPO_TO_CPO_FLAGS);
} }
orig_rhs = rhs; orig_rhs = rhs;
@@ -2665,7 +2661,7 @@ do_map (
if (STRICMP(rhs, "<nop>") == 0) { // "<Nop>" means nothing if (STRICMP(rhs, "<nop>") == 0) { // "<Nop>" means nothing
rhs = (char_u *)""; rhs = (char_u *)"";
} else { } else {
rhs = replace_termcodes(rhs, STRLEN(rhs), &arg_buf, false, true, special, rhs = replace_termcodes(rhs, STRLEN(rhs), &arg_buf, false, true, true,
CPO_TO_CPO_FLAGS); CPO_TO_CPO_FLAGS);
} }
} }
@@ -3245,7 +3241,7 @@ bool map_to_exists(const char *const str, const char *const modechars,
char_u *buf; char_u *buf;
char_u *const rhs = replace_termcodes((const char_u *)str, strlen(str), &buf, char_u *const rhs = replace_termcodes((const char_u *)str, strlen(str), &buf,
false, true, false, false, true, true,
CPO_TO_CPO_FLAGS); CPO_TO_CPO_FLAGS);
#define MAPMODE(mode, modechars, chr, modeflags) \ #define MAPMODE(mode, modechars, chr, modeflags) \
@@ -4158,8 +4154,7 @@ void add_map(char_u *map, int mode)
} }
// Translate an internal mapping/abbreviation representation into the // Translate an internal mapping/abbreviation representation into the
// corresponding external one recognized by :map/:abbrev commands; // corresponding external one recognized by :map/:abbrev commands.
// respects the current B/k/< settings of 'cpoption'.
// //
// This function is called when expanding mappings/abbreviations on the // This function is called when expanding mappings/abbreviations on the
// command-line, and for building the "Ambiguous mapping..." error message. // command-line, and for building the "Ambiguous mapping..." error message.
@@ -4179,7 +4174,6 @@ static char_u * translate_mapping (
ga_init(&ga, 1, 40); ga_init(&ga, 1, 40);
bool cpo_bslash = !(cpo_flags&FLAG_CPO_BSLASH); bool cpo_bslash = !(cpo_flags&FLAG_CPO_BSLASH);
bool cpo_special = !(cpo_flags&FLAG_CPO_SPECI);
for (; *str; ++str) { for (; *str; ++str) {
int c = *str; int c = *str;
@@ -4192,7 +4186,7 @@ static char_u * translate_mapping (
} }
if (c == K_SPECIAL && str[1] != NUL && str[2] != NUL) { if (c == K_SPECIAL && str[1] != NUL && str[2] != NUL) {
if (expmap && cpo_special) { if (expmap) {
ga_clear(&ga); ga_clear(&ga);
return NULL; return NULL;
} }
@@ -4204,7 +4198,7 @@ static char_u * translate_mapping (
str += 2; str += 2;
} }
if (IS_SPECIAL(c) || modifiers) { /* special key */ if (IS_SPECIAL(c) || modifiers) { /* special key */
if (expmap && cpo_special) { if (expmap) {
ga_clear(&ga); ga_clear(&ga);
return NULL; return NULL;
} }
@@ -4214,7 +4208,7 @@ static char_u * translate_mapping (
} }
if (c == ' ' || c == '\t' || c == Ctrl_J || c == Ctrl_V if (c == ' ' || c == '\t' || c == Ctrl_J || c == Ctrl_V
|| (c == '<' && !cpo_special) || (c == '\\' && !cpo_bslash)) { || (c == '\\' && !cpo_bslash)) {
ga_append(&ga, cpo_bslash ? Ctrl_V : '\\'); ga_append(&ga, cpo_bslash ? Ctrl_V : '\\');
} }

View File

@@ -756,9 +756,9 @@ int get_mouse_button(int code, bool *is_click, bool *is_drag)
/// Replace any terminal code strings with the equivalent internal /// Replace any terminal code strings with the equivalent internal
/// representation /// representation
/// ///
/// This is used for the "from" and "to" part of a mapping, and the "to" part of /// Used for the "from" and "to" part of a mapping, and the "to" part of
/// a menu command. Any strings like "<C-UP>" are also replaced, unless /// a menu command. Any strings like "<C-UP>" are also replaced, unless
/// 'cpoptions' contains '<'. K_SPECIAL by itself is replaced by K_SPECIAL /// `special` is false. K_SPECIAL by itself is replaced by K_SPECIAL
/// KS_SPECIAL KE_FILLER. /// KS_SPECIAL KE_FILLER.
/// ///
/// @param[in] from What characters to replace. /// @param[in] from What characters to replace.
@@ -771,7 +771,7 @@ int get_mouse_button(int code, bool *is_click, bool *is_drag)
/// When cpo_flags contains #FLAG_CPO_BSLASH, a backslash /// When cpo_flags contains #FLAG_CPO_BSLASH, a backslash
/// can be used in place of <C-v>. All other <C-v> /// can be used in place of <C-v>. All other <C-v>
/// characters are removed. /// characters are removed.
/// @param[in] special If true, always accept <key> notation. /// @param[in] special Replace keycodes, e.g. <CR> becomes a "\n" char.
/// @param[in] cpo_flags Relevant flags derived from p_cpo, see /// @param[in] cpo_flags Relevant flags derived from p_cpo, see
/// #CPO_TO_CPO_FLAGS. /// #CPO_TO_CPO_FLAGS.
/// ///
@@ -790,11 +790,9 @@ char_u *replace_termcodes(const char_u *from, const size_t from_len,
const char_u *src; const char_u *src;
const char_u *const end = from + from_len - 1; const char_u *const end = from + from_len - 1;
int do_backslash; // backslash is a special character int do_backslash; // backslash is a special character
int do_special; // recognize <> key codes
char_u *result; // buffer for resulting string char_u *result; // buffer for resulting string
do_backslash = !(cpo_flags&FLAG_CPO_BSLASH); do_backslash = !(cpo_flags&FLAG_CPO_BSLASH);
do_special = !(cpo_flags&FLAG_CPO_SPECI) || special;
// Allocate space for the translation. Worst case a single character is // Allocate space for the translation. Worst case a single character is
// replaced by 6 bytes (shifted special key), plus a NUL at the end. // replaced by 6 bytes (shifted special key), plus a NUL at the end.
@@ -817,9 +815,8 @@ char_u *replace_termcodes(const char_u *from, const size_t from_len,
// Copy each byte from *from to result[dlen] // Copy each byte from *from to result[dlen]
while (src <= end) { while (src <= end) {
// If 'cpoptions' does not contain '<', check for special key codes, // Check for special <> keycodes, like "<C-S-LeftMouse>"
// like "<C-S-LeftMouse>" if (special && (do_lt || ((end - src) >= 3
if (do_special && (do_lt || ((end - src) >= 3
&& STRNCMP(src, "<lt>", 4) != 0))) { && STRNCMP(src, "<lt>", 4) != 0))) {
// Replace <SID> by K_SNR <script-nr> _. // Replace <SID> by K_SNR <script-nr> _.
// (room: 5 * 6 = 30 bytes; needed: 3 + <nr> + 1 <= 14) // (room: 5 * 6 = 30 bytes; needed: 3 + <nr> + 1 <= 14)
@@ -846,7 +843,7 @@ char_u *replace_termcodes(const char_u *from, const size_t from_len,
} }
} }
if (do_special) { if (special) {
char_u *p, *s, len; char_u *p, *s, len;
// Replace <Leader> by the value of "mapleader". // Replace <Leader> by the value of "mapleader".

View File

@@ -464,13 +464,9 @@ enum key_extra {
#define MAX_KEY_CODE_LEN 6 #define MAX_KEY_CODE_LEN 6
#define FLAG_CPO_BSLASH 0x01 #define FLAG_CPO_BSLASH 0x01
#define FLAG_CPO_SPECI 0x02 #define CPO_TO_CPO_FLAGS ((vim_strchr(p_cpo, CPO_BSLASH) == NULL) \
#define CPO_TO_CPO_FLAGS (((vim_strchr(p_cpo, CPO_BSLASH) == NULL) \ ? 0 \
? 0 \ : FLAG_CPO_BSLASH)
: FLAG_CPO_BSLASH)| \
(vim_strchr(p_cpo, CPO_SPECI) == NULL \
? 0 \
: FLAG_CPO_SPECI))
#ifdef INCLUDE_GENERATED_DECLARATIONS #ifdef INCLUDE_GENERATED_DECLARATIONS
# include "keymap.h.generated.h" # include "keymap.h.generated.h"

View File

@@ -60,7 +60,6 @@ ex_menu (
char_u *map_to; char_u *map_to;
int noremap; int noremap;
bool silent = false; bool silent = false;
bool special = false;
int unmenu; int unmenu;
char_u *map_buf; char_u *map_buf;
char_u *arg; char_u *arg;
@@ -86,7 +85,7 @@ ex_menu (
continue; continue;
} }
if (STRNCMP(arg, "<special>", 9) == 0) { if (STRNCMP(arg, "<special>", 9) == 0) {
special = true; // Ignore obsolete "<special>" modifier.
arg = skipwhite(arg + 9); arg = skipwhite(arg + 9);
continue; continue;
} }
@@ -222,7 +221,7 @@ ex_menu (
map_buf = NULL; // Menu tips are plain text. map_buf = NULL; // Menu tips are plain text.
} else { } else {
map_to = replace_termcodes(map_to, STRLEN(map_to), &map_buf, false, true, map_to = replace_termcodes(map_to, STRLEN(map_to), &map_buf, false, true,
special, CPO_TO_CPO_FLAGS); true, CPO_TO_CPO_FLAGS);
} }
menuarg.modes = modes; menuarg.modes = modes;
menuarg.noremap[0] = noremap; menuarg.noremap[0] = noremap;

View File

@@ -3034,7 +3034,7 @@ did_set_string_option (
/* 'pastetoggle': translate key codes like in a mapping */ /* 'pastetoggle': translate key codes like in a mapping */
else if (varp == &p_pt) { else if (varp == &p_pt) {
if (*p_pt) { if (*p_pt) {
(void)replace_termcodes(p_pt, STRLEN(p_pt), &p, true, true, false, (void)replace_termcodes(p_pt, STRLEN(p_pt), &p, true, true, true,
CPO_TO_CPO_FLAGS); CPO_TO_CPO_FLAGS);
if (p != NULL) { if (p != NULL) {
if (new_value_alloced) if (new_value_alloced)

View File

@@ -123,15 +123,14 @@
#define CPO_DOLLAR '$' #define CPO_DOLLAR '$'
#define CPO_FILTER '!' #define CPO_FILTER '!'
#define CPO_MATCH '%' #define CPO_MATCH '%'
#define CPO_PLUS '+' /* ":write file" resets 'modified' */ #define CPO_PLUS '+' // ":write file" resets 'modified'
#define CPO_SPECI '<' /* don't recognize <> in mappings */ #define CPO_REGAPPEND '>' // insert NL when appending to a register
#define CPO_REGAPPEND '>' /* insert NL when appending to a register */ #define CPO_SCOLON ';' // using "," and ";" will skip over char if
#define CPO_SCOLON ';' /* using "," and ";" will skip over char if // cursor would not move
* cursor would not move */
#define CPO_CHANGEW '_' // "cw" special-case #define CPO_CHANGEW '_' // "cw" special-case
// default values for Vim and Vi // default values for Vim and Vi
#define CPO_VIM "aABceFs_" #define CPO_VIM "aABceFs_"
#define CPO_VI "aAbBcCdDeEfFiIJKlLmMnoOpPqrRsStuvWxXyZ$!%+<>;_" #define CPO_VI "aAbBcCdDeEfFiIJKlLmMnoOpPqrRsStuvWxXyZ$!%+>;_"
/* characters for p_ww option: */ /* characters for p_ww option: */
#define WW_ALL "bshl<>[],~" #define WW_ALL "bshl<>[],~"

View File

@@ -256,40 +256,38 @@ describe('get_keymap', function()
return ret return ret
end end
command('set cpo-=< cpo+=B') command('set cpo+=B')
command('nnoremap \\<C-a><C-a><LT>C-a>\\ \\<C-b><C-b><LT>C-b>\\') command('nnoremap \\<C-a><C-a><LT>C-a>\\ \\<C-b><C-b><LT>C-b>\\')
command('nnoremap <special> \\<C-c><C-c><LT>C-c>\\ \\<C-d><C-d><LT>C-d>\\') command('nnoremap <special> \\<C-c><C-c><LT>C-c>\\ \\<C-d><C-d><LT>C-d>\\')
command('set cpo+=B<') command('set cpo+=B')
command('xnoremap \\<C-a><C-a><LT>C-a>\\ \\<C-b><C-b><LT>C-b>\\') command('xnoremap \\<C-a><C-a><LT>C-a>\\ \\<C-b><C-b><LT>C-b>\\')
command('xnoremap <special> \\<C-c><C-c><LT>C-c>\\ \\<C-d><C-d><LT>C-d>\\') command('xnoremap <special> \\<C-c><C-c><LT>C-c>\\ \\<C-d><C-d><LT>C-d>\\')
command('set cpo-=B<') command('set cpo-=B')
command('snoremap \\<C-a><C-a><LT>C-a>\\ \\<C-b><C-b><LT>C-b>\\') command('snoremap \\<C-a><C-a><LT>C-a>\\ \\<C-b><C-b><LT>C-b>\\')
command('snoremap <special> \\<C-c><C-c><LT>C-c>\\ \\<C-d><C-d><LT>C-d>\\') command('snoremap <special> \\<C-c><C-c><LT>C-c>\\ \\<C-d><C-d><LT>C-d>\\')
command('set cpo-=B cpo+=<') command('set cpo-=B')
command('onoremap \\<C-a><C-a><LT>C-a>\\ \\<C-b><C-b><LT>C-b>\\') command('onoremap \\<C-a><C-a><LT>C-a>\\ \\<C-b><C-b><LT>C-b>\\')
command('onoremap <special> \\<C-c><C-c><LT>C-c>\\ \\<C-d><C-d><LT>C-d>\\') command('onoremap <special> \\<C-c><C-c><LT>C-c>\\ \\<C-d><C-d><LT>C-d>\\')
for _, cmd in ipairs({ for _, cmd in ipairs({
'set cpo-=B cpo+=<', 'set cpo-=B',
'set cpo-=B<', 'set cpo+=B',
'set cpo+=B<',
'set cpo-=< cpo+=B',
}) do }) do
command(cmd) command(cmd)
eq({cpomap('\\<C-C><C-C><lt>C-c>\\', '\\<C-D><C-D><lt>C-d>\\', 'n'), eq({cpomap('\\<C-C><C-C><lt>C-c>\\', '\\<C-D><C-D><lt>C-d>\\', 'n'),
cpomap('\\<C-A><C-A><lt>C-a>\\', '\\<C-B><C-B><lt>C-b>\\', 'n')}, cpomap('\\<C-A><C-A><lt>C-a>\\', '\\<C-B><C-B><lt>C-b>\\', 'n')},
meths.get_keymap('n')) meths.get_keymap('n'))
eq({cpomap('\\<C-C><C-C><lt>C-c>\\', '\\<C-D><C-D><lt>C-d>\\', 'x'), eq({cpomap('\\<C-C><C-C><lt>C-c>\\', '\\<C-D><C-D><lt>C-d>\\', 'x'),
cpomap('\\<lt>C-a><lt>C-a><lt>LT>C-a>\\', '\\<lt>C-b><lt>C-b><lt>LT>C-b>\\', 'x')}, cpomap('\\<C-A><C-A><lt>C-a>\\', '\\<C-B><C-B><lt>C-b>\\', 'x')},
meths.get_keymap('x')) meths.get_keymap('x'))
eq({cpomap('<lt>C-c><C-C><lt>C-c> ', '<lt>C-d><C-D><lt>C-d>', 's'), eq({cpomap('<lt>C-c><C-C><lt>C-c> ', '<lt>C-d><C-D><lt>C-d>', 's'),
cpomap('<lt>C-a><C-A><lt>C-a> ', '<lt>C-b><C-B><lt>C-b>', 's')}, cpomap('<lt>C-a><C-A><lt>C-a> ', '<lt>C-b><C-B><lt>C-b>', 's')},
meths.get_keymap('s')) meths.get_keymap('s'))
eq({cpomap('<lt>C-c><C-C><lt>C-c> ', '<lt>C-d><C-D><lt>C-d>', 'o'), eq({cpomap('<lt>C-c><C-C><lt>C-c> ', '<lt>C-d><C-D><lt>C-d>', 'o'),
cpomap('<lt>C-a><lt>C-a><lt>LT>C-a> ', '<lt>C-b><lt>C-b><lt>LT>C-b>', 'o')}, cpomap('<lt>C-a><C-A><lt>C-a> ', '<lt>C-b><C-B><lt>C-b>', 'o')},
meths.get_keymap('o')) meths.get_keymap('o'))
end end
end) end)

View File

@@ -373,6 +373,11 @@ describe('api', function()
'<NL>x<Esc>x<CR>x<lt>x', true, true, true)) '<NL>x<Esc>x<CR>x<lt>x', true, true, true))
end) end)
it('does not convert keycodes if special=false', function()
eq('<NL>x<Esc>x<CR>x<lt>x', helpers.nvim('replace_termcodes',
'<NL>x<Esc>x<CR>x<lt>x', true, true, false))
end)
it('does not crash when transforming an empty string', function() it('does not crash when transforming an empty string', function()
-- Actually does not test anything, because current code will use NULL for -- Actually does not test anything, because current code will use NULL for
-- an empty string. -- an empty string.
@@ -391,13 +396,13 @@ describe('api', function()
-- notice the special char(…) \xe2\80\xa6 -- notice the special char(…) \xe2\80\xa6
nvim('feedkeys', ':let x1="…"\n', '', true) nvim('feedkeys', ':let x1="…"\n', '', true)
-- Both replace_termcodes and feedkeys escape \x80 -- Both nvim_replace_termcodes and nvim_feedkeys escape \x80
local inp = helpers.nvim('replace_termcodes', ':let x2="…"<CR>', true, true, true) local inp = helpers.nvim('replace_termcodes', ':let x2="…"<CR>', true, true, true)
nvim('feedkeys', inp, '', true) nvim('feedkeys', inp, '', true) -- escape_csi=true
-- Disabling CSI escaping in feedkeys -- nvim_feedkeys with CSI escaping disabled
inp = helpers.nvim('replace_termcodes', ':let x3="…"<CR>', true, true, true) inp = helpers.nvim('replace_termcodes', ':let x3="…"<CR>', true, true, true)
nvim('feedkeys', inp, '', false) nvim('feedkeys', inp, '', false) -- escape_csi=false
helpers.stop() helpers.stop()
end end