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

PATCH: completion caching layer



OK, I've written the first draft of the completion caching layer I
mentioned I was thinking about ages ago.

It uses two styles: use-cache (yes/no/1/0) and cache-path (the
directory for the cache, defaults to ~/.zsh/cache).  I also included
patches for _rpm and _perl_modules to show example uses.  I think
you'll agree the interface is very simple.  Everything else should (!)
be crystal clear; if not, please ask.

The patch follows.  I won't commit until someone else has gone through
it and thinks it looks OK.  I'll also write some documentation at some
point ...

Adam

P.S. I know we decided against caching for _rpm, as any use of the rpm
command is likely to change the rpm database anyway.  However, it
really is important that we provide the user the choice on this issue
(as the patch does via styles); for instance running rpm -qa on my
laptop is excrutiatingly slow, and there's little point providing
correct completions when you could type the whole rpm name manually
faster.


Index: Completion/Base/.distfiles
===================================================================
RCS file: /cvsroot/zsh/zsh/Completion/Base/.distfiles,v
retrieving revision 1.4
diff -u -r1.4 .distfiles
--- Completion/Base/.distfiles	2000/05/30 09:30:08	1.4
+++ Completion/Base/.distfiles	2000/07/17 14:31:30
@@ -2,6 +2,6 @@
     .distfiles 
     _arg_compile _arguments _brace_parameter _combination
     _command_names _condition _default _describe _equal _first _in_vared
-    _jobs _math _parameter _precommand _redirect _regex_arguments _subscript
-    _tilde _value _values
+    _jobs _math _parameter _precommand _redirect _regex_arguments _retrieve_cache
+    _store_cache _subscript _tilde _value _values
 '
Index: Completion/Base/_retrieve_cache
===================================================================
RCS file: _retrieve_cache
diff -N _retrieve_cache
--- /dev/null	Tue May  5 13:32:27 1998
+++ _retrieve_cache	Mon Jul 17 07:31:30 2000
@@ -0,0 +1,29 @@
+#autoload
+#
+# Retrieval component of completions caching layer
+
+local _cache_filename
+_cache_filename="$1"
+
+if zstyle -t ":completion:${curcontext}:" use-cache; then
+  # Decide which directory to retrieve cache from, and ensure it exists
+  zstyle -s ":completion:${curcontext}:" cache-path _cache_dir
+  : ${_cache_dir:=~/.zsh/cache}
+  if [[ ! -d "$_cache_dir" ]]; then
+    if [[ -e "$_cache_dir" ]]; then
+      _message "cache-dir ($_cache_dir) isn't a directory\!"
+      return 1
+    else
+      return 1
+    fi
+  fi
+
+  if [[ -e "$_cache_dir/$_cache_filename" ]]; then
+    . "$_cache_dir/$_cache_filename"
+    return 0
+  else
+    return 1
+  fi
+else
+  return 1
+fi
Index: Completion/Base/_store_cache
===================================================================
RCS file: _store_cache
diff -N _store_cache
--- /dev/null	Tue May  5 13:32:27 1998
+++ _store_cache	Mon Jul 17 07:31:30 2000
@@ -0,0 +1,35 @@
+#autoload
+#
+# Storage component of completions caching layer
+
+local _cache_filename
+_cache_filename="$1"
+
+if zstyle -t ":completion:${curcontext}:" use-cache; then
+  # Decide which directory to cache to, and ensure it exists
+  zstyle -s ":completion:${curcontext}:" cache-path _cache_dir
+  : ${_cache_dir:=~/.zsh/cache}
+  if [[ ! -d "$_cache_dir" ]]; then
+    if [[ -e "$_cache_dir" ]]; then
+      _message "cache-dir style points to a non-directory\!"
+    else
+      mkdir -p "$_cache_dir"
+      if [[ ! -d "$_cache_dir" ]]; then
+        _message "Couldn't create cache-dir $_cache_dir"
+        return 1
+      fi
+    fi
+  fi
+
+  # grr, doesn't work, so we have to roll our own
+#  typeset "$@[2,-1]" > "$_cache_dir/$_cache_filename"
+
+  # only deals with arrays so far
+  for var in "$@[2,-1]"; do
+    print -n "$var=("
+    print -nr - "${(o@P)${var}}"
+    print ")\n"
+  done > "$_cache_dir/$_cache_filename"
+else
+  return 1
+fi
Index: Completion/Linux/_rpm
===================================================================
RCS file: /cvsroot/zsh/zsh/Completion/Linux/_rpm,v
retrieving revision 1.15
diff -u -r1.15 _rpm
--- Completion/Linux/_rpm	2000/07/12 09:01:41	1.15
+++ Completion/Linux/_rpm	2000/07/17 14:31:30
@@ -203,8 +203,12 @@
     state=package_file
     ;&
   package)
