Patch 9.0.0449

9 views
Skip to first unread message

Bram Moolenaar

unread,
Sep 12, 2022, 8:39:57 AM9/12/22
to vim...@googlegroups.com

Patch 9.0.0449
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)
Files: runtime/doc/builtin.txt, runtime/doc/usr_41.txt, src/evalfunc.c,
src/map.c, src/menu.c, src/message.c, src/option.c,
src/proto/message.pro, src/testdir/test_functions.vim


*** ../vim-9.0.0448/runtime/doc/builtin.txt 2022-09-09 18:46:41.558660414 +0100
--- runtime/doc/builtin.txt 2022-09-12 13:28:33.439747660 +0100
***************
*** 325,330 ****
--- 325,332 ----
json_decode({string}) any decode JSON
json_encode({expr}) String encode 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
***************
*** 5195,5200 ****
--- 5207,5222 ----
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
*** ../vim-9.0.0448/runtime/doc/usr_41.txt 2022-08-27 12:22:19.975008573 +0100
--- runtime/doc/usr_41.txt 2022-09-12 13:28:33.439747660 +0100
***************
*** 736,741 ****
--- 737,744 ----
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
***************
*** 1349,1355 ****
did_filetype() check if a FileType autocommand was used
eventhandler() check if invoked by an event handler
getpid() get process ID of Vim
! getscriptinfo() get list of sourced vim scripts
getimstatus() check if IME status is active
interrupt() interrupt script execution
windowsversion() get MS-Windows version
--- 1352,1358 ----
did_filetype() check if a FileType autocommand was used
eventhandler() check if invoked by an event handler
getpid() get process ID of Vim
! getscriptinfo() get list of sourced vim scripts
getimstatus() check if IME status is active
interrupt() interrupt script execution
windowsversion() get MS-Windows version
*** ../vim-9.0.0448/src/evalfunc.c 2022-09-09 18:46:41.558660414 +0100
--- src/evalfunc.c 2022-09-12 13:28:33.439747660 +0100
***************
*** 89,94 ****
--- 89,95 ----
static void f_interrupt(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_keytrans(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_libcallnr(typval_T *argvars, typval_T *rettv);
***************
*** 2058,2063 ****
--- 2059,2066 ----
ret_string, f_json_encode},
{"keys", 1, 1, FEARG_1, arg1_dict_any,
ret_list_string, f_keys},
+ {"keytrans", 1, 1, FEARG_1, arg1_string,
+ ret_string, f_keytrans},
{"last_buffer_nr", 0, 0, 0, NULL, // obsolete
ret_number, f_last_buffer_nr},
{"len", 1, 1, FEARG_1, arg1_len,
***************
*** 7136,7141 ****
--- 7139,7162 ----
}

/*
+ * "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.
*/
static void
*** ../vim-9.0.0448/src/map.c 2022-08-31 16:40:14.250932016 +0100
--- src/map.c 2022-09-12 13:28:33.439747660 +0100
***************
*** 2317,2323 ****
int buffer_local, // false if not buffer local mapping
int abbr) // true if abbreviation
{
! char_u *lhs = str2special_save(mp->m_keys, TRUE);
char_u *mapmode = map_mode_to_chars(mp->m_mode);

dict_add_string(dict, "lhs", lhs);
--- 2317,2323 ----
int buffer_local, // false if not buffer local mapping
int abbr) // true if abbreviation
{
! char_u *lhs = str2special_save(mp->m_keys, TRUE, FALSE);
char_u *mapmode = map_mode_to_chars(mp->m_mode);

dict_add_string(dict, "lhs", lhs);
***************
*** 2409,2415 ****
if (*rhs == NUL)
rettv->vval.v_string = vim_strsave((char_u *)"<Nop>");
else
! rettv->vval.v_string = str2special_save(rhs, FALSE);
}

}
--- 2409,2415 ----
if (*rhs == NUL)
rettv->vval.v_string = vim_strsave((char_u *)"<Nop>");
else
! rettv->vval.v_string = str2special_save(rhs, FALSE, FALSE);
}

}
***************
*** 2478,2484 ****
keys_buf = NULL;
did_simplify = FALSE;

! lhs = str2special_save(mp->m_keys, TRUE);
(void)replace_termcodes(lhs, &keys_buf, flags, &did_simplify);
vim_free(lhs);

--- 2478,2484 ----
keys_buf = NULL;
did_simplify = FALSE;

! lhs = str2special_save(mp->m_keys, TRUE, FALSE);
(void)replace_termcodes(lhs, &keys_buf, flags, &did_simplify);
vim_free(lhs);

