mirror of
https://github.com/neovim/neovim.git
synced 2024-12-20 03:05:11 -07:00
Merge pull request #18438 from famiu/feat/api/nvim_parse_cmd
fix(api): make `nvim_parse_cmd` propagate errors
This commit is contained in:
commit
e3edcd06e3
@ -802,10 +802,15 @@ Dictionary nvim_parse_cmd(String str, Dictionary opts, Error *err)
|
||||
// Parse command line
|
||||
exarg_T ea;
|
||||
CmdParseInfo cmdinfo;
|
||||
char_u *cmdline = (char_u *)string_to_cstr(str);
|
||||
char *cmdline = string_to_cstr(str);
|
||||
char *errormsg = NULL;
|
||||
|
||||
if (!parse_cmdline(cmdline, &ea, &cmdinfo)) {
|
||||
api_set_error(err, kErrorTypeException, "Error while parsing command line");
|
||||
if (!parse_cmdline(cmdline, &ea, &cmdinfo, &errormsg)) {
|
||||
if (errormsg != NULL) {
|
||||
api_set_error(err, kErrorTypeException, "Error while parsing command line: %s", errormsg);
|
||||
} else {
|
||||
api_set_error(err, kErrorTypeException, "Error while parsing command line");
|
||||
}
|
||||
goto end;
|
||||
}
|
||||
|
||||
|
@ -1359,12 +1359,17 @@ static int parse_count(exarg_T *eap, char **errormsg)
|
||||
|
||||
/// Parse command line and return information about the first command.
|
||||
///
|
||||
/// @param cmdline Command line string
|
||||
/// @param[out] eap Ex command arguments
|
||||
/// @param[out] cmdinfo Command parse information
|
||||
/// @param[out] errormsg Error message, if any
|
||||
///
|
||||
/// @return Success or failure
|
||||
bool parse_cmdline(char_u *cmdline, exarg_T *eap, CmdParseInfo *cmdinfo)
|
||||
bool parse_cmdline(char *cmdline, exarg_T *eap, CmdParseInfo *cmdinfo, char **errormsg)
|
||||
{
|
||||
char *errormsg = NULL;
|
||||
char *cmd;
|
||||
char *p;
|
||||
char *after_modifier = NULL;
|
||||
cmdmod_T save_cmdmod = cmdmod;
|
||||
|
||||
// Initialize cmdinfo
|
||||
@ -1374,15 +1379,17 @@ bool parse_cmdline(char_u *cmdline, exarg_T *eap, CmdParseInfo *cmdinfo)
|
||||
memset(eap, 0, sizeof(*eap));
|
||||
eap->line1 = 1;
|
||||
eap->line2 = 1;
|
||||
eap->cmd = (char *)cmdline;
|
||||
eap->cmdlinep = (char **)&cmdline;
|
||||
eap->cmd = cmdline;
|
||||
eap->cmdlinep = &cmdline;
|
||||
eap->getline = NULL;
|
||||
eap->cookie = NULL;
|
||||
|
||||
// Parse command modifiers
|
||||
if (parse_command_modifiers(eap, &errormsg, false) == FAIL) {
|
||||
if (parse_command_modifiers(eap, errormsg, false) == FAIL) {
|
||||
return false;
|
||||
}
|
||||
after_modifier = eap->cmd;
|
||||
|
||||
// Revert the side-effects of `parse_command_modifiers`
|
||||
if (eap->save_msg_silent != -1) {
|
||||
cmdinfo->silent = !!msg_silent;
|
||||
@ -1422,7 +1429,7 @@ bool parse_cmdline(char_u *cmdline, exarg_T *eap, CmdParseInfo *cmdinfo)
|
||||
// Set command attribute type and parse command range
|
||||
set_cmd_addr_type(eap, (char_u *)p);
|
||||
eap->cmd = cmd;
|
||||
if (parse_cmd_address(eap, &errormsg, false) == FAIL) {
|
||||
if (parse_cmd_address(eap, errormsg, false) == FAIL) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -1434,6 +1441,11 @@ bool parse_cmdline(char_u *cmdline, exarg_T *eap, CmdParseInfo *cmdinfo)
|
||||
}
|
||||
// Fail if command is invalid
|
||||
if (eap->cmdidx == CMD_SIZE) {
|
||||
STRCPY(IObuff, _("E492: Not an editor command"));
|
||||
// If the modifier was parsed OK the error must be in the following command
|
||||
char *cmdname = after_modifier ? after_modifier : cmdline;
|
||||
append_command(cmdname);
|
||||
*errormsg = (char *)IObuff;
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -1472,10 +1484,12 @@ bool parse_cmdline(char_u *cmdline, exarg_T *eap, CmdParseInfo *cmdinfo)
|
||||
}
|
||||
// Fail if command doesn't support bang but is used with a bang
|
||||
if (!(eap->argt & EX_BANG) && eap->forceit) {
|
||||
*errormsg = _(e_nobang);
|
||||
return false;
|
||||
}
|
||||
// Fail if command doesn't support a range but it is given a range
|
||||
if (!(eap->argt & EX_RANGE) && eap->addr_count > 0) {
|
||||
*errormsg = _(e_norange);
|
||||
return false;
|
||||
}
|
||||
// Set default range for command if required
|
||||
@ -1485,7 +1499,7 @@ bool parse_cmdline(char_u *cmdline, exarg_T *eap, CmdParseInfo *cmdinfo)
|
||||
|
||||
// Parse register and count
|
||||
parse_register(eap);
|
||||
if (parse_count(eap, NULL) == FAIL) {
|
||||
if (parse_count(eap, errormsg) == FAIL) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -3426,10 +3426,15 @@ describe('API', function()
|
||||
}, meths.parse_cmd('MyCommand test it', {}))
|
||||
end)
|
||||
it('errors for invalid command', function()
|
||||
eq('Error while parsing command line', pcall_err(meths.parse_cmd, 'Fubar', {}))
|
||||
eq('Error while parsing command line', pcall_err(meths.parse_cmd, '', {}))
|
||||
eq('Error while parsing command line', pcall_err(meths.parse_cmd, '" foo', {}))
|
||||
eq('Error while parsing command line: E492: Not an editor command: Fubar',
|
||||
pcall_err(meths.parse_cmd, 'Fubar', {}))
|
||||
command('command! Fubar echo foo')
|
||||
eq('Error while parsing command line', pcall_err(meths.parse_cmd, 'Fubar!', {}))
|
||||
eq('Error while parsing command line', pcall_err(meths.parse_cmd, '4,6Fubar', {}))
|
||||
eq('Error while parsing command line: E477: No ! allowed',
|
||||
pcall_err(meths.parse_cmd, 'Fubar!', {}))
|
||||
eq('Error while parsing command line: E481: No range allowed',
|
||||
pcall_err(meths.parse_cmd, '4,6Fubar', {}))
|
||||
end)
|
||||
end)
|
||||
end)
|
||||
|
Loading…
Reference in New Issue
Block a user