diff options
author | zeertzjq <zeertzjq@outlook.com> | 2024-10-09 08:14:18 +0800 |
---|---|---|
committer | GitHub <noreply@github.com> | 2024-10-09 08:14:18 +0800 |
commit | f449a38f6a47bee30f0d4e291d8234d1ac8288a7 (patch) | |
tree | e65db9b696571e64352b16f849b8cc7582183f8c /src | |
parent | e98b1b0235a5e817c00814549606631703ab2041 (diff) | |
download | rneovim-f449a38f6a47bee30f0d4e291d8234d1ac8288a7.tar.gz rneovim-f449a38f6a47bee30f0d4e291d8234d1ac8288a7.tar.bz2 rneovim-f449a38f6a47bee30f0d4e291d8234d1ac8288a7.zip |
vim-patch:9.1.0770: current command line completion is a bit limited (#30728)
Problem: current command completion is a bit limited
Solution: Add the shellcmdline completion type and getmdcomplpat()
function (Ruslan Russkikh).
closes: vim/vim#15823
https://github.com/vim/vim/commit/0407d621bbad020b840ffbbbd25ba023bbc05edd
Co-authored-by: Ruslan Russkikh <dvrussk@yandex.ru>
Diffstat (limited to 'src')
-rw-r--r-- | src/nvim/cmdexpand.c | 4 | ||||
-rw-r--r-- | src/nvim/cmdexpand_defs.h | 1 | ||||
-rw-r--r-- | src/nvim/eval.lua | 16 | ||||
-rw-r--r-- | src/nvim/ex_getln.c | 39 | ||||
-rw-r--r-- | src/nvim/usercmd.c | 7 |
5 files changed, 61 insertions, 6 deletions
diff --git a/src/nvim/cmdexpand.c b/src/nvim/cmdexpand.c index 402a891099..b37a1d690f 100644 --- a/src/nvim/cmdexpand.c +++ b/src/nvim/cmdexpand.c @@ -119,6 +119,7 @@ static bool cmdline_fuzzy_completion_supported(const expand_T *const xp) && xp->xp_context != EXPAND_PACKADD && xp->xp_context != EXPAND_RUNTIME && xp->xp_context != EXPAND_SHELLCMD + && xp->xp_context != EXPAND_SHELLCMDLINE && xp->xp_context != EXPAND_TAGS && xp->xp_context != EXPAND_TAGS_LISTFILES && xp->xp_context != EXPAND_USER_LIST @@ -1527,7 +1528,8 @@ static void set_context_for_wildcard_arg(exarg_T *eap, const char *arg, bool use xp->xp_context = EXPAND_FILES; // For a shell command more chars need to be escaped. - if (usefilter || eap->cmdidx == CMD_bang || eap->cmdidx == CMD_terminal) { + if (usefilter || eap->cmdidx == CMD_bang || eap->cmdidx == CMD_terminal + || *complp == EXPAND_SHELLCMDLINE) { #ifndef BACKSLASH_IN_FILENAME xp->xp_shell = true; #endif diff --git a/src/nvim/cmdexpand_defs.h b/src/nvim/cmdexpand_defs.h index 3369790151..86725eafd6 100644 --- a/src/nvim/cmdexpand_defs.h +++ b/src/nvim/cmdexpand_defs.h @@ -106,6 +106,7 @@ enum { EXPAND_ARGOPT, EXPAND_KEYMAP, EXPAND_DIRS_IN_CDPATH, + EXPAND_SHELLCMDLINE, EXPAND_CHECKHEALTH, EXPAND_LUA, }; diff --git a/src/nvim/eval.lua b/src/nvim/eval.lua index 50aaf9e03b..24f986ef4e 100644 --- a/src/nvim/eval.lua +++ b/src/nvim/eval.lua @@ -3611,6 +3611,20 @@ M.funcs = { returns = 'string', signature = 'getcharstr([{expr}])', }, + getcmdcomplpat = { + desc = [=[ + Return completion pattern of the current command-line. + Only works when the command line is being edited, thus + requires use of |c_CTRL-\_e| or |c_CTRL-R_=|. + Also see |getcmdtype()|, |setcmdpos()|, |getcmdline()|, + |getcmdprompt()|, |getcmdcompltype()| and |setcmdline()|. + Returns an empty string when completion is not defined. + ]=], + name = 'getcmdcomplpat', + params = {}, + returns = 'string', + signature = 'getcmdcomplpat()', + }, getcmdcompltype = { desc = [=[ Return the type of the current command-line completion. @@ -3618,7 +3632,7 @@ M.funcs = { requires use of |c_CTRL-\_e| or |c_CTRL-R_=|. See |:command-completion| for the return string. Also see |getcmdtype()|, |setcmdpos()|, |getcmdline()|, - |getcmdprompt()| and |setcmdline()|. + |getcmdprompt()|, |getcmdcomplpat()| and |setcmdline()|. Returns an empty string when completion is not defined. ]=], name = 'getcmdcompltype', diff --git a/src/nvim/ex_getln.c b/src/nvim/ex_getln.c index ca01a158a3..b58a6b16f1 100644 --- a/src/nvim/ex_getln.c +++ b/src/nvim/ex_getln.c @@ -4086,14 +4086,44 @@ static char *get_cmdline_str(void) return xstrnsave(p->cmdbuff, (size_t)p->cmdlen); } +/// Get the current command-line completion pattern. +static char *get_cmdline_completion_pattern(void) +{ + if (cmdline_star > 0) { + return NULL; + } + + CmdlineInfo *p = get_ccline_ptr(); + if (p == NULL || p->xpc == NULL) { + return NULL; + } + + int xp_context = p->xpc->xp_context; + if (xp_context == EXPAND_NOTHING) { + set_expand_context(p->xpc); + xp_context = p->xpc->xp_context; + p->xpc->xp_context = EXPAND_NOTHING; + } + if (xp_context == EXPAND_UNSUCCESSFUL) { + return NULL; + } + + char *compl_pat = p->xpc->xp_pattern; + if (compl_pat == NULL) { + return NULL; + } + + return xstrdup(compl_pat); +} + /// Get the current command-line completion type. static char *get_cmdline_completion(void) { if (cmdline_star > 0) { return NULL; } - CmdlineInfo *p = get_ccline_ptr(); + CmdlineInfo *p = get_ccline_ptr(); if (p == NULL || p->xpc == NULL) { return NULL; } @@ -4123,6 +4153,13 @@ static char *get_cmdline_completion(void) return xstrdup(cmd_compl); } +/// "getcmdcomplpat()" function +void f_getcmdcomplpat(typval_T *argvars, typval_T *rettv, EvalFuncData fptr) +{ + rettv->v_type = VAR_STRING; + rettv->vval.v_string = get_cmdline_completion_pattern(); +} + /// "getcmdcompltype()" function void f_getcmdcompltype(typval_T *argvars, typval_T *rettv, EvalFuncData fptr) { diff --git a/src/nvim/usercmd.c b/src/nvim/usercmd.c index d32e0ee319..8404b2bc14 100644 --- a/src/nvim/usercmd.c +++ b/src/nvim/usercmd.c @@ -91,6 +91,7 @@ static const char *command_complete[] = { [EXPAND_PACKADD] = "packadd", [EXPAND_RUNTIME] = "runtime", [EXPAND_SHELLCMD] = "shellcmd", + [EXPAND_SHELLCMDLINE] = "shellcmdline", [EXPAND_SIGN] = "sign", [EXPAND_TAGS] = "tag", [EXPAND_TAGS_LISTFILES] = "tag_listfiles", @@ -285,8 +286,7 @@ const char *set_context_in_user_cmdarg(const char *cmd FUNC_ATTR_UNUSED, const c } if (argt & EX_XFILE) { - // EX_XFILE: file names are handled above. - xp->xp_context = context; + // EX_XFILE: file names are handled before this call. return NULL; } @@ -675,7 +675,8 @@ int parse_compl_arg(const char *value, int vallen, int *complp, uint32_t *argt, *complp = i; if (i == EXPAND_BUFFERS) { *argt |= EX_BUFNAME; - } else if (i == EXPAND_DIRECTORIES || i == EXPAND_FILES) { + } else if (i == EXPAND_DIRECTORIES || i == EXPAND_FILES + || i == EXPAND_SHELLCMDLINE) { *argt |= EX_XFILE; } break; |