vim-patch:9.1.0741: No way to get prompt for input()/confirm()

Problem:  No way to get prompt for input()/confirm()
Solution: add getcmdprompt() function (Shougo Matsushita)
          (Shougo Matsushita)

closes: vim/vim#15667

6908428560

Co-authored-by: Shougo Matsushita <Shougo.Matsu@gmail.com>
This commit is contained in:
zeertzjq 2024-09-24 06:51:02 +08:00
parent 66197dde70
commit c2fb1fc700
7 changed files with 102 additions and 29 deletions

View File

@ -2361,18 +2361,18 @@ getcmdcompltype() *getcmdcompltype()*
Only works when the command line is being edited, thus
requires use of |c_CTRL-\_e| or |c_CTRL-R_=|.
See |:command-completion| for the return string.
Also see |getcmdtype()|, |setcmdpos()|, |getcmdline()| and
|setcmdline()|.
Also see |getcmdtype()|, |setcmdpos()|, |getcmdline()|,
|getcmdprompt()| and |setcmdline()|.
Returns an empty string when completion is not defined.
getcmdline() *getcmdline()*
Return the current command-line. Only works when the command
line is being edited, thus requires use of |c_CTRL-\_e| or
|c_CTRL-R_=|.
Return the current command-line input. Only works when the
command line is being edited, thus requires use of
|c_CTRL-\_e| or |c_CTRL-R_=|.
Example: >vim
cmap <F7> <C-\>eescape(getcmdline(), ' \')<CR>
< Also see |getcmdtype()|, |getcmdpos()|, |setcmdpos()| and
|setcmdline()|.
< Also see |getcmdtype()|, |getcmdpos()|, |setcmdpos()|,
|getcmdprompt()| and |setcmdline()|.
Returns an empty string when entering a password or using
|inputsecret()|.
@ -2382,8 +2382,16 @@ getcmdpos() *getcmdpos()*
Only works when editing the command line, thus requires use of
|c_CTRL-\_e| or |c_CTRL-R_=| or an expression mapping.
Returns 0 otherwise.
Also see |getcmdtype()|, |setcmdpos()|, |getcmdline()| and
|setcmdline()|.
Also see |getcmdtype()|, |setcmdpos()|, |getcmdline()|,
|getcmdprompt()| and |setcmdline()|.
getcmdprompt() *getcmdprompt()*
Return the current command-line prompt when using functions
like |input()| or |confirm()|.
Only works when the command line is being edited, thus
requires use of |c_CTRL-\_e| or |c_CTRL-R_=|.
Also see |getcmdtype()|, |getcmdline()|, |getcmdpos()|,
|setcmdpos()| and |setcmdline()|.
getcmdscreenpos() *getcmdscreenpos()*
Return the screen position of the cursor in the command line

View File

@ -908,7 +908,8 @@ Buffers, windows and the argument list:
Command line: *command-line-functions*
getcmdcompltype() get the type of the current command line
completion
getcmdline() get the current command line
getcmdline() get the current command line input
getcmdprompt() get the current command line prompt
getcmdpos() get position of the cursor in the command line
getcmdscreenpos() get screen position of the cursor in the
command line

View File

@ -2883,20 +2883,20 @@ function vim.fn.getcharstr(expr) end
--- Only works when the command line is being edited, thus
--- requires use of |c_CTRL-\_e| or |c_CTRL-R_=|.
--- See |:command-completion| for the return string.
--- Also see |getcmdtype()|, |setcmdpos()|, |getcmdline()| and
--- |setcmdline()|.
--- Also see |getcmdtype()|, |setcmdpos()|, |getcmdline()|,
--- |getcmdprompt()| and |setcmdline()|.
--- Returns an empty string when completion is not defined.
---
--- @return string
function vim.fn.getcmdcompltype() end
--- Return the current command-line. Only works when the command
--- line is being edited, thus requires use of |c_CTRL-\_e| or
--- |c_CTRL-R_=|.
--- Return the current command-line input. Only works when the
--- command line is being edited, thus requires use of
--- |c_CTRL-\_e| or |c_CTRL-R_=|.
--- Example: >vim
--- cmap <F7> <C-\>eescape(getcmdline(), ' \')<CR>
--- <Also see |getcmdtype()|, |getcmdpos()|, |setcmdpos()| and
--- |setcmdline()|.
--- <Also see |getcmdtype()|, |getcmdpos()|, |setcmdpos()|,
--- |getcmdprompt()| and |setcmdline()|.
--- Returns an empty string when entering a password or using
--- |inputsecret()|.
---
@ -2908,12 +2908,22 @@ function vim.fn.getcmdline() end
--- Only works when editing the command line, thus requires use of
--- |c_CTRL-\_e| or |c_CTRL-R_=| or an expression mapping.
--- Returns 0 otherwise.
--- Also see |getcmdtype()|, |setcmdpos()|, |getcmdline()| and
--- |setcmdline()|.
--- Also see |getcmdtype()|, |setcmdpos()|, |getcmdline()|,
--- |getcmdprompt()| and |setcmdline()|.
---
--- @return integer
function vim.fn.getcmdpos() end
--- Return the current command-line prompt when using functions
--- like |input()| or |confirm()|.
--- Only works when the command line is being edited, thus
--- requires use of |c_CTRL-\_e| or |c_CTRL-R_=|.
--- Also see |getcmdtype()|, |getcmdline()|, |getcmdpos()|,
--- |setcmdpos()| and |setcmdline()|.
---
--- @return string
function vim.fn.getcmdprompt() end
--- Return the screen position of the cursor in the command line
--- as a byte count. The first column is 1.
--- Instead of |getcmdpos()|, it adds the prompt position.

View File

@ -3594,8 +3594,8 @@ M.funcs = {
Only works when the command line is being edited, thus
requires use of |c_CTRL-\_e| or |c_CTRL-R_=|.
See |:command-completion| for the return string.
Also see |getcmdtype()|, |setcmdpos()|, |getcmdline()| and
|setcmdline()|.
Also see |getcmdtype()|, |setcmdpos()|, |getcmdline()|,
|getcmdprompt()| and |setcmdline()|.
Returns an empty string when completion is not defined.
]=],
name = 'getcmdcompltype',
@ -3605,13 +3605,13 @@ M.funcs = {
},
getcmdline = {
desc = [=[
Return the current command-line. Only works when the command
line is being edited, thus requires use of |c_CTRL-\_e| or
|c_CTRL-R_=|.
Return the current command-line input. Only works when the
command line is being edited, thus requires use of
|c_CTRL-\_e| or |c_CTRL-R_=|.
Example: >vim
cmap <F7> <C-\>eescape(getcmdline(), ' \')<CR>
<Also see |getcmdtype()|, |getcmdpos()|, |setcmdpos()| and
|setcmdline()|.
<Also see |getcmdtype()|, |getcmdpos()|, |setcmdpos()|,
|getcmdprompt()| and |setcmdline()|.
Returns an empty string when entering a password or using
|inputsecret()|.
]=],
@ -3627,14 +3627,28 @@ M.funcs = {
Only works when editing the command line, thus requires use of
|c_CTRL-\_e| or |c_CTRL-R_=| or an expression mapping.
Returns 0 otherwise.
Also see |getcmdtype()|, |setcmdpos()|, |getcmdline()| and
|setcmdline()|.
Also see |getcmdtype()|, |setcmdpos()|, |getcmdline()|,
|getcmdprompt()| and |setcmdline()|.
]=],
name = 'getcmdpos',
params = {},
returns = 'integer',
signature = 'getcmdpos()',
},
getcmdprompt = {
desc = [=[
Return the current command-line prompt when using functions
like |input()| or |confirm()|.
Only works when the command line is being edited, thus
requires use of |c_CTRL-\_e| or |c_CTRL-R_=|.
Also see |getcmdtype()|, |getcmdline()|, |getcmdpos()|,
|setcmdpos()| and |setcmdline()|.
]=],
name = 'getcmdprompt',
params = {},
returns = 'string',
signature = 'getcmdprompt()',
},
getcmdscreenpos = {
desc = [=[
Return the screen position of the cursor in the command line

View File

@ -813,6 +813,8 @@ static void f_confirm(typval_T *argvars, typval_T *rettv, EvalFuncData fptr)
const char *message = tv_get_string_chk(&argvars[0]);
if (message == NULL) {
error = true;
} else {
set_prompt(message);
}
if (argvars[1].v_type != VAR_UNKNOWN) {
buttons = tv_get_string_buf_chk(&argvars[1], buf);

View File

@ -4132,6 +4132,28 @@ void f_getcmdpos(typval_T *argvars, typval_T *rettv, EvalFuncData fptr)
rettv->vval.v_number = p != NULL ? p->cmdpos + 1 : 0;
}
static char current_prompt[CMDBUFFSIZE + 1] = "";
/// Get current command line prompt.
static char *get_prompt(void)
{
return current_prompt;
}
/// Set current command line prompt.
void set_prompt(const char *str)
{
xstrlcpy(current_prompt, str, sizeof(current_prompt));
}
/// "getcmdprompt()" function
void f_getcmdprompt(typval_T *argvars, typval_T *rettv, EvalFuncData fptr)
{
CmdlineInfo *p = get_ccline_ptr();
rettv->v_type = VAR_STRING;
rettv->vval.v_string = p != NULL ? xstrdup(get_prompt()) : NULL;
}
/// "getcmdscreenpos()" function
void f_getcmdscreenpos(typval_T *argvars, typval_T *rettv, EvalFuncData fptr)
{
@ -4730,6 +4752,8 @@ void get_user_input(const typval_T *const argvars, typval_T *const rettv, const
const bool cmd_silent_save = cmd_silent;
cmd_silent = false; // Want to see the prompt.
set_prompt(prompt);
// Only the part of the message after the last NL is considered as
// prompt for the command line, unlsess cmdline is externalized
const char *p = prompt;

View File

@ -1534,7 +1534,7 @@ endfunc
set cpo&
func Test_getcmdtype()
func Test_getcmdtype_getcmdprompt()
call feedkeys(":MyCmd a\<C-R>=Check_cmdline(':')\<CR>\<Esc>", "xt")
let cmdtype = ''
@ -1558,6 +1558,20 @@ func Test_getcmdtype()
cunmap <F6>
call assert_equal('', getcmdline())
call assert_equal('', getcmdprompt())
augroup test_CmdlineEnter
autocmd!
autocmd CmdlineEnter * let g:cmdprompt=getcmdprompt()
augroup END
call feedkeys(":call input('Answer?')\<CR>a\<CR>\<ESC>", "xt")
call assert_equal('Answer?', g:cmdprompt)
call assert_equal('', getcmdprompt())
augroup test_CmdlineEnter
au!
augroup END
augroup! test_CmdlineEnter
endfunc
func Test_getcmdwintype()