| 
									
										
										
										
											2012-11-01 21:41:07 -03:00
										 |  |  | #compdef pass | 
					
						
							|  |  |  | #autoload | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-07-26 23:23:13 +02:00
										 |  |  | # Copyright (C) 2012 - 2014: | 
					
						
							| 
									
										
										
										
											2012-11-01 21:41:07 -03:00
										 |  |  | #    Johan Venant <jvenant@invicem.pro> | 
					
						
							|  |  |  | #    Brian Mattern <rephorm@rephorm.com> | 
					
						
							| 
									
										
										
										
											2014-07-26 23:23:13 +02:00
										 |  |  | #    Jason A. Donenfeld <Jason@zx2c4.com>. | 
					
						
							| 
									
										
										
										
											2012-11-01 21:41:07 -03:00
										 |  |  | # All Rights Reserved. | 
					
						
							| 
									
										
										
										
											2012-12-08 15:31:13 -03:00
										 |  |  | # This file is licensed under the GPLv2+. | 
					
						
							| 
									
										
										
										
											2018-08-07 20:42:02 +02:00
										 |  |  | # Please visit https://git.zx2c4.com/password-store/tree/COPYING for more information. | 
					
						
							| 
									
										
										
										
											2018-08-09 20:17:43 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | # If you use multiple repositories, you can configure completion like this: | 
					
						
							| 
									
										
										
										
											2012-12-08 15:31:13 -03:00
										 |  |  | # | 
					
						
							| 
									
										
										
										
											2018-08-09 20:17:43 +02:00
										 |  |  | # compdef _pass workpass | 
					
						
							|  |  |  | # zstyle ':completion::complete:workpass::' prefix "$HOME/work/pass" | 
					
						
							|  |  |  | # workpass() { | 
					
						
							|  |  |  | #   PASSWORD_STORE_DIR=$HOME/work/pass pass $@ | 
					
						
							|  |  |  | # } | 
					
						
							| 
									
										
										
										
											2012-11-01 21:41:07 -03:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | _pass () { | 
					
						
							|  |  |  | 	local cmd | 
					
						
							|  |  |  | 	if (( CURRENT > 2)); then | 
					
						
							|  |  |  | 		cmd=${words[2]} | 
					
						
							|  |  |  | 		# Set the context for the subcommand. | 
					
						
							|  |  |  | 		curcontext="${curcontext%:*:*}:pass-$cmd" | 
					
						
							|  |  |  | 		# Narrow the range of words we are looking at to exclude `pass' | 
					
						
							|  |  |  | 		(( CURRENT-- )) | 
					
						
							|  |  |  | 		shift words | 
					
						
							|  |  |  | 		# Run the completion for the subcommand | 
					
						
							|  |  |  | 		case "${cmd}" in | 
					
						
							|  |  |  | 			init) | 
					
						
							|  |  |  | 				_arguments : \ | 
					
						
							| 
									
										
										
										
											2014-07-26 23:23:13 +02:00
										 |  |  | 					"-p[gpg-id will only be applied to this subfolder]" \ | 
					
						
							|  |  |  | 					"--path[gpg-id will only be applied to this subfolder]" | 
					
						
							| 
									
										
										
										
											2012-11-01 21:41:07 -03:00
										 |  |  | 				_pass_complete_keys | 
					
						
							|  |  |  | 				;; | 
					
						
							|  |  |  | 			ls|list|edit) | 
					
						
							|  |  |  | 				_pass_complete_entries_with_subdirs | 
					
						
							|  |  |  | 				;; | 
					
						
							|  |  |  | 			insert) | 
					
						
							|  |  |  | 				_arguments : \ | 
					
						
							|  |  |  | 					"-e[echo password to console]" \ | 
					
						
							|  |  |  | 					"--echo[echo password to console]" \ | 
					
						
							|  |  |  | 					"-m[multiline]" \ | 
					
						
							|  |  |  | 					"--multiline[multiline]" | 
					
						
							|  |  |  | 				_pass_complete_entries_with_subdirs | 
					
						
							|  |  |  | 				;; | 
					
						
							|  |  |  | 			generate) | 
					
						
							|  |  |  | 				_arguments : \ | 
					
						
							|  |  |  | 					"-n[don't include symbols in password]" \ | 
					
						
							|  |  |  | 					"--no-symbols[don't include symbols in password]" \ | 
					
						
							|  |  |  | 					"-c[copy password to the clipboard]" \ | 
					
						
							| 
									
										
										
										
											2014-07-26 23:23:13 +02:00
										 |  |  | 					"--clip[copy password to the clipboard]" \ | 
					
						
							|  |  |  | 					"-f[force overwrite]" \ | 
					
						
							|  |  |  | 					"--force[force overwrite]" \ | 
					
						
							|  |  |  | 					"-i[replace first line]" \ | 
					
						
							|  |  |  | 					"--in-place[replace first line]" | 
					
						
							| 
									
										
										
										
											2012-11-01 21:41:07 -03:00
										 |  |  | 				_pass_complete_entries_with_subdirs | 
					
						
							|  |  |  | 				;; | 
					
						
							| 
									
										
										
										
											2014-07-26 23:23:13 +02:00
										 |  |  | 			cp|copy|mv|rename) | 
					
						
							|  |  |  | 				_arguments : \ | 
					
						
							|  |  |  | 					"-f[force rename]" \ | 
					
						
							|  |  |  | 					"--force[force rename]" | 
					
						
							|  |  |  | 					_pass_complete_entries_with_subdirs | 
					
						
							|  |  |  | 				;; | 
					
						
							| 
									
										
										
										
											2012-11-01 21:41:07 -03:00
										 |  |  | 			rm) | 
					
						
							|  |  |  | 				_arguments : \ | 
					
						
							|  |  |  | 					"-f[force deletion]" \ | 
					
						
							|  |  |  | 					"--force[force deletion]" \ | 
					
						
							|  |  |  | 					"-r[recursively delete]" \ | 
					
						
							|  |  |  | 					"--recursive[recursively delete]" | 
					
						
							|  |  |  | 					_pass_complete_entries_with_subdirs | 
					
						
							|  |  |  | 				;; | 
					
						
							|  |  |  | 			git) | 
					
						
							|  |  |  | 				local -a subcommands | 
					
						
							|  |  |  | 				subcommands=( | 
					
						
							|  |  |  | 					"init:Initialize git repository" | 
					
						
							|  |  |  | 					"push:Push to remote repository" | 
					
						
							|  |  |  | 					"pull:Pull from remote repository" | 
					
						
							|  |  |  | 					"config:Show git config" | 
					
						
							|  |  |  | 					"log:Show git log" | 
					
						
							|  |  |  | 					"reflog:Show git reflog" | 
					
						
							|  |  |  | 				) | 
					
						
							|  |  |  | 				_describe -t commands 'pass git' subcommands | 
					
						
							|  |  |  | 				;; | 
					
						
							|  |  |  | 			show|*) | 
					
						
							|  |  |  | 				_pass_cmd_show | 
					
						
							|  |  |  | 				;; | 
					
						
							|  |  |  | 		esac | 
					
						
							|  |  |  | 	else | 
					
						
							|  |  |  | 		local -a subcommands | 
					
						
							|  |  |  | 		subcommands=( | 
					
						
							|  |  |  | 			"init:Initialize new password storage" | 
					
						
							|  |  |  | 			"ls:List passwords" | 
					
						
							| 
									
										
										
										
											2014-07-26 23:23:13 +02:00
										 |  |  | 			"find:Find password files or directories based on pattern" | 
					
						
							|  |  |  | 			"grep:Search inside decrypted password files for matching pattern" | 
					
						
							| 
									
										
										
										
											2012-11-01 21:41:07 -03:00
										 |  |  | 			"show:Decrypt and print a password" | 
					
						
							|  |  |  | 			"insert:Insert a new password" | 
					
						
							|  |  |  | 			"generate:Generate a new password using pwgen" | 
					
						
							|  |  |  | 			"edit:Edit a password with \$EDITOR" | 
					
						
							| 
									
										
										
										
											2014-07-26 23:23:13 +02:00
										 |  |  | 			"mv:Rename the password" | 
					
						
							|  |  |  | 			"cp:Copy the password" | 
					
						
							| 
									
										
										
										
											2012-11-01 21:41:07 -03:00
										 |  |  | 			"rm:Remove the password" | 
					
						
							|  |  |  | 			"git:Call git on the password store" | 
					
						
							|  |  |  | 			"version:Output version information" | 
					
						
							|  |  |  | 			"help:Output help message" | 
					
						
							|  |  |  | 		) | 
					
						
							|  |  |  | 		_describe -t commands 'pass' subcommands | 
					
						
							|  |  |  | 		_arguments : \ | 
					
						
							|  |  |  | 			"--version[Output version information]" \ | 
					
						
							|  |  |  | 			"--help[Output help message]" | 
					
						
							|  |  |  | 		_pass_cmd_show | 
					
						
							|  |  |  | 	fi | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | _pass_cmd_show () { | 
					
						
							|  |  |  | 	_arguments : \ | 
					
						
							|  |  |  | 		"-c[put it on the clipboard]" \ | 
					
						
							|  |  |  | 		"--clip[put it on the clipboard]" | 
					
						
							|  |  |  | 	_pass_complete_entries | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | _pass_complete_entries_helper () { | 
					
						
							|  |  |  | 	local IFS=$'\n' | 
					
						
							| 
									
										
										
										
											2018-08-09 20:17:43 +02:00
										 |  |  | 	local prefix | 
					
						
							|  |  |  | 	zstyle -s ":completion:${curcontext}:" prefix prefix || prefix="${PASSWORD_STORE_DIR:-$HOME/.password-store}" | 
					
						
							|  |  |  | 	_values -C 'passwords' ${$(find -L "$prefix" \( -name .git -o -name .gpg-id \) -prune -o $@ -print 2>/dev/null | sed -e "s#${prefix}/\{0,1\}##" -e 's#\.gpg##' -e 's#\\#\\\\#' | sort):-""} | 
					
						
							| 
									
										
										
										
											2012-11-01 21:41:07 -03:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | _pass_complete_entries_with_subdirs () { | 
					
						
							|  |  |  | 	_pass_complete_entries_helper | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | _pass_complete_entries () { | 
					
						
							|  |  |  | 	_pass_complete_entries_helper -type f | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | _pass_complete_keys () { | 
					
						
							|  |  |  | 	local IFS=$'\n' | 
					
						
							|  |  |  | 	# Extract names and email addresses from gpg --list-keys | 
					
						
							|  |  |  | 	_values 'gpg keys' $(gpg2 --list-secret-keys --with-colons | cut -d : -f 10 | sort -u | sed '/^$/d') | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
											  
											
												Fix pass zsh completion and autoloading
When autocompleting from `pass <TAB>', sometimes the following errors
appear:
  _values:compvalues:10: not enough arguments
  find: `/home/user/.password-store': No such file or directory
  _values:compvalues:10: not enough arguments
  find: `/home/user/.password-store': No such file or directory
The `_values' error happens when there is no password-store folder *or*
there are no passwords in pass; the `find' error only when there is no
password-store folder.
We can trace it back to line 108, which contains the only `_values'
statement that is executed when we autocomplete from pass. We confirm
this by following the trail of execution, which is
  _pass -> _pass_cmd_show -> _pass_complete_entries ->
        -> _pass_complete_entries_helper
If we try running the command inside `$()' on line 104, we see that it
returns nothing and the output is blank. This means that `_values' only
receives 1 of its 2 mandatory parameters, therefore the above error is
triggered (not enough arguments).
That is unless we don't have a password-store folder, in which case the
`find: [...] no such file or directory' error is *also* triggered.
We solve the first error by supplying a default value of "" if the
command outputs nothing, using the zsh construct ${var:-else}.
We solve the second error by redirecting the find command's stderr output
to /dev/null, so the error is effectively suppressed.
* * * *
This patch also fixes the first tab completion, which currently only
loads the completion function definition.
We do this by adding a `_pass' statement at the end of the file, which
runs the `_pass' completion function after loading its definition.
This is the standard way an autoloaded function works; for other examples
look at zsh's official completion files.
											
										 
											2014-07-26 23:26:12 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | _pass |