diff --git a/runtime/doc/change.txt b/runtime/doc/change.txt index cb868a0a06..8048d19d26 100644 --- a/runtime/doc/change.txt +++ b/runtime/doc/change.txt @@ -62,17 +62,17 @@ For inserting text see |insert.txt|. :[range]d[elete] [x] Delete [range] lines (default: current line) [into register x]. Note these weird abbreviations: - :dl delete and list - :dell idem - :delel idem - :deletl idem - :deletel idem - :dp delete and print - :dep idem - :delp idem - :delep idem - :deletp idem - :deletep idem + :dl delete and list + :dell idem + :delel idem + :deletl idem + :deletel idem + :dp delete and print + :dep idem + :delp idem + :delep idem + :deletp idem + :deletep idem :[range]d[elete] [x] {count} Delete {count} lines, starting with [range] diff --git a/runtime/doc/tagsrch.txt b/runtime/doc/tagsrch.txt index 67b2e41fbc..9272d7d613 100644 --- a/runtime/doc/tagsrch.txt +++ b/runtime/doc/tagsrch.txt @@ -840,8 +840,8 @@ CTRL-W i Open a new window, with the cursor on the first line Like `[D` and `]D`, but search in [range] lines (default: whole file). See |:search-args| for [/] and [!]. - Note that `:dl` works like `:delete` with the "l" - flag, not `:dlist`. + Note: `:dl` works like `:delete` with the "l" flag, + not `:dlist`. *[_CTRL-D* [ CTRL-D Jump to the first macro definition that contains the diff --git a/runtime/doc/usr_20.txt b/runtime/doc/usr_20.txt index 51e2ead124..a86053377f 100644 --- a/runtime/doc/usr_20.txt +++ b/runtime/doc/usr_20.txt @@ -119,6 +119,14 @@ Some of the ":" commands are really long. We already mentioned that ":substitute" can be abbreviated to ":s". This is a generic mechanism, all ":" commands can be abbreviated. +The builtin function |fullcommand()| can be used to return an abbreviated +command's full name. For example, the following commands echo "edit", "echo", +and "echomsg": +>vim + :echo fullcommand('e') + :echo fullcommand('ec') + :echo fullcommand('echom') +< How short can a command get? There are 26 letters, and many more commands. For example, ":set" also starts with ":s", but ":s" doesn't start a ":set" command. Instead ":set" can be abbreviated to ":se". diff --git a/runtime/doc/vimfn.txt b/runtime/doc/vimfn.txt index 977aca65a3..1a5ba40ca1 100644 --- a/runtime/doc/vimfn.txt +++ b/runtime/doc/vimfn.txt @@ -2901,8 +2901,16 @@ fullcommand({name}) *fullcommand()* Returns an empty string if a command doesn't exist or if it's ambiguous (for user-defined commands). - For example `fullcommand('s')`, `fullcommand('sub')`, - `fullcommand(':%substitute')` all return "substitute". + Note: Command validation is not performed. Results depend on + Vim's internal command-specific identification rules. + Examples: +>vim + echo [fullcommand('s')] |" ['substitute'] + echo [fullcommand('sub')] |" ['substitute'] + echo [fullcommand(': mark word')] |" ['mark'] + echo [fullcommand(': markword')] |" [''] + echo [fullcommand('en')] |" ['endif'] +< Parameters: ~ • {name} (`string`) diff --git a/runtime/lua/vim/_meta/vimfn.gen.lua b/runtime/lua/vim/_meta/vimfn.gen.lua index b7184207d2..6b70685a28 100644 --- a/runtime/lua/vim/_meta/vimfn.gen.lua +++ b/runtime/lua/vim/_meta/vimfn.gen.lua @@ -2571,8 +2571,16 @@ function vim.fn.foreach(expr1, expr2) end --- Returns an empty string if a command doesn't exist or if it's --- ambiguous (for user-defined commands). --- ---- For example `fullcommand('s')`, `fullcommand('sub')`, ---- `fullcommand(':%substitute')` all return "substitute". +--- Note: Command validation is not performed. Results depend on +--- Vim's internal command-specific identification rules. +--- Examples: +--- >vim +--- echo [fullcommand('s')] |" ['substitute'] +--- echo [fullcommand('sub')] |" ['substitute'] +--- echo [fullcommand(': mark word')] |" ['mark'] +--- echo [fullcommand(': markword')] |" [''] +--- echo [fullcommand('en')] |" ['endif'] +--- < --- --- @param name string --- @return string diff --git a/src/nvim/eval.lua b/src/nvim/eval.lua index e4018cc6ea..5728b248e3 100644 --- a/src/nvim/eval.lua +++ b/src/nvim/eval.lua @@ -3230,9 +3230,16 @@ M.funcs = { Returns an empty string if a command doesn't exist or if it's ambiguous (for user-defined commands). - For example `fullcommand('s')`, `fullcommand('sub')`, - `fullcommand(':%substitute')` all return "substitute". - + Note: Command validation is not performed. Results depend on + Vim's internal command-specific identification rules. + Examples: + >vim + echo [fullcommand('s')] |" ['substitute'] + echo [fullcommand('sub')] |" ['substitute'] + echo [fullcommand(': mark word')] |" ['mark'] + echo [fullcommand(': markword')] |" [''] + echo [fullcommand('en')] |" ['endif'] + < ]=], name = 'fullcommand', params = { { 'name', 'string' } }, diff --git a/src/nvim/ex_docmd.c b/src/nvim/ex_docmd.c index 425760f4ec..2a08f635fe 100644 --- a/src/nvim/ex_docmd.c +++ b/src/nvim/ex_docmd.c @@ -3269,6 +3269,14 @@ char *find_ex_command(exarg_T *eap, int *full) } } + // Force ":ho" to be unresolved. Without this, find_ex_command() + // matches it to CMD_horizontal (the only "ho*" entry), which makes + // fullcommand("ho") return "horizontal" even though ":ho" cannot be + // used as the modifier (cmdmods[] requires 3 chars, "hor"). + if (eap->cmdidx == CMD_horizontal && p - eap->cmd == 2) { + eap->cmdidx = CMD_SIZE; + } + return p; } diff --git a/test/old/testdir/test_marks.vim b/test/old/testdir/test_marks.vim index 44201cb289..59b7d9757a 100644 --- a/test/old/testdir/test_marks.vim +++ b/test/old/testdir/test_marks.vim @@ -253,7 +253,14 @@ func Test_marks_k_cmd() call setline(1, ['foo', 'bar', 'baz', 'qux']) 1,3kr call assert_equal([0, 3, 1, 0], getpos("'r")) + " whitespace before mark + 4k f + call assert_equal([0, 4, 1, 0], getpos("'f")) + :2 k g + call assert_equal([0, 2, 1, 0], getpos("'g")) bw! + call assert_fails(':kz7', 'E488: Trailing characters: z7') + call assert_fails(':execute ":k^"', 'E191: Argument must be a letter or forward/backward quote') endfunc " Test for file marks (A-Z) diff --git a/test/old/testdir/test_vimscript.vim b/test/old/testdir/test_vimscript.vim index 458eae9134..7d7cb7c535 100644 --- a/test/old/testdir/test_vimscript.vim +++ b/test/old/testdir/test_vimscript.vim @@ -7620,6 +7620,33 @@ func Test_catch_pattern_trailing_chars() bw! endfunc +" Test using fullcommand() {{{1 +func Test_builtin_fullcommand() + " :hor is the minimum abbreviation of :horizontal; :ho is invalid + call assert_equal('', fullcommand('ho')) + call assert_equal('horizontal', fullcommand('hor')) + + " :k takes one {a-zA-Z'} mark argument and optional whitespace + call assert_equal('k', fullcommand('k')) + call assert_equal('k', fullcommand(':k')) + call assert_equal('k', fullcommand('karrrrrgh!')) + + " :dl is "delete and list" in a legacy Vim script scope + call assert_equal('delete', fullcommand('dl')) + + " :s two and three letter commands + call assert_equal('substitute', fullcommand('sIr')) + call assert_equal('substitute', fullcommand('sIrarrrrrgh!')) + + " :finally + call assert_equal('finally', fullcommand('fina')) + " 'final' - returns 'final', a Vim9 script-exclusive keyword + " - is a valid shortening of :finally in legacy Vim script + "call assert_equal('final', fullcommand('final')) + call assert_equal('finally', fullcommand('finall')) + +endfunc + "------------------------------------------------------------------------------- " Modelines {{{1 " vim: ts=8 sw=2 sts=2 expandtab tw=80 fdm=marker