Hello,
I'm new here, so let me know if there already is an ongoing discussion
on this topic or if I get anything wrong about this.
I noticed that some extensions for pass (like pass-update or pass-tomb)
provide completion files, which are poorly integrated in pass. This is
due to the fact, that completion files are loaded dynamically on demand.
For example in bash the file $BASHCOMPDIR/pass is loaded when you enter
"pass <TAB>". As the completion file for pass-update is stored in
$BASHCOMPDIR/pass-update it is not loaded unless you type "pass-update
<TAB>". The completion files in fish and zsh are handled in a similar
manner.
I'd like to suggest a fix for that issue. The completion files of pass
may automatically seek completion files of extensions and source them.
Enclosed you find a patch that provides that feature together with
example completion files for the extension pass-file.
Regards,
Simon Blum
From 2a0749c2e5191d1a8c185fee8a7f75a4b363d15c Mon Sep 17 00:00:00 2001
From: Simon Blum <[email protected]>
Date: Thu, 1 Dec 2022 18:21:09 +0100
Subject: [PATCH] automatically source extension completion files
Currently the only way to provide completion for extensions is to modify
the completion files of pass.
With this patch the completion files of pass automatically source
completion files of extensions or call their init function (zsh).
---
src/completion/pass.bash-completion | 23 ++++++++++++++++-------
src/completion/pass.fish-completion | 7 +++++++
src/completion/pass.zsh-completion | 21 +++++++++++++++++++--
3 files changed, 42 insertions(+), 9 deletions(-)
diff --git a/src/completion/pass.bash-completion b/src/completion/pass.bash-completion
index 2d23cbf..9ca9ec1 100644
--- a/src/completion/pass.bash-completion
+++ b/src/completion/pass.bash-completion
@@ -4,6 +4,22 @@
# Brian Mattern <[email protected]>. All Rights Reserved.
# This file is licensed under the GPLv2+. Please see COPYING for more information.
+# To add completion for an extension command define a function like this:
+# __password_store_extension_complete_<COMMAND>() {
+# COMPREPLY+=($(compgen -W "-o --option" -- ${cur}))
+# _pass_complete_entries 1
+# }
+#
+# and add the command to the $PASSWORD_STORE_EXTENSION_COMMANDS array
+# within a file pass.extension.<EXTENSION_NAME> residing in the same
+# directory as this file
+readarray -d "" extension_compfiles < <(find $(dirname $BASH_SOURCE) -maxdepth 1 -name "pass.extension.*" \( -type f -o -type l \) -print0)
+for compfile in "${extension_compfiles[@]}"; do
+ source "$compfile"
+done
+unset compfile
+unset extension_compfiles
+
_pass_complete_entries () {
local prefix="${PASSWORD_STORE_DIR:-$HOME/.password-store/}"
prefix="${prefix%/}/"
@@ -125,13 +141,6 @@ _pass()
;;
esac
- # To add completion for an extension command define a function like this:
- # __password_store_extension_complete_<COMMAND>() {
- # COMPREPLY+=($(compgen -W "-o --option" -- ${cur}))
- # _pass_complete_entries 1
- # }
- #
- # and add the command to the $PASSWORD_STORE_EXTENSION_COMMANDS array
if [[ " ${PASSWORD_STORE_EXTENSION_COMMANDS[*]} " == *" ${COMP_WORDS[1]} "* ]] && type "__password_store_extension_complete_${COMP_WORDS[1]}" &> /dev/null; then
"__password_store_extension_complete_${COMP_WORDS[1]}"
fi
diff --git a/src/completion/pass.fish-completion b/src/completion/pass.fish-completion
index 0f57dd2..af4002f 100644
--- a/src/completion/pass.fish-completion
+++ b/src/completion/pass.fish-completion
@@ -1,6 +1,13 @@
# Copyright (C) 2012-2014 Dmitry Medvinsky <[email protected]>. All Rights Reserved.
# This file is licensed under the GPLv2+. Please see COPYING for more information.
+# Completion files for extensions should be named pass.extension.<EXTENSION_NAME>.fish
+# and reside in the same directory as this file
+set -l extension_compfiles (find $(path dirname $(status -f)) -maxdepth 1 -name "pass.extension.*.fish" \( -type f -o -type l \) -print0 | string split0)
+for compfile in $extension_compfiles
+ source "$compfile"
+end
+
set -l PROG 'pass'
function __fish_pass_get_prefix
diff --git a/src/completion/pass.zsh-completion b/src/completion/pass.zsh-completion
index d911e12..d4d038d 100644
--- a/src/completion/pass.zsh-completion
+++ b/src/completion/pass.zsh-completion
@@ -17,6 +17,19 @@
# PASSWORD_STORE_DIR=$HOME/work/pass pass $@
# }
+# To add completion for an extension command create a file named
+# _pass.extension.<EXTENSION_NAME> in the same directory as this file
+# with following content:
+# #autoload
+# PASSWORD_STORE_EXTENSION_COMMANDS+=("<COMMAND>:<COMMAND_DESCRIPTION>")
+# __password_store_extension_complete_<COMMAND>() {
+# <COMPLETION_FOR_COMMAND>
+# }
+# unfunction $(basename $(print -P %x))
+local -a extensions=($(print -l ${(ok)functions[(I)_pass.extension.*]}))
+for extension in "$extensions[@]"; do
+ $extension
+done
_pass () {
local cmd
@@ -84,10 +97,14 @@ _pass () {
)
_describe -t commands 'pass git' subcommands
;;
- show|*)
+ show|-*)
_pass_cmd_show
;;
esac
+
+ if [[ " ${PASSWORD_STORE_EXTENSION_COMMANDS[@]%%:*} " == *" ${cmd} "* ]] && type "__password_store_extension_complete_${cmd}" &> /dev/null; then
+ "__password_store_extension_complete_${cmd}"
+ fi
else
local -a subcommands
subcommands=(
@@ -106,7 +123,7 @@ _pass () {
"version:Output version information"
"help:Output help message"
)
- _describe -t commands 'pass' subcommands
+ _describe -t commands 'pass' subcommands -- PASSWORD_STORE_EXTENSION_COMMANDS
_arguments : \
"--version[Output version information]" \
"--help[Output help message]"
--
2.38.1
# completion file for bash
PASSWORD_STORE_EXTENSION_COMMANDS+=("file")
__password_store_extension_complete_file() {
local cur="${COMP_WORDS[COMP_CWORD]}"
case "$COMP_CWORD" in
2)
COMPREPLY+=($(compgen -W "add get" -- ${cur}))
;;
3)
case "${COMP_WORDS[2]}" in
a|add)
COMPREPLY+=($(compgen -f ${cur}))
;;
g|get)
_pass_complete_entries 1
;;
esac
;;
4)
case "${COMP_WORDS[2]}" in
a|add)
_pass_complete_entries
;;
esac
;;
esac
}
#autoload
PASSWORD_STORE_EXTENSION_COMMANDS+=("file:add/get file to/from password-store")
__password_store_extension_complete_file () {
case "$CURRENT" in
2)
local -a subcommands
subcommands=(
"add:add file to password-store"
"get:get file from password-store"
)
_describe -t commands 'pass' subcommands
;;
3)
local cmd=${words[2]}
case "${cmd}" in
a|add)
_files
;;
g|get)
_pass_complete_entries
;;
esac
;;
4)
local cmd=${words[2]}
case "${cmd}" in
a|add)
_pass_complete_entries
;;
esac
;;
esac
}
unfunction $(basename $(print -P %x))
set -l PROG 'pass'
function __fish_pass-file_needs_command
set -l cmd (commandline -opc)
if [ (count $cmd) -eq 2 -a "$cmd[2]" = file ]
return 0
end
return 1
end
function __fish_pass-file_arg_nr_of_command
set -l cmd (commandline -opc)
set -l expected_length (math 2 + $argv[1])
if [ (count $cmd) -eq $expected_length -a "$cmd[2]" = "file" -a "$cmd[3]" =
$argv[2] ]
return 0
end
return 1
end
complete -c $PROG -f -n '__fish_pass_needs_command' -a file -d 'Command:
add/get file to/from password-store'
complete -c $PROG -f -n '__fish_pass-file_needs_command' -a add -d 'add file to
password-store'
complete -c $PROG -n '__fish_pass-file_arg_nr_of_command 1 a'
complete -c $PROG -n '__fish_pass-file_arg_nr_of_command 1 add'
complete -c $PROG -f -n '__fish_pass-file_arg_nr_of_command 2 a' -a
"(__fish_pass_print_entries)"
complete -c $PROG -f -n '__fish_pass-file_arg_nr_of_command 2 add' -a
"(__fish_pass_print_entries)"
complete -c $PROG -f -n '__fish_pass-file_needs_command' -a get -d 'get file
from password-store'
complete -c $PROG -f -n '__fish_pass-file_arg_nr_of_command 1 g' -a
"(__fish_pass_print_entries)"
complete -c $PROG -f -n '__fish_pass-file_arg_nr_of_command 1 get' -a
"(__fish_pass_print_entries)"