vim-patch:8.2.2957: using getchar() in Vim9 script is problematic

Problem:    Using getchar() in Vim9 script is problematic.
Solution:   Add getcharstr(). (closes vim/vim#8343)
3a7503c34c

Cherry-pick Test_getchar() changes from patch v8.1.2304
to sync with upstream.

Port f_getcharstr() to src/nvim/eval/funcs.c, not src/nvim/getchar.c.
Patch v8.1.2042 is not ported yet.
This commit is contained in:
Jan Edmund Lazo 2021-06-07 20:21:21 -04:00
parent d628e4250f
commit 3865b43205
No known key found for this signature in database
GPG Key ID: 64915E6E9F735B15
4 changed files with 61 additions and 9 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

@ -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()