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: #15667
Signed-off-by: Shougo Matsushita <Shougo.Matsu@gmail.com>
Signed-off-by: Christian Brabandt <cb@256bit.org>
diff --git a/runtime/doc/builtin.txt b/runtime/doc/builtin.txt
index af918d1..fe0b9aa 100644
--- a/runtime/doc/builtin.txt
+++ b/runtime/doc/builtin.txt
@@ -1,4 +1,4 @@
-*builtin.txt* For Vim version 9.1. Last change: 2024 Sep 10
+*builtin.txt* For Vim version 9.1. Last change: 2024 Sep 23
VIM REFERENCE MANUAL by Bram Moolenaar
@@ -232,8 +232,9 @@
getcharstr([{expr}]) String get one character from the user
getcmdcompltype() String return the type of the current
command-line completion
-getcmdline() String return the current command-line
+getcmdline() String return the current command-line input
getcmdpos() Number return cursor position in command-line
+getcmdprompt() String return the current command-line prompt
getcmdscreenpos() Number return cursor screen position in
command-line
getcmdtype() String return current command-line type
@@ -3978,21 +3979,21 @@
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 type: |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
- |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: >
: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()|.
@@ -4005,12 +4006,23 @@
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 type: |Number|
+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()|.
+
+ Return type: |String|
+
+
getcmdscreenpos() *getcmdscreenpos()*
Return the screen position of the cursor in the command line
as a byte count. The first column is 1.
diff --git a/runtime/doc/tags b/runtime/doc/tags
index dd5a0a6..fb6adf8 100644
--- a/runtime/doc/tags
+++ b/runtime/doc/tags
@@ -7827,6 +7827,7 @@
getcmdcompltype() builtin.txt /*getcmdcompltype()*
getcmdline() builtin.txt /*getcmdline()*
getcmdpos() builtin.txt /*getcmdpos()*
+getcmdprompt() builtin.txt /*getcmdprompt()*
getcmdscreenpos() builtin.txt /*getcmdscreenpos()*
getcmdtype() builtin.txt /*getcmdtype()*
getcmdwintype() builtin.txt /*getcmdwintype()*
diff --git a/runtime/doc/usr_41.txt b/runtime/doc/usr_41.txt
index 765eab5..27df85a 100644
--- a/runtime/doc/usr_41.txt
+++ b/runtime/doc/usr_41.txt
@@ -1,4 +1,4 @@
-*usr_41.txt* For Vim version 9.1. Last change: 2024 Jun 09
+*usr_41.txt* For Vim version 9.1. Last change: 2024 Sep 23
VIM USER MANUAL - by Bram Moolenaar
@@ -1070,7 +1070,8 @@
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
diff --git a/runtime/doc/version9.txt b/runtime/doc/version9.txt
index 9d22521..94e662d 100644
--- a/runtime/doc/version9.txt
+++ b/runtime/doc/version9.txt
@@ -41608,6 +41608,7 @@
|diff()| diff two Lists of strings
|filecopy()| copy a file {from} to {to}
|foreach()| apply function to List items
+|getcmdprompt()| get prompt for input()/confirm()
|getregion()| get a region of text from a buffer
|getregionpos()| get a list of positions for a region
|id()| get unique identifier for a Dict, List, Object,
diff --git a/src/evalfunc.c b/src/evalfunc.c
index 173b544..7c096a2 100644
--- a/src/evalfunc.c
+++ b/src/evalfunc.c
@@ -2097,6 +2097,8 @@
ret_string, f_getcmdline},
{"getcmdpos", 0, 0, 0, NULL,
ret_number, f_getcmdpos},
+ {"getcmdprompt", 0, 0, 0, NULL,
+ ret_string, f_getcmdprompt},
{"getcmdscreenpos", 0, 0, 0, NULL,
ret_number, f_getcmdscreenpos},
{"getcmdtype", 0, 0, 0, NULL,
@@ -3778,6 +3780,8 @@
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);
diff --git a/src/ex_getln.c b/src/ex_getln.c
index b4c7941..61f8379 100644
--- a/src/ex_getln.c
+++ b/src/ex_getln.c
@@ -30,6 +30,7 @@
#ifdef FEAT_EVAL
static int new_cmdpos; // position set by set_cmdline_pos()
+static char_u current_prompt[CMDBUFFSIZE + 1] = "";
#endif
static int extra_char = NUL; // extra character to display when redrawing
@@ -49,6 +50,9 @@
static void draw_cmdline(int start, int len);
static void save_cmdline(cmdline_info_T *ccp);
static void restore_cmdline(cmdline_info_T *ccp);
+#ifdef FEAT_EVAL
+static char_u *get_prompt(void);
+#endif
static int cmdline_paste(int regname, int literally, int remcr);
static void redrawcmdprompt(void);
static int ccheck_abbr(int);
@@ -4232,6 +4236,24 @@
}
/*
+ * Get current command line prompt.
+ */
+ static char_u *
+get_prompt(void)
+{
+ return current_prompt;
+}
+
+/*
+ * Set current command line prompt.
+ */
+ void
+set_prompt(char_u* str)
+{
+ vim_strncpy(current_prompt, str, sizeof(current_prompt) - 1);
+}
+
+/*
* "getcmdpos()" function
*/
void
@@ -4243,6 +4265,17 @@
}
/*
+ * "getcmdprompt()" function
+ */
+ void
+f_getcmdprompt(typval_T *argvars UNUSED, typval_T *rettv)
+{
+ cmdline_info_T *p = get_ccline_ptr();
+ rettv->v_type = VAR_STRING;
+ rettv->vval.v_string = p != NULL ? vim_strsave(get_prompt()) : NULL;
+}
+
+/*
* "getcmdscreenpos()" function
*/
void
@@ -4865,6 +4898,8 @@
cmd_silent = FALSE; // Want to see the prompt.
if (prompt != NULL)
{
+ set_prompt(prompt);
+
// Only the part of the message after the last NL is considered as
// prompt for the command line
p = vim_strrchr(prompt, '\n');
diff --git a/src/proto/ex_getln.pro b/src/proto/ex_getln.pro
index 956916d..8cf75b7 100644
--- a/src/proto/ex_getln.pro
+++ b/src/proto/ex_getln.pro
@@ -33,12 +33,14 @@
void f_getcmdcompltype(typval_T *argvars, typval_T *rettv);
void f_getcmdline(typval_T *argvars, typval_T *rettv);
void f_getcmdpos(typval_T *argvars, typval_T *rettv);
+void f_getcmdprompt(typval_T *argvars, typval_T *rettv);
void f_getcmdscreenpos(typval_T *argvars, typval_T *rettv);
void f_getcmdtype(typval_T *argvars, typval_T *rettv);
void f_setcmdline(typval_T *argvars, typval_T *rettv);
void f_setcmdpos(typval_T *argvars, typval_T *rettv);
int get_cmdline_firstc(void);
int get_list_range(char_u **str, int *num1, int *num2);
+void set_prompt(char_u* str);
char *did_set_cedit(optset_T *args);
int is_in_cmdwin(void);
char_u *script_get(exarg_T *eap, char_u *cmd);
diff --git a/src/testdir/test_cmdline.vim b/src/testdir/test_cmdline.vim
index 3f6918a..17717d2 100644
--- a/src/testdir/test_cmdline.vim
+++ b/src/testdir/test_cmdline.vim
@@ -1617,7 +1617,7 @@
set cpo&
-func Test_getcmdtype()
+func Test_getcmdtype_getcmdprompt()
call feedkeys(":MyCmd a\<C-R>=Check_cmdline(':')\<CR>\<Esc>", "xt")
let cmdtype = ''
@@ -1641,6 +1641,20 @@
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_verbosefile()
diff --git a/src/version.c b/src/version.c
index 4669e37..72e443a 100644
--- a/src/version.c
+++ b/src/version.c
@@ -705,6 +705,8 @@
static int included_patches[] =
{ /* Add new patch number below this line */
/**/
+ 741,
+/**/
740,
/**/
739,