mirror of
https://github.com/vim/vim.git
synced 2025-09-27 04:14:06 -04:00
patch 9.0.0449: there is no easy way to translate a key code into a string
Problem: There is no easy way to translate a string with a key code into a readable string. Solution: Add the keytrans() function. (closes #11114)
This commit is contained in:
@@ -325,6 +325,8 @@ js_encode({expr}) String encode JS style JSON
|
|||||||
json_decode({string}) any decode JSON
|
json_decode({string}) any decode JSON
|
||||||
json_encode({expr}) String encode JSON
|
json_encode({expr}) String encode JSON
|
||||||
keys({dict}) List keys in {dict}
|
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}
|
len({expr}) Number the length of {expr}
|
||||||
libcall({lib}, {func}, {arg}) String call {func} in library {lib} with {arg}
|
libcall({lib}, {func}, {arg}) String call {func} in library {lib} with {arg}
|
||||||
libcallnr({lib}, {func}, {arg}) Number idem, but return a Number
|
libcallnr({lib}, {func}, {arg}) Number idem, but return a Number
|
||||||
@@ -5205,6 +5207,16 @@ keys({dict}) *keys()*
|
|||||||
Can also be used as a |method|: >
|
Can also be used as a |method|: >
|
||||||
mydict->keys()
|
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()* *E701*
|
||||||
len({expr}) The result is a Number, which is the length of the argument.
|
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
|
When {expr} is a String or a Number the length in bytes is
|
||||||
|
@@ -89,6 +89,7 @@ static void f_inputsecret(typval_T *argvars, typval_T *rettv);
|
|||||||
static void f_interrupt(typval_T *argvars, typval_T *rettv);
|
static void f_interrupt(typval_T *argvars, typval_T *rettv);
|
||||||
static void f_invert(typval_T *argvars, typval_T *rettv);
|
static void f_invert(typval_T *argvars, typval_T *rettv);
|
||||||
static void f_islocked(typval_T *argvars, typval_T *rettv);
|
static void f_islocked(typval_T *argvars, typval_T *rettv);
|
||||||
|
static void f_keytrans(typval_T *argvars, typval_T *rettv);
|
||||||
static void f_last_buffer_nr(typval_T *argvars, typval_T *rettv);
|
static void f_last_buffer_nr(typval_T *argvars, typval_T *rettv);
|
||||||
static void f_libcall(typval_T *argvars, typval_T *rettv);
|
static void f_libcall(typval_T *argvars, typval_T *rettv);
|
||||||
static void f_libcallnr(typval_T *argvars, typval_T *rettv);
|
static void f_libcallnr(typval_T *argvars, typval_T *rettv);
|
||||||
@@ -2058,6 +2059,8 @@ static funcentry_T global_functions[] =
|
|||||||
ret_string, f_json_encode},
|
ret_string, f_json_encode},
|
||||||
{"keys", 1, 1, FEARG_1, arg1_dict_any,
|
{"keys", 1, 1, FEARG_1, arg1_dict_any,
|
||||||
ret_list_string, f_keys},
|
ret_list_string, f_keys},
|
||||||
|
{"keytrans", 1, 1, FEARG_1, arg1_string,
|
||||||
|
ret_string, f_keytrans},
|
||||||
{"last_buffer_nr", 0, 0, 0, NULL, // obsolete
|
{"last_buffer_nr", 0, 0, 0, NULL, // obsolete
|
||||||
ret_number, f_last_buffer_nr},
|
ret_number, f_last_buffer_nr},
|
||||||
{"len", 1, 1, FEARG_1, arg1_len,
|
{"len", 1, 1, FEARG_1, arg1_len,
|
||||||
@@ -7135,6 +7138,24 @@ f_islocked(typval_T *argvars, typval_T *rettv)
|
|||||||
clear_lval(&lv);
|
clear_lval(&lv);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* "keytrans()" function
|
||||||
|
*/
|
||||||
|
static void
|
||||||
|
f_keytrans(typval_T *argvars, typval_T *rettv)
|
||||||
|
{
|
||||||
|
char_u *escaped;
|
||||||
|
|
||||||
|
rettv->v_type = VAR_STRING;
|
||||||
|
if (check_for_string_arg(argvars, 0) == FAIL
|
||||||
|
|| argvars[0].vval.v_string == NULL)
|
||||||
|
return;
|
||||||
|
// Need to escape K_SPECIAL and CSI for mb_unescape().
|
||||||
|
escaped = vim_strsave_escape_csi(argvars[0].vval.v_string);
|
||||||
|
rettv->vval.v_string = str2special_save(escaped, TRUE, TRUE);
|
||||||
|
vim_free(escaped);
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* "last_buffer_nr()" function.
|
* "last_buffer_nr()" function.
|
||||||
*/
|
*/
|
||||||
|
@@ -2317,7 +2317,7 @@ mapblock2dict(
|
|||||||
int buffer_local, // false if not buffer local mapping
|
int buffer_local, // false if not buffer local mapping
|
||||||
int abbr) // true if abbreviation
|
int abbr) // true if abbreviation
|
||||||
{
|
{
|
||||||
char_u *lhs = str2special_save(mp->m_keys, TRUE);
|
char_u *lhs = str2special_save(mp->m_keys, TRUE, FALSE);
|
||||||
char_u *mapmode = map_mode_to_chars(mp->m_mode);
|
char_u *mapmode = map_mode_to_chars(mp->m_mode);
|
||||||
|
|
||||||
dict_add_string(dict, "lhs", lhs);
|
dict_add_string(dict, "lhs", lhs);
|
||||||
@@ -2409,7 +2409,7 @@ get_maparg(typval_T *argvars, typval_T *rettv, int exact)
|
|||||||
if (*rhs == NUL)
|
if (*rhs == NUL)
|
||||||
rettv->vval.v_string = vim_strsave((char_u *)"<Nop>");
|
rettv->vval.v_string = vim_strsave((char_u *)"<Nop>");
|
||||||
else
|
else
|
||||||
rettv->vval.v_string = str2special_save(rhs, FALSE);
|
rettv->vval.v_string = str2special_save(rhs, FALSE, FALSE);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -2478,7 +2478,7 @@ f_maplist(typval_T *argvars UNUSED, typval_T *rettv)
|
|||||||
keys_buf = NULL;
|
keys_buf = NULL;
|
||||||
did_simplify = FALSE;
|
did_simplify = FALSE;
|
||||||
|
|
||||||
lhs = str2special_save(mp->m_keys, TRUE);
|
lhs = str2special_save(mp->m_keys, TRUE, FALSE);
|
||||||
(void)replace_termcodes(lhs, &keys_buf, flags, &did_simplify);
|
(void)replace_termcodes(lhs, &keys_buf, flags, &did_simplify);
|
||||||
vim_free(lhs);
|
vim_free(lhs);
|
||||||
|
|
||||||
|
@@ -2890,7 +2890,7 @@ menuitem_getinfo(char_u *menu_name, vimmenu_T *menu, int modes, dict_T *dict)
|
|||||||
*menu->strings[bit] == NUL
|
*menu->strings[bit] == NUL
|
||||||
? (char_u *)"<Nop>"
|
? (char_u *)"<Nop>"
|
||||||
: (tofree = str2special_save(
|
: (tofree = str2special_save(
|
||||||
menu->strings[bit], FALSE)));
|
menu->strings[bit], FALSE, FALSE)));
|
||||||
vim_free(tofree);
|
vim_free(tofree);
|
||||||
}
|
}
|
||||||
if (status == OK)
|
if (status == OK)
|
||||||
|
@@ -1759,7 +1759,7 @@ msg_outtrans_special(
|
|||||||
++str;
|
++str;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
text = (char *)str2special(&str, from);
|
text = (char *)str2special(&str, from, FALSE);
|
||||||
if (text[0] != NUL && text[1] == NUL)
|
if (text[0] != NUL && text[1] == NUL)
|
||||||
// single-byte character or illegal byte
|
// single-byte character or illegal byte
|
||||||
text = (char *)transchar_byte((char_u)text[0]);
|
text = (char *)transchar_byte((char_u)text[0]);
|
||||||
@@ -1782,14 +1782,16 @@ msg_outtrans_special(
|
|||||||
char_u *
|
char_u *
|
||||||
str2special_save(
|
str2special_save(
|
||||||
char_u *str,
|
char_u *str,
|
||||||
int is_lhs) // TRUE for lhs, FALSE for rhs
|
int replace_spaces, // TRUE to replace " " with "<Space>".
|
||||||
|
// used for the lhs of mapping and keytrans().
|
||||||
|
int replace_lt) // TRUE to replace "<" with "<lt>".
|
||||||
{
|
{
|
||||||
garray_T ga;
|
garray_T ga;
|
||||||
char_u *p = str;
|
char_u *p = str;
|
||||||
|
|
||||||
ga_init2(&ga, 1, 40);
|
ga_init2(&ga, 1, 40);
|
||||||
while (*p != NUL)
|
while (*p != NUL)
|
||||||
ga_concat(&ga, str2special(&p, is_lhs));
|
ga_concat(&ga, str2special(&p, replace_spaces, replace_lt));
|
||||||
ga_append(&ga, NUL);
|
ga_append(&ga, NUL);
|
||||||
return (char_u *)ga.ga_data;
|
return (char_u *)ga.ga_data;
|
||||||
}
|
}
|
||||||
@@ -1804,7 +1806,9 @@ str2special_save(
|
|||||||
char_u *
|
char_u *
|
||||||
str2special(
|
str2special(
|
||||||
char_u **sp,
|
char_u **sp,
|
||||||
int from) // TRUE for lhs of mapping
|
int replace_spaces, // TRUE to replace " " with "<Space>".
|
||||||
|
// used for the lhs of mapping and keytrans().
|
||||||
|
int replace_lt) // TRUE to replace "<" with "<lt>".
|
||||||
{
|
{
|
||||||
int c;
|
int c;
|
||||||
static char_u buf[7];
|
static char_u buf[7];
|
||||||
@@ -1861,8 +1865,10 @@ str2special(
|
|||||||
*sp = str + (*str == NUL ? 0 : 1);
|
*sp = str + (*str == NUL ? 0 : 1);
|
||||||
|
|
||||||
// Make special keys and C0 control characters in <> form, also <M-Space>.
|
// Make special keys and C0 control characters in <> form, also <M-Space>.
|
||||||
// Use <Space> only for lhs of a mapping.
|
if (special
|
||||||
if (special || c < ' ' || (from && c == ' '))
|
|| c < ' '
|
||||||
|
|| (replace_spaces && c == ' ')
|
||||||
|
|| (replace_lt && c == '<'))
|
||||||
return get_special_key_name(c, modifiers);
|
return get_special_key_name(c, modifiers);
|
||||||
buf[0] = c;
|
buf[0] = c;
|
||||||
buf[1] = NUL;
|
buf[1] = NUL;
|
||||||
@@ -1880,7 +1886,7 @@ str2specialbuf(char_u *sp, char_u *buf, int len)
|
|||||||
*buf = NUL;
|
*buf = NUL;
|
||||||
while (*sp)
|
while (*sp)
|
||||||
{
|
{
|
||||||
s = str2special(&sp, FALSE);
|
s = str2special(&sp, FALSE, FALSE);
|
||||||
if ((int)(STRLEN(s) + STRLEN(buf)) < len)
|
if ((int)(STRLEN(s) + STRLEN(buf)) < len)
|
||||||
STRCAT(buf, s);
|
STRCAT(buf, s);
|
||||||
}
|
}
|
||||||
|
@@ -3994,7 +3994,8 @@ get_option_value(
|
|||||||
if (stringval != NULL)
|
if (stringval != NULL)
|
||||||
{
|
{
|
||||||
if ((char_u **)varp == &p_pt) // 'pastetoggle'
|
if ((char_u **)varp == &p_pt) // 'pastetoggle'
|
||||||
*stringval = str2special_save(*(char_u **)(varp), FALSE);
|
*stringval = str2special_save(*(char_u **)(varp), FALSE,
|
||||||
|
FALSE);
|
||||||
#ifdef FEAT_CRYPT
|
#ifdef FEAT_CRYPT
|
||||||
// never return the value of the crypt key
|
// never return the value of the crypt key
|
||||||
else if ((char_u **)varp == &curbuf->b_p_key
|
else if ((char_u **)varp == &curbuf->b_p_key
|
||||||
@@ -4879,7 +4880,7 @@ put_setstring(
|
|||||||
{
|
{
|
||||||
s = *valuep;
|
s = *valuep;
|
||||||
while (*s != NUL)
|
while (*s != NUL)
|
||||||
if (put_escstr(fd, str2special(&s, FALSE), 2) == FAIL)
|
if (put_escstr(fd, str2special(&s, FALSE, FALSE), 2) == FAIL)
|
||||||
return FAIL;
|
return FAIL;
|
||||||
}
|
}
|
||||||
// expand the option value, replace $HOME by ~
|
// expand the option value, replace $HOME by ~
|
||||||
|
@@ -37,8 +37,8 @@ char_u *msg_outtrans_one(char_u *p, int attr);
|
|||||||
int msg_outtrans_len_attr(char_u *msgstr, int len, int attr);
|
int msg_outtrans_len_attr(char_u *msgstr, int len, int attr);
|
||||||
void msg_make(char_u *arg);
|
void msg_make(char_u *arg);
|
||||||
int msg_outtrans_special(char_u *strstart, int from, int maxlen);
|
int msg_outtrans_special(char_u *strstart, int from, int maxlen);
|
||||||
char_u *str2special_save(char_u *str, int is_lhs);
|
char_u *str2special_save(char_u *str, int replace_spaces, int replace_lt);
|
||||||
char_u *str2special(char_u **sp, int from);
|
char_u *str2special(char_u **sp, int replace_spaces, int replace_lt);
|
||||||
void str2specialbuf(char_u *sp, char_u *buf, int len);
|
void str2specialbuf(char_u *sp, char_u *buf, int len);
|
||||||
void msg_prt_line(char_u *s, int list);
|
void msg_prt_line(char_u *s, int list);
|
||||||
void msg_puts(char *s);
|
void msg_puts(char *s);
|
||||||
|
@@ -2764,6 +2764,32 @@ func Test_eval()
|
|||||||
call assert_fails("call eval('5 a')", 'E488:')
|
call assert_fails("call eval('5 a')", 'E488:')
|
||||||
endfunc
|
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('', test_null_string()->keytrans())
|
||||||
|
call assert_fails('call keytrans(1)', 'E1174:')
|
||||||
|
call assert_fails('call keytrans()', 'E119:')
|
||||||
|
endfunc
|
||||||
|
|
||||||
" Test for the nr2char() function
|
" Test for the nr2char() function
|
||||||
func Test_nr2char()
|
func Test_nr2char()
|
||||||
set encoding=latin1
|
set encoding=latin1
|
||||||
|
@@ -703,6 +703,8 @@ static char *(features[]) =
|
|||||||
|
|
||||||
static int included_patches[] =
|
static int included_patches[] =
|
||||||
{ /* Add new patch number below this line */
|
{ /* Add new patch number below this line */
|
||||||
|
/**/
|
||||||
|
449,
|
||||||
/**/
|
/**/
|
||||||
448,
|
448,
|
||||||
/**/
|
/**/
|
||||||
|
Reference in New Issue
Block a user