Better error messages for EDITOR=vim git... type commands.

https://github.com/fish-shell/fish-shell/issues/809
This commit is contained in:
ridiculousfish 2013-09-30 14:55:25 -07:00
parent cbe615224d
commit 2f33e5919d
3 changed files with 61 additions and 15 deletions

View file

@ -152,7 +152,7 @@ The fish parser. Contains functions for parsing and evaluating code.
#define INVALID_END_ERR_MSG _( L"'end' command outside of block") #define INVALID_END_ERR_MSG _( L"'end' command outside of block")
/** /**
Error message for Posix-style assignment Error message for Posix-style assignment: foo=bar
*/ */
#define COMMAND_ASSIGN_ERR_MSG _( L"Unknown command '%ls'. Did you mean 'set %ls %ls'? See the help section on the set command by typing 'help set'.") #define COMMAND_ASSIGN_ERR_MSG _( L"Unknown command '%ls'. Did you mean 'set %ls %ls'? See the help section on the set command by typing 'help set'.")
@ -2014,8 +2014,6 @@ int parser_t::parse_job(process_t *p,
const wchar_t *cmd = args.at(0).completion.c_str(); const wchar_t *cmd = args.at(0).completion.c_str();
fprintf(stderr, "arg count: %lu\n", args.size());
/* /*
We couldn't find the specified command. We couldn't find the specified command.
@ -2034,19 +2032,39 @@ int parser_t::parse_job(process_t *p,
and zsh). and zsh).
*/ */
if (wcschr(cmd, L'=')) const wchar_t * const equals_ptr = wcschr(cmd, L'=');
if (equals_ptr != NULL)
{ {
wchar_t *cpy = wcsdup(cmd); /* Try to figure out if this is a pure variable assignment (foo=bar), or if this appears to be running a command (foo=bar ruby...) */
wchar_t *valpart = wcschr(cpy, L'=');
*valpart++=0; const wcstring name_str = wcstring(cmd, equals_ptr - cmd); //variable name, up to the =
const wcstring val_str = wcstring(equals_ptr + 1); //variable value, past the =
debug(0,
COMMAND_ASSIGN_ERR_MSG, wcstring next_str;
cmd, if (tok_peek_next(tok, &next_str) == TOK_STRING && ! next_str.empty())
cpy, {
valpart); wcstring ellipsis_str = wcstring(1, ellipsis_char);
free(cpy); if (ellipsis_str == L"$")
ellipsis_str = L"...";
/* Looks like a command */
debug(0,
_( L"Unknown command '%ls'. Did you mean to run %ls with a modified environment? Try 'env %ls=%ls %ls%ls'. See the help section on the set command by typing 'help set'."),
cmd,
next_str.c_str(),
name_str.c_str(),
val_str.c_str(),
next_str.c_str(),
ellipsis_str.c_str());
}
else
{
debug(0,
COMMAND_ASSIGN_ERR_MSG,
cmd,
name_str.c_str(),
val_str.c_str());
}
} }
else if (cmd[0]==L'$' || cmd[0] == VARIABLE_EXPAND || cmd[0] == VARIABLE_EXPAND_SINGLE) else if (cmd[0]==L'$' || cmd[0] == VARIABLE_EXPAND || cmd[0] == VARIABLE_EXPAND_SINGLE)
{ {

View file

@ -641,6 +641,31 @@ void tok_next(tokenizer_t *tok)
} }
enum token_type tok_peek_next(tokenizer_t *tok, wcstring *out_next_string)
{
if (out_next_string != NULL)
{
out_next_string->clear();
}
enum token_type result = TOK_END;
if (tok_has_next(tok))
{
int saved = tok_get_pos(tok);
tok_next(tok);
result = tok_last_type(tok);
if (out_next_string != NULL)
{
const wchar_t *last = tok_last(tok);
out_next_string->assign(last ? last : L"");
}
tok_set_pos(tok, saved);
}
return result;
}
const wchar_t *tok_string(tokenizer_t *tok) const wchar_t *tok_string(tokenizer_t *tok)
{ {
return tok?tok->orig_buff:0; return tok?tok->orig_buff:0;

View file

@ -145,6 +145,9 @@ int tok_has_next(tokenizer_t *tok);
*/ */
int tok_get_pos(tokenizer_t *tok); int tok_get_pos(tokenizer_t *tok);
/** Returns the token type after the current one, without adjusting the position. Optionally returns the next string by reference. */
enum token_type tok_peek_next(tokenizer_t *tok, wcstring *out_next_string);
/** /**
Returns the original string to tokenizer Returns the original string to tokenizer
*/ */