Pārlūkot izejas kodu

Refactor bash completion: pull out subcommand parsing

`docker network` is the second command with subcommands.

This refactoring pulls out parsing and processing of subcommands
from `docker volume` completion and thus makes its logic available
for other commands.

Also enables `__docker_pos_first_nonflag` for subcommand completion.

Signed-off-by: Harald Albers <github@albersweb.de>
Harald Albers 9 gadi atpakaļ
vecāks
revīzija
e4bf5cff49
1 mainītis faili ar 35 papildinājumiem un 19 dzēšanām
  1. 35 19
      contrib/completion/bash/docker

+ 35 - 19
contrib/completion/bash/docker

@@ -149,7 +149,7 @@ __docker_volumes() {
 __docker_pos_first_nonflag() {
 __docker_pos_first_nonflag() {
 	local argument_flags=$1
 	local argument_flags=$1
 
 
-	local counter=$((command_pos + 1))
+	local counter=$((${subcommand_pos:-${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++ ))
@@ -212,6 +212,35 @@ __docker_to_extglob() {
 	echo "@($extglob)"
 	echo "@($extglob)"
 }
 }
 
 
+# Subcommand processing.
+# Locates the first occurrence of any of the subcommands contained in the
+# first argument. In case of a match, calls the corresponding completion
+# function and returns 0.
+# If no match is found, 1 is returned. The calling function can then
+# continue processing its completion.
+#
+# TODO if the preceding command has options that accept arguments and an
+# argument is equal ot one of the subcommands, this is falsely detected as
+# a match.
+__docker_subcommands() {
+	local subcommands="$1"
+
+	local counter=$(($command_pos + 1))
+	while [ $counter -lt $cword ]; do
+		case "${words[$counter]}" in
+			$(__docker_to_extglob "$subcommands") )
+				subcommand_pos=$counter
+				local subcommand=${words[$counter]}
+				local completions_func=_docker_${command}_${subcommand}
+				declare -F $completions_func >/dev/null && $completions_func
+				return 0
+				;;
+		esac
+		(( counter++ ))
+	done
+	return 1
+}
+
 # suppress trailing whitespace
 # suppress trailing whitespace
 __docker_nospace() {
 __docker_nospace() {
 	# compopt is not available in ancient bash versions
 	# compopt is not available in ancient bash versions
@@ -1540,33 +1569,20 @@ _docker_volume_rm() {
 }
 }
 
 
 _docker_volume() {
 _docker_volume() {
-	local subcommands=(
+	local subcommands="
 		create
 		create
 		inspect
 		inspect
 		ls
 		ls
 		rm
 		rm
-	)
-
-	local counter=$(($command_pos + 1))
-	while [ $counter -lt $cword ]; do
-		case "${words[$counter]}" in
-			$(__docker_to_extglob "${subcommands[*]}") )
-				local subcommand=${words[$counter]}
-				local completions_func=_docker_volume_$subcommand
-				declare -F $completions_func >/dev/null && $completions_func
-				return
-				;;
-
-		esac
-		(( counter++ ))
-	done
+	"
+	__docker_subcommands "$subcommands" && return
 
 
 	case "$cur" in
 	case "$cur" in
 		-*)
 		-*)
 			COMPREPLY=( $( compgen -W "--help" -- "$cur" ) )
 			COMPREPLY=( $( compgen -W "--help" -- "$cur" ) )
 			;;
 			;;
 		*)
 		*)
-			COMPREPLY=( $( compgen -W "${subcommands[*]}" -- "$cur" ) )
+			COMPREPLY=( $( compgen -W "$subcommands" -- "$cur" ) )
 			;;
 			;;
 	esac
 	esac
 }
 }
@@ -1652,7 +1668,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' command_pos=0
+	local command='docker' command_pos=0 subcommand_pos
 	local counter=1
 	local counter=1
 	while [ $counter -lt $cword ]; do
 	while [ $counter -lt $cword ]; do
 		case "${words[$counter]}" in
 		case "${words[$counter]}" in