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}])
any variable {varname} in buffer {expr}
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
getcharsearch() Dict last character search
getcharstr([expr]) String get one character from the user
getcmdline() String return the current command-line
getcmdpos() Number return cursor position in command-line
getcmdtype() String return current command-line type
@ -4308,6 +4310,7 @@ getchar([expr]) *getchar()*
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()|.
Without [expr] and when [expr] is 0 a whole character or
special key is returned. If it is a single character, the
@ -4399,6 +4402,20 @@ getcharsearch() *getcharsearch()*
:nnoremap <expr> , getcharsearch().forward ? ',' : ';'
< 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()*
Return the current command-line. Only works when the command
line is being edited, thus requires use of |c_CTRL-\_e| or

View File

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

View File

@ -3028,10 +3028,9 @@ static void f_getchangelist(typval_T *argvars, typval_T *rettv, FunPtr fptr)
}
}
/*
* "getchar()" function
*/
static void f_getchar(typval_T *argvars, typval_T *rettv, FunPtr fptr)
// "getchar()" and "getcharstr()" functions
static void getchar_common(typval_T *argvars, typval_T *rettv)
FUNC_ATTR_NONNULL_ALL
{
varnumber_T n;
bool error = false;
@ -3098,6 +3097,7 @@ static void f_getchar(typval_T *argvars, typval_T *rettv, FunPtr fptr)
} else {
i += utf_char2bytes(n, temp + i);
}
assert(i < 10);
temp[i++] = NUL;
rettv->v_type = VAR_STRING;
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 col = mouse_col;
int grid = mouse_grid;
win_T *win;
linenr_T lnum;
win_T *wp;
int winnr = 1;
if (row >= 0 && col >= 0) {
/* Find the window at the mouse coordinates and compute the
* text position. */
win = mouse_find_win(&grid, &row, &col);
// Find the window at the mouse coordinates and compute the
// text position.
win_T *const win = mouse_find_win(&grid, &row, &col);
if (win == NULL) {
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
*/

View File

@ -6045,8 +6045,10 @@ static const char *highlight_init_both[] = {
"RedrawDebugClear ctermbg=Yellow guibg=Yellow",
"RedrawDebugComposed ctermbg=Green guibg=Green",
"RedrawDebugRecompose ctermbg=Red guibg=Red",
"Error term=reverse cterm=NONE ctermfg=White ctermbg=Red gui=NONE guifg=White guibg=Red",
"Todo term=standout cterm=NONE ctermfg=Black ctermbg=Yellow gui=NONE guifg=Blue guibg=Yellow",
"Error term=reverse cterm=NONE ctermfg=White ctermbg=Red gui=NONE "
"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 Character Constant",
"default link Number Constant",
@ -6104,15 +6106,24 @@ static const char *highlight_init_light[] = {
"Title ctermfg=DarkMagenta gui=bold guifg=Magenta",
"Visual guibg=LightGrey",
"WarningMsg ctermfg=DarkRed guifg=Red",
"Comment term=bold cterm=NONE ctermfg=DarkBlue ctermbg=NONE gui=NONE guifg=Blue guibg=NONE",
"Constant term=underline cterm=NONE ctermfg=DarkRed ctermbg=NONE gui=NONE guifg=Magenta guibg=NONE",
"Special term=bold cterm=NONE ctermfg=DarkMagenta ctermbg=NONE gui=NONE guifg=#6a5acd guibg=NONE",
"Identifier term=underline cterm=NONE ctermfg=DarkCyan ctermbg=NONE gui=NONE guifg=DarkCyan 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",
"Comment term=bold cterm=NONE ctermfg=DarkBlue ctermbg=NONE "
"gui=NONE guifg=Blue guibg=NONE",
"Constant term=underline cterm=NONE ctermfg=DarkRed ctermbg=NONE "
"gui=NONE guifg=Magenta guibg=NONE",
"Special term=bold cterm=NONE ctermfg=DarkMagenta ctermbg=NONE "
"gui=NONE guifg=#6a5acd guibg=NONE",
"Identifier term=underline cterm=NONE ctermfg=DarkCyan ctermbg=NONE "
"gui=NONE guifg=DarkCyan 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
};
@ -6146,15 +6157,24 @@ static const char *highlight_init_dark[] = {
"Title ctermfg=LightMagenta gui=bold guifg=Magenta",
"Visual guibg=DarkGrey",
"WarningMsg ctermfg=LightRed guifg=Red",
"Comment term=bold cterm=NONE ctermfg=Cyan ctermbg=NONE gui=NONE guifg=#80a0ff guibg=NONE",
"Constant term=underline cterm=NONE ctermfg=Magenta ctermbg=NONE gui=NONE guifg=#ffa0a0 guibg=NONE",
"Special term=bold cterm=NONE ctermfg=LightRed ctermbg=NONE gui=NONE guifg=Orange guibg=NONE",
"Identifier term=underline cterm=bold ctermfg=Cyan ctermbg=NONE gui=NONE guifg=#40ffff 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",
"Comment term=bold cterm=NONE ctermfg=Cyan ctermbg=NONE "
"gui=NONE guifg=#80a0ff guibg=NONE",
"Constant term=underline cterm=NONE ctermfg=Magenta ctermbg=NONE "
"gui=NONE guifg=#ffa0a0 guibg=NONE",
"Special term=bold cterm=NONE ctermfg=LightRed ctermbg=NONE "
"gui=NONE guifg=Orange guibg=NONE",
"Identifier term=underline cterm=bold ctermfg=Cyan ctermbg=NONE "
"gui=NONE guifg=#40ffff 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
};

View File

@ -1325,7 +1325,15 @@ endfunc
func Test_getchar()
call feedkeys('a', '')
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)
" let v:mouse_win = 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(1, v:mouse_lnum)
call assert_equal(3, v:mouse_col)
enew!
endfunc
func Test_libcall_libcallnr()