From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 11152 invoked from network); 17 Jul 2000 14:39:05 -0000 Received: from sunsite.auc.dk (130.225.51.30) by ns1.primenet.com.au with SMTP; 17 Jul 2000 14:39:05 -0000 Received: (qmail 2451 invoked by alias); 17 Jul 2000 14:38:55 -0000 Mailing-List: contact zsh-workers-help@sunsite.auc.dk; run by ezmlm Precedence: bulk X-No-Archive: yes X-Seq: 12276 Received: (qmail 2416 invoked from network); 17 Jul 2000 14:38:49 -0000 Date: Mon, 17 Jul 2000 15:38:44 +0100 From: Adam Spiers To: zsh workers mailing list Subject: PATCH: completion caching layer Message-ID: <20000717153844.A6095@thelonious.new.ox.ac.uk> Reply-To: Adam Spiers Mail-Followup-To: zsh workers mailing list Mime-Version: 1.0 Content-Type: text/plain; charset=us-ascii X-Mailer: Mutt 1.0.1i X-Home-Page: http://www.new.ox.ac.uk/~adam/ X-OS: RedHat Linux 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