#compdef rpm # This uses `_arguments' in a state-machine kind of way. These states # have names and before executing the default action for such a state # we try to call a function with the name `_rpm_'. If such a # function exists, we return with its return status immediately. This # allows users to override the default completions by simply defining # these functions. # The states (and possible values for the `' above) are: # # query # complete for `rpm -q' query # verify # complete for `rpm --verify' # install # complete for `rpm -i' or `rpm --install' # upgrade # complete for `rpm -U' or `rpm --upgrade' # uninstall # complete for `rpm -e' or `rpm --erase' # build_b # complete for `rpm -bx' (the stage `x' is already completed) # build_t # complete for `rpm -tx' (the stage `x' is already completed) # sigcheck # complete for `rpm --sigcheck' # rebuild # complete for `rpm --rebuild' # package # complete a RPM package name # package_file # complete a RPM package file name # package_or_file # the previous two together # file_or_package # an absolute path to any file (not a package file) or a package # tags # complete a tag name # capability # complete a capability # relocate # complete a `old=new' pair of paths _rpm () { local curcontext="$curcontext" state lstate line nm="$compstate[nmatches]" typeset -A opt_args local ret=1 local -a tmp expl commonopts selectopts pathopts commonopts=( '(-v --verbose)--quiet[print as little as possible]' '(--quiet)*'{-v,--verbose}'[verbose output]' '--rcfile:resource file:_files' '--ftpproxy:ftp proxy server:_hosts' '--ftpport:ftp port number' '--httpproxy:http proxy server:_hosts' '--httpport:http port number' {-\?,--help}'[print help information]' '--version[print version number]' '--pipe:pipe command:->command' ) # package selection options of which only one can be used selectopts=( {-a,--all}'[query all packages]' {-f,--file}'[query packages that own specified files]' {-p,--package}'[query uninstalled packages]' {-g,--group}'[query packages in one of specified groups]' --fileid --hdrid --pkgid --tid --querybynumber '--triggeredby' '--whatprovides:*:provided file:->file_or_package' '--whatrequires' ) sopts=${selectopts%\[*}\ --specfile selectopts=( "(* $sopts)"${selectopts[1,2]} "($sopts)"${selectopts[3,-1]} '(-a --all)*: :->package-select' ) pathopts=( '--root:rpm root directory:_files -/' '--dbpath:rpm database path:_files -/' ) _arguments -C -s \ "${commonopts[@]}" \ {-q+,--query}'[query mode]:*:query:->query' \ '(-V -y --verify)'{-V+,-y+,--verify}'[verify mode]:*:verify:->verify' \ '--import:*:public key' \ '(-K --checksig)'{-K,--checksig}'[signature check mode]:*:sigcheck:->sigcheck' \ '(-i --install)'{-i+,--install}'[install mode]:*:install:->install' \ '(-U --upgrade)'{-U+,--upgrade}'[upgrade mode]:*:upgrade:->upgrade' \ '(-F --freshen)'{-F+,--freshen}'[freshen mode]:*:upgrade:->upgrade' \ '(-e --erase)'{-e+,--erase}'[uninstall mode]:*:uninstall:->uninstall' \ --{initdb,querytags,showrc} \ '--rebuilddb:*:rebuild:->rebuild' \ --{resign,addsign}':*:package:->package_file' \ '--setperms[set file permissions]:*:package:->setattrs' \ '--setugids[set file owner/group]:*:package:->setattrs' \ '-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' \ '--rmsource:*:spec file:->spec_files' \ --{rebuild,recompile}':*:source rpm file:->package_src' \ '--eval:macro:->macros' && ret=0 # As long as we have a state name... while [[ -n "$state" ]]; do # First try to call a user-defined function. _call_function 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 one of -{l,c,d} # --triggers requires --script _arguments -s -C \ \!{-q,--query} "${commonopts[@]}" "${selectopts[@]}" "${pathopts[@]}" \ "($sopts)--specfile[query specified spec file as if it were a package]" \ '(-i --info)'{-i,--info}'[display package information]' \ '--changelog[display change log]' \ '(-s --state -l --list --filesbypkg)'{-l,--list}'[display package file list]' \ '(-s --state -l --list --filesbypkg)'{-s,--state}'[show file states]' \ '(-s --state -l --list)--filesbypkg[list files with package names]' \ {-d,--docfiles}'[documentation files only]' \ {-c,--configfiles}'[configuration files only]' \ '--dump[show all information]' \ '--provides[show capabilities provided]' \ \*--{qf,queryformat}'[specify format for package information]:rpm query format:->tags' \ -{R,-requires}'[list dependencies]' \ '--scripts[show (un)install scripts]' \ {--triggers,--triggerscripts}'[show trigger scripts]' && ret=0 ;; setattrs) _arguments -s -C --set{perm,ugids} "${selectopts[@]}" && ret=0 ;; verify) _arguments -s -C \!-{y,V} \ "${commonopts[@]}" "${selectopts[@]}" "${pathopts[@]}" \ --no{deps,files,scripts,digest,signature,linkto,md5,size,user,group,mtime,mode,rdev} && ret=0 ;; upgrade) tmp=( '(--force)--oldpackage' ) ;& install) _arguments -s -C \!-{i,U} "$tmp[@]" \ "${commonopts[@]}" "${pathopts[@]}" \ '--excludepath:file to exclude:_files -/' \ '--relocate:relocate:->relocate' \ '--prefix:package prefix directory:_files -/' \ '(-h --hash)'{-h,--hash} \ '(--replacepkgs --replacefiles --oldpackage)--force' \ '(--force)--'{replacefiles,replacepkgs} \ --{aid,allfiles,badreloc,excludedocs,ignorearch,ignoreos,ignoresize,includedocs,justdb,percent,repackage,test} \ --no{digest,signature,deps,suggest,order,pre,post,preun,postun,trigger{s,in,un,postun}} \ '(--nopre --nopost --nopreun --nopostun)--noscripts' \ '*:pkg file:->package_file' && ret=0 ;; uninstall) _arguments -s -C \!-e \ "${commonopts[@]}" "${pathopts[@]}" \ --{allmatches,justdb,repackage,test} \ --no{deps,scripts,preun,postun,trigger{s,un,postun}} \ '*:package:->package' && ret=0 ;; build_b) tmp=( '*:spec file:_files -g "*.spec(-.)"' ) ;& build_t) (( $#tmp )) || tmp=( '*:tar file:_files -g "*.(#i)tar(.*|)(-.)"' ) _arguments -s -C \ "${commonopts[@]}" "${pathopts[@]}" \ --{short-circuit,clean,nobuild,rmsource,sign,test} \ '--target:specify a build target:->target'\ '--buildroot:build root directory:_files -/' \ '--buildarch:architecture for which to build:->target' \ '--buildos:operating system for which to build:' \ '--timecheck:time check (seconds):' "$tmp[1]" && ret=0 ;; sigcheck) _arguments -s -C \!-K \ "${commonopts[@]}" \ --no{gpg,pgp,md5,signature,digest} \ '*:package file:->package_file' && ret=0 ;; rebuild) _arguments -s -C \ "${commonopts[@]}" "${pathopts[@]}" \ '*:source package file:->package_file' && ret=0 ;; package-select) case "${opt_args[(i)${sopts// /|}]}" in -f|--file) _files ;; -p|--package) state=package_file ;; -g|--group) state=groups ;; --fileid|--pkgid) _message -e md5 md5 ;; --hdrid) _message -e sha1 sha1 ;; --querybynumber) _message -e value number ;; --what*) state=capabilities ;; --specfile) state=spec_files ;; *) state=package ;; esac ;; macros) local -a macros local mfile for mfile in {/usr/lib/rpm/{,redhat/}macros,/etc/rpm/macros,~/.rpmmacros}(N); do macros+=( ${${(M)${(f)"$(<$mfile)"}:#%[^\{]*}%%[[:blank:]]*} ) done if zstyle -t ":completion:${curcontext}:macros" prefix-hidden; then macros=( ${macros#%} ) _wanted macros expl macro compadd -p '%' -a - macros else _wanted macros expl macro compadd -a - macros fi ;; command) compset -q _normal ;; target) _wanted targets expl 'target platform' compadd \ ${${(M)${(f)"$(_call_programs targets rpm --showrc)"}:#compatible archs*}##*: } && ret=0 ;; groups) if ( (( ! $+_rpm_groups )) || _cache_invalid rpm-groups ) && ! _retrieve_cache rpm-groups then typeset -gaU _rpm_groups _rpm_groups=( ${(f)"$(_call_program groups rpm -qa --queryformat '%\{group}\\n' 2>/dev/null)"} ) _store_cache RPM-groups _rpm_groups fi _wanted groups expl 'group' _multi_parts / _rpm_groups && ret=0 ;; package_or_file) state=package_file ;; file_or_package) if [[ $PREFIX = /* ]]; then _wanted files expl 'file' _files else state=package fi ;; package) if ( [[ ${+_rpms} -eq 0 ]] || _cache_invalid RPMs ) && ! _retrieve_cache RPMs; then _rpms=( $(_call_program packages rpm -qa 2>/dev/null) ) _store_cache RPMs _rpms fi _wanted packages expl 'package' \ compadd -M 'r:|-=* r:|=*' - "$_rpms[@]" && ret=0 ;; spec_files) _wanted specfiles expl 'spec file' \ _files -g '*.spec(-.)' && ret=0 ;; package_file) _wanted files expl '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 '(#i)*.src.rpm(-.)' && ret=0 ;; tags) local -a suf if compset -P "*%*${${QIPREFIX:+{}:-\{}"; then compset -S '(|\\)}*' || suf=( -qS ${${QIPREFIX:+\}}:-\\\}} ) _wanted tags expl 'rpm tag' compadd -M 'm:{a-z}={A-Z}' "$suf[@]" - \ "${(L@)${(@f)$(_call_program tags rpm --querytags 2>/dev/null)}#RPMTAG_}" && ret=0 else _message -e formats 'rpm query format' fi ;; capabilities) _wanted capabilities expl capability compadd \ ${(f)"$(_call_program capabilities rpm -qa --queryformat '%\{requirename}\\n' 2>/dev/null)"} && ret=0 ;; relocate) if compset -P 1 '*='; 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 } # 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 _rpms_caching_policy () { # rebuild if cache is more than a week old local -a oldp oldp=( "$1"(mw+1) ) (( $#oldp )) && return 0 pkg_indices=( /var/lib/rpm/{packages.rpm,Packages}(N) ) for pkg_index in $pkg_indices; do [[ "$pkg_index" -nt "$1" ]] && return 0 done } _rpm "$@"