*** ../vim-9.0.0448/src/menu.c 2022-08-14 14:16:07.995582211 +0100
--- src/menu.c 2022-09-12 13:28:33.443747653 +0100
***************
*** 2890,2896 ****
*menu->strings[bit] == NUL
? (char_u *)"<Nop>"
: (tofree = str2special_save(
! menu->strings[bit], FALSE)));
vim_free(tofree);
}
if (status == OK)
--- 2890,2896 ----
*menu->strings[bit] == NUL
? (char_u *)"<Nop>"
: (tofree = str2special_save(
! menu->strings[bit], FALSE, FALSE)));
vim_free(tofree);
}
if (status == OK)
*** ../vim-9.0.0448/src/message.c 2022-09-11 21:35:47.554255165 +0100
--- src/message.c 2022-09-12 13:28:33.443747653 +0100
***************
*** 1759,1765 ****
++str;
}
else
! text = (char *)str2special(&str, from);
if (text[0] != NUL && text[1] == NUL)
// single-byte character or illegal byte
text = (char *)transchar_byte((char_u)text[0]);
--- 1759,1765 ----
++str;
}
else
! text = (char *)str2special(&str, from, FALSE);
if (text[0] != NUL && text[1] == NUL)
// single-byte character or illegal byte
text = (char *)transchar_byte((char_u)text[0]);
***************
*** 1782,1795 ****
char_u *
str2special_save(
char_u *str,
! int is_lhs) // TRUE for lhs, FALSE for rhs
{
garray_T ga;
char_u *p = str;

ga_init2(&ga, 1, 40);
while (*p != NUL)
! ga_concat(&ga, str2special(&p, is_lhs));
ga_append(&ga, NUL);
return (char_u *)ga.ga_data;
}
--- 1782,1797 ----
char_u *
str2special_save(
char_u *str,
! 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;
char_u *p = str;

ga_init2(&ga, 1, 40);
while (*p != NUL)
! ga_concat(&ga, str2special(&p, replace_spaces, replace_lt));
ga_append(&ga, NUL);
return (char_u *)ga.ga_data;
}
***************
*** 1804,1810 ****
char_u *
str2special(
char_u **sp,
! int from) // TRUE for lhs of mapping
{
int c;
static char_u buf[7];
--- 1806,1814 ----
char_u *
str2special(
char_u **sp,
! 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;
static char_u buf[7];
***************
*** 1861,1868 ****
*sp = str + (*str == NUL ? 0 : 1);

// Make special keys and C0 control characters in <> form, also <M-Space>.
! // Use <Space> only for lhs of a mapping.
! if (special || c < ' ' || (from && c == ' '))
return get_special_key_name(c, modifiers);
buf[0] = c;
buf[1] = NUL;
--- 1865,1874 ----
*sp = str + (*str == NUL ? 0 : 1);

// Make special keys and C0 control characters in <> form, also <M-Space>.
! if (special
! || c < ' '
! || (replace_spaces && c == ' ')
! || (replace_lt && c == '<'))
return get_special_key_name(c, modifiers);
buf[0] = c;
buf[1] = NUL;
***************
*** 1880,1886 ****
*buf = NUL;
while (*sp)
{
! s = str2special(&sp, FALSE);
if ((int)(STRLEN(s) + STRLEN(buf)) < len)
STRCAT(buf, s);
}
--- 1886,1892 ----
*buf = NUL;
while (*sp)
{
! s = str2special(&sp, FALSE, FALSE);
if ((int)(STRLEN(s) + STRLEN(buf)) < len)
STRCAT(buf, s);
}
*** ../vim-9.0.0448/src/option.c 2022-08-31 14:46:07.911016920 +0100
--- src/option.c 2022-09-12 13:28:33.443747653 +0100
***************
*** 3994,4000 ****
if (stringval != NULL)
{
if ((char_u **)varp == &p_pt) // 'pastetoggle'
! *stringval = str2special_save(*(char_u **)(varp), FALSE);
#ifdef FEAT_CRYPT
// never return the value of the crypt key
else if ((char_u **)varp == &curbuf->b_p_key
--- 3994,4001 ----
if (stringval != NULL)
{
if ((char_u **)varp == &p_pt) // 'pastetoggle'
! *stringval = str2special_save(*(char_u **)(varp), FALSE,
! FALSE);
#ifdef FEAT_CRYPT
// never return the value of the crypt key
else if ((char_u **)varp == &curbuf->b_p_key
***************
*** 4879,4885 ****
{
s = *valuep;
while (*s != NUL)
! if (put_escstr(fd, str2special(&s, FALSE), 2) == FAIL)
return FAIL;
}
// expand the option value, replace $HOME by ~
--- 4880,4886 ----
{
s = *valuep;
while (*s != NUL)
! if (put_escstr(fd, str2special(&s, FALSE, FALSE), 2) == FAIL)
return FAIL;
}
// expand the option value, replace $HOME by ~
*** ../vim-9.0.0448/src/proto/message.pro 2022-08-31 14:46:07.907016957 +0100
--- src/proto/message.pro 2022-09-12 13:28:33.443747653 +0100
***************
*** 37,44 ****
int msg_outtrans_len_attr(char_u *msgstr, int len, int attr);
void msg_make(char_u *arg);
int msg_outtrans_special(char_u *strstart, int from, int maxlen);
! char_u *str2special_save(char_u *str, int is_lhs);
! char_u *str2special(char_u **sp, int from);
void str2specialbuf(char_u *sp, char_u *buf, int len);
void msg_prt_line(char_u *s, int list);
void msg_puts(char *s);
--- 37,44 ----
int msg_outtrans_len_attr(char_u *msgstr, int len, int attr);
void msg_make(char_u *arg);
int msg_outtrans_special(char_u *strstart, int from, int maxlen);
! char_u *str2special_save(char_u *str, int replace_spaces, int replace_lt);
! char_u *str2special(char_u **sp, int replace_spaces, int replace_lt);
void str2specialbuf(char_u *sp, char_u *buf, int len);
void msg_prt_line(char_u *s, int list);
void msg_puts(char *s);
*** ../vim-9.0.0448/src/testdir/test_functions.vim 2022-09-02 21:55:45.503049444 +0100
--- src/testdir/test_functions.vim 2022-09-12 13:28:33.443747653 +0100
***************
*** 2764,2769 ****
--- 2764,2795 ----
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('', test_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
*** ../vim-9.0.0448/src/version.c 2022-09-12 12:43:20.289108044 +0100
--- src/version.c 2022-09-12 13:34:23.159037194 +0100
***************
*** 705,706 ****
--- 705,708 ----
{ /* Add new patch number below this line */
+ /**/
+ 449,
/**/

--
hundred-and-one symptoms of being an internet addict:
49. You never have to deal with busy signals when calling your ISP...because
you never log off.

/// Bram Moolenaar -- Br...@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 ///
Reply all
Reply to author
Forward
0 new messages