diff options
-rw-r--r-- | ChangeLog | 56 | ||||
-rw-r--r-- | Completion/Linux/Command/_fusermount | 2 | ||||
-rw-r--r-- | Completion/Unix/Command/_mount | 6 | ||||
-rw-r--r-- | Completion/Zsh/Context/_brace_parameter | 1 | ||||
-rw-r--r-- | Config/version.mk | 4 | ||||
-rw-r--r-- | Doc/Zsh/compsys.yo | 4 | ||||
-rw-r--r-- | Doc/Zsh/expn.yo | 3 | ||||
-rw-r--r-- | Functions/Misc/zed | 2 | ||||
-rw-r--r-- | Functions/Zle/bracketed-paste-magic | 44 | ||||
-rw-r--r-- | NEWS | 24 | ||||
-rw-r--r-- | Src/Zle/computil.c | 91 | ||||
-rw-r--r-- | Src/input.c | 2 | ||||
-rw-r--r-- | Src/zsh.h | 4 | ||||
-rw-r--r-- | Test/B02typeset.ztst | 2 | ||||
-rw-r--r-- | Test/C02cond.ztst | 2 | ||||
-rw-r--r-- | Test/D07multibyte.ztst | 32 | ||||
-rw-r--r-- | Test/Y03arguments.ztst | 251 |
17 files changed, 432 insertions, 98 deletions
@@ -1,3 +1,56 @@ +2016-12-09 Peter Stephenson <p.w.stephenson@ntlworld.com> + + * unposted: Config/version.mk: 5.2-test-3. + + * users/22161: Doc/Zsh/expn.yo: the (E) parameter flag is one + after every other use of indexing. + +2016-12-09 Daniel Shahaf <d.s@daniel.shahaf.name> + + * 40117: Doc/Zsh/compsys.yo, Src/input.c: Revert a hunk of + 40035 that changed semantics incorrectly. + +2016-12-09 Peter Stephenson <p.stephenson@samsung.com> + + * unposted: Test/D07multibyte.ztst: minor typos. + + * 40138: Test/D07multibyte.ztst: Put the regex test last as it + has an additional dependency, and note this in a failure + message. + +2016-12-09 Daniel Shahaf <d.s@daniel.shahaf.name> + + * 40126: Functions/Misc/zed: zed (fned): When editing a new + function. escape its name. + +2016-12-08 Oliver Kiddle <opk@zsh.org> + + * 40130: NEWS: mention some changes since 5.2 + + * 40129: Src/Zle/computil.c, Test/Y03arguments.ztst: + revert 39611, add code comments and test cases for _arguments + + * c.f. 40119: Src/zsh.h: correct typo in comment + + * 40114: Completion/Zsh/Context/_brace_parameter: complete + :/ with other parameter operators + +2016-12-06 Barton E. Schaefer <schaefer@zsh.org> + + * Zhiming Wang: 40115: Functions/Zle/bracketed-paste-magic: + revert 38579 due to bug restoring BUFFER after history search + + * 40110: Test/B02typeset.ztst: ignore strerror text in test + output, it differs by OS + + * 40110: Test/C02cond.ztst: discard stderr when looking for + a path to the "mount" command, to avoid spurious test failure + +2016-12-06 Mikael Magnusson <mikachu@gmail.com> + + * 40107: Completion/Linux/Command/_fusermount, + Completion/Unix/Command/_mount: fix quoting + 2016-12-06 Peter Stephenson <p.w.stephenson@ntlworld.com> * unposted: Config/version.mk: 5.2-test-2. @@ -1917,9 +1970,6 @@ 2016-06-09 Oliver Kiddle <opk@zsh.org> - * 38579: Functions/Zle/bracketed-paste-magic: simplify saving - and restoring of state - * 38641: Completion/Base/Utility/_values: allow for values which resemble compadd options diff --git a/Completion/Linux/Command/_fusermount b/Completion/Linux/Command/_fusermount index d3d1647fa..02cb57237 100644 --- a/Completion/Linux/Command/_fusermount +++ b/Completion/Linux/Command/_fusermount @@ -20,7 +20,7 @@ case "$state" in _files -/ else mtpts=(${${${"${(f)$(< /etc/mtab)}"}#* }%% *}) - _canonical_paths mounted 'mounted filesystem' $mtpts + _canonical_paths mounted 'mounted filesystem' "${(@g::)mtpts}" fi ;; esac diff --git a/Completion/Unix/Command/_mount b/Completion/Unix/Command/_mount index e2c3cfdad..7c5605016 100644 --- a/Completion/Unix/Command/_mount +++ b/Completion/Unix/Command/_mount @@ -959,9 +959,9 @@ udevordir) esac local MATCH MBEGIN MEND - mp_tmp=("${(@qg::)mp_tmp}") - dpath_tmp=( "${(@Mqg::)dev_tmp:#/*}" ) - dev_tmp=( "${(@qg::)dev_tmp:#/*}" ) + mp_tmp=("${(@g::)mp_tmp}") + dpath_tmp=( "${(@Mg::)dev_tmp:#/*}" ) + dev_tmp=( "${(@g::)dev_tmp:#/*}" ) _alternative \ 'device-labels:device label:compadd -a dev_tmp' \ diff --git a/Completion/Zsh/Context/_brace_parameter b/Completion/Zsh/Context/_brace_parameter index e77d4c58b..e4f5e6639 100644 --- a/Completion/Zsh/Context/_brace_parameter +++ b/Completion/Zsh/Context/_brace_parameter @@ -197,6 +197,7 @@ elif compset -P '*:'; then '\:=:unconditionally assign value to parameter' '?:print error if parameter is set and non-null' '#:filter value matching pattern' + '/:replace whole word matching pattern' '|:set difference' '*:set intersection' '^:zip arrays' diff --git a/Config/version.mk b/Config/version.mk index ca3da65ca..7aca34cb3 100644 --- a/Config/version.mk +++ b/Config/version.mk @@ -27,5 +27,5 @@ # This must also serve as a shell script, so do not add spaces around the # `=' signs. -VERSION=5.2-test-2 -VERSION_DATE='December 6, 2016' +VERSION=5.2-test-3 +VERSION_DATE='December 9, 2016' diff --git a/Doc/Zsh/compsys.yo b/Doc/Zsh/compsys.yo index 60ef9ee2c..ceb98c7bc 100644 --- a/Doc/Zsh/compsys.yo +++ b/Doc/Zsh/compsys.yo @@ -144,8 +144,8 @@ directory mentioned in the tt(fpath) parameter, and should be autoloaded few utility functions, arrange for all the necessary shell functions to be autoloaded, and will then re-define all widgets that do completion to use the new system. If you use the tt(menu-select) widget, which is part of the -tt(zsh/complist) module, you should make sure that the module is loaded -before the call to tt(compinit) so that the widget is also +tt(zsh/complist) module, you should make sure that that module is loaded +before the call to tt(compinit) so that that widget is also re-defined. If completion styles (see below) are set up to perform expansion as well as completion by default, and the TAB key is bound to tt(expand-or-complete), tt(compinit) will rebind it to tt(complete-word); diff --git a/Doc/Zsh/expn.yo b/Doc/Zsh/expn.yo index 87ca7905d..cf4f69ea2 100644 --- a/Doc/Zsh/expn.yo +++ b/Doc/Zsh/expn.yo @@ -1394,7 +1394,8 @@ item(tt(B))( Include the index of the beginning of the match in the result. ) item(tt(E))( -Include the index of the end of the match in the result. +Include the index one character past the end of the match in the result +(note this is inconsistent with other uses of parameter index). ) item(tt(M))( Include the matched portion in the result. diff --git a/Functions/Misc/zed b/Functions/Misc/zed index 0ea90c7df..77d392bc3 100644 --- a/Functions/Misc/zed +++ b/Functions/Misc/zed @@ -76,7 +76,7 @@ if ((fun)) then if [[ $var = *\#\ undefined* ]] then var="$(autoload +X $1; functions -- $1)" elif [[ -z $var ]] then - var="$1() { + var="${(q-)1} () { }" fi vared -M zed -m zed-vicmd var && eval function "$var" diff --git a/Functions/Zle/bracketed-paste-magic b/Functions/Zle/bracketed-paste-magic index fb584d595..c46f741d5 100644 --- a/Functions/Zle/bracketed-paste-magic +++ b/Functions/Zle/bracketed-paste-magic @@ -145,26 +145,27 @@ bracketed-paste-magic() { done fi + # Save context, create a clean slate for the paste + integer bpm_mark=$MARK bpm_cursor=$CURSOR bpm_region=$REGION_ACTIVE + integer bpm_numeric=${NUMERIC:-1} + local bpm_buffer=$BUFFER + fc -p -a /dev/null 0 0 + BUFFER= + zstyle -a :bracketed-paste-magic inactive-keys bpm_inactive if zstyle -s :bracketed-paste-magic active-widgets bpm_active '|'; then - # Save context, create a clean slate for the paste - integer bpm_mark=$MARK bpm_region=$REGION_ACTIVE - integer bpm_numeric=${NUMERIC:-1} - integer bpm_limit=$UNDO_LIMIT_NO bpm_undo=$UNDO_CHANGE_NO - BUFFER= - CURSOR=1 - zle .split-undo - UNDO_LIMIT_NO=$UNDO_CHANGE_NO - fc -p -a /dev/null 0 0 + # There are active widgets. Reprocess $PASTED as keystrokes. + NUMERIC=1 + zle -U - $PASTED + if [[ $bmp_keymap = vicmd ]]; then zle -K viins fi - # There are active widgets. Reprocess $PASTED as keystrokes. - NUMERIC=1 - zle -U - "$PASTED" - # Just in case there are active undo widgets + zle .split-undo + integer bpm_limit=$UNDO_LIMIT_NO bpm_undo=$UNDO_CHANGE_NO + UNDO_LIMIT_NO=$UNDO_CHANGE_NO while [[ -n $PASTED ]] && zle .read-command; do PASTED=${PASTED#$KEYS} @@ -182,16 +183,21 @@ bracketed-paste-magic() { done PASTED=$BUFFER - # Restore state - zle -K $bpm_keymap - fc -P - MARK=$bpm_mark - REGION_ACTIVE=$bpm_region - NUMERIC=$bpm_numeric + # Reset the undo state zle .undo $bpm_undo UNDO_LIMIT_NO=$bpm_limit + + zle -K $bpm_keymap fi + # Restore state + BUFFER=$bpm_buffer + MARK=$bpm_mark + CURSOR=$bpm_cursor + REGION_ACTIVE=$bpm_region + NUMERIC=$bpm_numeric + fc -P + # PASTED has been updated, run the paste-finish functions if zstyle -a :bracketed-paste-magic paste-finish bpm_hooks; then for bpm_func in $bpm_hooks; do @@ -26,6 +26,30 @@ The output of "typeset -p" uses "export" commands or the "-g" option for parameters that are not local to the current scope. Previously, all output was in the form of "typeset" commands, never using "-g". +vi-repeat-change can repeat user-defined widgets if the widget calls +zle -f vichange. + +The parameter $registers now makes the contents of vi register buffers +available to user-defined widgets. + +New vi-up-case and vi-down-case builtin widgets bound to gU/gu (or U/u +in visual mode) for doing case conversion. + +A new select-word-match function provides vim-style text objects with +configurable word boundaries using the existing match-words-by-style +mechanism. + +Support for the conditional expression [[ -v var ]] to test if a +variable is set for compatibility with other shells. + +The print and printf builtins have a new option -v to assign the output +to a variable. This is for bash compatibility but with the additional +feature that, for an array, a separate element is used each time the +format is reused. + +New x: syntax in completion match specifications make it possible to +disable match specifications hardcoded in completion functions. + Changes from 5.1.1 to 5.2 ------------------------- diff --git a/Src/Zle/computil.c b/Src/Zle/computil.c index c78167329..192ddeab9 100644 --- a/Src/Zle/computil.c +++ b/Src/Zle/computil.c @@ -914,7 +914,7 @@ struct cadef { int lastt; /* last time this was used */ Caopt *single; /* array of single-letter options */ char *match; /* -M spec to use */ - int argsactive; /* if arguments are still allowed */ + int argsactive; /* if normal arguments are still allowed */ /* used while parsing a command line */ char *set; /* set name prefix (<name>-), shared */ char *sname; /* set name */ @@ -922,7 +922,7 @@ struct cadef { char *nonarg; /* pattern for non-args (-A argument) */ }; -#define CDF_SEP 1 +#define CDF_SEP 1 /* -S was specified: -- terminates options */ /* Description for an option. */ @@ -939,11 +939,11 @@ struct caopt { int not; /* don't complete this option (`!...') */ }; -#define CAO_NEXT 1 -#define CAO_DIRECT 2 -#define CAO_ODIRECT 3 -#define CAO_EQUAL 4 -#define CAO_OEQUAL 5 +#define CAO_NEXT 1 /* argument follows in next argument (`-opt:...') */ +#define CAO_DIRECT 2 /* argument follows option directly (`-opt-:...') */ +#define CAO_ODIRECT 3 /* argument may follow option directly (`-opt+:...') */ +#define CAO_EQUAL 4 /* argument follows mandatory equals (`-opt=-:...') */ +#define CAO_OEQUAL 5 /* argument follows optional equals (`-opt=:...') */ /* Description for an argument */ @@ -957,7 +957,7 @@ struct caarg { char *opt; /* option name if for an option */ int num; /* it's the num'th argument */ int min; /* it's also this argument, using opt. args */ - int direct; /* number was given directly */ + int direct; /* true if argument number was given explicitly */ int active; /* still allowed on command line */ char *set; /* set name, shared */ }; @@ -1772,7 +1772,12 @@ ca_get_arg(Cadef d, int n) return NULL; } -/* Use a xor list, marking options as inactive. */ +/* Mark options as inactive. + * d: option definitions for a set + * pass either: + * xor: a list if exclusions + * opts: if set, all options excluded leaving only nornal/rest arguments + * if ca_xor list initialised, exclusions are added to it */ static LinkList ca_xor; @@ -1848,22 +1853,37 @@ ca_inactive(Cadef d, char **xor, int cur, int opts, char *optname) typedef struct castate *Castate; -/* - * **** DOCUMENT ME **** - * - * This structure and its use are a nightmare. - */ +/* Encapsulates details from parsing the current line against a particular set, + * Covers positions of options and normal arguments. Used as a linked list + * with one state for each set. */ struct castate { - Castate snext; - Cadef d; - int nopts; - Caarg def, ddef; - Caopt curopt, dopt; - int opt, arg, argbeg, optbeg, nargbeg, restbeg, curpos, argend; - int inopt, inrest, inarg, nth, doff, singles, oopt, actopts; - LinkList args; - LinkList *oargs; + Castate snext; /* state for next set */ + Cadef d; /* parsed _arguments specs for the set */ + int nopts; /* number of specified options (size of oargs) */ + Caarg def; /* definition for the current set */ + Caarg ddef; + Caopt curopt; /* option description corresponding to option found on the command-line */ + Caopt dopt; + int opt; /* the length of the option up to a maximum of 2 */ + int arg; /* completing arguments to an option or rest args */ + int argbeg; /* position of first rest argument (+1) */ + int optbeg; /* first word after the last option to the left of the cursor: + * in effect the start of any arguments to the current option */ + int nargbeg; /* same as optbeg but used during parse */ + int restbeg; /* same as argbeg but used during parse */ + int curpos; /* current word position */ + int argend; /* total number of words */ + int inopt; /* set to current word pos if word is a recognised option */ + int inrest; /* unused */ + int inarg; /* in a normal argument */ + int nth; /* number of current normal arg */ + int doff; /* length of current option */ + int singles; /* argument consists of clumped options */ + int oopt; + int actopts; /* count of active options */ + LinkList args; /* list of non-option args used for populating $line */ + LinkList *oargs; /* list of lists used for populating $opt_args */ }; static struct castate ca_laststate; @@ -1909,7 +1929,9 @@ ca_opt_arg(Caopt opt, char *line) return ztrdup(line); } -/* Parse a command line. */ +/* Parse the command line for a particular argument set (d). + * Returns 1 if the set should be skipped because it doesn't match + * existing options on the line. */ static int ca_parse_line(Cadef d, int multi, int first) @@ -1971,7 +1993,7 @@ ca_parse_line(Cadef d, int multi, int first) goto end; } - if (d->nonarg) + if (d->nonarg) /* argument to -A */ napat = patcompile(d->nonarg, 0, NULL); /* Loop over the words from the line. */ @@ -2009,8 +2031,9 @@ ca_parse_line(Cadef d, int multi, int first) return 1; continue; } - /* We've got a definition for an argument, skip to the next. */ + /* We've got a definition for an option/rest argument. For an option, + * this means that we're completing arguments to that option. */ if (state.def) { state.arg = 0; if (state.curopt) @@ -2159,8 +2182,7 @@ ca_parse_line(Cadef d, int multi, int first) state.opt = 0; else state.curopt = NULL; - } else if (multi && (*line == '-' || *line == '+') && cur != compcurrent && - ca_get_opt(d, line, 0, NULL) + } else if (multi && (*line == '-' || *line == '+') && cur != compcurrent #if 0 /**** Ouch. Using this will disable the mutual exclusion of different sets. Not using it will make the -A @@ -2177,6 +2199,8 @@ ca_parse_line(Cadef d, int multi, int first) return 1; arglast = 1; + /* if this is the first normal arg after an option, may have been + * earlier normal arguments if they're intermixed with options */ if (state.inopt) { state.inopt = 0; state.nargbeg = cur - 1; @@ -2526,25 +2550,26 @@ bin_comparguments(char *nam, char **args, UNUSED(Options ops), UNUSED(int func)) if (!(def = get_cadef(nam, args + 1))) return 1; - multi = !!def->snext; + multi = !!def->snext; /* if we have sets */ ca_parsed = cap; ca_xor = (multi ? newlinklist() : NULL); - while (def) { + while (def) { /* for each set */ use = !ca_parse_line(def, multi, first); nx = ca_xor; - ca_xor = NULL; + ca_xor = NULL; /* don't want to duplicate the xors in the list */ while ((def = def->snext)) { if (nx) { for (node = firstnode(nx); node; incnode(node)) { xor[0] = (char *) getdata(node); if (!strcmp(xor[0], def->sname) || ca_inactive(def, xor, compcurrent, 0, NULL)) - break; + break; /* exclude this whole set */ } - if (!node) + if (!node) /* continue with this set */ break; } + /* entire set was excluded, continue to next set */ } ca_xor = nx; if (use && def) { diff --git a/Src/input.c b/Src/input.c index fe94b8ef7..eb968ea72 100644 --- a/Src/input.c +++ b/Src/input.c @@ -51,7 +51,7 @@ * Note that the input string is itself used as the input buffer: it is not * copied, nor is it every written back to, so using a constant string * should work. Consequently, when passing areas of memory from the heap - * it is necessary that the heap last as long as the operation of reading + * it is necessary that that heap last as long as the operation of reading * the string. After the string is read, the stack should be popped with * inpop(), which effectively flushes any unread input as well as restoring * the previous input state. @@ -1589,8 +1589,8 @@ struct zpc_disables_save { struct zpc_disables_save *next; /* * Bit vector of ZPC_COUNT disabled characters. - * We'll live dangerously and assumed ZPC_COUNT is no greater - * than the number of bits an unsigned int. + * We'll live dangerously and assume ZPC_COUNT is no greater + * than the number of bits in an unsigned int. */ unsigned int disables; }; diff --git a/Test/B02typeset.ztst b/Test/B02typeset.ztst index 9c56c7e5e..b27bb4f6b 100644 --- a/Test/B02typeset.ztst +++ b/Test/B02typeset.ztst @@ -720,4 +720,4 @@ 0:when cannot change UID, the command isn't run # 'date' did not run. >Status is printed, 1 -?(eval):2: failed to change user ID: operation not permitted +*?*: failed to change user ID: * diff --git a/Test/C02cond.ztst b/Test/C02cond.ztst index 27a22593d..38525016c 100644 --- a/Test/C02cond.ztst +++ b/Test/C02cond.ztst @@ -146,7 +146,7 @@ # can't be bothered with -S - if [[ ${mtab::="$({mount || /sbin/mount})"} = *[(]?*[)] ]]; then + if [[ ${mtab::="$({mount || /sbin/mount || /usr/sbin/mount} 2>/dev/null)"} = *[(]?*[)] ]]; then print -u $ZTST_fd 'This test takes two seconds...' else unmodified_ls="$(ls -lu $unmodified)" diff --git a/Test/D07multibyte.ztst b/Test/D07multibyte.ztst index 3a6e95543..d5a15ef04 100644 --- a/Test/D07multibyte.ztst +++ b/Test/D07multibyte.ztst @@ -500,18 +500,6 @@ # aren't quite double width, but the arithmetic is correct. # It appears just to be an effect of the font. - if zmodload zsh/regex 2>/dev/null; then - [[ $'\ua0' =~ '^.$' ]] && print OK - [[ $'\ua0' =~ $'^\ua0$' ]] && print OK - [[ $'\ua0'X =~ '^X$' ]] || print OK - else - ZTST_skip="regexp library not found." - fi -0:Ensure no confusion on metafied input to regex module ->OK ->OK ->OK - () { emulate -L zsh setopt errreturn @@ -561,7 +549,7 @@ "↓" } : $functions) -0:Multibtye handled of functions parameter +0:Multibtye handling of functions parameter if [[ -n ${$(locale -a 2>/dev/null)[(R)pl_PL.utf8]} ]]; then ( @@ -574,7 +562,7 @@ print ? ) else - ZTST_skip="No Polish UTF-8 local found, skipping sort test" + ZTST_skip="No Polish UTF-8 locale found, skipping sort test" fi 0:Sorting of metafied Polish characters >a ą b c ć d e ę f @@ -583,3 +571,19 @@ printf '%q%q\n' 你你 0:printf %q and quotestring and general metafy / token madness >你你 + +# This test is kept last as it introduces an additional +# dependency on the system regex library. + if zmodload zsh/regex 2>/dev/null; then + [[ $'\ua0' =~ '^.$' ]] && print OK + [[ $'\ua0' =~ $'^\ua0$' ]] && print OK + [[ $'\ua0'X =~ '^X$' ]] || print OK + else + ZTST_skip="regexp library not found." + fi +0:Ensure no confusion on metafied input to regex module +>OK +>OK +>OK +F:A failure here may indicate the system regex library does not +F:support character sets outside the portable 7-bit range. diff --git a/Test/Y03arguments.ztst b/Test/Y03arguments.ztst index d59ed5424..b5a5a4be9 100644 --- a/Test/Y03arguments.ztst +++ b/Test/Y03arguments.ztst @@ -40,6 +40,15 @@ >NO:{a} >NO:{b} +# it ought to be possible to include the quoted backslash here + tst_arguments ':desc2:((a\:a\ value b\:other\\value))' + comptest $'tst \t' +0:a and b with descriptions +>line: {tst }{} +>DESCRIPTION:{desc2} +>NO:{a -- a value} +>NO:{b -- othervalue} + tst_arguments ':desc1:(arg1)' ':desc2:(arg2)' ':desc3:(arg3)' comptest $'tst \t\t\t\C-w\C-w\C-w\C-d' 0:three arguments @@ -81,6 +90,74 @@ >line: {tst -o a }{} >line: {tst -o a b }{} + tst_arguments '!-x:arg:(ok)' + comptest $'tst -x \t' +0:option argument to ignored option +>line: {tst -x ok }{} + + tst_arguments '!-a' -b + comptest $'tst -\t' +0:ignored option not completed +>line: {tst -b }{} + + tst_arguments +x +y '!+z' ':arg:(x)' + comptest $'tst +z \t' +0:ignored option is not taken to be the normal argument +>line: {tst +z x }{} + + tst_arguments --known --other + comptest $'tst --unknown -\t' +0:unrecognised option has no effect on proceedings with no normal arguments +>line: {tst --unknown --}{} + + tst_arguments +x +y ':arg:(x)' + comptest $'tst +z \t' +0:unrecognised option is taken to be the normal argument +>line: {tst +z +}{} + + tst_arguments '*-a:value:(1)' + comptest $'tst -a\t\t -a=\t' +0:option argument follows in next argument +>line: {tst -a }{} +>line: {tst -a 1 }{} +>line: {tst -a 1 -a=}{} +>MESSAGE:{no arguments} + + tst_arguments '*-a+:value:(1)' + comptest $'tst -a\t -a \t -a=\t' +0:option argument either direct or in following argument +>line: {tst -a1 }{} +>line: {tst -a1 -a 1 }{} +>line: {tst -a1 -a 1 -a=}{} + + tst_arguments '*-a-:value:(1)' + comptest $'tst -a\t -a \t=\t' +0:option argument follows directly +>line: {tst -a1 }{} +>line: {tst -a1 -a -a}{} +>line: {tst -a1 -a -a=}{} + + tst_arguments '*-a=:value:(1)' + comptest $'tst -a\t\t -a \t' +0:option argument follows optional equals +>line: {tst -a=}{} +>line: {tst -a=1 }{} +>line: {tst -a=1 -a 1 }{} + + tst_arguments -s '*-a=:value:(1)' + comptest $'tst -a\t-a=\t -a \t' +0:option argument follows optional equals, with -s +>line: {tst -a1 }{} +>line: {tst -a1 -a=1 }{} +>line: {tst -a1 -a=1 -a 1 }{} + + tst_arguments '*-a=-:value:(1)' + comptest $'tst -a\t\t-a \t' +0:option argument follows mandatory equals +>line: {tst -a=}{} +>line: {tst -a=1 }{} +>line: {tst -a=1 -a -a=}{} + tst_arguments '-x:arg:' comptest $'tst -x\t' 0:sticky option argument @@ -99,6 +176,11 @@ >DESCRIPTION:{option} >NO:{-x} + tst_arguments '-x' ": :_guard '[0-9]#' number" + comptest $'tst -\t' +0:argument beginning with minus, guard on rest argument +>line: {tst -x }{} + tst_arguments '-o::optarg:(oa)' ':arg1:(a1)' comptest $'tst -o\t\t' 0:optional option argument @@ -110,9 +192,10 @@ >NO:{a1} tst_arguments '-o:*a:a:(a)' ':A:(A)' ':B:(B)' - comptest $'tst A -o a \t' + comptest $'tst A -o a \t\C-W\C-w-a -b -c a \t' 0:variable length option arguments >line: {tst A -o a B }{} +>line: {tst A -o -a -b -c a B }{} tst_arguments -s '-a' '-b' ':descr:{compadd - $+opt_args[-a]}' comptest $'tst -ab \t' @@ -129,6 +212,40 @@ 0:rest arguments >line: {tst arg -b }{} + tst_arguments -a :more '*:rest:{ compadd - $words }' + comptest $'tst x -a rest \t' +0:rest arguments with single colon +>line: {tst x -a rest }{} +>NO:{-a} +>NO:{rest} +>NO:{tst} +>NO:{x} + + tst_arguments -a :more '*::rest:{ compadd - $words }' + comptest $'tst x -a rest \t\eb\eb\eb\et\C-E \t' +0:rest arguments with two colons +>line: {tst x -a rest rest }{} +>line: {tst -a x rest rest }{} +>NO:{rest} +>NO:{x} + + tst_arguments -a -b :more '*:::rest:{ compadd - $words }' + comptest $'tst -b x -a -x rest \t' +0:rest arguments with three colons +>line: {tst -b x -a -x rest }{} +>NO:{-x} +>NO:{rest} + + tst_arguments -a ::more '*:::rest:{ compadd - $words }' + comptest $'tst -a opt rest \t' +0:rest arguments with three colons following optional argument +>line: {tst -a opt rest rest }{} + + tst_arguments -a::arg '*:::rest:{ compadd - $words }' + comptest $'tst -a opt rest \t' +0:rest arguments with three colons following optional argument to an option +>line: {tst -a opt rest rest }{} + tst_arguments '-e:*last:::b:{compadd "${(j:,:)words}"}' ':arg1:(arg1)' comptest $'tst -\t\tla\t\C-hst\t\t\eb\eb\C-b\t\t' 0:words array in rest arguments @@ -140,14 +257,14 @@ >line: {tst -e ,last }{ last arg1} >line: {tst -e ,last ,last,,last }{ last arg1} - tst_arguments -s '-d+:msg1:' '*::msg2:{compadd $CURRENT}' + tst_arguments -s '-d+:msg1:' '*::msg2:{compadd $CURRENT}' comptest $'tst add \t\t\t' 0:opt_args >line: {tst add 2 }{} >line: {tst add 2 3 }{} >line: {tst add 2 3 4 }{} - tst_arguments -s '-a' '-b' '-c' ':words:compadd - abyyy abzzz' + tst_arguments -s '-a' '-b' '-c' ':words:compadd - abyyy abzzz' comptest $'tst ab\t' 0:options and words (zsh-workers:12257) >line: {tst ab}{} @@ -155,6 +272,12 @@ >NO:{abyyy} >NO:{abzzz} + tst_arguments -M 'm:{j}={y}' -y -n ':yes/no:(y n)' + comptest $'tst j\t\eb-\C-e\t' +0:matcher applies to options but not rest arguments +>line: {tst j}{} +>line: {tst -y }{} + tst_arguments -x :word comptest $'tst -- -\t' 0:option after -- @@ -175,15 +298,15 @@ 0:option after a word >line: {tst word -x }{} - tst_arguments -A '-*' -x :word + tst_arguments -A'-*' -x :word comptest $'tst word -\t' -0:option after word that doesn't match -A pattern +0:option after word that doesn't match -A pattern, no space before pattern >line: {tst word -}{} >MESSAGE:{no more arguments} tst_arguments -A '-*' -x ':word:(-word)' comptest $'tst word\eB\C-b-\t' -0:option before a word that doesn't match -A pattern +0:option before a word that doesn't match -A pattern, separate -A from pattern >line: {tst -}{ word} >DESCRIPTION:{word} >NO:{-word} @@ -195,12 +318,68 @@ 0:continue completion after rest argument that looks like an option >line: {tst -a -x more }{} + tst_arguments '*-v' + comptest $'tst -v -\t' +0:repeatable options +>line: {tst -v -v }{} + +# necessary to exclude the rest arguments for the other set because +# it is currently any unknown option rather than options from another +# set that causes a set to be excluded tst_arguments -A '-*' - help -h -V - other -a '*: :(-x more)' comptest $'tst -a -x m\t' 0:continue completion after rest argument that looks like an option (with sets) ->line: {tst -a -x more }{} +>line: {tst -a -x m}{} +#>line: {tst -a -x more }{} + + tst_arguments - '(help)' -h -V - other -a '*:rest:(1 2 3)' + comptest $'tst -h \t' +0:unknown option disables whole set (without -A) +>line: {tst -h }{} +>MESSAGE:{no arguments} + + tst_arguments -A "-*" - '(help)' -h -V - other -a '*:rest:(1 2 3)' + comptest $'tst -h \t' +0:unknown option disables whole set (with -A) +>line: {tst -h }{} +>MESSAGE:{no arguments} - tst_arguments '(-v)-a' '(set1--m -a)-b' - '(set1)' -m -n - set2 -v -w + tst_arguments '(-C)-a' - set1 -C -v - set2 '(-a)-C' -w + comptest $'tst -a -\t' $'\C-w\C-w-C -\t' +0:exclude option common to two sets and from one common option +>line: {tst -a -}{} +>DESCRIPTION:{option} +>NO:{-v} +>NO:{-w} +>line: {tst -C -}{} +>DESCRIPTION:{option} +>NO:{-a} +>NO:{-v} +>NO:{-w} + +# _arguments doesn't know what rest arguments might be so any non-option +# might apply: for the one set, it accepts "a" + tst_arguments -e - one -o '*:number:(1 2)' - two '(-e)*:letter:(a b)' + comptest $'tst \t' $'a -\t' +0:rest argument rule in two sets +>line: {tst }{} +>DESCRIPTION:{letter} +>NO:{a} +>NO:{b} +>DESCRIPTION:{number} +>NO:{1} +>NO:{2} +>line: {tst a -}{} +>DESCRIPTION:{option} +>NO:{-e} +>NO:{-o} + + tst_arguments '(set1-: set2-* set3-1)-a' - set1 '1: :(1)' '2: :(2)' - set2 '*:rest:(rest)' - set3 '1:num:(num)' '*: :(allowable)' - set4 ': :(allowed)' + comptest $'tst -a \t' +0:exclude various forms of rest argument in set specific form +>line: {tst -a allow}{} + + tst_arguments '(-v)-a' '(set1--m -a)-b' - '(set1)' '( -a )-m' '( )-n' - set2 '(-w)*-v' -w comptest $'tst -a -\t' $'\C-w\C-w-'{b,m,v}$' -\t' 0:exclusion lists >line: {tst -a -}{} @@ -214,19 +393,36 @@ >NO:{-n} >NO:{-v} >NO:{-w} ->line: {tst -m -}{} +>line: {tst -m -b }{} +>line: {tst -v -}{} >DESCRIPTION:{option} >NO:{-a} >NO:{-b} >NO:{-v} ->NO:{-w} ->line: {tst -v -}{} + + 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 +>line: {tst -m -a }{} + +# the following two tests only verify the current questionable behaviour + tst_arguments - set1 '(set2)-a' -m -n - set2 -a -t -u + comptest $'tst -a -\t' +0:exclude later set from an option common to both +>line: {tst -a -}{} >DESCRIPTION:{option} ->NO:{-a} ->NO:{-b} >NO:{-m} >NO:{-n} ->NO:{-w} + + tst_arguments - set2 -a -t -u - set1 '(set2)-a' -m -n + comptest $'tst -a -\t' +0:exclude later set from an option common to both +>line: {tst -a -}{} +>DESCRIPTION:{option} +>NO:{-m} +>NO:{-n} +>NO:{-t} +>NO:{-u} tst_arguments '(-)-h' -a -b -c comptest $'tst -h -\t' @@ -243,6 +439,33 @@ >NO:{-a} >NO:{-b} +# ideally, would handle exclusion within the current word + tst_arguments -s : '(-d)-a' -b -c -d + comptest $'tst -ab\t -\t\eb\eb \C-b-\t' +0:exclusion with clumped options, in, after and before +>line: {tst -ab}{} +>DESCRIPTION:{option} +>NO:{-c} +>NO:{-d} +>line: {tst -ab -c }{} +>line: {tst -}{ -ab -c} +>DESCRIPTION:{option} +>NO:{-a} +>NO:{-b} +>NO:{-c} +>NO:{-d} + + tst_arguments '-a:arg' -b '(-b)-c' + comptest $'tst -a -c -\t' +0:exclusion with option argument that looks like an option +>line: {tst -a -c -}{} +>MESSAGE:{no arguments} +# seems we don't handle this case, ideal result would be as follows +#>line: {tst -a -c -}{} +#>DESCRIPTION:{option} +#>NO:{-b} +#>NO:{-c} + tst_arguments --abc --aah :arg: comptesteval 'setopt bashautolist automenu' comptest $'tst --a\t\t\t' |