mirror of
https://github.com/neovim/neovim.git
synced 2025-12-05 14:13:10 +00:00
fix(api): nvim_parse_cmd error message in pcall() #23297
Problem:
nvim_parse_cmd() in pcall() may show an error message (side-effect):
:lua pcall(vim.api.nvim_parse_cmd, vim.fn.getcmdline(), {})
E16: Invalid range
Solution:
Avoid emsg() in the nvim_parse_cmd() codepath.
- refactor(api): add error message output parameter to get_address()
- fix: null check emsg() parameter
- refactor: remove emsg_off workaround from do_incsearch_highlighting()
- refactor: remove emsg_off workaround from cmdpreview_may_show()
- refactor: remove remaining calls to emsg() from parse_cmd_address() and get_address()
- (refactor): lint set_cmd_dflall_range()
- refactor: addr_error() - move output parameter to return value
Fix #20339
TODO:
These are the functions called by `get_address()`:
```
nvim_parse_cmd() -> parse_cmdline() -> parse_cmd_address() -> get_address()
skipwhite()
addr_error()
qf_get_cur_idx()
qf_get_cur_valid_idx()
qf_get_size()
qf_get_valid_size()
mark_get()
mark_check()
assert()
skip_regexp()
magic_isset()
> do_search()
> searchit()
ascii_isdigit()
getdigits()
getdigits_int32()
compute_buffer_local_count()
hasFolding()
```
From these functions, I found at least two that call emsg directly:
- do_search()
- seems to be simple to refactor
- searchit()
- will be more challenging because it may generate multiple error messages,
which can't be handled by the current `errormsg` out-parameter.
For example, it makes multiple calls to `vim_regexec_multi()` in a loop that
possibly generate error messages, and later `searchit()` itself may generate
another one:
- c194acbfc4/src/nvim/search.c (L631-L647)
- c194acbfc4/src/nvim/search.c (L939-L954)
---------
Co-authored-by: Justin M. Keyes <justinkz@gmail.com>
This commit is contained in:
@@ -3467,6 +3467,7 @@ describe('API', function()
|
||||
end)
|
||||
end)
|
||||
end)
|
||||
|
||||
describe('nvim_parse_cmd', function()
|
||||
it('works', function()
|
||||
eq({
|
||||
@@ -4048,7 +4049,13 @@ describe('API', function()
|
||||
meths.cmd(meths.parse_cmd("set cursorline", {}), {})
|
||||
eq(true, meths.get_option_value("cursorline", {}))
|
||||
end)
|
||||
it('no side-effects (error messages) in pcall() #20339', function()
|
||||
eq({ false, 'Error while parsing command line: E16: Invalid range' },
|
||||
exec_lua([=[return {pcall(vim.api.nvim_parse_cmd, "'<,'>n", {})}]=]))
|
||||
eq('', eval('v:errmsg'))
|
||||
end)
|
||||
end)
|
||||
|
||||
describe('nvim_cmd', function()
|
||||
it('works', function ()
|
||||
meths.cmd({ cmd = "set", args = { "cursorline" } }, {})
|
||||
|
||||
Reference in New Issue
Block a user