[Bash-completion-devel] wget(1) completion
Raphaël Droz
raphael.droz+floss at gmail.com
Sun Dec 11 18:30:56 UTC 2011
On Wed, Dec 07, 2011 at 08:43:40PM +0200, Ville Skyttä wrote:
> On 12/04/2011 08:49 PM, Raphaël Droz wrote:
> > back with this one
> > [ http://lists.alioth.debian.org/pipermail/bash-completion-devel/2009-March/001088.html ]
>
> Some quick comments, not actually tested:
>
> > [[ $cur =~ (unix|windows), ]] && excludes=( windows unix )
> > [[ $cur =~ (low|upp)ercase, ]] && excludes+=( lowercase uppercase )
> > [ ... etc similar unnecessary =~ cases here and there ... ]
> Plain == with @(...) instead of regexp should work for these -- it's
> faster and cleaner when considering the case that the above should
> probably match the entire $cur exactly, not just a substring (the regexp
> version would need anchoring). Actually I suggest using a case block
> (with "non-fancy" labels, see below) for the above particular case
> instead of doing redundant regexp tests when we know only one of them
> can match.
fixed,
I ended up using such idioms: *lowercase*|*uppercase*) is it what you
expected ?
> > -D|-@(bind-address|@(exclude-|)domains))
>
> See "Globbing in case labels" in style guide for this and several other
> similar cases.
fixed
> I suppose these should do a "return" instead of a ":".
> > --@(local|remote)-encoding)
> > : # TODO
> > ;;
fixed
completes as for iconv -f
> > --execute)
> > : # TODO: base=STR
> > ;;
fixed
only returns 0 for now
> > --header)
>
> I'm not convinced that offering HTTP header names after this is useful
> as it's not only header names that are required, but "Header: value"
> strings.
According to the section 4.2 of the RFC 2616:
" The field value MAY be preceded by any amount of LWS, though a single
SP is preferred. "
=> wget --header=From:test ... is valid.
So I added a -o nospace as I still think that providing supported HTTP
headers may sometimes help a bit.
> > [ Big case $prev block ]
>
> "$split && return" missing after the block.
fixed
> > [ The last case $cur block ]
>
> Looks like this could be combined to just one "if [[ $cur == -* ]]". At
> least for me, _parse_help returns only long options.
fixed
[ new version + patch attached ]
thanks for the review !
Raph
-------------- next part --------------
# wget(1) completion -*- shell-script -*-
_wget() {
local cur prev words cword split
_init_completion -s || return
case $prev in
--progress)
COMPREPLY=( $( compgen -W 'bar dot' -- $cur ) )
return 0
;;
--bind-address)
_ip_addresses "$cur"
return 0
;;
-D|--domains|--exclude-domains)
_known_hosts_real "$cur"
return 0
;;
--restrict-file-names)
local excludes=()
case $cur in
*unix*|*windows*)
excludes=( windows unix )
;;&
*lowercase*|*uppercase*)
excludes+=( lowercase uppercase )
;;&
*nocontrol*)
excludes+=( nocontrol )
;;&
*ascii*)
excludes+=( ascii )
;;
esac
local excludes_str=$( export IFS='|'; echo "${excludes[*]}"; )
# prevopt is the previous options string used as a prefix
# to avoid COMPREPLY replacing them with the $lastopt completion
local lastopt=${cur/*,} prevopt=
[[ $cur = *, ]] && prevopt=${cur%,*},
COMPREPLY=( $( compgen -P "$prevopt" -X "@($excludes_str)" \
-W 'unix windows nocontrol ascii lowercase uppercase' \
-- $lastopt ) )
# +o nospace when no more valid option is possible (= append a space)
local opt_as_arr=( $(echo ${COMPREPLY[0]//,/ }) )
[[ ${#opt_as_arr[@]} -lt 4 ]] && compopt -o nospace
return 0
;;
--prefer-family)
COMPREPLY=( $( compgen -W 'IPv4 IPv6 none' -- $cur ) )
return 0
;;
-P|--directory-prefix|--ca-directory)
_filedir -d
return 0
;;
-a|--append-output|--load-cookies|--post-file|--ca-certificate|\
--certificate|--private-key|--random-file|--egd-file)
_filedir
return 0
;;
-o|--output-file|-O|--output-document|--save-cookies|--default-page)
# avoid accidentally overwriting files: suggest directories only
_filedir -d
# and, in some cases, the standard output too
[[ $prev = @(-O|--output-document) && ( $cur = -* || -z $cur ) ]] && COMPREPLY+=( - )
return 0
;;
-i|--input-file)
# adds the standard input to the possibilities
_filedir && [[ $cur = -* || -z $cur ]] && COMPREPLY+=( - )
return 0
;;
--secure-protocol)
COMPREPLY=( $( compgen -W 'auto SSLv2 SSLv3 TLSv1' -- $cur ) )
return 0
;;
--certificate-type|--private-key-type)
COMPREPLY=( $( compgen -W 'PEM DER' -- $cur ) )
return 0
;;
--follow-tags|--ignore-tags)
local lastopt=${cur/*,} prevopt=
[[ $cur = *, ]] && prevopt=${cur%,*},
COMPREPLY=( $( compgen -P "${prevopt}"
-W 'a abbr acronym address applet area b base basefont bdo big blockquote
body br button caption center cite code col colgroup dd del dir div dfn dl dt em fieldset
font form frame frameset h6 head hr html i iframe img input ins isindex kbd label legend
li link map menu meta noframes noscript object ol optgroup option p param pre q s samp
script select small span strike strong style sub sup table tbody td textarea tfoot th
thead title tr tt u ul var xmp' -- $lastopt ) )
return 0
;;
--tries|--dns-timeout|--connect-timeout|--timeout|--limit-rate|\
--wait|--waitretry|--cut-dirs|--max-redirect)
COMPREPLY=( $( compgen -W "{0..9}" -- $cur ) )
return 0
;;
--quota)
COMPREPLY=( $( compgen -W "{0..9}{k,m}" -- $cur ) )
return 0
;;
--http-user|--proxy-user|--ftp-user|--user)
COMPREPLY=( $( compgen -W "$(sed -n '/^login/s/^[[:blank:]]*login[[:blank:]]//p' ~/.netrc)" -- $cur ) )
return 0
;;
--level)
COMPREPLY=( $( compgen -W "{1..5}" -- $cur ) )
return 0
;;
--header)
COMPREPLY=( $( compgen -W 'Accept Accept-Charset Accept-Encoding Accept-Language
Accept-Ranges Age Allow Authorization Cache-Control Connection Content-Encoding
Content-Language Content-Length Content-Location Content-MD5 Content-Range
Content-Type Date ETag Expect Expires From Host If-Match If-Modified-Since
If-None-Match If-Range If-Unmodified-Since Last-Modified Location Max-Forwards
Pragma Proxy-Authenticate Proxy-Authorization Range Referer Retry-After
Server TE Trailer Transfer-Encoding Upgrade User-Agent Vary Via Warning
WWW-Authenticate' -- $cur ) )
compopt -o nospace
return 0
;;
--local-encoding|--remote-encoding)
type -P xauth &>/dev/null && \
COMPREPLY=( $( compgen -W '$( iconv -l | \
sed -e "s@/*\$@@" -e "s/[,()]//g" )' -- "$cur" ) )
return 0
;;
--execute)
return 0 # TODO base=STR
;;
esac
$split && return
if [[ $cur = -* ]]; then
COMPREPLY=( $( compgen -W '$( _parse_help "$1" )' -- "$cur" ) )
[[ $COMPREPLY == *= ]] && compopt -o nospace
fi
return 0
} &&
complete -F _wget wget
# Local variables:
# mode: shell-script
# sh-basic-offset: 4
# sh-indent-comment: t
# indent-tabs-mode: nil
# End:
# ex: ts=4 sw=4 et filetype=sh
-------------- next part --------------
diff --git a/completions/wget b/completions/wget
index 09b4b23..c497a71 100644
--- a/completions/wget
+++ b/completions/wget
@@ -9,24 +9,38 @@ _wget() {
COMPREPLY=( $( compgen -W 'bar dot' -- $cur ) )
return 0
;;
- -D|-@(bind-address|@(exclude-|)domains))
- _known_hosts_real
+ --bind-address)
+ _ip_addresses "$cur"
+ return 0
+ ;;
+ -D|--domains|--exclude-domains)
+ _known_hosts_real "$cur"
return 0
;;
--restrict-file-names)
local excludes=()
- [[ $cur =~ (unix|windows), ]] && excludes=( windows unix )
- [[ $cur =~ (low|upp)ercase, ]] && excludes+=( lowercase uppercase )
- [[ $cur =~ nocontrol ]] && excludes+=( nocontrol )
- [[ $cur =~ ascii ]] && excludes+=( ascii )
+ case $cur in
+ *unix*|*windows*)
+ excludes=( windows unix )
+ ;;&
+ *lowercase*|*uppercase*)
+ excludes+=( lowercase uppercase )
+ ;;&
+ *nocontrol*)
+ excludes+=( nocontrol )
+ ;;&
+ *ascii*)
+ excludes+=( ascii )
+ ;;
+ esac
+ local excludes_str=$( export IFS='|'; echo "${excludes[*]}"; )
# prevopt is the previous options string used as a prefix
# to avoid COMPREPLY replacing them with the $lastopt completion
local lastopt=${cur/*,} prevopt=
- [[ ${cur} =~ , ]] && prevopt=${cur%,*},
- local excludes_str=$( export IFS='|'; echo "${excludes[*]}"; )
+ [[ $cur = *, ]] && prevopt=${cur%,*},
- COMPREPLY=( $( compgen -P "${prevopt}" -X "@($excludes_str)" \
+ COMPREPLY=( $( compgen -P "$prevopt" -X "@($excludes_str)" \
-W 'unix windows nocontrol ascii lowercase uppercase' \
-- $lastopt ) )
@@ -43,18 +57,20 @@ _wget() {
_filedir -d
return 0
;;
- -a|--append-output|--load-cookies|--post-file|--@(ca-|)certificate|--private-key|--random-file|--egd-file)
+ -a|--append-output|--load-cookies|--post-file|--ca-certificate|\
+ --certificate|--private-key|--random-file|--egd-file)
_filedir
return 0
;;
-o|--output-file|-O|--output-document|--save-cookies|--default-page)
- # these options specify a file which may or may not be overwriten
- # _filedir
- [[ $prev =~ -O|--output-document && ( $cur = -* || -z $cur ) ]] && COMPREPLY+=( - )
- return 0;
+ # avoid accidentally overwriting files: suggest directories only
+ _filedir -d
+ # and, in some cases, the standard output too
+ [[ $prev = @(-O|--output-document) && ( $cur = -* || -z $cur ) ]] && COMPREPLY+=( - )
+ return 0
;;
-i|--input-file)
- # adds the standard input/output to the possibilities
+ # adds the standard input to the possibilities
_filedir && [[ $cur = -* || -z $cur ]] && COMPREPLY+=( - )
return 0
;;
@@ -62,13 +78,13 @@ _wget() {
COMPREPLY=( $( compgen -W 'auto SSLv2 SSLv3 TLSv1' -- $cur ) )
return 0
;;
- --@(certificate|private-key)-type)
+ --certificate-type|--private-key-type)
COMPREPLY=( $( compgen -W 'PEM DER' -- $cur ) )
return 0
;;
- --@(follow|ignore)-tags)
+ --follow-tags|--ignore-tags)
local lastopt=${cur/*,} prevopt=
- [[ ${cur} =~ , ]] && prevopt=${cur%,*},
+ [[ $cur = *, ]] && prevopt=${cur%,*},
COMPREPLY=( $( compgen -P "${prevopt}"
-W 'a abbr acronym address applet area b base basefont bdo big blockquote
@@ -79,7 +95,8 @@ _wget() {
thead title tr tt u ul var xmp' -- $lastopt ) )
return 0
;;
- --tries|--@(dns-|connect-|)timeout|--limit-rate|--wait|--waitretry|--cut-dirs|--max-redirect)
+ --tries|--dns-timeout|--connect-timeout|--timeout|--limit-rate|\
+ --wait|--waitretry|--cut-dirs|--max-redirect)
COMPREPLY=( $( compgen -W "{0..9}" -- $cur ) )
return 0
;;
@@ -87,7 +104,7 @@ _wget() {
COMPREPLY=( $( compgen -W "{0..9}{k,m}" -- $cur ) )
return 0
;;
- --@(http-|proxy-|ftp-|)user)
+ --http-user|--proxy-user|--ftp-user|--user)
COMPREPLY=( $( compgen -W "$(sed -n '/^login/s/^[[:blank:]]*login[[:blank:]]//p' ~/.netrc)" -- $cur ) )
return 0
;;
@@ -104,27 +121,26 @@ _wget() {
Pragma Proxy-Authenticate Proxy-Authorization Range Referer Retry-After
Server TE Trailer Transfer-Encoding Upgrade User-Agent Vary Via Warning
WWW-Authenticate' -- $cur ) )
+ compopt -o nospace
return 0
;;
- --@(local|remote)-encoding)
- : # TODO
- ;;
+ --local-encoding|--remote-encoding)
+ type -P xauth &>/dev/null && \
+ COMPREPLY=( $( compgen -W '$( iconv -l | \
+ sed -e "s@/*\$@@" -e "s/[,()]//g" )' -- "$cur" ) )
+ return 0
+ ;;
--execute)
- : # TODO: base=STR
- ;;
+ return 0 # TODO base=STR
+ ;;
esac
- case $cur in
- --*)
- COMPREPLY=( $( compgen -W '$( _parse_help "$1" )' -- "$cur" ) )
- [[ $COMPREPLY == *= ]] && compopt -o nospace
- ;;
- # only complete long options
- -)
- compopt -o nospace
- COMPREPLY=( -- )
- ;;
- esac
+ $split && return
+
+ if [[ $cur = -* ]]; then
+ COMPREPLY=( $( compgen -W '$( _parse_help "$1" )' -- "$cur" ) )
+ [[ $COMPREPLY == *= ]] && compopt -o nospace
+ fi
return 0
} &&
diff --git a/doc/styleguide.txt b/doc/styleguide.txt
index 3391970..85e6d6b 100644
--- a/doc/styleguide.txt
+++ b/doc/styleguide.txt
@@ -106,3 +106,14 @@ COMPREPLY.
COMPREPLY=( ... -- $cur ) or COMPREPLY=( ... -- "$cur" ) ?
----------------------------------------------------------
+
+$split && return
+----------------
+Should be used in completions using the -s flag of _init_completion,
+after $prev has been managed but before $cur is considered.
+Rationale: -s flag calls _split_longopt() which attempt to split $cur.
+$split = 0 means:
+- $cur was actually split (during _init_completion())
+- _split_longopt() actually split $cur into $prev=--* and $cur=<something>
+- the value of $cur within the completion is rather non-significant outside
+the context of $prev.
More information about the Bash-completion-devel
mailing list