Merge pull request #14744 from janlazo/vim-8.2.2957

vim-patch:8.2.2957: using getchar() in Vim9 script is problematic
This commit is contained in:
Jan Edmund Lazo 2021-07-30 09:01:35 -04:00 committed by GitHub
commit 74a38c03c0
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 101 additions and 29 deletions

View File

@ -2203,9 +2203,11 @@ getbufline({expr}, {lnum} [, {end}])
getbufvar({expr}, {varname} [, {def}]) getbufvar({expr}, {varname} [, {def}])
any variable {varname} in buffer {expr} any variable {varname} in buffer {expr}
getchangelist({expr}) List list of change list items getchangelist({expr}) List list of change list items
getchar([expr]) Number get one character from the user getchar([expr]) Number or String
get one character from the user
getcharmod() Number modifiers for the last typed character getcharmod() Number modifiers for the last typed character
getcharsearch() Dict last character search getcharsearch() Dict last character search
getcharstr([expr]) String get one character from the user
getcmdline() String return the current command-line getcmdline() String return the current command-line
getcmdpos() Number return cursor position in command-line getcmdpos() Number return cursor position in command-line
getcmdtype() String return current command-line type getcmdtype() String return current command-line type
@ -4308,6 +4310,7 @@ getchar([expr]) *getchar()*
Return zero otherwise. Return zero otherwise.
If [expr] is 1, only check if a character is available, it is If [expr] is 1, only check if a character is available, it is
not consumed. Return zero if no character available. not consumed. Return zero if no character available.
If you prefer always getting a string use |getcharstr()|.
Without [expr] and when [expr] is 0 a whole character or Without [expr] and when [expr] is 0 a whole character or
special key is returned. If it is a single character, the special key is returned. If it is a single character, the
@ -4399,6 +4402,20 @@ getcharsearch() *getcharsearch()*
:nnoremap <expr> , getcharsearch().forward ? ',' : ';' :nnoremap <expr> , getcharsearch().forward ? ',' : ';'
< Also see |setcharsearch()|. < Also see |setcharsearch()|.
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.
getcmdline() *getcmdline()* getcmdline() *getcmdline()*
Return the current command-line. Only works when the command Return the current command-line. Only works when the command
line is being edited, thus requires use of |c_CTRL-\_e| or line is being edited, thus requires use of |c_CTRL-\_e| or

View File

@ -136,6 +136,7 @@ return {
getchar={args={0, 1}}, getchar={args={0, 1}},
getcharmod={}, getcharmod={},
getcharsearch={}, getcharsearch={},
getcharstr={args={0, 1}},
getcmdline={}, getcmdline={},
getcmdpos={}, getcmdpos={},
getcmdtype={}, getcmdtype={},

View File

@ -3028,10 +3028,9 @@ static void f_getchangelist(typval_T *argvars, typval_T *rettv, FunPtr fptr)
} }
} }
/* // "getchar()" and "getcharstr()" functions
* "getchar()" function static void getchar_common(typval_T *argvars, typval_T *rettv)
*/ FUNC_ATTR_NONNULL_ALL
static void f_getchar(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{ {
varnumber_T n; varnumber_T n;
bool error = false; bool error = false;
@ -3098,6 +3097,7 @@ static void f_getchar(typval_T *argvars, typval_T *rettv, FunPtr fptr)
} else { } else {
i += utf_char2bytes(n, temp + i); i += utf_char2bytes(n, temp + i);
} }
assert(i < 10);
temp[i++] = NUL; temp[i++] = NUL;
rettv->v_type = VAR_STRING; rettv->v_type = VAR_STRING;
rettv->vval.v_string = vim_strsave(temp); rettv->vval.v_string = vim_strsave(temp);
@ -3106,15 +3106,14 @@ static void f_getchar(typval_T *argvars, typval_T *rettv, FunPtr fptr)
int row = mouse_row; int row = mouse_row;
int col = mouse_col; int col = mouse_col;
int grid = mouse_grid; int grid = mouse_grid;
win_T *win;
linenr_T lnum; linenr_T lnum;
win_T *wp; win_T *wp;
int winnr = 1; int winnr = 1;
if (row >= 0 && col >= 0) { if (row >= 0 && col >= 0) {
/* Find the window at the mouse coordinates and compute the // Find the window at the mouse coordinates and compute the
* text position. */ // text position.
win = mouse_find_win(&grid, &row, &col); win_T *const win = mouse_find_win(&grid, &row, &col);
if (win == NULL) { if (win == NULL) {
return; return;
} }
@ -3130,6 +3129,32 @@ static void f_getchar(typval_T *argvars, typval_T *rettv, FunPtr fptr)
} }
} }
// "getchar()" function
static void f_getchar(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
getchar_common(argvars, rettv);
}
// "getcharstr()" function
static void f_getcharstr(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
getchar_common(argvars, rettv);
if (rettv->v_type == VAR_NUMBER) {
char_u temp[7]; // mbyte-char: 6, NUL: 1
const varnumber_T n = rettv->vval.v_number;
int i = 0;
if (n != 0) {
i += utf_char2bytes(n, temp);
}
assert(i < 7);
temp[i++] = NUL;
rettv->v_type = VAR_STRING;
rettv->vval.v_string = vim_strsave(temp);
}
}
/* /*
* "getcharmod()" function * "getcharmod()" function
*/ */