+    if ! _retrieve_cache RPMs; then
+      _rpms=( $(_call packages rpm -qa 2>/dev/null) )
+      _store_cache RPMs _rpms
+    fi
     _wanted packages expl 'RPM package' \
-        compadd -M 'r:|-=* r:|=*' - $(_call packages rpm -qa 2> /dev/null) && ret=0
+        compadd -M 'r:|-=* r:|=*' - "$_rpms[@]" && ret=0
     ;;
   spec_file)
     _wanted specfiles expl 'spec file' \
cvs server: Diffing Completion/User
Index: Completion/User/_perl_modules
===================================================================
RCS file: /cvsroot/zsh/zsh/Completion/User/_perl_modules,v
retrieving revision 1.6
diff -u -r1.6 _perl_modules
--- Completion/User/_perl_modules	2000/05/31 09:38:26	1.6
+++ Completion/User/_perl_modules	2000/07/17 14:31:30
@@ -21,42 +21,46 @@
 zparseopts -D -a opts S: q
 
 if [[ ${+_perl_modules} -eq 0 ]]; then
-  if zstyle -t ":completion:${curcontext}:modules" try-to-use-pminst \
-     && (( ${+commands[pminst]} )); then
-    _perl_modules=( $(pminst) )
-  else
-    local inc libdir new_pms
-    if (( ${+commands[perl]} )); then
-      inc=( $( perl -e 'print "@INC"' ) )
+  if ! _retrieve_cache perl_modules; then
+    if zstyle -t ":completion:${curcontext}:modules" try-to-use-pminst \
+       && (( ${+commands[pminst]} )); then
+      _perl_modules=( $(pminst) )
     else
-      # If perl isn't there, one wonders why the user's trying to
-      # complete Perl modules.  Maybe her $path is wrong?
-      _message "Didn't find perl on \$PATH; guessing @INC ..."
-
-      setopt localoptions extendedglob
-      inc=( /usr/lib/perl5{,/{site_perl/,}<5->.([0-9]##)}(N) 
-            ${(s.:.)PERL5LIB} )
-    fi
-
-    typeset -agU _perl_modules  # _perl_modules is global, no duplicates
-    _perl_modules=( )
-
-    for libdir in $inc; do
-      # Ignore cwd - could be too expensive e.g. if we're near /
-      if [[ $libdir == '.' ]]; then break; fi
-
-      # Find all modules
-      if [[ -d $libdir && -x $libdir ]]; then
-      cd $libdir
-      new_pms=( {[A-Z]*/***/,}*.pm~*blib*(N) )
-      cd $OLDPWD
+      local inc libdir new_pms
+      if (( ${+commands[perl]} )); then
+        inc=( $( perl -e 'print "@INC"' ) )
+      else
+        # If perl isn't there, one wonders why the user's trying to
+        # complete Perl modules.  Maybe her $path is wrong?
+        _message "Didn't find perl on \$PATH; guessing @INC ..."
+  
+        setopt localoptions extendedglob
+        inc=( /usr/lib/perl5{,/{site_perl/,}<5->.([0-9]##)}(N) 
+              ${(s.:.)PERL5LIB} )
       fi
-
-      # Convert to Perl nomenclature
-      new_pms=( ${new_pms:r:fs#/#::#} )
+  
+      typeset -agU _perl_modules  # _perl_modules is global, no duplicates
+      _perl_modules=( )
+  
+      for libdir in $inc; do
+        # Ignore cwd - could be too expensive e.g. if we're near /
+        if [[ $libdir == '.' ]]; then break; fi
+  
+        # Find all modules
+        if [[ -d $libdir && -x $libdir ]]; then
+        cd $libdir
+        new_pms=( {[A-Z]*/***/,}*.pm~*blib*(N) )
+        cd $OLDPWD
+        fi
+  
+        # Convert to Perl nomenclature
+        new_pms=( ${new_pms:r:fs#/#::#} )
+  
+        _perl_modules=( $new_pms $_perl_modules )
+      done
+    fi
 
-      _perl_modules=( $new_pms $_perl_modules )
-    done
+    _store_cache perl_modules _perl_modules
   fi
 fi
 



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