mirror of
https://github.com/neovim/neovim
synced 2025-07-16 01:01:49 +00:00
vim-patch:9.1.1068: getchar() can't distinguish between C-I and Tab (#32295)
Problem: getchar() can't distinguish between C-I and Tab.
Solution: Add {opts} to pass extra flags to getchar() and getcharstr(),
with "number" and "simplify" keys.
related: vim/vim#10603
closes: vim/vim#16554
e0a2ab397f
Cherry-pick tv_dict_has_key() from patch 8.2.4683.
This commit is contained in:
49
runtime/doc/builtin.txt
generated
49
runtime/doc/builtin.txt
generated
@ -3079,14 +3079,16 @@ getchangelist([{buf}]) *getchangelist()*
|
||||
Return: ~
|
||||
(`table[]`)
|
||||
|
||||
getchar([{expr}]) *getchar()*
|
||||
getchar([{expr} [, {opts}]]) *getchar()*
|
||||
Get a single character from the user or input stream.
|
||||
If {expr} is omitted, wait until a character is available.
|
||||
If {expr} is omitted or is -1, wait until a character is
|
||||
available.
|
||||
If {expr} is 0, only get a character when one is available.
|
||||
Return zero otherwise.
|
||||
If {expr} is 1, only check if a character is available, it is
|
||||
not consumed. Return zero if no character available.
|
||||
If you prefer always getting a string use |getcharstr()|.
|
||||
If you prefer always getting a string use |getcharstr()|, or
|
||||
specify |FALSE| as "number" in {opts}.
|
||||
|
||||
Without {expr} and when {expr} is 0 a whole character or
|
||||
special key is returned. If it is a single character, the
|
||||
@ -3096,7 +3098,8 @@ getchar([{expr}]) *getchar()*
|
||||
starting with 0x80 (decimal: 128). This is the same value as
|
||||
the String "\<Key>", e.g., "\<Left>". The returned value is
|
||||
also a String when a modifier (shift, control, alt) was used
|
||||
that is not included in the character.
|
||||
that is not included in the character. |keytrans()| can also
|
||||
be used to convert a returned String into a readable form.
|
||||
|
||||
When {expr} is 0 and Esc is typed, there will be a short delay
|
||||
while Vim waits to see if this is the start of an escape
|
||||
@ -3108,6 +3111,24 @@ getchar([{expr}]) *getchar()*
|
||||
|
||||
Use getcharmod() to obtain any additional modifiers.
|
||||
|
||||
The optional argument {opts} is a Dict and supports the
|
||||
following items:
|
||||
|
||||
number If |TRUE|, return a Number when getting
|
||||
a single character.
|
||||
If |FALSE|, the return value is always
|
||||
converted to a String, and an empty
|
||||
String (instead of 0) is returned when
|
||||
no character is available.
|
||||
(default: |TRUE|)
|
||||
|
||||
simplify If |TRUE|, include modifiers in the
|
||||
character if possible. E.g., return
|
||||
the same value for CTRL-I and <Tab>.
|
||||
If |FALSE|, don't include modifiers in
|
||||
the character.
|
||||
(default: |TRUE|)
|
||||
|
||||
When the user clicks a mouse button, the mouse event will be
|
||||
returned. The position can then be found in |v:mouse_col|,
|
||||
|v:mouse_lnum|, |v:mouse_winid| and |v:mouse_win|.
|
||||
@ -3145,10 +3166,11 @@ getchar([{expr}]) *getchar()*
|
||||
<
|
||||
|
||||
Parameters: ~
|
||||
• {expr} (`0|1?`)
|
||||
• {expr} (`-1|0|1?`)
|
||||
• {opts} (`table?`)
|
||||
|
||||
Return: ~
|
||||
(`integer`)
|
||||
(`integer|string`)
|
||||
|
||||
getcharmod() *getcharmod()*
|
||||
The result is a Number which is the state of the modifiers for
|
||||
@ -3213,19 +3235,12 @@ getcharsearch() *getcharsearch()*
|
||||
(`table`)
|
||||
|
||||
getcharstr([{expr}]) *getcharstr()*
|
||||
Get a single character from the user or input stream as a
|
||||
string.
|
||||
If {expr} is omitted, wait until a character is available.
|
||||
If {expr} is 0 or false, only get a character when one is
|
||||
available. Return an empty string otherwise.
|
||||
If {expr} is 1 or true, only check if a character is
|
||||
available, it is not consumed. Return an empty string
|
||||
if no character is available.
|
||||
Otherwise this works like |getchar()|, except that a number
|
||||
result is converted to a string.
|
||||
The same as |getchar()|, except that this always returns a
|
||||
String, and "number" isn't allowed in {opts}.
|
||||
|
||||
Parameters: ~
|
||||
• {expr} (`0|1?`)
|
||||
• {expr} (`-1|0|1?`)
|
||||
• {opts} (`table?`)
|
||||
|
||||
Return: ~
|
||||
(`string`)
|
||||
|
51
runtime/lua/vim/_meta/vimfn.lua
generated
51
runtime/lua/vim/_meta/vimfn.lua
generated
@ -2748,12 +2748,14 @@ function vim.fn.getcellwidths() end
|
||||
function vim.fn.getchangelist(buf) end
|
||||
|
||||
--- Get a single character from the user or input stream.
|
||||
--- If {expr} is omitted, wait until a character is available.
|
||||
--- If {expr} is omitted or is -1, wait until a character is
|
||||
--- available.
|
||||
--- If {expr} is 0, only get a character when one is available.
|
||||
--- Return zero otherwise.
|
||||
--- If {expr} is 1, only check if a character is available, it is
|
||||
--- not consumed. Return zero if no character available.
|
||||
--- If you prefer always getting a string use |getcharstr()|.
|
||||
--- If you prefer always getting a string use |getcharstr()|, or
|
||||
--- specify |FALSE| as "number" in {opts}.
|
||||
---
|
||||
--- Without {expr} and when {expr} is 0 a whole character or
|
||||
--- special key is returned. If it is a single character, the
|
||||
@ -2763,7 +2765,8 @@ function vim.fn.getchangelist(buf) end
|
||||
--- starting with 0x80 (decimal: 128). This is the same value as
|
||||
--- the String "\<Key>", e.g., "\<Left>". The returned value is
|
||||
--- also a String when a modifier (shift, control, alt) was used
|
||||
--- that is not included in the character.
|
||||
--- that is not included in the character. |keytrans()| can also
|
||||
--- be used to convert a returned String into a readable form.
|
||||
---
|
||||
--- When {expr} is 0 and Esc is typed, there will be a short delay
|
||||
--- while Vim waits to see if this is the start of an escape
|
||||
@ -2775,6 +2778,24 @@ function vim.fn.getchangelist(buf) end
|
||||
---
|
||||
--- Use getcharmod() to obtain any additional modifiers.
|
||||
---
|
||||
--- The optional argument {opts} is a Dict and supports the
|
||||
--- following items:
|
||||
---
|
||||
--- number If |TRUE|, return a Number when getting
|
||||
--- a single character.
|
||||
--- If |FALSE|, the return value is always
|
||||
--- converted to a String, and an empty
|
||||
--- String (instead of 0) is returned when
|
||||
--- no character is available.
|
||||
--- (default: |TRUE|)
|
||||
---
|
||||
--- simplify If |TRUE|, include modifiers in the
|
||||
--- character if possible. E.g., return
|
||||
--- the same value for CTRL-I and <Tab>.
|
||||
--- If |FALSE|, don't include modifiers in
|
||||
--- the character.
|
||||
--- (default: |TRUE|)
|
||||
---
|
||||
--- When the user clicks a mouse button, the mouse event will be
|
||||
--- returned. The position can then be found in |v:mouse_col|,
|
||||
--- |v:mouse_lnum|, |v:mouse_winid| and |v:mouse_win|.
|
||||
@ -2811,9 +2832,10 @@ function vim.fn.getchangelist(buf) end
|
||||
--- endfunction
|
||||
--- <
|
||||
---
|
||||
--- @param expr? 0|1
|
||||
--- @return integer
|
||||
function vim.fn.getchar(expr) end
|
||||
--- @param expr? -1|0|1
|
||||
--- @param opts? table
|
||||
--- @return integer|string
|
||||
function vim.fn.getchar(expr, opts) end
|
||||
|
||||
--- The result is a Number which is the state of the modifiers for
|
||||
--- the last obtained character with getchar() or in another way.
|
||||
@ -2872,20 +2894,13 @@ function vim.fn.getcharpos(expr) end
|
||||
--- @return table
|
||||
function vim.fn.getcharsearch() end
|
||||
|
||||
--- Get a single character from the user or input stream as a
|
||||
--- string.
|
||||
--- If {expr} is omitted, wait until a character is available.
|
||||
--- If {expr} is 0 or false, only get a character when one is
|
||||
--- available. Return an empty string otherwise.
|
||||
--- If {expr} is 1 or true, only check if a character is
|
||||
--- available, it is not consumed. Return an empty string
|
||||
--- if no character is available.
|
||||
--- Otherwise this works like |getchar()|, except that a number
|
||||
--- result is converted to a string.
|
||||
--- The same as |getchar()|, except that this always returns a
|
||||
--- String, and "number" isn't allowed in {opts}.
|
||||
---
|
||||
--- @param expr? 0|1
|
||||
--- @param expr? -1|0|1
|
||||
--- @param opts? table
|
||||
--- @return string
|
||||
function vim.fn.getcharstr(expr) end
|
||||
function vim.fn.getcharstr(expr, opts) end
|
||||
|
||||
--- Return completion pattern of the current command-line.
|
||||
--- Only works when the command line is being edited, thus
|
||||
|
@ -3471,15 +3471,17 @@ M.funcs = {
|
||||
signature = 'getchangelist([{buf}])',
|
||||
},
|
||||
getchar = {
|
||||
args = { 0, 1 },
|
||||
args = { 0, 2 },
|
||||
desc = [=[
|
||||
Get a single character from the user or input stream.
|
||||
If {expr} is omitted, wait until a character is available.
|
||||
If {expr} is omitted or is -1, wait until a character is
|
||||
available.
|
||||
If {expr} is 0, only get a character when one is available.
|
||||
Return zero otherwise.
|
||||
If {expr} is 1, only check if a character is available, it is
|
||||
not consumed. Return zero if no character available.
|
||||
If you prefer always getting a string use |getcharstr()|.
|
||||
If you prefer always getting a string use |getcharstr()|, or
|
||||
specify |FALSE| as "number" in {opts}.
|
||||
|
||||
Without {expr} and when {expr} is 0 a whole character or
|
||||
special key is returned. If it is a single character, the
|
||||
@ -3489,7 +3491,8 @@ M.funcs = {
|
||||
starting with 0x80 (decimal: 128). This is the same value as
|
||||
the String "\<Key>", e.g., "\<Left>". The returned value is
|
||||
also a String when a modifier (shift, control, alt) was used
|
||||
that is not included in the character.
|
||||
that is not included in the character. |keytrans()| can also
|
||||
be used to convert a returned String into a readable form.
|
||||
|
||||
When {expr} is 0 and Esc is typed, there will be a short delay
|
||||
while Vim waits to see if this is the start of an escape
|
||||
@ -3501,6 +3504,24 @@ M.funcs = {
|
||||
|
||||
Use getcharmod() to obtain any additional modifiers.
|
||||
|
||||
The optional argument {opts} is a Dict and supports the
|
||||
following items:
|
||||
|
||||
number If |TRUE|, return a Number when getting
|
||||
a single character.
|
||||
If |FALSE|, the return value is always
|
||||
converted to a String, and an empty
|
||||
String (instead of 0) is returned when
|
||||
no character is available.
|
||||
(default: |TRUE|)
|
||||
|
||||
simplify If |TRUE|, include modifiers in the
|
||||
character if possible. E.g., return
|
||||
the same value for CTRL-I and <Tab>.
|
||||
If |FALSE|, don't include modifiers in
|
||||
the character.
|
||||
(default: |TRUE|)
|
||||
|
||||
When the user clicks a mouse button, the mouse event will be
|
||||
returned. The position can then be found in |v:mouse_col|,
|
||||
|v:mouse_lnum|, |v:mouse_winid| and |v:mouse_win|.
|
||||
@ -3538,9 +3559,9 @@ M.funcs = {
|
||||
<
|
||||
]=],
|
||||
name = 'getchar',
|
||||
params = { { 'expr', '0|1' } },
|
||||
returns = 'integer',
|
||||
signature = 'getchar([{expr}])',
|
||||
params = { { 'expr', '-1|0|1' }, { 'opts', 'table' } },
|
||||
returns = 'integer|string',
|
||||
signature = 'getchar([{expr} [, {opts}]])',
|
||||
},
|
||||
getcharmod = {
|
||||
desc = [=[
|
||||
@ -3613,21 +3634,13 @@ M.funcs = {
|
||||
signature = 'getcharsearch()',
|
||||
},
|
||||
getcharstr = {
|
||||
args = { 0, 1 },
|
||||
args = { 0, 2 },
|
||||
desc = [=[
|
||||
Get a single character from the user or input stream as a
|
||||
string.
|
||||
If {expr} is omitted, wait until a character is available.
|
||||
If {expr} is 0 or false, only get a character when one is
|
||||
available. Return an empty string otherwise.
|
||||
If {expr} is 1 or true, only check if a character is
|
||||
available, it is not consumed. Return an empty string
|
||||
if no character is available.
|
||||
Otherwise this works like |getchar()|, except that a number
|
||||
result is converted to a string.
|
||||
The same as |getchar()|, except that this always returns a
|
||||
String, and "number" isn't allowed in {opts}.
|
||||
]=],
|
||||
name = 'getcharstr',
|
||||
params = { { 'expr', '0|1' } },
|
||||
params = { { 'expr', '-1|0|1' }, { 'opts', 'table' } },
|
||||
returns = 'string',
|
||||
signature = 'getcharstr([{expr}])',
|
||||
},
|
||||
|
@ -2234,6 +2234,18 @@ dictitem_T *tv_dict_find(const dict_T *const d, const char *const key, const ptr
|
||||
return TV_DICT_HI2DI(hi);
|
||||
}
|
||||
|
||||
/// Check if a key is present in a dictionary.
|
||||
///
|
||||
/// @param[in] d Dictionary to check.
|
||||
/// @param[in] key Dictionary key.
|
||||
///
|
||||
/// @return whether the key is present in the dictionary.
|
||||
bool tv_dict_has_key(const dict_T *const d, const char *const key)
|
||||
FUNC_ATTR_NONNULL_ARG(2) FUNC_ATTR_PURE FUNC_ATTR_WARN_UNUSED_RESULT
|
||||
{
|
||||
return tv_dict_find(d, key, -1) != NULL;
|
||||
}
|
||||
|
||||
/// Get a typval item from a dictionary and copy it into "rettv".
|
||||
///
|
||||
/// @param[in] d Dictionary to check.
|
||||
|
@ -1866,22 +1866,47 @@ bool char_avail(void)
|
||||
return retval != NUL;
|
||||
}
|
||||
|
||||
static int no_reduce_keys = 0; ///< Do not apply modifiers to the key.
|
||||
|
||||
/// "getchar()" and "getcharstr()" functions
|
||||
static void getchar_common(typval_T *argvars, typval_T *rettv)
|
||||
static void getchar_common(typval_T *argvars, typval_T *rettv, bool allow_number)
|
||||
FUNC_ATTR_NONNULL_ALL
|
||||
{
|
||||
varnumber_T n;
|
||||
bool error = false;
|
||||
bool simplify = true;
|
||||
|
||||
if (argvars[0].v_type != VAR_UNKNOWN
|
||||
&& tv_check_for_opt_dict_arg(argvars, 1) == FAIL) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (argvars[0].v_type != VAR_UNKNOWN && argvars[1].v_type == VAR_DICT) {
|
||||
dict_T *d = argvars[1].vval.v_dict;
|
||||
|
||||
if (allow_number) {
|
||||
allow_number = tv_dict_get_bool(d, "number", true);
|
||||
} else if (tv_dict_has_key(d, "number")) {
|
||||
semsg(_(e_invarg2), "number");
|
||||
error = true;
|
||||
}
|
||||
|
||||
simplify = tv_dict_get_bool(d, "simplify", true);
|
||||
}
|
||||
|
||||
no_mapping++;
|
||||
allow_keys++;
|
||||
while (true) {
|
||||
if (!simplify) {
|
||||
no_reduce_keys++;
|
||||
}
|
||||
while (!error) {
|
||||
if (msg_col > 0) {
|
||||
// Position the cursor. Needed after a message that ends in a space.
|
||||
ui_cursor_goto(msg_row, msg_col);
|
||||
}
|
||||
|
||||
if (argvars[0].v_type == VAR_UNKNOWN) {
|
||||
if (argvars[0].v_type == VAR_UNKNOWN
|
||||
|| (argvars[0].v_type == VAR_NUMBER && argvars[0].vval.v_number == -1)) {
|
||||
// getchar(): blocking wait.
|
||||
// TODO(bfredl): deduplicate shared logic with state_enter ?
|
||||
if (!char_avail()) {
|
||||
@ -1916,14 +1941,16 @@ static void getchar_common(typval_T *argvars, typval_T *rettv)
|
||||
}
|
||||
no_mapping--;
|
||||
allow_keys--;
|
||||
if (!simplify) {
|
||||
no_reduce_keys--;
|
||||
}
|
||||
|
||||
set_vim_var_nr(VV_MOUSE_WIN, 0);
|
||||
set_vim_var_nr(VV_MOUSE_WINID, 0);
|
||||
set_vim_var_nr(VV_MOUSE_LNUM, 0);
|
||||
set_vim_var_nr(VV_MOUSE_COL, 0);
|
||||
|
||||
rettv->vval.v_number = n;
|
||||
if (n != 0 && (IS_SPECIAL(n) || mod_mask != 0)) {
|
||||
if (n != 0 && (!allow_number || IS_SPECIAL(n) || mod_mask != 0)) {
|
||||
char temp[10]; // modifier: 3, mbyte-char: 6, NUL: 1
|
||||
int i = 0;
|
||||
|
||||
@ -1970,35 +1997,23 @@ static void getchar_common(typval_T *argvars, typval_T *rettv)
|
||||
set_vim_var_nr(VV_MOUSE_COL, col + 1);
|
||||
}
|
||||
}
|
||||
} else if (!allow_number) {
|
||||
rettv->v_type = VAR_STRING;
|
||||
} else {
|
||||
rettv->vval.v_number = n;
|
||||
}
|
||||
}
|
||||
|
||||
/// "getchar()" function
|
||||
void f_getchar(typval_T *argvars, typval_T *rettv, EvalFuncData fptr)
|
||||
{
|
||||
getchar_common(argvars, rettv);
|
||||
getchar_common(argvars, rettv, true);
|
||||
}
|
||||
|
||||
/// "getcharstr()" function
|
||||
void f_getcharstr(typval_T *argvars, typval_T *rettv, EvalFuncData fptr)
|
||||
{
|
||||
getchar_common(argvars, rettv);
|
||||
|
||||
if (rettv->v_type != VAR_NUMBER) {
|
||||
return;
|
||||
}
|
||||
|
||||
char temp[7]; // mbyte-char: 6, NUL: 1
|
||||
const varnumber_T n = rettv->vval.v_number;
|
||||
int i = 0;
|
||||
|
||||
if (n != 0) {
|
||||
i += utf_char2bytes((int)n, temp);
|
||||
}
|
||||
assert(i < 7);
|
||||
temp[i] = NUL;
|
||||
rettv->v_type = VAR_STRING;
|
||||
rettv->vval.v_string = xmemdupz(temp, (size_t)i);
|
||||
getchar_common(argvars, rettv, false);
|
||||
}
|
||||
|
||||
/// "getcharmod()" function
|
||||
@ -2058,7 +2073,7 @@ static int check_simplify_modifier(int max_offset)
|
||||
{
|
||||
// We want full modifiers in Terminal mode so that the key can be correctly
|
||||
// encoded
|
||||
if (State & MODE_TERMINAL) {
|
||||
if ((State & MODE_TERMINAL) || no_reduce_keys > 0) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -557,7 +557,7 @@ describe('terminal input', function()
|
||||
'--cmd',
|
||||
'set notermguicolors',
|
||||
'-c',
|
||||
'while 1 | redraw | echo keytrans(getcharstr()) | endwhile',
|
||||
'while 1 | redraw | echo keytrans(getcharstr(-1, #{simplify: 0})) | endwhile',
|
||||
})
|
||||
screen:expect([[
|
||||
^ |
|
||||
@ -566,7 +566,10 @@ describe('terminal input', function()
|
||||
|
|
||||
{3:-- TERMINAL --} |
|
||||
]])
|
||||
for _, key in ipairs({
|
||||
local keys = {
|
||||
'<Tab>',
|
||||
'<CR>',
|
||||
'<Esc>',
|
||||
'<M-Tab>',
|
||||
'<M-CR>',
|
||||
'<M-Esc>',
|
||||
@ -632,7 +635,14 @@ describe('terminal input', function()
|
||||
'<S-ScrollWheelRight>',
|
||||
'<ScrollWheelLeft>',
|
||||
'<ScrollWheelRight>',
|
||||
}) do
|
||||
}
|
||||
-- FIXME: The escape sequence to enable kitty keyboard mode doesn't work on Windows
|
||||
if not is_os('win') then
|
||||
table.insert(keys, '<C-I>')
|
||||
table.insert(keys, '<C-M>')
|
||||
table.insert(keys, '<C-[>')
|
||||
end
|
||||
for _, key in ipairs(keys) do
|
||||
feed(key)
|
||||
screen:expect(([[
|
||||
|
|
||||
@ -643,82 +653,6 @@ describe('terminal input', function()
|
||||
]]):format(key:gsub('<%d+,%d+>$', '')))
|
||||
end
|
||||
end)
|
||||
|
||||
-- TODO(bfredl): getcharstr() erases the distinction between <C-I> and <Tab>.
|
||||
-- If it was enhanced or replaced this could get folded into the test above.
|
||||
it('can send TAB/C-I and ESC/C-[ separately', function()
|
||||
if
|
||||
skip(
|
||||
is_os('win'),
|
||||
"The escape sequence to enable kitty keyboard mode doesn't work on Windows"
|
||||
)
|
||||
then
|
||||
return
|
||||
end
|
||||
clear()
|
||||
local screen = tt.setup_child_nvim({
|
||||
'-u',
|
||||
'NONE',
|
||||
'-i',
|
||||
'NONE',
|
||||
'--cmd',
|
||||
'colorscheme vim',
|
||||
'--cmd',
|
||||
'set notermguicolors',
|
||||
'--cmd',
|
||||
'noremap <Tab> <cmd>echo "Tab!"<cr>',
|
||||
'--cmd',
|
||||
'noremap <C-i> <cmd>echo "Ctrl-I!"<cr>',
|
||||
'--cmd',
|
||||
'noremap <Esc> <cmd>echo "Esc!"<cr>',
|
||||
'--cmd',
|
||||
'noremap <C-[> <cmd>echo "Ctrl-[!"<cr>',
|
||||
})
|
||||
|
||||
screen:expect([[
|
||||
^ |
|
||||
{4:~ }|*3
|
||||
{5:[No Name] 0,0-1 All}|
|
||||
|
|
||||
{3:-- TERMINAL --} |
|
||||
]])
|
||||
|
||||
feed('<tab>')
|
||||
screen:expect([[
|
||||
^ |
|
||||
{4:~ }|*3
|
||||
{5:[No Name] 0,0-1 All}|
|
||||
Tab! |
|
||||
{3:-- TERMINAL --} |
|
||||
]])
|
||||
|
||||
feed('<c-i>')
|
||||
screen:expect([[
|
||||
^ |
|
||||
{4:~ }|*3
|
||||
{5:[No Name] 0,0-1 All}|
|
||||
Ctrl-I! |
|
||||
{3:-- TERMINAL --} |
|
||||
]])
|
||||
|
||||
feed('<Esc>')
|
||||
screen:expect([[
|
||||
^ |
|
||||
{4:~ }|*3
|
||||
{5:[No Name] 0,0-1 All}|
|
||||
Esc! |
|
||||
{3:-- TERMINAL --} |
|
||||
]])
|
||||
|
||||
feed('<c-[>')
|
||||
screen:expect([[
|
||||
^ |
|
||||
{4:~ }|*3
|
||||
{5:[No Name] 0,0-1 All}|
|
||||
Ctrl-[! |
|
||||
{3:-- TERMINAL --} |
|
||||
]])
|
||||
end)
|
||||
end)
|
||||
|
||||
if is_os('win') then
|
||||
|
@ -2390,6 +2390,77 @@ func Test_getchar()
|
||||
call assert_equal("\<M-F2>", getchar(0))
|
||||
call assert_equal(0, getchar(0))
|
||||
|
||||
call feedkeys("\<Tab>", '')
|
||||
call assert_equal(char2nr("\<Tab>"), getchar())
|
||||
call feedkeys("\<Tab>", '')
|
||||
call assert_equal(char2nr("\<Tab>"), getchar(-1))
|
||||
call feedkeys("\<Tab>", '')
|
||||
call assert_equal(char2nr("\<Tab>"), getchar(-1, {}))
|
||||
call feedkeys("\<Tab>", '')
|
||||
call assert_equal(char2nr("\<Tab>"), getchar(-1, #{number: v:true}))
|
||||
call assert_equal(0, getchar(0))
|
||||
call assert_equal(0, getchar(1))
|
||||
call assert_equal(0, getchar(0, #{number: v:true}))
|
||||
call assert_equal(0, getchar(1, #{number: v:true}))
|
||||
|
||||
call feedkeys("\<Tab>", '')
|
||||
call assert_equal("\<Tab>", getcharstr())
|
||||
call feedkeys("\<Tab>", '')
|
||||
call assert_equal("\<Tab>", getcharstr(-1))
|
||||
call feedkeys("\<Tab>", '')
|
||||
call assert_equal("\<Tab>", getcharstr(-1, {}))
|
||||
call feedkeys("\<Tab>", '')
|
||||
call assert_equal("\<Tab>", getchar(-1, #{number: v:false}))
|
||||
call assert_equal('', getcharstr(0))
|
||||
call assert_equal('', getcharstr(1))
|
||||
call assert_equal('', getchar(0, #{number: v:false}))
|
||||
call assert_equal('', getchar(1, #{number: v:false}))
|
||||
|
||||
" Nvim: <M-x> is never simplified
|
||||
" for key in ["C-I", "C-X", "M-x"]
|
||||
for key in ["C-I", "C-X"]
|
||||
let lines =<< eval trim END
|
||||
call feedkeys("\<*{key}>", '')
|
||||
call assert_equal(char2nr("\<{key}>"), getchar())
|
||||
call feedkeys("\<*{key}>", '')
|
||||
call assert_equal(char2nr("\<{key}>"), getchar(-1))
|
||||
call feedkeys("\<*{key}>", '')
|
||||
call assert_equal(char2nr("\<{key}>"), getchar(-1, {{}}))
|
||||
call feedkeys("\<*{key}>", '')
|
||||
call assert_equal(char2nr("\<{key}>"), getchar(-1, {{'number': 1}}))
|
||||
call feedkeys("\<*{key}>", '')
|
||||
call assert_equal(char2nr("\<{key}>"), getchar(-1, {{'simplify': 1}}))
|
||||
call feedkeys("\<*{key}>", '')
|
||||
call assert_equal("\<*{key}>", getchar(-1, {{'simplify': v:false}}))
|
||||
call assert_equal(0, getchar(0))
|
||||
call assert_equal(0, getchar(1))
|
||||
END
|
||||
call CheckLegacyAndVim9Success(lines)
|
||||
|
||||
let lines =<< eval trim END
|
||||
call feedkeys("\<*{key}>", '')
|
||||
call assert_equal("\<{key}>", getcharstr())
|
||||
call feedkeys("\<*{key}>", '')
|
||||
call assert_equal("\<{key}>", getcharstr(-1))
|
||||
call feedkeys("\<*{key}>", '')
|
||||
call assert_equal("\<{key}>", getcharstr(-1, {{}}))
|
||||
call feedkeys("\<*{key}>", '')
|
||||
call assert_equal("\<{key}>", getchar(-1, {{'number': 0}}))
|
||||
call feedkeys("\<*{key}>", '')
|
||||
call assert_equal("\<{key}>", getcharstr(-1, {{'simplify': 1}}))
|
||||
call feedkeys("\<*{key}>", '')
|
||||
call assert_equal("\<*{key}>", getcharstr(-1, {{'simplify': v:false}}))
|
||||
call assert_equal('', getcharstr(0))
|
||||
call assert_equal('', getcharstr(1))
|
||||
END
|
||||
call CheckLegacyAndVim9Success(lines)
|
||||
endfor
|
||||
|
||||
call assert_fails('call getchar(1, 1)', 'E1206:')
|
||||
call assert_fails('call getcharstr(1, 1)', 'E1206:')
|
||||
call assert_fails('call getcharstr(1, #{number: v:true})', 'E475:')
|
||||
call assert_fails('call getcharstr(1, #{number: v:false})', 'E475:')
|
||||
|
||||
call setline(1, 'xxxx')
|
||||
call Ntest_setmouse(1, 3)
|
||||
let v:mouse_win = 9
|
||||
|
Reference in New Issue
Block a user