diff --git a/contrib/completion/bash/docker b/contrib/completion/bash/docker index c8c02ecbfc..0375e6f95b 100644 --- a/contrib/completion/bash/docker +++ b/contrib/completion/bash/docker @@ -138,6 +138,10 @@ __docker_containers_and_images() { COMPREPLY+=( "${containers[@]}" ) } +__docker_networks() { + COMPREPLY=( $(compgen -W "$(__docker_q network ls | awk 'NR>1 {print $2}')" -- "$cur") ) +} + __docker_volumes() { COMPREPLY=( $(compgen -W "$(__docker_q volume ls -q)" -- "$cur") ) } @@ -149,7 +153,7 @@ __docker_volumes() { __docker_pos_first_nonflag() { local argument_flags=$1 - local counter=$((command_pos + 1)) + local counter=$((${subcommand_pos:-${command_pos}} + 1)) while [ $counter -le $cword ]; do if [ -n "$argument_flags" ] && eval "case '${words[$counter]}' in $argument_flags) true ;; *) false ;; esac"; then (( counter++ )) @@ -212,6 +216,35 @@ __docker_to_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 __docker_nospace() { # compopt is not available in ancient bash versions @@ -965,6 +998,98 @@ _docker_logs() { esac } +_docker_network_connect() { + case "$cur" in + -*) + COMPREPLY=( $( compgen -W "--help" -- "$cur" ) ) + ;; + *) + local counter=$(__docker_pos_first_nonflag '--tail') + if [ $cword -eq $counter ]; then + __docker_networks + elif [ $cword -eq $(($counter + 1)) ]; then + __docker_containers_running + fi + ;; + esac +} + +_docker_network_create() { + case "$prev" in + --driver|-d) + # no need to suggest drivers that allow one instance only + # (host, null) + COMPREPLY=( $( compgen -W "bridge overlay" -- "$cur" ) ) + return + ;; + esac + + case "$cur" in + -*) + COMPREPLY=( $( compgen -W "--driver -d --help" -- "$cur" ) ) + ;; + esac +} + +_docker_network_disconnect() { + # TODO disconnect should only complete running containers connected + # to the specified network. + _docker_network_connect +} + +_docker_network_inspect() { + case "$cur" in + -*) + COMPREPLY=( $( compgen -W "--help" -- "$cur" ) ) + ;; + *) + local counter=$(__docker_pos_first_nonflag) + if [ $cword -eq $counter ]; then + __docker_networks + fi + ;; + esac +} + +_docker_network_ls() { + case "$prev" in + -n) + return + ;; + esac + + case "$cur" in + -*) + COMPREPLY=( $( compgen -W "--help --latest -l -n --no-trunc --quiet -q" -- "$cur" ) ) + ;; + esac +} + +_docker_network_rm() { + _docker_network_inspect +} + +_docker_network() { + local subcommands=" + connect + create + disconnect + inspect + ls + rm + " + __docker_subcommands "$subcommands" && return + + case "$cur" in + -*) + COMPREPLY=( $( compgen -W "--help" -- "$cur" ) ) + ;; + *) + COMPREPLY=( $( compgen -W "$subcommands" -- "$cur" ) ) + ;; + esac +} + _docker_pause() { case "$cur" in -*) @@ -1540,33 +1665,20 @@ _docker_volume_rm() { } _docker_volume() { - local subcommands=( + local subcommands=" create inspect ls 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 -*) COMPREPLY=( $( compgen -W "--help" -- "$cur" ) ) ;; *) - COMPREPLY=( $( compgen -W "${subcommands[*]}" -- "$cur" ) ) + COMPREPLY=( $( compgen -W "$subcommands" -- "$cur" ) ) ;; esac } @@ -1607,6 +1719,7 @@ _docker() { login logout logs + network pause port ps @@ -1652,7 +1765,7 @@ _docker() { local 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 while [ $counter -lt $cword ]; do case "${words[$counter]}" in