Skip to content

Commit

Permalink
vim-patch:9.0.0449: there is no easy way to translate a key code into…
Browse files Browse the repository at this point in the history
… a string (#20168)

Problem:    There is no easy way to translate a string with a key code into a
            readable string.
Solution:   Add the keytrans() function. (closes vim/vim#11114)
vim/vim@cdc8393

vim-patch:7b2d87220c6c

Add missing part of patch
vim/vim@7b2d872
  • Loading branch information
zeertzjq authored Sep 12, 2022
1 parent 91a150d commit 907fc8a
Show file tree
Hide file tree
Showing 8 changed files with 61 additions and 9 deletions.
12 changes: 12 additions & 0 deletions runtime/doc/builtin.txt
Original file line number Diff line number Diff line change
Expand Up @@ -277,6 +277,8 @@ join({list} [, {sep}]) String join {list} items into one String
json_decode({expr}) any Convert {expr} from JSON
json_encode({expr}) String Convert {expr} to JSON
keys({dict}) List keys in {dict}
keytrans({string}) String translate internal keycodes to a form
that can be used by |:map|
len({expr}) Number the length of {expr}
libcall({lib}, {func}, {arg}) String call {func} in library {lib} with {arg}
libcallnr({lib}, {func}, {arg}) Number idem, but return a Number
Expand Down Expand Up @@ -4537,6 +4539,16 @@ keys({dict}) *keys()*
Can also be used as a |method|: >
mydict->keys()
keytrans({string}) *keytrans()*
Turn the internal byte representation of keys into a form that
can be used for |:map|. E.g. >
:let xx = "\<C-Home>"
:echo keytrans(xx)
< <C-Home>

Can also be used as a |method|: >
"\<C-Home>"->keytrans()
< *len()* *E701*
len({expr}) The result is a Number, which is the length of the argument.
When {expr} is a String or a Number the length in bytes is
Expand Down
2 changes: 2 additions & 0 deletions runtime/doc/usr_41.txt
Original file line number Diff line number Diff line change
Expand Up @@ -604,6 +604,8 @@ String manipulation: *string-functions*
fnameescape() escape a file name for use with a Vim command
tr() translate characters from one set to another
strtrans() translate a string to make it printable
keytrans() translate internal keycodes to a form that
can be used by |:map|
tolower() turn a string to lowercase
toupper() turn a string to uppercase
charclass() class of a character
Expand Down
1 change: 1 addition & 0 deletions src/nvim/eval.lua
Original file line number Diff line number Diff line change
Expand Up @@ -236,6 +236,7 @@ return {
json_decode={args=1, base=1},
json_encode={args=1, base=1},
keys={args=1, base=1},
keytrans={args=1, base=1},
last_buffer_nr={}, -- obsolete
len={args=1, base=1},
libcall={args=3, base=3},
Expand Down
14 changes: 14 additions & 0 deletions src/nvim/eval/funcs.c
Original file line number Diff line number Diff line change
Expand Up @@ -4673,6 +4673,20 @@ static void f_json_encode(typval_T *argvars, typval_T *rettv, EvalFuncData fptr)
rettv->vval.v_string = encode_tv2json(&argvars[0], NULL);
}

/// "keytrans()" function
static void f_keytrans(typval_T *argvars, typval_T *rettv, EvalFuncData fptr)
{
rettv->v_type = VAR_STRING;
if (tv_check_for_string_arg(argvars, 0) == FAIL
|| argvars[0].vval.v_string == NULL) {
return;
}
// Need to escape K_SPECIAL for mb_unescape().
char *escaped = vim_strsave_escape_ks(argvars[0].vval.v_string);
rettv->vval.v_string = str2special_save(escaped, true, true);
xfree(escaped);
}

/// "last_buffer_nr()" function.
static void f_last_buffer_nr(typval_T *argvars, typval_T *rettv, EvalFuncData fptr)
{
Expand Down
3 changes: 1 addition & 2 deletions src/nvim/menu.c
Original file line number Diff line number Diff line change
Expand Up @@ -685,8 +685,7 @@ static dict_T *menu_get_recursive(const vimmenu_T *menu, int modes)
if ((menu->modes & modes & (1 << bit)) != 0) {
dict_T *impl = tv_dict_alloc();
tv_dict_add_allocated_str(impl, S_LEN("rhs"),
str2special_save(menu->strings[bit],
false, false));
str2special_save(menu->strings[bit], false, false));
tv_dict_add_nr(impl, S_LEN("silent"), menu->silent[bit]);
tv_dict_add_nr(impl, S_LEN("enabled"),
(menu->enabled & (1 << bit)) ? 1 : 0);
Expand Down
8 changes: 4 additions & 4 deletions src/nvim/message.c
Original file line number Diff line number Diff line change
Expand Up @@ -1681,8 +1681,8 @@ int msg_outtrans_special(const char *strstart, bool from, int maxlen)
/// Used for lhs or rhs of mappings.
///
/// @param[in] str String to convert.
/// @param[in] replace_spaces Convert spaces into `<Space>`, normally used fo
/// lhs, but not rhs.
/// @param[in] replace_spaces Convert spaces into `<Space>`, normally used for
/// lhs of mapping and keytrans(), but not rhs.
/// @param[in] replace_lt Convert `<` into `<lt>`.
///
/// @return [allocated] Converted string.
Expand All @@ -1704,8 +1704,8 @@ char *str2special_save(const char *const str, const bool replace_spaces, const b
/// Convert character, replacing key with printable representation.
///
/// @param[in,out] sp String to convert. Is advanced to the next key code.
/// @param[in] replace_spaces Convert spaces into <Space>, normally used for
/// lhs, but not rhs.
/// @param[in] replace_spaces Convert spaces into `<Space>`, normally used for
/// lhs of mapping and keytrans(), but not rhs.
/// @param[in] replace_lt Convert `<` into `<lt>`.
///
/// @return Converted key code, in a static buffer. Buffer is always one and the
Expand Down
4 changes: 1 addition & 3 deletions src/nvim/option.c
Original file line number Diff line number Diff line change
Expand Up @@ -3558,9 +3558,7 @@ static int put_setstring(FILE *fd, char *cmd, char *name, char **valuep, uint64_
if (valuep == &p_pt) {
s = (char_u *)(*valuep);
while (*s != NUL) {
if (put_escstr(fd, (char_u *)str2special((const char **)&s, false,
false), 2)
== FAIL) {
if (put_escstr(fd, (char_u *)str2special((const char **)&s, false, false), 2) == FAIL) {
return FAIL;
}
}
Expand Down
26 changes: 26 additions & 0 deletions src/nvim/testdir/test_functions.vim
Original file line number Diff line number Diff line change
Expand Up @@ -1907,6 +1907,32 @@ func Test_eval()
call assert_fails("call eval('5 a')", 'E488:')
endfunc

" Test for the keytrans() function
func Test_keytrans()
call assert_equal('<Space>', keytrans(' '))
call assert_equal('<lt>', keytrans('<'))
call assert_equal('<lt>Tab>', keytrans('<Tab>'))
call assert_equal('<Tab>', keytrans("\<Tab>"))
call assert_equal('<C-V>', keytrans("\<C-V>"))
call assert_equal('<BS>', keytrans("\<BS>"))
call assert_equal('<Home>', keytrans("\<Home>"))
call assert_equal('<C-Home>', keytrans("\<C-Home>"))
call assert_equal('<M-Home>', keytrans("\<M-Home>"))
call assert_equal('<C-Space>', keytrans("\<C-Space>"))
call assert_equal('<M-Space>', keytrans("\<*M-Space>"))
call assert_equal('<M-x>', "\<*M-x>"->keytrans())
call assert_equal('<C-I>', "\<*C-I>"->keytrans())
call assert_equal('<S-3>', "\<*S-3>"->keytrans())
call assert_equal('π', 'π'->keytrans())
call assert_equal('<M-π>', "\<M-π>"->keytrans())
call assert_equal('ě', 'ě'->keytrans())
call assert_equal('<M-ě>', "\<M-ě>"->keytrans())
call assert_equal('', ''->keytrans())
call assert_equal('', v:_null_string->keytrans())
call assert_fails('call keytrans(1)', 'E1174:')
call assert_fails('call keytrans()', 'E119:')
endfunc

" Test for the nr2char() function
func Test_nr2char()
" set encoding=latin1
Expand Down

0 comments on commit 907fc8a

Please sign in to comment.