From 9ef7847f74d6bfd57c2cdae59518ab9c894681ac Mon Sep 17 00:00:00 2001 From: Harald Albers Date: Thu, 13 Oct 2016 04:09:53 -0700 Subject: [PATCH] Improve bash completion of containers Signed-off-by: Harald Albers --- contrib/completion/bash/docker | 80 +++++++++++++++++++++------------- 1 file changed, 49 insertions(+), 31 deletions(-) diff --git a/contrib/completion/bash/docker b/contrib/completion/bash/docker index 84401ca9..96d93ac1 100644 --- a/contrib/completion/bash/docker +++ b/contrib/completion/bash/docker @@ -20,6 +20,7 @@ # For several commands, the amount of completions can be configured by # setting environment variables. # +# DOCKER_COMPLETION_SHOW_CONTAINER_IDS # DOCKER_COMPLETION_SHOW_NETWORK_IDS # DOCKER_COMPLETION_SHOW_NODE_IDS # DOCKER_COMPLETION_SHOW_SERVICE_IDS @@ -58,32 +59,56 @@ __docker_q() { docker ${host:+-H "$host"} ${config:+--config "$config"} 2>/dev/null "$@" } -__docker_complete_containers_all() { - local IFS=$'\n' - local containers=( $(__docker_q ps -aq --no-trunc) ) - if [ "$1" ]; then - containers=( $(__docker_q inspect --format "{{if $1}}{{.Id}}{{end}}" "${containers[@]}") ) +# Returns a list of containers. Additional arguments to `docker ps` +# may be specified in order to filter the list, e.g. +# `__docker_containers --filter status=running` +# By default, only names are returned. +# Set DOCKER_COMPLETION_SHOW_CONTAINER_IDS=yes to also complete IDs. +# An optional first option `--id|--name` may be used to limit the +# output to the IDs or names of matching items. This setting takes +# precedence over the environment setting. +__docker_containers() { + local format + if [ "$1" = "--id" ] ; then + format='{{.ID}}' + shift + elif [ "$1" = "--name" ] ; then + format='{{.Names}}' + shift + elif [ "${DOCKER_COMPLETION_SHOW_CONTAINER_IDS}" = yes ] ; then + format='{{.ID}} {{.Names}}' + else + format='{{.Names}}' fi - local names=( $(__docker_q inspect --format '{{.Name}}' "${containers[@]}") ) - names=( "${names[@]#/}" ) # trim off the leading "/" from the container names - unset IFS - COMPREPLY=( $(compgen -W "${names[*]} ${containers[*]}" -- "$cur") ) + __docker_q ps --format "$format" "$@" +} + +# Applies completion of containers based on the current value of `$cur` or +# the value of the optional first option `--cur`, if given. +# Additional filters may be appended, see `__docker_containers`. +__docker_complete_containers() { + local current="$cur" + if [ "$1" = "--cur" ] ; then + current="$2" + shift 2 + fi + COMPREPLY=( $(compgen -W "$(__docker_containers "$@")" -- "$current") ) +} + +__docker_complete_containers_all() { + __docker_complete_containers "$@" --all } __docker_complete_containers_running() { - __docker_complete_containers_all '.State.Running' + __docker_complete_containers "$@" --filter status=running } __docker_complete_containers_stopped() { - __docker_complete_containers_all 'not .State.Running' -} - -__docker_complete_containers_pauseable() { - __docker_complete_containers_all 'and .State.Running (not .State.Paused)' + __docker_complete_containers "$@" --filter status=exited } __docker_complete_containers_unpauseable() { - __docker_complete_containers_all '.State.Paused' + __docker_complete_containers "$@" --filter status=paused } __docker_complete_container_names() { @@ -1114,8 +1139,7 @@ _docker_events() { local key=$(__docker_map_key_of_current_option '-f|--filter') case "$key" in container) - cur="${cur##*=}" - __docker_complete_containers_all + __docker_complete_containers_all --cur "${cur##*=}" return ;; daemon) @@ -2172,7 +2196,7 @@ _docker_pause() { *) local counter=$(__docker_pos_first_nonflag) if [ $cword -eq $counter ]; then - __docker_complete_containers_pauseable + __docker_complete_containers_running fi ;; esac @@ -2201,13 +2225,11 @@ _docker_ps() { return ;; before) - cur="${cur##*=}" - __docker_complete_containers_all + __docker_complete_containers_all --cur "${cur##*=}" return ;; id) - cur="${cur##*=}" - __docker_complete_container_ids + __docker_complete_containers_all --cur "${cur##*=}" --id return ;; is-task) @@ -2215,8 +2237,7 @@ _docker_ps() { return ;; name) - cur="${cur##*=}" - __docker_complete_container_names + __docker_complete_containers_all --cur "${cur##*=}" --name return ;; network) @@ -2224,8 +2245,7 @@ _docker_ps() { return ;; since) - cur="${cur##*=}" - __docker_complete_containers_all + __docker_complete_containers_all --cur "${cur##*=}" return ;; status) @@ -2560,8 +2580,7 @@ _docker_run() { --network) case "$cur" in container:*) - local cur=${cur#*:} - __docker_complete_containers_all + __docker_complete_containers_all --cur "${cur#*:}" ;; *) COMPREPLY=( $( compgen -W "$(__docker_plugins Network) $(__docker_networks) container:" -- "$cur") ) @@ -2575,8 +2594,7 @@ _docker_run() { --pid) case "$cur" in *:*) - cur="${cur#*:}" - __docker_complete_containers_running + __docker_complete_containers_running --cur "${cur#*:}" ;; *) COMPREPLY=( $( compgen -W 'host container:' -- "$cur" ) )