Zsh Mailing List Archive
Messages sorted by:
Reverse Date,
Date,
Thread,
Author
[PATCH v2] coding practice in examples (-- with globs mostly)
- X-seq: zsh-workers 45183
- From: Stephane Chazelas <stephane.chazelas@xxxxxxxxx>
- To: zsh-workers@xxxxxxx
- Subject: [PATCH v2] coding practice in examples (-- with globs mostly)
- Date: Wed, 1 Jan 2020 21:18:09 +0000
- In-reply-to: <20200101125213.fo75ca2wdkwrbzi4@tarpaulin.shahaf.local2>
- List-help: <mailto:zsh-workers-help@zsh.org>
- List-id: Zsh Workers List <zsh-workers.zsh.org>
- List-post: <mailto:zsh-workers@zsh.org>
- List-unsubscribe: <mailto:zsh-workers-unsubscribe@zsh.org>
- Mailing-list: contact zsh-workers-help@xxxxxxx; run by ezmlm
- References: <20191231091618.v2erkblkwkiy3i5a@chaz.gmail.com> <20191231171638.en6olco722w4ldcc@tarpaulin.shahaf.local2> <20200101120009.24l375svthztyszj@chaz.gmail.com> <20200101125213.fo75ca2wdkwrbzi4@tarpaulin.shahaf.local2>
2020-01-01 12:52:13 +0000, Daniel Shahaf:
[...]
> Looks good, thanks. Please commit.
>
> Further suggestions (nice-to-have's, not blockers):
>
> - Clarify that the third -- isn't syntactically significant, and is just passed
> to ls verbatim.
[...]
Please find a new version below, with a small change that goes
in that direction. Note that I'm not a commiter (I don't mind it
staying that way), someone else would have to commit for me.
diff --git a/Doc/Zsh/builtins.yo b/Doc/Zsh/builtins.yo
index 415bce613..ada69c99a 100644
--- a/Doc/Zsh/builtins.yo
+++ b/Doc/Zsh/builtins.yo
@@ -39,11 +39,11 @@ be familiar to most command line users.
Typically, options are single letters preceded by a hyphen (tt(-)).
Options that take an argument accept it either immediately following the
-option letter or after white space, for example `tt(print -C3 *)' or
-`tt(print -C 3 *)' are equivalent. Arguments to options are not the
+option letter or after white space, for example `tt(print -C3 {1..9})' or
+`tt(print -C 3 {1..9})' are equivalent. Arguments to options are not the
same as arguments to the command; the documentation indicates which is
which. Options that do not take an argument may be combined in a single
-word, for example `tt(print -ca *)' and `tt(print -c -a *)' are
+word, for example `tt(print -rca -- *)' and `tt(print -r -c -a -- *)' are
equivalent.
Some shell builtin commands also take options that begin with `tt(+)'
@@ -54,14 +54,14 @@ Options (together with their individual arguments, if any) must appear
in a group before any non-option arguments; once the first non-option
argument has been found, option processing is terminated.
-All builtin commands other than precommand modifiers, even those that
-have no options, can be given the argument `tt(-)tt(-)' to terminate option
-processing. This indicates that the following words are non-option
-arguments, but is otherwise ignored. This is useful in cases where
-arguments to the command may begin with `tt(-)'. For historical
-reasons, most builtin commands also recognize a single `tt(-)' in a
-separate word for this purpose; note that this is less standard and
-use of `tt(-)tt(-)' is recommended.
+All builtin commands other than `tt(echo)' and precommand modifiers,
+even those that have no options, can be given the argument `tt(-)tt(-)'
+to terminate option processing. This indicates that the following words
+are non-option arguments, but is otherwise ignored. This is useful in
+cases where arguments to the command may begin with `tt(-)'. For
+historical reasons, most builtin commands (including `tt(echo)') also
+recognize a single `tt(-)' in a separate word for this purpose; note
+that this is less standard and use of `tt(-)tt(-)' is recommended.
startitem()
prefix(-)
@@ -114,9 +114,9 @@ var(text) is any non-empty string, it is replaced by the text
a literal string, not a pattern. A trailing space in var(value) is not
special in this case. For example,
-example(alias -s ps=gv)
+example(alias -s ps='gv --')
-will cause the command `tt(*.ps)' to be expanded to `tt(gv *.ps)'. As
+will cause the command `tt(*.ps)' to be expanded to `tt(gv -- *.ps)'. As
alias expansion is carried out earlier than globbing, the `tt(*.ps)' will
then be expanded. Suffix aliases constitute a different name space from
other aliases (so in the above example it is still possible
@@ -1258,7 +1258,10 @@ If given together with tt(-o) or tt(-O), sorting is performed
case-independently.
)
item(tt(-l))(
-Print the arguments separated by newlines instead of spaces.
+Print the arguments separated by newlines instead of spaces. Note: if
+the list of arguments is empty, tt(print -l) will still output one empty
+line. To print a possibly-empty list of arguments one per line, use
+tt(print -C1), as in `tt(print -rC1 -- "$list[@]")'.
)
item(tt(-m))(
Take the first argument as a pattern (should be quoted), and remove
@@ -1269,7 +1272,9 @@ item(tt(-n))(
Do not add a newline to the output.
)
item(tt(-N))(
-Print the arguments separated and terminated by nulls.
+Print the arguments separated and terminated by nulls. Again,
+tt(print -rNC1 -- "$list[@]") is a canonical way to print an
+arbitrary list as null-delimited records.
)
item(tt(-o))(
Print the arguments sorted in ascending order.
diff --git a/Doc/Zsh/contrib.yo b/Doc/Zsh/contrib.yo
index 558342711..871c3e6f5 100644
--- a/Doc/Zsh/contrib.yo
+++ b/Doc/Zsh/contrib.yo
@@ -4418,24 +4421,28 @@ the elements from the tt(input) list in each run. If no var(command) is
provided, then no var(arg) list may be provided, and in that event the
default command is `tt(print)' with arguments `tt(-r -)tt(-)'.
-For example, to get a long tt(ls) listing of all plain files in the
-current directory or its subdirectories:
+For example, to get a long tt(ls) listing of all non-hidden plain files
+in the current directory or its subdirectories:
example(autoload -U zargs
-zargs -- **/*(.) -- ls -l)
+zargs -- **/*(.) -- ls -ld --)
+
+The first and third occurrences of `tt(-)tt(-)' are used to mark the end
+of options for tt(zargs) and tt(ls) respectively to guard against
+filenames starting with `tt(-)', while the second is used to separate the
+list of files from the command to run (`tt(ls -ld --)').
+
+The first `tt(-)tt(-)' would also be needed if there was a chance the
+list might be empty as in:
-Note that `tt(-)tt(-)' is used both to mark the end of the var(option)
-list and to mark the end of the var(input) list, so it must appear twice
-whenever the var(input) list may be empty. If there is guaranteed to be
-at least one var(input) and the first var(input) does not begin with a
-`tt(-)', then the first `tt(-)tt(-)' may be omitted.
+example(zargs -r -- ./*.back(#qN) -- rm -f)
In the event that the string `tt(-)tt(-)' is or may be an var(input), the
tt(-e) option may be used to change the end-of-inputs marker. Note that
this does em(not) change the end-of-options marker. For example, to use
`tt(..)' as the marker:
-example(zargs -e.. -- **/*(.) .. ls -l)
+example(zargs -e.. -- **/*(.) .. ls -ld --)
This is a good choice in that example because no plain file can be named
`tt(..)', but the best end-marker depends on the circumstances.
diff --git a/Doc/Zsh/expn.yo b/Doc/Zsh/expn.yo
index d7147dbd7..6f4700dc4 100644
--- a/Doc/Zsh/expn.yo
+++ b/Doc/Zsh/expn.yo
@@ -400,7 +400,7 @@ backslashes.
For example, the following piece of filename generation code
with the tt(EXTENDED_GLOB) option:
-example(print *.c+LPAR()#q:s/#%+LPAR()#b+RPAR()s+LPAR()*+RPAR().c/'S${match[1]}.C'/+RPAR())
+example(print -r -- *.c+LPAR()#q:s/#%+LPAR()#b+RPAR()s+LPAR()*+RPAR().c/'S${match[1]}.C'/+RPAR())
takes the expansion of tt(*.c) and applies the glob qualifiers in the
tt(LPAR()#q)var(...)tt(RPAR()) expression, which consists of a substitution
@@ -2492,11 +2492,11 @@ therefore matches files in the current directory as well as
subdirectories.
Thus:
-example(ls (*/)#bar)
+example(ls -ld -- (*/)#bar)
or
-example(ls **/bar)
+example(ls -ld -- **/bar)
does a recursive directory search for files named `tt(bar)' (potentially
including the file `tt(bar)' in the current directory). This form does not
@@ -2511,11 +2511,11 @@ they are treated as if both a tt(/) plus a further tt(*) are present.
Hence:
example(setopt GLOBSTARSHORT
-ls **.c)
+ls -ld -- **.c)
is equivalent to
-example(ls **/*.c)
+example(ls -ld -- **/*.c)
subsect(Glob Qualifiers)
cindex(globbing, qualifiers)
cindex(qualifiers, globbing)
@@ -2707,7 +2707,7 @@ appropriate test. For example,
example(nt+LPAR()RPAR() { [[ $REPLY -nt $NTREF ]] }
NTREF=reffile
-ls -l *(+nt))
+ls -ld -- *(+nt))
lists all files in the directory that have been modified more recently than
tt(reffile).
@@ -2898,36 +2898,36 @@ is performed, although note that the presence of the parentheses
causes the entire expression to be subjected to any global pattern matching
options such as tt(NULL_GLOB). Thus:
-example(ls *(-/))
+example(ls -ld -- *(-/))
lists all directories and symbolic links that point to directories,
and
-example(ls *(-@))
+example(ls -ld -- *(-@))
lists all broken symbolic links, and
-example(ls *(%W))
+example(ls -ld -- *(%W))
lists all world-writable device files in the current directory, and
-example(ls *(W,X))
+example(ls -ld -- *(W,X))
lists all files in the current directory that are
world-writable or world-executable, and
-example(echo /tmp/foo*(u0^@:t))
+example(print -rC1 /tmp/foo*(u0^@:t))
outputs the basename of all root-owned files beginning with the string
`tt(foo)' in tt(/tmp), ignoring symlinks, and
-example(ls *.*~(lex|parse).[ch](^D^l1))
+example(ls -ld -- *.*~(lex|parse).[ch](^D^l1))
lists all files having a link count of one whose names contain a dot
(but not those starting with a dot, since tt(GLOB_DOTS) is explicitly
switched off) except for tt(lex.c), tt(lex.h), tt(parse.c) and tt(parse.h).
-example(print b*.pro+LPAR()#q:s/pro/shmo/+RPAR()(#q.:s/builtin/shmiltin/))
+example(print -rC1 b*.pro+LPAR()#q:s/pro/shmo/+RPAR()(#q.:s/builtin/shmiltin/))
demonstrates how colon modifiers and other qualifiers may be chained
together. The ordinary qualifier `tt(.)' is applied first, then the colon
Messages sorted by:
Reverse Date,
Date,
Thread,
Author