瀏覽代碼

Refactor handling of key specific subcompletions

The currently used idiom for handling key specific subcompletions
did not work here: behind `docker event -f type=network `, the completion
of networks triggered. The expected behaviour is not to complete
anything here.

In order to limit the scope of the corresponding PR, the new idiom is
currently only used in `docker events --filter`.

Signed-off-by: Harald Albers <github@albersweb.de>
Harald Albers 9 年之前
父節點
當前提交
1fe410e173
共有 1 個文件被更改,包括 51 次插入25 次删除
  1. 51 25
      contrib/completion/bash/docker

+ 51 - 25
contrib/completion/bash/docker

@@ -220,6 +220,32 @@ __docker_pos_first_nonflag() {
 	echo $counter
 	echo $counter
 }
 }
 
 
+# If we are currently completing the value of a map option (key=value)
+# which matches the extglob given as an argument, returns key.
+# This function is needed for key-specific completions.
+# TODO use this in all "${words[$cword-2]}$prev=" occurrences
+__docker_map_key_of_current_option() {
+	local glob="$1"
+
+	local key glob_pos
+	if [ "$cur" = "=" ] ; then        # key= case
+		key="$prev"
+		glob_pos=$((cword - 2))
+	elif [[ $cur == *=* ]] ; then     # key=value case (OSX)
+		key=${cur%=*}
+		glob_pos=$((cword - 1))
+	elif [ "$prev" = "=" ] ; then
+		key=${words[$cword - 2]}  # key=value case
+		glob_pos=$((cword - 3))
+	else
+		return
+	fi
+
+	[ "${words[$glob_pos]}" = "=" ] && ((glob_pos--))  # --option=key=value syntax
+
+	[[ ${words[$glob_pos]} == @($glob) ]] && echo "$key"
+}
+
 # Returns the value of the first option matching option_glob.
 # Returns the value of the first option matching option_glob.
 # Valid values for option_glob are option names like '--log-level' and
 # Valid values for option_glob are option names like '--log-level' and
 # globs like '--log-level|-l'
 # globs like '--log-level|-l'
@@ -860,24 +886,14 @@ _docker_diff() {
 }
 }
 
 
 _docker_events() {
 _docker_events() {
-	case "$prev" in
-		--filter|-f)
-			COMPREPLY=( $( compgen -S = -W "container event image label network type volume" -- "$cur" ) )
-			__docker_nospace
-			return
-			;;
-		--since|--until)
-			return
-			;;
-	esac
-
-	case "${words[$cword-2]}$prev=" in
-		*container=*)
-			cur="${cur#=}"
+	local filter=$(__docker_map_key_of_current_option '-f|--filter')
+	case "$filter" in
+		container)
+			cur="${cur##*=}"
 			__docker_complete_containers_all
 			__docker_complete_containers_all
 			return
 			return
 			;;
 			;;
-		*event=*)
+		event)
 			COMPREPLY=( $( compgen -W "
 			COMPREPLY=( $( compgen -W "
 				attach
 				attach
 				commit
 				commit
@@ -909,31 +925,41 @@ _docker_events() {
 				unpause
 				unpause
 				untag
 				untag
 				update
 				update
-			" -- "${cur#=}" ) )
+			" -- "${cur##*=}" ) )
 			return
 			return
 			;;
 			;;
-		*image=*)
-			cur="${cur#=}"
+		image)
+			cur="${cur##*=}"
 			__docker_complete_images
 			__docker_complete_images
 			return
 			return
 			;;
 			;;
-		*network=*)
-			## BUG: this also triggers after -f type=network
-			cur="${cur#=}"
+		network)
+			cur="${cur##*=}"
 			__docker_complete_networks
 			__docker_complete_networks
 			return
 			return
 			;;
 			;;
-		*type=*)
-			COMPREPLY=( $( compgen -W "container image network volume" -- "${cur#=}" ) )
+		type)
+			COMPREPLY=( $( compgen -W "container image network volume" -- "${cur##*=}" ) )
 			return
 			return
 			;;
 			;;
-		*volume=*)
-			cur="${cur#=}"
+		volume)
+			cur="${cur##*=}"
 			__docker_complete_volumes
 			__docker_complete_volumes
 			return
 			return
 			;;
 			;;
 	esac
 	esac
 
 
+	case "$prev" in
+		--filter|-f)
+			COMPREPLY=( $( compgen -S = -W "container event image label network type volume" -- "$cur" ) )
+			__docker_nospace
+			return
+			;;
+		--since|--until)
+			return
+			;;
+	esac
+
 	case "$cur" in
 	case "$cur" in
 		-*)
 		-*)
 			COMPREPLY=( $( compgen -W "--filter -f --help --since --until" -- "$cur" ) )
 			COMPREPLY=( $( compgen -W "--filter -f --help --since --until" -- "$cur" ) )