mirror of
https://github.com/neovim/neovim.git
synced 2026-06-15 16:23:48 +00:00
vim-patch:partial:9.2.0573: Vim9: missing EX_WHOLE on some block keywords (#40071)
Problem: Several Vim9 keywords lack EX_WHOLE and can be shortened in
Vim9 script, inconsistent with endif/enddef/endfor/endwhile/
endtry which already have it. The error from :endd in a
nested function also hardcodes "enddef" instead of reporting
what the user typed. fullcommand("ho") returns "horizontal"
even though :ho is below the documented 3-char minimum.
Solution: Add EX_WHOLE to :class, :def, :endclass, :endinterface,
:endenum, :public and :static. In get_function_body() pass
the user-typed command to the error message. Force :ho to
CMD_SIZE in find_ex_command() so fullcommand() reflects the
modifier minimum. Extend tests and documentation accordingly
(Peter Kenny).
fixes: vim/vim#20032
closes: vim/vim#20191
38d9a16eba
Co-authored-by: Peter Kenny <github.com@k1w1.cyou>
This commit is contained in:
@@ -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]
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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".
|
||||
|
||||
@@ -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`)
|
||||
|
||||
12
runtime/lua/vim/_meta/vimfn.gen.lua
generated
12
runtime/lua/vim/_meta/vimfn.gen.lua
generated
@@ -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
|
||||
|
||||
@@ -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' } },
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user