From: Peter Stephenson <p.w.stephenson@ntlworld.com>
To: Zsh Hackers' List <zsh-workers@sunsite.dk>
Subject: Re: Please add pinfo completion
Date: Tue, 10 Oct 2006 22:23:25 +0100 [thread overview]
Message-ID: <20061010222325.92d317e0.p.w.stephenson@ntlworld.com> (raw)
In-Reply-To: <20061010185959.c84c0b49.pws@csr.com>
On Tue, 10 Oct 2006 18:59:59 +0100
Peter Stephenson <pws@csr.com> wrote:
> OK, here is _arguments updated to provide option descriptions from --help
> text automatically.
I tried this on zsh's own configure script.
There was a bug: square brackets in the descriptions caused
comparguments to barf.
I've also added various improvements based on the handling of configure:
- now --option[descriptions] are handled in all cases, even if a separate
option argument description is provided
- configure --help prints descriptions on the next line if the don't
fit; I've taken account of this
- I've also consistently used array+=() syntax in _arguments, which I
have absolutely no intention of porting back to before 4.0.
Every option for ./configure now has a comment in verbose mode (which
you can, of course, turn off if you don't like it), as do all long
options for GNU tar.
However, if you don't WANT to be impressed you don't NEED to be.
Index: Completion/Base/Utility/_arguments
===================================================================
RCS file: /cvsroot/zsh/zsh/Completion/Base/Utility/_arguments,v
retrieving revision 1.18
diff -u -r1.18 _arguments
--- Completion/Base/Utility/_arguments 10 Oct 2006 18:06:28 -0000 1.18
+++ Completion/Base/Utility/_arguments 10 Oct 2006 21:18:24 -0000
@@ -3,7 +3,7 @@
# Complete the arguments of the current command according to the
# descriptions given as arguments to this function.
-local long cmd="$words[1]" descr mesg subopts opt usecc autod
+local long cmd="$words[1]" descr odescr mesg subopts opt opt2 usecc autod
local oldcontext="$curcontext" hasopts rawret optarg singopt alwopt
local setnormarg
local -a match mbegin mend
@@ -51,9 +51,9 @@
tmp=( "${(@P)tmp}" )
fi
if [[ "$1" = -i* ]]; then
- iopts=( "$iopts[@]" "$tmp[@]" )
+ iopts+=( "$tmp[@]" )
else
- sopts=( "$sopts[@]" "$tmp[@]" )
+ sopts+=( "$tmp[@]" )
fi
shift cur
done
@@ -69,8 +69,28 @@
# those hyphens and anything from the space or tab after the
# option up to the end.
- _call_program options ${~words[1]} --help 2>&1 | while read opt; do
- tmp=()
+ tmp=()
+ _call_program options ${~words[1]} --help 2>&1 | while IFS= read -r opt; do
+ if (( ${#tmp} )); then
+ # Previous line had no comment. Is the current one suitable?
+ # It's hard to be sure, but if it there was nothing on the
+ # previous line and the current one is indented more than
+ # a couple of spaces (and isn't completely whitespace or punctuation)
+ # there's a pretty good chance.
+ if [[ $opt = [[:space:]][[:space:]][[:space:]]*[[:alpha:]]* ]]; then
+ # Assume so.
+ opt=${opt##[[:space:]]##}
+ # Same substitution as below.
+ lopts+=("${^tmp[@]}":${${${opt//:/-}//\[/(}//\]/)})
+ tmp=()
+ # Finished with this line.
+ continue
+ else
+ # Still no comment, add the previous options anyway.
+ lopts+=("${tmp[@]}")
+ tmp=()
+ fi
+ fi
while [[ $opt = [,[:space:]]#(#b)(-[^,[:space:]]#)(*) ]]; do
# We used to remove the brackets from "[=STUFF]",
# but later the code appears to handle it with the brackets
@@ -89,10 +109,19 @@
# and we need to remove fooarg. Use whitespace for hints.
opt=${opt## [^[:space:]]## }
opt=${opt##[[:space:]]##}
- # Add description after a ":", converting any : in the description
- # to a -. Use RCQUOTES to append this to all versions of the option.
- lopts+=("${^tmp[@]}"${opt:+:${opt//:/-}})
+ if [[ -n $opt ]]; then
+ # Add description after a ":", converting any : in the description
+ # to a -. Use RCQUOTES to append this to all versions of the option.
+ lopts+=("${^tmp[@]}":${${${opt//:/-}//\[/(}//\]/)})
+ tmp=()
+ # If there's no comment, we'll see if there's one on the
+ # next line.
+ fi
done
+ # Tidy up any remaining uncommented options.
+ if (( ${#tmp} )); then
+ lopts+=("${tmp[@]}")
+ fi
# Remove options also described by user-defined specs.
@@ -104,7 +133,7 @@
# Using (( ... )) gives a parse error.
let "$tmpargv[(I)(|\([^\)]#\))(|\*)${opt}(|[-+]|=(|-))(|\[*\])(|:*)]" ||
- tmp=( "$tmp[@]" "$lopts[(r)$opt(|[\[:=]*)]" )
+ tmp+=( "$lopts[(r)$opt(|[\[:=]*)]" )
done
lopts=( "$tmp[@]" )
@@ -122,7 +151,7 @@
# on the existence of --enable-*.
# TODO: there's no anchoring here, is that correct?
# If it's not, careful with the [\[:=]* stuff.
- lopts=( $lopts ${lopts/$~sopts[1]/$sopts[2]} )
+ lopts+=( ${lopts/$~sopts[1]/$sopts[2]} )
shift 2 sopts
done
@@ -130,8 +159,12 @@
# The last one matches all options; the `special' description and action
# makes those options be completed without an argument description.
- set -- "$@" '*=FILE*:file:_files' \
- '*=(DIR|PATH)*:directory:_files -/' '*=*:=: ' '*: : '
+ argv+=(
+ '*=FILE*:file:_files'
+ '*=(DIR|PATH)*:directory:_files -/'
+ '*=*:=: '
+ '*: : '
+ )
while (( $# )); do
@@ -174,36 +207,25 @@
if (( $#tmpo )); then
tmp=("${(@)tmp:#*\[\=*}")
- if [[ "$descr" = :\=* ]]; then
- for opt in "$tmpo[@]"; do
- # Look for --option:description and turn it into
- # --option[description]. We didn't do that above
- # since it could get confused with the [=ARG] stuff.
- if [[ $opt = (#b)(*):([^:]#) ]]; then
- opt=$match[1]
- descr="[${match[2]}]"
- else
- descr=
- fi
- cache=(
- "$cache[@]"
- "${${opt%%\=*}//[^a-zA-Z0-9-]}=${descr}::${(L)${opt%\]}#*\=}: "
- )
- done
- else
- # We don't handle the [description] form here.
- # TODO: we could with a bit of rewriting.
- #
- # The "[" didn't get removed here until I added it.
- # This may be why we used to try to remove the square brackets
- # higher up.
- tmpo=("${(@)${(@)tmpo%%\[\=*}//[^a-zA-Z0-9-]}")
- if [[ "$descr" = ::* ]]; then
- cache=( "$cache[@]" "${(@)^tmpo}=${dir}${descr}" )
- else
- cache=( "$cache[@]" "${(@)^tmpo}=${dir}:${descr}" )
- fi
- fi
+ for opt in "$tmpo[@]"; do
+ # Look for --option:description and turn it into
+ # --option[description]. We didn't do that above
+ # since it could get confused with the [=ARG] stuff.
+ if [[ $opt = (#b)(*):([^:]#) ]]; then
+ opt=$match[1]
+ odescr="[${match[2]}]"
+ else
+ odescr=
+ fi
+ opt2=${${opt%%\[\=*}//[^a-zA-Z0-9-]}=${dir}${odescr}
+ if [[ "$descr" = :\=* ]]; then
+ cache+=( "${opt2}::${(L)${opt%\]}#*\=}: " )
+ elif [[ "$descr" = ::* ]]; then
+ cache+=( "${opt2}${descr}" )
+ else
+ cache+=( "${opt2}:${descr}" )
+ fi
+ done
fi
# Descriptions with `=': mandatory argument.
@@ -214,24 +236,20 @@
if (( $#tmpo )); then
tmp=("${(@)tmp:#*\=*}")
- if [[ "$descr" = :\=* ]]; then
- for opt in "$tmpo[@]"; do
- if [[ $opt = (#b)(*):([^:]#) ]]; then
- opt=$match[1]
- descr="[${match[2]}]"
- else
- descr=
- fi
- cache=(
- "$cache[@]"
- "${${opt%%\=*}//[^a-zA-Z0-9-]}=${descr}:${(L)${opt%\]}#*\=}: "
- )
- done
- else
- tmpo=("${(@)${(@)tmpo%%\=*}//[^a-z0-9-]}")
-
- cache=( "$cache[@]" "${(@)^tmpo}=${dir}${descr}" )
- fi
+ for opt in "$tmpo[@]"; do
+ if [[ $opt = (#b)(*):([^:]#) ]]; then
+ opt=$match[1]
+ odescr="[${match[2]}]"
+ else
+ odescr=
+ fi
+ opt2="${${opt%%\=*}//[^a-zA-Z0-9-]}=${dir}${odescr}"
+ if [[ "$descr" = :\=* ]]; then
+ cache+=( "${opt2}:${(L)${opt%\]}#*\=}: " )
+ else
+ cache+=( "${opt2}${descr}" )
+ fi
+ done
fi
# Everything else is just added as an option without arguments or
@@ -248,9 +266,9 @@
# commands with no description
"${(@)${(@)tmp:#*:*}//[^a-zA-Z0-9-]}")
if [[ -n "$descr" && "$descr" != ': : ' ]]; then
- cache=( "$cache[@]" "${(@)^tmp}${descr}" )
+ cache+=( "${(@)^tmp}${descr}" )
else
- cache=( "$cache[@]" "$tmp[@]" )
+ cache+=( "$tmp[@]" )
fi
fi
done
@@ -344,11 +362,11 @@
action="${${action[3,-1]##[ ]#}%%[ ]#}"
if (( ! $state[(I)$action] )); then
comparguments -W line opt_args
- state=( "$state[@]" "$action" )
+ state+=( "$action" )
if [[ -n "$usecc" ]]; then
curcontext="${oldcontext%:*}:$subc"
else
- context=( "$context[@]" "$subc" )
+ context+=( "$subc" )
fi
compstate[restore]=''
aret=yes
@@ -475,7 +493,7 @@
fi
single=yes
else
- next=( "$next[@]" "$odirect[@]" )
+ next+=( "$odirect[@]" )
_describe -O option \
next -Q -M "$matcher" -- \
direct -QS '' -M "$matcher" -- \
--
Peter Stephenson <p.w.stephenson@ntlworld.com>
Web page now at http://homepage.ntlworld.com/p.w.stephenson/
next prev parent reply other threads:[~2006-10-10 21:23 UTC|newest]
Thread overview: 12+ messages / expand[flat|nested] mbox.gz Atom feed top
2006-10-07 1:35 Vincent Lefevre
2006-10-07 15:27 ` Nikolai Weibull
2006-10-08 21:13 ` Mikael Magnusson
2006-10-10 14:22 ` Vincent Lefevre
2006-10-10 15:29 ` Bart Schaefer
2006-10-11 1:03 ` Vincent Lefevre
2006-10-10 17:59 ` Peter Stephenson
2006-10-10 21:23 ` Peter Stephenson [this message]
2006-10-11 2:48 ` Andrey Borzenkov
[not found] ` <200610110933.k9B9XJTB021853@news01.csr.com>
2006-10-11 15:43 ` Andrey Borzenkov
2006-10-11 16:30 ` Peter Stephenson
2006-10-11 2:52 ` Andrey Borzenkov
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20061010222325.92d317e0.p.w.stephenson@ntlworld.com \
--to=p.w.stephenson@ntlworld.com \
--cc=zsh-workers@sunsite.dk \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
Code repositories for project(s) associated with this public inbox
https://git.vuxu.org/mirror/zsh/
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).