summaryrefslogtreecommitdiff
path: root/Doc/Zsh/expn.yo
diff options
context:
space:
mode:
Diffstat (limited to 'Doc/Zsh/expn.yo')
-rw-r--r--Doc/Zsh/expn.yo284
1 files changed, 224 insertions, 60 deletions
diff --git a/Doc/Zsh/expn.yo b/Doc/Zsh/expn.yo
index eb8cdbae5..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,6 +987,11 @@ 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 interpret
these as character codes. Output the corresponding characters. Note
@@ -1093,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
@@ -1177,34 +1202,35 @@ 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)
@@ -1212,16 +1238,20 @@ for parameters tied to another parameter in the manner of tt(PATH)
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
@@ -1229,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
@@ -1520,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)
@@ -1542,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
@@ -1773,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)
@@ -1970,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)
@@ -2987,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