summaryrefslogtreecommitdiff
path: root/scripts
diff options
context:
space:
mode:
authorAllan McRae <allan@archlinux.org>2016-10-09 22:21:45 +1000
committerAllan McRae <allan@archlinux.org>2016-10-10 10:38:05 +1000
commit2e76c184aac74c4848fa5ee092fe54c9954c4054 (patch)
tree5dff5536f7a67cf032a0bd8b7e43f4192a96f030 /scripts
parentd590a45795b30a14cdb697754749c85907053570 (diff)
downloadpacman-2e76c184aac74c4848fa5ee092fe54c9954c4054.tar.xz
Move bash/zsh completion out of contrib
Signed-off-by: Allan McRae <allan@archlinux.org>
Diffstat (limited to 'scripts')
-rw-r--r--scripts/Makefile.am29
-rw-r--r--scripts/completion/.gitignore2
-rw-r--r--scripts/completion/bash_completion.in156
-rw-r--r--scripts/completion/zsh_completion.in723
4 files changed, 909 insertions, 1 deletions
diff --git a/scripts/Makefile.am b/scripts/Makefile.am
index 86624968..8278b6fd 100644
--- a/scripts/Makefile.am
+++ b/scripts/Makefile.am
@@ -26,6 +26,7 @@ EXTRA_DIST = \
pacman-key.sh.in \
pkgdelta.sh.in \
repo-add.sh.in \
+ $(COMPLETION_DIST) \
$(LIBRARY) \
$(LIBMAKEPKG_DIST)
@@ -102,8 +103,15 @@ LIBMAKEPKG_DIST = \
$(LIBMAKEPKG) \
$(addsuffix .in, $(LIBMAKEPKG_IN))
+COMPLETION_IN = \
+ completion/bash_completion \
+ completion/zsh_completion
+
+COMPLETION_DIST = \
+ $(addsuffix .in, $(COMPLETION_IN))
+
# Files that should be removed, but which Automake does not know.
-MOSTLYCLEANFILES = $(bin_SCRIPTS) $(LIBMAKEPKG_IN)
+MOSTLYCLEANFILES = $(bin_SCRIPTS) $(LIBMAKEPKG_IN) $(COMPLETION_IN)
clean-local:
$(AM_V_at)$(RM) -r .lib
@@ -157,6 +165,14 @@ $(LIBMAKEPKG_IN): %: %.in Makefile
$(AM_V_at)chmod a-w $@
@$(BASH_SHELL) -O extglob -n $@
+$(COMPLETION_IN): %: %.in Makefile
+ $(AM_V_at)$(RM) $@
+ $(AM_V_at)$(MKDIR_P) $(dir $@)
+ $(AM_V_GEN)$(edit) $(srcdir)/$@.in >$@
+ $(AM_V_at)chmod a-w $@
+
+all-am: $(COMPLETION_IN)
+
makepkg: \
$(srcdir)/makepkg.sh.in \
$(srcdir)/makepkg-wrapper.sh.in \
@@ -213,6 +229,16 @@ makepkg-wrapper: \
$(AM_V_at)chmod +x,a-w $@
$(AM_V_at)$(LN_S) makepkg-wrapper makepkg
+install-data-local:
+ $(MKDIR_P) $(DESTDIR)$(sysconfdir)/bash_completion.d/
+ $(INSTALL_DATA) completion/bash_completion $(DESTDIR)$(sysconfdir)/bash_completion.d/pacman
+ $(MKDIR_P) $(DESTDIR)$(datarootdir)/zsh/site-functions/
+ $(INSTALL_DATA) completion/zsh_completion $(DESTDIR)$(datarootdir)/zsh/site-functions/_pacman
+
+uninstall-local:
+ $(RM) $(DESTDIR)$(sysconfdir)/bash_completion.d/pacman
+ $(RM) $(DESTDIR)$(datarootdir)/zsh/site-functions/_pacman
+
install-exec-hook:
cd $(DESTDIR)$(bindir) && \
$(RM) makepkg makepkg-wrapper
@@ -247,4 +273,5 @@ uninstall-hook:
$(RM) -r $(DESTDIR)$(libmakepkgdir)/$$dir; \
done
+
# vim:set noet:
diff --git a/scripts/completion/.gitignore b/scripts/completion/.gitignore
new file mode 100644
index 00000000..881bfd14
--- /dev/null
+++ b/scripts/completion/.gitignore
@@ -0,0 +1,2 @@
+bash_completion
+zsh_completion
diff --git a/scripts/completion/bash_completion.in b/scripts/completion/bash_completion.in
new file mode 100644
index 00000000..06963c42
--- /dev/null
+++ b/scripts/completion/bash_completion.in
@@ -0,0 +1,156 @@
+# This file is in the public domain.
+
+_arch_compgen() {
+ local i r
+ COMPREPLY=($(compgen -W '$*' -- "$cur"))
+ for ((i=1; i < ${#COMP_WORDS[@]}-1; i++)); do
+ for r in ${!COMPREPLY[@]}; do
+ if [[ ${COMP_WORDS[i]} = ${COMPREPLY[r]} ]]; then
+ unset 'COMPREPLY[r]'; break
+ fi
+ done
+ done
+}
+
+_arch_ptr2comp() {
+ local list= x y
+ for x; do
+ for y in '0 --' '1 -'; do
+ eval 'set -- ${'$x'[${y% *}]}'
+ list+=\ ${@/#/${y#* }}
+ done
+ done
+ _arch_compgen $list
+}
+
+_arch_incomp() {
+ local r="\s-(-${1#* }\s|\w*${1% *})"; [[ $COMP_LINE =~ $r ]]
+}
+
+_pacman_keyids() {
+ \pacman-key --list-keys 2>/dev/null | awk '
+ $1 == "pub" {
+ # key id
+ split($2, a, "/"); print a[2]
+ }
+ $1 == "uid" {
+ # email
+ if (match($NF, /<[^>]+>/))
+ print substr($NF, RSTART + 1, RLENGTH - 2)
+ }'
+}
+
+_pacman_key() {
+ local o cur opts prev wantfiles
+ COMPREPLY=()
+ _get_comp_words_by_ref cur prev
+ opts=('add config delete edit-key export finger gpgdir
+ help import import-trustdb init keyserver list-keys list-sigs
+ lsign-key nocolor populate recv-keys refresh-keys updatedb
+ verify version'
+ 'a d e f h l r u v V')
+
+ # operations for which we want to complete keyids
+ for o in 'd delete' 'e export' 'f finger' 'l list-keys' 'r recv-keys' \
+ 'edit-key' 'list-sigs' 'lsign-key' 'refresh-keys'; do
+ _arch_incomp "$o" && break
+ unset o
+ done
+
+ # options for which we want file completion
+ wantfiles='-@(c|-config|g|-gpgdir)'
+
+ if [[ $prev = 'pacman-key' || ( $cur = -* && $prev != $wantfiles ) ]]; then
+ _arch_ptr2comp opts
+ elif [[ $prev = @(-k|--keyserver) ]]; then
+ return
+ elif [[ $prev != $wantfiles && $o ]]; then
+ COMPREPLY=($(compgen -W '$(_pacman_keyids)' -- "$cur"))
+ fi
+ true
+}
+
+_makepkg() {
+ local cur opts prev
+ COMPREPLY=()
+ _get_comp_words_by_ref cur prev
+ if [[ $cur = -* && ! $prev =~ ^-(-(config|help|key|version)$|\w*[Vhp]) ]]; then
+ opts=('allsource asdeps check clean cleanbuild config force geninteg help
+ holdver ignorearch install key log needed noarchive nobuild nocheck
+ nocolor noconfirm nodeps noextract noprepare noprogressbar nosign
+ packagelist printsrcinfo repackage rmdeps sign skipchecksums
+ skipinteg skippgpcheck source syncdeps verifysource version'
+ 'A C L R S c d e f g h i m o p r s')
+ _arch_ptr2comp opts
+ fi
+ true
+}
+
+_pacman_pkg() {
+ _arch_compgen "$(
+ if [[ $2 ]]; then
+ \pacman -$1 2>/dev/null | \cut -d' ' -f1 | \sort -u
+ else
+ \pacman -$1 2>/dev/null
+ fi
+ )"
+}
+
+_pacman() {
+ local common core cur database files prev query remove sync upgrade o
+ COMPREPLY=()
+ _get_comp_words_by_ref cur prev
+ database=('asdeps asexplicit')
+ files=('list machinereadable owns search refresh regex' 'l o s x y')
+ query=('changelog check deps explicit file foreign groups info list owns
+ search unrequired upgrades' 'c e g i k l m o p s t u')
+ remove=('cascade dbonly nodeps assume-installed nosave print recursive unneeded' 'c n p s u')
+ sync=('asdeps asexplicit clean dbonly downloadonly force groups ignore ignoregroup
+ info list needed nodeps assume-installed print refresh recursive search sysupgrade'
+ 'c g i l p s u w y')
+ upgrade=('asdeps asexplicit force needed nodeps assume-installed print recursive' 'p')
+ common=('arch cachedir color config confirm dbpath debug gpgdir help hookdir logfile
+ noconfirm noprogressbar noscriptlet quiet root verbose' 'b d h q r v')
+ core=('database files help query remove sync upgrade version' 'D F Q R S U V h')
+
+ for o in 'D database' 'F files' 'Q query' 'R remove' 'S sync' 'U upgrade'; do
+ _arch_incomp "$o" && break
+ done
+
+ if [[ $? != 0 ]]; then
+ _arch_ptr2comp core
+ elif [[ ! $prev =~ ^-\w*[Vbhr] &&
+ ! $prev = --@(cachedir|color|config|dbpath|help|hookdir|gpgdir|logfile|root|version) ]]
+ then
+ [[ $cur = -* ]] && _arch_ptr2comp ${o#* } common ||
+ case ${o% *} in
+ D|R)
+ _pacman_pkg Qq;;
+ F)
+ _arch_incomp 'l list' && _pacman_pkg Slq;
+ ;;
+ Q)
+ { _arch_incomp 'g groups' && _pacman_pkg Qg sort; } ||
+ { _arch_incomp 'p file' && _pacman_file; } ||
+ _arch_incomp 'o owns' || _arch_incomp 'u upgrades' ||
+ _pacman_pkg Qq;;
+ S)
+ { _arch_incomp 'g groups' && _pacman_pkg Sg; } ||
+ { _arch_incomp 'l list' && _pacman_pkg Sl sort; } ||
+ _pacman_pkg Slq;;
+ U)
+ _pacman_file;;
+ esac
+ fi
+ true
+}
+
+_pacman_file() {
+ compopt -o filenames; _filedir 'pkg.tar*'
+}
+
+complete -F _pacman -o default pacman
+complete -F _makepkg -o default makepkg
+complete -F _pacman_key -o default pacman-key
+
+# ex:et ts=2 sw=2 ft=sh
diff --git a/scripts/completion/zsh_completion.in b/scripts/completion/zsh_completion.in
new file mode 100644
index 00000000..f74fa297
--- /dev/null
+++ b/scripts/completion/zsh_completion.in
@@ -0,0 +1,723 @@
+#compdef pacman pacman.static=pacman pacman-key makepkg
+
+# copy this file to /usr/share/zsh/site-functions/_pacman
+
+typeset -A opt_args
+setopt extendedglob
+
+# options for passing to _arguments: main pacman commands
+_pacman_opts_commands=(
+ {-D,--database}'[Modify database]'
+ {-F,--files}'[Query the files database]'
+ {-Q,--query}'[Query the package database]'
+ {-R,--remove}'[Remove a package from the system]'
+ {-S,--sync}'[Synchronize packages]'
+ {-T,--deptest}'[Check if dependencies are installed]'
+ {-U,--upgrade}'[Upgrade a package]'
+ {-V,--version}'[Display version and exit]'
+ '(-h --help)'{-h,--help}'[Display usage]'
+)
+
+# options for passing to _arguments: options common to all commands
+_pacman_opts_common=(
+ '--arch[Set an alternate architecture]'
+ {-b,--dbpath}'[Alternate database location]:database_location:_files -/'
+ '--color[colorize the output]:color options:(always never auto)'
+ {-h,--help}'[Display syntax for the given operation]'
+ {-r,--root}'[Set alternate installation root]:installation root:_files -/'
+ {-v,--verbose}'[Be more verbose]'
+ '--cachedir[Alternate package cache location]:cache_location:_files -/'
+ '--config[An alternate configuration file]:config file:_files'
+ '--confirm[Always ask for confirmation]'
+ '--debug[Display debug messages]'
+ '--gpgdir[Set an alternate directory for GnuPG (instead of @sysconfdir@/pacman.d/gnupg)]: :_files -/'
+ '--hookdir[Set an alternate hook location]: :_files -/'
+ '--logfile[An alternate log file]:config file:_files'
+ '--noconfirm[Do not ask for confirmation]'
+ '--noprogressbar[Do not show a progress bar when downloading files]'
+ '--noscriptlet[Do not execute the install scriptlet if one exists]'
+)
+
+# options for passing to _arguments: options for --upgrade commands
+_pacman_opts_pkgfile=(
+ '*-d[Skip dependency checks]'
+ '*--nodeps[Skip dependency checks]'
+ '*--assume-installed[Add virtual package to satisfy dependencies]'
+ '--dbonly[Only remove database entry, do not remove files]'
+ '--force[Overwrite conflicting files]'
+ '--needed[Do not reinstall up to date packages]'
+ '--asdeps[mark packages as non-explicitly installed]'
+ '--asexplicit[mark packages as explicitly installed]'
+ {-p,--print}'[Only print the targets instead of performing the operation]'
+ '*--ignore[Ignore a package upgrade]:package: _pacman_completions_all_packages'
+ '*--ignoregroup[Ignore a group upgrade]:package group:_pacman_completions_all_groups'
+ '--print-format[Specify how the targets should be printed]'
+ '*:package file:_files -g "*.pkg.tar*~*.sig(.,@)"'
+)
+
+# options for passing to _arguments: subactions for --query command
+_pacman_opts_query_actions=(
+ '(-Q --query)'{-Q,--query}
+ {-g,--groups}'[View all members of a package group]:*:package groups:->query_group'
+ {-o,--owns}'[Query the package that owns a file]:file:_files'
+ {-p,--file}'[Package file to query]:*:package file:->query_file'
+ {-s,--search}'[Search package names and descriptions]:*:search text:->query_search'
+)
+
+# options for passing to _arguments: options for --query and subcommands
+_pacman_opts_query_modifiers=(
+ {-c,--changelog}'[List package changelog]'
+ {-d,--deps}'[List packages installed as dependencies]'
+ {-e,--explicit}'[List packages explicitly installed]'
+ {\*-i,\*--info}'[View package information]'
+ {\*-k,\*--check}'[Check package files]'
+ {-l,--list}'[List package contents]'
+ {-m,--foreign}'[List installed packages not found in sync db(s)]'
+ {-n,--native}'[List installed packages found in sync db(s)]'
+ {-q,--quiet}'[Show less information for query and search]'
+ {-t,--unrequired}'[List packages not required by any package]'
+ {-u,--upgrades}'[List packages that can be upgraded]'
+)
+
+# options for passing to _arguments: options for --remove command
+_pacman_opts_remove=(
+ {-c,--cascade}'[Remove all dependent packages]'
+ {-d,--nodeps}'[Skip dependency checks]'
+ '*--assume-installed[Add virtual package to satisfy dependencies]'
+ {-n,--nosave}'[Remove protected configuration files]'
+ {-p,--print}'[Only print the targets instead of performing the operation]'
+ {\*-s,\*--recursive}'[Remove dependencies not required by other packages]'
+ {-u,--unneeded}'[Remove unneeded packages]'
+ '--dbonly[Only remove database entry, do not remove files]'
+ '--print-format[Specify how the targets should be printed]'
+ '*:installed package:_pacman_completions_installed_packages'
+)
+
+_pacman_opts_database=(
+ '--asdeps[mark packages as non-explicitly installed]'
+ '--asexplicit[mark packages as explicitly installed]'
+ '*:installed package:_pacman_completions_installed_packages'
+)
+
+_pacman_opts_files=(
+ {-l,--list}'[List the files owned by the queried package]:package:_pacman_completions_all_packages'
+ {-o,--owns}'[Query the package that owns]:files:_files'
+ {-s,--search}'[Search package file names for matching strings]:files:_files'
+ {-x,--regex}'[Enable searching using regular expressions]:regex:'
+ {-y,--refresh}'[Download fresh files databases from the server]'
+ '--machinereadable[Produce machine-readable output]'
+ {-q,--quiet}'[Show less information for query and search]'
+)
+
+# options for passing to _arguments: options for --sync command
+_pacman_opts_sync_actions=(
+ '(-S --sync)'{-S,--sync}
+ {\*-c,\*--clean}'[Remove old packages from cache]:\*:clean:->sync_clean'
+ {-g,--groups}'[View all members of a package group]:*:package groups:->sync_group'
+ {-s,--search}'[Search package names and descriptions]:*:search text:->sync_search'
+ '--dbonly[Only remove database entry, do not remove files]'
+ '--needed[Do not reinstall up to date packages]'
+ '--recursive[Reinstall all dependencies of target packages]'
+)
+
+# options for passing to _arguments: options for --sync command
+_pacman_opts_sync_modifiers=(
+ {\*-d,\*--nodeps}'[Skip dependency checks]'
+ '*--assume-installed[Add virtual package to satisfy dependencies]'
+ {\*-i,\*--info}'[View package information]'
+ {-l,--list}'[List all packages in a repository]'
+ {-p,--print}'[Print download URIs for each package to be installed]'
+ {-q,--quiet}'[Show less information for query and search]'
+ {\*-u,\*--sysupgrade}'[Upgrade all out-of-date packages]'
+ {-w,--downloadonly}'[Download packages only]'
+ {\*-y,\*--refresh}'[Download fresh package databases]'
+ '*--ignore[Ignore a package upgrade]:package: _pacman_completions_all_packages'
+ '*--ignoregroup[Ignore a group upgrade]:package group:_pacman_completions_all_groups'
+ '--asdeps[Install packages as non-explicitly installed]'
+ '--asexplicit[Install packages as explicitly installed]'
+ '--force[Overwrite conflicting files]'
+ '--print-format[Specify how the targets should be printed]'
+)
+
+# handles --help subcommand
+_pacman_action_help() {
+ _arguments -s : \
+ "$_pacman_opts_commands[@]"
+}
+
+# handles cases where no subcommand has yet been given
+_pacman_action_none() {
+ _arguments -s : \
+ "$_pacman_opts_commands[@]"
+}
+
+# handles --query subcommand
+_pacman_action_query() {
+ local context state line
+ typeset -A opt_args
+
+ case $state in
+ query_file)
+ _arguments -s : \
+ "$_pacman_opts_common[@]" \
+ "$_pacman_opts_query_modifiers[@]" \
+ '*:package file:_files -g "*.pkg.tar*~*.sig(.,@)"'
+ ;;
+ query_group)
+ _arguments -s : \
+ "$_pacman_opts_common[@]" \
+ "$_pacman_opts_query_modifiers[@]" \
+ '*:groups:_pacman_completions_installed_groups'
+ ;;
+ query_owner)
+ _arguments -s : \
+ "$_pacman_opts_common[@]" \
+ "$_pacman_opts_query_modifiers[@]" \
+ '*:file:_files'
+ ;;
+ query_search)
+ _arguments -s : \
+ "$_pacman_opts_common[@]" \
+ "$_pacman_opts_query_modifiers[@]" \
+ '*:search text: '
+ ;;
+ *)
+ _arguments -s : \
+ "$_pacman_opts_common[@]" \
+ "$_pacman_opts_query_actions[@]" \
+ "$_pacman_opts_query_modifiers[@]" \
+ '*:package:_pacman_completions_installed_packages'
+ ;;
+ esac
+}
+
+# handles --remove subcommand
+_pacman_action_remove() {
+ _arguments -s : \
+ '(--remove -R)'{-R,--remove} \
+ "$_pacman_opts_common[@]" \
+ "$_pacman_opts_remove[@]"
+}
+
+# handles --database subcommand
+_pacman_action_database() {
+ _arguments -s : \
+ '(--database -D)'{-D,--database} \
+ "$_pacman_opts_common[@]" \
+ "$_pacman_opts_database[@]"
+}
+
+# handles --files subcommand
+_pacman_action_files() {
+ _arguments -s : \
+ '(--files -F)'{-F,--files} \
+ "$_pacman_opts_common[@]" \
+ "$_pacman_opts_files[@]"
+}
+
+_pacman_action_deptest () {
+ _arguments -s : \
+ '(--deptest)-T' \
+ "$_pacman_opts_common[@]" \
+ ":packages:_pacman_all_packages"
+}
+
+
+# handles --sync subcommand
+_pacman_action_sync() {
+ local context state line
+ typeset -A opt_args
+ if (( $+words[(r)--clean] )); then
+ state=sync_clean
+ elif (( $+words[(r)--groups] )); then
+ state=sync_group
+ elif (( $+words[(r)--search] )); then
+ state=sync_search
+ fi
+
+ case $state in
+ sync_clean)
+ _arguments -s : \
+ {\*-c,\*--clean}'[Remove old packages from cache]' \
+ "$_pacman_opts_common[@]" \
+ "$_pacman_opts_sync_modifiers[@]"
+ ;;
+ sync_group)
+ _arguments -s : \
+ "$_pacman_opts_common[@]" \
+ "$_pacman_opts_sync_modifiers[@]" \
+ '(-g --group)'{-g,--groups} \
+ '*:package group:_pacman_completions_all_groups'
+ ;;
+ sync_search)
+ _arguments -s : \
+ "$_pacman_opts_common[@]" \
+ "$_pacman_opts_sync_modifiers[@]" \
+ '*:search text: '
+ ;;
+ *)
+ _arguments -s : \
+ "$_pacman_opts_common[@]" \
+ "$_pacman_opts_sync_actions[@]" \
+ "$_pacman_opts_sync_modifiers[@]" \
+ '*:package:_pacman_completions_all_packages'
+ ;;
+ esac
+}
+
+# handles --upgrade subcommand
+_pacman_action_upgrade() {
+ _arguments -s : \
+ '(-U --upgrade)'{-U,--upgrade} \
+ "$_pacman_opts_common[@]" \
+ "$_pacman_opts_pkgfile[@]"
+}
+
+# handles --version subcommand
+_pacman_action_version() {
+ # no further arguments
+ return 0
+}
+
+# provides completions for package groups
+_pacman_completions_all_groups() {
+ local -a cmd groups
+ _pacman_get_command
+ groups=( $(_call_program groups $cmd[@] -Sg) )
+ typeset -U groups
+
+ if [[ ${words[CURRENT-1]} == '--ignoregroup' ]]; then
+ _sequence compadd -S ',' "$@" -a groups
+ else
+ compadd "$@" -a groups
+ fi
+}
+
+# provides completions for packages available from repositories
+# these can be specified as either 'package' or 'repository/package'
+_pacman_completions_all_packages() {
+ local -a seq sep cmd packages repositories packages_long
+ _pacman_get_command
+
+ if [[ ${words[CURRENT-1]} == '--ignore' ]]; then
+ seq='_sequence'
+ sep=(-S ',')
+ else
+ seq=
+ sep=()
+ fi
+
+ if compset -P1 '*/*'; then
+ packages=( $(_call_program packages $cmd[@] -Sql ${words[CURRENT]%/*}) )
+ typeset -U packages
+ ${seq} _wanted repo_packages expl "repository/package" compadd ${sep[@]} ${(@)packages}
+ else
+ packages=( $(_call_program packages $cmd[@] -Sql) )
+ typeset -U packages
+ ${seq} _wanted packages expl "packages" compadd ${sep[@]} - "${(@)packages}"
+
+ repositories=(${(o)${${${(M)${(f)"$(<@sysconfdir@/pacman.conf)"}:#\[*}/\[/}/\]/}:#options})
+ typeset -U repositories
+ _wanted repo_packages expl "repository/package" compadd -S "/" $repositories
+ fi
+}
+
+# provides completions for package groups
+_pacman_completions_installed_groups() {
+ local -a cmd groups
+ _pacman_get_command
+ groups=(${(o)${(f)"$(_call_program groups $cmd[@] -Qg)"}% *})
+ typeset -U groups
+ compadd "$@" -a groups
+}
+
+# provides completions for installed packages
+_pacman_completions_installed_packages() {
+ local -a cmd packages packages_long
+ packages_long=(@localstatedir@/lib/pacman/local/*(/))
+ packages=( ${${packages_long#@localstatedir@/lib/pacman/local/}%-*-*} )
+ compadd "$@" -a packages
+}
+
+_pacman_all_packages() {
+ _alternative : \
+ 'localpkgs:local packages:_pacman_completions_installed_packages' \
+ 'repopkgs:repository packages:_pacman_completions_all_packages'
+}
+
+# provides completions for repository names
+_pacman_completions_repositories() {
+ local -a cmd repositories
+ repositories=(${(o)${${${(M)${(f)"$(<@sysconfdir@/pacman.conf)"}:#\[*}/\[/}/\]/}:#options})
+ # Uniq the array
+ typeset -U repositories
+ compadd "$@" -a repositories
+}
+
+# builds command for invoking pacman in a _call_program command - extracts
+# relevant options already specified (config file, etc)
+# $cmd must be declared by calling function
+_pacman_get_command() {
+ # this is mostly nicked from _perforce
+ cmd=( "pacman" "2>/dev/null")
+ integer i
+ for (( i = 2; i < CURRENT - 1; i++ )); do
+ if [[ ${words[i]} = "--config" || ${words[i]} = "--root" ]]; then
+ cmd+=( ${words[i,i+1]} )
+ fi
+ done
+}
+
+# main dispatcher
+_pacman_zsh_comp() {
+ local -a args cmds;
+ local tmp
+ args=( ${${${(M)words:#-*}#-}:#-*} )
+ for tmp in $words; do
+ cmds+=("${${_pacman_opts_commands[(r)*$tmp\[*]%%\[*}#*\)}")
+ done
+ case $args in #$words[2] in
+ h*)
+ if (( ${(c)#args} <= 1 && ${(w)#cmds} <= 1 )); then
+ _pacman_action_help
+ else
+ _message "no more arguments"
+ fi
+ ;;
+ *h*)
+ _message "no more arguments"
+ ;;
+ D*)
+ _pacman_action_database
+ ;;
+ F*)
+ _pacman_action_files
+ ;;
+ Q*g*) # ipkg groups
+ _arguments -s : \
+ "$_pacman_opts_common[@]" \
+ "$_pacman_opts_query_modifiers[@]" \
+ '*:groups:_pacman_completions_installed_groups'
+ ;;
+ Q*o*) # file
+ _arguments -s : \
+ "$_pacman_opts_common[@]" \
+ "$_pacman_opts_query_modifiers[@]" \
+ '*:package file:_files'
+ ;;
+ Q*p*) # file *.pkg.tar*
+ _arguments -s : \
+ "$_pacman_opts_common[@]" \
+ "$_pacman_opts_query_modifiers[@]" \
+ '*:package file:_files -g "*.pkg.tar*~*.sig(.,@)"'
+ ;;
+ T*)
+ _pacman_action_deptest
+ ;;
+ Q*)
+ _pacman_action_query
+ ;;
+ R*)
+ _pacman_action_remove
+ ;;
+ S*c*) # no completion
+ _arguments -s : \
+ '(-c --clean)'{\*-c,\*--clean}'[Remove all files from the cache]' \
+ "$_pacman_opts_common[@]"
+ ;;
+ S*l*) # repos
+ _arguments -s : \
+ "$_pacman_opts_common[@]" \
+ "$_pacman_opts_sync_modifiers[@]" \
+ '*:package repo:_pacman_completions_repositories' \
+ ;;
+ S*g*) # pkg groups
+ _arguments -s : \
+ "$_pacman_opts_common[@]" \
+ "$_pacman_opts_sync_modifiers[@]" \
+ '*:package group:_pacman_completions_all_groups'
+ ;;
+ S*s*)
+ _arguments -s : \
+ "$_pacman_opts_common[@]" \
+ "$_pacman_opts_sync_modifiers[@]" \
+ '*:search text: '
+ ;;
+ S*)
+ _pacman_action_sync
+ ;;
+ T*)
+ _arguments -s : \
+ '-T' \
+ "$_pacman_opts_common[@]" \
+ ":packages:_pacman_all_packages"
+ ;;
+ U*)
+ _pacman_action_upgrade
+ ;;
+ V*)
+ _pacman_action_version
+ ;;
+ *)
+
+ case ${(M)words:#--*} in
+ *--help*)
+ if (( ${(w)#cmds} == 1 )); then
+ _pacman_action_help
+ else
+ return 0;
+ fi
+ ;;
+ *--sync*)
+ _pacman_action_sync
+ ;;
+ *--query*)
+ _pacman_action_query
+ ;;
+ *--remove*)
+ _pacman_action_remove
+ ;;
+ *--deptest*)
+ _pacman_action_deptest
+ ;;
+ *--database*)
+ _pacman_action_database
+ ;;
+ *--files*)
+ _pacman_action_files
+ ;;
+ *--version*)
+ _pacman_action_version
+ ;;
+ *--upgrade*)
+ _pacman_action_upgrade
+ ;;
+ *)
+ _pacman_action_none
+ ;;
+ esac
+ ;;
+ esac
+}
+
+_key_shortopts=(
+ '-h[show help]'
+ '-a[Add the specified keys (empty for stdin)]: :_files'
+ '-d[Remove the Specified keyids]:*: :_keys'
+ '-e[Export the specified or all keyids]:*: :_keys'
+ '-f[List fingerprint for specified or all keyids]:*: :_keys'
+ '-l[List the specified or all keys]:*: :_keys'
+ '-r[Fetch the specified keyids]:*: :_keys'
+ '-u[Update the trustdb of pacman]'
+ '-v[Verify the file specified by the signature]: :_files -g "*.sig"'
+ '-V[Show program version]'
+)
+
+_key_longopts=(
+ '--help[show help]'
+ '--add[Add the specified keys (empty for stdin)]: :_files'
+ '--delete[Remove the Specified keyids]:*: :_keys'
+ '--export[Export the specified or all keyids]:*: :_keys'
+ '--finger[List fingerprint for specified or all keyids]:*: :_keys'
+ '--list-keys[List the specified or all keys]:*: :_keys'
+ '--recv-keys[Fetch the specified keyids]:*: :_keys'
+ '--updatedb[Update the trustdb of pacman]'
+ '--verify[Verify the file specified by the signature]: :_files -g "*.sig"'
+ '--version[Show program version]'
+ '--edit-key[Present a menu for key management task on keyids]:*: :_keys'
+ '--import[Imports pubring.gpg from dir(s)]: :_files -g "*.gpg"'
+ '--import-tb[Imports ownertrust values from trustdb.gpg in dir(s)]: :_files -g "*.gpg"'
+ '--init[Ensure the keyring is properly initialized]'
+ '--list-sigs[List keys and their signatures]:*: :_keys'
+ '--lsign-key[Locally sign the specified keyid]:*: :_keys'
+ '--populate[Reload the default keys from the (given) keyrings in '/usr/share/pacman/keyrings']: :_path_files -W /usr/share/pacman/keyrings'
+ '--refresh-keys[Update specified or all keys from a keyserver]:*: :_keys'
+)
+
+_pacman_key_options=(
+ '--config[Use an alternate config file (instead of @sysconfdir@/pacman.conf)]: :_files'
+ '--gpgdir[Set an alternate directory for GnuPG (instead of @sysconfdir@/pacman.d/gnupg)]: :_files -/'
+ '--keyserver[Specify a keyserver to use if necessary]'
+)
+
+_pacman_key() {
+ case $words[CURRENT] in
+ --*)
+ _arguments -s : \
+ "$_pacman_key_options[@]" \
+ "$_key_longopts[@]"
+ ;;
+ -*)
+ _arguments -s : \
+ "$_pacman_key_options[@]" \
+ "$_key_shortopts[@]" \
+ "$_key_longopts[@]"
+ ;;
+ *)
+ i=$#;
+ while [[ $words[$i] != -* ]] && [[ $words[$i] != "pacman-key" ]];do
+ i=$(($i-1))
+ done
+ case $i in
+ --*)
+ _arguments -s : \
+ "$_pacman_key_options[@]" \
+ "$_key_longopts[@]"
+ ;;
+ -*)
+ _arguments -s : \
+ "$_pacman_key_options[@]" \
+ "$_key_shortopts[@]" \
+ "$_key_longopts[@]"
+ ;;
+ *)
+ return 1
+ ;;
+ esac
+ ;;
+ esac
+}
+
+_keys() {
+ local keylist keys
+ keylist=$(pacman-key --list-keys 2>/dev/null | awk '
+ $1 == "pub" {
+ # key id
+ split($2, a, "/"); print a[2]
+ }
+ $1 == "uid" {
+ # email
+ if (match($NF, /<[^>]+>/))
+ print substr($NF, RSTART + 1, RLENGTH - 2)
+ #this adds support for names as well if that is ever added
+ }
+ $1 == "uid" {
+ for (i=2;i<NF;i++) {printf "%s%s",sep, $i;sep=" "}; printf "\n"
+ }' |sed -e 's/(.*)//g' -e 's/^\ //g' -e 's/\ *$//g' |uniq
+ )
+ keys=(${(s:/:)${keylist//$'\n'/\/}})
+ _describe -t modules 'keys in keyring' keys && return 0
+}
+
+_makepkg_shortopts=(
+ '-s[Install missing dependencies with pacman]'
+ '-i[Install package after successful build]'
+ '-A[Ignore incomplete arch field in PKGBUILD]'
+ '-c[Clean up work files after build]'
+ '-C[Remove $srcdir/ dir before building the package]'
+ '-d[Skip all dependency checks]'
+ '-e[Do not extract source files (use existing $srcdir/ dir)]'
+ '-f[Overwrite existing package]'
+ '-g[Generate integrity checks for source files]'
+ '-h[Show help message and exit]'
+ '-L[Log package build process]'
+ '-m[Disable colorized output messages]'
+ '-o[Download and extract files only]'
+ '-p[Use an alternate build script (instead of 'PKGBUILD')]: :_files'
+ '-r[Remove installed dependencies after a successful build]'
+ '-R[Repackage contents of the package without rebuilding]'
+ '-S[Generate a source-only tarball without downloading sources]'
+ '-V[Show version information and exit]'
+)
+
+_makepkg_action_none(){
+ _arguments \
+ "$_makepkg_shortopts[@]" \
+ "$_makepkg_longopts[@]"
+}
+_makepkg_longopts=(
+ '--ignorearch[Ignore incomplete arch field in PKGBUILD]'
+ '--clean[Clean up work files after build]'
+ '--cleanbuild[Remove $srcdir/ dir before building the package]'
+ '--nodeps[Skip all dependency checks]'
+ '--noextract[Do not extract source files (use existing $srcdir/ dir)]'
+ '--force[Overwrite existing package]'
+ '--geninteg[Generate integrity checks for source files]'
+ '--help[Show help message and exit]'
+ '--install[Install package after successful build]'
+ '--log[Log package build process]'
+ '--nocolor[Disable colorized output messages]'
+ '--nobuild[Download and extract files only]'
+ '--rmdeps[Remove installed dependencies after a successful build]'
+ '--repackage[Repackage contents of the package without rebuilding]'
+ '--syncdeps[Install missing dependencies with pacman]'
+ '--source[Generate a source-only tarball without downloading sources]'
+ '--version[Show version information and exit]'
+ '--allsource[Generate a source-only tarball including downloaded source]'
+ '--check[Run check() function in the PKGBUILD]'
+ '--config[Use an alternate config file instead of '@sysconfdir@/makepkg.conf']: :_files'
+ '--holdver[Do not update VCS sources]'
+ '--key[Specify key to use for gpg signing instead of the default]: :_keys'
+ '--noarchive[Do not create package archive]'
+ '--nocheck[Do not run the check() function in the PKGBUILD]'
+ '--noprepare[Do not run the prepare() function in the PKGBUILD]'
+ '--nosign[Do not create a signature for the package]'
+ '--packagelist[Only list packages that would be produced, without PKGEXT]'
+ '--printsrcinfo[Print the generated SRCINFO and exit]'
+ '--sign[Sign the resulting package with gpg]'
+ '--skipchecksums[Do not verify checksums of the source files]'
+ '--skipinteg[do not perform any verification checks on source files]'
+ '--skippgpcheck[Do not verify source files with PGP signatures]'
+ '--noconfirm[Do not ask for confirmation when resolving dependencies]'
+ '--asdeps[Install packages as non-explicitly installed]'
+ '--noprogressbar[Do not show a progress bar when downloading files]'
+ '--needed[Do not reinstall the targets that are already up to date]'
+ '--verifysource[Download source files (if needed) and perform integrity checks]'
+)
+_makepkg(){
+ case $words[CURRENT] in
+ -*)
+ _arguments -s -w : \
+ "$_makepkg_shortopts[@]" \
+ "$_makepkg_longopts[@]"
+ ;;
+ --* )
+ _arguments -s \
+ "$_makepkg_longopts[@]"
+ ;;
+ - )
+ _makepkg_action_none
+ ;;
+ *)
+ i=$#
+ while [[ $words[i] != -* ]] && [[ $words[$i] != "makepkg" ]];do
+ i=$((i-1));
+ done
+ case $words[$i] in
+ -*)
+ _arguments -s -w : \
+ "$_makepkg_shortopts[@]" \
+ "$_makepkg_longopts[@]"
+ ;;
+ --* )
+ _arguments -s \
+ "$_makepkg_longopts[@]"
+ ;;
+ - )
+ _makepkg_action_none
+ ;;
+ * )
+ return 1
+ ;;
+ esac
+ ;;
+ esac
+}
+_pacman_comp() {
+ case "$service" in
+ makepkg)
+ _makepkg "$@"
+ ;;
+ pacman-key)
+ _pacman_key "$@"
+ ;;
+ pacman)
+ _pacman_zsh_comp "$@"
+ ;;
+ *)
+ _message "Error"
+ ;;
+ esac
+}
+
+_pacman_comp "$@"