summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorShougo Matsushita <Shougo.Matsu@gmail.com>2022-05-07 12:48:29 +0100
committerBram Moolenaar <Bram@vim.org>2022-05-07 12:48:29 +0100
commit79d599b8772022af1d657f368c2fc97aa342c0da (patch)
treeee415de85697c73717db8ca0679481349d097965
parentc27747e6ddcbda7d1d3b39867898f746dc4db471 (diff)
patch 8.2.4903: cannot get the current cmdline completion type and positionv8.2.4903
Problem: Cannot get the current cmdline completion type and position. Solution: Add getcmdcompltype() and getcmdscreenpos(). (Shougo Matsushita, closes #10344)
-rw-r--r--runtime/doc/builtin.txt20
-rw-r--r--runtime/doc/usr_41.txt4
-rw-r--r--src/cmdexpand.c3
-rw-r--r--src/evalfunc.c4
-rw-r--r--src/ex_getln.c58
-rw-r--r--src/proto/cmdexpand.pro1
-rw-r--r--src/proto/ex_getln.pro2
-rw-r--r--src/proto/usercmd.pro3
-rw-r--r--src/testdir/test_cmdline.vim12
-rw-r--r--src/usercmd.c19
-rw-r--r--src/version.c2
11 files changed, 125 insertions, 3 deletions
diff --git a/runtime/doc/builtin.txt b/runtime/doc/builtin.txt
index 12fb509a78..acd0f5caa3 100644
--- a/runtime/doc/builtin.txt
+++ b/runtime/doc/builtin.txt
@@ -213,8 +213,12 @@ getcharmod() Number modifiers for the last typed character
getcharpos({expr}) List position of cursor, mark, etc.
getcharsearch() Dict last character search
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
getcmdpos() Number return cursor position in command-line
+getcmdscreenpos() Number return cursor screen position in
+ command-line
getcmdtype() String return current command-line type
getcmdwintype() String return current command-line window type
getcompletion({pat}, {type} [, {filtered}])
@@ -3208,6 +3212,13 @@ getcharstr([expr]) *getcharstr()*
Otherwise this works like |getchar()|, except that a number
result is converted to a string.
+getcmdcompltype() *getcmdcompltype()*
+ Return the type of the current command-line completion.
+ 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()| and |getcmdline()|.
+ Returns an empty string when completion is not defined.
getcmdline() *getcmdline()*
Return the current command-line. Only works when the command
@@ -3227,6 +3238,15 @@ getcmdpos() *getcmdpos()*
Returns 0 otherwise.
Also see |getcmdtype()|, |setcmdpos()| and |getcmdline()|.
+getcmdscreenpos() *getcmdscreenpos()*
+ 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.
+ 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 |getcmdpos()|, |setcmdpos()|.
+
getcmdtype() *getcmdtype()*
Return the current command-line type. Possible return values
are:
diff --git a/runtime/doc/usr_41.txt b/runtime/doc/usr_41.txt
index a9a1fcd883..1102f7e1a0 100644
--- a/runtime/doc/usr_41.txt
+++ b/runtime/doc/usr_41.txt
@@ -976,8 +976,12 @@ Buffers, windows and the argument list:
swapname() get the swap file path of a buffer
Command line: *command-line-functions*
+ getcmdcompltype() get the type of the current command line
+ completion
getcmdline() get the current command line
getcmdpos() get position of the cursor in the command line
+ getcmdscreenpos() get screen position of the cursor in the
+ command line
setcmdpos() set position of the cursor in the command line
getcmdtype() return the current command-line type
getcmdwintype() return the current command-line window type
diff --git a/src/cmdexpand.c b/src/cmdexpand.c
index 87953375d5..ea8dbfa14d 100644
--- a/src/cmdexpand.c
+++ b/src/cmdexpand.c
@@ -15,7 +15,6 @@
static int cmd_showtail; // Only show path tail in lists ?
-static void set_expand_context(expand_T *xp);
static int ExpandGeneric(char_u *pat, expand_T *xp, regmatch_T *regmatch,
char_u ***matches, int *numMatches,
char_u *((*func)(expand_T *, int)), int escaped);
@@ -1230,7 +1229,7 @@ addstar(
* EXPAND_ENV_VARS Complete environment variable names
* EXPAND_USER Complete user names
*/
- static void
+ void
set_expand_context(expand_T *xp)
{
cmdline_info_T *ccline = get_cmdline_info();
diff --git a/src/evalfunc.c b/src/evalfunc.c
index 55041b945f..219751ba13 100644
--- a/src/evalfunc.c
+++ b/src/evalfunc.c
@@ -1850,10 +1850,14 @@ static funcentry_T global_functions[] =
ret_dict_any, f_getcharsearch},
{"getcharstr", 0, 1, 0, arg1_bool,
ret_string, f_getcharstr},
+ {"getcmdcompltype", 0, 0, 0, NULL,
+ ret_string, f_getcmdcompltype},
{"getcmdline", 0, 0, 0, NULL,
ret_string, f_getcmdline},
{"getcmdpos", 0, 0, 0, NULL,
ret_number, f_getcmdpos},
+ {"getcmdscreenpos", 0, 0, 0, NULL,
+ ret_number, f_getcmdscreenpos},
{"getcmdtype", 0, 0, 0, NULL,
ret_string, f_getcmdtype},
{"getcmdwintype", 0, 0, 0, NULL,
diff --git a/src/ex_getln.c b/src/ex_getln.c
index 7020f5143a..09f2842833 100644
--- a/src/ex_getln.c
+++ b/src/ex_getln.c
@@ -4119,6 +4119,42 @@ get_cmdline_str(void)
}
/*
+ * Get the current command-line completion type.
+ */
+ static char_u *
+get_cmdline_completion(void)
+{
+ cmdline_info_T *p;
+
+ if (cmdline_star > 0)
+ return NULL;
+
+ p = get_ccline_ptr();
+ if (p && p->xpc != NULL)
+ {
+ char_u *cmd_compl;
+
+ set_expand_context(p->xpc);
+
+ cmd_compl = cmdcomplete_type_to_str(p->xpc->xp_context);
+ if (cmd_compl != NULL)
+ return vim_strnsave(cmd_compl, strlen((char *)cmd_compl));
+ }
+
+ return NULL;
+}
+
+/*
+ * "getcmdcompltype()" function
+ */
+ void
+f_getcmdcompltype(typval_T *argvars UNUSED, typval_T *rettv)
+{
+ rettv->v_type = VAR_STRING;
+ rettv->vval.v_string = get_cmdline_completion();
+}
+
+/*
* "getcmdline()" function
*/
void
@@ -4142,6 +4178,28 @@ f_getcmdpos(typval_T *argvars UNUSED, typval_T *rettv)
}
/*
+ * Get the command line cursor screen position.
+ */
+ static int
+get_cmdline_screen_pos(void)
+{
+ cmdline_info_T *p = get_ccline_ptr();
+
+ if (p == NULL)
+ return -1;
+ return p->cmdspos;
+}
+
+/*
+ * "getcmdscreenpos()" function
+ */
+ void
+f_getcmdscreenpos(typval_T *argvars UNUSED, typval_T *rettv)
+{
+ rettv->vval.v_number = get_cmdline_screen_pos() + 1;
+}
+
+/*
* Set the command line byte position to "pos". Zero is the first position.
* Only works when the command line is being edited.
* Returns 1 when failed, 0 when OK.
diff --git a/src/proto/cmdexpand.pro b/src/proto/cmdexpand.pro
index 5ffab8c545..924b0b4529 100644
--- a/src/proto/cmdexpand.pro
+++ b/src/proto/cmdexpand.pro
@@ -13,6 +13,7 @@ int showmatches(expand_T *xp, int wildmenu);
char_u *sm_gettail(char_u *s);
char_u *addstar(char_u *fname, int len, int context);
void set_cmd_context(expand_T *xp, char_u *str, int len, int col, int use_ccline);
+void set_expand_context(expand_T *xp);
int expand_cmdline(expand_T *xp, char_u *str, int col, int *matchcount, char_u ***matches);
void globpath(char_u *path, char_u *file, garray_T *ga, int expand_options);
int wildmenu_translate_key(cmdline_info_T *cclp, int key, expand_T *xp, int did_wild_list);
diff --git a/src/proto/ex_getln.pro b/src/proto/ex_getln.pro
index f97719b756..374b0a1770 100644
--- a/src/proto/ex_getln.pro
+++ b/src/proto/ex_getln.pro
@@ -30,9 +30,11 @@ char_u *vim_strsave_fnameescape(char_u *fname, int what);
void escape_fname(char_u **pp);
void tilde_replace(char_u *orig_pat, int num_files, char_u **files);
cmdline_info_T *get_cmdline_info(void);
+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_setcmdpos(typval_T *argvars, typval_T *rettv);
+void f_getcmdscreenpos(typval_T *argvars, typval_T *rettv);
void f_getcmdtype(typval_T *argvars, typval_T *rettv);
int get_cmdline_firstc(void);
int get_list_range(char_u **str, int *num1, int *num2);
diff --git a/src/proto/usercmd.pro b/src/proto/usercmd.pro
index c3ac79cecf..47ef6f097a 100644
--- a/src/proto/usercmd.pro
+++ b/src/proto/usercmd.pro
@@ -1,7 +1,7 @@
/* usercmd.c */
char_u *find_ucmd(exarg_T *eap, char_u *p, int *full, expand_T *xp, int *complp);
-char_u *set_context_in_user_cmdarg(char_u *cmd, char_u *arg, long argt, int context, expand_T *xp, int forceit);
char_u *set_context_in_user_cmd(expand_T *xp, char_u *arg_in);
+char_u *set_context_in_user_cmdarg(char_u *cmd, char_u *arg, long argt, int context, expand_T *xp, int forceit);
char_u *expand_user_command_name(int idx);
char_u *get_user_commands(expand_T *xp, int idx);
char_u *get_user_command_name(int idx, int cmdidx);
@@ -9,6 +9,7 @@ char_u *get_user_cmd_addr_type(expand_T *xp, int idx);
char_u *get_user_cmd_flags(expand_T *xp, int idx);
char_u *get_user_cmd_nargs(expand_T *xp, int idx);
char_u *get_user_cmd_complete(expand_T *xp, int idx);
+char_u *cmdcomplete_type_to_str(int expand);
int cmdcomplete_str_to_type(char_u *complete_str);
char *uc_fun_cmd(void);
int parse_compl_arg(char_u *value, int vallen, int *complp, long *argt, char_u **compl_arg);
diff --git a/src/testdir/test_cmdline.vim b/src/testdir/test_cmdline.vim
index 5a849f77f7..e944f8d24d 100644
--- a/src/testdir/test_cmdline.vim
+++ b/src/testdir/test_cmdline.vim
@@ -3380,4 +3380,16 @@ func Test_cmdline_complete_substitute_short()
endfor
endfunc
+func Check_completion()
+ call assert_equal('let a', getcmdline())
+ call assert_equal(6, getcmdpos())
+ call assert_equal(7, getcmdscreenpos())
+ call assert_equal('var', getcmdcompltype())
+ return ''
+endfunc
+
+func Test_screenpos_and_completion()
+ call feedkeys(":let a\<C-R>=Check_completion()\<CR>\<Esc>", "xt")
+endfunc
+
" vim: shiftwidth=2 sts=2 expandtab
diff --git a/src/usercmd.c b/src/usercmd.c
index 0e9d712e31..e73f6f64fb 100644
--- a/src/usercmd.c
+++ b/src/usercmd.c
@@ -443,6 +443,25 @@ get_user_cmd_complete(expand_T *xp UNUSED, int idx)
}
#ifdef FEAT_EVAL
+/*
+ * Get the name of completion type "expand" as a string.
+ */
+ char_u *
+cmdcomplete_type_to_str(int expand)
+{
+ int i;
+
+ for (i = 0; command_complete[i].expand != 0; i++)
+ if (command_complete[i].expand == expand)
+ return (char_u *)command_complete[i].name;
+
+ return NULL;
+}
+
+/*
+ * Get the index of completion type "complete_str".
+ * Returns EXPAND_NOTHING if no match found.
+ */
int
cmdcomplete_str_to_type(char_u *complete_str)
{
diff --git a/src/version.c b/src/version.c
index 5ee96b6178..9ec5e3174d 100644
--- a/src/version.c
+++ b/src/version.c
@@ -747,6 +747,8 @@ static char *(features[]) =
static int included_patches[] =
{ /* Add new patch number below this line */
/**/
+ 4903,
+/**/
4902,
/**/
4901,