From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 22255 invoked from network); 10 Oct 2006 21:23:41 -0000 X-Spam-Checker-Version: SpamAssassin 3.1.6 (2006-10-03) on f.primenet.com.au X-Spam-Level: X-Spam-Status: No, score=-2.5 required=5.0 tests=BAYES_00,FORGED_RCVD_HELO autolearn=ham version=3.1.6 Received: from news.dotsrc.org (HELO a.mx.sunsite.dk) (130.225.247.88) by ns1.primenet.com.au with SMTP; 10 Oct 2006 21:23:41 -0000 Received-SPF: none (ns1.primenet.com.au: domain at sunsite.dk does not designate permitted sender hosts) Received: (qmail 96966 invoked from network); 10 Oct 2006 21:23:35 -0000 Received: from sunsite.dk (130.225.247.90) by a.mx.sunsite.dk with SMTP; 10 Oct 2006 21:23:35 -0000 Received: (qmail 24617 invoked by alias); 10 Oct 2006 21:23:33 -0000 Mailing-List: contact zsh-workers-help@sunsite.dk; run by ezmlm Precedence: bulk X-No-Archive: yes X-Seq: 22859 Received: (qmail 24605 invoked from network); 10 Oct 2006 21:23:32 -0000 Received: from news.dotsrc.org (HELO a.mx.sunsite.dk) (130.225.247.88) by sunsite.dk with SMTP; 10 Oct 2006 21:23:32 -0000 Received: (qmail 96715 invoked from network); 10 Oct 2006 21:23:32 -0000 Received: from mtaout01-winn.ispmail.ntl.com (81.103.221.47) by a.mx.sunsite.dk with SMTP; 10 Oct 2006 21:23:31 -0000 Received: from aamtaout02-winn.ispmail.ntl.com ([81.103.221.35]) by mtaout01-winn.ispmail.ntl.com with ESMTP id <20061010212329.LBMW15018.mtaout01-winn.ispmail.ntl.com@aamtaout02-winn.ispmail.ntl.com> for ; Tue, 10 Oct 2006 22:23:29 +0100 Received: from pwslaptop.csr.com ([82.6.97.160]) by aamtaout02-winn.ispmail.ntl.com with SMTP id <20061010212329.FTKP23938.aamtaout02-winn.ispmail.ntl.com@pwslaptop.csr.com> for ; Tue, 10 Oct 2006 22:23:29 +0100 Date: Tue, 10 Oct 2006 22:23:25 +0100 From: Peter Stephenson To: Zsh Hackers' List Subject: Re: Please add pinfo completion Message-Id: <20061010222325.92d317e0.p.w.stephenson@ntlworld.com> In-Reply-To: <20061010185959.c84c0b49.pws@csr.com> References: <20061007013551.GE8188@prunille.vinc17.org> <237967ef0610081413v291de92ck71f45c8990bf67ae@mail.gmail.com> <20061010142200.GC17674@prunille.vinc17.org> <20061010185959.c84c0b49.pws@csr.com> X-Mailer: Sylpheed version 2.2.9 (GTK+ 2.8.20; i386-redhat-linux-gnu) Mime-Version: 1.0 Content-Type: text/plain; charset=US-ASCII Content-Transfer-Encoding: 7bit On Tue, 10 Oct 2006 18:59:59 +0100 Peter Stephenson 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 Web page now at http://homepage.ntlworld.com/p.w.stephenson/