From 4d2bcf2fe7637b641ccde31a8ca7c4875f0699c1 Mon Sep 17 00:00:00 2001 From: Daniel Shahaf Date: Mon, 27 Apr 2020 19:30:39 +0000 Subject: 45729: internal: Add a second parameter to zlinklist2array(), analogously to hlinklist2array(). Will be used in the next commit. --- Src/Zle/computil.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'Src/Zle/computil.c') diff --git a/Src/Zle/computil.c b/Src/Zle/computil.c index 90db8b4b8..ddfa70077 100644 --- a/Src/Zle/computil.c +++ b/Src/Zle/computil.c @@ -3591,7 +3591,7 @@ bin_compvalues(char *nam, char **args, UNUSED(Options ops), UNUSED(int func)) if (cv_laststate.vals) { char **ret; - ret = zlinklist2array(cv_laststate.vals); + ret = zlinklist2array(cv_laststate.vals, 1); sethparam(args[1], ret); return 0; @@ -4016,7 +4016,7 @@ bin_comptry(char *nam, char **args, UNUSED(Options ops), UNUSED(int func)) set = (Ctset) zalloc(sizeof(*set)); - set->tags = zlinklist2array(list); + set->tags = zlinklist2array(list, 1); set->next = NULL; set->ptr = NULL; set->tag = NULL; -- cgit v1.2.3 From deca7c928520fba5a73383f1cac0b3ace8e0e45d Mon Sep 17 00:00:00 2001 From: Daniel Shahaf Date: Mon, 27 Apr 2020 19:30:40 +0000 Subject: 45730: _arguments: Add the -0 flag, which makes $opt_args be populated sanely. Also, write/extend docstrings for sepjoin() and zjoin(). --- ChangeLog | 5 +++++ Completion/Base/Utility/_arguments | 8 +++++--- Doc/Zsh/compsys.yo | 25 +++++++++++++++++++++--- Src/Zle/computil.c | 40 +++++++++++++++++++++++++++++++++----- Src/utils.c | 15 +++++++++++++- Test/Y03arguments.ztst | 8 +++++++- 6 files changed, 88 insertions(+), 13 deletions(-) (limited to 'Src/Zle/computil.c') diff --git a/ChangeLog b/ChangeLog index 1942d9aab..1afa30114 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,10 @@ 2020-05-03 Daniel Shahaf + * 45730: Completion/Base/Utility/_arguments, Doc/Zsh/compsys.yo, + Src/Zle/computil.c, Src/utils.c, Test/Y03arguments.ztst: + _arguments: Add the -0 flag, which makes $opt_args be populated + sanely. + * 45729: Src/Modules/curses.c, Src/Zle/compcore.c, Src/Zle/computil.c, Src/builtin.c, Src/linklist.c: internal: Add a second parameter to zlinklist2array(), analogously to diff --git a/Completion/Base/Utility/_arguments b/Completion/Base/Utility/_arguments index 136dd5826..3f1b39304 100644 --- a/Completion/Base/Utility/_arguments +++ b/Completion/Base/Utility/_arguments @@ -7,11 +7,13 @@ local long cmd="$words[1]" descr odescr mesg subopts opt opt2 usecc autod local oldcontext="$curcontext" hasopts rawret optarg singopt alwopt local setnormarg start rest local -a match mbegin mend +integer opt_args_use_NUL_separators=0 subopts=() singopt=() -while [[ "$1" = -([AMO]*|[CRSWnsw]) ]]; do +while [[ "$1" = -([AMO]*|[0CRSWnsw]) ]]; do case "$1" in + -0) opt_args_use_NUL_separators=1; shift ;; -C) usecc=yes; shift ;; -O) subopts=( "${(@P)2}" ); shift 2 ;; -O*) subopts=( "${(@P)${1[3,-1]}}" ); shift ;; @@ -388,7 +390,7 @@ if (( $# )) && comparguments -i "$autod" "$singopt[@]" "$@"; then if [[ "$action" = -\>* ]]; then action="${${action[3,-1]##[ ]#}%%[ ]#}" if (( ! $state[(I)$action] )); then - comparguments -W line opt_args + comparguments -W line opt_args $opt_args_use_NUL_separators state+=( "$action" ) state_descr+=( "$descr" ) if [[ -n "$usecc" ]]; then @@ -406,7 +408,7 @@ if (( $# )) && comparguments -i "$autod" "$singopt[@]" "$@"; then local=yes fi - comparguments -W line opt_args + comparguments -W line opt_args $opt_args_use_NUL_separators if [[ "$action" = \ # ]]; then diff --git a/Doc/Zsh/compsys.yo b/Doc/Zsh/compsys.yo index 1ce17dccc..98ab46d8a 100644 --- a/Doc/Zsh/compsys.yo +++ b/Doc/Zsh/compsys.yo @@ -3740,6 +3740,12 @@ The default var(matchspec) allows partial word completion after `tt(_)' and var(matchspec) is: example(tt(r:|[_-]=* r:|=*)) ) +item(tt(-0))( +When populating values of the `tt(opt_args)' associative array, don't +backslash-escape colons and backslashes and use NUL rather than colon for +joining multiple values. This option is described in more detail below, under +the heading em(var(spec)s: actions). +) enditem() em(var(spec)s: overview) @@ -3912,6 +3918,7 @@ specific contexts: on the first call `tt(_arguments $global_options)' is used, and on subsequent calls `tt(_arguments !$^global_options)'. em(var(spec)s: actions) +COMMENT(If you change this section title, change the references to it in running text.) In each of the forms above the var(action) determines how completions should be generated. Except for the `tt(->)var(string)' @@ -4033,9 +4040,21 @@ the normal arguments from the command line, i.e. the words from the command line after the command name excluding all options and their arguments. Options are stored in the associative array `tt(opt_args)' with option names as keys and their arguments as -the values. For options that have more than one argument these are -given as one string, separated by colons. All colons and backslashes -in the original arguments are preceded with backslashes. +the values. By default, all colons and backslashes in the value are escaped +with backslashes, and if an option has multiple arguments (for example, when +using an var(optspec) of the form `tt(*)var(optspec)'), they are joined with +(unescaped) colons. However, if the tt(-0) option was passed, no backslash +escaping is performed, and multiple values are joined with NUL bytes. For +example, after `tt(zsh -o foo:foo -o bar:bar -o )', the contents of +`tt(opt_args)' would be + +example(typeset -A opt_args=( [-o]='foo\:foo:bar\:bar:' )) + +by default, and + +example(typeset -A opt_args=( [-o]=$'foo:foo\x00bar:bar\x00' )) + +if tt(_arguments) had been called with the tt(-0) option. The parameter `tt(context)' is set when returning to the calling function to perform an action of the form `tt(->)var(string)'. It is set to an diff --git a/Src/Zle/computil.c b/Src/Zle/computil.c index ddfa70077..e08788e89 100644 --- a/Src/Zle/computil.c +++ b/Src/Zle/computil.c @@ -2375,6 +2375,23 @@ ca_parse_line(Cadef d, Cadef all, int multi, int first) return 0; } +/* Build a NUL-separated from a list. + * + * This is only used to populate values of $opt_args. + */ + +static char * +ca_nullist(LinkList l) +{ + if (l) { + char **array = zlinklist2array(l, 0 /* don't dup elements */); + char *ret = zjoin(array, '\0', 0 /* permanent allocation */); + free(array); /* the elements are owned by the list */ + return ret; + } else + return ztrdup(""); +} + /* Build a colon-list from a list. * * This is only used to populate values of $opt_args. @@ -2563,7 +2580,7 @@ bin_comparguments(char *nam, char **args, UNUSED(Options ops), UNUSED(int func)) case 's': min = 1; max = 1; break; case 'M': min = 1; max = 1; break; case 'a': min = 0; max = 0; break; - case 'W': min = 2; max = 2; break; + case 'W': min = 3; max = 3; break; case 'n': min = 1; max = 1; break; default: zwarnnam(nam, "invalid option: %s", args[0]); @@ -2795,11 +2812,20 @@ bin_comparguments(char *nam, char **args, UNUSED(Options ops), UNUSED(int func)) return 0; return 1; case 'W': - /* This gets two parameter names as arguments. The first is set to - * the current word sans any option prefixes handled by comparguments. + /* This gets two parameter names and one integer as arguments. + * + * The first parameter is set to the current word sans any option + * prefixes handled by comparguments. + * * The second parameter is set to an array containing the options on * the line and their arguments. I.e. the stuff _arguments returns - * to its caller in the `line' and `opt_args' parameters. */ + * to its caller in the `line' and `opt_args' parameters. + * + * The integer is one if the second parameter (which is just $opt_args, + * you know) should encode multiple values by joining them with NULs + * and zero if it should encode multiple values by joining them with + * colons after backslash-escaping colons and backslashes. + */ { Castate s; char **ret, **p; @@ -2807,6 +2833,7 @@ bin_comparguments(char *nam, char **args, UNUSED(Options ops), UNUSED(int func)) LinkList *a; Caopt o; int num; + int opt_args_use_NUL_separators = (args[3][0] != '0'); for (num = 0, s = lstate; s; s = s->snext) num += countlinknodes(s->args); @@ -2832,7 +2859,10 @@ bin_comparguments(char *nam, char **args, UNUSED(Options ops), UNUSED(int func)) if (*a) { *p++ = (o->gsname ? tricat(o->gsname, o->name, "") : ztrdup(o->name)); - *p++ = ca_colonlist(*a); + if (opt_args_use_NUL_separators) + *p++ = ca_nullist(*a); + else + *p++ = ca_colonlist(*a); } *p = NULL; diff --git a/Src/utils.c b/Src/utils.c index e258ef836..5158a70b1 100644 --- a/Src/utils.c +++ b/Src/utils.c @@ -3596,6 +3596,17 @@ strftimehandling: return buf - origbuf; } +/* + * Return a string consisting of the elements of 'arr' joined by the character + * 'delim', which will be metafied if necessary. The string will be allocated + * on the heap iff 'heap'. + * + * Comparable to: + * + * char metafied_delim[] = { Meta, delim ^ 32, '\0' }; + * sepjoin(arr, metafied_delim, heap) + */ + /**/ mod_export char * zjoin(char **arr, int delim, int heap) @@ -3894,10 +3905,12 @@ wordcount(char *s, char *sep, int mul) /* * 's' is a NULL-terminated array of strings. - * 'sep' is a string. + * 'sep' is a string, or NULL to split on ${IFS[1]}. * * Return a string consisting of the elements of 's' joined by 'sep', * allocated on the heap iff 'heap'. + * + * See also zjoin(). */ /**/ diff --git a/Test/Y03arguments.ztst b/Test/Y03arguments.ztst index fa4589374..a815799b3 100644 --- a/Test/Y03arguments.ztst +++ b/Test/Y03arguments.ztst @@ -231,9 +231,15 @@ tst_arguments '-a:one: :two' ':descr:{compadd -Q - $opt_args[-a]}' comptest $'tst -a 1:x \\2 \t' -0:opt_args with multiple arguments and quoting of colons and backslashes +0:opt_args with multiple arguments and quoting of colons and backslashes, part #1: default behaviour >line: {tst -a 1:x \2 1\:x:\\2 }{} + # Same as previous test, except with -0 and (qqqq) added + tst_arguments -0 : '-a:one: :two' ':descr:{compadd -Q - ${(qqqq)opt_args[-a]}}' + comptest $'tst -a 1:x \\2 \t' +0:opt_args with multiple arguments and quoting of colons and backslashes, part #2: NUL escaping +>line: {tst -a 1:x \2 $'1:x\0\\2' }{} + tst_arguments -a -b comptest $'tst rest -\t\C-w\eb\C-b-\t' 0:option completion with rest arguments on the line but not in the specs -- cgit v1.2.3 From e40938c1287beaeb6eaeb0a4ce62d786a65930d3 Mon Sep 17 00:00:00 2001 From: Oliver Kiddle Date: Sat, 23 Oct 2021 18:21:24 +0200 Subject: 49499 based on 49496 by Jun T.: fixes to option -A of _arguments --- ChangeLog | 3 +++ Src/Zle/computil.c | 27 +++++++++++++++++++-------- Test/Y03arguments.ztst | 35 +++++++++++++++++++++++++++++++++++ 3 files changed, 57 insertions(+), 8 deletions(-) (limited to 'Src/Zle/computil.c') diff --git a/ChangeLog b/ChangeLog index 77209ca6d..21e72305a 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,8 @@ 2021-10-23 Oliver Kiddle + * 49499 based on 49496 by Jun T.: Src/Zle/computil.c + Test/Y03arguments.ztst: fixes to option -A of _arguments + * 49500: Completion/Linux/Command/_lsns: new completion 2021-10-16 dana diff --git a/Src/Zle/computil.c b/Src/Zle/computil.c index e08788e89..b311d6c5f 100644 --- a/Src/Zle/computil.c +++ b/Src/Zle/computil.c @@ -2031,9 +2031,9 @@ ca_parse_line(Cadef d, Cadef all, int multi, int first) state.def = state.ddef = NULL; state.curopt = state.dopt = NULL; state.argbeg = state.optbeg = state.nargbeg = state.restbeg = state.actopts = - state.nth = state.inopt = state.inarg = state.opt = state.arg = 1; + state.nth = state.inarg = state.opt = state.arg = 1; state.argend = argend = arrlen(compwords) - 1; - state.singles = state.oopt = 0; + state.inopt = state.singles = state.oopt = 0; state.curpos = compcurrent; state.args = znewlinklist(); state.oargs = (LinkList *) zalloc(d->nopts * sizeof(LinkList)); @@ -2080,9 +2080,14 @@ ca_parse_line(Cadef d, Cadef all, int multi, int first) remnulargs(line); untokenize(line); - ca_inactive(d, argxor, cur - 1, 0); - if ((d->flags & CDF_SEP) && cur != compcurrent && !strcmp(line, "--")) { + if (argxor) { + ca_inactive(d, argxor, cur - 1, 0); + argxor = NULL; + } + if ((d->flags & CDF_SEP) && cur != compcurrent && state.actopts && + !strcmp(line, "--")) { ca_inactive(d, NULL, cur, 1); + state.actopts = 0; continue; } @@ -2235,11 +2240,17 @@ ca_parse_line(Cadef d, Cadef all, int multi, int first) } else if (multi && (*line == '-' || *line == '+') && cur != compcurrent && (ca_foreign_opt(d, all, line))) return 1; - else if (state.arg && - (!napat || cur <= compcurrent || !pattry(napat, line))) { + else if (state.arg && cur <= compcurrent) { /* Otherwise it's a normal argument. */ - if (napat && cur <= compcurrent) + + /* test pattern passed to -A. if it matches treat this as an unknown + * option and continue to the next word */ + if (napat && cur < compcurrent && state.actopts) { + if (pattry(napat, line)) + continue; ca_inactive(d, NULL, cur + 1, 1); + state.actopts = 0; + } arglast = 1; /* if this is the first normal arg after an option, may have been @@ -2293,7 +2304,7 @@ ca_parse_line(Cadef d, Cadef all, int multi, int first) if (adef) state.oopt = adef->num - state.nth; - if (state.def) + if (state.def && cur != compcurrent) argxor = state.def->xor; if (state.def && state.def->type != CAA_NORMAL && diff --git a/Test/Y03arguments.ztst b/Test/Y03arguments.ztst index bf41aead5..ef7a0ec56 100644 --- a/Test/Y03arguments.ztst +++ b/Test/Y03arguments.ztst @@ -359,6 +359,12 @@ 0:allowed option before -- >line: {tst -x }{ --} + tst_arguments -S '1:one' '2:two' + comptest $'tst -- -- \t' +0:only first of duplicate -- is ignored +>line: {tst -- -- }{} +>DESCRIPTION:{two} + tst_arguments -x :word comptest $'tst word -\t' 0:option after a word @@ -390,6 +396,25 @@ 0:continue completion after rest argument that looks like an option >line: {tst -a -x more }{} + tst_arguments -A '-*' -a -b '*: :(words)' + comptest $'tst -x -\t' +0:word matching -A pattern doesn't exclude options +>line: {tst -x -}{} +>DESCRIPTION:{option} +>NO:{-a} +>NO:{-b} + + tst_arguments -A '-*' -a -b '1:word:(word)' + comptest $'tst -x \t' +0:unrecognised word matching -A pattern not treated as a rest argument +>line: {tst -x word }{} + + tst_arguments -A "-*" '(3)-a' '1:one' '2:two' '3:three' '4:four' '*:extra' + comptest $'tst x -a \t' +0:exclusion from option following word matching -A pattern should not apply +>line: {tst x -a }{} +>DESCRIPTION:{three} + tst_arguments '*-v' comptest $'tst -v -\t' 0:repeatable options @@ -478,6 +503,16 @@ >NO:{-b} >NO:{-v} + tst_arguments -a -b -c '(-a)1:one' '(-b)2:two' '(-c)*:extra' + comptest $'tst x y z\e6\C-b-\t' +0:exclude option from normal argument to the right of the cursor +>line: {tst -}{ x y z} +>DESCRIPTION:{one} +>DESCRIPTION:{option} +>NO:{-a} +>NO:{-b} +>NO:{-c} + tst_arguments -a - set1 -d - set2 '(set2)-m' -n -o ':arg:(x)' - set2 -x comptest $'tst -m \t' 0:exclude own set from an option -- cgit v1.2.3 From 7cb980b5366afd5b82b3540961ea4a2e68faab8e Mon Sep 17 00:00:00 2001 From: Oliver Kiddle Date: Fri, 22 Oct 2021 21:50:52 +0200 Subject: 49518: fix exclusions for mixed - and + stacked options --- ChangeLog | 5 +++++ Etc/BUGS | 2 -- Src/Zle/computil.c | 39 +++++++++++++++++++++++++++++---------- Test/Y03arguments.ztst | 22 ++++++++++++++++++++++ 4 files changed, 56 insertions(+), 12 deletions(-) (limited to 'Src/Zle/computil.c') diff --git a/ChangeLog b/ChangeLog index 2fd7926ab..676a2584c 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2021-12-14 Oliver Kiddle + + * 49518: Src/Zle/computil.c, Etc/BUGS, Test/Y03arguments.ztst: + fix exclusions for mixed - and + stacked options + 2021-12-13 Oliver Kiddle * 49646: Doc/Zsh/mod_watch.yo, Src/Modules/watch.c, Src/prompt.c: diff --git a/Etc/BUGS b/Etc/BUGS index f1f8e44f8..5624fb24d 100644 --- a/Etc/BUGS +++ b/Etc/BUGS @@ -37,8 +37,6 @@ See test case in Test/C03traps.ztst. ------------------------------------------------------------------------ 44850 terminal issues with continuation markers ------------------------------------------------------------------------ -45422 _arguments !-x !+x ------------------------------------------------------------------------- users/24765 -direct terminals. Not a bug as such but we may need to do something if -direct values in TERM are ever common ------------------------------------------------------------------------ diff --git a/Src/Zle/computil.c b/Src/Zle/computil.c index b311d6c5f..c49d688c8 100644 --- a/Src/Zle/computil.c +++ b/Src/Zle/computil.c @@ -1035,7 +1035,7 @@ freecadef(Cadef d) freecaargs(d->rest); zsfree(d->nonarg); if (d->single) - zfree(d->single, 256 * sizeof(Caopt)); + zfree(d->single, 188 * sizeof(Caopt)); zfree(d, sizeof(*d)); d = s; } @@ -1079,6 +1079,21 @@ bslashcolon(char *s) return r; } +/* Get an index into the single array used in struct cadef + * opt is the option letter and pre is either - or + + * we only keep an array for the 94 ASCII characters from ! to ~ so + * with - and + prefixes, the array is double that at 188 elements + * returns -1 if opt is out-of-range + */ +static int +single_index(char pre, char opt) +{ + if (opt <= 20 || opt > 0x7e) + return -1; + + return opt + (pre == '-' ? -21 : 94 - 21); +} + /* Parse an argument definition. */ static Caarg @@ -1151,8 +1166,8 @@ alloc_cadef(char **args, int single, char *match, char *nonarg, int flags) ret->lastt = time(0); ret->set = NULL; if (single) { - ret->single = (Caopt *) zalloc(256 * sizeof(Caopt)); - memset(ret->single, 0, 256 * sizeof(Caopt)); + ret->single = (Caopt *) zalloc(188 * sizeof(Caopt)); + memset(ret->single, 0, 188 * sizeof(Caopt)); } else ret->single = NULL; ret->match = ztrdup(match); @@ -1558,9 +1573,10 @@ parse_cadef(char *nam, char **args) * pointer for the definition in the array for fast lookup. * But don't treat '--' as a single option called '-' */ - - if (single && name[1] && !name[2] && name[1] != '-') - ret->single[STOUC(name[1])] = opt; + if (single && name[1] && !name[2] && name[1] != '-') { + int sidx = single_index(*name, name[1]); + if (sidx >= 0) ret->single[sidx] = opt; + } if (again == 1) { /* Do it all again for `*-...'. */ @@ -1738,11 +1754,12 @@ ca_get_sopt(Cadef d, char *line, char **end, LinkList *lp) Caopt p, pp = NULL; char pre = *line++; LinkList l = NULL; + int sidx; *lp = NULL; for (p = NULL; *line; line++) { - if ((p = d->single[STOUC(*line)]) && p->active && - p->args && p->name[0] == pre) { + if ((sidx = single_index(pre, *line)) != -1 && + (p = d->single[sidx]) && p->active && p->args) { if (p->type == CAO_NEXT) { if (!l) *lp = l = newlinklist(); @@ -1813,7 +1830,7 @@ ca_get_arg(Cadef d, int n) /* Mark options as inactive. * d: option definitions for a set * pass either: - * xor: a list if exclusions + * xor: a list of exclusions * opts: if set, all options excluded leaving only nornal/rest arguments */ static void @@ -2195,6 +2212,7 @@ ca_parse_line(Cadef d, Cadef all, int multi, int first) char *p; Caopt tmpopt; + int sidx; if (cur != compcurrent && sopts && nonempty(sopts)) state.curopt = (Caopt) uremnode(sopts, firstnode(sopts)); @@ -2212,7 +2230,8 @@ ca_parse_line(Cadef d, Cadef all, int multi, int first) state.singles = (!pe || !*pe); for (p = line + 1; p < pe; p++) { - if ((tmpopt = d->single[STOUC(*p)])) { + if ((sidx = single_index(*line, *p)) != -1 && + (tmpopt = d->single[sidx])) { if (!state.oargs[tmpopt->num]) state.oargs[tmpopt->num] = znewlinklist(); diff --git a/Test/Y03arguments.ztst b/Test/Y03arguments.ztst index ef7a0ec56..200c83e8c 100644 --- a/Test/Y03arguments.ztst +++ b/Test/Y03arguments.ztst @@ -102,6 +102,28 @@ >NO:{+o} >NO:{-o} + tst_arguments -s -{a,b,c} \!-{d,e,f} \!+{d,e,f} + comptest $'tst -ad\t\024\t\bef\t' +0:mix of + and - and exclusion of stacked options +>line: {tst -ad}{} +>DESCRIPTION:{option} +>NO:{-b} +>NO:{-c} +>line: {tst -da}{} +>DESCRIPTION:{option} +>NO:{-b} +>NO:{-c} +>line: {tst -def}{} +>DESCRIPTION:{option} +>NO:{-a} +>NO:{-b} +>NO:{-c} + + tst_arguments -s -{a,b,c} +{a,b,c} + comptest $'tst -a +b +c\t' +0:mix of + and - and exclusion of stacked options +>line: {tst -a +b +ca}{} + tst_arguments '-o:1:(a):2:(b)' comptest $'tst \t\t\t' 0:two option arguments -- cgit v1.2.3 From 6b763233b2d7db08ed4c16400356d7deb292fe50 Mon Sep 17 00:00:00 2001 From: Oliver Kiddle Date: Thu, 16 Dec 2021 14:27:59 +0100 Subject: 49653: fix array indexing issue introduced with 49518 due to using decimal rather than hex 20 Also avoid comparing the current word against all options when the word doesn't start with - or +. --- ChangeLog | 3 +++ Src/Zle/computil.c | 8 +++++--- 2 files changed, 8 insertions(+), 3 deletions(-) (limited to 'Src/Zle/computil.c') diff --git a/ChangeLog b/ChangeLog index 12809f662..4e1af7445 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,8 @@ 2021-12-16 Oliver Kiddle + * 49653: Src/Zle/computil.c: fix array indexing issue introduced + with 49518 due to using decimal rather than hex 20 + * 49648 based on github #80 (Vincent Bernat): Completion/Unix/Command/_find, Completion/Zsh/Type/_globquals: invert before/since for date glob qualifiers completion diff --git a/Src/Zle/computil.c b/Src/Zle/computil.c index c49d688c8..59abb4cc4 100644 --- a/Src/Zle/computil.c +++ b/Src/Zle/computil.c @@ -1088,10 +1088,10 @@ bslashcolon(char *s) static int single_index(char pre, char opt) { - if (opt <= 20 || opt > 0x7e) + if (opt <= 0x20 || opt > 0x7e) return -1; - return opt + (pre == '-' ? -21 : 94 - 21); + return opt + (pre == '-' ? -0x21 : 94 - 0x21); } /* Parse an argument definition. */ @@ -2158,7 +2158,8 @@ ca_parse_line(Cadef d, Cadef all, int multi, int first) /* See if it's an option. */ - if (state.opt == 2 && (state.curopt = ca_get_opt(d, line, 0, &pe)) && + if (state.opt == 2 && (*line == '-' || *line == '+') && + (state.curopt = ca_get_opt(d, line, 0, &pe)) && (state.curopt->type == CAO_OEQUAL ? (compwords[cur] || pe[-1] == '=') : (state.curopt->type == CAO_EQUAL ? @@ -2206,6 +2207,7 @@ ca_parse_line(Cadef d, Cadef all, int multi, int first) state.curopt = NULL; } } else if (state.opt == 2 && d->single && + (*line == '-' || *line == '+') && ((state.curopt = ca_get_sopt(d, line, &pe, &sopts)) || (cur != compcurrent && sopts && nonempty(sopts)))) { /* Or maybe it's a single-letter option? */ -- cgit v1.2.3