diff options
-rw-r--r-- | ChangeLog | 43 | ||||
-rw-r--r-- | Completion/Zsh/Context/_tilde | 32 | ||||
-rw-r--r-- | Doc/Zsh/expn.yo | 360 | ||||
-rw-r--r-- | Doc/Zsh/options.yo | 9 | ||||
-rw-r--r-- | Doc/Zsh/zle.yo | 8 | ||||
-rw-r--r-- | Src/exec.c | 7 | ||||
-rw-r--r-- | Src/parse.c | 6 | ||||
-rw-r--r-- | Test/A01grammar.ztst | 321 | ||||
-rw-r--r-- | Test/A05execution.ztst | 159 | ||||
-rw-r--r-- | Test/B02typeset.ztst | 10 | ||||
-rw-r--r-- | Test/C02cond.ztst | 7 | ||||
-rw-r--r-- | Test/D04parameter.ztst | 2 | ||||
-rw-r--r-- | Test/E01options.ztst | 3 | ||||
-rw-r--r-- | Test/E02xtrace.ztst | 91 | ||||
-rw-r--r-- | Test/Y01completion.ztst | 56 | ||||
-rw-r--r-- | Test/Y02compmatch.ztst | 671 | ||||
-rw-r--r-- | Test/Y03arguments.ztst | 151 |
17 files changed, 1760 insertions, 176 deletions
diff --git a/ChangeLog b/ChangeLog index d01e1d2c7..3e9a711db 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,40 @@ +2001-10-16 Bart Schaefer <schaefer@zsh.org> + + * 15812: Doc/Zsh/zle.yo: Cross-reference parameters used by ZLE. + + * 15702: Doc/Zsh/expn.yo: Alphabetize (mostly) parameter flag + descriptions; fix a couple of typos; parameter rule #12. + + * 15676: Test/A01grammar.ztst, Test/A05execution.ztst, + Test/C02cond.ztst, Test/D04parameter.ztst, Test/E01options.ztst, + Test/E02xtrace.ztst, Test/Y01completion.ztst, + Test/Y03arguments.ztst: Tweak %prep sections to exit sooner on + certain failures (by adding blank lines). Other whitespace-only + changes. Avoid [[ ! -r ... ]] test when running as root, as it + always fails in that case. Test `typeset -ft' (function trace). + + * 15488: Doc/Zsh/expn.yo: More index entry cleanup. Reorder the + description section to look less as if it has two menus in info + and to add some cross-references. + + * 15375: Doc/Zsh/options.yo: Explain the effect of CORRECT on + HASH_CMDS et al. + + * 15198 (adapted): Completion/Zsh/Context/_tilde: Return nonzero + if no matches are found. + + * 15060: Test/Y01completion.ztst, Test/Y02compmatch.ztst, + Test/Y03arguments.ztst, Test/comptest: Abandon the tests during + the %prep section if the zpty module can't be loaded. + + * 15057: Src/exec.c: PRINT_EXIT_VALUE for shell functions, too. + + * Andrej: 15038: Test/A01grammar.ztst: test case for 15023. + (unposted) fix a couple of typos in test decriptions + + * 15023, 15027: Src/parse.c: Accept newlines before the "in" + keyword in "for" and "select", per POSIX. + 2001-10-15 Clint Adams <clint@zsh.org> * 15094: Functions/Prompts/prompt_clint_setup: @@ -27,6 +64,12 @@ Test/C02cond.ztst: allow dynamic loading to work on MacOS X if the dlcompat library is installed. +2001-10-11 Bart Schaefer <schaefer@zsh.org> + + * 16013: Src/exec.c: Properly save/restore state around the + DEBUG trap, so that its return value does not alter the return + value of current command (among other things). + 2001-10-08 Oliver Kiddle <opk@zsh.org> * 15983: Completion/Unix/Command/_user_admin, diff --git a/Completion/Zsh/Context/_tilde b/Completion/Zsh/Context/_tilde new file mode 100644 index 000000000..5fad92da3 --- /dev/null +++ b/Completion/Zsh/Context/_tilde @@ -0,0 +1,32 @@ +#compdef -tilde- + +# We use all named directories and user names here. If this is too slow +# for you or if there are too many of them, you may want to use +# `compadd -qS/ -a friends' or something like that. + +[[ -n "$compstate[quote]" ]] && return 1 + +local expl suf dirs list lines revlines i ret=1 disp nm="$compstate[nmatches]" + +if [[ "$SUFFIX" = */* ]]; then + ISUFFIX="/${SUFFIX#*/}$ISUFFIX" + SUFFIX="${SUFFIX%%/*}" + suf=(-S '') +else + suf=(-qS/) +fi + +_tags users named-directories directory-stack + +while _tags; do + _requested users && _users "$suf[@]" "$@" && ret=0 + + _requested named-directories expl 'named directory' \ + compadd "$suf[@]" "$@" -k nameddirs + + _requested directory-stack && _directory_stack "$suf[@]" && ret=0 + + (( ret )) || return 0 +done + +return ret diff --git a/Doc/Zsh/expn.yo b/Doc/Zsh/expn.yo index a4631f37b..a2a4b3e2e 100644 --- a/Doc/Zsh/expn.yo +++ b/Doc/Zsh/expn.yo @@ -1,36 +1,44 @@ texinode(Expansion)(Parameters)(Prompt Expansion)(Top) chapter(Expansion) cindex(expansion) -sect(Description) -The types of expansions performed are - -startlist() -list(em(History Expansion)) -list(em(Alias Expansion)) -list(em(Process Substitution)) -list(em(Parameter Expansion)) -list(em(Command Substitution)) -list(em(Arithmetic Expansion)) -list(em(Brace Expansion)) -list(em(Filename Expansion)) -list(em(Filename Generation)) -endlist() - -Expansion is done in the above specified order in five steps. The -first is em(history expansion), which is only performed in -interactive shells. The next step is em(alias expansion), which is -done right before the command line is parsed. They are followed by -em(process substitution), em(parameter expansion), em(command -substitution), em(arithmetic expansion) and em(brace expansion) -which are performed in one step in left-to-right fashion. After -these expansions, all unquoted occurrences of the characters `tt(\)', -`tt(')' and `tt(")' are removed, and the result is subjected to -em(filename expansion) followed by em(filename generation). +ifnztexi(sect(Description)) +The following types of expansions are performed in the indicated order in +five steps: -If the tt(SH_FILE_EXPANSION) option is set, the order of expansion is modified -for compatibility with bf(sh) and bf(ksh). em(Filename expansion) -is performed immediately after em(alias expansion), +startitem() +item(em(History Expansion))( +This is performed only in interactive shells. +) +item(em(Alias Expansion))( +Aliases are expanded immediately before the command line is parsed as +explained +ifzman(under Aliasing in zmanref(zshmisc))\ +ifnzman(in noderef(Aliasing))\ +. +) +xitem(em(Process Substitution)) +xitem(em(Parameter Expansion)) +xitem(em(Command Substitution)) +xitem(em(Arithmetic Expansion)) +item(em(Brace Expansion))( +These five are performed in one step in left-to-right fashion. After +these expansions, all unquoted occurrences of the characters `tt(\)', +`tt(')' and `tt(")' are removed. +) +item(em(Filename Expansion))( +If the tt(SH_FILE_EXPANSION) option is set, the order of expansion is +modified for compatibility with bf(sh) and bf(ksh). In that case +em(filename expansion) is performed immediately after em(alias expansion), preceding the set of five expansions mentioned above. +) +cindex(globbing) +item(em(Filename Generation))( +This expansion, commonly referred to as bf(globbing), is always done last. +) +enditem() + +The following sections explain the types of expansion in detail. + startmenu() menu(History Expansion) menu(Process Substitution) @@ -55,8 +63,10 @@ the size of which is controlled by the tt(HISTSIZE) parameter. The one most recent command is always retained in any case. Each saved command in the history list is called a history em(event) and is assigned a number, beginning with 1 (one) when the shell starts up. The history number that -you may see in your prompt (see noderef(Prompt Expansion)) is the number -that is to be assigned to the em(next) command. +you may see in your prompt (see +ifzman(Prompt Expansion in zmanref(zshmisc))\ +ifnzman(noderef(Prompt Expansion))\ +) is the number that is to be assigned to the em(next) command. startmenu() menu(Overview) @@ -192,8 +202,11 @@ tt(!?) expansion (possibly in an earlier command). Anything else results in an error, although the error may not be the most obvious one. texinode(Modifiers)()(Word Designators)(History Expansion) subsect(Modifiers) -cindex(modifiers, history) +cindex(modifiers) +cindex(colon modifiers) cindex(history modifiers) +cindex(globbing modifiers) +cindex(parameter modifiers) After the optional word designator, you can add a sequence of one or more of the following modifiers, each preceded by a `tt(:)'. These modifiers also work on the result @@ -230,7 +243,7 @@ item(tt(Q))( Remove one level of quotes from the substituted words. ) item(tt(x))( -Like tt(q), but break into words at each blank. Does not work with +Like tt(q), but break into words at whitespace. Does not work with parameter expansion. ) item(tt(l))( @@ -312,7 +325,7 @@ tt(>) is selected then writing on this special file will provide input for var(list). If tt(<) is used, then the file passed as an argument will be connected to the output of the var(list) process. For example, -nofill(tt(paste <LPAR()cut -f1) var(file1)tt(RPAR() <LPAR()cut -f3) var(file2)tt(RPAR() | +example(tt(paste <LPAR()cut -f1) var(file1)tt(RPAR() <LPAR()cut -f3) var(file2)tt(RPAR() | tee >LPAR())var(process1)tt(RPAR() >LPAR())var(process2)tt(RPAR() >/dev/null)) cuts fields 1 and 3 from the files var(file1) and var(file2) respectively, @@ -323,8 +336,8 @@ Both the tt(/dev/fd) and the named pipe implementation have drawbacks. In the former case, some programmes may automatically close the file descriptor in question before examining the file on the command line, particularly if this is necessary for security reasons such as when the -programme is running setuid. In the second case, if the -programme does not actually open the file the subshell attempting to read +programme is running setuid. In the second case, if the +programme does not actually open the file, the subshell attempting to read from or write to the pipe will (in a typical implementation, different operating systems may have different behaviour) block for ever and have to be killed explicitly. In both cases, the shell actually supplies the @@ -334,7 +347,8 @@ information using a pipe, so that programmes that expect to lseek Also note that the previous example can be more compactly and efficiently written (provided the tt(MULTIOS) option is set) as: -nofill(tt(paste <LPAR()cut -f1) var(file1)tt(RPAR() <LPAR()cut -f3) var(file2)tt(RPAR() > >LPAR())var(process1)tt(RPAR() > >LPAR())var(process2)tt(RPAR())) +example(tt(paste <LPAR()cut -f1) var(file1)tt(RPAR() <LPAR()cut -f3) var(file2)tt(RPAR()) ifzman(\ +)tt(> >LPAR())var(process1)tt(RPAR() > >LPAR())var(process2)tt(RPAR())) The shell uses pipes instead of FIFOs to implement the latter two process substitutions in the above example. @@ -365,7 +379,7 @@ the pattern is the same as that used for filename generation; see noderef(Filename Generation). Note that these patterns, along with the replacement text of any substitutions, are themselves subject to parameter expansion, command substitution, and arithmetic expansion. -In addition to the following operations, the file modifiers described in +In addition to the following operations, the colon modifiers described in noderef(Modifiers) in noderef(History Expansion) can be applied: for example, tt(${i:s/foo/bar/}) performs string substitution on the expansion of parameter tt($i). @@ -501,7 +515,7 @@ Note that `tt(^)', `tt(=)', and `tt(~)', below, must appear to the left of `tt(#)' when these forms are combined. ) item(tt(${^)var(spec)tt(}))( -pindex(RC_EXPAND_PARAM, use of) +pindex(RC_EXPAND_PARAM, toggle) cindex(array expansion style, rc) cindex(rc, array expansion style) Turn on the tt(RC_EXPAND_PARAM) option for the @@ -522,9 +536,9 @@ tt($var[)var(N)tt(]) may themselves be split into different list elements. ) item(tt(${=)var(spec)tt(}))( -pindex(SH_WORD_SPLIT, use of) -cindex(field splitting, sh style) -cindex(sh, field splitting style) +pindex(SH_WORD_SPLIT, toggle) +cindex(field splitting, sh style, parameter) +cindex(sh, field splitting style, parameter) Perform word splitting using the rules for tt(SH_WORD_SPLIT) during the evaluation of var(spec), but regardless of whether the parameter appears in double quotes; if the `tt(=)' is doubled, turn it off. @@ -538,7 +552,7 @@ of var(spec) em(before) the assignment to var(name) is performed. This affects the result of array assignments with the tt(A) flag. ) item(tt(${~)var(spec)tt(}))( -pindex(GLOB_SUBST) +pindex(GLOB_SUBST, toggle) Turn on the tt(GLOB_SUBST) option for the evaluation of var(spec); if the `tt(~)' is doubled, turn it off. When this option is set, the string resulting from the expansion will be interpreted as a @@ -576,12 +590,26 @@ cindex(flags, parameter expansion) cindex(substitution, parameter, flags) If the opening brace is directly followed by an opening parenthesis, the string up to the matching closing parenthesis will be taken as a -list of flags. Where arguments are valid, any character, or the -matching pairs `tt(LPAR())...tt(RPAR())', `tt({)...tt(})', -`tt([)...tt(])', or `tt(<)...tt(>)', may be used -in place of the colon as delimiters. The following flags are supported: +list of flags. In cases where repeating a flag is meaningful, the +repetitions need not be consecutive; for example, `(tt(q%q%q))' +means the same thing as the more readable `(tt(%%qqq))'. The +following flags are supported: startitem() +item(tt(%))( +Expand all tt(%) escapes in the resulting words in the same way as in in +prompts (see noderef(Prompt Expansion)). If this flag is given twice, +full prompt expansion is done on the resulting words, depending on the +setting of the tt(PROMPT_PERCENT), tt(PROMPT_SUBST) and tt(PROMPT_BANG) +options. +) +item(tt(@))( +In double quotes, array elements are put into separate words. +E.g., `tt("${(@)foo}")' is equivalent to `tt("${foo[@]}")' and +`tt("${(@)foo[1,2]}")' is the same as `tt("$foo[1]" "$foo[2]")'. +This is distinct from em(field splitting) by the the tt(f), tt(s) +or tt(z) flags, which still applies within each array element. +) item(tt(A))( Create an array parameter with `tt(${)...tt(=)...tt(})', `tt(${)...tt(:=)...tt(})' or `tt(${)...tt(::=)...tt(})'. @@ -589,49 +617,57 @@ If this flag is repeated (as in `tt(AA)'), create an associative array parameter. Assignment is made before sorting or padding. The var(name) part may be a subscripted range for ordinary arrays; the var(word) part em(must) be converted to an array, for -example by using `tt(${(AA)=)var(name)tt(=)...tt(})' to activate word -splitting, when creating an associative array. +example by using `tt(${(AA)=)var(name)tt(=)...tt(})' to activate +field splitting, when creating an associative array. ) -item(tt(@))( -In double quotes, array elements are put into separate words. -E.g., `tt("${(@)foo}")' is equivalent to `tt("${foo[@]}")' and -`tt("${(@)foo[1,2]}")' is the same as `tt("$foo[1]" "$foo[2]")'. +item(tt(c))( +With tt(${#)var(name)tt(}), count the total number of characters in an array, +as if the elements were concatenated with spaces between them. +) +item(tt(C))( +Capitalize the resulting words. `Words' in this case refers to sequences +of alphanumeric characters separated by non-alphanumerics, em(not) to words +that result from field splitting. ) item(tt(e))( Perform em(parameter expansion), em(command substitution) and em(arithmetic expansion) on the result. Such expansions can be nested but too deep recursion may have unpredictable effects. ) -item(tt(P))( -This forces the value of the parameter var(name) to be interpreted as a -further parameter name, whose value will be used where appropriate. If used -with a nested parameter or command substitution, the result of that will be -taken as a parameter name in the same way. For example, if you have -`tt(foo=bar)' and `tt(bar=baz)', the strings tt(${(P)foo}), -tt(${(P)${foo}}), and tt(${(P)$(echo bar)}) will be expanded to `tt(baz)'. -) -item(tt(o))( -Sort the resulting words in ascending order. +item(tt(f))( +Split the result of the expansion to lines. This is a shorthand +for `tt(ps:\n:)'. ) -item(tt(O))( -Sort the resulting words in descending order. +item(tt(F))( +Join the words of arrays together using newline as a separator. +This is a shorthand for `tt(pj:\n:)'. ) item(tt(i))( With tt(o) or tt(O), sort case-independently. ) +item(tt(k))( +If var(name) refers to an associative array, substitute the em(keys) +(element names) rather than the values of the elements. Used with +subscripts (including ordinary arrays), force indices or keys to be +substituted even if the subscript form refers to values. However, +this flag may not be combined with subscript ranges. +) item(tt(L))( Convert all letters in the result to lower case. ) -item(tt(U))( -Convert all letters in the result to upper case. +item(tt(o))( +Sort the resulting words in ascending order. ) -item(tt(C))( -Capitalize the resulting words. `Words' in this case refers to sequences -of alphanumeric characters separated by non-alphanumerics, em(not) to words -that result from field splitting. +item(tt(O))( +Sort the resulting words in descending order. ) -item(tt(V))( -Make any special characters in the resulting words visible. +item(tt(P))( +This forces the value of the parameter var(name) to be interpreted as a +further parameter name, whose value will be used where appropriate. If +used with a nested parameter or command substitution, the result of that +will be taken as a parameter name in the same way. For example, if you +have `tt(foo=bar)' and `tt(bar=baz)', the strings tt(${(P)foo}), +tt(${(P)${foo}}), and tt(${(P)$(echo bar)}) will be expanded to `tt(baz)'. ) item(tt(q))( Quote the resulting words with backslashes. If this flag is given @@ -642,87 +678,6 @@ given four times, the words are quoted in single quotes preceded by a tt($). item(tt(Q))( Remove one level of quotes from the resulting words. ) -item(tt(%))( -Expand all tt(%) escapes in the resulting words in the same way as in -prompts (see noderef(Prompt Expansion)). If this flag is given twice, -full prompt expansion is done on the resulting words, depending on the -setting of the tt(PROMPT_PERCENT), tt(PROMPT_SUBST) and -tt(PROMPT_BANG) options. -) -item(tt(X))( -With this flag parsing errors occurring with the tt(Q) and tt(e) flags or the -pattern matching forms such as `tt(${)var(name)tt(#)var(pattern)tt(})' -are reported. Without the flag they are silently ignored. -) -item(tt(c))( -With tt(${#)var(name)tt(}), count the total number of characters in an array, -as if the elements were concatenated with spaces between them. -) -item(tt(w))( -With tt(${#)var(name)tt(}), count words in arrays or strings; the tt(s) -flag may be used to set a word delimiter. -) -item(tt(W))( -Similar to tt(w) with the difference that empty words between -repeated delimiters are also counted. -) -item(tt(k))( -If var(name) refers to an associative array, substitute the em(keys) -(element names) rather than the values of the elements. Used with -subscripts (including ordinary arrays), force indices or keys to be -substituted even if the subscript form refers to values. However, -this flag may not be combined with subscript ranges. -) -item(tt(v))( -Used with tt(k), substitute (as two consecutive words) both the key -and the value of each associative array element. Used with subscripts, -force values to be substituted even if the subscript form refers to -indices or keys. -) -item(tt(p))( -Recognize the same escape sequences as the tt(print) builtin -in string arguments to any of the flags described below. -) -item(tt(l:)var(expr)tt(::)var(string1)tt(::)var(string2)tt(:))( -Pad the resulting words on the left. Each word will be truncated if -required and placed in a field var(expr) characters wide. The space -to the left will be filled with var(string1) (concatenated as often -as needed) or spaces if var(string1) is not given. If both -var(string1) and var(string2) are given, this string is inserted -once directly to the left of each word, before padding. -) -item(tt(r:)var(expr)tt(::)var(string1)tt(::)var(string2)tt(:))( -As tt(l), but pad the words on the right and insert var(string2) -on the right. -) -item(tt(j:)var(string)tt(:))( -Join the words of arrays together using var(string) as a separator. -pindex(SH_WORD_SPLIT, use of) -Note that this occurs before field splitting by the tt(SH_WORD_SPLIT) -option. -) -item(tt(F))( -Join the words of arrays together using newline as a separator. -This is a shorthand for `tt(pj:\n:)'. -) -item(tt(s:)var(string)tt(:))( -Force field splitting (see the option tt(SH_WORD_SPLIT)) at the -separator var(string). Splitting only occurs in places where an -array value is valid. -) -item(tt(f))( -Split the result of the expansion to lines. This is a shorthand -for `tt(ps:\n:)'. -) -item(tt(z))( -Split the result of the expansion into words using shell parsing to -find the words, i.e. taking into account any quoting in the value. - -Note that this is done very late, as for the `tt((s))' flag. So to -access single words in the result, one has to use nested expansions as -in `tt(${${(z)foo}[2]})'. Likewise, to remove the quotes in the -resulting words one would do: `tt(${(Q)${(z)foo}})'. -) item(tt(t))( Use a string describing the type of the parameter where the value of the parameter would usually appear. This string consists of keywords @@ -772,6 +727,77 @@ for special parameters defined by the shell ) enditem() ) +item(tt(U))( +Convert all letters in the result to upper case. +) +item(tt(v))( +Used with tt(k), substitute (as two consecutive words) both the key +and the value of each associative array element. Used with subscripts, +force values to be substituted even if the subscript form refers to +indices or keys. +) +item(tt(V))( +Make any special characters in the resulting words visible. +) +item(tt(w))( +With tt(${#)var(name)tt(}), count words in arrays or strings; the tt(s) +flag may be used to set a word delimiter. +) +item(tt(W))( +Similar to tt(w) with the difference that empty words between +repeated delimiters are also counted. +) +item(tt(X))( +With this flag parsing errors occurring with the tt(Q) and tt(e) flags or the +pattern matching forms such as `tt(${)var(name)tt(#)var(pattern)tt(})' +are reported. Without the flag they are silently ignored. +) +item(tt(z))( +Split the result of the expansion into words using shell parsing to +find the words, i.e. taking into account any quoting in the value. + +Note that this is done very late, as for the `tt((s))' flag. So to +access single words in the result, one has to use nested expansions as +in `tt(${${(z)foo}[2]})'. Likewise, to remove the quotes in the +resulting words one would do: `tt(${(Q)${(z)foo}})'. +) +enditem() + +The following flags (except tt(p)) are followed by one or more arguments +as shown. Any character, or the matching pairs `tt(LPAR())...tt(RPAR())', +`tt({)...tt(})', `tt([)...tt(])', or `tt(<)...tt(>)', may be used in place +of a colon as delimiters, but note that when a flag takes more than one +argument, a matched pair of delimiters must surround each argument. + +startitem() +item(tt(p))( +Recognize the same escape sequences as the tt(print) builtin +in string arguments to any of the flags described below. +) +item(tt(j:)var(string)tt(:))( +Join the words of arrays together using var(string) as a separator. +pindex(SH_WORD_SPLIT, use of) +Note that this occurs before field splitting by the tt(SH_WORD_SPLIT) +option. +) +item(tt(l:)var(expr)tt(::)var(string1)tt(::)var(string2)tt(:))( +Pad the resulting words on the left. Each word will be truncated if +required and placed in a field var(expr) characters wide. The space +to the left will be filled with var(string1) (concatenated as often +as needed) or spaces if var(string1) is not given. If both +var(string1) and var(string2) are given, this string is inserted +once directly to the left of each word, before padding. +) +item(tt(r:)var(expr)tt(::)var(string1)tt(::)var(string2)tt(:))( +As tt(l), but pad the words on the right and insert var(string2) +on the right. +) +item(tt(s:)var(string)tt(:))( +Force field splitting (see the option tt(SH_WORD_SPLIT)) at the +separator var(string). Note that a var(string) of two or more +characters means all must all match in sequence; this differs from +the treatment of two or more characters in the tt(IFS) parameter. +) enditem() The following flags are meaningful with the tt(${)...tt(#)...tt(}) or @@ -783,8 +809,8 @@ item(tt(S))( Search substrings as well as beginnings or ends; with tt(#) start from the beginning and with tt(%) start from the end of the string. With substitution via tt(${)...tt(/)...tt(}) or -tt(${)...tt(//)...tt(}), specifies that the shortest instead of the -longest match should be replaced. +tt(${)...tt(//)...tt(}), specifies non-greedy matching, i.e. that the +shortest instead of the longest match should be replaced. ) item(tt(I:)var(expr)tt(:))( Search the var(expr)th match (where var(expr) evaluates to a number). @@ -812,21 +838,21 @@ will remove the same matches as for `tt(#)', but in reverse order, and the form using `tt(%%)' will remove the same matches as for `tt(##)' in reverse order. ) -item(tt(M))( -Include the matched portion in the result. -) -item(tt(R))( -Include the unmatched portion in the result (the em(R)est). -) 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. ) +item(tt(M))( +Include the matched portion in the result. +) item(tt(N))( Include the length of the match in the result. ) +item(tt(R))( +Include the unmatched portion in the result (the em(R)est). +) enditem() subsect(Rules) @@ -918,6 +944,15 @@ item(tt(11.) em(Padding))( Any padding of the value by the `tt(LPAR()l.)var(fill)tt(.RPAR())' or `tt(LPAR()r.)var(fill)tt(.RPAR())' flags is applied. ) +item(tt(12.) em(Semantic Joining))( +In contexts where expansion semantics requires a single word to +result, all words are rejoined with the first character of tt(IFS) +between. So in `tt(${LPAR()P)tt(RPAR()${LPAR()f)tt(RPAR()lines}})' +the value of tt(${lines}) is split at newlines, but then must be +joined again before the tt(P) flag can be applied. + +If a single word is not required, this rule is skipped. +) enditem() subsect(Examples) @@ -1102,7 +1137,6 @@ first `tt(=)' also inhibits this. texinode(Filename Generation)()(Filename Expansion)(Expansion) sect(Filename Generation) cindex(filename generation) -cindex(globbing) If a word contains an unquoted instance of one of the characters `tt(*)', `tt(LPAR())', `tt(|)', `tt(<)', `tt([)', or `tt(?)', it is regarded as a pattern for filename generation, unless the tt(GLOB) option is unset. @@ -1745,7 +1779,7 @@ tt(n) they are sorted by name (the default); if it is tt(L) they are sorted depending on the size (length) of the files; if tt(l) they are sorted by the number of links; if tt(a), tt(m), or tt(c) they are sorted by the time of the last access, modification, or -inode change respectively; if var(d), files in subdirectories appear before +inode change respectively; if tt(d), files in subdirectories appear before those in the current directory at each level of the search --- this is best combined with other criteria, for example `tt(odon)' to sort on names for files within the same directory. Note that tt(a), tt(m), and tt(c) compare diff --git a/Doc/Zsh/options.yo b/Doc/Zsh/options.yo index 564e6701b..065f01454 100644 --- a/Doc/Zsh/options.yo +++ b/Doc/Zsh/options.yo @@ -483,15 +483,18 @@ item(tt(HASH_CMDS) <D>)( Note the location of each command the first time it is executed. Subsequent invocations of the same command will use the saved location, avoiding a path search. -If this option is unset, no path hashing will be done at all. +If this option is unset, no path hashing is done at all. +However, when tt(CORRECT) is set, commands whose names do not appear in +the functions or aliases hash tables are hashed in order to avoid +reporting them as spelling errors. ) pindex(HASH_DIRS) cindex(hashing, of directories) cindex(directories, hashing) item(tt(HASH_DIRS) <D>)( -Whenever a command is executed, hash the directory containing it, +Whenever a command name is hashed, hash the directory containing it, as well as all directories that occur earlier in the path. -Has no effect if tt(HASH_CMDS) is unset. +Has no effect if neither tt(HASH_CMDS) nor tt(CORRECT) is set. ) pindex(HASH_LIST_ALL) item(tt(HASH_LIST_ALL) <D>)( diff --git a/Doc/Zsh/zle.yo b/Doc/Zsh/zle.yo index d39c610f4..07735def9 100644 --- a/Doc/Zsh/zle.yo +++ b/Doc/Zsh/zle.yo @@ -21,6 +21,14 @@ This mode is similar to bf(ksh), and uses no termcap sequences. If tt(TERM) is "emacs", the tt(ZLE) option will be unset by default. +vindex(BAUD, use of) +vindex(COLUMNS, use of) +vindex(LINES, use of) +The parameters tt(BAUD), tt(COLUMNS), and tt(LINES) are also used by the +line editor. +ifzman(See em(Parameters Used By The Shell) in zmanref(zshparam))\ +ifnzman(noderef(Parameters Used By The Shell)). + startmenu() menu(Keymaps) menu(Zle Builtins) diff --git a/Src/exec.c b/Src/exec.c index aa2e3437b..f1206e93c 100644 --- a/Src/exec.c +++ b/Src/exec.c @@ -2297,9 +2297,6 @@ execcmd(Estate state, int input, int output, int how, int last1) #ifdef PATH_DEV_FD closem(2); #endif - if (isset(PRINTEXITVALUE) && isset(SHINSTDIN) && lastval && !subsh) { - fprintf(stderr, "zsh: exit %ld\n", (long)lastval); - } fflush(stdout); if (save[1] == -2) { if (ferror(stdout)) { @@ -2309,6 +2306,10 @@ execcmd(Estate state, int input, int output, int how, int last1) } else clearerr(stdout); } + if (isset(PRINTEXITVALUE) && isset(SHINSTDIN) && + lastval && !subsh) { + fprintf(stderr, "zsh: exit %ld\n", (long)lastval); + } if (do_exec) { if (subsh) diff --git a/Src/parse.c b/Src/parse.c index b7b8050c4..15a53add1 100644 --- a/Src/parse.c +++ b/Src/parse.c @@ -903,12 +903,16 @@ par_for(int *complex) yylex(); type = WC_FOR_COND; } else { + int posix_in; infor = 0; if (tok != STRING || !isident(tokstr)) YYERRORV(oecused); ecstr(tokstr); incmdpos = 1; yylex(); + posix_in = isnewlin; + while (isnewlin) + yylex(); if (tok == STRING && !strcmp(tokstr, "in")) { int np, n; @@ -920,7 +924,7 @@ par_for(int *complex) YYERRORV(oecused); ecbuf[np] = n; type = (sel ? WC_SELECT_LIST : WC_FOR_LIST); - } else if (tok == INPAR) { + } else if (!posix_in && tok == INPAR) { int np, n; incmdpos = 0; diff --git a/Test/A01grammar.ztst b/Test/A01grammar.ztst new file mode 100644 index 000000000..8b6b403fb --- /dev/null +++ b/Test/A01grammar.ztst @@ -0,0 +1,321 @@ +# +# This file contains tests corresponding to the `Shell Grammar' texinfo node. +# + +%prep + + mkdir basic.tmp && cd basic.tmp + + touch foo bar + +%test +# +# Tests for `Simple Commands and Pipelines' +# + echo foo | cat | sed 's/foo/bar/' +0:Basic pipeline handling +>bar + + false | true +0:Exit status of pipeline with builtins (true) + + true | false +1:Exit status of pipeline with builtins (false) + + fn() { local foo; read foo; print $foo; } + coproc fn + print -p coproc test output + read -p bar + print $bar +0:Basic coprocess handling +>coproc test output + + true | false && print true || print false +0:Basic sublist (i) +>false + + false | true && print true || print false +0:Basic sublist (ii) +>true + + (cd /NonExistentDirectory >&/dev/null) || print false +0:Basic subshell list with error +>false + + { cd /NonExistentDirectory >&/dev/null } || print false +0:Basic current shell list with error +>false + +# +# Tests for `Precommand Modifiers' +# + - $ZTST_testdir/../Src/zsh -fc "[[ \$0 = \"-$ZTST_testdir/../Src/zsh\" ]]" +0:`-' precommand modifier + + echo f* + noglob echo f* +0:`noglob' precommand modifier +>foo +>f* + + (exec /bin/sh; echo bar) +0:`exec' precommand modifier + + cat() { echo Function cat executed; } + command cat && unfunction cat +0:`command' precommand modifier +<External command cat executed +>External command cat executed + + cd() { echo Not cd at all; } + builtin cd . && unfunction cd +0:`builtin' precommand modifier + +# +# Tests for `Complex Commands' +# + + if true; then + print true-1 + elif true; then + print true-2 + else + print false + fi +0:`if ...' (i) +>true-1 + + if false; then + print true-1 + elif true; then + print true-2 + else + print false + fi +0:`if ...' (ii) +>true-2 + + if false; then + print true-1 + elif false; then + print true-2 + else + print false + fi +0:`if ...' (iii) +>false + + if true; + : + fi +1d:`if ...' (iv) +?ZTST_execchunk:-1: parse error near `fi' + + for name in word to term; do + print $name + done +0:`for' loop +>word +>to +>term + + for name + in word to term; do + print $name + done +0:`for' loop with newline before in keyword +>word +>to +>term + + for (( name = 0; name < 3; name++ )); do + print $name + done +0:arithmetic `for' loop +>0 +>1 +>2 + + name=0 + while (( name < 3 )); do + print $name + (( name++ )) + done +0:`while' loop +>0 +>1 +>2 + + name=0 + until (( name == 3 )); do + print $name + (( name++ )) + done +0:`until' loop +>0 +>1 +>2 + + repeat 3 do + echo over and over + done +0:`repeat' loop +>over and over +>over and over +>over and over + + word=Trinity + case $word in + Michaelmas) print 0 + ;; + Hilary) print 1 + ;; + Trinity) print 2 + ;; + *) print 3 + ;; + esac +0:`case', old syntax +>2 + + word=Trinity + case $word in + (Michaelmas) print 0 + ;; + (Hilary) print 1 + ;; + (Trinity) print 2 + ;; + (*) print 3 + ;; + esac +0:`case', new syntax +>2 + + word=Hilary + case $word in + (Michaelmas) print 0 + ;; + (Hilary) print 1 + ;& + (Trinity) print 2 + ;& + (*) print 3 + ;; + esac +0:`case', new syntax, cascaded +>1 +>2 +>3 + +## This doesn't work, because zsh tries to read from the terminal +## even in a non-interactive shell. The manual implies it always reads +## from stdin, even in an interactive shell. +# PS3="input> " +# select name in one two three; do +# print $name +# done +#0:`select' loop +#<2 +#>1) one 2) two 3) three +#>input> +#>two + + function name1 name2 () { print This is $0; } + name2 + name1 name2() { print This is still $0; } + name2 +0:`function' keyword +>This is name2 +>This is still name2 + + (time cat) >&/dev/null +0:`time' keyword (status only) + + if [[ -f foo && -d . && -n $ZTST_testdir ]]; then + true + else + false + fi +0:basic [[ ... ]] test + +# +# Tests for `Alternate Forms For Complex Commands' +# + + if (true) { print true-1 } elif (true) { print true-2 } else { print false } + if (false) { print true-1 } elif (true) { print true-2 } else { print false } + if (false) { print true-1 } elif (false) { print true-2 } else { print false } +0:Alternate `if' with braces +>true-1 +>true-2 +>false + + if true; print true +0:Short form of `if' +>true + + for name ( word1 word2 word3 ) print $name +0:Form of `for' with parentheses. +>word1 +>word2 +>word3 + + for name in alpha beta gamma; print $name +0:Short form of `for' +>alpha +>beta +>gamma + + for (( val = 2; val < 10; val *= val )) print $val +0:Short arithmetic `for' +>2 +>4 + + foreach name ( verbiage words periphrasis ) + print $name + end +0:Csh-like `for' +>verbiage +>words +>periphrasis + +# see comment with braces used in if loops + val=0; + while (( val < 2 )) { print $((val++)); } +0:Alternative `while' +>0 +>1 + + val=2; + until (( val == 0 )) { print $((val--)); } +0:Alternative `until' +>2 +>1 + + repeat 3 print Hip hip hooray +0:Short `repeat' +>Hip hip hooray +>Hip hip hooray +>Hip hip hooray + + case bravo { + (alpha) print schmalpha + ;; + (bravo) print schmavo + ;; + (charlie) print schmarlie + ;; + } +0:`case' with braces +>schmavo + + print 'This test hangs the shell when it fails...' >&8 + name=0 +# The number 4375 here is chosen to produce more than 16384 bytes of output + while (( name < 4375 )); do + print -n $name + (( name++ )) + done < /dev/null | { read name; print done } +0:Bug regression: `while' loop with redirection and pipeline +>done diff --git a/Test/A05execution.ztst b/Test/A05execution.ztst new file mode 100644 index 000000000..202a4bb7a --- /dev/null +++ b/Test/A05execution.ztst @@ -0,0 +1,159 @@ +%prep + + storepath=($path) + + mkdir command.tmp command.tmp/dir1 command.tmp/dir2 + + cd command.tmp + + print '#!/bin/sh\necho This is top' >tstcmd + + print '#!/bin/sh\necho This is dir1' >dir1/tstcmd + + print '#!/bin/sh\necho This is dir2' >dir2/tstcmd + + chmod 755 tstcmd dir1/tstcmd dir2/tstcmd + +%test + ./tstcmd +0:./prog execution +>This is top + + path=($ZTST_testdir/command.tmp/dir1 + $ZTST_testdir/command.tmp/dir2 + .) + tstcmd + path=($storepath) +0:path (1) +>This is dir1 + + path=(. command.tmp/dir{1,2}) + tstcmd + path=($storepath) +0:path (2) +>This is top + + functst() { print $# arguments:; print -l $*; } + functst "Eines Morgens" "als Gregor Samsa" + functst "" + functst "aus unrühigen Träumen erwachte" + foo="fand er sich in seinem Bett" + bar= + rod="zu einem ungeheuren Ungeziefer verwandelt." + functst $foo $bar $rod +# set up alias for next test + alias foo='print This is alias one' +0:function argument passing +>2 arguments: +>Eines Morgens +>als Gregor Samsa +>1 arguments: +> +>1 arguments: +>aus unrühigen Träumen erwachte +>2 arguments: +>fand er sich in seinem Bett +>zu einem ungeheuren Ungeziefer verwandelt. + + alias foo='print This is alias two' + fn() { foo; } + fn +0:Aliases in functions +>This is alias one + + foo='Global foo' + traptst() { local foo="Local foo"; trap 'print $foo' EXIT; } + traptst +0:EXIT trap environment +>Global foo + + functst() { return 0; print Ha ha; return 1; } + functst +0:return (1) + + functst() { return 1; print Ho ho; return 0; } + functst +1:return (2) + + unfunction functst + fpath=(.) + print "print This is functst." >functst + autoload functst + functst +0:autoloading (1) +>This is functst. + + unfunction functst + print "functst() { print This, too, is functst; }; print Hello." >functst + typeset -fu functst + functst + functst +0:autoloading with initialization +>Hello. +>This, too, is functst + + unfunction functst + print "print Yet another version" >functst + functst() { autoload -X; } + functst +0:autoloading via -X +>Yet another version + + chpwd() { print Changed to $PWD; } + cd . + unfunction chpwd +0q:chpwd +>Changed to $ZTST_testdir/command.tmp + +# Hard to test periodic, precmd and preexec non-interactively. + + fn() { TRAPEXIT() { print Exit; }; } + fn +0:TRAPEXIT +>Exit + + unfunction fn + print 'TRAPDEBUG() { + print Line $LINENO + } + : + unfunction TRAPDEBUG + ' > fn + autoload fn + fn + rm fn +0:TRAPDEBUG +>Line 1 +>Line 1 + + unfunction fn + print 'trap '\''print Line $LINENO'\'' DEBUG + : + trap - DEBUG + ' > fn + autoload fn + fn + rm fn +0:trap DEBUG +>Line 1 +>Line 2 + + TRAPZERR() { print Command failed; } + true + false + true + false + unfunction TRAPZERR +0:TRAPZERR +>Command failed +>Command failed + + trap 'print Command failed again.' ZERR + true + false + true + false + trap - ZERR +0:trap ZERR +>Command failed again. +>Command failed again. diff --git a/Test/B02typeset.ztst b/Test/B02typeset.ztst index 2dc015d31..da04a79e2 100644 --- a/Test/B02typeset.ztst +++ b/Test/B02typeset.ztst @@ -102,7 +102,7 @@ declare +m 1:Differences of declare and typeset -?(eval):1: bad option: -m +?ZTST_execchunk:2: bad option: -m scope10 print $outer @@ -160,7 +160,7 @@ r=failure 1:Readonly declaration >success -?(eval):3: read-only variable: r +?ZTST_execchunk:2: read-only variable: r typeset r=success readonly r @@ -168,7 +168,7 @@ r=failure 1:Convert to readonly >success -?(eval):4: read-only variable: r +?ZTST_execchunk:2: read-only variable: r typeset -gU array print $array @@ -186,7 +186,7 @@ typeset -T SCALAR array typeset +T SCALAR 1:Untying is prohibited -?(eval):typeset:2: use unset to remove tied variables +?ZTST_execchunk:typeset:2: use unset to remove tied variables OUTER=outer scope13 @@ -197,7 +197,7 @@ local array[2]=x 1:Illegal local array element assignment -?(eval):local:1: array[2]: can't create local array elements +?ZTST_execchunk:local:2: array[2]: can't create local array elements local -a array typeset array[1]=a array[2]=b array[3]=c diff --git a/Test/C02cond.ztst b/Test/C02cond.ztst index b575e92be..b320634d5 100644 --- a/Test/C02cond.ztst +++ b/Test/C02cond.ztst @@ -85,7 +85,12 @@ fi 0dD:-p cond - [[ -r zerolength && ! -r unmodish ]] + if (( EUID == 0 )); then + print -u8 'Warning: Not testing [[ ! -r file ]] (root reads anything)' + [[ -r zerolength && -r unmodish ]] + else + [[ -r zerolength && ! -r unmodish ]] + fi 0:-r cond [[ -s nonzerolength && ! -s zerolength ]] diff --git a/Test/D04parameter.ztst b/Test/D04parameter.ztst index 9506f56e4..7e70691f7 100644 --- a/Test/D04parameter.ztst +++ b/Test/D04parameter.ztst @@ -3,7 +3,9 @@ %prep mkdir parameter.tmp + cd parameter.tmp + touch boringfile evenmoreboringfile %test diff --git a/Test/E01options.ztst b/Test/E01options.ztst index ee58a5c8a..f93012020 100644 --- a/Test/E01options.ztst +++ b/Test/E01options.ztst @@ -82,8 +82,11 @@ %prep mkdir options.tmp && cd options.tmp + mkdir tmpcd + touch tmpfile1 tmpfile2 + mydir=$PWD mydirt=`print -P %~` catpath=$(which cat) diff --git a/Test/E02xtrace.ztst b/Test/E02xtrace.ztst new file mode 100644 index 000000000..09c8eb6b5 --- /dev/null +++ b/Test/E02xtrace.ztst @@ -0,0 +1,91 @@ +# Test that xtrace output is correctly generated + +%prep + mkdir xtrace.tmp && cd xtrace.tmp + + function xtf { + local regression_test_dummy_variable + print "$*" + } + echo 'print "$*"' > xt.in + +%test + + set -x + print 'Tracing: builtin' + print 'Tracing: builtin 2>file' 2>xtrace.err + cat <<<'Tracing: external' + cat <<<'Tracing: external 2>file' 2>>xtrace.err + ( print 'Tracing: ( builtin )' ) + ( print 'Tracing: ( builtin ) 2>file' ) 2>>xtrace.err + ( cat <<<'Tracing: ( external )' ) + ( cat <<<'Tracing: ( external ) 2>file' ) 2>>xtrace.err + { print 'Tracing: { builtin }' } + { print 'Tracing: { builtin } 2>file' } 2>>xtrace.err + { cat <<<'Tracing: { external }' } + { cat <<<'Tracing: { external } 2>file' } 2>>xtrace.err + repeat 1 do print 'Tracing: do builtin done'; done + repeat 1 do print 'Tracing: do builtin done 2>file'; done 2>>xtrace.err + repeat 1 do cat <<<'Tracing: do external done'; done + repeat 1 do cat <<<'Tracing: do external done 2>file'; done 2>>xtrace.err + xtf 'Tracing: function' + xtf 'Tracing: function 2>file' 2>>xtrace.err + . ./xt.in 'Tracing: source' + . ./xt.in 'Tracing: source 2>file' 2>>xtrace.err + set +x + cat xtrace.err +0:xtrace with and without redirection +>Tracing: builtin +>Tracing: builtin 2>file +>Tracing: external +>Tracing: external 2>file +>Tracing: ( builtin ) +>Tracing: ( builtin ) 2>file +>Tracing: ( external ) +>Tracing: ( external ) 2>file +>Tracing: { builtin } +>Tracing: { builtin } 2>file +>Tracing: { external } +>Tracing: { external } 2>file +>Tracing: do builtin done +>Tracing: do builtin done 2>file +>Tracing: do external done +>Tracing: do external done 2>file +>Tracing: function +>Tracing: function 2>file +>Tracing: source +>Tracing: source 2>file +>+ZTST_execchunk:2> print Tracing: ( builtin ) 2>file +>+ZTST_execchunk:2> cat +>+ZTST_execchunk:2> print Tracing: { builtin } 2>file +>+ZTST_execchunk:2> cat +>+ZTST_execchunk:2> print Tracing: do builtin done 2>file +>+ZTST_execchunk:2> cat +?+ZTST_execchunk:2> print Tracing: builtin +?+ZTST_execchunk:2> print Tracing: builtin 2>file +?+ZTST_execchunk:2> cat +?+ZTST_execchunk:2> cat +?+ZTST_execchunk:2> print Tracing: ( builtin ) +?+ZTST_execchunk:2> cat +?+ZTST_execchunk:2> print Tracing: { builtin } +?+ZTST_execchunk:2> cat +?+ZTST_execchunk:2> print Tracing: do builtin done +?+ZTST_execchunk:2> cat +?+ZTST_execchunk:2> xtf Tracing: function +?+xtf:0> local regression_test_dummy_variable +?+xtf:0> print Tracing: function +?+ZTST_execchunk:2> xtf Tracing: function 2>file +?+xtf:0> local regression_test_dummy_variable +?+xtf:0> print Tracing: function 2>file +?+ZTST_execchunk:2> . ./xt.in Tracing: source +?+./xt.in:1> print Tracing: source +?+ZTST_execchunk:2> . ./xt.in Tracing: source 2>file +?+./xt.in:1> print Tracing: source 2>file +?+ZTST_execchunk:2> set +x + + typeset -ft xtf + xtf 'Tracing: function' +0: +>Tracing: function +?+xtf:0> local regression_test_dummy_variable +?+xtf:0> print Tracing: function diff --git a/Test/Y01completion.ztst b/Test/Y01completion.ztst new file mode 100644 index 000000000..371cad247 --- /dev/null +++ b/Test/Y01completion.ztst @@ -0,0 +1,56 @@ +# Tests for completion system. + +%prep + . $ZTST_srcdir/comptest + + mkdir comp.tmp + cd comp.tmp + + comptestinit -z $ZTST_testdir/../Src/zsh && + { + mkdir dir1 + mkdir dir2 + touch file1 + touch file2 + } + +%test + + comptest $': \t\t\t\t\t\t\t' +0:directories and files +>line: {: }{} +>DESCRIPTION:{file} +>DI:{dir1} +>DI:{dir2} +>FI:{file1} +>FI:{file2} +>line: {: dir1/}{} +>line: {: dir2/}{} +>line: {: file1}{} +>line: {: file2}{} +>line: {: dir1/}{} +>line: {: dir2/}{} + + comptesteval '_users () { compadd user1 user2 }' + comptest $': ~\t\t\t\t\t' +0:tilde +>line: {: ~user}{} +>line: {: ~user}{} +>NO:{user1} +>NO:{user2} +>line: {: ~user1}{} +>line: {: ~user2}{} +>line: {: ~user1}{} + + comptest $'echo ;:\C-b\C-b\t' +0:tilde +>line: {echo }{;:} +>DESCRIPTION:{file} +>DI:{dir1} +>DI:{dir2} +>FI:{file1} +>FI:{file2} + +%clean + + zmodload -ui zsh/zpty diff --git a/Test/Y02compmatch.ztst b/Test/Y02compmatch.ztst new file mode 100644 index 000000000..4d4e0c0fa --- /dev/null +++ b/Test/Y02compmatch.ztst @@ -0,0 +1,671 @@ +# Tests for completion system matching control + +# Most tests follow this format: +# test_code $matcher_string selection_list +# comptest -c "$code" $' tst input_string' +# test_code generates the string $codem which sets what words the completion +# should be selecting from. The comptest function actually performs the +# completion test, using the completion function generated by test_code. +# +# This test also tests error conditions that compadd reports, so output also +# contains the compadd output. + +%prep + . $ZTST_srcdir/comptest + + mkdir match.tmp + cd match.tmp + + comptestinit -z $ZTST_testdir/../Src/zsh && + { + list1=(IndianRed IndianRed2 IndianRed3 IndianRed4) + test_code () { + matcher=$1; + list=$2; + code="compdef _tst tst ; _tst () { echo -n '<COMPADD>';compadd -M '" + code="$code$matcher" + code="$code' - ${(P)list} ; echo -n '</COMPADD>'" + code="$code; $extra_cmd" + code="$code; echo -n '<INSERT_POSITIONS>'" + code="$code; echo \$compstate[insert_positions]" + code="$code; echo -n '</INSERT_POSITIONS>'" + code="$code}" + comptesteval "$code" + } + } + + +%test + + test_code z: list1 + comptest $'tst \t' +0:Match Error for "z:" +>line: {tst }{} +>COMPADD:{_tst:compadd: unknown match specification character `z'} +>INSERT_POSITIONS:{} + + test_code m: list1 + comptest $'tst \t' +0:Match Error for "m:" +>line: {tst }{} +>COMPADD:{_tst:compadd: missing patterns} +>INSERT_POSITIONS:{} + + test_code M: list1 + comptest $'tst \t' +0:Match Error for "M:" +>line: {tst }{} +>COMPADD:{_tst:compadd: missing patterns} +>INSERT_POSITIONS:{} + + test_code r: list1 + comptest $'tst \t' +0:Match Error "r:" +>line: {tst }{} +>COMPADD:{_tst:compadd: missing patterns} +>INSERT_POSITIONS:{} + + test_code R: list1 + comptest $'tst \t' +0:Match Error "R:" +>line: {tst }{} +>COMPADD:{_tst:compadd: missing patterns} +>INSERT_POSITIONS:{} + + test_code l: list1 + comptest $'tst \t' +0:Match Error for "l:" +>line: {tst }{} +>COMPADD:{_tst:compadd: missing patterns} +>INSERT_POSITIONS:{} + + test_code L: list1 + comptest $'tst \t' +0:Match Error for "L:" +>line: {tst }{} +>COMPADD:{_tst:compadd: missing patterns} +>INSERT_POSITIONS:{} + + test_code 'm:{0-9' list1 + comptest $'tst \t' +0:Match Error for "m:{0-9" +>line: {tst }{} +>COMPADD:{_tst:compadd: unterminated character class} +>INSERT_POSITIONS:{} + + test_code 'm:{0-9}' list1 + comptest $'tst \t' +0:Match Error for "m:{0-9}" +>line: {tst }{} +>COMPADD:{_tst:compadd: missing word pattern} +>INSERT_POSITIONS:{} + + test_code 'm:{0-9}={' list1 + comptest $'tst \t' +0:Match Error for "m:{0-9}={" +>line: {tst }{} +>COMPADD:{_tst:compadd: unterminated character class} +>INSERT_POSITIONS:{} + + test_code 'm:{0-9}={0-' list1 + comptest $'tst \t' +0:Match Error for "m:{0-9}={0-" +>line: {tst }{} +>COMPADD:{_tst:compadd: unterminated character class} +>INSERT_POSITIONS:{} + + test_code 'm:{0-9}={-' list1 + comptest $'tst \t' +0:Match Error for "m:{0-9}={-" +>line: {tst }{} +>COMPADD:{_tst:compadd: unterminated character class} +>INSERT_POSITIONS:{} + + test_code r: list1 + comptest $'tst \t' +0:Match Error "r:" +>line: {tst }{} +>COMPADD:{_tst:compadd: missing patterns} +>INSERT_POSITIONS:{} + + example1_list=( + kshoptionprint shglob + listambiguous shinstdin + listbeep shnullcmd + listpacked shoptionletters + listrowsfirst shortloops + listtypes shwordsplit + ) + options_matcher='L:|[nN][oO]= M:_= M:{A-Z}={a-z}' + test_code $options_matcher example1_list + comptest $'tst nolistbee\t' +0:Documentation example for options, input "nolistbee" +>line: {tst nolistbeep }{} +>COMPADD:{} +>INSERT_POSITIONS:{14} + + + test_code $options_matcher example1_list + comptest $'tst list_bee\t' +0:Documentation example for options, input "list_bee" +>line: {tst list_beep }{} +>COMPADD:{} +>INSERT_POSITIONS:{13} + + test_code $options_matcher example1_list + comptest $'tst ListBee\t' +0:Documentation example for options, input "ListBee" +>line: {tst ListBeep }{} +>COMPADD:{} +>INSERT_POSITIONS:{12} + + test_code $options_matcher example1_list + comptest $'tst NOList\tB\t' +0:Documentation example for options, input "NOList" +>line: {tst NOList}{} +>COMPADD:{} +>INSERT_POSITIONS:{10} +>NO:{NOListambiguous} +>NO:{NOListbeep} +>NO:{NOListpacked} +>NO:{NOListrowsfirst} +>NO:{NOListtypes} +>line: {tst NOListBeep }{} +>COMPADD:{} +>INSERT_POSITIONS:{14} + + + test_code $options_matcher example1_list + comptest $'tst NO_List\t__\tB\t' +0:Documentation example for options, input "NO_List\t__\tB\t" +>line: {tst NO_List}{} +>COMPADD:{} +>INSERT_POSITIONS:{11} +>NO:{NO_Listambiguous} +>NO:{NO_Listbeep} +>NO:{NO_Listpacked} +>NO:{NO_Listrowsfirst} +>NO:{NO_Listtypes} +>line: {tst NO_List__}{} +>COMPADD:{} +>INSERT_POSITIONS:{13} +>NO:{NO_List__ambiguous} +>NO:{NO_List__beep} +>NO:{NO_List__packed} +>NO:{NO_List__rowsfirst} +>NO:{NO_List__types} +>line: {tst NO_List__Beep }{} +>COMPADD:{} +>INSERT_POSITIONS:{17} + + test_code $options_matcher example1_list + comptest $'tst __\tN\t__o\t___\tlist_\tbeep__\t' +0:Documentation example for options, input "__\tN\t__o\t___\tlist_\tbeep__\t" +>line: {tst __}{} +>COMPADD:{} +>INSERT_POSITIONS:{6} +>NO:{__kshoptionprint} +>NO:{__listambiguous} +>NO:{__listbeep} +>NO:{__listpacked} +>NO:{__listrowsfirst} +>NO:{__listtypes} +>NO:{__shglob} +>NO:{__shinstdin} +>NO:{__shnullcmd} +>NO:{__shoptionletters} +>NO:{__shortloops} +>NO:{__shwordsplit} +>line: {tst __N}{} +>COMPADD:{} +>INSERT_POSITIONS:{} +>line: {tst __N__o}{} +>COMPADD:{} +>INSERT_POSITIONS:{} +>line: {tst __N__o___}{} +>COMPADD:{} +>INSERT_POSITIONS:{} +>line: {tst __N__o___list_}{} +>COMPADD:{} +>INSERT_POSITIONS:{} +>line: {tst __N__o___list_beep__}{} +>COMPADD:{} +>INSERT_POSITIONS:{} + + test_code $options_matcher example1_list + comptest $'tst __\tNo\t___\tlist_\tbeep__\t' +0:Documentation example for options, input "__\tNo\t___\tlist_\tbeep__\t" +>line: {tst __}{} +>COMPADD:{} +>INSERT_POSITIONS:{6} +>NO:{__kshoptionprint} +>NO:{__listambiguous} +>NO:{__listbeep} +>NO:{__listpacked} +>NO:{__listrowsfirst} +>NO:{__listtypes} +>NO:{__shglob} +>NO:{__shinstdin} +>NO:{__shnullcmd} +>NO:{__shoptionletters} +>NO:{__shortloops} +>NO:{__shwordsplit} +>line: {tst __No}{} +>COMPADD:{} +>INSERT_POSITIONS:{} +>line: {tst __No___}{} +>COMPADD:{} +>INSERT_POSITIONS:{} +>line: {tst __No___list_}{} +>COMPADD:{} +>INSERT_POSITIONS:{} +>line: {tst __No___list_beep__}{} +>COMPADD:{} +>INSERT_POSITIONS:{} + + + test_code $options_matcher example1_list + comptest $'tst ___\tlist_\tbeep__\t' +0:Documentation example for options, input "___\tlist_\tbeep__\t" +>line: {tst ___}{} +>COMPADD:{} +>INSERT_POSITIONS:{7} +>NO:{___kshoptionprint} +>NO:{___listambiguous} +>NO:{___listbeep} +>NO:{___listpacked} +>NO:{___listrowsfirst} +>NO:{___listtypes} +>NO:{___shglob} +>NO:{___shinstdin} +>NO:{___shnullcmd} +>NO:{___shoptionletters} +>NO:{___shortloops} +>NO:{___shwordsplit} +>line: {tst ___list_}{} +>COMPADD:{} +>INSERT_POSITIONS:{12} +>NO:{___list_ambiguous} +>NO:{___list_beep} +>NO:{___list_packed} +>NO:{___list_rowsfirst} +>NO:{___list_types} +>line: {tst ___list_beep__ }{} +>COMPADD:{} +>INSERT_POSITIONS:{18} + + test_code 'B:[nN][oO]= M:_= M:{A-Z}={a-z}' example1_list + comptest $'tst __no_listbe\t' +0:Documentation example for options, input "__no_listbe" +>line: {tst __no_listbeep }{} +>COMPADD:{} +>INSERT_POSITIONS:{17} + + test_code 'B:[nN][oO]= M:_= M:{A-Z}={a-z}' example1_list + comptest $'tst nonono_listbe\t' +0:Documentation example for options, input "nonono_listbe" +>line: {tst nonono_listbeep }{} +>COMPADD:{} +>INSERT_POSITIONS:{19} + + lower_insensitive_M="M:{a-z}={A-Z}" + lower_insensitive_m="m:{a-z}={A-Z}" + example2_list=(ABC Abc abc) + test_code $lower_insensitive_M example2_list + comptest $'tst ab\tC\t' +0:Documentation example for lowercase insenitive M, input "ab\tC\t" +>line: {tst ab}{} +>COMPADD:{} +>INSERT_POSITIONS:{6} +>NO:{abC} +>NO:{abc} +>line: {tst abC }{} +>COMPADD:{} +>INSERT_POSITIONS:{7} + + test_code $lower_insensitive_m example2_list + comptest $'tst A\t\t' +0:Documentation example for lowercase insenitive m, input "A\t\t" +>line: {tst A}{} +>COMPADD:{} +>INSERT_POSITIONS:{5} +>NO:{ABC} +>NO:{Abc} +>line: {tst ABC}{} +>COMPADD:{} +>INSERT_POSITIONS:{5} + + example3_list=(ABC Abc abc) + case_insensitive_M="M:{a-zA-Z}={A-Za-z}" + case_insensitive_m="m:{a-zA-Z}={A-Za-z}" + test_code $case_insensitive_M example3_list + comptest $'tst aB\t\t' +0:Documentation example for case insenitive M, input "aB\t\t" +>line: {tst aB}{} +>COMPADD:{} +>INSERT_POSITIONS:{6} +>NO:{aBC} +>NO:{aBc} +>line: {tst aBC}{} +>COMPADD:{} +>INSERT_POSITIONS:{6} + + + test_code $case_insensitive_m example3_list + comptest $'tst aB\t\t' +0:Documentation example for case insenitive m, input "aB\t\t" +>line: {tst a}{BC} +>COMPADD:{} +>INSERT_POSITIONS:{5:7} +>line: {tst a}{BC} +>COMPADD:{} +>INSERT_POSITIONS:{5:7} +>NO:{ABC} +>NO:{Abc} +>NO:{abc} + + example4_matcher='r:|.=* r:|=*' + example4_list=(comp.sources.unix comp.sources.misc + comp.graphics.algorithms comp.graphics.animation comp.graphics.api + comp.graphics.apps comp.graphics.misc comp.graphics.packages + comp.graphics.rendering comp.graphics.visualization comp.graphics.apps.alias + comp.graphics.apps.gimp comp.graphics.apps.gnuplot + comp.graphics.apps.lightwave comp.graphics.apps.pagemaker + comp.graphics.apps.paint-shop-pro comp.graphics.apps.photoshop + comp.graphics.apps.softimage comp.graphics.apps.ulead + comp.graphics.rendering.misc comp.graphics.rendering.raytracing + comp.graphics.rendering.renderman) + test_code $example4_matcher example4_list + comptest $'tst c.s.u\t' +0:Documentation example using input c.s.u +>line: {tst comp.sources.unix }{} +>COMPADD:{} +>INSERT_POSITIONS:{21} + + test_code $example4_matcher example4_list + comptest $'tst c.g.\ta\t.\tp\ta\tg\t' +0:Documentation example using input c.g.\ta\t.\tp\ta\tg\t +>line: {tst comp.graphics.}{} +>COMPADD:{} +>INSERT_POSITIONS:{18} +>line: {tst comp.graphics.a}{} +>COMPADD:{} +>INSERT_POSITIONS:{19} +>NO:{comp.graphics.algorithms} +>NO:{comp.graphics.animation} +>NO:{comp.graphics.api} +>NO:{comp.graphics.apps} +>NO:{comp.graphics.apps.alias} +>NO:{comp.graphics.apps.gimp} +>NO:{comp.graphics.apps.gnuplot} +>NO:{comp.graphics.apps.lightwave} +>NO:{comp.graphics.apps.pagemaker} +>NO:{comp.graphics.apps.paint-shop-pro} +>NO:{comp.graphics.apps.photoshop} +>NO:{comp.graphics.apps.softimage} +>NO:{comp.graphics.apps.ulead} +>line: {tst comp.graphics.apps.}{} +>COMPADD:{} +>INSERT_POSITIONS:{23} +>line: {tst comp.graphics.apps.p}{} +>COMPADD:{} +>INSERT_POSITIONS:{24} +>NO:{comp.graphics.apps.pagemaker} +>NO:{comp.graphics.apps.paint-shop-pro} +>NO:{comp.graphics.apps.photoshop} +>line: {tst comp.graphics.apps.pa}{} +>COMPADD:{} +>INSERT_POSITIONS:{25} +>NO:{comp.graphics.apps.pagemaker} +>NO:{comp.graphics.apps.paint-shop-pro} +>line: {tst comp.graphics.apps.pagemaker }{} +>COMPADD:{} +>INSERT_POSITIONS:{32} + + test_code $example4_matcher example4_list + comptest $'tst c...pag\t' +0:Documentation example using input c...pag\t +>line: {tst comp.graphics.apps.pagemaker }{} +>COMPADD:{} +>INSERT_POSITIONS:{32} + + test_code $example4_matcher example4_list + comptest $'tst c...pa\tg\t' +0:Documentation example using input c...pa\tg\t +>line: {tst comp.graphics.apps.pa}{} +>COMPADD:{} +>INSERT_POSITIONS:{25} +>line: {tst comp.graphics.apps.pagemaker }{} +>COMPADD:{} +>INSERT_POSITIONS:{32} + + example5_matcher='r:|[.,_-]=* r:|=*' + example5_list=(veryverylongfile.c veryverylongheader.h) + test_code $example5_matcher example5_list + comptest $'tst v.c\tv.h\t' +0:Documentation example using input v.c\t +>line: {tst veryverylongfile.c }{} +>COMPADD:{} +>INSERT_POSITIONS:{23} +>line: {tst veryverylongfile.c veryverylongheader.h }{} +>COMPADD:{} +>INSERT_POSITIONS:{44} + + + example6_list=(LikeTHIS FooHoo 5foo123 5bar234) + test_code 'r:|[A-Z0-9]=* r:|=*' example6_list + comptest $'tst H\t' +0:Documentation example using "r:|[A-Z0-9]=* r:|=*", input H +>line: {tst H}{} +>COMPADD:{} +>INSERT_POSITIONS:{} + + test_code 'r:|[A-Z0-9]=* r:|=*' example6_list + comptest $'tst 2\t' +0:Documentation example using "r:|[A-Z0-9]=* r:|=*", input 2 +>line: {tst 2}{} +>COMPADD:{} +>INSERT_POSITIONS:{} + + test_code 'r:|[A-Z0-9]=** r:|=*' example6_list + comptest $'tst H\t' +0:Documentation example using "r:|[A-Z0-9]=** r:|=*", input H +>line: {tst H}{} +>COMPADD:{} +>INSERT_POSITIONS:{4} +>NO:{FooHoo} +>NO:{LikeTHIS} + + test_code 'r:|[A-Z0-9]=** r:|=*' example6_list + comptest $'tst 2\t\t' +0:Documentation example using "r:|[A-Z0-9]=** r:|=*", input 2 +>line: {tst 5}{23} +>COMPADD:{} +>INSERT_POSITIONS:{5:7} +>line: {tst 5}{23} +>COMPADD:{} +>INSERT_POSITIONS:{5:7} +>NO:{5bar234} +>NO:{5foo123} + + example7_matcher="r:[^A-Z0-9]||[A-Z0-9]=** r:|=*" + example7_list=($example6_list) + test_code $example7_matcher example7_list + comptest $'tst H\t2\t' +0:Documentation example using "r:[^A-Z0-9]||[A-Z0-9]=** r:|=*" +>line: {tst FooHoo }{} +>COMPADD:{} +>INSERT_POSITIONS:{10} +>line: {tst FooHoo 5bar234 }{} +>COMPADD:{} +>INSERT_POSITIONS:{18} + + + workers_7311_matcher="m:{a-z}={A-Z} r:|[.,_-]=* r:|=*" + workers_7311_list=(Abc-Def-Ghij.txt Abc-def.ghi.jkl_mno.pqr.txt Abc_def_ghi_jkl_mno_pqr.txt) + test_code $workers_7311_matcher workers_7311_list + comptest $'tst a-a\t' +0:Bug from workers 7311 +>line: {tst a-a}{} +>COMPADD:{} +>INSERT_POSITIONS:{} + + test_code $workers_7311_matcher workers_7311_list + comptest $'tst a\t\t-d.\t' +0:Bug from workers_7311 +>line: {tst Abc}{} +>COMPADD:{} +>INSERT_POSITIONS:{7} +>line: {tst Abc}{} +>COMPADD:{} +>INSERT_POSITIONS:{7} +>NO:{Abc-Def-Ghij.txt} +>NO:{Abc-def.ghi.jkl_mno.pqr.txt} +>NO:{Abc_def_ghi_jkl_mno_pqr.txt} +>line: {tst Abc-def.ghi.jkl_mno.pqr.txt }{} +>COMPADD:{} +>INSERT_POSITIONS:{31} + + workers_10886_matcher="r:|[A-Z0-9]=* r:|=*" + workers_10886_list=(BW UWB W) + test_code $workers_10886_matcher workers_10886_list + comptest $'tst W\t' +0:Bug from workers 10886 +>line: {tst W }{} +>COMPADD:{} +>INSERT_POSITIONS:{5} + + workers_11081_matcher='m:{a-zA-Z}={A-Za-z} r:|[.,_-]=* r:[^A-Z0-9]||[A-Z0-9]=* r:[A-Z0-9]||[^A-Z0-9]=* r:[^0-9]||[0-9]=* r:|=*' + workers_11081_list=(build.out build.out1 build.out2) + test_code $workers_11081_matcher workers_11081_list + comptest $'tst bui\t\t\t' +0:Bug from workers 11081 +>line: {tst build.out}{} +>COMPADD:{} +>INSERT_POSITIONS:{13} +>line: {tst build.out}{} +>COMPADD:{} +>INSERT_POSITIONS:{13} +>NO:{build.out} +>NO:{build.out1} +>NO:{build.out2} +>line: {tst build.out}{} +>COMPADD:{} +>INSERT_POSITIONS:{13} + + + workers_11388_matcher='r:|[:.]=* r:|=*' + workers_11388_list=(a.b:0 c.d:1) + test_code $workers_11388_matcher workers_11388_list + comptest $'tst :\t' +0:Non-bug from workers 11388 +>line: {tst :}{} +>COMPADD:{} +>INSERT_POSITIONS:{} + + workers_11388_matcher='r:|[:.]=** r:|=*' + workers_11388_list=(a.b:0 c.d:1) + test_code $workers_11388_matcher workers_11388_list + comptest $'tst :\t' +0:Non-bug from workers 11388 +>line: {tst .:}{} +>COMPADD:{} +>INSERT_POSITIONS:{4:5:6} + + workers_11586_matcher='r:|.=** r:[^0-9]||[0-9]=**' + workers_11586_list=(c00.abc c01.abc.def.00.0) + test_code $workers_11586_matcher workers_11586_list + comptest $'tst c00\t.\ta\t' +0:Bug from workers 11586 +>line: {tst c00}{} +>COMPADD:{} +>INSERT_POSITIONS:{6} +>NO:{c00.abc} +>NO:{c01.abc.def.00.0} +>line: {tst c00.}{} +>COMPADD:{} +>INSERT_POSITIONS:{7:8} +>NO:{c00.abc} +>NO:{c01.abc.def.00.0} +>line: {tst c00.abc }{} +>COMPADD:{} +>INSERT_POSITIONS:{11} + + workers_12995a_matcher='r:|/=* r:|=*' + workers_12995a_list=(u1 u1/q1 u1/q1/e1 u2 u2/q1 u2/q1/e2 u2/q1/e2/a1 u2/q1/e2/a2 u3 u3/q1 u4 u4/q u4/q/a1 u4/q/a2) + test_code $workers_12995a_matcher workers_12995a_list + comptest $'tst u/q/a\t' +0:First test from workers 12995 +>line: {tst u4/q/a}{} +>COMPADD:{} +>INSERT_POSITIONS:{10} + + workers_12995b_matcher='m:{a-z}={A-Z} r:|/=* r:|=*' + workers_12995b_list=(../Completion/Core ../Completion/Commands) + test_code $workers_12995b_matcher workers_12995b_list + comptest $'tst ../com/cor\002\002\002\002\002\002\002\t' +0:Second test from workers 12995 +>line: {tst ../Completion/Core }{} +>COMPADD:{} +>INSERT_POSITIONS:{22} + + workers_13320_matcher='r:|[.,_-]=** r:[^0-9]||[0-9]=**' + workers_13320_list=(glibc-2.1.94-3.i386.rpm glibc-devel-2.1.94-3.i386.rpm) + workers_13320_list=($workers_13320_list glibc-profile-2.1.94-3.i386.rpm) + test_code $workers_13320_matcher workers_13320_list + comptest $'tst glibc-2.1\t' +0:Test from workers 13320 +>line: {tst glibc}{-2.1.94-3.i386.rpm} +>COMPADD:{} +>INSERT_POSITIONS:{9:27} + + test_code $workers_13320_matcher workers_13320_list + comptest $'tst g-2\t' +0:Test from workers 13320 +>line: {tst glibc}{-2.1.94-3.i386.rpm} +>COMPADD:{} +>INSERT_POSITIONS:{9:27} + + workers_13345a_matcher='r:|[.,_-]=**' + workers_13345a_list=(A.B.C A.B.C.D A.C) + test_code $workers_13345a_matcher workers_13345a_list + comptest $'tst A.C\t' +0:First test from workers 13345 +>line: {tst A.C}{} +>COMPADD:{} +>INSERT_POSITIONS:{5:7} +>NO:{A.B.C} +>NO:{A.B.C.D} +>NO:{A.C} + + + workers_13345b_matcher='r:|[.,_-]=** r:[^0-9]||[0-9]=**' + workers_13345b_list=(a-b_1_2_2 a-b_2_0.gz a-b_2_0.zip) + test_code $workers_13345b_matcher workers_13345b_list + comptest $'tst a-b_2\t' +0:Second test from workers 13345 +>line: {tst a-b_2_}{} +>COMPADD:{} +>INSERT_POSITIONS:{8:10} + + workers_13382_matcher='r:|.=**' + workers_13382_list=(a.b.c a.b.c.d aA.bB.cB.dA aA.bB.cC.dD aD.bC.cB.dA aA.bC.cB.dA) + test_code $workers_13382_matcher workers_13382_list + comptest $'tst a...\tA\tC\t' +0:Test for insert positions +>line: {tst a.b.c.d}{} +>COMPADD:{} +>INSERT_POSITIONS:{5:7:9:11} +>line: {tst a.b}{.cB.dA} +>COMPADD:{} +>INSERT_POSITIONS:{5:7:13} +>line: {tst a}{.bC.cB.dA} +>COMPADD:{} +>INSERT_POSITIONS:{5:14} +>NO:{aA.bC.cB.dA} +>NO:{aD.bC.cB.dA} + + +%clean + + zmodload -ui zsh/zpty diff --git a/Test/Y03arguments.ztst b/Test/Y03arguments.ztst new file mode 100644 index 000000000..2ffa11577 --- /dev/null +++ b/Test/Y03arguments.ztst @@ -0,0 +1,151 @@ +# Tests for _arguments. + +%prep + . $ZTST_srcdir/comptest + + mkdir comp.tmp + cd comp.tmp + + comptestinit -z $ZTST_testdir/../Src/zsh && + { + comptesteval 'compdef _tst tst' + tst_arguments () { comptesteval "_tst () { _arguments ${${(@qq)*}} }" } + } + +%test + tst_arguments ':desc1:(arg1)' + comptest $'tst \t\C-wa\t\C-war\t\C-warg\t\C-warg1\t\C-wr\t\C-wx\t \ty \t' +0:one non-option argument +>line: {tst arg1 }{} +>line: {tst arg1 }{} +>line: {tst arg1 }{} +>line: {tst arg1 }{} +>line: {tst arg1 }{} +>line: {tst r}{} +>line: {tst x}{} +>line: {tst x }{} +>MESSAGE:{no more arguments} +>line: {tst x y }{} +>MESSAGE:{no more arguments} + + tst_arguments ':desc1:(a b)' + comptest $'tst \t' +0:a and b +>line: {tst }{} +>DESCRIPTION:{desc1} +>NO:{a} +>NO:{b} + + tst_arguments ':desc1:(arg1)' ':desc2:(arg2)' ':desc3:(arg3)' + comptest $'tst \t\t\t\C-w\C-w\C-w\C-d' +0:three arguments +>line: {tst arg1 }{} +>line: {tst arg1 arg2 }{} +>line: {tst arg1 arg2 arg3 }{} +>DESCRIPTION:{desc1} +>NO:{arg1} + + tst_arguments '1:desc1:(arg1)' + comptest $'tst \t\t' +0:first argument +>line: {tst arg1 }{} +>line: {tst arg1 }{} +>MESSAGE:{no more arguments} + + tst_arguments '-\+[opt]' + comptest $'tst -\C-d' +0:-+ +>DESCRIPTION:{option} +>NO:{-+ -- opt} + + tst_arguments -+o + comptest $'tst -\t\t\t\C-w\C-w+\t\t\t' +0:option beginning with + and -. +>line: {tst -o }{} +>line: {tst -o +o }{} +>line: {tst -o +o }{} +>MESSAGE:{no arguments} +>line: {tst +o }{} +>line: {tst +o -o }{} +>line: {tst +o -o }{} +>MESSAGE:{no arguments} + + tst_arguments '-o:1:(a):2:(b)' + comptest $'tst \t\t\t' +0:two option arguments +>line: {tst -o }{} +>line: {tst -o a }{} +>line: {tst -o a b }{} + + tst_arguments '-x:arg:' + comptest $'tst -x\t' +0:sticky option argument +>line: {tst -x }{} + + tst_arguments '-x[desc]' + comptest $'tst -x\t' +0:end of option sequence +>line: {tst -x }{} + + tst_arguments '-x' ':arg:' + comptest $'tst -\t' +0:argument beginning with minus +>line: {tst -}{} +>MESSAGE:{arg} +>DESCRIPTION:{option} +>NO:{-x} + + tst_arguments '-o::optarg:(oa)' ':arg1:(a1)' + comptest $'tst -o\t\t' +0:optional option argument +>line: {tst -o }{} +>line: {tst -o }{} +>DESCRIPTION:{optarg} +>NO:{oa} +>DESCRIPTION:{arg1} +>NO:{a1} + + tst_arguments '-o:*a:a:(a)' ':A:(A)' ':B:(B)' + comptest $'tst A -o a \t' +0:variable length option arguments +>line: {tst A -o a B }{} + + tst_arguments -s '-a' '-b' ':descr:{compadd - $+opt_args[-a]}' + comptest $'tst -ab \t' +0:opt_args +>line: {tst -ab 1 }{} + + tst_arguments '-a' '*::rest:{compadd - -b}' + comptest $'tst arg -\t' +0:rest arguments +>line: {tst arg -b }{} + + 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 +>line: {tst -e }{} +>line: {tst -e }{} +>line: {tst -e la }{} +>line: {tst -e last }{} +>line: {tst -e last arg1 }{} +>line: {tst -e ,last }{ last arg1} +>line: {tst -e ,last ,last,,last }{ last arg1} + + 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' + comptest $'tst ab\t' +0:options and words (zsh-workers:12257) +>line: {tst ab}{} +>DESCRIPTION:{words} +>NO:{abyyy} +>NO:{abzzz} + +%clean + + zmodload -ui zsh/zpty |