2012-11-02 08:41:07 +08:00
|
|
|
#compdef pass
|
|
|
|
#autoload
|
|
|
|
|
2014-07-27 05:23:13 +08:00
|
|
|
# Copyright (C) 2012 - 2014:
|
2012-11-02 08:41:07 +08:00
|
|
|
# Johan Venant <jvenant@invicem.pro>
|
|
|
|
# Brian Mattern <rephorm@rephorm.com>
|
2014-07-27 05:23:13 +08:00
|
|
|
# Jason A. Donenfeld <Jason@zx2c4.com>.
|
2012-11-02 08:41:07 +08:00
|
|
|
# All Rights Reserved.
|
2021-12-29 03:34:05 +08:00
|
|
|
# This file is licensed under the GPLv2+. Please see COPYING for more information.
|
2018-08-10 02:17:43 +08:00
|
|
|
|
|
|
|
|
|
|
|
# If you use multiple repositories, you can configure completion like this:
|
2012-12-09 02:31:13 +08:00
|
|
|
#
|
2018-08-10 02:17:43 +08:00
|
|
|
# compdef _pass workpass
|
|
|
|
# zstyle ':completion::complete:workpass::' prefix "$HOME/work/pass"
|
|
|
|
# workpass() {
|
|
|
|
# PASSWORD_STORE_DIR=$HOME/work/pass pass $@
|
|
|
|
# }
|
2012-11-02 08:41:07 +08:00
|
|
|
|
|
|
|
|
|
|
|
_pass () {
|
|
|
|
local cmd
|
2024-05-30 23:05:50 +08:00
|
|
|
local rootcontext
|
|
|
|
rootcontext=$curcontext
|
2012-11-02 08:41:07 +08:00
|
|
|
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-27 05:23:13 +08:00
|
|
|
"-p[gpg-id will only be applied to this subfolder]" \
|
|
|
|
"--path[gpg-id will only be applied to this subfolder]"
|
2012-11-02 08:41:07 +08: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-27 05:23:13 +08:00
|
|
|
"--clip[copy password to the clipboard]" \
|
|
|
|
"-f[force overwrite]" \
|
|
|
|
"--force[force overwrite]" \
|
|
|
|
"-i[replace first line]" \
|
|
|
|
"--in-place[replace first line]"
|
2012-11-02 08:41:07 +08:00
|
|
|
_pass_complete_entries_with_subdirs
|
|
|
|
;;
|
2014-07-27 05:23:13 +08:00
|
|
|
cp|copy|mv|rename)
|
|
|
|
_arguments : \
|
|
|
|
"-f[force rename]" \
|
|
|
|
"--force[force rename]"
|
|
|
|
_pass_complete_entries_with_subdirs
|
|
|
|
;;
|
2012-11-02 08:41:07 +08: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-27 05:23:13 +08:00
|
|
|
"find:Find password files or directories based on pattern"
|
|
|
|
"grep:Search inside decrypted password files for matching pattern"
|
2012-11-02 08:41:07 +08: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-27 05:23:13 +08:00
|
|
|
"mv:Rename the password"
|
|
|
|
"cp:Copy the password"
|
2012-11-02 08:41:07 +08: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-10 02:17:43 +08:00
|
|
|
local prefix
|
2024-05-30 23:05:50 +08:00
|
|
|
zstyle -s ":completion:${rootcontext}:" 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#\\#\\\\#g' -e 's#:#\\:#g' | sort):-""}
|
2012-11-02 08:41:07 +08: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-27 05:26:12 +08:00
|
|
|
|
|
|
|
_pass
|