1
+ # Define completion for asdf version manager
1
2
# compdef asdf
2
3
# description tool to manage versions of multiple runtimes
3
4
4
- local curcontext=" $curcontext " state state_descr line subcmd
5
+ # Initialize local variables for ZSH completion context
6
+ local state subcmd
7
+
8
+ # Set asdf directory path, using ASDF_DATA_DIR if set, otherwise default to ~/.asdf
5
9
local asdf_dir=" ${ASDF_DATA_DIR:- $HOME / .asdf} "
6
10
11
+ # Define plugin management commands
7
12
local -a asdf_plugin_commands
8
13
asdf_plugin_commands=(
9
14
' add:add plugin from asdf-plugins repo or from git URL'
10
15
' list:list installed plugins (--urls with URLs)'
11
- ' list all:list all plugins registered in asdf-plugins repo'
12
- ' remove:remove named plugin and all versions for it'
16
+ ' remove:remove named plugin and all packages for it'
13
17
' update:update named plugin (or --all)'
14
18
)
19
+
20
+ # Define main asdf commands array with descriptions
15
21
local -a asdf_commands
16
22
asdf_commands=( # 'asdf help' lists commands with help text
17
- # plugins
23
+ # Plugin related commands
18
24
' plugin:plugin management sub-commands'
19
25
20
26
# tools
27
+ ' help:Output documentation for plugin and tool'
21
28
' install:install tool at stated version, or all from .tools-versions'
22
29
' uninstall:remove a specific version of a tool'
23
30
' current:display current versions for named tool (else all)'
24
31
' latest:display latest version available to install for a named tool'
25
32
' where:display install path for given tool at optional specified version'
26
33
' which:display path to an executable'
27
- ' set:set tool version'
34
+ ' set:Set a tool version in a .tool-version file '
28
35
' list:list installed versions of a tool'
29
- ' list all:list all available (remote) versions of a tool'
30
36
31
- # utils
37
+ # Utility commands
32
38
' exec:executes the command shim for the current version'
33
39
' env:prints or runs an executable under a command environment'
34
40
' info:print os, shell and asdf debug information'
35
41
' version:print the currently installed version of ASDF'
36
42
' reshim:recreate shims for version of a tool'
37
43
' shim:shim management sub-commands'
38
44
' shimversions:list for given command which plugins and versions provide it'
39
- ' update:update ASDF to the latest stable release (unless --head)'
40
45
)
41
46
47
+ # Function to list all available plugins from the repository
42
48
_asdf__available_plugins () {
43
49
local plugin_dir=" ${asdf_dir:? } /repository/plugins"
44
50
if [[ ! -d " $plugin_dir " ]]; then
@@ -52,6 +58,7 @@ _asdf__available_plugins() {
52
58
compadd -a plugins
53
59
}
54
60
61
+ # Function to list currently installed plugins
55
62
_asdf__installed_plugins () {
56
63
local plugin_dir=" ${asdf_dir:? } /plugins"
57
64
if [[ ! -d " $plugin_dir " ]]; then
@@ -65,6 +72,7 @@ _asdf__installed_plugins() {
65
72
compadd -a plugins
66
73
}
67
74
75
+ # Function to list installed versions for a specific plugin
68
76
_asdf__installed_versions_of () {
69
77
local plugin_dir=" ${asdf_dir:? } /installs/${1:? need a plugin version} "
70
78
if [[ ! -d " $plugin_dir " ]]; then
@@ -78,6 +86,7 @@ _asdf__installed_versions_of() {
78
86
compadd -a versions
79
87
}
80
88
89
+ # Similar to _asdf__installed_versions_of but includes 'system' as an option
81
90
_asdf__installed_versions_of_plus_system () {
82
91
local plugin_dir=" ${asdf_dir:? } /installs/${1:? need a plugin version} "
83
92
if [[ ! -d " $plugin_dir " ]]; then
@@ -92,110 +101,246 @@ _asdf__installed_versions_of_plus_system() {
92
101
compadd -a versions
93
102
}
94
103
104
+ # Function to get available git references for a plugin
105
+ _asdf__plugin_git_refs () {
106
+ local plugin=$1
107
+ local data_dir=${ASDF_DATA_DIR:- $HOME / .asdf}
108
+ local plugin_path=" $data_dir /plugins/$plugin "
95
109
110
+ if [[ -d " $plugin_path /.git" ]]; then
111
+ # Get remote branches and format them
112
+ git -C " $plugin_path " branch -r 2> /dev/null | \
113
+ sed \
114
+ -e ' s/^[[:space:]]*[^\/]*\///' \
115
+ -e ' s/[[:space:]]*->.*$//' \
116
+ -e ' s/\(.*\)/\1:Remote branch \1/' | \
117
+ sort -fd
118
+ # Get tags and format them
119
+ git -C " $plugin_path " tag 2> /dev/null | \
120
+ sed -e ' s/\(.*\)/\1:Tag \1/' | \
121
+ sort -V
122
+ # Get recent commit hashes and messages (last 10 commits)
123
+ git -C " $plugin_path " log --pretty=format:' %h:%s' -n 10 2> /dev/null
124
+ fi
125
+ }
126
+
127
+ # Handle top-level command completion first
96
128
if (( CURRENT == 2 )) ; then
97
129
_arguments -C : ' --version[version]' ' :command:->command'
98
130
fi
99
131
132
+ # Process command state for top-level commands
100
133
case " $state " in
101
134
(command)
102
135
_describe -t asdf-commands ' ASDF Commands' asdf_commands
103
136
return
104
137
;;
105
138
esac
139
+
140
+ # Get the subcommand for further processing
106
141
subcmd=" ${words[2]} "
107
- subcmd2=" ${words[3]} "
108
142
143
+ # Complex completion logic for each subcommand
144
+ # Each case handles specific completion scenarios for the respective command
109
145
case " $subcmd " in
110
146
(plugin)
111
- case " $subcmd2 " in
147
+ # Handle plugin subcommand completions with nested subcommands
148
+ if (( CURRENT == 3 )) ; then
149
+ _describe -t asdf-plugin-commands ' ASDF Plugin Commands' asdf_plugin_commands
150
+ else
151
+ local plugin_subcmd=" ${words[3]} "
152
+ case " $plugin_subcmd " in
112
153
(add)
154
+ # Complete available plugins or URLs for add command
113
155
if (( CURRENT == 4 )) ; then
114
156
_asdf__available_plugins
115
- else
116
- if (( CURRENT == 5 )) ; then
117
- _arguments " *:${words[3]} plugin url:_urls"
118
- fi
157
+ elif (( CURRENT == 5 )) ; then
158
+ _arguments " *:${words[4]} plugin url:_urls"
119
159
fi
120
160
return
121
161
;;
122
162
(update)
123
- _alternative \
124
- ' all:all:(--all)' \
125
- ' asdf-available-plugins:Installed ASDF Plugins:_asdf__installed_plugins'
126
- return
127
- ;;
163
+ # Handle update command with support for --all flag and git refs
164
+ if (( CURRENT == 4 )) ; then
165
+ _alternative \
166
+ ' flags:flags:((--all\:"Update all installed plugins"))' \
167
+ ' asdf-available-plugins:Installed ASDF Plugins:_asdf__installed_plugins'
168
+ elif (( CURRENT == 5 )) ; then
169
+ if [[ ${words[4]} != " --all" ]]; then
170
+ local -a refs
171
+ while IFS=: read -r value descr; do
172
+ refs+=( " ${value} :${descr} " )
173
+ done < <( _asdf__plugin_git_refs ${words[4]} )
174
+ _describe -V -t git-refs ' Git References' refs
175
+ fi
176
+ fi
177
+ ;;
128
178
(remove)
179
+ # Complete installed plugin names for remove command
129
180
_asdf__installed_plugins
130
181
return
131
182
;;
132
183
(list)
133
- _asdf__installed_plugins
134
- return
184
+ # Handle list command options with support for --urls and --refs flags
185
+ case $CURRENT in
186
+ 4)
187
+ _alternative \
188
+ ' flags:flags:((--urls\:"Show repository URLs" --refs\:"Show Git references"))' \
189
+ ' commands:commands:((all\:"List all available plugins"))'
190
+ return
191
+ ;;
192
+ 5)
193
+ # Handle remaining available flags
194
+ if [[ ${words[4]} == --* ]]; then
195
+ local used_flags=(" ${words[@]} " )
196
+ local -a available_flags
197
+ available_flags=()
198
+ if [[ ! " ${used_flags[@]} " =~ " --urls" ]]; then
199
+ available_flags+=(" --urls" )
200
+ fi
201
+ if [[ ! " ${used_flags[@]} " =~ " --refs" ]]; then
202
+ available_flags+=(" --refs" )
203
+ fi
204
+ (( ${# available_flags[@]} )) && compadd -- " ${available_flags[@]} "
205
+ fi
206
+ return
207
+ ;;
208
+ esac
135
209
;;
136
- (* )
137
- _describe -t asdf-commands ' ASDF Plugin Commands' asdf_plugin_commands
138
- return
139
- ;;
140
- esac
210
+ esac
211
+ fi
141
212
;;
142
213
(current)
214
+ # Complete with installed plugins for current command
143
215
_asdf__installed_plugins
144
216
;;
217
+ (list)
218
+ # Handle list command completions with support for 'all' and specific plugins
219
+ case $CURRENT in
220
+ 3)
221
+ _alternative \
222
+ ' commands:commands:((all\:"List all available (remote) versions"))' \
223
+ ' plugin:plugin:_asdf__installed_plugins'
224
+ ;;
225
+ 4)
226
+ if [[ ${words[3]} == " all" ]]; then
227
+ _asdf__installed_plugins
228
+ else
229
+ # For normal list: show installed versions with optional filter
230
+ _asdf__installed_versions_of ${words[3]}
231
+ fi
232
+ ;;
233
+ 5)
234
+ # When listing all versions of a specific plugin
235
+ if [[ ${words[3]} == " all" ]]; then
236
+ local versions
237
+ if versions=$( asdf list all " ${words[4]} " 2> /dev/null) ; then
238
+ _wanted " remote-versions-${words[4]} " \
239
+ expl " Available versions of ${words[4]} " \
240
+ compadd -- ${(f)versions}
241
+ else
242
+ _message " Unable to fetch versions for ${words[4]} "
243
+ fi
244
+ fi
245
+ ;;
246
+ esac
247
+ ;;
248
+ (help)
249
+ # Complete installed plugins and their versions for help command
250
+ if (( CURRENT == 3 )) ; then
251
+ _asdf__installed_plugins
252
+ elif (( CURRENT == 4 )) ; then
253
+ _asdf__installed_versions_of ${words[3]}
254
+ fi
255
+ ;;
145
256
(install)
146
- if (( CURRENT == 3 )) ; then
257
+ # Handle complex install command completion with latest tag support
258
+ if (( CURRENT == 3 )) ; then
147
259
_asdf__installed_plugins
148
260
return
149
261
elif (( CURRENT == 4 )) ; then
150
262
local tool=" ${words[3]} "
151
263
local ver_prefix=" ${words[4]} "
152
264
if [[ $ver_prefix == latest:* ]]; then
265
+ # Handle latest:<version> syntax
153
266
_wanted " latest-versions-$tool " \
154
267
expl " Latest version" \
155
268
compadd -- latest:${^$(asdf list all " $tool " )}
156
- else
157
- _wanted " latest-tag-$tool " \
158
- expl " Latest version" \
159
- compadd -- ' latest' ' latest:'
160
- _wanted " remote-versions-$tool " \
161
- expl " Available versions of $tool " \
162
- compadd -- $( asdf list all " $tool " )
269
+ else
270
+ # Offer both latest options and specific versions
271
+ _wanted " latest-tag-$tool " \
272
+ expl " Latest version" \
273
+ compadd -- ' latest' ' latest:'
274
+ _wanted " remote-versions-$tool " \
275
+ expl " Available versions of $tool " \
276
+ compadd -- $( asdf list all " $tool " )
163
277
fi
164
278
return
165
279
fi
166
280
;;
167
281
(latest)
282
+ # Complete plugin names or --all flag for latest command
168
283
if (( CURRENT == 3 )) ; then
169
284
_alternative \
170
- ' all:all:( --all)' \
285
+ ' flags:flags:(( --all\:"Show latest version of all tools") )' \
171
286
' asdf-available-plugins:Installed ASDF Plugins:_asdf__installed_plugins'
172
- elif (( CURRENT == 4 )) ; then
173
- local tool=" ${words[3]} "
174
- local query=${words[4]}
175
- [[ -n $query ]] || query=' [0-9]'
176
- _wanted " latest-pattern-$tool " \
177
- expl " Pattern to look for in matching versions of $tool " \
178
- compadd -- $( asdf list all " $tool " " $query " )
179
287
fi
180
288
;;
181
- (uninstall|reshim)
182
- compset -n 2
183
- _arguments ' 1:plugin-name: _asdf__installed_plugins' ' 2:tool-version:{_asdf__installed_versions_of ${words[2]}}'
289
+ (uninstall|reshim|where)
290
+ # Handle complex install command completion with latest tag support
291
+ if (( CURRENT == 3 )) ; then
292
+ _asdf__installed_plugins
293
+ return
294
+ elif (( CURRENT == 4 )) ; then
295
+ # For normal list: show installed versions with optional filter
296
+ _asdf__installed_versions_of ${words[3]}
297
+ return
298
+ fi
184
299
;;
185
300
(set)
186
- compset -n 2
187
- _arguments ' 1:plugin-name: _asdf__installed_plugins' ' 2:tool-version:{_asdf__installed_versions_of_plus_system ${words[2]}}'
188
- ;;
189
- (where)
190
- # version is optional
191
- compset -n 2
192
- _arguments ' 1:plugin-name: _asdf__installed_plugins' ' 2::tool-version:{_asdf__installed_versions_of ${words[2]}}'
301
+ # Handle set command completion
302
+ case $CURRENT in
303
+ 3)
304
+ _alternative \
305
+ ' flags:flags:((-u\:"set version in user home directory" -p\:"set version in closest parent .tool-versions"))' \
306
+ ' plugin:plugin:_asdf__installed_plugins'
307
+ ;;
308
+ 4)
309
+ if [[ ${words[3]} == -* ]]; then
310
+ # After flag, complete with plugin name
311
+ _asdf__installed_plugins
312
+ else
313
+ # Complete with available versions for the plugin
314
+ local versions
315
+ if versions=$( asdf list all " ${words[3]} " 2> /dev/null) ; then
316
+ _wanted " versions-${words[3]} " \
317
+ expl " Available versions of ${words[3]} " \
318
+ compadd -- ${(f)versions}
319
+ fi
320
+ fi
321
+ ;;
322
+ * )
323
+ # Support for multiple version specifications
324
+ if [[ ${words[3]} == -* ]]; then
325
+ local plugin=" ${words[4]} "
326
+ else
327
+ local plugin=" ${words[3]} "
328
+ fi
329
+ local versions
330
+ if versions=$( asdf list all " $plugin " 2> /dev/null) ; then
331
+ _wanted " versions-$plugin " \
332
+ expl " Available versions of $plugin " \
333
+ compadd -- ${(f)versions}
334
+ fi
335
+ ;;
336
+ esac
193
337
;;
194
338
(which|shimversions)
339
+ # Complete with available shims for which and shimversions commands
195
340
_wanted asdf-shims expl " ASDF Shims" compadd -- " ${asdf_dir:? } /shims" /* (:t)
196
341
;;
197
342
(exec)
198
- # asdf exec <shim-cmd> [< shim-cmd args ...>]
343
+ # Handle exec command completion with shim command and args
199
344
if (( CURRENT == 3 )) ; then
200
345
_wanted asdf-shims expl " ASDF Shims" compadd -- " ${asdf_dir:? } /shims" /* (:t)
201
346
else
@@ -204,7 +349,7 @@ case "$subcmd" in
204
349
fi
205
350
;;
206
351
(env)
207
- # asdf exec < shim- name> < arbitrary-cmd> [<cmd args ...>]
352
+ # Handle env command completion with shim name and arbitrary command
208
353
if (( CURRENT == 3 )) ; then
209
354
_wanted asdf-shims expl " ASDF Shims" compadd -- " ${asdf_dir:? } /shims" /* (:t)
210
355
else
0 commit comments