podman
237 строк · 9.5 Кб
1# fish completion for podman -*- shell-script -*-
2
3function __podman_debug
4set -l file "$BASH_COMP_DEBUG_FILE"
5if test -n "$file"
6echo "$argv" >> $file
7end
8end
9
10function __podman_perform_completion
11__podman_debug "Starting __podman_perform_completion"
12
13# Extract all args except the last one
14set -l args (commandline -opc)
15# Extract the last arg and escape it in case it is a space
16set -l lastArg (string escape -- (commandline -ct))
17
18__podman_debug "args: $args"
19__podman_debug "last arg: $lastArg"
20
21# Disable ActiveHelp which is not supported for fish shell
22set -l requestComp "PODMAN_ACTIVE_HELP=0 $args[1] __complete $args[2..-1] $lastArg"
23
24__podman_debug "Calling $requestComp"
25set -l results (eval $requestComp 2> /dev/null)
26
27# Some programs may output extra empty lines after the directive.
28# Let's ignore them or else it will break completion.
29# Ref: https://github.com/spf13/cobra/issues/1279
30for line in $results[-1..1]
31if test (string trim -- $line) = ""
32# Found an empty line, remove it
33set results $results[1..-2]
34else
35# Found non-empty line, we have our proper output
36break
37end
38end
39
40set -l comps $results[1..-2]
41set -l directiveLine $results[-1]
42
43# For Fish, when completing a flag with an = (e.g., <program> -n=<TAB>)
44# completions must be prefixed with the flag
45set -l flagPrefix (string match -r -- '-.*=' "$lastArg")
46
47__podman_debug "Comps: $comps"
48__podman_debug "DirectiveLine: $directiveLine"
49__podman_debug "flagPrefix: $flagPrefix"
50
51for comp in $comps
52printf "%s%s\n" "$flagPrefix" "$comp"
53end
54
55printf "%s\n" "$directiveLine"
56end
57
58# this function limits calls to __podman_perform_completion, by caching the result behind $__podman_perform_completion_once_result
59function __podman_perform_completion_once
60__podman_debug "Starting __podman_perform_completion_once"
61
62if test -n "$__podman_perform_completion_once_result"
63__podman_debug "Seems like a valid result already exists, skipping __podman_perform_completion"
64return 0
65end
66
67set --global __podman_perform_completion_once_result (__podman_perform_completion)
68if test -z "$__podman_perform_completion_once_result"
69__podman_debug "No completions, probably due to a failure"
70return 1
71end
72
73__podman_debug "Performed completions and set __podman_perform_completion_once_result"
74return 0
75end
76
77# this function is used to clear the $__podman_perform_completion_once_result variable after completions are run
78function __podman_clear_perform_completion_once_result
79__podman_debug ""
80__podman_debug "========= clearing previously set __podman_perform_completion_once_result variable =========="
81set --erase __podman_perform_completion_once_result
82__podman_debug "Successfully erased the variable __podman_perform_completion_once_result"
83end
84
85function __podman_requires_order_preservation
86__podman_debug ""
87__podman_debug "========= checking if order preservation is required =========="
88
89__podman_perform_completion_once
90if test -z "$__podman_perform_completion_once_result"
91__podman_debug "Error determining if order preservation is required"
92return 1
93end
94
95set -l directive (string sub --start 2 $__podman_perform_completion_once_result[-1])
96__podman_debug "Directive is: $directive"
97
98set -l shellCompDirectiveKeepOrder 32
99set -l keeporder (math (math --scale 0 $directive / $shellCompDirectiveKeepOrder) % 2)
100__podman_debug "Keeporder is: $keeporder"
101
102if test $keeporder -ne 0
103__podman_debug "This does require order preservation"
104return 0
105end
106
107__podman_debug "This doesn't require order preservation"
108return 1
109end
110
111
112# This function does two things:
113# - Obtain the completions and store them in the global __podman_comp_results
114# - Return false if file completion should be performed
115function __podman_prepare_completions
116__podman_debug ""
117__podman_debug "========= starting completion logic =========="
118
119# Start fresh
120set --erase __podman_comp_results
121
122__podman_perform_completion_once
123__podman_debug "Completion results: $__podman_perform_completion_once_result"
124
125if test -z "$__podman_perform_completion_once_result"
126__podman_debug "No completion, probably due to a failure"
127# Might as well do file completion, in case it helps
128return 1
129end
130
131set -l directive (string sub --start 2 $__podman_perform_completion_once_result[-1])
132set --global __podman_comp_results $__podman_perform_completion_once_result[1..-2]
133
134__podman_debug "Completions are: $__podman_comp_results"
135__podman_debug "Directive is: $directive"
136
137set -l shellCompDirectiveError 1
138set -l shellCompDirectiveNoSpace 2
139set -l shellCompDirectiveNoFileComp 4
140set -l shellCompDirectiveFilterFileExt 8
141set -l shellCompDirectiveFilterDirs 16
142
143if test -z "$directive"
144set directive 0
145end
146
147set -l compErr (math (math --scale 0 $directive / $shellCompDirectiveError) % 2)
148if test $compErr -eq 1
149__podman_debug "Received error directive: aborting."
150# Might as well do file completion, in case it helps
151return 1
152end
153
154set -l filefilter (math (math --scale 0 $directive / $shellCompDirectiveFilterFileExt) % 2)
155set -l dirfilter (math (math --scale 0 $directive / $shellCompDirectiveFilterDirs) % 2)
156if test $filefilter -eq 1; or test $dirfilter -eq 1
157__podman_debug "File extension filtering or directory filtering not supported"
158# Do full file completion instead
159return 1
160end
161
162set -l nospace (math (math --scale 0 $directive / $shellCompDirectiveNoSpace) % 2)
163set -l nofiles (math (math --scale 0 $directive / $shellCompDirectiveNoFileComp) % 2)
164
165__podman_debug "nospace: $nospace, nofiles: $nofiles"
166
167# If we want to prevent a space, or if file completion is NOT disabled,
168# we need to count the number of valid completions.
169# To do so, we will filter on prefix as the completions we have received
170# may not already be filtered so as to allow fish to match on different
171# criteria than the prefix.
172if test $nospace -ne 0; or test $nofiles -eq 0
173set -l prefix (commandline -t | string escape --style=regex)
174__podman_debug "prefix: $prefix"
175
176set -l completions (string match -r -- "^$prefix.*" $__podman_comp_results)
177set --global __podman_comp_results $completions
178__podman_debug "Filtered completions are: $__podman_comp_results"
179
180# Important not to quote the variable for count to work
181set -l numComps (count $__podman_comp_results)
182__podman_debug "numComps: $numComps"
183
184if test $numComps -eq 1; and test $nospace -ne 0
185# We must first split on \t to get rid of the descriptions to be
186# able to check what the actual completion will be.
187# We don't need descriptions anyway since there is only a single
188# real completion which the shell will expand immediately.
189set -l split (string split --max 1 \t $__podman_comp_results[1])
190
191# Fish won't add a space if the completion ends with any
192# of the following characters: @=/:.,
193set -l lastChar (string sub -s -1 -- $split)
194if not string match -r -q "[@=/:.,]" -- "$lastChar"
195# In other cases, to support the "nospace" directive we trick the shell
196# by outputting an extra, longer completion.
197__podman_debug "Adding second completion to perform nospace directive"
198set --global __podman_comp_results $split[1] $split[1].
199__podman_debug "Completions are now: $__podman_comp_results"
200end
201end
202
203if test $numComps -eq 0; and test $nofiles -eq 0
204# To be consistent with bash and zsh, we only trigger file
205# completion when there are no other completions
206__podman_debug "Requesting file completion"
207return 1
208end
209end
210
211return 0
212end
213
214# Since Fish completions are only loaded once the user triggers them, we trigger them ourselves
215# so we can properly delete any completions provided by another script.
216# Only do this if the program can be found, or else fish may print some errors; besides,
217# the existing completions will only be loaded if the program can be found.
218if type -q "podman"
219# The space after the program name is essential to trigger completion for the program
220# and not completion of the program name itself.
221# Also, we use '> /dev/null 2>&1' since '&>' is not supported in older versions of fish.
222complete --do-complete "podman " > /dev/null 2>&1
223end
224
225# Remove any pre-existing completions for the program since we will be handling all of them.
226complete -c podman -e
227
228# this will get called after the two calls below and clear the $__podman_perform_completion_once_result global
229complete -c podman -n '__podman_clear_perform_completion_once_result'
230# The call to __podman_prepare_completions will setup __podman_comp_results
231# which provides the program's completion choices.
232# If this doesn't require order preservation, we don't use the -k flag
233complete -c podman -n 'not __podman_requires_order_preservation && __podman_prepare_completions' -f -a '$__podman_comp_results'
234# otherwise we use the -k flag
235complete -k -c podman -n '__podman_requires_order_preservation && __podman_prepare_completions' -f -a '$__podman_comp_results'
236
237# This file is generated with "podman completion"; see: podman-completion(1)
238