View File

@ -6045,8 +6045,10 @@ static const char *highlight_init_both[] = {
"RedrawDebugClear ctermbg=Yellow guibg=Yellow", "RedrawDebugClear ctermbg=Yellow guibg=Yellow",
"RedrawDebugComposed ctermbg=Green guibg=Green", "RedrawDebugComposed ctermbg=Green guibg=Green",
"RedrawDebugRecompose ctermbg=Red guibg=Red", "RedrawDebugRecompose ctermbg=Red guibg=Red",
"Error term=reverse cterm=NONE ctermfg=White ctermbg=Red gui=NONE guifg=White guibg=Red", "Error term=reverse cterm=NONE ctermfg=White ctermbg=Red gui=NONE "
"Todo term=standout cterm=NONE ctermfg=Black ctermbg=Yellow gui=NONE guifg=Blue guibg=Yellow", "guifg=White guibg=Red",
"Todo term=standout cterm=NONE ctermfg=Black ctermbg=Yellow gui=NONE "
"guifg=Blue guibg=Yellow",
"default link String Constant", "default link String Constant",
"default link Character Constant", "default link Character Constant",
"default link Number Constant", "default link Number Constant",
@ -6104,15 +6106,24 @@ static const char *highlight_init_light[] = {
"Title ctermfg=DarkMagenta gui=bold guifg=Magenta", "Title ctermfg=DarkMagenta gui=bold guifg=Magenta",
"Visual guibg=LightGrey", "Visual guibg=LightGrey",
"WarningMsg ctermfg=DarkRed guifg=Red", "WarningMsg ctermfg=DarkRed guifg=Red",
"Comment term=bold cterm=NONE ctermfg=DarkBlue ctermbg=NONE gui=NONE guifg=Blue guibg=NONE", "Comment term=bold cterm=NONE ctermfg=DarkBlue ctermbg=NONE "
"Constant term=underline cterm=NONE ctermfg=DarkRed ctermbg=NONE gui=NONE guifg=Magenta guibg=NONE", "gui=NONE guifg=Blue guibg=NONE",
"Special term=bold cterm=NONE ctermfg=DarkMagenta ctermbg=NONE gui=NONE guifg=#6a5acd guibg=NONE", "Constant term=underline cterm=NONE ctermfg=DarkRed ctermbg=NONE "
"Identifier term=underline cterm=NONE ctermfg=DarkCyan ctermbg=NONE gui=NONE guifg=DarkCyan guibg=NONE", "gui=NONE guifg=Magenta guibg=NONE",
"Statement term=bold cterm=NONE ctermfg=Brown ctermbg=NONE gui=bold guifg=Brown guibg=NONE", "Special term=bold cterm=NONE ctermfg=DarkMagenta ctermbg=NONE "
"PreProc term=underline cterm=NONE ctermfg=DarkMagenta ctermbg=NONE gui=NONE guifg=#6a0dad guibg=NONE", "gui=NONE guifg=#6a5acd guibg=NONE",
"Type term=underline cterm=NONE ctermfg=DarkGreen ctermbg=NONE gui=bold guifg=SeaGreen guibg=NONE", "Identifier term=underline cterm=NONE ctermfg=DarkCyan ctermbg=NONE "
"Underlined term=underline cterm=underline ctermfg=DarkMagenta gui=underline guifg=SlateBlue", "gui=NONE guifg=DarkCyan guibg=NONE",
"Ignore term=NONE cterm=NONE ctermfg=white ctermbg=NONE gui=NONE guifg=bg guibg=NONE", "Statement term=bold cterm=NONE ctermfg=Brown ctermbg=NONE "
"gui=bold guifg=Brown guibg=NONE",
"PreProc term=underline cterm=NONE ctermfg=DarkMagenta ctermbg=NONE "
"gui=NONE guifg=#6a0dad guibg=NONE",
"Type term=underline cterm=NONE ctermfg=DarkGreen ctermbg=NONE "
"gui=bold guifg=SeaGreen guibg=NONE",
"Underlined term=underline cterm=underline ctermfg=DarkMagenta "
"gui=underline guifg=SlateBlue",
"Ignore term=NONE cterm=NONE ctermfg=white ctermbg=NONE "
"gui=NONE guifg=bg guibg=NONE",
NULL NULL
}; };
@ -6146,15 +6157,24 @@ static const char *highlight_init_dark[] = {
"Title ctermfg=LightMagenta gui=bold guifg=Magenta", "Title ctermfg=LightMagenta gui=bold guifg=Magenta",
"Visual guibg=DarkGrey", "Visual guibg=DarkGrey",
"WarningMsg ctermfg=LightRed guifg=Red", "WarningMsg ctermfg=LightRed guifg=Red",
"Comment term=bold cterm=NONE ctermfg=Cyan ctermbg=NONE gui=NONE guifg=#80a0ff guibg=NONE", "Comment term=bold cterm=NONE ctermfg=Cyan ctermbg=NONE "
"Constant term=underline cterm=NONE ctermfg=Magenta ctermbg=NONE gui=NONE guifg=#ffa0a0 guibg=NONE", "gui=NONE guifg=#80a0ff guibg=NONE",
"Special term=bold cterm=NONE ctermfg=LightRed ctermbg=NONE gui=NONE guifg=Orange guibg=NONE", "Constant term=underline cterm=NONE ctermfg=Magenta ctermbg=NONE "
"Identifier term=underline cterm=bold ctermfg=Cyan ctermbg=NONE gui=NONE guifg=#40ffff guibg=NONE", "gui=NONE guifg=#ffa0a0 guibg=NONE",
"Statement term=bold cterm=NONE ctermfg=Yellow ctermbg=NONE gui=bold guifg=#ffff60 guibg=NONE", "Special term=bold cterm=NONE ctermfg=LightRed ctermbg=NONE "
"PreProc term=underline cterm=NONE ctermfg=LightBlue ctermbg=NONE gui=NONE guifg=#ff80ff guibg=NONE", "gui=NONE guifg=Orange guibg=NONE",
"Type term=underline cterm=NONE ctermfg=LightGreen ctermbg=NONE gui=bold guifg=#60ff60 guibg=NONE", "Identifier term=underline cterm=bold ctermfg=Cyan ctermbg=NONE "
"Underlined term=underline cterm=underline ctermfg=LightBlue gui=underline guifg=#80a0ff", "gui=NONE guifg=#40ffff guibg=NONE",
"Ignore term=NONE cterm=NONE ctermfg=black ctermbg=NONE gui=NONE guifg=bg guibg=NONE", "Statement term=bold cterm=NONE ctermfg=Yellow ctermbg=NONE "
"gui=bold guifg=#ffff60 guibg=NONE",
"PreProc term=underline cterm=NONE ctermfg=LightBlue ctermbg=NONE "
"gui=NONE guifg=#ff80ff guibg=NONE",
"Type term=underline cterm=NONE ctermfg=LightGreen ctermbg=NONE "
"gui=bold guifg=#60ff60 guibg=NONE",
"Underlined term=underline cterm=underline ctermfg=LightBlue "
"gui=underline guifg=#80a0ff",
"Ignore term=NONE cterm=NONE ctermfg=black ctermbg=NONE "
"gui=NONE guifg=bg guibg=NONE",
NULL NULL
}; };

View File

@ -1325,7 +1325,15 @@ endfunc
func Test_getchar() func Test_getchar()
call feedkeys('a', '') call feedkeys('a', '')
call assert_equal(char2nr('a'), getchar()) call assert_equal(char2nr('a'), getchar())
call assert_equal(0, getchar(0))
call assert_equal(0, getchar(1))
call feedkeys('a', '')
call assert_equal('a', getcharstr())
call assert_equal('', getcharstr(0))
call assert_equal('', getcharstr(1))
call setline(1, 'xxxx')
" call test_setmouse(1, 3) " call test_setmouse(1, 3)
" let v:mouse_win = 9 " let v:mouse_win = 9
" let v:mouse_winid = 9 " let v:mouse_winid = 9
@ -1338,6 +1346,7 @@ func Test_getchar()
call assert_equal(win_getid(1), v:mouse_winid) call assert_equal(win_getid(1), v:mouse_winid)
call assert_equal(1, v:mouse_lnum) call assert_equal(1, v:mouse_lnum)
call assert_equal(3, v:mouse_col) call assert_equal(3, v:mouse_col)
enew!
endfunc endfunc
func Test_libcall_libcallnr() func Test_libcall_libcallnr()