Skip to content

Commit 544277e

Browse files
add bash completions
1 parent 9b6d60f commit 544277e

File tree

1 file changed

+214
-0
lines changed

1 file changed

+214
-0
lines changed

_passage

Lines changed: 214 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,214 @@
1+
#compdef passage
2+
3+
local curcontext="$curcontext" ret=1
4+
local -a state line args
5+
6+
_arguments -C \
7+
'1: :->cmds' \
8+
'*:: :->args' && ret=0
9+
10+
# Helper function to process directories and files
11+
_process_completions() {
12+
local search_dir="$1"
13+
local dir_prefix="$2"
14+
local -a completions=()
15+
16+
# Get directories and files for current level
17+
local files=($search_dir/*.age(N))
18+
local dirs=($search_dir/*(N/))
19+
20+
# Process directories first
21+
for d in $dirs; do
22+
[[ $d == $search_dir ]] && continue # Skip base dir
23+
completions+=(${d#$dir_prefix/}/)
24+
done
25+
26+
# Process files, strip .age and dir prefix
27+
for f in $files; do
28+
completions+=(${${f#$dir_prefix/}%.age})
29+
done
30+
31+
echo "${completions[@]}"
32+
}
33+
34+
_passage_secrets() {
35+
local dir=${PASSAGE_SECRETS:-$HOME/.config/passage/secrets}
36+
local current="${words[$CURRENT]}"
37+
local prefix="${current%/*}"
38+
local search_dir="$dir"
39+
40+
# If we have a prefix, search in that directory
41+
if [[ -n "$prefix" && "$current" == */* ]]; then
42+
search_dir="$dir/$prefix"
43+
fi
44+
45+
# Get completions and show them
46+
local completions=($(_process_completions "$search_dir" "$dir"))
47+
compadd -Q -S '' -q -- ${completions}
48+
}
49+
50+
_passage_secrets_and_folders() {
51+
local dir=${PASSAGE_SECRETS:-$HOME/.config/passage/secrets}
52+
local current="${words[$CURRENT]}"
53+
local prefix="${current%/*}"
54+
local search_dir="$dir"
55+
56+
# If we have a prefix, search in that directory
57+
if [[ -n "$prefix" && "$current" == */* ]]; then
58+
search_dir="$dir/$prefix"
59+
fi
60+
61+
# Get completions and show them
62+
local completions=($(_process_completions "$search_dir" "$dir"))
63+
compadd -Q -S '' -q -- ${completions}
64+
}
65+
66+
_passage_recipients() {
67+
local -a recipients groups
68+
local keys_dir=${PASSAGE_KEYS:-$HOME/.config/passage/keys}
69+
if [[ -d $keys_dir ]]; then
70+
# Get groups first, strip .group extension and add @ prefix
71+
groups=(${keys_dir}/**/*.group(:t:r))
72+
groups=("${(@)groups/#/@}") # Add @ prefix to all elements
73+
74+
# Get regular recipients (.pub files)
75+
recipients=(${keys_dir}/**/*.pub(:t:r))
76+
77+
# Combine groups and recipients
78+
recipients=($groups $recipients)
79+
fi
80+
compadd -Q -S '' -a recipients
81+
}
82+
83+
_passage_recipients_and_paths() {
84+
local dir=${PASSAGE_SECRETS:-$HOME/.config/passage/secrets}
85+
local keys_dir=${PASSAGE_KEYS:-$HOME/.config/passage/keys}
86+
local current="${words[$CURRENT]}"
87+
local prefix="${current%/*}"
88+
local search_dir="$dir"
89+
local completions=()
90+
91+
# Add groups at the top level
92+
if [[ -d $keys_dir && "$current" != */* ]]; then
93+
local groups=(${keys_dir}/**/*.group(:t:r))
94+
groups=("${(@)groups/#/@}") # Add @ prefix to all elements
95+
completions+=($groups)
96+
fi
97+
98+
# If we have a prefix, search in that directory
99+
if [[ -n "$prefix" && "$current" == */* ]]; then
100+
search_dir="$dir/$prefix"
101+
fi
102+
103+
# Get completions and show them
104+
completions+=($(_process_completions "$search_dir" "$dir"))
105+
compadd -Q -S '' -q -- ${completions}
106+
}
107+
108+
case "$state" in
109+
cmds)
110+
local -a commands
111+
commands=(
112+
'cat:get the whole contents of the specified secret, including comments'
113+
'create:creates a new secret from stdin'
114+
'delete:remove a secret or a folder and its secrets'
115+
'edit:edit the contents of the specified secret'
116+
'edit-who:edit the recipients of the specified path'
117+
'get:get the text of the specified secret, excluding comments'
118+
'healthcheck:check for issues with secrets, find directories that do not have keys'
119+
'init:initial setup of passage'
120+
'list:recursively list all secrets'
121+
'ls:recursively list all secrets'
122+
'new:interactive creation of a new single-line secret'
123+
'realpath:show the full filesystem path to secrets/folders'
124+
'refresh:re-encrypt secrets in the specified path(s)'
125+
'replace:replaces the contents of the specified secret, keeping the comments'
126+
'replace-comment:replaces the comments of the specified secret, keeping the secret'
127+
'rm:remove a secret or a folder and its secrets'
128+
'search:list secrets containing contents that match the specified pattern'
129+
'secret:get the text of the specified secret, excluding comments'
130+
'show:recursively list all secrets in a tree-like format'
131+
'subst:fill in values in the provided template'
132+
'template:outputs target file by substituting all secrets in the template file'
133+
'template-secrets:sorted unique list of secret references found in a template'
134+
'what:list secrets that a recipient has access to'
135+
'who:list all recipients of secrets in the specified path'
136+
)
137+
_describe -t commands 'passage commands' commands && ret=0
138+
;;
139+
args)
140+
case $line[1] in
141+
get|secret)
142+
_arguments \
143+
'*:secret name:_passage_secrets' \
144+
'(-l --line)'{-l,--line}'[line number of the secret to output]:line number' \
145+
'(-s --singleline)'{-s,--singleline}'[outputs secrets only if they are single-line secrets]' \
146+
'(-n --no-new-line)'{-n,--no-new-line}'[outputs secrets without the new-line at the end of the output]' \
147+
'(-c --clip)'{-c,--clip}'[copy to clipboard]' \
148+
'(-q --qrcode)'{-q,--qrcode}'[display as QR code]' && ret=0
149+
;;
150+
cat)
151+
_arguments \
152+
'*:secret name:_passage_secrets' \
153+
'(-l --line)'{-l,--line}'[line number of the secret to output]:line number' \
154+
'(-c --clip)'{-c,--clip}'[copy to clipboard]' \
155+
'(-q --qrcode)'{-q,--qrcode}'[display as QR code]' && ret=0
156+
;;
157+
delete|rm)
158+
_arguments \
159+
'*:secret or folder:_passage_secrets_and_folders' \
160+
'(-f --force)'{-f,--force}'[delete without asking for confirmation]' \
161+
'(-v --verbose)'{-v,--verbose}'[print verbose output]' && ret=0
162+
;;
163+
edit-who|list|ls|show)
164+
_arguments \
165+
'*:secret path:_passage_secrets_and_folders' && ret=0
166+
;;
167+
edit|replace|replace-comment)
168+
_arguments \
169+
'*:secret path:_passage_secrets' && ret=0
170+
;;
171+
healthcheck)
172+
_arguments \
173+
'(- --dry-run-upgrade-legacy-secrets --upgrade-legacy-secrets)'{--dry-run-upgrade-legacy-secrets,--upgrade-legacy-secrets}'[dry run on the legacy secrets upgrade or upgrade found legacy secrets]' \
174+
'(-v --verbose)'{-v,--verbose}'[print verbose output]' && ret=0
175+
;;
176+
realpath|refresh)
177+
_arguments \
178+
'*:path:_passage_secrets_and_folders' \
179+
'(-v --verbose)'{-v,--verbose}'[print verbose output]' && ret=0
180+
;;
181+
search)
182+
_arguments \
183+
'1:pattern' \
184+
'*:path:_passage_secrets_and_folders' \
185+
'(-v --verbose)'{-v,--verbose}'[print verbose output]' && ret=0
186+
;;
187+
subst)
188+
_arguments \
189+
'1:template string' && ret=0
190+
;;
191+
template)
192+
_arguments \
193+
'1:template file:_files' \
194+
'2:target file:_files' && ret=0
195+
;;
196+
template-secrets)
197+
_arguments \
198+
'1:template file:_files' && ret=0
199+
;;
200+
what)
201+
_arguments \
202+
'*:recipient name:_passage_recipients' \
203+
'(-v --verbose)'{-v,--verbose}'[print verbose output]' && ret=0
204+
;;
205+
who)
206+
_arguments \
207+
'*:path:_passage_recipients_and_paths' \
208+
'(-f --expand-groups)'{-f,--expand-groups}'[expand groups of recipients]' && ret=0
209+
;;
210+
esac
211+
;;
212+
esac
213+
214+
return ret

0 commit comments

Comments
 (0)