From 1fe410e17317af82bc0caeb01527e94d37054467 Mon Sep 17 00:00:00 2001 From: Harald Albers Date: Mon, 18 Jan 2016 09:37:12 -0800 Subject: [PATCH] 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 --- contrib/completion/bash/docker | 76 +++++++++++++++++++++++----------- 1 file changed, 51 insertions(+), 25 deletions(-) diff --git a/contrib/completion/bash/docker b/contrib/completion/bash/docker index 2fb67d2b2d..3cf39ab987 100644 --- a/contrib/completion/bash/docker +++ b/contrib/completion/bash/docker @@ -220,6 +220,32 @@ __docker_pos_first_nonflag() { 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. # Valid values for option_glob are option names like '--log-level' and # globs like '--log-level|-l' @@ -860,24 +886,14 @@ _docker_diff() { } _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 return ;; - *event=*) + event) COMPREPLY=( $( compgen -W " attach commit @@ -909,31 +925,41 @@ _docker_events() { unpause untag update - " -- "${cur#=}" ) ) + " -- "${cur##*=}" ) ) return ;; - *image=*) - cur="${cur#=}" + image) + cur="${cur##*=}" __docker_complete_images return ;; - *network=*) - ## BUG: this also triggers after -f type=network - cur="${cur#=}" + network) + cur="${cur##*=}" __docker_complete_networks return ;; - *type=*) - COMPREPLY=( $( compgen -W "container image network volume" -- "${cur#=}" ) ) + type) + COMPREPLY=( $( compgen -W "container image network volume" -- "${cur##*=}" ) ) return ;; - *volume=*) - cur="${cur#=}" + volume) + cur="${cur##*=}" __docker_complete_volumes return ;; 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 -*) COMPREPLY=( $( compgen -W "--filter -f --help --since --until" -- "$cur" ) )