Completion: Add support for '=' in arguments to __docker_pos_first_nonflag

This solves several problems that arise from the special treatment of
"=" in Bash.
The fix was required as some log drivers have options in a key=value
form. It also addresses the --option=value and the negated boolean syntax
(--boolean=false).

Note that this is not a general fix for these problems, it is limited to
the __docker_pos_first_nonflag function.

Signed-off-by: Harald Albers <github@albersweb.de>
This commit is contained in:
Harald Albers 2015-07-13 18:06:22 +02:00 committed by Tibor Vass
parent d3098f54ab
commit f7eb7787da
1 changed files with 16 additions and 4 deletions

View File

@ -94,13 +94,19 @@ __docker_containers_and_images() {
COMPREPLY+=( "${containers[@]}" ) COMPREPLY+=( "${containers[@]}" )
} }
# Finds the position of the first word that is neither option nor an option's argument.
# If there are options that require arguments, you should pass a glob describing those
# options, e.g. "--option1|-o|--option2"
# Use this function to restrict completions to exact positions after the argument list.
__docker_pos_first_nonflag() { __docker_pos_first_nonflag() {
local argument_flags=$1 local argument_flags=$1
local counter=$cpos local counter=$((command_pos + 1))
while [ $counter -le $cword ]; do while [ $counter -le $cword ]; do
if [ -n "$argument_flags" ] && eval "case '${words[$counter]}' in $argument_flags) true ;; *) false ;; esac"; then if [ -n "$argument_flags" ] && eval "case '${words[$counter]}' in $argument_flags) true ;; *) false ;; esac"; then
(( counter++ )) (( counter++ ))
# eat "=" in case of --option=arg syntax
[ "${words[$counter]}" = "=" ] && (( counter++ ))
else else
case "${words[$counter]}" in case "${words[$counter]}" in
-*) -*)
@ -110,6 +116,13 @@ __docker_pos_first_nonflag() {
;; ;;
esac esac
fi fi
# Bash splits words at "=", retaining "=" as a word, examples:
# "--debug=false" => 3 words, "--log-opt syslog-facility=daemon" => 4 words
while [ "${words[$counter + 1]}" = "=" ] ; do
counter=$(( counter + 2))
done
(( counter++ )) (( counter++ ))
done done
@ -1295,7 +1308,7 @@ _docker() {
local cur prev words cword local cur prev words cword
_get_comp_words_by_ref -n : cur prev words cword _get_comp_words_by_ref -n : cur prev words cword
local command='docker' cpos=0 local command='docker' command_pos=0
local counter=1 local counter=1
while [ $counter -lt $cword ]; do while [ $counter -lt $cword ]; do
case "${words[$counter]}" in case "${words[$counter]}" in
@ -1314,8 +1327,7 @@ _docker() {
;; ;;
*) *)
command="${words[$counter]}" command="${words[$counter]}"
cpos=$counter command_pos=$counter
(( cpos++ ))
break break
;; ;;
esac esac