summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog56
-rw-r--r--Completion/Linux/Command/_fusermount2
-rw-r--r--Completion/Unix/Command/_mount6
-rw-r--r--Completion/Zsh/Context/_brace_parameter1
-rw-r--r--Config/version.mk4
-rw-r--r--Doc/Zsh/compsys.yo4
-rw-r--r--Doc/Zsh/expn.yo3
-rw-r--r--Functions/Misc/zed2
-rw-r--r--Functions/Zle/bracketed-paste-magic44
-rw-r--r--NEWS24
-rw-r--r--Src/Zle/computil.c91
-rw-r--r--Src/input.c2
-rw-r--r--Src/zsh.h4
-rw-r--r--Test/B02typeset.ztst2
-rw-r--r--Test/C02cond.ztst2
-rw-r--r--Test/D07multibyte.ztst32
-rw-r--r--Test/Y03arguments.ztst251
17 files changed, 432 insertions, 98 deletions
diff --git a/ChangeLog b/ChangeLog
index f2f5cd052..b4da645cb 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -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
diff --git a/NEWS b/NEWS
index 403cd612c..ba9eb9b2c 100644
--- a/NEWS
+++ b/NEWS
@@ -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.
diff --git a/Src/zsh.h b/Src/zsh.h
index f2c030004..f22d8b135 100644
--- a/Src/zsh.h
+++ b/Src/zsh.h
@@ -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'