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

View File

@ -2883,20 +2883,20 @@ function vim.fn.getcharstr(expr) end
--- Only works when the command line is being edited, thus --- Only works when the command line is being edited, thus
--- requires use of |c_CTRL-\_e| or |c_CTRL-R_=|. --- requires use of |c_CTRL-\_e| or |c_CTRL-R_=|.
--- See |:command-completion| for the return string. --- See |:command-completion| for the return string.
--- Also see |getcmdtype()|, |setcmdpos()|, |getcmdline()| and --- Also see |getcmdtype()|, |setcmdpos()|, |getcmdline()|,
--- |setcmdline()|. --- |getcmdprompt()| and |setcmdline()|.
--- Returns an empty string when completion is not defined. --- Returns an empty string when completion is not defined.
--- ---
--- @return string --- @return string
function vim.fn.getcmdcompltype() end function vim.fn.getcmdcompltype() end
--- Return the current command-line. Only works when the command --- Return the current command-line input. Only works when the
--- line is being edited, thus requires use of |c_CTRL-\_e| or --- command line is being edited, thus requires use of
--- |c_CTRL-R_=|. --- |c_CTRL-\_e| or |c_CTRL-R_=|.
--- Example: >vim --- Example: >vim
--- cmap <F7> <C-\>eescape(getcmdline(), ' \')<CR> --- cmap <F7> <C-\>eescape(getcmdline(), ' \')<CR>
--- <Also see |getcmdtype()|, |getcmdpos()|, |setcmdpos()| and --- <Also see |getcmdtype()|, |getcmdpos()|, |setcmdpos()|,
--- |setcmdline()|. --- |getcmdprompt()| and |setcmdline()|.
--- Returns an empty string when entering a password or using --- Returns an empty string when entering a password or using
--- |inputsecret()|. --- |inputsecret()|.
--- ---
@ -2908,12 +2908,22 @@ function vim.fn.getcmdline() end
--- Only works when editing the command line, thus requires use of --- Only works when editing the command line, thus requires use of
--- |c_CTRL-\_e| or |c_CTRL-R_=| or an expression mapping. --- |c_CTRL-\_e| or |c_CTRL-R_=| or an expression mapping.
--- Returns 0 otherwise. --- Returns 0 otherwise.
--- Also see |getcmdtype()|, |setcmdpos()|, |getcmdline()| and --- Also see |getcmdtype()|, |setcmdpos()|, |getcmdline()|,
--- |setcmdline()|. --- |getcmdprompt()| and |setcmdline()|.
--- ---
--- @return integer --- @return integer
function vim.fn.getcmdpos() end 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 --- Return the screen position of the cursor in the command line
--- as a byte count. The first column is 1. --- as a byte count. The first column is 1.
--- Instead of |getcmdpos()|, it adds the prompt position. --- 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 Only works when the command line is being edited, thus
requires use of |c_CTRL-\_e| or |c_CTRL-R_=|. requires use of |c_CTRL-\_e| or |c_CTRL-R_=|.
See |:command-completion| for the return string. See |:command-completion| for the return string.
Also see |getcmdtype()|, |setcmdpos()|, |getcmdline()| and Also see |getcmdtype()|, |setcmdpos()|, |getcmdline()|,
|setcmdline()|. |getcmdprompt()| and |setcmdline()|.
Returns an empty string when completion is not defined. Returns an empty string when completion is not defined.
]=], ]=],
name = 'getcmdcompltype', name = 'getcmdcompltype',
@ -3605,13 +3605,13 @@ M.funcs = {
}, },
getcmdline = { getcmdline = {
desc = [=[ desc = [=[
Return the current command-line. Only works when the command Return the current command-line input. Only works when the
line is being edited, thus requires use of |c_CTRL-\_e| or command line is being edited, thus requires use of
|c_CTRL-R_=|. |c_CTRL-\_e| or |c_CTRL-R_=|.
Example: >vim Example: >vim
cmap <F7> <C-\>eescape(getcmdline(), ' \')<CR> cmap <F7> <C-\>eescape(getcmdline(), ' \')<CR>
<Also see |getcmdtype()|, |getcmdpos()|, |setcmdpos()| and <Also see |getcmdtype()|, |getcmdpos()|, |setcmdpos()|,
|setcmdline()|. |getcmdprompt()| and |setcmdline()|.
Returns an empty string when entering a password or using Returns an empty string when entering a password or using
|inputsecret()|. |inputsecret()|.
]=], ]=],
@ -3627,14 +3627,28 @@ M.funcs = {
Only works when editing the command line, thus requires use of Only works when editing the command line, thus requires use of
|c_CTRL-\_e| or |c_CTRL-R_=| or an expression mapping. |c_CTRL-\_e| or |c_CTRL-R_=| or an expression mapping.
Returns 0 otherwise. Returns 0 otherwise.
Also see |getcmdtype()|, |setcmdpos()|, |getcmdline()| and Also see |getcmdtype()|, |setcmdpos()|, |getcmdline()|,
|setcmdline()|. |getcmdprompt()| and |setcmdline()|.
]=], ]=],
name = 'getcmdpos', name = 'getcmdpos',
params = {}, params = {},
returns = 'integer', returns = 'integer',
signature = 'getcmdpos()', 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 = { getcmdscreenpos = {
desc = [=[ desc = [=[
Return the screen position of the cursor in the command line 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]); const char *message = tv_get_string_chk(&argvars[0]);
if (message == NULL) { if (message == NULL) {
error = true; error = true;
} else {
set_prompt(message);
} }
if (argvars[1].v_type != VAR_UNKNOWN) { if (argvars[1].v_type != VAR_UNKNOWN) {
buttons = tv_get_string_buf_chk(&argvars[1], buf); 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; 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 /// "getcmdscreenpos()" function
void f_getcmdscreenpos(typval_T *argvars, typval_T *rettv, EvalFuncData fptr) 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; const bool cmd_silent_save = cmd_silent;
cmd_silent = false; // Want to see the prompt. cmd_silent = false; // Want to see the prompt.
set_prompt(prompt);
// Only the part of the message after the last NL is considered as // Only the part of the message after the last NL is considered as
// prompt for the command line, unlsess cmdline is externalized // prompt for the command line, unlsess cmdline is externalized
const char *p = prompt; const char *p = prompt;

View File

@ -1534,7 +1534,7 @@ endfunc
set cpo& set cpo&
func Test_getcmdtype() func Test_getcmdtype_getcmdprompt()
call feedkeys(":MyCmd a\<C-R>=Check_cmdline(':')\<CR>\<Esc>", "xt") call feedkeys(":MyCmd a\<C-R>=Check_cmdline(':')\<CR>\<Esc>", "xt")
let cmdtype = '' let cmdtype = ''
@ -1558,6 +1558,20 @@ func Test_getcmdtype()
cunmap <F6> cunmap <F6>
call assert_equal('', getcmdline()) 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 endfunc
func Test_getcmdwintype() func Test_getcmdwintype()