diff options
Diffstat (limited to 'Doc/Zsh/expn.yo')
-rw-r--r-- | Doc/Zsh/expn.yo | 306 |
1 files changed, 242 insertions, 64 deletions
diff --git a/Doc/Zsh/expn.yo b/Doc/Zsh/expn.yo index 753e5a008..7eade4a11 100644 --- a/Doc/Zsh/expn.yo +++ b/Doc/Zsh/expn.yo @@ -312,7 +312,8 @@ zero) that are neither `tt(.)' nor `tt(/)' and that continue to the end of the string. For example, the extension of `tt(foo.orig.c)' is `tt(.c)', and `tt(dir.c/foo)' has no extension. ) -item(tt(s/)var(l)tt(/)var(r)[tt(/)])( +xitem(tt(s/)var(l)tt(/)var(r)[tt(/)]) +item(tt(S/)var(l)tt(/)var(r)[tt(/)])( Substitute var(r) for var(l) as described below. The substitution is done only for the first string that matches var(l). For arrays and for filename @@ -324,13 +325,17 @@ perform global substitution, i.e. substitute every occurrence of var(r) for var(l). Note that the tt(g) or tt(:G) must appear in exactly the position shown. +The use of tt(S) instead of tt(s) is identical except that +the source is treated as a pattern, just as if the option +tt(HIST_SUBST_PATTERN) were set. + See further notes on this form of substitution below. ) item(tt(&))( -Repeat the previous tt(s) substitution. Like tt(s), may be preceded -immediately by a tt(g). In parameter expansion the tt(&) must appear -inside braces, and in filename generation it must be quoted with a -backslash. +Repeat the previous tt(s) or tt(S) substitution, whichever was most +recent. Like tt(s) and tt(S), may be preceded immediately by a tt(g). +In parameter expansion the tt(&) must appear inside braces, and in +filename generation it must be quoted with a backslash. ) item(tt(t) [ var(digits) ])( Remove all leading pathname components, leaving the final component (tail). @@ -377,7 +382,8 @@ substitutions or expansions are performed once at the time the qualifier is parsed, even before the `tt(:s)' expression itself is divided into var(l) and var(r) sides. -If the option tt(HIST_SUBST_PATTERN) is set, var(l) is treated as +If the option tt(HIST_SUBST_PATTERN) is set or the original substitution +was started with a capital tt(S), var(l) is treated as a pattern of the usual form described in ifzman(the section FILENAME GENERATION below)\ ifnzman(noderef(Filename Generation)). This can be used in @@ -604,6 +610,16 @@ and other operators, such as `tt(${PREFIX:-"/usr/local"})'. Parameter expansions can also be nested. These topics will be introduced below. The full rules are complicated and are noted at the end. +cindex(namespace) +Parameter expansions may optionally include a em(namespace) prefix in +the format `tt(.)var(identifier)tt(.)' This currently has no special +meaning to the shell, but provides a convenient means of grouping +related parameters. Expansions using a namespace em(must) include +braces (tt({) and tt(})) as shown in the descriptions below, and +only one namespace prefix is allowed. Note that, for support of +possible future features, the first `tt(.)' is optional, but omitting +it is discouraged. + In the expansions discussed below that require a pattern, the form of the pattern is the same as that used for filename generation; see noderef(Filename Generation). Note that these patterns, along with @@ -616,6 +632,8 @@ substitution on the expansion of parameter tt($i). In the following descriptions, `var(word)' refers to a single word substituted on the command line, not necessarily a space delimited word. +The reference to `var(name)' in each description presumes any optional +namespace prefix. startitem() item(tt(${)var(name)tt(}))( @@ -665,7 +683,9 @@ item(tt(${)var(name)tt(:?)var(word)tt(}))( In the first form, if var(name) is set, or in the second form if var(name) is both set and non-null, then substitute its value; otherwise, print var(word) and exit from the shell. Interactive shells instead return to -the prompt. If var(word) is omitted, then a standard message is printed. +the prompt. If var(word) is omitted, then a standard message is +printed. Note that var(word) is expanded even though its value +is not substituted onto the command line. ) enditem() @@ -967,10 +987,16 @@ means the same thing as the more readable `(tt(%%qqq))'. The following flags are supported: startitem() +item(tt(!))( +When the parameter being expanded is a named reference, the reference +itself is examined and thus is em(not) resolved to its referent. In +ksh emulation, the parens around this flag are optional. +) item(tt(#))( -Evaluate the resulting words as numeric expressions and output the -characters corresponding to the resulting integer. Note that this form is -entirely distinct from use of the tt(#) without parentheses. +Evaluate the resulting words as numeric expressions and interpret +these as character codes. Output the corresponding characters. Note +that this form is entirely distinct from use of the tt(#) without +parentheses. If the tt(MULTIBYTE) option is set and the number is greater than 127 (i.e. not an ASCII character) it is treated as a Unicode character. @@ -1092,7 +1118,7 @@ tt(KSH_ARRAYS) option a subscript `tt([*])' or `tt([@])' is needed to operate on the whole array, as usual. ) item(tt(L))( -Convert all letters in the result to lower case. +Convert all letters in the result to lower case, like `tt(typeset -l)'. ) item(tt(n))( Sort decimal integers numerically; if the first differing @@ -1176,46 +1202,56 @@ of the parameter would usually appear. This string consists of keywords separated by hyphens (`tt(-)'). The first keyword in the string describes the main type, it can be one of `tt(scalar)', `tt(array)', `tt(integer)', `tt(float)' or `tt(association)'. The other keywords describe the type in -more detail: +more detail, in most cases corresponding to options of the `tt(typeset)' +command: startitem() item(tt(local))( for local parameters ) item(tt(left))( -for left justified parameters +for left justified parameters (tt(-L)) ) item(tt(right_blanks))( -for right justified parameters with leading blanks +for right justified parameters with leading blanks (tt(-R)) ) item(tt(right_zeros))( -for right justified parameters with leading zeros +for right justified parameters with leading zeros (tt(-Z)) ) item(tt(lower))( for parameters whose value is converted to all lower case when it is -expanded +expanded (tt(-l)) ) item(tt(upper))( for parameters whose value is converted to all upper case when it is -expanded +expanded (tt(-u)) ) item(tt(readonly))( -for readonly parameters +for readonly parameters (tt(-r)) ) item(tt(tag))( -for tagged parameters +for tagged parameters (tt(-t)) +) +item(tt(tied))( +for parameters tied to another parameter in the manner of tt(PATH) +(colon-separated list) and tt(path) (array), whether these are +special parameters or user-defined with `tt(typeset -T)' ) item(tt(export))( -for exported parameters +for exported parameters (tt(-x) or `tt(export)') ) item(tt(unique))( -for arrays which keep only the first occurrence of duplicated values +for arrays which keep only the first occurrence of duplicated values (tt(-U)) ) item(tt(hide))( -for parameters with the `hide' flag +for parameters with the `hide' flag (tt(-h)) ) item(tt(hideval))( -for parameters with the `hideval' flag +for parameters with the `hideval' flag (tt(-H)) +) +item(tt(nameref))( +for named references (tt(typeset -n)) either having an empty value or +when combined with `tt(!)' as in `tt(${LPAR()!t)tt(RPAR()var(rname)})' ) item(tt(special))( for special parameters defined by the shell @@ -1223,10 +1259,10 @@ for special parameters defined by the shell enditem() ) item(tt(u))( -Expand only the first occurrence of each unique word. +Expand only the first occurrence of each unique word, like `tt(typeset -U)'. ) item(tt(U))( -Convert all letters in the result to upper case. +Convert all letters in the result to upper case, like `tt(typeset -u)'. ) item(tt(v))( Used with tt(k), substitute (as two consecutive words) both the key @@ -1492,8 +1528,9 @@ form using `tt(%%)' will remove the same matches as for `tt(##)' in reverse order. ) item(tt(*))( +pindex(EXTENDED_GLOB, enable) Enable tt(EXTENDED_GLOB) for substitution via tt(${)...tt(/)...tt(}) or -tt(${)...tt(//)...tt(}). +tt(${)...tt(//)...tt(}). Note that `tt(**)' does not disable extendedglob. ) item(tt(B))( Include the index of the beginning of the match in the result. @@ -1513,6 +1550,103 @@ Include the unmatched portion in the result (the em(R)est). ) enditem() +subsect(Named References) +cindex(named references) +cindex(namerefs) +cindex(reference variables) +cindex(parameters, nameref) +The command +ifzman() +indent(tt(typeset -n )var(pname)tt(=)var(rname)) + +initializes a parameter var(pname) as a reference to a second +parameter var(rname). With the few exceptions described here, when +var(pname) is used in any of the expansion forms described above, the +parameter var(rname) is expanded instead. This is similar to the +action of the `tt((P))' expansion flag, but when var(rname) has itself +been declared a named reference, that third parameter referenced by +var(pname) is also expanded, and so on. With `tt((P))' this must be +done explicitly, so for example +tt(${LPAR()P)tt(RPAR()${LPAR()P)tt(RPAR())var(name)tt(}}). + +Unlike `tt((P))', named references in substitutions that perform +assignment, such as tt(${)var(pname)tt(::=)var(word)tt(}), do not +create new arrays when var(rname) is in the form of an array element +or slice and no such array (or associative array) is presently set. +This includes arrays declared, but not initialized, when the option +tt(TYPESET_TO_UNSET) is in effect. The var(word) is substituted but +no assignment occurs. + +Also unlike `tt((P))' named references always expand parameters at +the scope in which var(rname) existed when `tt(typeset -n)' was +called. This can be used to expand or assign parameters from an +earlier scope even if a local of the same name has been declared at +a later scope. Example: +ifzman() +example(tt(caller=OUTER) +tt(func LPAR()RPAR() {) +tt( print before local: $caller) +tt( typeset -n outer=$1) +tt( local caller=INNER) +tt( print by reference: $outer) +tt( outer=RESULT) +tt(}) +tt(func caller) +tt(print after func: $caller)) + +displays the output +ifzman() +example(tt(before local: OUTER) +tt(by reference: OUTER) +tt(after func: RESULT)) + +To force a named reference to refer to the outer scope, even if a local +has already been declared, add the tt(-u) option when declaring the +named reference. In this case var(rname) should already exist in the +outer scope, otherwise the behavior of assignment through var(pname) +is not defined and may change the scope of the reference or fail with +a status of 1. Example of correct usage: +ifzman() +example(tt(caller=OUTER) +tt(func LPAR()RPAR() {) +tt( print before local: $caller) +tt( local caller=INNER) +tt( print after local: $caller) +tt( typeset -n -u outer=$1) +tt( print by reference: $outer) +tt( outer=RESULT) +tt(}) +tt(func caller) +tt(print after func: $caller)) + +Note, however, that named references to em(special) parameters acquire +the behavior of the special parameter, regardless of the scope where +the reference is declared. + +When var(rname) includes an array subscript, the subscript expression +is interpreted at the time tt(${)var(pname)tt(}) is expanded. Any +form of subscript is allowed, including those that select individual +elements, substrings of scalar strings, or multiple elements as with +array slices or the `tt((i))', `tt((I))', `tt((r))', `tt((R))' and +`tt((w))' subscript flags. However, the subscript is evaluated with +the tt(NO_EXEC) option in effect, so command substitution and other +similar constructs produce no output, although are not syntactically +excluded. + +When var(rname) is an array (but not an array element or slice), the +named reference may also be used in substitutions requiring an +var(arrayname), so these are equivalent: +ifzman() +example(tt(${)var(name)tt(:|)var(rname)tt(}) +tt(${)var(name)tt(:|)var(pname)tt(})) + +Expansions of the form `tt(${LPAR()t)tt(RPAR())var(pname)tt(})' expand +the type information of var(rname), unless var(rname) is empty, in which +case the expansion is `tt(nameref)', or when no variable var(rname) +exists, in which case the expansion is empty. + +See also ifzman(zmanref(zshparam))ifnzman(noderef(Parameters)). + subsect(Rules) cindex(parameter expansion rules) cindex(rules, parameter expansion) @@ -1535,12 +1669,16 @@ substitutions; the nested substitution will return either a scalar or an array as determined by the flags, possibly adjusted for quoting. All the following steps take place where applicable at all levels of substitution. -Note that, unless the `tt((P))' flag is present, the flags and any +Note that, unless the `tt((P))' flag or a named reference is present, +the flags and any subscripts apply directly to the value of the nested substitution; for example, the expansion tt(${${foo}}) behaves exactly the same as -tt(${foo}). When the `tt((P))' flag is present in a nested substitution, +tt(${foo}). When a named reference or the `tt((P))' flag is used in a +nested substitution, the other substitution rules are applied to the value em(before) it is interpreted as a name, so tt(${${(P)foo}}) may differ from tt(${(P)foo}). +When both a named reference and the `tt((P))' flag appear, the named +reference is resolved before `tt((P))' is applied. At each nested level of substitution, the substituted words undergo all forms of single-word substitution (i.e. not filename generation), including @@ -1766,23 +1904,65 @@ sect(Command Substitution) cindex(command substitution) cindex(substitution, command) A command enclosed in parentheses preceded by a dollar sign, like -`tt($LPAR())...tt(RPAR())', or quoted with grave -accents, like `tt(`)...tt(`)', is replaced with its standard output, with -any trailing newlines deleted. -If the substitution is not enclosed in double quotes, the -output is broken into words using the tt(IFS) parameter. +`tt($LPAR())...tt(RPAR())', or quoted with grave accents, like +`tt(`)...tt(`)', is executed in a subshell and replaced by its +standard output, with any trailing newlines deleted. If the +substitution is not enclosed in double quotes, the output is broken +into words using the tt(IFS) parameter. vindex(IFS, use of) The substitution `tt($LPAR()cat) var(foo)tt(RPAR())' may be replaced by the faster `tt($LPAR()<)var(foo)tt(RPAR())'. In this case var(foo) undergoes single word shell expansions (em(parameter expansion), em(command substitution) and em(arithmetic expansion)), but not -filename generation. +filename generation. No subshell is created. If the option tt(GLOB_SUBST) is set, the result of any unquoted command substitution, including the special form just mentioned, is eligible for filename generation. +A command with a leading pipe character, enclosed in braces prefixed by +a dollar sign, as in `tt(${|)...tt(})', is executed in the current shell +context, rather than in a subshell, and is replaced by the value of the +parameter tt(REPLY) at the end of the command. There em(must not) be +any whitespace between the opening brace and the pipe character. Any +prior value of tt($REPLY) is saved and restored around this substitution, +in the manner of a function local parameter. Other parameters declared +within the substitution also behave as locals, as if in a function, +unless `tt(typeset -g)' is used. Trailing newlines are em(not) deleted +from the final replacement in this case, and it is subject to filename +generation in the same way as `tt($LPAR())...tt(RPAR())' but is em(not) +split on tt(IFS) unless the tt(SH_WORD_SPLIT) option is set. + +cindex(substitution, command, current shell) +cindex(substitution, command, non forking) +cindex(substitution, nofork) +Substitutions of the form `tt(${{)var(param)tt(}) ...tt(})' are similar, +except that the substitution is replaced by the value of the parameter +named by var(param). No implicit save or restore applies to var(param) +and var(param) should em(not) be declared within the command. No space +is allowed within `tt(${{)' and space or newline is required after +`tt({)var(param)tt(})'. The var(param) may include a subscript, and if, +after evaluating the expression, var(param) names an array, then array +expansion rules apply to the final substitution. + +A command enclosed in braces preceded by a dollar sign, and set off from +the braces by whitespace, like `tt(${ )...tt( })', is replaced by its +standard output. Like `tt(${|)...tt(})' and unlike +`tt($LPAR())...tt(RPAR())', the command executes in the current shell +context with function local behaviors and does not create a subshell. +Word splitting does not apply unless tt(SH_WORD_SPLIT) is set, but a +single trailing newline is stripped unless the substitution is enclosed +in double quotes. + +Note that because `tt(${|)...tt(})' and the two related substitutions +must be parsed at once as both string tokens and commands, all other +braces (`tt({)' or `tt(})') within the command either must be quoted, +or must appear in syntactically valid pairs, such as around complex +commands, function bodies, or parameter references. Furthermore, +comments are always recognized, even when tt(NO_INTERACTIVE_COMMENTS) +is in effect. + texinode(Arithmetic Expansion)(Brace Expansion)(Command Substitution)(Expansion) sect(Arithmetic Expansion) cindex(arithmetic expansion) @@ -1892,6 +2072,13 @@ The tt(PUSHD_MINUS) option exchanges the effects of `tt(~PLUS())' and `tt(~-)' where they are followed by a number. +startmenu() +menu(Dynamic named directories) +menu(Static named directories) +menu(`=' expansion) +menu(Notes) +endmenu() + texinode(Dynamic named directories)(Static named directories)()(Filename Expansion) subsect(Dynamic named directories) cindex(directories, named, dynamic) @@ -1956,34 +2143,24 @@ tt(/home/pws/perforce). In this simple case a static name for the directory would be just as effective. example(zsh_directory_name+LPAR()RPAR() { - emulate -L zsh - setopt extendedglob + emulate -L zsh -o extendedglob local -a match mbegin mend - if [[ $1 = d ]]; then - # turn the directory into a name - if [[ $2 = (#b)(/home/pws/perforce/)([^/]##)* ]]; then - typeset -ga reply - reply=(p:$match[2] $(( ${#match[1]} + ${#match[2]} )) ) - else - return 1 - fi - elif [[ $1 = n ]]; then - # turn the name into a directory - [[ $2 != (#b)p:(?*) ]] && return 1 - typeset -ga reply - reply=(/home/pws/perforce/$match[1]) - elif [[ $1 = c ]]; then - # complete names - local expl - local -a dirs - dirs=(/home/pws/perforce/*(/:t)) - dirs=(p:${^dirs}) - _wanted dynamic-dirs expl 'dynamic directory' compadd -S\] -a dirs - return - else - return 1 - fi - return 0 + local base=/home/pws/perforce + case $1 in + ( d ) # Turn the directory into a name. + [[ $2 == (#b)($base/)([^/]##)* ]] && + reply=( p:$match[2] $(( $#match[1] + $#match[2] )) ) + ;; + ( n ) # Turn the name into a directory. + [[ $2 == (#b)p:(?*) ]] && + reply=( $base/$match[1] ) + ;; + ( c ) # Complete names. + local -a dirs=( $base/*(/:t) ) + # Completion system populates $expl with flags for compadd. + compadd "$expl[@]" p:$^dirs + ;; + esac }) texinode(Static named directories)(`=' expansion)(Dynamic named directories)(Filename Expansion) @@ -2973,9 +3150,10 @@ so both can be used on the same glob expression; for example by writing ) enditem() -More than one of these lists can be combined, separated by commas. The -whole list matches if at least one of the sublists matches (they are -`or'ed, the qualifiers in the sublists are `and'ed). Some qualifiers, +Multiple consecutive qualifiers are joined into a list by implicit logical AND. +More than one of these lists can be combined using comma `tt(,)' as logical OR. +The whole list matches if at least one of the sublists matches. +Some qualifiers, however, affect all matches generated, independent of the sublist in which they are given. These are the qualifiers `tt(M)', `tt(T)', `tt(N)', `tt(D)', `tt(n)', `tt(o)', `tt(O)' and the subscripts given |