/ scripts / completion / _pkg.in
_pkg.in
  1  #compdef pkg pkg-static
  2  
  3  _pkg_cmd() {
  4  	%prefix%/sbin/pkg "${pkg_config[@]}" "$@"
  5  }
  6  
  7  _pkg_installed() {
  8  	local expl
  9  	_wanted packages expl package \
 10  		compadd "$@" - $(_call_program packages _pkg_cmd query "%n-%v")
 11  }
 12  
 13  _pkg_available_name() {
 14  	local expl scache
 15  	zstyle -t ":completion:${curcontext}:packages" remote-access || scache=1
 16  	_wanted packages expl package \
 17  		compadd "$@" - $(_call_program packages _pkg_cmd rquery ${scache:+--no-repo-update} "%n")
 18  }
 19  
 20  _pkg_aliases() {
 21  	local expl
 22  	_wanted aliases expl alias \
 23  		compadd "$@" - $(_call_program packages _pkg_cmd alias -ql)
 24  }
 25  
 26  _pkg_available() {
 27  	local ret=1 scache
 28  	_tags files packages
 29  	while _tags; do
 30  		if _requested files; then
 31  			_files "$@" -g "*.t?z" && ret=0
 32  		fi
 33  		if _requested packages; then
 34  			zstyle -t ":completion:${curcontext}:packages" remote-access || scache=1
 35  			compadd "$@" - $(_call_program packages _pkg_cmd rquery ${scache:+--no-repo-update} "%n-%v") && ret=0
 36  		fi
 37  		(( ret )) || break
 38  	done
 39  	return ret
 40  }
 41  
 42  _pkg_subcommands() {
 43  	local len full
 44  	local -a alts allmatching subcommands_f aliases_f subcommands_m aliases_m
 45  	subcommands_f=(
 46  		'add:compatibility interface to install a package'
 47  		'alias:list the command line aliases'
 48  		'annotate:add, modify or delete tag-value style annotations on packages'
 49  		'audit:report vulnerable packages'
 50  		'autoremove:remove orphaned packages'
 51  		'check:check for missing dependencies and database consistency'
 52  		'clean:clean old packages from the cache'
 53  		'config:display value of a configuration option'
 54  		'create:create software package distributions'
 55  		'delete:delete packages from the database and the system'
 56  		'fetch:fetch packages from a remote repository'
 57  		'help:display help information'
 58  		'info:display information about installed packages'
 59  		'install:install packages from remote package repositories'
 60  		'lock:lock package against modifications or deletion'
 61  		'query:query information about installed packages'
 62  		'plugins:list available plugins'
 63  		'register:register a package with the local database'
 64  		'repo:create a package repository catalogue'
 65  		'rquery:query information in repository catalogues'
 66  		'search:perform a search of package repository catalogues'
 67  		'set:modify information about packages in the local database'
 68  		'shell:open a debug shell'
 69  		'shlib:list packages that link against a specific shared library'
 70  		'stats:display package database statistics'
 71  		'unlock:unlock a package, allowing modification or deletion'
 72  		'update:update package repository catalogues'
 73  		'updating:display UPDATING information for a package'
 74  		'upgrade:perform upgrades of packaged software distributions'
 75  		'version:display versions of installed packages'
 76  		'which:display which package installed a specific file'
 77  	)
 78  	pkg_config=( -N ${(kv)opt_args[(I)-([cjoR]|config|jail|option|repo-conf-dir)]} )
 79  	aliases_f=(
 80  		"remove:synonym for 'delete'"
 81  		${${(f)"$(_call_program aliases _pkg_cmd alias -q)"}/ ##/:alias for }
 82  	)
 83  	zstyle -s ":completion:${curcontext}:" list-separator sep || sep=--
 84  	aliases_m=( ${aliases_f%%:*} )
 85  	subcommands_m=( ${subcommands_f%%:*} )
 86  	if zstyle -T ":completion:${curcontext}:" verbose; then
 87  		zstyle -T ":completion:${curcontext}:" verbose && disp=( -ld '${cmdtype}_d' )
 88  		_description '' expl '' # get applicable matchers
 89  		compadd "$expl[@]" -O allmatching -a aliases_m subcommands_m
 90  		len=${#${(O)allmatching//?/.}[1]} # length of longest match
 91  		for cmdtype in subcommands aliases; do
 92  			local -a ${cmdtype}_d
 93  			full=${cmdtype}_f
 94  			set -A ${cmdtype}_d \
 95  				${${(r.COLUMNS-4.)${(P)full}/(#s)(#m)[^:]##:/${(r.len.)MATCH[1,-2]} $sep }%% #}
 96  			alts+=( "${cmdtype}:pkg ${cmdtype%%(e|)s}:compadd ${(e)disp} -a ${cmdtype}_m" )
 97  		done
 98  	else
 99  		alts=(
100  			'commands:pkg subcommand:compadd -a subcommands_m'
101  			'aliases:pkg alias:compadd -a aliases_m'
102  		)
103  	fi
104  	_alternative "$alts[@]"
105  }
106  
107  _pkg_config_opts() {
108  	_values 'configuration option' \
109  		'ABI[ABI of package you want to install]:string' \
110  		'ALIAS[define local aliases for various pkg(8) standard command lines]:key/value list' \
111  		'AUTOCLEAN[cleanout content of cache directory after upgrades or installations]:boolean:(yes no)' \
112  		'AUTOMERGE[automatically merge configuration files]:boolean:(yes no)' \
113  		'DEFAULT_ALWAYS_YES[default to "yes" for all questions requiring user confirmation]:boolean:(yes no)' \
114  		'ASSUME_ALWAYS_YES[assume "yes" to all questions requiring user confirmation]:boolean:(yes no)' \
115  		'CONSERVATIVE_UPGRADE[give priority to repo where a package was first installed from]:boolean:(yes no)' \
116  		'CUDF_SOLVER[experimental\: use an external CUDF solver]:CUDF solver:_files' \
117  		'CASE_SENSITIVE_MATCH[case-sensitive package matching]:boolean:(yes no)' \
118  		'DEBUG_LEVEL[debugging level]:debug level:( {0..4} )' \
119  		'DEBUG_SCRIPTS[activate debug mode (set -x) for scripts]:boolean:(yes no)' \
120  		'DEVELOPER_MODE[make certain errors immediately fatal, adds warnings and suggestions]:boolean:(yes no)' \
121  		'DOT_FILE[save SAT problem to the specified dot file]:file:_files' \
122  		'EVENT_PIPE[send all event messages to specified FIFO or UNIX socket]:event pipe:_files' \
123  		'FETCH_RETRY[number of times to retry a failed fetch of a file]:number of retries' \
124  		'FETCH_TIMEOUT[time to wait for a file to download]:timeout (seconds)' \
125  		'HANDLE_RC_SCRIPTS[automatically perform start/stop of service on install/removal]:boolean:(yes no)' \
126  		'HTTP_USER_AGENT[define User-agent HTTP header to send]:user agent' \
127  		'IGNORE_OSVERSION[ignore FreeBSD OS version check]:boolean:(yes no)' \
128  		'INDEXDIR[directory to search for ports index file in]:directory:_files -/' \
129  		'INDEXFILE[ports index file]:index file:_files' \
130  		'IP_VERSION[restrict network access to specified IP version]:IP version:((0\:"system default" 4\:IPv4 6\:IPv6 ))' \
131  		'LOCK_RETRIES[number of retries to obtain a lock]:retries' \
132  		'LOCK_WAIT[wait time to regain a lock]:wait time (seconds):' \
133  		'METALOG[if set, write a METALOG of the extracted files]:string' \
134  		'NAMESERVER[hostname or IPv\[46\] address of a nameserver for DNS resolution]:name server:_hosts' \
135  		'OSVERSION[FreeBSD OS version]:version' \
136  		'PERMISSIVE[ignore conflicts while registering a package]:boolean:(yes no)' \
137  		'PKG_CACHEDIR[specify cache directory for packages]:directory:_files -/' \
138  		'PKG_CREATE_VERBOSE[make pkg_create(8) use verbose mode]:boolean:(yes no)' \
139  		'PKG_DBDIR[specify directory to use for storing package database files]:directory:_files -/' \
140  		'PKG_ENABLE_PLUGINS[activate plugin support]:boolean:(yes no)' \
141  		'PKG_ENV[key/value pair of environment variables]:key/value list' \
142  		'PKG_PLUGINS_DIR[specify directory for plugins]:directory:_files -/' \
143  		'PKG_SSH_ARGS[extra arguments for ssh(1)]:ssh(1) arguments' \
144  		'PLIST_KEYWORDS_DIR[directory containing definitions of plist keywords]:directory:_files -/' \
145  		'PLUGINS[list of plugins pkg(8) should load]:plugins' \
146  		'PLUGINS_CONF_DIR[directory containing per-plugin configurations files]:directory:_files -/' \
147  		'PORTSDIR[specify location of ports directory]:directory:_files -/' \
148  		'READ_LOCK[use read locking for query database]:boolean:(yes no)' \
149  		'REPOS_DIR[list of directories to search for repository configuration files]: : _sequence _directories' \
150  		'REPOSITORIES[repository config in pkg.conf]:value' \
151  		'REPO_AUTOUPDATE[automatically check for repo.sqlsite updates]:boolean:(yes no)' \
152  		'RUN_SCRIPTS[run pre-/post-installation action scripts]:boolean:(yes no)' \
153  		'SAT_SOLVER[experimental\: use an external SAT solver]:SAT solver:_files' \
154  		'SQLITE_PROFILE[profile SQLite queries]:boolean:(yes no)' \
155  		'SSH_RESTRICT_DIR[directory which ssh subsystem will be restricted to]:chroot:_files -/' \
156  		'SYSLOG[log install/deinstall/upgrade operations to syslog(3)]:boolean:(yes no)' \
157  		"UNSET_TIMESTAMP[don't include timestamps in package tar(1) archive]:boolean:(yes no)" \
158  		'VALID_URL_SCHEME[valid URL schemes]:list' \
159  		'VERSION_SOURCE[default database for comparing version numbers in pkg-version(8)]:database:(( I\:index P\:ports R\:remote ))' \
160  		'VULNXML_SITE[specify URL to fetch vuln.xml vulnerability database from]: : _urls -F "( gopher:* file:* ftp:* )"' \
161  		'WARN_SIZE_LIMIT[ask user when performing changes for more than this limit]:limit [1048576]' \
162  		'WORKERS_COUNT[how many workers are used for pkg-repo]:workers:( {0..$(sysctl -n hw.ncpu)} )'
163  }
164  
165  _pkg() {
166  	_arguments -s -A '-*' \
167  		'(-d --debug)'{-d,--debug}'[increment debug level]' \
168  		'(-j --jail)'{-j+,--jail=}'[execute pkg(8) inside a jail(8)]:jail:_jails' \
169  		'(-c --chroot)'{-c+,--chroot=}'[execute pkg(8) inside a chroot(8)]:chroot:_files -/' \
170  		\*{-o+,--option=}'[set configuration option]:option:_pkg_config_opts' \
171  		'(-C --config)'{-C,--config}'[use the specified configuration file]:configuration file:_files' \
172  		'(- 1 *)'{-l,--list}'[list available commands and exit]' \
173  		'(- 1 *)'{-v,--version}'[display pkg(8) version]' \
174  		'-N[test if pkg(8) is activated and avoid auto-activation]' \
175  		'(-R --repo-conf-dir)'{-R,--repo-conf-dir}'[specify directory for per-repository configuration files]: : _files' \
176  		'-4[use IPv4 for fetching repository and packages]' \
177  		'-6[use IPv6 for fetching repository and packages]' \
178  		'1:sub command:_pkg_subcommands' \
179  		'*::command:_pkg_args'
180  }
181  
182  _pkg_args() {
183  	local curcontext="$curcontext" state state_descr line expl ret=1
184  	local -a pkg_config args
185  	pkg_config=( -N ${(kv)opt_args[(I)-([cjoR]|config|jail|option|repo-conf-dir)]} )
186  	state=()
187  	service="$words[1]"
188  	curcontext="${curcontext%:*}-$service:"
189  
190  	case "$words[1]" in
191  		(add)
192  			_arguments -C -A '-*' -s \
193  				'(-A --automatic)'{-A,--automatic}'[mark the installed packages as automatic]' \
194  				'(-f --force)'{-f,--force}'[force the reinstallation of package]' \
195  				'(-I --no-scripts)'{-I,--no-scripts}'[ignore pre-/post-install scripts]' \
196  				'(-M --accept-missing)'{-M,--accept-missing}'[ignore missing dependencies when installing]' \
197  				'(-q --quiet)'{-q,--quiet}'[force quiet output]' \
198  				'*:package:->packages' && ret=0
199  
200  			if [[ $state[1] == packages ]]; then
201  				_alternative \
202  					'packages:file:_files -f "*.t?z(-.)"' \
203  					'urls: : _urls -F "( gopher:* file:* )"' && ret=0
204  			fi
205  			return ret
206  			;;
207  		(alias)
208  			_arguments -A '-*' -s \
209  				'(-l --list)'{-l,--list}'[list aliases]' \
210  				'(-q --quiet)'{-q,--quiet}'[quiet]' \
211  				'*:aliases:_pkg_aliases'
212  			return
213  			;;
214  		(annotate)
215  			_arguments -A '-*' -s \
216  				'(-a --all 1 -g --glob -C --case-sensitive -i --case-insensitive -x --regex)'{-a,--all}'[annotate all installed packages]' \
217  				'(-A --add -D --delete -M --modify -S --show)'{-A,--add}'[add a new annotation]' \
218  				'(-C --case-sensitive -i --case-insensitive)'{-C,--case-sensitive}'[match package names case-sensitively]' \
219  				'(-A --add -D --delete -M --modify -S --show 3)'{-D,--delete}'[delete an annotation]' \
220  				'(-g --glob -a --all -x --regex)'{-g,--glob}'[treat package name as a shell glob pattern]' \
221  				'(-C --case-sensitive -i --case-insensitive)'{-i,--case-insensitive}'[match package names case-sensitively]' \
222  				'(-A --add -D --delete -M --modify -S --show)'{-M,--modify}'[modify an existing annotation]' \
223  				'(-A --add -D --delete -M --modify -S --show 3)'{-S,--show}'[display an annotation]' \
224  				'(-q --quiet)'{-q,--quiet}'[limit output to confirmatory questions]' \
225  				'(-y --yes)'{-y,--yes}'[assume "yes" as the answer to all questions]' \
226  				'(-g --glob -a --all -x --regex)'{-x,--regex}'[treat package name as an extended regular expression]' \
227  				'1:package:_pkg_installed' \
228  				'2:tag' \
229  				'3:value'
230  			return
231  			;;
232  		(audit)
233  			_arguments -A '-*' -s \
234  				'(-F --fetch)'{-F,--fetch}'[fetch database before checking]' \
235  				'(-q --quiet)'{-q,--quiet}'[quiet]' \
236  				'(-r --recursive)'{-r,--recursive}'[print packages that depend on vulnerable packages]' \
237  				'(-f --file)'{-f+,--file=}'[local copy of the vulnerability database]:audit file:_files' \
238  				'*:package:_pkg_installed'
239  			return
240  			;;
241  		(autoremove)
242  			_arguments -s \
243  				'(-q --quiet)'{-q,--quiet}'[force quiet output]' \
244  				'(-y --yes -n --dry-run)'{-y,--yes}'[assume yes when asked for confirmation]' \
245  				'(-y --yes -n --dry-run)'{-n,--dry-run}'[assume no (dry run) when asked for confirmation]'
246  			return
247  			;;
248  		(check)
249  			_arguments -A '-*' -s \
250  				'(-B --shlibs)'{-B,--shlibs}'[reanalyze the shared libraries]' \
251  				'(-d --dependencies)'{-d,--dependencies}'[check for and install missing dependencies]' \
252  				'(-r --recompute)'{-r,--recompute}'[recompute sizes and checksums of installed packages]' \
253  				'(-s --checksums)'{-s,--checksums}'[find invalid checksums]' \
254  				'(-v --verbose)'{-v,--verbose}'[be verbose]' \
255  				'(-n --dry-run)'{-n,--dry-run}"[check for missing dependencies but don't install them]" \
256  				'(-y --yes)'{-y,--yes}'[assume yes for confirmations]' \
257  				'(-q --quiet)'{-q,--quiet}'[force quiet output]' \
258  				- '(all)' \
259  				{-a,--all}'[process all packages]' \
260  				- 'patterns' \
261  				'(-a --all -i --case-insensitive -C --case-sensitive)'{-i,--case-insensitive}'[case insensitive pattern matching]' \
262  				'(-a --all -i --case-insensitive -C --case-sensitive)'{-C,--case-sensitive}'[case sensitive pattern matching]' \
263  				'(-g --glob -x --regex)'{-x,--regex}'[process packages that match the regex pattern]' \
264  				'(-g --glob -x --regex)'{-g,--glob}'[process packages that match the glob pattern]' \
265  				'*:available package:_pkg_installed'
266  			return
267  			;;
268  		(clean)
269  			_arguments -s \
270  				'(-a --all)'{-a,--all}'[delete all packages]' \
271  				'(-n --dry-run)'{-n,--dry-run}'[show what packages would be removed]' \
272  				'(-q --quiet)'{-q,--quiet}'[force quiet output]' \
273  				'(-y --yes)'{-y,--yes}'[assume yes for confirmations]'
274  			return
275  			;;
276  		(create)
277  			_arguments -A '-*' -s \
278  				'(-q --quiet)'{-q,--quiet}'[force quiet output]' \
279  				'(-v --verbose)'{-v,--verbose}'[be verbose]' \
280  				'(-n --no-clobber)'{-n,--no-clobber}"[don't overwrite existing packages]" \
281  				'(-f --format)'{-f+,--format=}'[specify package output format]:format:(tar tgz tbz txz tzst)' \
282  				'(-l --level)'{-l+,--level=}'[specify compression level]:level:(integer fast best)' \
283  				'(-o --out-dir)'{-o+,--out-dir=}'[output directory]:outdir:_files -/' \
284  				'(-r --root-dir)'{-r+,--root-dir=}'[specify root directory]:rootdir:_files -/' \
285  				- '(manifest)' \
286  				{-M+,--manifest=}'[specify manifest file]:manifest file:_files' \
287  				- metadata \
288  				'(-m --metadata)'{-m+,--metadata=}'[specify manifest directory]:manifestdir:_files -/' \
289  				'(-p --plist)'{-p+,--plist=}'[specify package metadata using the legacy plist format]:plist' \
290  				- '(all)' \
291  				{-a,--all}'[process all packages]' \
292  				- patterns \
293  				'(-g --glob -x --regex)'{-g,--glob}'[process packages that match a glob pattern]' \
294  				'(-g --glob -x --regex)'{-x,--regex}'[process packages that match a regex pattern]' \
295  				'*:package:_pkg_installed'
296  			return
297  			;;
298  		(delete|remove)
299  			_arguments -A '-*' -s \
300  				'(-q --quiet)'{-q,--quiet}'[force quiet output]' \
301  				'(-n --dry-run -y --yes)'{-y,--yes}'[assume yes when asked for confirmation]' \
302  				'(-y --yes -n --dry-run)'{-n,--dry-run}'[assume no (dry run) when asked for confirmation]' \
303  				'(-f --force)'{-f,--force}'[force the package(s) to be removed]' \
304  				'(-D --no-scripts)'{-D,--no-scripts}"[don't execute deinstallation scripts]" \
305  				'(-R --recursive)'{-R,--recursive}'[delete all packages that require the list packages as well]' \
306  				- '(all)' \
307  				{-a,--all}'[process all packages]' \
308  				- patterns \
309  				'(-i --case-insensitive -C --case-sensitive)'{-i,--case-insensitive}'[case insensitive pattern matching]' \
310  				'(-i --case-insensitive -C --case-sensitive)'{-C,--case-sensitive}'[case sensitive pattern matching]' \
311  				'(-g --glob -x --regex)'{-g,--glob}'[process packages that match a glob pattern]' \
312  				'(-g --glob -x --regex)'{-x,--regex}'[process packages that match a regex pattern]' \
313  				'*:package:_pkg_installed'
314  			return
315  			;;
316  		(fetch)
317  			_arguments -A '-*' -s \
318  				'(-y --yes)'{-y,--yes}'[assume yes when asked for confirmation]' \
319  				'(-r --repository)'{-r+,--repository=}'[specify the repository to fetch from]:repository:->repositories' \
320  				'(-q --quiet)'{-q,--quiet}'[force quiet output]' \
321  				'(-o --output)'{-o+,--output=}'[place files in a subdirectory named `All'\'' of the specified directory]: : _files -/' \
322  				'(-d --dependencies)'{-d,--dependencies}'[fetch dependencies as well]' \
323  				'(-U --no-repo-update)'{-U,--no-repo-update}'[suppress the automatic update of the repo catalogue]' \
324  				- '(all)' \
325  				'(-i --case-insensitive -C --case-sensitive)'{-a,--all}'[process all packages]' \
326  				- patterns \
327  				'(-i --case-insensitive -C --case-sensitive)'{-i,--case-insensitive}'[case insensitive pattern matching]' \
328  				'(-i --case-insensitive -C --case-sensitive)'{-C,--case-sensitive}'[case sensitive pattern matching]' \
329  				'(-g --glob -x --regex)'{-g,--glob}'[process packages that match a glob pattern]' \
330  				'(-g --glob -x --regex)'{-x,--regex}'[process packages that match a regex pattern]' \
331  				'*:available package:_pkg_available' \
332  				- '(updates)' \
333  				{-u,--available-updates}'[fetch all available updates for currently installed packages]' && ret=0
334  			;;
335  		(help)
336  			_wanted commands expl 'pkg subcommand' compadd - ${(f)"$(_call_program commands _pkg_cmd -l)"}
337  			return
338  			;;
339  		(info)
340  			local mutexopts='(-e --exists -d --dependencies -r --required-by -l --list-files -I --comment'
341  			mutexopts+=' -R --raw -o --origin -O --by-origin -p --prefix -D --pkg-message -f --full)'
342  			_arguments -A '-*' -s \
343  				'(-A --annotations)'{-A,--annotations}'[display any annotations added to the package]' \
344  				'(-q --quiet)'{-q,--quiet}'[force quiet output]' \
345  				'--raw-format=[output format for raw output]:format:(json json-compact yaml)' \
346  				'(-f --full)'{-f,--full}'[display full information]' \
347  				${mutexopts}{-e,--exists}'[return 0 if specified package is installed]' \
348  				${mutexopts}{-R,--raw}'[display the full manifest]' \
349  				'(-d --dependencies)'{-d,--dependencies}'[display the dependencies]' \
350  				'(-r --required-by)'{-r,--required-by}'[display the reverse dependencies]' \
351  				'(-l --list-files)'{-l,--list-files}'[display all files]' \
352  				'(-o --origin -O --by-origin)'{-o,--origin,-O,--by-origin}'[display origin]' \
353  				'(-p --prefix)'{-p,--prefix}'[display prefix]' \
354  				'(-D --pkg-message)'{-D,--pkg-message}'[display message]' \
355  				'(-k --locked)'{-k,--locked}'[show the locking status]' \
356  				'(-I --comment)'{-I,--comment}'[display comments]' \
357  				'(-b --provided-shlibs)'{-b,--provided-shlibs}'[display shared libraries provided by the package]' \
358  				'(-B --required-shlibs)'{-B,--required-shlibs}'[display all shared libraries used by the package]' \
359  				'(-s --size)'{-s,--size}'[display the total size of the files installed by the package]' \
360  				- '(all)' \
361  				{-a,--all}'[process all packages]' \
362  				- '(pkg-file)' \
363  				{-F+,--file=}'[display information from an package archive]:package:_files' \
364  				- patterns \
365  				'(-i --case-insensitive -C --case-sensitive)'{-i,--case-insensitive}'[case insensitive pattern matching]' \
366  				'(-i --case-insensitive -C --case-sensitive)'{-C,--case-sensitive}'[case sensitive pattern matching]' \
367  				'(-g --glob -x --regex)'{-g,--glob}'[process packages that match a glob pattern]' \
368  				'(-g --glob -x --regex)'{-x,--regex}'[process packages that match a regex pattern]' \
369  				'*:available package:_pkg_installed'
370  			return
371  			;;
372  		(install)
373  			_arguments -A '-*' -s \
374  				'(-A --automatic)'{-A,--automatic}'[mark the installed packages as automatic]' \
375  				'(-r --repository)'{-r+,--repository=}'[specify the repository to install packages from]:repository:->repositories' \
376  				'(-U --no-repo-update)'{-U,--no-repo-update}'[suppress the automatic update of the repo catalogue]' \
377  				'(-I --no-scripts)'{-I,--no-scripts}"[don't execute any pre/post-install scripts]" \
378  				'(-M --ignore-missing)'{-M,--ignore-missing}'[ignore missing dependencies]' \
379  				'(-n --dry-run -y --yes)'{-y,--yes}'[assume yes when asked for confirmation]' \
380  				'(-y --yes -n --dry-run)'{-n,--dry-run}'[assume no (dry run) when asked for confirmation]' \
381  				'(-f --force)'{-f,--force}'[force reinstallation if needed]' \
382  				'(-F --fetch-only)'{-F,--fetch-only}"[don't perform actual installation of packages]" \
383  				'(-q --quiet)'{-q,--quiet}'[quiet output]' \
384  				'(-R --recursive)'{-R,--recursive}'[reinstall every package depending on matching expressions]' \
385  				- '(all)' \
386  				{-a,--all}'[process all packages]' \
387  				- patterns \
388  				'(-i --case-insensitive -C --case-sensitive)'{-i,--case-insensitive}'[case insensitive pattern matching]' \
389  				'(-i --case-insensitive -C --case-sensitive)'{-C,--case-sensitive}'[case sensitive pattern matching]' \
390  				'(-g --glob -x --regex)'{-g,--glob}'[process packages that match a glob pattern]' \
391  				'(-g --glob -x --regex)'{-x,--regex}'[process packages that match a regex pattern]' \
392  				'*:available package:_pkg_available' && ret=0
393  			;;
394  		(lock)
395  			args=( '--has-locked-packages[return 0 if at least one package is locked]' )
396  			;&
397  		(unlock)
398  			_arguments -A '-*' -s $args \
399  				'(-l --show-locked)'{-l,--show-locked}'[show a list of all locked packages]' \
400  				'(-y --yes)'{-y,--yes}'[assume yes when asked for confirmation]' \
401  				'(-y --yes -n --dry-run)'{-n,--dry-run}'[assume no (dry run) when asked for confirmation]' \
402  				'(-q --quiet)'{-q,--quiet}'[quiet output]' \
403  				- '(all)' \
404  				{-a,--all}'[process all packages]' \
405  				- patterns \
406  				'(-i --case-insensitive -C --case-sensitive)'{-i,--case-insensitive}'[case insensitive pattern matching]' \
407  				'(-i --case-insensitive -C --case-sensitive)'{-C,--case-sensitive}'[case sensitive pattern matching]' \
408  				'(-g --glob -x --regex)'{-g,--glob}'[process packages that match a glob pattern]' \
409  				'(-g --glob -x --regex)'{-x,--regex}'[process packages that match a regex pattern]' \
410  				'*:available package:_pkg_installed'
411  			return
412  			;;
413  		(plugins)
414  			_arguments -A '-*' '-l' '*:plugin'
415  			return
416  			;;
417  		(query)
418  			_arguments -C -s \
419  				'(-)1:output format:->query' \
420  				- '(all)' \
421  				{-a,--all}'[process all packages]' \
422  				- 'patterns' \
423  				'(-i --case-insensitive -C --case-sensitive)'{-C,--case-sensitive}'[case sensitive pattern matching]' \
424  				'(-i --case-insensitive -C --case-sensitive)'{-i,--case-insensitive}'[case insensitive pattern matching]' \
425  				'(-g --glob -x --regex)'{-g,--glob}'[process packages that match a glob pattern]' \
426  				'(-g --glob -x --regex)'{-x,--regex}'[process packages that match a regex pattern]' \
427  				'*:package:_pkg_installed' \
428  				- '(eval)' \
429  				{-e+,--evaluate=}'[process packages that match an evaluation]:evaluation:->evaluation' \
430  				- '(files)' \
431  				{-F,--file}'[process the specified package]:package:_files -g "*.t?z(-.)"' \
432  				&& ret=0
433  			;;
434  		(register)
435  			_arguments -A '-*' -s \
436  				'(-A --automatic)'{-A,--automatic}'[mark the package to be automatically removed if no other packages depend on it]' \
437  				'(-l --legacy)'{-l,--legacy}'[register as a legacy format]' \
438  				'(-d --debug)'{-d,--debug}'[mark the package as an automatic dependency]' \
439  				'(-t --test)'{-t,--test}'[enable testing mode]' \
440  				- metadatadir \
441  				'(-f --plist)'{-f+,--plist=}'[packing list file]:packing list file:_files' \
442  				'(-m --metadata)'{-m+,--metadata=}'[metadata directory]:metadatadir:_files -/' \
443  				'(-i --root)'{-i+,--root=}'[input path (aka root directory)]:input path:_files -/' \
444  				- 'metadatafile' \
445  				'!--relocate=:alternate root:_directories' \
446  				'(-M --manifest)'{-M+,--manifest=}'[specify package manifest file]:manifest file:_files'
447  			return
448  			;;
449  		(repo)
450  			_arguments -A '-*' -s \
451  				'(-h --hash)'{-h,--hash}'[Rename repo files with a short hash appeneded]' \
452  				'(-l --list-files)'{-l,--list-files}'[generate list of all files in repo as filesite.txz archive]' \
453  				'(-q --quiet)'{-q,--quiet}'[force quiet output]' \
454  				'(-o --output-dir)'{-o+,--output-dir=}'[specify the location of the new repo]:repo location:_files -/' \
455  				'(-m --meta-file)'{-m+,--meta-file=}'[use specified file as repository meta file instead of the defaults]:meta file:_files' \
456  				'(-s --symlink)'{-s,--symlink}'[Create a symlink between the hashed and regular filename]' \
457  				':repository path:_files -/' \
458  				':RSA key: _alternative "files\:RSA key\:_files" "commands\:commands\:_cmdstring"'
459  			return
460  			;;
461  		(rquery)
462  			_arguments -A '-*' -C -s \
463  				'(-U --no-repo-update)'{-U,--no-repo-update}'[suppress the automatic update of the repo catalogue]' \
464  				'(-r --repository)'{-r+,--repository=}'[specify the repository to search]:repository:->repositories' \
465  				'(-I --index-line)'{-I,--index-line}'[print corresponding line from ports index file]' \
466  				${words[(r)(-I|--index-line)]+!}':output format:->query' \
467  				- '(all)' \
468  				{-a,--all}'[process all packages]' \
469  				- 'patterns' \
470  				'(-i --case-insensitive -C --case-sensitive)'{-C,--case-sensitive}'[case sensitive pattern matching]' \
471  				'(-i --case-insensitive -C --case-sensitive)'{-i,--case-insensitive}'[case insensitive pattern matching]' \
472  				'(-g --glob -x --regex)'{-g,--glob}'[process packages that match the glob pattern]' \
473  				'(-g --glob -x --regex)'{-x,--regex}'[process packages that match a regex pattern]' \
474  				'*:available package:_pkg_available_name' \
475  				- '(eval)' \
476  				{-e+,--evaluate=}'[process packages that match an evaluation]:evaluation:->evaluation' \
477  				&& ret=0
478  			;;
479  		(search)
480  			local -a label_opts modifier_opts
481  			label_opts=(comment description name origin pkg-name)
482  			modifier_opts=(
483  			annotations arch categories comment depends-on description full
484  			licenses maintainer name options pkg-size prefix repository
485  			required-by shared-libs-{required,provided} size url version www
486  			)
487  			_arguments -A '-*' -s \
488  				'(-x --regex -g --glob -e --exact)'{-g,--glob}'[process packages that match the glob pattern]' \
489  				'(-x --regex -g --glob -e --exact)'{-x,--regex}'[process packages that match the regex pattern]' \
490  				'(-x --regex -g --glob -e --exact)'{-e,--exact}'[process packages that match the string exactly]' \
491  				'(-i --case-insensitive -C --case-sensitive)'{-C,--case-sensitive}'[case sensitive pattern matching]' \
492  				'(-i --case-insensitive -C --case-sensitive)'{-i,--case-insensitive}'[case insensitive pattern matching]' \
493  				'(-U --no-repo-update)'{-U,--no-repo-update}'[suppress the automatic update of the repo catalogue]' \
494  				'(-r --repository)'{-r+,--repository=}'[specify the repository to search]:repository:->repositories' \
495  				'1:available package:_pkg_available_name' \
496  				- set1 \
497  				'(-L --label)'{-L+,--label=}'[select which identifying label is printed for each matched package]:field:( $label_opts )' \
498  				'(-S --search)'{-S+,--search=}'[specify the field to search the repository catalogue on]:field:( $label_opts )' \
499  				\*{-Q+,--query-modifier=}'[add an additional field to the result]:modifier:( $modifier_opts )' \
500  				- set2 \
501  				'(-D --description -c --comment)'{-c,--comment}'[use pattern matching on comments text]' \
502  				'(-D --description -c --comment)'{-D,--description}'[use pattern matching on description text]' \
503  				'(-d --depends-on)'{-d,--depends-on}'[list dependencies of the matched packages]' \
504  				'(-f --full)'{-f,--full}"[show \`\`full'' information about the package]" \
505  				'(-o --origins)'{-o,--origins}'[list packages by origins]' \
506  				'(-p --prefix)'{-p,--prefix}'[display package installation prefix]' \
507  				'(-q --quiet)'{-q,--quiet}'[be quiet]' \
508  				'(-R --raw)'{-R,--raw}'[display full manifest]' \
509  				'(-s --size)'{-s,--size}'[display the installed size]' \
510  				'--raw-format=[output format for raw output]:format:(json json-compact yaml)' && ret=0
511  			;;
512  		(set)
513  			local mutexopts='(-o --change-origin -A --automatic -n --change-name)'
514  			_arguments -A '-*' -s \
515  				${mutexopts}{-A+,--automatic=}'[mark as automatic or not]:flag:((1\:automatic 0\:not\ automatic))' \
516  				'-v+[mark as vital or not]:flag:((1\:vital 0\:not\ vital))' \
517  				${mutexopts}{-o+,--change-origin=}'[change the origin]:oldorigin\:neworigin' \
518  				${mutexopts}{-n+,--change-name=}'[change the name]:oldname\:newname' \
519  				'(-y --yes)'{-y,--yes}'[assume yes when asked for confirmation]' \
520  				- '(all)' \
521  				{-a,--all}'[process all packages]' \
522  				- '(patterns)' \
523  				'(-i --case-insensitive -C --case-sensitive)'{-C,--case-sensitive}'[case sensitive pattern matching]' \
524  				'(-i --case-insensitive -C --case-sensitive)'{-i,--case-insensitive}'[case insensitive pattern matching]' \
525  				'(-g --glob -x --regex)'{-g,--glob}'[process packages that match the glob pattern]' \
526  				'(-g --glob -x --regex)'{-x,--regex}'[process packages that match the regex pattern]' \
527  				'*:package:_pkg_installed'
528  			return
529  			;;
530  		(shell)
531  			_arguments -s \
532  				':database:_files'
533  			return
534  			;;
535  		(shlib)
536  			_arguments -A '-*' -s \
537  				'(-q --quiet)'{-q,--quiet}'[force quiet output]' \
538  				'(-P --provides)'{-P,--provides}'[show the package which provides the library]' \
539  				'(-R --requires)'{-R,--requires}'[show installed packages which requires the library]' \
540  				':library:'
541  			return
542  			;;
543  		(stats)
544  			_arguments -A '-*' -s \
545  				'(-q --quiet)'{-q,--quiet}'[be quiet]' \
546  				- '(remote)' \
547  				{-r,--remote}'[display stats only for the remote package database]' \
548  				- '(local)' \
549  				{-l,--local}'[display stats only for the local package database(s)]' \
550  				- '(size)' \
551  				{-b,--bytes}'[display space usage, in bytes]'
552  			return
553  			;;
554  		(update)
555  			_arguments -A '-*' -s \
556  				'(-f --force)'{-f,--force}'[force update]' \
557  				'(-q --quiet)'{-q,--quiet}'[be quiet]' \
558  				'(-r --repository)'{-r+,--repository=}'[specify the repository to update from]:repository:->repositories' && ret=0
559  			;;
560  		(updating)
561  			# recall dates starting the from the beginning of this month.
562  			# zstyle ':completion:*:*:pkg-updating:option-(d|-date)-1:*' fake ${(%):-"%D{%Y%m}"}{01..${(%):-"%D{%d}"}}
563  			_arguments -A '-*' -s \
564  				'(-d --date)'{-d+,--date=}'[only entries newer than date are shown]:date' \
565  				'(-f --file)'{-f+,--file=}'[specify alternative location of the UPDATING file]:UPDATING file:_files' \
566  				'(-i --case-insensitive)'{-i,--case-insensitive}'[case insensitive pattern matching]' \
567  				'*:package:_pkg_installed'
568  			return
569  			;;
570  		(upgrade)
571  			_arguments -A '-*' -s \
572  				"(-F --fetch-only)"{-F,--fetch-only}"[don't install packages, merely fetch them]" \
573  				'(-y --yes -n --dry-run)'{-n,--dry-run}'[assume no (dry run) when asked for confirmation]' \
574  				'(-n --dry-run -y --yes)'{-y,--yes}'[assume yes when asked for confirmation]' \
575  				'(-f --force)'{-f,--force}'[upgrade/reinstall everything]' \
576  				'(-i --case-insensitive -C --case-sensitive)'{-C,--case-sensitive}'[case sensitive pattern matching]' \
577  				'(-i --case-insensitive -C --case-sensitive)'{-i,--case-insensitive}'[case insensitive pattern matching]' \
578  				'(-U --no-repo-update)'{-U,--no-repo-update}'[suppress the automatic update of the repo catalogue]' \
579  				'(-I --no-scripts)'{-I,--no-scripts}"[don't execute any pre/post-install scripts]" \
580  				'(-q --quiet)'{-q,--quiet}'[be quiet]' \
581  				'(-r --repository)'{-r+,--repository=}'[specify the repository to upgrade from]:repository:->repositories' \
582  				'(-g --glob -x --regex)'{-g,--glob}'[process packages that match a glob pattern]' \
583  				'(-g --glob -x --regex)'{-x,--regex}'[process packages that match a regex pattern]' \
584  				'*:available package:_pkg_installed' && ret=0
585  			;;
586  		(version)
587  			_arguments -A '-*' -s \
588  				- '(testversion)' \
589  				{-t+,--test-version=}'[test a pair of version number strings]: : _message -e values "version string": : _message -e values "version string"' \
590  				- '(testpattern)' \
591  				{-T+,--test-pattern=}'[compare pkgname against a shell glob pattern]:package:_pkg_installed: : _message -e values glob' \
592  				- other \
593  				'(-r --repository -P --ports -R --remote -I --index)'{-I,--index}'[use INDEX file]' \
594  				'(-r --repository -P --ports -R --remote -I --index)'{-P,--ports}'[force checking against the ports tree]' \
595  				'(-P --ports -R --remote -I --index)'{-R,--remote}'[use remote repository]' \
596  				'(-o --origin)'{-o,--origin}'[display package origin, instead of package name]' \
597  				'(-q --quiet)'{-q,--quiet}'[be quiet]' \
598  				'(-v --verbose)'{-v,--verbose}'[be verbose]' \
599  				${words[(r)(-*[PI]*|--(index|ports))]+!}'(-r --repository)'{-r+,--repository=}'[specify the repository to ]:repository:->repositories' \
600  				'(-U --no-repo-update)'{-U,--no-repo-update}'[suppress the automatic update of the repo catalogue]' \
601  				'(-L --not-like -l --like)'{-l+,--like=}'[display only the packages with a given status flag]:flag:((\< = \>))' \
602  				'(-l --like -L --not-like)'{-L+,--not-like=}'[display only the packages without a given status flag]:flag:((\< = \>))' \
603  				'(-O --match-origin)'{-M+,--match-origin=}'[display only packages matching specified origin]:origin' \
604  				'(-n --match-name)'{-M+,--match-name=}'[display only packages matching specified name]:name' \
605  				'(-i --case-insensitive -C --case-sensitive)'{-C,--case-sensitive}'[case sensitive pattern matching]' \
606  				'(-i --case-insensitive -C --case-sensitive)'{-i,--case-insensitive}'[case insensitive pattern matching]' \
607  				'(-x --regex -g --glob -e --exact)'{-g+,--glob=}'[display packages that match the glob pattern]:glob pattern' \
608  				'(-x --regex -g --glob -e --exact)'{-x+,--regex=}'[display packages that match the regex pattern]:regex pattern' \
609  				'(-x --regex -g --glob -e --exact)'{-e+,--exact=}'[display the packages that exactly match the string]:string' && ret=0
610  			;;
611  		(which)
612  			_arguments -A '-*' -s \
613  				'(-q --quiet)'{-q,--quiet}'[be quiet]' \
614  				'(-o --origin)'{-o,--origin}'[display origin]' \
615  				':file:_files' \
616  				- '(glob)' \
617  				{-g,--glob}'[treat filename as a glob pattern]' \
618  				{-m,--show-match}'[show files that match the glob pattern (requires -g)]' \
619  				- '(PATH)' \
620  				{-p,--path-search}'[search for the filename in PATH]'
621  			return
622  			;;
623  		(*)
624  			# expand aliases, avoid recursing multiple times if aliases are recursive
625  			if [[ $funcstack[2] != _pkg_args ]] && line="$(_call_program pkg-alias _pkg_cmd alias "$words[1]")"; then
626  				(( CURRENT -= $#words ))
627  				words[1]=( ${=${line#*\'}%\'} )
628  				(( CURRENT += $#words ))
629  				_pkg_args
630  			else
631  				# fallback to default completion for an unknown command
632  				_default
633  			fi
634  			return
635  			;;
636  	esac
637  
638  	[[ -z $state ]] && return ret
639  	if [[ $state = repositories ]]; then
640  		local -U repos
641  		repos=( $(_call_program repositories _pkg_cmd query '%R') )
642  		_wanted -x repositories expl repository compadd -a repos
643  		return
644  	fi
645  	local -a specs elements
646  	elements=(
647  		'd:dependencies' 'r:reverse dependencies' 'C:categories'
648  		'O:options' 'L:licenses' 'A:annotations'
649  		'B:required share libraries' 'b:provided shared libraries'
650  	)
651  	specs=(
652  		'n:package name' 'o:origin' 'p:prefix' 'm:maintainer'
653  		'c:comment' 'e:description' 'w:home page' 's:size'
654  		'Q:alternative architecture' 'q:architecture' 'M:message'
655  		'?:if info exists' '#:no of elements'
656  	)
657  	if [[ $service = query ]]; then
658  		specs+=( 'a:automatic' 'k:locked' 't:timestamp' 'V:vital' )
659  		elements+=( 'F:files' 'D:directories'  'U:users' 'G:groups' )
660  	fi
661  	if [[ $state = query ]]; then
662  		specs+=( 'v:version' 'l:license' 'R:repository' )
663  		compset -P '(%[^sOFdrA?#]|%?[^%]|[^%])#'
664  	else
665  		compset -P '(%[^OFdrA?#]|%?[^%]|[^%])#'
666  	fi
667  	if compset -P '%s'; then
668  		_describe -t units unit '( b:bytes h:human\ readable )' -S '' && ret=0
669  	elif compset -P '%F'; then
670  		_describe -t properties property '( p:path s:sum )' -S '' && ret=0
671  	elif compset -P '%O'; then
672  		_describe -t properties property '( k:key v:value d:default D:description )' -S '' && ret=0
673  	elif compset -P '%[dr]'; then
674  		_describe -t properties 'dependency property' '( n:name o:origin v:version )' -S '' && ret=0
675  	elif compset -P '%A'; then
676  		_describe -t properties property '( t:tag s:value )' -S '' && ret=0
677  	elif compset -P '%(|\\)[?#]'; then
678  		_describe -t lists list elements -S '' && ret=0
679  	else
680  		[[ $IPREFIX = *%(#b)([${(j..)elements%%:*}])* ]] &&
681  			elements=( ${(M)elements:#$match[1]:*} )
682  		if [[ $state = evaluation ]]; then
683  			_tags variables operators
684  		else
685  			_tags patterns elements
686  		fi
687  		while _tags; do
688  			_requested elements && _describe -t elements 'list element' elements -p % -S '' && ret=0
689  			_requested variables && _describe -t variables 'variable' specs -p % -S '' && ret=0
690  			_requested patterns && _describe -t patterns 'query specifier' specs -p % -S '' && ret=0
691  			_requested operators expl operator compadd -S '' \~ {,\!,\>,\<}= \> \< \&\& \|\| && ret=0
692  			(( ret )) || break
693  		done
694  	fi
695  	return ret
696  }
697  
698  _pkg "$@"