From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 24523 invoked from network); 28 Jan 2003 09:15:41 -0000 Received: from sunsite.dk (130.225.247.90) by ns1.primenet.com.au with SMTP; 28 Jan 2003 09:15:41 -0000 Received: (qmail 17249 invoked by alias); 28 Jan 2003 09:15:31 -0000 Mailing-List: contact zsh-workers-help@sunsite.dk; run by ezmlm Precedence: bulk X-No-Archive: yes X-Seq: 18149 Received: (qmail 17241 invoked from network); 28 Jan 2003 09:15:31 -0000 Received: from localhost (HELO sunsite.dk) (127.0.0.1) by localhost with SMTP; 28 Jan 2003 09:15:31 -0000 X-MessageWall-Score: 0 (sunsite.dk) Received: from [212.125.75.12] by sunsite.dk (MessageWall 1.0.8) with SMTP; 28 Jan 2003 9:15:30 -0000 X-VirusChecked: Checked X-Env-Sender: kiddleo@logica.com X-Msg-Ref: server-9.tower-4.messagelabs.com!1043745324!3933 Received: (qmail 20238 invoked from network); 28 Jan 2003 09:15:24 -0000 Received: from iris.logica.co.uk (158.234.9.163) by server-9.tower-4.messagelabs.com with SMTP; 28 Jan 2003 09:15:24 -0000 Received: from finches.logica.co.uk ([158.234.142.11]) by iris.logica.co.uk (8.9.3/8.9.3/Debian 8.9.3-21) with ESMTP id JAA30336 for ; Tue, 28 Jan 2003 09:15:22 GMT X-Authentication-Warning: iris.logica.co.uk: Host [158.234.142.11] claimed to be finches.logica.co.uk Received: from finches.logica.co.uk (localhost [127.0.0.1]) by finches.logica.co.uk (8.11.6/8.11.6/SuSE Linux 0.5) with ESMTP id h0S9I9E15301 for ; Tue, 28 Jan 2003 10:18:10 +0100 From: Oliver Kiddle To: Zsh workers Subject: bash completion functions Date: Tue, 28 Jan 2003 10:18:09 +0100 Message-ID: <15299.1043745489@finches.logica.co.uk> Sender: kiddleo@logica.com Attached is the bash completion emulation as promised. I've called the function which enables the system bashcompinit so if you have an idea for a better name, please say now. Which directory should it go in? I was thinking just the Completion directory. It contains three functions. compgen and complete correspond to the bash builtins. _bash_complete is a wrapper function which gets run from the zsh completion system. It requires 4.1, mainly because I stuff the arguments all into the _comps array elements so for the 4.0 back port (which I will do), I'll have to use a separate (_bash_comps) array. The only things I've knowingly left unimplemented is completion for jobs (because compgen is always run in a subshell) and complete -r (because I couldn't be bothered). Actually compdef perhaps ought to have -L and -r (remove) options. I've also commented out support for the last compgen argument which is something I'm a little unsure about. Also, $COMP_POINT might be iffy but it never seems to be used anyway. Finally bash's compgen -C option does something weird so either it is buggy or I don't understand but I've gone mostly by the documentation there. If you want to attempt to source the bash_completion project, the following may help a little. # their have function doesn't work in zsh (unset -v) have() { unset have (( ${+commands[$1]} )) && have=yes } # shopt is bash's setopt alias shopt=':' # resolve function name clash (if you don't use autoload -U) alias _expand=_bash_expand # these are the options I seem to need to best emulate bash. Some may be # missing and noshglob is questionable (but solved a specific issue) emulate -L sh setopt kshglob noshglob braceexpand Oliver #autoload _bash_complete() { local ret=1 local -a suf matches local COMP_POINT COMP_CWORD local -a COMP_WORDS COMPREPLY BASH_VERSINFO local COMP_LINE="$words" (( COMP_POINT = ${#${(j. .)words}} + $$#QIPREFIX + $#IPREFIX + $#PREFIX )) (( COMP_CWORD = CURRENT - 1)) COMP_WORDS=( $words ) BASH_VERSINFO=( 2 05b 0 1 release ) [[ ${argv[${argv[(I)nospace]:-0}-1]} = -o ]] && suf=( -S '' ) matches=( ${(f)"$(compgen $@)"} ) if [[ -n $matches ]]; then if [[ ${argv[${argv[(I)filenames]:-0}-1]} = -o ]]; then compset -P '*/' && matches=( ${matches##*/} ) compset -S '/*' && matches=( ${matches%%/*} ) compadd -f "${suf[@]}" -a matches && ret=0 else compadd "${suf[@]}" -a matches && ret=0 fi fi if (( ret )); then if [[ ${argv[${argv[(I)default]:-0}-1]} = -o ]]; then _default "${suf[@]}" && ret=0 elif [[ ${argv[${argv[(I)dirnames]:-0}-1]} = -o ]]; then _directories "${suf[@]}" && ret=0 fi fi return ret } compgen() { local opts prefix suffix ret=1 OPTARG OPTIND local -a name res results local -A shortopts emulate -L sh setopt kshglob noshglob braceexpand nokshautoload shortopts=( a alias b builtin c command d directory e export f file g group j job k keyword u user v variable ) while getopts "o:A:G:C:F:P:S:W:X:abcdefgjkuv" name; do case $name in [abcdefgjkuv]) OPTARG="${shortopts[$name]}" ;& A) case $OPTARG in alias) results+=( "${(k)aliases[@]}" ) ;; arrayvar) results+=( "${(k@)parameters[(R)array*]}" ) ;; binding) results+=( "${(k)widgets[@]}" ) ;; builtin) results+=( "${(k)builtins[@]}" "${(k)dis_builtins[@]}" ) ;; command) results+=( "${(k)commands[@]}" "${(k)aliases[@]}" "${(k)builtins[@]}" "${(k)functions[@]}" "${(k)reswords[@]}" ) ;; directory) setopt bareglobqual results+=( ${IPREFIX}${PREFIX}*${SUFFIX}${ISUFFIX}(N-/) ) setopt nobareglobqual ;; disabled) results+=( "${(k)dis_builtins[@]}" ) ;; enabled) results+=( "${(k)builtins[@]}" ) ;; export) results+=( "${(k)parameters[(R)*export*]}" ) ;; file) setopt bareglobqual results+=( ${IPREFIX}${PREFIX}*${SUFFIX}${ISUFFIX}(N) ) setopt nobareglobqual ;; function) results+=( "${(k)functions[@]}" ) ;; group) emulate zsh _groups -U -O res emulate sh setopt kshglob noshglob braceexpand results+=( "${res[@]}" ) ;; hostname) emulate zsh _hosts -U -O res emulate sh setopt kshglob noshglob braceexpand results+=( "${res[@]}" ) ;; keyword) results+=( "${(k)reswords[@]}" ) ;; setopt|shopt) results+=( "${(k)options[@]}" ) ;; signal) results+=( "SIG${^signals[@]}" ) ;; user) results+=( "${(k)userdirs[@]}" ) ;; variable) results+=( "${(k)parameters[@]}" ) ;; helptopic|job|running|stopped) ;; esac ;; F) COMPREPLY=() $OPTARG "${words[0]}" "${words[CURRENT-1]}" "${words[CURRENT-2]}" results+=( "${COMPREPLY[@]}" ) ;; G) setopt nullglob results+=( ${~OPTARG} ) unsetopt nullglob ;; W) eval "results+=( $OPTARG )" ;; C) results+=( $(eval $OPTARG) ) ;; P) prefix="$OPTARG" ;; S) suffix="$OPTARG" ;; X) if [[ ${OPTARG[0]} = '!' ]]; then results=( "${(M)results[@]:#${OPTARG#?}}" ) else results=( "${results[@]:#$OPTARG}" ) fi ;; esac done # support for the last, `word' option to compgen. Not particularly valuable # and without it zsh matching can do a better job. Comment in if needed. #shift $(( OPTIND - 1 )) #(( $# )) && results=( "${(M)results[@]:#$1*}" ) print -l -- "$prefix${^results[@]}$suffix" } complete() { emulate -L zsh local args void cmd print remove args=( "$@" ) zparseopts -D -a void o: A: G: W: C: F: P: S: X: a b c d e f g j k u v \ p=print r=remove if [[ -n $print ]]; then for cmd print in ${(kv)_comps[(R)_bash*]}; do print "complete ${print#* } $cmd" done elif [[ -n $remove ]]; then print "not implemented: -r option" else compdef _bash_complete\ ${(j. .)${(q)args[1,-1-$#]}} "$@" fi } unfunction bashcompinit autoload -U bashcompinit return 0 This e-mail and any attachment is for authorised use by the intended recipient(s) only. It may contain proprietary material, confidential information and/or be subject to legal privilege. It should not be copied, disclosed to, retained or used by, any other party. If you are not an intended recipient then please promptly delete this e-mail and any attachment and all copies and inform the sender. Thank you.