From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 26426 invoked from network); 26 Aug 1999 09:28:41 -0000 Received: from sunsite.auc.dk (130.225.51.30) by ns1.primenet.com.au with SMTP; 26 Aug 1999 09:28:41 -0000 Received: (qmail 27588 invoked by alias); 26 Aug 1999 09:28:28 -0000 Mailing-List: contact zsh-workers-help@sunsite.auc.dk; run by ezmlm Precedence: bulk X-No-Archive: yes X-Seq: 7492 Received: (qmail 27579 invoked from network); 26 Aug 1999 09:28:27 -0000 Date: Thu, 26 Aug 1999 11:28:05 +0200 (MET DST) Message-Id: <199908260928.LAA14797@beta.informatik.hu-berlin.de> From: Sven Wischnowsky To: zsh-workers@sunsite.auc.dk Subject: PATCH: completion functions This tries to make `_arguments' a bit faster by caching the results of parsing its arguments. The it makes `_find' use `_arguments' and then there is a fixlet for `_x_font' (forgot to make the cache global). One comment about the caching: I'd like to use `_arguments' in much more functions (even rewriting some of the `{Builtins,User}/*' functions we have). But then a single cache is pretty useless. But if we were able to put arrays and associations into associations, we could have command-specific caches. Internally, this probably wouldn't be too hard to implement, I think, but if I remember correctly, Bart was against it and explicitly disallowed this. Maybe if we just tell the users that associative arrays can act as name-spaces? (In other words: Bart, what was the reason that you was against it? Or weren't you against it and my memory is failing?) Bye Sven diff -u -r oc/Base/_arguments Completion/Base/_arguments --- oc/Base/_arguments Wed Aug 25 14:59:03 1999 +++ Completion/Base/_arguments Thu Aug 26 11:20:00 1999 @@ -14,119 +14,144 @@ typeset -A opts dopts odopts typeset -A oneshot -# See if we are using single-letter options. +# Fill the cache if we were called with different arguments. -if [[ "$1" = -s ]]; then - shift - single=yes -fi +if [[ "$*" != "$_args_cache_descr" ]]; then + _args_cache_descr="$*" -# See if we support long options, too. + unset _args_cache_{opts,dopts,odopts,oneshot} + typeset -gA _args_cache_{opts,dopts,odopts,oneshot} -nth=$argv[(I)--] -if (( nth )); then - long=( "${(@)argv[nth+1,-1]}" ) - argv=("${(@)argv[1,nth-1]}") -else - long=() -fi + unset _args_cache_{long,single,rest,args,sopts,soptseq,soptseq1} -# Now parse the arguments... + # See if we are using single-letter options. + + if [[ "$1" = -s ]]; then + shift + _args_cache_single=yes + fi -args=() -nth=1 -while (( $# )); do - - # This describes a one-shot option. - - if [[ "$1" = [-+]* ]]; then - if [[ "$1" = *:* ]]; then - - # If the option name ends in a `-', the first argument comes - # directly after the option, if it ends in a `+', the first - # argument *may* come directly after the option, otherwise it - # is in the next word. - - if [[ "$1" = [^:]##-:* ]]; then - tmp="${${1%%:*}[1,-2]}" - dopts[$tmp]="${1#*:}" - elif [[ "$1" = [^:]##+:* ]]; then - tmp="${${1%%:*}[1,-2]}" - odopts[$tmp]="${1#*:}" + # See if we support long options, too. + + nth=$argv[(I)--] + if (( nth )); then + _args_cache_long=( "${(@)argv[nth+1,-1]}" ) + _args_cache_long_nth=$(( nth - 1 )) + else + _args_cache_long=() + fi + + # Now parse the arguments... + + args=() + nth=1 + while (( $# )); do + + # This describes a one-shot option. + + if [[ "$1" = [-+]* ]]; then + if [[ "$1" = *:* ]]; then + + # If the option name ends in a `-', the first argument comes + # directly after the option, if it ends in a `+', the first + # argument *may* come directly after the option, otherwise it + # is in the next word. + + if [[ "$1" = [^:]##-:* ]]; then + tmp="${${1%%:*}[1,-2]}" + _args_cache_dopts[$tmp]="${1#*:}" + elif [[ "$1" = [^:]##+:* ]]; then + tmp="${${1%%:*}[1,-2]}" + _args_cache_odopts[$tmp]="${1#*:}" + else + tmp="${1%%:*}" + _args_cache_opts[$tmp]="${1#*:}" + fi else - tmp="${1%%:*}" - opts[$tmp]="${1#*:}" + tmp="$1" + _args_cache_opts[$tmp]='' fi - else - tmp="$1" - opts[$tmp]='' - fi - oneshot[$tmp]=yes - elif [[ "$1" = \*[-+]* ]]; then + _args_cache_oneshot[$tmp]=yes + elif [[ "$1" = \*[-+]* ]]; then - # The same for options that may appear more than once. + # The same for options that may appear more than once. - if [[ "$1" = *:* ]]; then - if [[ "$1" = [^:]##-:* ]]; then - tmp="${${1[2,-1]%%:*}[1,-2]}" - dopts[$tmp]="${1#*:}" - elif [[ "$1" = [^:]##+:* ]]; then - tmp="${${1[2,-1]%%:*}[1,-2]}" - odopts[$tmp]="${1#*:}" + if [[ "$1" = *:* ]]; then + if [[ "$1" = [^:]##-:* ]]; then + tmp="${${1[2,-1]%%:*}[1,-2]}" + _args_cache_dopts[$tmp]="${1#*:}" + elif [[ "$1" = [^:]##+:* ]]; then + tmp="${${1[2,-1]%%:*}[1,-2]}" + _args_cache_odopts[$tmp]="${1#*:}" + else + tmp="${1[2,-1]%%:*}" + _args_cache_opts[$tmp]="${1#*:}" + fi else - tmp="${1[2,-1]%%:*}" - opts[$tmp]="${1#*:}" + tmp="${1[2,-1]}" + _args_cache_opts[$tmp]='' fi - else - tmp="${1[2,-1]}" - opts[$tmp]='' - fi - unset "oneshot[$tmp]" - elif [[ "$1" = \*::* ]]; then + unset "_args_cache_oneshot[$tmp]" + elif [[ "$1" = \*::* ]]; then - # This is `*:...', describing `all other arguments', with argument - # range restriction. + # This is `*:...', describing `all other arguments', with argument + # range restriction. - if [[ "$1" = \*:::* ]]; then - rest="*${1[3,-1]}" - else - rest="$1" - fi - elif [[ "$1" = \*:* ]]; then + if [[ "$1" = \*:::* ]]; then + _args_cache_rest="*${1[3,-1]}" + else + _args_cache_rest="$1" + fi + elif [[ "$1" = \*:* ]]; then - # This is `*:...', describing `all other arguments'. + # This is `*:...', describing `all other arguments'. - rest="${1[3,-1]}" - elif [[ "$1" = :* ]]; then + _args_cache_rest="${1[3,-1]}" + elif [[ "$1" = :* ]]; then - # This is `:...', describing `the next argument'. + # This is `:...', describing `the next argument'. - args[nth++]="${1#*:}" - else + _args_cache_args[nth++]="${1#*:}" + else - # And this is `n:...', describing the `n'th argument. + # And this is `n:...', describing the `n'th argument. - args[${1%%:*}]="${1#*:}" - nth=$(( ${1%%:*} + 1 )) - fi - shift -done + _args_cache_args[${1%%:*}]="${1#*:}" + nth=$(( ${1%%:*} + 1 )) + fi + shift + done -if [[ -n "$single" ]]; then - soptseq="${(@j::)${(@M)${(@k)opts[(R)]}:#[-+]?}#[-+]}" - if [[ -n "$soptseq" ]]; then - soptseq="[$soptseq]#" - soptseq1="$soptseq#" + if [[ -n "$_args_cache_single" ]]; then + _args_cache_soptseq="${(@j::)${(@M)${(@k)opts[(R)]}:#[-+]?}#[-+]}" + if [[ -n "$_args_cache_soptseq" ]]; then + _args_cache_soptseq="[$_args_cache_soptseq]#" + _args_cache_soptseq1="$_args_cache_soptseq#" + else + _args_cache_soptseq='' + _args_cache_soptseq1='' + fi + _args_cache_sopts="${(@j::)${(@M)${(@k)opts}:#[-+]?}#[-+]}${(@j::)${(@M)${(@k)dopts}:#[-+]?}#[-+]}${(@j::)${(@M)${(@k)odopts}:#[-+]?}#[-+]}" else - soptseq='' - soptseq1='' + _args_cache_soptseq='' + _args_cache_soptseq1='' + _args_cache_sopts='' fi - sopts="${(@j::)${(@M)${(@k)opts}:#[-+]?}#[-+]}${(@j::)${(@M)${(@k)dopts}:#[-+]?}#[-+]}${(@j::)${(@M)${(@k)odopts}:#[-+]?}#[-+]}" -else - soptseq='' - soptseq1='' - sopts='' fi + +soptseq="$_args_cache_soptseq" +soptseq1="$_args_cache_soptseq1" +sopts="$_args_cache_sopts" +args=( "$_args_cache_args[@]" ) +rest="$_args_cache_rest" +opts=( "${(@kv)_args_cache_opts}" ) +dopts=( "${(@kv)_args_cache_dopts}" ) +odopts=( "${(@kv)_args_cache_odopts}" ) +oneshot=( "${(@kv)_args_cache_oneshot}" ) +single="$_args_cache_single" +long=( "$_args_cache_long[@]" ) + +argv=( "${(@)argv[1,_args_cache_long_nth]}" ) # Parse the command line... diff -u -r oc/User/_find Completion/User/_find --- oc/User/_find Wed Aug 25 14:59:13 1999 +++ Completion/User/_find Thu Aug 26 10:58:55 1999 @@ -1,31 +1,59 @@ #compdef find -local prev="$words[CURRENT-1]" expl - -if compset -N '-(ok|exec)' '\;'; then - _normal -elif [[ "$PREFIX" = -* ]]; then - _description expl option - compadd "$expl[@]" - -daystart -{max,min,}depth -follow -noleaf \ - -version -xdev -{a,c,}newer -{a,c,m}{min,time} -empty -false \ - -{fs,x,}type -gid -inum -links -{i,}{l,}name -{no,}{user,group} \ - -path -perm -regex -size -true -uid -used -exec -{f,}print{f,0,} \ - -ok -prune -ls -elif [[ CURRENT -eq 2 ]]; then - local ret=1 - - _description expl directory - compgen "$expl[@]" -g '. ..' && ret=0 - _files -/ && ret=0 - - return ret -elif [[ "$prev" = -((a|c|)newer|fprint(|0|f)) ]]; then - _files -elif [[ "$prev" = -fstype ]]; then - _description expl 'file system type' - compadd "$expl[@]" ufs 4.2 4.3 nfs tmp mfs S51K S52K -elif [[ "$prev" = -group ]]; then - _groups -elif [[ "$prev" = -user ]]; then - _users -fi +_arguments \ + '-daystart' \ + '-depth' \ + '-follow' \ + '-help' \ + '-maxdepth:maximum search depth:' \ + '-mindepth:minimum search depth:' \ + '-mount' \ + '-noleaf' \ + '-version' \ + '-xdev' \ + '-amin:access time (minutes):' \ + '-cmin:inode change time (minutes):' \ + '-mmin:modification time (minutes):' \ + '-atime:access time (days):' \ + '-ctime:inode change time (days):' \ + '-mtime:modification time (days):' \ + '-anewer:file to compare (access time):_files' \ + '-cnewer:file to compare (inode change time):_files' \ + '-newer:file to compare (modification time):_files' \ + '-used:access after inode change (days):' \ + '-empty' \ + '-false' \ + '-fstype:filesystem type:(ufs 4.2 4.3 nfs tmp mfs S51K S52K)' \ + '-gid:numeric group ID:' \ + '-group:group:_groups' \ + '-uid:numeric user ID:' \ + '-user:user:_users' \ + '-lname:link pattern to search:' \ + '-ilname:link pattern to search (case insensitive):' \ + '-name:name pattern to search:' \ + '-iname:name pattern to search (case insensitive):' \ + '-path:path pattern to search:' \ + '-ipath:path pattern to search (case insensitive):' \ + '-regex:regular expression to search:' \ + '-iregex:regular expression to search (case insensitive):' \ + '-inum:inode number:' \ + '-links:number of links:' \ + '-nouser' \ + '-nogroup' \ + '-perm:file permission bits:' \ + '-size:file size:' \ + '-true' \ + '-type:file type:(b c d p f l s)' \ + '-xtype:file type:(b c d p f l s)' \ + '-exec:program: _command_names -e:*\;::program arguments: _normal' \ + '-ok:program: _command_names -e:*\;::program arguments: _normal' \ + '-fls:output file:_files' \ + '-fprint:output file:_files' \ + '-fprint0:output file:_files' \ + '-fprintf:output file:_files:output format:' \ + '-print' \ + '-print0' \ + '-printf:output format:' \ + '-prune' \ + '-ls' \ + '*:directory:_files -/' diff -u -r oc/X/_x_font Completion/X/_x_font --- oc/X/_x_font Wed Aug 25 14:59:16 1999 +++ Completion/X/_x_font Thu Aug 26 10:23:50 1999 @@ -5,7 +5,7 @@ # This *has* to be improved some day... if (( ! $+_font_cache )); then - typeset -U _font_cache + typeset -gU _font_cache _font_cache=( "${(@)^${(@f)$(xlsfonts)}%%--*}--" ) fi -- Sven Wischnowsky wischnow@informatik.hu-berlin.de