about summary refs log tree commit diff
path: root/Doc/Zsh/expn.yo
diff options
context:
space:
mode:
Diffstat (limited to 'Doc/Zsh/expn.yo')
-rw-r--r--Doc/Zsh/expn.yo345
1 files changed, 265 insertions, 80 deletions
diff --git a/Doc/Zsh/expn.yo b/Doc/Zsh/expn.yo
index c218ded05..7eade4a11 100644
--- a/Doc/Zsh/expn.yo
+++ b/Doc/Zsh/expn.yo
@@ -84,7 +84,7 @@ vindex(histchars, use of)
 A history expansion begins with the first character of the tt(histchars)
 parameter, which is `tt(!)' by default, and may occur anywhere on the
 command line, including inside double quotes (but not inside single quotes
-tt('...') or C-style quotes tt($'...') nor when escaped with a backslash).  
+tt('...') or C-style quotes tt($'...') nor when escaped with a backslash).
 
 The first character is followed by an optional event designator
 (ifzman(see )noderef(Event Designators)) and then an optional word
@@ -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
@@ -496,7 +502,7 @@ which treats var(arg) as a file name and replaces it with the file's
 contents.
 
 The tt(=) form is useful as both the tt(/dev/fd) and the named pipe
-implementation of tt(<LPAR())var(...)tt(RPAR()) have drawbacks.  In 
+implementation of tt(<LPAR())var(...)tt(RPAR()) 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
@@ -511,7 +517,7 @@ 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:
 
-example(tt(paste <LPAR()cut -f1) var(file1)tt(RPAR() <LPAR()cut -f3) var(file2)tt(RPAR()) ifzman(\ 
+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
@@ -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()
 
@@ -872,7 +892,8 @@ of the string tt($-) and the array tt($*) respectively.  If
 tt(POSIX_IDENTIFIERS) is set, then braces are required for
 the tt(#) to be treated in this fashion.
 )
-item(tt(${^)var(spec)tt(}))(
+xitem(tt(${^)var(spec)tt(}))
+item(tt(${^^)var(spec)tt(}))(
 pindex(RC_EXPAND_PARAM, toggle)
 cindex(array expansion style, rc)
 cindex(rc, array expansion style)
@@ -895,7 +916,8 @@ happening later.  If word splitting is also in effect the
 tt($var[)var(N)tt(]) may themselves be split into different list
 elements.
 )
-item(tt(${=)var(spec)tt(}))(
+xitem(tt(${=)var(spec)tt(}))
+item(tt(${==)var(spec)tt(}))(
 pindex(SH_WORD_SPLIT, toggle)
 cindex(field splitting, sh style, parameter)
 cindex(sh, field splitting style, parameter)
@@ -911,7 +933,8 @@ Note that splitting is applied to var(word) in the assignment forms
 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(}))(
+xitem(tt(${~)var(spec)tt(}))
+item(tt(${~~)var(spec)tt(}))(
 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
@@ -964,17 +987,23 @@ 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.
 )
 item(tt(%))(
 Expand all tt(%) escapes in the resulting words in the same way as in
-prompts (see 
+prompts (see
 ifzman(EXPANSION OF PROMPT SEQUENCES in zmanref(zshmisc))\
 ifnzman(noderef(Prompt Expansion))). If this flag is given twice,
 full prompt expansion is done on the resulting words, depending on the
@@ -1089,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
@@ -1173,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
@@ -1220,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
@@ -1489,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.
@@ -1510,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)
@@ -1532,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
@@ -1729,7 +1870,7 @@ This produces the result tt(b).  First, the inner substitution
 tt("${foo}"), which has no array (tt(@)) flag, produces a single word
 result tt("bar baz").  The outer substitution tt("${(@)...[1]}") detects
 that this is a scalar, so that (despite the `tt((@))' flag) the subscript
-picks the first character. 
+picks the first character.
 )
 item(tt("${${(@)foo}[1]}"))(
 This produces the result `tt(bar)'.  In this case, the inner substitution
@@ -1763,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)
@@ -1854,7 +2037,7 @@ has similar effects.
 
 To combine brace expansion with array expansion, see the
 tt(${^)var(spec)tt(}) form described
-ifzman(in the section Parameter Expansion)\
+ifzman(in the section `Parameter Expansion')\
 ifnzman(in noderef(Parameter Expansion))
 above.
 
@@ -1889,6 +2072,14 @@ 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)
 cindex(named directories, dynamic)
