mirror of
https://github.com/fish-shell/fish-shell.git
synced 2025-01-31 19:33:00 +08:00
abbr: stop parsing option after first expansion token
Historical behavior is to stop option parsing at the first non-option argument. Since we have added more options, it seemed impractical to keep that behavior. However people are using options in their abbr expansions ("abbr e emacs -nw"). To support this, we ignore options. However, we only ignore them if they are not valid "abbr" options. Let's ignore all options in the expansion definition, which is a small price to pay to keep most existing configurations working. Fixes #9410 This does not fix other cases which used to work, like abbr x -unknown Those are hopefully not used by anyone, so I don't think we need to maintain support for that.
This commit is contained in:
parent
d14b4b96f0
commit
9790907ca8
|
@ -295,8 +295,9 @@ maybe_t<int> builtin_abbr(parser_t &parser, io_streams_t &streams, const wchar_t
|
||||||
int argc = builtin_count_args(argv);
|
int argc = builtin_count_args(argv);
|
||||||
int opt;
|
int opt;
|
||||||
wgetopter_t w;
|
wgetopter_t w;
|
||||||
bool unrecognized_options_are_args = false;
|
bool in_expansion = false;
|
||||||
while ((opt = w.wgetopt_long(argc, argv, short_options, long_options, nullptr)) != -1) {
|
while (!in_expansion &&
|
||||||
|
(opt = w.wgetopt_long(argc, argv, short_options, long_options, nullptr)) != -1) {
|
||||||
switch (opt) {
|
switch (opt) {
|
||||||
case NON_OPTION_ARGUMENT:
|
case NON_OPTION_ARGUMENT:
|
||||||
// If --add is specified (or implied by specifying no other commands), all
|
// If --add is specified (or implied by specifying no other commands), all
|
||||||
|
@ -307,7 +308,7 @@ maybe_t<int> builtin_abbr(parser_t &parser, io_streams_t &streams, const wchar_t
|
||||||
opts.args.push_back(w.woptarg);
|
opts.args.push_back(w.woptarg);
|
||||||
if (opts.args.size() >= 2 &&
|
if (opts.args.size() >= 2 &&
|
||||||
!(opts.rename || opts.show || opts.list || opts.erase || opts.query)) {
|
!(opts.rename || opts.show || opts.list || opts.erase || opts.query)) {
|
||||||
unrecognized_options_are_args = true;
|
in_expansion = true;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case 'a':
|
case 'a':
|
||||||
|
@ -376,12 +377,8 @@ maybe_t<int> builtin_abbr(parser_t &parser, io_streams_t &streams, const wchar_t
|
||||||
return STATUS_CMD_OK;
|
return STATUS_CMD_OK;
|
||||||
}
|
}
|
||||||
case '?': {
|
case '?': {
|
||||||
if (unrecognized_options_are_args) {
|
builtin_unknown_option(parser, streams, cmd, argv[w.woptind - 1]);
|
||||||
opts.args.push_back(argv[w.woptind - 1]);
|
return STATUS_INVALID_ARGS;
|
||||||
} else {
|
|
||||||
builtin_unknown_option(parser, streams, cmd, argv[w.woptind - 1]);
|
|
||||||
return STATUS_INVALID_ARGS;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -30,10 +30,10 @@ send(r"echo alpha ?")
|
||||||
expect_str(r"<echo alpha >")
|
expect_str(r"<echo alpha >")
|
||||||
|
|
||||||
# Abbreviation expansions may have multiple words.
|
# Abbreviation expansions may have multiple words.
|
||||||
sendline(r"abbr --add emacsnw emacs -nw")
|
sendline(r"abbr --add emacsnw emacs -nw -l")
|
||||||
expect_prompt()
|
expect_prompt()
|
||||||
send(r"emacsnw ?")
|
send(r"emacsnw ?")
|
||||||
expect_str(r"<emacs -nw >")
|
expect_str(r"<emacs -nw -l >")
|
||||||
|
|
||||||
# Regression test that abbreviations still expand in incomplete positions.
|
# Regression test that abbreviations still expand in incomplete positions.
|
||||||
sendline(r"""abbr --erase (abbr --list)""")
|
sendline(r"""abbr --erase (abbr --list)""")
|
||||||
|
@ -103,9 +103,9 @@ expect_prompt()
|
||||||
|
|
||||||
# Abbreviations which cause the command line to become incomplete or invalid
|
# Abbreviations which cause the command line to become incomplete or invalid
|
||||||
# are visibly expanded.
|
# are visibly expanded.
|
||||||
sendline(r"abbr openparen '(' --position anywhere")
|
sendline(r"abbr openparen --position anywhere '('")
|
||||||
expect_prompt()
|
expect_prompt()
|
||||||
sendline(r"abbr closeparen ')' --position anywhere")
|
sendline(r"abbr closeparen --position anywhere ')'")
|
||||||
expect_prompt()
|
expect_prompt()
|
||||||
sendline(r"echo openparen")
|
sendline(r"echo openparen")
|
||||||
expect_str(r"echo (")
|
expect_str(r"echo (")
|
||||||
|
|
Loading…
Reference in New Issue
Block a user