From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 27808 invoked from network); 25 Mar 2009 13:14:12 -0000 X-Spam-Checker-Version: SpamAssassin 3.2.5 (2008-06-10) on f.primenet.com.au X-Spam-Level: X-Spam-Status: No, score=-2.4 required=5.0 tests=AWL,BAYES_00 autolearn=ham version=3.2.5 Received: from news.dotsrc.org (HELO a.mx.sunsite.dk) (130.225.247.88) by ns1.primenet.com.au with SMTP; 25 Mar 2009 13:14:12 -0000 Received-SPF: none (ns1.primenet.com.au: domain at sunsite.dk does not designate permitted sender hosts) Received: (qmail 25175 invoked from network); 25 Mar 2009 13:14:08 -0000 Received: from sunsite.dk (130.225.247.90) by a.mx.sunsite.dk with SMTP; 25 Mar 2009 13:14:08 -0000 Received: (qmail 8239 invoked by alias); 25 Mar 2009 13:14:01 -0000 Mailing-List: contact zsh-workers-help@sunsite.dk; run by ezmlm Precedence: bulk X-No-Archive: yes X-Seq: 26783 Received: (qmail 8216 invoked from network); 25 Mar 2009 13:13:59 -0000 Received: from bifrost.dotsrc.org (130.225.254.106) by sunsite.dk with SMTP; 25 Mar 2009 13:13:59 -0000 Received: from cluster-g.mailcontrol.com (cluster-g.mailcontrol.com [208.87.233.190]) by bifrost.dotsrc.org (Postfix) with ESMTPS id BD69280590EB for ; Wed, 25 Mar 2009 14:13:53 +0100 (CET) Received: from cameurexb01.EUROPE.ROOT.PRI ([193.128.72.68]) by rly21g.srv.mailcontrol.com (MailControl) with ESMTP id n2PDDlf8007837 for ; Wed, 25 Mar 2009 13:13:48 GMT Received: from news01.csr.com ([10.99.50.25]) by cameurexb01.EUROPE.ROOT.PRI with Microsoft SMTPSVC(6.0.3790.3959); Wed, 25 Mar 2009 13:13:45 +0000 Received: from news01.csr.com (localhost.localdomain [127.0.0.1]) by news01.csr.com (8.14.2/8.13.4) with ESMTP id n2PDDjK0011525 for ; Wed, 25 Mar 2009 13:13:45 GMT Received: from csr.com (pws@localhost) by news01.csr.com (8.14.2/8.14.2/Submit) with ESMTP id n2PDDiod011521 for ; Wed, 25 Mar 2009 13:13:45 GMT X-Authentication-Warning: news01.csr.com: pws owned process doing -bs To: zsh-workers@sunsite.dk (Zsh hackers list) Subject: PATCH: _user_expand completer X-Mailer: MH-E 8.0.3; nmh 1.3; GNU Emacs 22.1.1 Date: Wed, 25 Mar 2009 13:13:44 +0000 Message-ID: <11520.1237986824@csr.com> From: Peter Stephenson X-OriginalArrivalTime: 25 Mar 2009 13:13:45.0102 (UTC) FILETIME=[86B65AE0:01C9AD4B] X-Scanned-By: MailControl A_08_51_00 (www.mailcontrol.com) on 10.71.0.131 X-Virus-Scanned: ClamAV 0.92.1/9164/Wed Mar 25 05:02:31 2009 on bifrost X-Virus-Status: Clean _user_expand is a new completer which allows you to define expansions of your own. Effectively they're a sort of abbreviation, but you have the full power of the completion system in handling multiple expansions. Most of the code is directly ripped off from _expand. Simple example: typeset -gA my_ips my_ips=( darth 192.168.135.2 dean 10.104.10.123 dash-lab-pc15 10.99.11.102 ) zstyle ':completion:*' user-expand '$my_ips' Now "darth" expands to its IP address. Not a great example, I might just as well use a parameter for that (and the IP address is years out of date anyway since I never use it and it's now in the DNS but you don't know that). There are all sorts of possible enhancements, for example delimiting parts of a word to be expanded, but I'll see if it turns out to be useful first. The tt(bashcompinit) documentation looked a bit forlorn at the end of the list of completers. I've moved it up to where initialisaion functions are documented. Index: Completion/Base/Completer/.distfiles =================================================================== RCS file: /cvsroot/zsh/zsh/Completion/Base/Completer/.distfiles,v retrieving revision 1.1 diff -u -r1.1 .distfiles --- Completion/Base/Completer/.distfiles 2 Apr 2001 12:42:26 -0000 1.1 +++ Completion/Base/Completer/.distfiles 25 Mar 2009 13:06:19 -0000 @@ -1,6 +1,17 @@ DISTFILES_SRC=' .distfiles -_all_matches _correct _history _match _prefix -_approximate _expand _ignored _menu -_complete _expand_alias _list _oldlist +_all_matches +_approximate +_complete +_correct +_expand +_expand_alias +_history +_ignored +_list +_match +_menu +_oldlist +_prefix +_user_expand ' Index: Completion/Base/Completer/_user_expand =================================================================== RCS file: Completion/Base/Completer/_user_expand diff -N Completion/Base/Completer/_user_expand --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ Completion/Base/Completer/_user_expand 25 Mar 2009 13:06:20 -0000 @@ -0,0 +1,141 @@ +#autoload + +# This completer function is an addition to the _expand completer that +# allows the user to define their own expansions. It does not replace +# the _expand completer. +# +# This function will allow other completer functions to be called if +# the expansions done produce no result or do not change the original +# word from the line. + +setopt localoptions nonomatch + +[[ _matcher_num -gt 1 ]] && return 1 + +local exp word sort expr expl subd suf=" " asp tmp spec +local -a specs reply + +if [[ "$funcstack[2]" = _prefix ]]; then + word="$IPREFIX$PREFIX$SUFFIX" +else + word="$IPREFIX$PREFIX$SUFFIX$ISUFFIX" +fi + +# In exp we will collect the expansions. + +exp=("$word") + +# Now look for user completions. + +zstyle -a ":completion:${curcontext}" user-expand specs || return 1 + +for spec in $specs; do + case $spec in + ('$'[[:IDENT:]]##) + # Spec is an associative array with explicit keys. + # Surely there's a better way of doing an associative array + # lookup from its name? + eval tmp='${'$spec[2,-1]'[$word]}' + if [[ -n $tmp ]]; then + exp=("$tmp") + break + fi + ;; + + ('_'*) + reply=() + $spec $word + if (( ${#reply} )); then + exp=("${reply[@]}") + break + fi + ;; + esac +done + +[[ $#exp -eq 1 && "$exp[1]" = "$word" ]] && return 1 + +# Now add as matches whatever the user requested. + +zstyle -s ":completion:${curcontext}:" sort sort + +[[ "$sort" = (yes|true|1|on) ]] && exp=( "${(@o)exp}" ) + +if zstyle -s ":completion:${curcontext}:" add-space tmp; then + if [[ "$tmp" != *subst* || "$word" != *\$* || "$exp[1]" = *\$* ]]; then + [[ "$tmp" = *file* ]] && asp=file + [[ "$tmp" = *(yes|true|1|on|subst)* ]] && asp="yes$asp" + fi +else + asp=file +fi + +# If there is only one expansion, add a suitable suffix + +if (( $#exp == 1 )); then + if [[ -d ${exp[1]} && "$exp[1]" != */ ]]; then + suf=/ + elif [[ "$asp" = yes* || + ( "$asp" = *file && -f "${exp[1]}" ) ]]; then + suf=' ' + else + suf= + fi +fi + +if [[ -z "$compstate[insert]" ]] ;then + if [[ "$sort" = menu ]]; then + _description expansions expl expansions "o:$word" + else + _description -V expansions expl expansions "o:$word" + fi + + compadd "$expl[@]" -UQ -qS "$suf" -a exp +else + _tags all-expansions expansions original + + if [[ $#exp -gt 1 ]] && _requested expansions; then + local i j normal space dir + + if [[ "$sort" = menu ]]; then + _description expansions expl expansions "o:$word" + else + _description -V expansions expl expansions "o:$word" + fi + normal=() + space=() + dir=() + + for i in "$exp[@]"; do + j="${i}" + if [[ -d "$j" && "$i" != */ ]]; then + dir=( "$dir[@]" "$i" ) + elif [[ "$asp" = yes* || ( "$asp" = *file && -f "$j" ) ]]; then + space=( "$space[@]" "$i" ) + else + normal=( "$normal[@]" "$i" ) + fi + done + (( $#dir )) && compadd "$expl[@]" -UQ -qS/ -a dir + (( $#space )) && compadd "$expl[@]" -UQ -qS " " -a space + (( $#normal )) && compadd "$expl[@]" -UQ -qS "" -a normal + fi + if _requested all-expansions expl 'all expansions'; then + local disp dstr + + if [[ "${#${exp}}" -ge COLUMNS ]]; then + disp=( -ld dstr ) + dstr=( "${(r:COLUMNS-5:)exp} ..." ) + else + disp=() + fi + [[ -o multios ]] && exp=($exp[1] $compstate[redirect]${^exp[2,-1]}) + compadd "$disp[@]" "$expl[@]" -UQ -qS "$suf" - "$exp" + fi + + _requested original expl original && compadd "$expl[@]" -UQ - "$word" + + compstate[insert]=menu +fi + +return 0 Index: Doc/Zsh/compsys.yo =================================================================== RCS file: /cvsroot/zsh/zsh/Doc/Zsh/compsys.yo,v retrieving revision 1.219 diff -u -r1.219 compsys.yo --- Doc/Zsh/compsys.yo 6 Feb 2009 09:59:38 -0000 1.219 +++ Doc/Zsh/compsys.yo 25 Mar 2009 13:06:20 -0000 @@ -202,6 +202,13 @@ currently named in tt(fpath), set tt(_compdir) to an empty string before calling tt(compaudit) or tt(compinit). +findex(bashcompinit) +The function tt(bashcompinit) compatibility with bash's programmable +completion system. When run it will define the functions, tt(compgen) and +tt(complete) which correspond to the bash builtins with the same names. +It will then be possible to use completion specifications and functions +written for bash. + subsect(Autoloaded files) cindex(completion system, autoloaded functions) @@ -3096,13 +3103,35 @@ be moved to the end of the current word before the completion code is called and hence there will be no suffix. ) -findex(bashcompinit) -item(tt(bashcompinit))( -This function provides compatibility with bash's programmable completion -system. When run it will define the functions, tt(compgen) and -tt(complete) which correspond to the bash builtins with the same names. -It will then be possible to use completion specifications and functions -written for bash. +findex(_user_expand) +item(tt(_user_expand))( +This completer behaves similarly to the tt(_expand) completer but +instead performs expansions defined by users. The styles tt(add-space) and +tt(sort) styles specific to the tt(_expand) completer are usable with +tt(_user_expand) in addition to other styles handled more generally by +the completion system. The tag tt(all-expansions) is also available. + +The expansion depends on the array style tt(user-expand) being defined +for the current context; remember that the context for completers is less +specific than that for contextual completion as the full context has not +yet been determined. Elements of the array may have one of the following +forms: +startsitem() +sitem(tt($)var(hash))( +var(hash) is the name of an associative array. Note this is not a full +parameter expression, merely a tt($), suitably quoted to prevent immediate +expansion, followed by the name of an associative array. If the trial +expansion word matches a key in var(hash), the resulting expansion is the +corresponding value. +) +sitem(var(_func))( +var(_func) is the name of a shell function whose name must begin with +tt(_) but is not otherwise special to the completion system. The function +is called with the trial word as an argument. If the word is to be +expanded, the function should set the array tt(reply) to a list of +expansions. The return status of the function is irrelevant. +) +endsitem() ) enditem() -- Peter Stephenson Software Engineer CSR PLC, Churchill House, Cambridge Business Park, Cowley Road Cambridge, CB4 0WZ, UK Tel: +44 (0)1223 692070