@@ -1952,36 +2143,27 @@ 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)
 subsect(Static named directories)
 cindex(directories, named, static)
 cindex(named directories, static)
@@ -2008,6 +2190,7 @@ i.e. either the directory name or the full path; the name is used
 if they are the same length.
 The parameters tt($PWD) and tt($OLDPWD) are never abbreviated in this fashion.
 
+texinode(`=' expansion)(Notes)(Static named directories)(Filename Expansion)
 subsect(`=' expansion)
 
 If a word begins with an unquoted `tt(=)'
@@ -2017,6 +2200,7 @@ name of a command.  If a command
 exists by that name, the word is replaced
 by the full pathname of the command.
 
+texinode(Notes)()(`=' expansion)(Filename Expansion)
 subsect(Notes)
 cindex(filename expansion, notes)
 Filename expansion is performed on the right hand side of a parameter
@@ -2461,7 +2645,7 @@ qualifiers are also not applied in ordinary pattern matching.
 )
 item(tt(u))(
 Respect the current locale in determining the presence of multibyte
-characters in a pattern, provided the shell was compiled with 
+characters in a pattern, provided the shell was compiled with
 tt(MULTIBYTE_SUPPORT).  This overrides the tt(MULTIBYTE)
 option; the default behaviour is taken from the option.  Compare tt(U).
 (Mnemonic: typically multibyte characters are from Unicode in the UTF-8
@@ -2712,18 +2896,18 @@ expected, if combined with a `tt(=)', the value given must match the
 file-modes exactly, with a `tt(PLUS())', at least the bits in the
 given number must be set in the file-modes, and with a `tt(-)', the
 bits in the number must not be set. Giving a `tt(?)' instead of a
-octal digit anywhere in the number ensures that the corresponding bits 
+octal digit anywhere in the number ensures that the corresponding bits
 in the file-modes are not checked, this is only useful in combination
 with `tt(=)'.
 
 If the qualifier `tt(f)' is followed by any other character anything
-up to the next matching character (`tt([)', `tt({)', and `tt(<)' match 
+up to the next matching character (`tt([)', `tt({)', and `tt(<)' match
 `tt(])', `tt(})', and `tt(>)' respectively, any other character
 matches itself) is taken as a list of comma-separated
 var(sub-spec)s. Each var(sub-spec) may be either an octal number as
 described above or a list of any of the characters `tt(u)', `tt(g)',
 `tt(o)', and `tt(a)', followed by a `tt(=)', a `tt(PLUS())', or a
-`tt(-)', followed by a list of any of the characters `tt(r)', `tt(w)', 
+`tt(-)', followed by a list of any of the characters `tt(r)', `tt(w)',
 `tt(x)', `tt(s)', and `tt(t)', or an octal digit. The first list of
 characters specify which access rights are to be checked. If a `tt(u)'
 is given, those for the owner of the file are used, if a `tt(g)' is
@@ -2732,7 +2916,7 @@ of other users, and the `tt(a)' says to test all three groups. The
 `tt(=)', `tt(PLUS())', and `tt(-)' again says how the modes are to be
 checked and have the same meaning as described for the first form
 above. The second list of characters finally says which access rights
-are to be expected: `tt(r)' for read access, `tt(w)' for write access, 
+are to be expected: `tt(r)' for read access, `tt(w)' for write access,
 `tt(x)' for the right to execute the file (or to search a directory),
 `tt(s)' for the setuid and setgid bits, and `tt(t)' for the sticky
 bit.
@@ -2741,7 +2925,7 @@ Thus, `tt(*(f70?))' gives the files for which the owner has read,
 write, and execute permission, and for which other group members have
 no rights, independent of the permissions for other users. The pattern
 `tt(*(f-100))' gives all files for which the owner does not have
-execute permission, and `tt(*(f:gu+w,o-rx:))' gives the files for which 
+execute permission, and `tt(*(f:gu+w,o-rx:))' gives the files for which
 the owner and the other members of the group have at least write
 permission, and for which other users don't have read or execute
 permission.
@@ -2942,7 +3126,7 @@ item(tt([)var(beg)[tt(,)var(end)]tt(]))(
 specifies which of the matched filenames should be included in the
 returned list. The syntax is the same as for array
 subscripts. var(beg) and the optional var(end) may be mathematical
-expressions. As in parameter subscripting they may be negative to make 
+expressions. As in parameter subscripting they may be negative to make
 them count from the last match backward. E.g.: `tt(*(-OL[1,3]))'
 gives a list of the names of the three largest files.
 )
@@ -2966,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