Fix docker plugin suggestions in Zsh completion

The __docker_plugins function calls `docker plugin ls` to get its information,
but it doesn't output a TAG column anymore. Without this change, triggering
the function, e.g. trying to complete `docker plugin inspect`, produces the
following error repeatedly:

  __docker_plugins:27: bad math expression: empty string

Also, the tag part of the docker plugin is shown in the NAME column, but the
colon (:) character is swallowed by the `_describe` function and interpreted
so that the right-side of the string is displayed as a comment to the suggestion.
For example: vieux/sshfs:latest is suggested like

  vieux/sshfs    -- latest

instead of the tag being part of the suggestion. This means that if there are
more than one tags installed of the same docker plugin, they are both combined
into a single completion entry, instead of two, one for each tag. By quoting
the colon character, the tag is now correctly offered in the suggestion.

With this commit the plugin description is added to each completion suggestion
and plugin names are shown without the redundant ":latest" tag.

Fixes #9294

Signed-off-by: Marc Cornellà <hello@mcornella.com>
This commit is contained in:
Marc Cornellà 2021-01-01 13:16:12 +01:00
parent 73b05aaa82
commit f617883fdf
No known key found for this signature in database
GPG Key ID: 0314585E776A9C1B
1 changed files with 8 additions and 18 deletions

View File

@ -1559,31 +1559,21 @@ __docker_plugin_complete_ls_filters() {
__docker_plugins() {
[[ $PREFIX = -* ]] && return 1
integer ret=1
local line s
local filter line s
declare -a lines plugins args
filter=$1; shift
[[ $filter != "none" ]] && args=("-f $filter")
lines=(${(f)${:-"$(_call_program commands docker $docker_options plugin ls $args)"$'\n'}})
# Output plugins in format "name:tag\|description"
lines=(${(f)${:-"$(_call_program commands docker $docker_options plugin ls --format='{{.Name}}\|{{.Description}}' $args)"}})
# Parse header line to find columns
local i=1 j=1 k header=${lines[1]}
declare -A begin end
while (( j < ${#header} - 1 )); do
i=$(( j + ${${header[$j,-1]}[(i)[^ ]]} - 1 ))
j=$(( i + ${${header[$i,-1]}[(i) ]} - 1 ))
k=$(( j + ${${header[$j,-1]}[(i)[^ ]]} - 2 ))
begin[${header[$i,$((j-1))]}]=$i
end[${header[$i,$((j-1))]}]=$k
done
end[${header[$i,$((j-1))]}]=-1
lines=(${lines[2,-1]})
# Name
# Suggestion entries: name:tag -- description
for line in $lines; do
s="${line[${begin[NAME]},${end[NAME]}]%% ##}"
s="$s:${(l:7:: :::)${${line[${begin[TAG]},${end[TAG]}]}%% ##}}"
# - Remove redundant :latest tag
# - Quote : in name:tag (_describe splits on : to separate entry and description)
# - Replace \| separator with :
s="${${${line//:latest/}//:/\:}//\|/:}"
plugins=($plugins $s)
done