# HG changeset patch # User Bram Moolenaar # Date 1612611904 -3600 # Node ID a9ed31ab85c3c70a553ef841ae7d2394143792cf # Parent cbebf5f1a5a73b55470391d025e6bd6da33f1fdb patch 8.2.2468: not easy to get the full command name from a shortened one Commit: https://github.com/vim/vim/commit/038e09ee7645731de0296d255aabb17603276443 Author: Bram Moolenaar Date: Sat Feb 6 12:38:51 2021 +0100 patch 8.2.2468: not easy to get the full command name from a shortened one Problem: Not easy to get the full command name from a shortened one. Solution: Add fullcommand(). (Martin Tournoij, closes https://github.com/vim/vim/issues/7777) diff --git a/runtime/doc/eval.txt b/runtime/doc/eval.txt --- a/runtime/doc/eval.txt +++ b/runtime/doc/eval.txt @@ -2562,6 +2562,7 @@ foldlevel({lnum}) Number fold level at foldtext() String line displayed for closed fold foldtextresult({lnum}) String text for closed fold at {lnum} foreground() Number bring the Vim window to the foreground +fullcommand({name}) String get full command from {name} funcref({name} [, {arglist}] [, {dict}]) Funcref reference to function {name} function({name} [, {arglist}] [, {dict}]) @@ -4902,6 +4903,21 @@ foreground() Move the Vim window to the {only in the Win32, Athena, Motif and GTK GUI versions and the Win32 console version} +fullcommand({name}) *fullcommand()* + Get the full command name from a short abbreviated command + name; see |20.2| for details on command abbreviations. + + {name} may start with a `:` and can include a [range], these + are skipped and not returned. + Returns an empty string if a command doesn't exist or if it's + ambiguous (for user-defined functions). + + For example `fullcommand('s')`, `fullcommand('sub')`, + `fullcommand(':%substitute')` all return "substitute". + + Can also be used as a |method|: > + GetName()->fullcommand() +< *funcref()* funcref({name} [, {arglist}] [, {dict}]) Just like |function()|, but the returned Funcref will lookup diff --git a/runtime/doc/usr_41.txt b/runtime/doc/usr_41.txt --- a/runtime/doc/usr_41.txt +++ b/runtime/doc/usr_41.txt @@ -883,6 +883,7 @@ Command line: *command-line-function getcmdtype() return the current command-line type getcmdwintype() return the current command-line window type getcompletion() list of command-line completion matches + fullcommand() get full command name Quickfix and location lists: *quickfix-functions* getqflist() list of quickfix errors diff --git a/src/evalfunc.c b/src/evalfunc.c --- a/src/evalfunc.c +++ b/src/evalfunc.c @@ -978,6 +978,8 @@ static funcentry_T global_functions[] = ret_string, f_foldtextresult}, {"foreground", 0, 0, 0, NULL, ret_void, f_foreground}, + {"fullcommand", 1, 1, FEARG_1, arg1_string, + ret_string, f_fullcommand}, {"funcref", 1, 3, FEARG_1, NULL, ret_func_any, f_funcref}, {"function", 1, 3, FEARG_1, NULL, diff --git a/src/ex_docmd.c b/src/ex_docmd.c --- a/src/ex_docmd.c +++ b/src/ex_docmd.c @@ -3668,6 +3668,33 @@ cmd_exists(char_u *name) return 0; // trailing garbage return (ea.cmdidx == CMD_SIZE ? 0 : (full ? 2 : 1)); } + +/* + * "fullcommand" function + */ + void +f_fullcommand(typval_T *argvars, typval_T *rettv) +{ + exarg_T ea; + char_u *name = argvars[0].vval.v_string; + char_u *p; + + while (name[0] != NUL && name[0] == ':') + name++; + name = skip_range(name, TRUE, NULL); + + rettv->v_type = VAR_STRING; + + ea.cmd = (*name == '2' || *name == '3') ? name + 1 : name; + ea.cmdidx = (cmdidx_T)0; + p = find_ex_command(&ea, NULL, NULL, NULL); + if (p == NULL || ea.cmdidx == CMD_SIZE) + return; + + rettv->vval.v_string = vim_strsave(IS_USER_CMDIDX(ea.cmdidx) + ? get_user_commands(NULL, ea.useridx) + : cmdnames[ea.cmdidx].cmd_name); +} #endif cmdidx_T diff --git a/src/proto/evalfunc.pro b/src/proto/evalfunc.pro --- a/src/proto/evalfunc.pro +++ b/src/proto/evalfunc.pro @@ -23,4 +23,5 @@ void range_list_materialize(list_T *list float_T vim_round(float_T f); long do_searchpair(char_u *spat, char_u *mpat, char_u *epat, int dir, typval_T *skip, int flags, pos_T *match_pos, linenr_T lnum_stop, long time_limit); void f_string(typval_T *argvars, typval_T *rettv); +void f_fullcommand(typval_T *argvars, typval_T *rettv); /* vim: set ft=c : */ diff --git a/src/testdir/test_cmdline.vim b/src/testdir/test_cmdline.vim --- a/src/testdir/test_cmdline.vim +++ b/src/testdir/test_cmdline.vim @@ -442,6 +442,43 @@ func Test_getcompletion() call assert_fails('call getcompletion("abc", [])', 'E475:') endfunc +func Test_fullcommand() + let tests = { + \ '': '', + \ ':': '', + \ ':::': '', + \ ':::5': '', + \ 'not_a_cmd': '', + \ 'Check': '', + \ 'syntax': 'syntax', + \ ':syntax': 'syntax', + \ '::::syntax': 'syntax', + \ 'sy': 'syntax', + \ 'syn': 'syntax', + \ 'synt': 'syntax', + \ ':sy': 'syntax', + \ '::::sy': 'syntax', + \ 'match': 'match', + \ '2match': 'match', + \ '3match': 'match', + \ 'aboveleft': 'aboveleft', + \ 'abo': 'aboveleft', + \ 's': 'substitute', + \ '5s': 'substitute', + \ ':5s': 'substitute', + \ "'<,'>s": 'substitute', + \ ":'<,'>s": 'substitute', + \ 'CheckUni': 'CheckUnix', + \ 'CheckUnix': 'CheckUnix', + \ } + + for [in, want] in items(tests) + call assert_equal(want, fullcommand(in)) + endfor + + call assert_equal('syntax', 'syn'->fullcommand()) +endfunc + func Test_shellcmd_completion() let save_path = $PATH diff --git a/src/version.c b/src/version.c --- a/src/version.c +++ b/src/version.c @@ -751,6 +751,8 @@ static char *(features[]) = static int included_patches[] = { /* Add new patch number below this line */ /**/ + 2468, +/**/ 2467, /**/ 2466,