Zsh Mailing List Archive
Messages sorted by: Reverse Date, Date, Thread, Author

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@xxxxxxxxxxxxxxxxxxxxxxx



Messages sorted by: Reverse Date, Date, Thread, Author