From 6f9bd6c1b87ca876617b349e00f5e51cc3ef716c Mon Sep 17 00:00:00 2001 From: Harald Albers Date: Sun, 7 Feb 2016 10:02:30 -0800 Subject: [PATCH 1/2] Check key specific bash subcompletions first This is a refactoring in preparation of cleaning up the handling of key specific subcompletions. The new `__docker_map_key_of_current_option()` function will be used instead of the `__docker_map_key_of_current_option()` idiom in the following commit. As this function is very specific, checks using it should be executed before those checking for `$prev`. This commit just moves the checks without any modification. Signed-off-by: Harald Albers --- contrib/completion/bash/docker | 128 ++++++++++++++++----------------- 1 file changed, 64 insertions(+), 64 deletions(-) diff --git a/contrib/completion/bash/docker b/contrib/completion/bash/docker index 4bb8f75f43..6d1f626da7 100644 --- a/contrib/completion/bash/docker +++ b/contrib/completion/bash/docker @@ -787,6 +787,29 @@ _docker_daemon() { --userns-remap " + __docker_complete_log_driver_options && return + + case "${words[$cword-2]}$prev=" in + # completions for --storage-opt + *dm.@(blkdiscard|override_udev_sync_check|use_deferred_@(removal|deletion))=*) + COMPREPLY=( $( compgen -W "false true" -- "${cur#=}" ) ) + return + ;; + *dm.fs=*) + COMPREPLY=( $( compgen -W "ext4 xfs" -- "${cur#=}" ) ) + return + ;; + *dm.thinpooldev=*) + _filedir + return + ;; + # completions for --cluster-store-opt + *kv.*file=*) + _filedir + return + ;; + esac + case "$prev" in --authorization-plugin) __docker_complete_plugins Authorization @@ -869,29 +892,6 @@ _docker_daemon() { ;; esac - __docker_complete_log_driver_options && return - - case "${words[$cword-2]}$prev=" in - # completions for --storage-opt - *dm.@(blkdiscard|override_udev_sync_check|use_deferred_@(removal|deletion))=*) - COMPREPLY=( $( compgen -W "false true" -- "${cur#=}" ) ) - return - ;; - *dm.fs=*) - COMPREPLY=( $( compgen -W "ext4 xfs" -- "${cur#=}" ) ) - return - ;; - *dm.thinpooldev=*) - _filedir - return - ;; - # completions for --cluster-store-opt - *kv.*file=*) - _filedir - return - ;; - esac - case "$cur" in -*) COMPREPLY=( $( compgen -W "$boolean_options $options_with_args" -- "$cur" ) ) @@ -1051,6 +1051,16 @@ _docker_history() { } _docker_images() { + case "${words[$cword-2]}$prev=" in + *dangling=*) + COMPREPLY=( $( compgen -W "true false" -- "${cur#=}" ) ) + return + ;; + *label=*) + return + ;; + esac + case "$prev" in --filter|-f) COMPREPLY=( $( compgen -S = -W "dangling label" -- "$cur" ) ) @@ -1062,16 +1072,6 @@ _docker_images() { ;; esac - case "${words[$cword-2]}$prev=" in - *dangling=*) - COMPREPLY=( $( compgen -W "true false" -- "${cur#=}" ) ) - return - ;; - *label=*) - return - ;; - esac - case "$cur" in -*) COMPREPLY=( $( compgen -W "--all -a --digests --filter -f --format --help --no-trunc --quiet -q" -- "$cur" ) ) @@ -1329,14 +1329,6 @@ _docker_network_inspect() { } _docker_network_ls() { - case "$prev" in - --filter|-f) - COMPREPLY=( $( compgen -S = -W "id name type" -- "$cur" ) ) - __docker_nospace - return - ;; - esac - case "${words[$cword-2]}$prev=" in *id=*) cur="${cur#=}" @@ -1354,6 +1346,14 @@ _docker_network_ls() { ;; esac + case "$prev" in + --filter|-f) + COMPREPLY=( $( compgen -S = -W "id name type" -- "$cur" ) ) + __docker_nospace + return + ;; + esac + case "$cur" in -*) COMPREPLY=( $( compgen -W "--filter -f --help --no-trunc --quiet -q" -- "$cur" ) ) @@ -1421,20 +1421,6 @@ _docker_port() { } _docker_ps() { - case "$prev" in - --before|--since) - __docker_complete_containers_all - ;; - --filter|-f) - COMPREPLY=( $( compgen -S = -W "ancestor exited id label name status" -- "$cur" ) ) - __docker_nospace - return - ;; - --format|-n) - return - ;; - esac - case "${words[$cword-2]}$prev=" in *ancestor=*) cur="${cur#=}" @@ -1457,6 +1443,20 @@ _docker_ps() { ;; esac + case "$prev" in + --before|--since) + __docker_complete_containers_all + ;; + --filter|-f) + COMPREPLY=( $( compgen -S = -W "ancestor exited id label name status" -- "$cur" ) ) + __docker_nospace + return + ;; + --format|-n) + return + ;; + esac + case "$cur" in -*) COMPREPLY=( $( compgen -W "--all -a --before --filter -f --format --help --latest -l -n --no-trunc --quiet -q --size -s --since" -- "$cur" ) ) @@ -1651,6 +1651,8 @@ _docker_run() { local all_options="$options_with_args $boolean_options" + __docker_complete_log_driver_options && return + case "$prev" in --add-host) case "$cur" in @@ -1797,8 +1799,6 @@ _docker_run() { ;; esac - __docker_complete_log_driver_options && return - case "$cur" in -*) COMPREPLY=( $( compgen -W "$all_options" -- "$cur" ) ) @@ -2015,17 +2015,17 @@ _docker_volume_inspect() { } _docker_volume_ls() { - case "$prev" in - --filter|-f) - COMPREPLY=( $( compgen -S = -W "dangling" -- "$cur" ) ) - __docker_nospace + case "${words[$cword-2]}$prev=" in + *dangling=*) + COMPREPLY=( $( compgen -W "true false" -- "${cur#=}" ) ) return ;; esac - case "${words[$cword-2]}$prev=" in - *dangling=*) - COMPREPLY=( $( compgen -W "true false" -- "${cur#=}" ) ) + case "$prev" in + --filter|-f) + COMPREPLY=( $( compgen -S = -W "dangling" -- "$cur" ) ) + __docker_nospace return ;; esac From 7e31a96d220fe53e101c35332f5772ff42bcd092 Mon Sep 17 00:00:00 2001 From: Harald Albers Date: Sun, 7 Feb 2016 10:05:43 -0800 Subject: [PATCH 2/2] Improve key specific bash subcompletions The obscure `case "${words[$cword-2]}$prev=" in` idiom is no longer used for key specific completions in options with map values. The `__docker_map_key_of_current_option()` function does a much better job. Signed-off-by: Harald Albers --- contrib/completion/bash/docker | 132 +++++++++++++++++---------------- 1 file changed, 69 insertions(+), 63 deletions(-) diff --git a/contrib/completion/bash/docker b/contrib/completion/bash/docker index 6d1f626da7..7588e33355 100644 --- a/contrib/completion/bash/docker +++ b/contrib/completion/bash/docker @@ -227,7 +227,6 @@ __docker_pos_first_nonflag() { # 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" @@ -452,21 +451,20 @@ __docker_complete_log_options() { } __docker_complete_log_driver_options() { - # "=" gets parsed to a word and assigned to either $cur or $prev depending on whether - # it is the last character or not. So we search for "xxx=" in the the last two words. - case "${words[$cword-2]}$prev=" in - *gelf-address=*) - COMPREPLY=( $( compgen -W "udp" -S "://" -- "${cur#=}" ) ) + local key=$(__docker_map_key_of_current_option '--log-opt') + case "$key" in + gelf-address) + COMPREPLY=( $( compgen -W "udp" -S "://" -- "${cur##*=}" ) ) __docker_nospace return ;; - *syslog-address=*) - COMPREPLY=( $( compgen -W "tcp:// tcp+tls:// udp:// unix://" -- "${cur#=}" ) ) + syslog-address) + COMPREPLY=( $( compgen -W "tcp:// tcp+tls:// udp:// unix://" -- "${cur##*=}" ) ) __docker_nospace __ltrim_colon_completions "${cur}" return ;; - *syslog-facility=*) + syslog-facility) COMPREPLY=( $( compgen -W " auth authpriv @@ -488,26 +486,25 @@ __docker_complete_log_driver_options() { syslog user uucp - " -- "${cur#=}" ) ) + " -- "${cur##*=}" ) ) return ;; - *syslog-tls-@(ca-cert|cert|key)=*) + syslog-tls-@(ca-cert|cert|key)) _filedir return ;; - *syslog-tls-skip-verify=*) - COMPREPLY=( $( compgen -W "true" -- "${cur#=}" ) ) + syslog-tls-skip-verify) + COMPREPLY=( $( compgen -W "true" -- "${cur##*=}" ) ) return ;; - *splunk-url=*) - COMPREPLY=( $( compgen -W "http:// https://" -- "${cur#=}" ) ) + splunk-url) + COMPREPLY=( $( compgen -W "http:// https://" -- "${cur##*=}" ) ) __docker_nospace __ltrim_colon_completions "${cur}" return ;; - *splunk-insecureskipverify=*) - COMPREPLY=( $( compgen -W "true false" -- "${cur#=}" ) ) - __docker_nospace + splunk-insecureskipverify) + COMPREPLY=( $( compgen -W "false true" -- "${cur##*=}" ) ) return ;; esac @@ -789,26 +786,31 @@ _docker_daemon() { __docker_complete_log_driver_options && return - case "${words[$cword-2]}$prev=" in - # completions for --storage-opt - *dm.@(blkdiscard|override_udev_sync_check|use_deferred_@(removal|deletion))=*) - COMPREPLY=( $( compgen -W "false true" -- "${cur#=}" ) ) - return - ;; - *dm.fs=*) - COMPREPLY=( $( compgen -W "ext4 xfs" -- "${cur#=}" ) ) - return - ;; - *dm.thinpooldev=*) - _filedir - return - ;; - # completions for --cluster-store-opt - *kv.*file=*) - _filedir - return - ;; - esac + key=$(__docker_map_key_of_current_option '--cluster-store-opt') + case "$key" in + kv.*file) + cur=${cur##*=} + _filedir + return + ;; + esac + + local key=$(__docker_map_key_of_current_option '--storage-opt') + case "$key" in + dm.@(blkdiscard|override_udev_sync_check|use_deferred_@(removal|deletion))) + COMPREPLY=( $( compgen -W "false true" -- "${cur##*=}" ) ) + return + ;; + dm.fs) + COMPREPLY=( $( compgen -W "ext4 xfs" -- "${cur##*=}" ) ) + return + ;; + dm.thinpooldev) + cur=${cur##*=} + _filedir + return + ;; + esac case "$prev" in --authorization-plugin) @@ -914,8 +916,8 @@ _docker_diff() { } _docker_events() { - local filter=$(__docker_map_key_of_current_option '-f|--filter') - case "$filter" in + local key=$(__docker_map_key_of_current_option '-f|--filter') + case "$key" in container) cur="${cur##*=}" __docker_complete_containers_all @@ -1051,12 +1053,13 @@ _docker_history() { } _docker_images() { - case "${words[$cword-2]}$prev=" in - *dangling=*) - COMPREPLY=( $( compgen -W "true false" -- "${cur#=}" ) ) + local key=$(__docker_map_key_of_current_option '--filter|-f') + case "$key" in + dangling) + COMPREPLY=( $( compgen -W "false true" -- "${cur##*=}" ) ) return ;; - *label=*) + label) return ;; esac @@ -1329,19 +1332,20 @@ _docker_network_inspect() { } _docker_network_ls() { - case "${words[$cword-2]}$prev=" in - *id=*) - cur="${cur#=}" + local key=$(__docker_map_key_of_current_option '--filter|-f') + case "$key" in + id) + cur="${cur##*=}" __docker_complete_network_ids return ;; - *name=*) - cur="${cur#=}" + name) + cur="${cur##*=}" __docker_complete_network_names return ;; - *type=*) - COMPREPLY=( $( compgen -W "builtin custom" -- "${cur#=}" ) ) + type) + COMPREPLY=( $( compgen -W "builtin custom" -- "${cur##*=}" ) ) return ;; esac @@ -1421,24 +1425,25 @@ _docker_port() { } _docker_ps() { - case "${words[$cword-2]}$prev=" in - *ancestor=*) - cur="${cur#=}" + local key=$(__docker_map_key_of_current_option '--filter|-f') + case "$key" in + ancestor) + cur="${cur##*=}" __docker_complete_images return ;; - *id=*) - cur="${cur#=}" + id) + cur="${cur##*=}" __docker_complete_container_ids return ;; - *name=*) - cur="${cur#=}" + name) + cur="${cur##*=}" __docker_complete_container_names return ;; - *status=*) - COMPREPLY=( $( compgen -W "created dead exited paused restarting running" -- "${cur#=}" ) ) + status) + COMPREPLY=( $( compgen -W "created dead exited paused restarting running" -- "${cur##*=}" ) ) return ;; esac @@ -2015,9 +2020,10 @@ _docker_volume_inspect() { } _docker_volume_ls() { - case "${words[$cword-2]}$prev=" in - *dangling=*) - COMPREPLY=( $( compgen -W "true false" -- "${cur#=}" ) ) + local key=$(__docker_map_key_of_current_option '--filter|-f') + case "$key" in + dangling) + COMPREPLY=( $( compgen -W "true false" -- "${cur##*=}" ) ) return ;; esac