summaryrefslogtreecommitdiff
path: root/Completion
diff options
context:
space:
mode:
Diffstat (limited to 'Completion')
-rw-r--r--Completion/Base/.distfiles6
-rw-r--r--Completion/Base/_cache_invalid21
-rw-r--r--Completion/Base/_retrieve_cache31
-rw-r--r--Completion/Base/_store_cache36
-rw-r--r--Completion/Builtins/_zstyle2
-rw-r--r--Completion/Linux/_rpm435
-rw-r--r--Completion/User/_perl_modules108
7 files changed, 395 insertions, 244 deletions
diff --git a/Completion/Base/.distfiles b/Completion/Base/.distfiles
index a906bfc76..0cbe1f97f 100644
--- a/Completion/Base/.distfiles
+++ b/Completion/Base/.distfiles
@@ -1,7 +1,7 @@
DISTFILES_SRC='
.distfiles
- _arg_compile _arguments _brace_parameter _combination
+ _arg_compile _arguments _brace_parameter _cache_invalid _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
'
diff --git a/Completion/Base/_cache_invalid b/Completion/Base/_cache_invalid
new file mode 100644
index 000000000..e55381439
--- /dev/null
+++ b/Completion/Base/_cache_invalid
@@ -0,0 +1,21 @@
+#autoload
+#
+# Function to decide whether a completions cache needs rebuilding
+
+local _cache_ident _cache_dir _cache_path _cache_policy
+_cache_ident="$1"
+
+# If the cache is disabled, we never want to rebuild it, so pretend
+# it's valid.
+zstyle -t ":completion:${curcontext}:" use-cache || return 1
+
+zstyle -s ":completion:${curcontext}:" cache-path _cache_dir
+: ${_cache_dir:=${ZDOTDIR:-$HOME}/.zcompcache}
+_cache_path="$_cache_dir/$_cache_ident"
+
+# See whether the caching policy says that the cache needs rebuilding
+# (the policy will return 0 if it does).
+zstyle -s ":completion:${curcontext}:" cache-policy _cache_policy
+[[ -n "$_cache_policy" ]] && "$_cache_policy" "$_cache_path" && return 0
+
+return 1
diff --git a/Completion/Base/_retrieve_cache b/Completion/Base/_retrieve_cache
new file mode 100644
index 000000000..6a82cd48b
--- /dev/null
+++ b/Completion/Base/_retrieve_cache
@@ -0,0 +1,31 @@
+#autoload
+#
+# Retrieval component of completions caching layer
+
+local _cache_ident _cache_dir _cache_path _cache_policy
+_cache_ident="$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:=${ZDOTDIR:-HOME}/.zcompcache}
+ if [[ ! -d "$_cache_dir" ]]; then
+ [[ -e "$_cache_dir" ]] &&
+ _message "cache-dir ($_cache_dir) isn't a directory\!"
+ return 1
+ fi
+
+ _cache_path="$_cache_dir/$_cache_ident"
+
+ if [[ -e "$_cache_path" ]]; then
+ _cache_invalid "$_cache_ident" && return 1
+
+ . "$_cache_path"
+ return 0
+ else
+ return 1
+ fi
+else
+ return 1
+fi
+
diff --git a/Completion/Base/_store_cache b/Completion/Base/_store_cache
new file mode 100644
index 000000000..2fe7dfcb6
--- /dev/null
+++ b/Completion/Base/_store_cache
@@ -0,0 +1,36 @@
+#autoload
+#
+# Storage component of completions caching layer
+
+local _cache_ident
+_cache_ident="$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:=${ZDOTDIR:-$HOME}/.zcompcache}
+ 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
+
+ shift
+ for var; do
+ case ${(Pt)var} in
+ (*readonly*) ;;
+ (*(association|array)*) print -r "$var=( ${(kv@Pqq)^^var} )";;
+ (*) print -r "$var=${(Pqq)^^var}";;
+ esac
+ done >! "$_cache_dir/$_cache_ident"
+else
+ return 1
+fi
+
+return 0
diff --git a/Completion/Builtins/_zstyle b/Completion/Builtins/_zstyle
index fefa8af51..abfec06d3 100644
--- a/Completion/Builtins/_zstyle
+++ b/Completion/Builtins/_zstyle
@@ -15,6 +15,7 @@ styles=(
assign-list c:
auto-description c:
break-keys c:
+ cache-path 'c:_wanted directories expl directory _path_files -/'
command c:command
completer c:completer
completions c:bool
@@ -80,6 +81,7 @@ styles=(
suffix c:bool
tag-order c:tag
try-to-use-pminst c:bool
+ use-cache c:bool
use-compctl c:urgh
users c:_users
users-hosts c:user-host
diff --git a/Completion/Linux/_rpm b/Completion/Linux/_rpm
index e047af6d6..11bb370b8 100644
--- a/Completion/Linux/_rpm
+++ b/Completion/Linux/_rpm
@@ -41,213 +41,238 @@
# Used by `_arguments', made local here.
-local curcontext="$curcontext" state lstate line nm="$compstate[nmatches]"
-typeset -A opt_args
-
-state=''
-
-local ret=1
-local -a tmp expl commonopts packageopts
-commonopts=(
- '*-v[verbose mode]'
- '--rcfile:resource file:_files'
- '--ftpproxy:FTP proxy server:_hosts'
- '--ftpport:FTP port number:'
- '--httpproxy:HTTP proxy server:_hosts'
- '--httpport:HTTP port number:'
-)
-packageopts=(
- '-a[query all packages]'
- '-p+[query uninstalled package file]:*:RPM package file:->package_file'
- '-f[specify file to query owner of]:file:_files'
- '--triggeredby:RPM package:->package'
- '--whatprovides:RPM capability:->capability'
- '--whatrequires:RPM capability:->capability'
-)
-pathopts=(
- '--root:RPM root directory:_files -/'
- '--dbpath:RPM database path:_files -/'
-)
-
-# Do simple completions or get the first state.
-
-_arguments -C -s \
- '--help[print help message]' \
- '--version[print version number]' \
- "${commonopts[@]}" \
- '-q+[query mode]:*:query:->query' \
- --{querytags,initdb,showrc} \
- '--pipe:pipe command:_command_names -e' \
- -{V,y}'[verify mode]:*:verify:->verify' \
- '--verify[verify mode]:*:verify:->verify' \
- '--setperms[set file permissions]:*:package:->setattrs' \
- '--setugids[set file owner/group]:*:package:->setattrs' \
- '(--install)-i+[install mode]:*:install:->install' \
- '(-i)--install:*:install:->install' \
- '(--upgrade)-U+[upgrade mode]:*:upgrade:->upgrade' \
- '(-U)--upgrade:*:upgrade:->upgrade' \
- '(--freshen)-F+[freshen mode]:*:upgrade:->upgrade' \
- '(-F)--freshen:*:upgrade:->upgrade' \
- '(--erase)-e+[uninstall mode]:*:uninstall:->uninstall' \
- '(-e)--erase:*:uninstall:->uninstall' \
- '-b+[build mode (spec file)]:build stage:((p\:execute\ \%prep\ stage l\:do\ a\ list\ check c\:execute\ build\ stage i\:execute\ install\ stage b\:build\ a\ binary\ package a\:build\ binary\ and\ source\ packages)):*:build:->build_b' \
- '(-b)-t+[build mode (tar file)]:build stage:((p\:execute\ \%prep\ stage l\:do\ a\ list\ check c\:execute\ build\ stage i\:execute\ install\ stage b\:build\ a\ binary\ package a\:build\ binary\ and\ source\ packages)):*:build:->build_t' \
- --{resign,addsign}':*:RPM package:->package_file' \
- '--rmsource:*:spec file:->spec_file' \
- --{rebuild,recompile}':*:Src RPM files:->package_src' \
- '(--checksig)-K+[signature check mode]:*:sigcheck:->sigcheck' \
- '(-K)--checksig:*:sigcheck:->sigcheck' \
- '--rebuilddb:*:rebuild:->rebuild' && ret=0
-
-# As long as we have a state name...
-
-while [[ -n "$state" ]]; do
-
- # First try to call a user-defined function.
-
- _funcall ret _rpm_$state && return ret
-
- # Copy the state and reset `state', to simplify the test above.
-
- lstate="$state"
+_rpm () {
+ local curcontext="$curcontext" state lstate line nm="$compstate[nmatches]"
+ typeset -A opt_args
+
state=''
- tmp=()
-
- # Dispatch...
-
- case "$lstate" in
- query)
- # --dump requires on of -{l,c,d}
- # --triggers requires --script
- _arguments -s \
- -q "${commonopts[@]}" "${packageopts[@]}" "${pathopts[@]}" \
- '--queryformat:RPM query format:->tags' \
- '-i[display package information]' \
- '--changelog[display change log]' \
- '-l[display package file list]' \
- '-s[show file states]' \
- '-d[documentation files only]' \
- '-c[configuration files only]' \
- '--dump[show all information]' \
- --provides \
- -{R,-requires}'[list dependencies]' \
- '--scripts[show (un)install scripts]' \
- '--triggers[show trigger scripts]' \
- '*:RPM package:->package_or_file' && ret=0
- ;;
- setattrs)
- _arguments -s --set{perm,ugids} "${packageopts[@]}" && ret = 0
- ;;
- verify)
- _arguments -s \
- '(-y --verify)-V' '(-V --verify)-y' '(-y -V)--verify' \
- "${commonopts[@]}" "${pathopts[@]}" \
- --no{deps,md5,files} \
- '*:RPM package:->package' && ret=0
- ;;
- upgrade)
- tmp=( '(--upgrade)-U' '(-U)--upgrade' '(--force)--oldpackage' )
- ;&
- install)
- (( $#tmp )) || tmp=( '(--install)-i' '(-i)--install' )
- _arguments -s "$tmp[@]" \
- "${commonopts[@]}" "${pathopts[@]}" \
- '--excludepath:exclude files in following path:_files -/' \
- '--relocate:relocate:->relocate' \
- '--prefix:package prefix directory:_files -/' \
- '(-h)--hash' '(--hash)-h' \
- '(--replacepkgs --replacefiles --oldpackage)--force' \
- '(--force)--'{replacefiles,replacepkgs} \
- --{badreloc,excludedocs,allfiles,ignorearch,ignoreos,includedocs,justdb,nodeps,noorder,noscripts,notriggers,percent,test} \
- '*:pkg file:->package_file' && ret=0
- ;;
- uninstall)
- _arguments -s \
- '(-e)--erase' '(--erase)-e' \
- "${commonopts[@]}" "${pathopts[@]}" \
- --{allmatches,justdb,nodeps,noorder,noscripts,notriggers} \
- '*:RPM package:->package' && ret=0
- ;;
- build_b)
- tmp=( '*:spec file:_files -g \*.spec' )
- ;&
- build_t)
- (( $#tmp )) || tmp=( '*:tar file:_files -g \*.\(\#i\)tar\(.\*\|\)' )
+
+ local ret=1
+ local -a tmp expl commonopts packageopts
+ commonopts=(
+ '*-v[verbose mode]'
+ '--rcfile:resource file:_files'
+ '--ftpproxy:FTP proxy server:_hosts'
+ '--ftpport:FTP port number:'
+ '--httpproxy:HTTP proxy server:_hosts'
+ '--httpport:HTTP port number:'
+ )
+ packageopts=(
+ '-a[query all packages]'
+ '-p+[query uninstalled package file]:*:RPM package file:->package_file'
+ '-f[specify file to query owner of]:file:_files'
+ '--triggeredby:RPM package:->package'
+ '--whatprovides:RPM capability:->capability'
+ '--whatrequires:RPM capability:->capability'
+ )
+ pathopts=(
+ '--root:RPM root directory:_files -/'
+ '--dbpath:RPM database path:_files -/'
+ )
+
+ # Do simple completions or get the first state.
+
+ _arguments -C -s \
+ '--help[print help message]' \
+ '--version[print version number]' \
+ "${commonopts[@]}" \
+ '-q+[query mode]:*:query:->query' \
+ --{querytags,initdb,showrc} \
+ '--pipe:pipe command:_command_names -e' \
+ -{V,y}'[verify mode]:*:verify:->verify' \
+ '--verify[verify mode]:*:verify:->verify' \
+ '--setperms[set file permissions]:*:package:->setattrs' \
+ '--setugids[set file owner/group]:*:package:->setattrs' \
+ '(--install)-i+[install mode]:*:install:->install' \
+ '(-i)--install:*:install:->install' \
+ '(--upgrade)-U+[upgrade mode]:*:upgrade:->upgrade' \
+ '(-U)--upgrade:*:upgrade:->upgrade' \
+ '(--freshen)-F+[freshen mode]:*:upgrade:->upgrade' \
+ '(-F)--freshen:*:upgrade:->upgrade' \
+ '(--erase)-e+[uninstall mode]:*:uninstall:->uninstall' \
+ '(-e)--erase:*:uninstall:->uninstall' \
+ '-b+[build mode (spec file)]:build stage:((p\:execute\ \%prep\ stage l\:do\ a\ list\ check c\:execute\ build\ stage i\:execute\ install\ stage b\:build\ a\ binary\ package a\:build\ binary\ and\ source\ packages)):*:build:->build_b' \
+ '(-b)-t+[build mode (tar file)]:build stage:((p\:execute\ \%prep\ stage l\:do\ a\ list\ check c\:execute\ build\ stage i\:execute\ install\ stage b\:build\ a\ binary\ package a\:build\ binary\ and\ source\ packages)):*:build:->build_t' \
+ --{resign,addsign}':*:RPM package:->package_file' \
+ '--rmsource:*:spec file:->spec_file' \
+ --{rebuild,recompile}':*:Src RPM files:->package_src' \
+ '(--checksig)-K+[signature check mode]:*:sigcheck:->sigcheck' \
+ '(-K)--checksig:*:sigcheck:->sigcheck' \
+ '--rebuilddb:*:rebuild:->rebuild' && ret=0
+
+ # As long as we have a state name...
+
+ while [[ -n "$state" ]]; do
+
+ # First try to call a user-defined function.
+
+ _funcall ret _rpm_$state && return ret
+
+ # Copy the state and reset `state', to simplify the test above.
+
+ lstate="$state"
+ state=''
+ tmp=()
+
+ # Dispatch...
+
+ case "$lstate" in
+ query)
+ # --dump requires on of -{l,c,d}
+ # --triggers requires --script
+ _arguments -s \
+ -q "${commonopts[@]}" "${packageopts[@]}" "${pathopts[@]}" \
+ '--queryformat:RPM query format:->tags' \
+ '-i[display package information]' \
+ '--changelog[display change log]' \
+ '-l[display package file list]' \
+ '-s[show file states]' \
+ '-d[documentation files only]' \
+ '-c[configuration files only]' \
+ '--dump[show all information]' \
+ --provides \
+ -{R,-requires}'[list dependencies]' \
+ '--scripts[show (un)install scripts]' \
+ '--triggers[show trigger scripts]' \
+ '*:RPM package:->package_or_file' && ret=0
+ ;;
+ setattrs)
+ _arguments -s --set{perm,ugids} "${packageopts[@]}" && ret = 0
+ ;;
+ verify)
+ _arguments -s \
+ '(-y --verify)-V' '(-V --verify)-y' '(-y -V)--verify' \
+ "${commonopts[@]}" "${pathopts[@]}" \
+ --no{deps,md5,files} \
+ '*:RPM package:->package' && ret=0
+ ;;
+ upgrade)
+ tmp=( '(--upgrade)-U' '(-U)--upgrade' '(--force)--oldpackage' )
+ ;&
+ install)
+ (( $#tmp )) || tmp=( '(--install)-i' '(-i)--install' )
+ _arguments -s "$tmp[@]" \
+ "${commonopts[@]}" "${pathopts[@]}" \
+ '--excludepath:exclude files in following path:_files -/' \
+ '--relocate:relocate:->relocate' \
+ '--prefix:package prefix directory:_files -/' \
+ '(-h)--hash' '(--hash)-h' \
+ '(--replacepkgs --replacefiles --oldpackage)--force' \
+ '(--force)--'{replacefiles,replacepkgs} \
+ --{badreloc,excludedocs,allfiles,ignorearch,ignoreos,includedocs,justdb,nodeps,noorder,noscripts,notriggers,percent,test} \
+ '*:pkg file:->package_file' && ret=0
+ ;;
+ uninstall)
+ _arguments -s \
+ '(-e)--erase' '(--erase)-e' \
+ "${commonopts[@]}" "${pathopts[@]}" \
+ --{allmatches,justdb,nodeps,noorder,noscripts,notriggers} \
+ '*:RPM package:->package' && ret=0
+ ;;
+ build_b)
+ tmp=( '*:spec file:_files -g \*.spec' )
+ ;&
+ build_t)
+ (( $#tmp )) || tmp=( '*:tar file:_files -g \*.\(\#i\)tar\(.\*\|\)' )
+
+ _arguments -s \
+ "${commonopts[@]}" "${pathopts[@]}" \
+ --{short-circuit,clean,rmsource,sign,test} \
+ '--target:specify a build target:->target'\
+ '--buildroot:build root directory:_files -/' \
+ '--buildarch:architecture for which to build:->target' \
+ '--buildos:ositecture for which to build:' \
+ '--timecheck:time check (seconds):' "$tmp[1]" && ret=0
+ ;;
+ sigcheck)
+ _arguments -s \
+ '(-K)--checksig' '(--checksig)-K' \
+ "${commonopts[@]}" \
+ --no{pgp,md5} \
+ '*:RPM package file:->package_file' && ret=0
+ ;;
+ rebuild)
+ _arguments -s \
+ "${commonopts[@]}" "${pathopts[@]}" \
+ '*:RPM source package file:->package_file' && ret=0
+ ;;
+ target)
+ _wanted target expl 'Target platforms' \
+ compadd $(_call target rpm --showrc 2> /dev/null |grep 'compatible archs'|sed 's/.*: //') && ret=0
+ ;;
+ package_or_file)
+ state=package_file
+ ;&
+ package)
+ if ( [[ ${+_rpms} -eq 0 ]] || _cache_invalid RPMs ) &&
+ ! _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:|=*' - "$_rpms[@]" && ret=0
+ ;;
+ spec_file)
+ _wanted specfiles expl 'spec file' \
+ _files -g \*.spec && ret=0
+ ;;
+ package_file)
+ _wanted files expl 'RPM package file' \
+ _files -g '*.(#i)rpm' && ret=0
+ if [[ -prefix 1 (f|ht)tp:// ]]; then
+ _wanted urls expl 'URL of RPM package file' \
+ _urls -f -g '*.(#i)rpm' "${expl[@]}" && ret=0
+ else
+ _wanted urls expl 'URL of RPM package file' \
+ compadd -S '' "${expl[@]}" ftp:// http:// && ret=0
+ fi
+ ;;
+ package_src)
+ _files -g \*.src\(\#i\).rpm
+ ;&
+ tags)
+ if compset -P '*%*\{'; then
+ _wanted tags expl 'RPM tag' \
+ compadd -M 'm:{a-z}={A-Z}' -S '\}' - \
+ "${(@)${(@f)$(_call tags rpm --querytags 2> /dev/null)}#RPMTAG_}" && ret=0
+ else
+ _message 'RPM format'
+ fi
+ ;;
+ capability)
+ _message 'RPM capability'
+ ;;
+ relocate)
+ if compset -P '*='; then
+ _description directories expl 'new path'
+ else
+ _description directories expl 'old path'
+ fi
+
+ _files "$expl[@]" -/ && ret=0
+ ;;
+ esac
+
+ [[ ret -eq 0 || $nm -ne $compstate[nmatches] ]] && return 0
+ done
+
+ return ret
+}
- _arguments -s \
- "${commonopts[@]}" "${pathopts[@]}" \
- --{short-circuit,clean,rmsource,sign,test} \
- '--target:specify a build target:->target'\
- '--buildroot:build root directory:_files -/' \
- '--buildarch:architecture for which to build:->target' \
- '--buildos:ositecture for which to build:' \
- '--timecheck:time check (seconds):' "$tmp[1]" && ret=0
- ;;
- sigcheck)
- _arguments -s \
- '(-K)--checksig' '(--checksig)-K' \
- "${commonopts[@]}" \
- --no{pgp,md5} \
- '*:RPM package file:->package_file' && ret=0
- ;;
- rebuild)
- _arguments -s \
- "${commonopts[@]}" "${pathopts[@]}" \
- '*:RPM source package file:->package_file' && ret=0
- ;;
- target)
- _wanted target expl 'Target platforms' \
- compadd $(_call target rpm --showrc 2> /dev/null |grep 'compatible archs'|sed 's/.*: //') && ret=0
- ;;
- package_or_file)
- state=package_file
- ;&
- package)
- _wanted packages expl 'RPM package' \
- compadd -M 'r:|-=* r:|=*' - $(_call packages rpm -qa 2> /dev/null) && ret=0
- ;;
- spec_file)
- _wanted specfiles expl 'spec file' \
- _files -g \*.spec && ret=0
- ;;
- package_file)
- _wanted files expl 'RPM package file' \
- _files -g '*.(#i)rpm' && ret=0
- if [[ -prefix 1 (f|ht)tp:// ]]; then
- _wanted urls expl 'URL of RPM package file' \
- _urls -f -g '*.(#i)rpm' "${expl[@]}" && ret=0
- else
- _wanted urls expl 'URL of RPM package file' \
- compadd -S '' "${expl[@]}" ftp:// http:// && ret=0
- fi
- ;;
- package_src)
- _files -g \*.src\(\#i\).rpm
- ;&
- tags)
- if compset -P '*%*\{'; then
- _wanted tags expl 'RPM tag' \
- compadd -M 'm:{a-z}={A-Z}' -S '\}' - \
- "${(@)${(@f)$(_call tags rpm --querytags 2> /dev/null)}#RPMTAG_}" && ret=0
- else
- _message 'RPM format'
- fi
- ;;
- capability)
- _message 'RPM capability'
- ;;
- relocate)
- if compset -P '*='; then
- _description directories expl 'new path'
- else
- _description directories expl 'old path'
- fi
+# set a sensible default caching policy
+local update_policy
+zstyle -s ":completion:*:*:rpm:*" cache-policy update_policy
+if [[ -z "$update_policy" ]]; then
+ zstyle ":completion:*:*:rpm:*" cache-policy _rpms_caching_policy
+fi
- _files "$expl[@]" -/ && ret=0
- ;;
- esac
+_rpms_caching_policy () {
+ # rebuild if cache is more than a week old
+ oldp=( "$1"(Nmw+1) )
+ (( $#oldp )) && return 0
- [[ ret -eq 0 || $nm -ne $compstate[nmatches] ]] && return 0
-done
+ [[ /var/lib/rpm/packages.rpm -nt "$1" ]]
+}
-return ret
+_rpm "$@"
diff --git a/Completion/User/_perl_modules b/Completion/User/_perl_modules
index 88efdd395..117933022 100644
--- a/Completion/User/_perl_modules
+++ b/Completion/User/_perl_modules
@@ -17,49 +17,85 @@
# algorithm (the zsh code does almost the same, but only misses
# modules which don't begin with an uppercase letter).
-local opts
-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"' ) )
+_perl_modules () {
+ local opts
+ zparseopts -D -a opts S: q
+
+ # Set a sensible default caching policy. This has to be done inside
+ # this function otherwise we wouldn't know the context for the style.
+ local update_policy
+ zstyle -s ":completion:${curcontext}:" cache-policy update_policy
+ if [[ -z "$update_policy" ]]; then
+ zstyle ":completion:${curcontext}:" cache-policy \
+ _perl_modules_caching_policy
+ fi
+
+ if ( [[ ${+_perl_modules} -eq 0 ]] || _cache_invalid perl_modules ) &&
+ ! _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} )
+ 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
+
+ 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
+
+ _store_cache perl_modules _perl_modules
+ fi
+
+ local expl
+
+ _wanted modules expl 'Perl modules' compadd "$opts[@]" -a _perl_modules
+}
- 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
+_perl_modules_caching_policy () {
+ local _perllocals
- # Find all modules
- if [[ -d $libdir && -x $libdir ]]; then
- cd $libdir
- new_pms=( {[A-Z]*/***/,}*.pm~*blib*(N) )
- cd $OLDPWD
- fi
+ # rebuild if cache is more than a week old
+ oldp=( "$1"(Nmw+1) )
+ (( $#oldp )) && return 0
- # Convert to Perl nomenclature
- new_pms=( ${new_pms:r:fs#/#::#} )
+ _perllocals=( /usr/lib/perl5/**/perllocal.pod(N) )
- _perl_modules=( $new_pms $_perl_modules )
+ if (( $#_perllocals )); then
+ for pod in $_perllocals; do
+ [[ "$pod" -nt "$1" ]] && return 0
done
fi
-fi
-local expl
+ return 1
+}
-_wanted modules expl 'Perl modules' compadd "$opts[@]" -a _perl_modules
+_perl_modules "$@"