From 11311b17f6e108d1b201f47f46f6a2619031fbfd Mon Sep 17 00:00:00 2001 From: ravenhall Date: Thu, 19 May 2016 22:08:46 -0500 Subject: [PATCH 1/8] Implemented solution to issue #676 --- install.sh | 55 ++++++++++++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 51 insertions(+), 4 deletions(-) diff --git a/install.sh b/install.sh index 17250eb0..ff354b19 100755 --- a/install.sh +++ b/install.sh @@ -1,4 +1,44 @@ #!/usr/bin/env bash +# bash-it installer +show_usage() { + echo -e "\n$0 : Install bash-it" + echo -e "Usage:\n$0 [arguments] \n" + echo "Arguments:" + echo "--help (-h): Display this help message" + echo "--silent (-s): Install default settings without prompting for input"; + echo "--interactive (-i): Interactively choose plugins" + exit 0; +} + +echo "Installing bash-it" + +for param in "$@"; do + shift + case "$param" in + "--help") set -- "$@" "-h" ;; + "--silent") set -- "$@" "-s" ;; + "--interactive") set -- "$@" "-i" ;; + *) set -- "$@" "$param" + esac +done + +OPTIND=1 +while getopts "hsi" opt +do + case "$opt" in + "h") show_usage; exit 0 ;; + "s") silent=true ;; + "i") interactive=true ;; + "?") show_usage >&2; exit 1 ;; + esac +done +shift $(expr $OPTIND - 1) + +if [[ $silent ]] && [[ $interactive ]]; then + echo "Options --silent and --interactive are mutually exclusive. Please choose one or the other." + exit 1; +fi + BASH_IT="$(cd "$(dirname "$0")" && pwd)" case $OSTYPE in @@ -14,8 +54,7 @@ BACKUP_FILE=$CONFIG_FILE.bak if [ -e "$HOME/$BACKUP_FILE" ]; then echo -e "\033[0;33mBackup file already exists. Make sure to backup your .bashrc before running this installation.\033[0m" >&2 - while true - do + while ! [ $silent ]; do read -e -n 1 -r -p "Would you like to overwrite the existing backup? This will delete your existing backup file ($HOME/$BACKUP_FILE) [y/N] " RESP case $RESP in [yY]) @@ -32,7 +71,7 @@ if [ -e "$HOME/$BACKUP_FILE" ]; then done fi -while true +while ! [ $silent ] do read -e -n 1 -r -p "Would you like to keep your $CONFIG_FILE and append bash-it templates at the end? [y/N] " choice case $choice in @@ -58,6 +97,14 @@ do esac done +if [ $silent ]; then + # backup/new by default + test -w "$HOME/$CONFIG_FILE" && + cp -aL "$HOME/$CONFIG_FILE" "$HOME/$CONFIG_FILE.bak" && + echo -e "\033[0;32mYour original $CONFIG_FILE has been backed up to $CONFIG_FILE.bak\033[0m" + sed "s|{{BASH_IT}}|$BASH_IT|" "$BASH_IT/template/bash_profile.template.bash" > "$HOME/$CONFIG_FILE" +fi + echo -e "\033[0;32mCopied the template $CONFIG_FILE into ~/$CONFIG_FILE, edit this file to customize bash-it\033[0m" function load_one() { @@ -98,7 +145,7 @@ function load_some() { done } -if [[ "$1" == "--interactive" ]] +if [[ $interactive ]] && ! [[ $silent ]] ; then for type in "aliases" "plugins" "completion" do From c6c21abb0eec8199ff50f7b4f0875761c5d2a329 Mon Sep 17 00:00:00 2001 From: ravenhall Date: Tue, 31 May 2016 14:14:12 -0500 Subject: [PATCH 2/8] Colorized error, relocated installing message, created backup_new func, reformatted do --- install.sh | 29 +++++++++++++---------------- 1 file changed, 13 insertions(+), 16 deletions(-) diff --git a/install.sh b/install.sh index ff354b19..ac53675a 100755 --- a/install.sh +++ b/install.sh @@ -10,8 +10,6 @@ show_usage() { exit 0; } -echo "Installing bash-it" - for param in "$@"; do shift case "$param" in @@ -35,7 +33,7 @@ done shift $(expr $OPTIND - 1) if [[ $silent ]] && [[ $interactive ]]; then - echo "Options --silent and --interactive are mutually exclusive. Please choose one or the other." + echo "\033[91mOptions --silent and --interactive are mutually exclusive. Please choose one or the other.\033[m" exit 1; fi @@ -51,7 +49,7 @@ case $OSTYPE in esac BACKUP_FILE=$CONFIG_FILE.bak - +echo "Installing bash-it" if [ -e "$HOME/$BACKUP_FILE" ]; then echo -e "\033[0;33mBackup file already exists. Make sure to backup your .bashrc before running this installation.\033[0m" >&2 while ! [ $silent ]; do @@ -71,8 +69,7 @@ if [ -e "$HOME/$BACKUP_FILE" ]; then done fi -while ! [ $silent ] -do +while ! [ $silent ]; do read -e -n 1 -r -p "Would you like to keep your $CONFIG_FILE and append bash-it templates at the end? [y/N] " choice case $choice in [yY]) @@ -85,10 +82,7 @@ do break ;; [nN]|"") - test -w "$HOME/$CONFIG_FILE" && - cp -aL "$HOME/$CONFIG_FILE" "$HOME/$CONFIG_FILE.bak" && - echo -e "\033[0;32mYour original $CONFIG_FILE has been backed up to $CONFIG_FILE.bak\033[0m" - sed "s|{{BASH_IT}}|$BASH_IT|" "$BASH_IT/template/bash_profile.template.bash" > "$HOME/$CONFIG_FILE" + backup_new break ;; *) @@ -99,14 +93,9 @@ done if [ $silent ]; then # backup/new by default - test -w "$HOME/$CONFIG_FILE" && - cp -aL "$HOME/$CONFIG_FILE" "$HOME/$CONFIG_FILE.bak" && - echo -e "\033[0;32mYour original $CONFIG_FILE has been backed up to $CONFIG_FILE.bak\033[0m" - sed "s|{{BASH_IT}}|$BASH_IT|" "$BASH_IT/template/bash_profile.template.bash" > "$HOME/$CONFIG_FILE" + backup_new fi -echo -e "\033[0;32mCopied the template $CONFIG_FILE into ~/$CONFIG_FILE, edit this file to customize bash-it\033[0m" - function load_one() { file_type=$1 file_to_enable=$2 @@ -145,6 +134,14 @@ function load_some() { done } +function backup_new() { + test -w "$HOME/$CONFIG_FILE" && + cp -aL "$HOME/$CONFIG_FILE" "$HOME/$CONFIG_FILE.bak" && + echo -e "\033[0;32mYour original $CONFIG_FILE has been backed up to $CONFIG_FILE.bak\033[0m" + sed "s|{{BASH_IT}}|$BASH_IT|" "$BASH_IT/template/bash_profile.template.bash" > "$HOME/$CONFIG_FILE" + echo -e "\033[0;32mCopied the template $CONFIG_FILE into ~/$CONFIG_FILE, edit this file to customize bash-it\033[0m" +} + if [[ $interactive ]] && ! [[ $silent ]] ; then for type in "aliases" "plugins" "completion" From 49afeb707e385bae2368acdc22d0bd271ae2a1c8 Mon Sep 17 00:00:00 2001 From: ravenhall Date: Tue, 31 May 2016 18:45:36 -0500 Subject: [PATCH 3/8] Added forgotten -e and moved funcs to the top to prevent scoping issue --- install.sh | 101 ++++++++++++++++++++++++++++------------------------- 1 file changed, 53 insertions(+), 48 deletions(-) diff --git a/install.sh b/install.sh index ac53675a..e6518042 100755 --- a/install.sh +++ b/install.sh @@ -1,6 +1,8 @@ #!/usr/bin/env bash # bash-it installer -show_usage() { + +# Show how to use this installer +function show_usage() { echo -e "\n$0 : Install bash-it" echo -e "Usage:\n$0 [arguments] \n" echo "Arguments:" @@ -10,6 +12,55 @@ show_usage() { exit 0; } +# enable a thing +function load_one() { + file_type=$1 + file_to_enable=$2 + mkdir -p "$BASH_IT/${file_type}/enabled" + + dest="${BASH_IT}/${file_type}/enabled/${file_to_enable}" + if [ ! -e "${dest}" ]; then + ln -sf "../available/${file_to_enable}" "${dest}" + else + echo "File ${dest} exists, skipping" + fi +} + +# Interactively enable several things +function load_some() { + file_type=$1 + [ -d "$BASH_IT/$file_type/enabled" ] || mkdir "$BASH_IT/$file_type/enabled" + for path in `ls $BASH_IT/${file_type}/available/[^_]*` + do + file_name=$(basename "$path") + while true + do + read -e -n 1 -p "Would you like to enable the ${file_name%%.*} $file_type? [y/N] " RESP + case $RESP in + [yY]) + ln -s "../available/${file_name}" "$BASH_IT/$file_type/enabled" + break + ;; + [nN]|"") + break + ;; + *) + echo -e "\033[91mPlease choose y or n.\033[m" + ;; + esac + done + done +} + +# Back up existing profile and create new one for bash-it +function backup_new() { + test -w "$HOME/$CONFIG_FILE" && + cp -aL "$HOME/$CONFIG_FILE" "$HOME/$CONFIG_FILE.bak" && + echo -e "\033[0;32mYour original $CONFIG_FILE has been backed up to $CONFIG_FILE.bak\033[0m" + sed "s|{{BASH_IT}}|$BASH_IT|" "$BASH_IT/template/bash_profile.template.bash" > "$HOME/$CONFIG_FILE" + echo -e "\033[0;32mCopied the template $CONFIG_FILE into ~/$CONFIG_FILE, edit this file to customize bash-it\033[0m" +} + for param in "$@"; do shift case "$param" in @@ -33,7 +84,7 @@ done shift $(expr $OPTIND - 1) if [[ $silent ]] && [[ $interactive ]]; then - echo "\033[91mOptions --silent and --interactive are mutually exclusive. Please choose one or the other.\033[m" + echo -e "\033[91mOptions --silent and --interactive are mutually exclusive. Please choose one or the other.\033[m" exit 1; fi @@ -96,52 +147,6 @@ if [ $silent ]; then backup_new fi -function load_one() { - file_type=$1 - file_to_enable=$2 - mkdir -p "$BASH_IT/${file_type}/enabled" - - dest="${BASH_IT}/${file_type}/enabled/${file_to_enable}" - if [ ! -e "${dest}" ]; then - ln -sf "../available/${file_to_enable}" "${dest}" - else - echo "File ${dest} exists, skipping" - fi -} - -function load_some() { - file_type=$1 - [ -d "$BASH_IT/$file_type/enabled" ] || mkdir "$BASH_IT/$file_type/enabled" - for path in `ls $BASH_IT/${file_type}/available/[^_]*` - do - file_name=$(basename "$path") - while true - do - read -e -n 1 -p "Would you like to enable the ${file_name%%.*} $file_type? [y/N] " RESP - case $RESP in - [yY]) - ln -s "../available/${file_name}" "$BASH_IT/$file_type/enabled" - break - ;; - [nN]|"") - break - ;; - *) - echo -e "\033[91mPlease choose y or n.\033[m" - ;; - esac - done - done -} - -function backup_new() { - test -w "$HOME/$CONFIG_FILE" && - cp -aL "$HOME/$CONFIG_FILE" "$HOME/$CONFIG_FILE.bak" && - echo -e "\033[0;32mYour original $CONFIG_FILE has been backed up to $CONFIG_FILE.bak\033[0m" - sed "s|{{BASH_IT}}|$BASH_IT|" "$BASH_IT/template/bash_profile.template.bash" > "$HOME/$CONFIG_FILE" - echo -e "\033[0;32mCopied the template $CONFIG_FILE into ~/$CONFIG_FILE, edit this file to customize bash-it\033[0m" -} - if [[ $interactive ]] && ! [[ $silent ]] ; then for type in "aliases" "plugins" "completion" From d1f5648b6bb00dc5e9bd6308a19f7473781d79d6 Mon Sep 17 00:00:00 2001 From: Beorn Facchini Date: Sun, 3 Jul 2016 11:51:08 +1000 Subject: [PATCH 4/8] Bash-it theme inspired by oh-my-zsh tonotdo. --- themes/tonotdo/tonotdo.theme.bash | 13 +++++++++++++ 1 file changed, 13 insertions(+) create mode 100644 themes/tonotdo/tonotdo.theme.bash diff --git a/themes/tonotdo/tonotdo.theme.bash b/themes/tonotdo/tonotdo.theme.bash new file mode 100644 index 00000000..a1e18ba6 --- /dev/null +++ b/themes/tonotdo/tonotdo.theme.bash @@ -0,0 +1,13 @@ +#!/usr/bin/env bash + +SCM_THEME_PROMPT_PREFIX=" ${purple}" +SCM_THEME_PROMPT_SUFFIX=" ${normal}" +SCM_THEME_PROMPT_DIRTY=" ${red}✗" +SCM_THEME_PROMPT_CLEAN=" ${green}✓" +SCM_GIT_SHOW_DETAILS="false" + +function prompt_command() { + PS1="${yellow}\u${normal}${cyan}@\h${normal}${purple} ${normal}${green}\w${normal}$(scm_prompt_info)> " +} + +PROMPT_COMMAND=prompt_command From 482703e754cdd57f20950aafc4b614ab0b4922f3 Mon Sep 17 00:00:00 2001 From: Forrest Sill Date: Tue, 5 Jul 2016 11:36:22 -0700 Subject: [PATCH 5/8] Add `gap` alias for `git add -p` - Useful for seeing your changes before committing Signed-off-by: Lyle Franklin --- aliases/available/git.aliases.bash | 1 + 1 file changed, 1 insertion(+) diff --git a/aliases/available/git.aliases.bash b/aliases/available/git.aliases.bash index d80c0927..843f3c99 100644 --- a/aliases/available/git.aliases.bash +++ b/aliases/available/git.aliases.bash @@ -4,6 +4,7 @@ about-alias 'common git abbreviations' # Aliases alias gcl='git clone' alias ga='git add' +alias gap='git add -p' alias gall='git add -A' alias gf='git fetch --all --prune' alias gft='git fetch --all --prune --tags' From 03600e0da157d068fc5e411423a701b66c40eb33 Mon Sep 17 00:00:00 2001 From: Nils Winkler Date: Wed, 6 Jul 2016 08:21:38 +0200 Subject: [PATCH 6/8] Added docker-compose plugin Only function so far: docker-compose-fresh, which shuts down a running docker-compose instance, deletes the containers, and starts up fresh instances, then tails the container logs. Converted this from an alias to a function so that a parameter can be provided for the name of the docker-compose.yaml file name. --- aliases/available/docker-compose.aliases.bash | 3 ++- plugins/available/docker-compose.plugin.bash | 20 +++++++++++++++++++ 2 files changed, 22 insertions(+), 1 deletion(-) create mode 100644 plugins/available/docker-compose.plugin.bash diff --git a/aliases/available/docker-compose.aliases.bash b/aliases/available/docker-compose.aliases.bash index 99b1db19..01eb62fb 100644 --- a/aliases/available/docker-compose.aliases.bash +++ b/aliases/available/docker-compose.aliases.bash @@ -2,4 +2,5 @@ cite 'about-alias' about-alias 'docker-compose abbreviations' alias dco="docker-compose" -alias dcofresh="docker-compose stop ; docker-compose rm -f ; docker-compose up -d ; docker-compose logs" +alias dcofresh="docker-compose-fresh" +alias dcol="docker-compose logs -f --tail 100" diff --git a/plugins/available/docker-compose.plugin.bash b/plugins/available/docker-compose.plugin.bash new file mode 100644 index 00000000..e46c709f --- /dev/null +++ b/plugins/available/docker-compose.plugin.bash @@ -0,0 +1,20 @@ +cite about-plugin +about-plugin 'Helper functions for using docker-compose' + +function docker-compose-fresh() { + about 'Shut down, remove and start again the docker-compose setup, then tail the logs' + group 'docker-compose' + param '1: name of the docker-compose.yaml file to use (optional). Default: docker-compose.yaml' + example 'docker-compose-fresh docker-compose-foo.yaml' + + local DCO_FILE_PARAM="" + if [ -n "$1" ]; then + echo "Using docker-compose file: $1" + DCO_FILE_PARAM="--file $1" + fi + + docker-compose $DCO_FILE_PARAM stop + docker-compose $DCO_FILE_PARAM rm -f --all + docker-compose $DCO_FILE_PARAM up -d + docker-compose $DCO_FILE_PARAM logs -f --tail 100 +} From af96da5d11bccb16923694fd68cda557200882db Mon Sep 17 00:00:00 2001 From: Yuhao Wu Date: Thu, 7 Jul 2016 17:13:00 +0900 Subject: [PATCH 7/8] Fix bug: themes break global $PROMPT_COMMAND variable Safely append functions to $PROMPT_COMMAND instead of setting it. --- themes/axin/axin.theme.bash | 2 +- themes/bakke/bakke.theme.bash | 2 +- themes/base.theme.bash | 9 +++++++++ themes/binaryanomaly/binaryanomaly.theme.bash | 2 +- themes/bobby-python/bobby-python.theme.bash | 2 +- themes/bobby/bobby.theme.bash | 2 +- themes/brunton/brunton.theme.bash | 2 +- themes/candy/candy.theme.bash | 2 +- themes/clean/clean.theme.bash | 2 +- themes/cooperkid/cooperkid.theme.bash | 2 +- themes/cupcake/cupcake.theme.bash | 2 +- themes/demula/demula.theme.bash | 2 +- themes/doubletime/doubletime.theme.bash | 2 +- .../doubletime_multiline/doubletime_multiline.theme.bash | 2 +- .../doubletime_multiline_pyonly.theme.bash | 2 +- themes/dulcie/dulcie.theme.bash | 2 +- themes/duru/duru.theme.bash | 2 +- themes/emperor/emperor.theme.bash | 2 +- themes/envy/envy.theme.bash | 2 +- themes/gallifrey/gallifrey.theme.bash | 2 +- themes/hawaii50/hawaii50.theme.bash | 2 +- themes/iterate/iterate.theme.bash | 2 +- themes/luan/luan.theme.bash | 2 +- themes/mairan/mairan.theme.bash | 2 +- themes/mbriggs/mbriggs.theme.bash | 2 +- themes/minimal/minimal.theme.bash | 2 +- themes/modern-t/modern-t.theme.bash | 2 +- themes/modern/modern.theme.bash | 2 +- themes/morris/morris.theme.bash | 2 +- themes/n0qorg/n0qorg.theme.bash | 2 +- themes/nwinkler/nwinkler.theme.bash | 2 +- .../nwinkler_random_colors.theme.bash | 2 +- themes/pete/pete.theme.bash | 2 +- .../powerline-multiline/powerline-multiline.theme.bash | 2 +- themes/powerline-naked/powerline-naked.theme.bash | 2 +- themes/powerline-plain/powerline-plain.theme.bash | 2 +- themes/powerline/powerline.theme.bash | 2 +- themes/primer/primer.theme.bash | 2 +- themes/pro/pro.theme.bash | 2 +- themes/pure/pure.theme.bash | 2 +- themes/rainbowbrite/rainbowbrite.theme.bash | 2 +- themes/rana/rana.theme.bash | 2 +- themes/rjorgenson/rjorgenson.theme.bash | 2 +- themes/roderik/roderik.theme.bash | 2 +- themes/sexy/sexy.theme.bash | 2 +- themes/simple/simple.theme.bash | 2 +- themes/sirup/sirup.theme.bash | 2 +- themes/slick/slick.theme.bash | 2 +- themes/standard/standard.theme.bash | 2 +- themes/tonka/tonka.theme.bash | 2 +- themes/tonotdo/tonotdo.theme.bash | 2 +- themes/tylenol/tylenol.theme.bash | 2 +- themes/zitron/zitron.theme.bash | 2 +- themes/zork/zork.theme.bash | 2 +- 54 files changed, 62 insertions(+), 53 deletions(-) diff --git a/themes/axin/axin.theme.bash b/themes/axin/axin.theme.bash index 0b95b531..32684fbc 100644 --- a/themes/axin/axin.theme.bash +++ b/themes/axin/axin.theme.bash @@ -35,4 +35,4 @@ function prompt_command() { PS1="\[${BOLD}${MAGENTA}\]\u \[$WHITE\]@ \[$ORANGE\]\h \[$WHITE\]in \[$GREEN\]\w\[$WHITE\]\[$SCM_THEME_PROMPT_PREFIX\]${white}\t \[$PURPLE\]\$(scm_prompt_info) \n\$ \[$RESET\]" } -PROMPT_COMMAND=prompt_command +safe_append_prompt_command prompt_command diff --git a/themes/bakke/bakke.theme.bash b/themes/bakke/bakke.theme.bash index 3663bc17..57585984 100644 --- a/themes/bakke/bakke.theme.bash +++ b/themes/bakke/bakke.theme.bash @@ -19,4 +19,4 @@ function prompt_command() { PS1="\n${cyan}\h: ${reset_color} ${yellow}\w ${green}$(scm_prompt_info)\n${reset_color}→ " } -PROMPT_COMMAND=prompt_command; +safe_append_prompt_command prompt_command diff --git a/themes/base.theme.bash b/themes/base.theme.bash index d961b10d..50225023 100644 --- a/themes/base.theme.bash +++ b/themes/base.theme.bash @@ -403,3 +403,12 @@ function aws_profile { echo -e "default" fi } + +function safe_append_prompt_command { + if [[ -n $1 ]] ; then + case $PROMPT_COMMAND in + *$1*) ;; + *) PROMPT_COMMAND="$1;$PROMPT_COMMAND";; + esac + fi +} \ No newline at end of file diff --git a/themes/binaryanomaly/binaryanomaly.theme.bash b/themes/binaryanomaly/binaryanomaly.theme.bash index 58748f1d..38afe72b 100644 --- a/themes/binaryanomaly/binaryanomaly.theme.bash +++ b/themes/binaryanomaly/binaryanomaly.theme.bash @@ -102,4 +102,4 @@ SCM_GIT_CHAR="${green}±${light_grey}" SCM_SVN_CHAR="${bold_cyan}⑆${light_grey}" SCM_HG_CHAR="${bold_red}☿${light_grey}" -PROMPT_COMMAND=prompt_command; +safe_append_prompt_command prompt_command diff --git a/themes/bobby-python/bobby-python.theme.bash b/themes/bobby-python/bobby-python.theme.bash index 962ebca7..e2e5a97f 100644 --- a/themes/bobby-python/bobby-python.theme.bash +++ b/themes/bobby-python/bobby-python.theme.bash @@ -16,4 +16,4 @@ function prompt_command() { PS1="\n${yellow}$(python_version_prompt) ${purple}\h ${reset_color}in ${green}\w\n${bold_cyan}$(scm_char)${green}$(scm_prompt_info) ${green}→${reset_color} " } -PROMPT_COMMAND=prompt_command; +safe_append_prompt_command prompt_command diff --git a/themes/bobby/bobby.theme.bash b/themes/bobby/bobby.theme.bash index e0011759..f014e771 100644 --- a/themes/bobby/bobby.theme.bash +++ b/themes/bobby/bobby.theme.bash @@ -17,4 +17,4 @@ function prompt_command() { PS1="\n$(battery_char) $(clock_char) ${yellow}$(ruby_version_prompt) ${purple}\h ${reset_color}in ${green}\w\n${bold_cyan}$(scm_char)${green}$(scm_prompt_info) ${green}→${reset_color} " } -PROMPT_COMMAND=prompt_command; +safe_append_prompt_command prompt_command diff --git a/themes/brunton/brunton.theme.bash b/themes/brunton/brunton.theme.bash index 839ae674..b085725a 100644 --- a/themes/brunton/brunton.theme.bash +++ b/themes/brunton/brunton.theme.bash @@ -31,4 +31,4 @@ ${white}>${normal} " } -PROMPT_COMMAND=prompt +safe_append_prompt_command prompt diff --git a/themes/candy/candy.theme.bash b/themes/candy/candy.theme.bash index 77f8ff41..fe3c2dff 100644 --- a/themes/candy/candy.theme.bash +++ b/themes/candy/candy.theme.bash @@ -3,4 +3,4 @@ function prompt_command() { PS1="${green}\u@\h ${blue}\T ${reset_color}${white}\w${reset_color}$(scm_prompt_info)${blue} →${bold_blue} ${reset_color} "; } -PROMPT_COMMAND=prompt_command; +safe_append_prompt_command prompt_command diff --git a/themes/clean/clean.theme.bash b/themes/clean/clean.theme.bash index 9998d65e..b4cd7b58 100644 --- a/themes/clean/clean.theme.bash +++ b/themes/clean/clean.theme.bash @@ -17,4 +17,4 @@ function prompt_command() { RPROMPT='[\t]' } -PROMPT_COMMAND=prompt_command; +safe_append_prompt_command prompt_command diff --git a/themes/cooperkid/cooperkid.theme.bash b/themes/cooperkid/cooperkid.theme.bash index ff4df68e..1ffb95aa 100644 --- a/themes/cooperkid/cooperkid.theme.bash +++ b/themes/cooperkid/cooperkid.theme.bash @@ -36,4 +36,4 @@ function prompt() { PS1="\n${user_host}${prompt_symbol}${ruby} ${git_branch} ${return_status}\n${prompt_char}" } -PROMPT_COMMAND=prompt +safe_append_prompt_command prompt diff --git a/themes/cupcake/cupcake.theme.bash b/themes/cupcake/cupcake.theme.bash index 3f1ca055..889f3e68 100644 --- a/themes/cupcake/cupcake.theme.bash +++ b/themes/cupcake/cupcake.theme.bash @@ -76,4 +76,4 @@ function prompt_command() { } # Runs prompt (this bypasses bash_it $PROMPT setting) -PROMPT_COMMAND=prompt_command +safe_append_prompt_command prompt_command diff --git a/themes/demula/demula.theme.bash b/themes/demula/demula.theme.bash index 15faeded..ed03a708 100644 --- a/themes/demula/demula.theme.bash +++ b/themes/demula/demula.theme.bash @@ -126,5 +126,5 @@ ${D_INTERMEDIATE_COLOR}$ ${D_DEFAULT_COLOR}" } # Runs prompt (this bypasses bash_it $PROMPT setting) -PROMPT_COMMAND=prompt +safe_append_prompt_command prompt diff --git a/themes/doubletime/doubletime.theme.bash b/themes/doubletime/doubletime.theme.bash index 87ced7ed..6146b215 100644 --- a/themes/doubletime/doubletime.theme.bash +++ b/themes/doubletime/doubletime.theme.bash @@ -56,7 +56,7 @@ $(doubletime_scm_prompt)$reset_color $ " PS4='+ ' } -PROMPT_COMMAND=prompt_setter +safe_append_prompt_command prompt_setter git_prompt_status() { local git_status_output diff --git a/themes/doubletime_multiline/doubletime_multiline.theme.bash b/themes/doubletime_multiline/doubletime_multiline.theme.bash index d431657d..759917c2 100644 --- a/themes/doubletime_multiline/doubletime_multiline.theme.bash +++ b/themes/doubletime_multiline/doubletime_multiline.theme.bash @@ -21,4 +21,4 @@ $(doubletime_scm_prompt)$reset_color $ " PS4='+ ' } -PROMPT_COMMAND=prompt_setter +safe_append_prompt_command prompt_setter diff --git a/themes/doubletime_multiline_pyonly/doubletime_multiline_pyonly.theme.bash b/themes/doubletime_multiline_pyonly/doubletime_multiline_pyonly.theme.bash index 5073507f..a77ce55f 100644 --- a/themes/doubletime_multiline_pyonly/doubletime_multiline_pyonly.theme.bash +++ b/themes/doubletime_multiline_pyonly/doubletime_multiline_pyonly.theme.bash @@ -21,4 +21,4 @@ $(doubletime_scm_prompt)$reset_color $ " PS4='+ ' } -PROMPT_COMMAND=prompt_setter +safe_append_prompt_command prompt_setter diff --git a/themes/dulcie/dulcie.theme.bash b/themes/dulcie/dulcie.theme.bash index 12cc4545..a83b62fb 100644 --- a/themes/dulcie/dulcie.theme.bash +++ b/themes/dulcie/dulcie.theme.bash @@ -95,4 +95,4 @@ dulcie_prompt() { PS1="${PS1}${DULCIE_PROMPTCHAR} " } -PROMPT_COMMAND=dulcie_prompt +safe_append_prompt_command dulcie_prompt diff --git a/themes/duru/duru.theme.bash b/themes/duru/duru.theme.bash index f1b47e92..69284100 100644 --- a/themes/duru/duru.theme.bash +++ b/themes/duru/duru.theme.bash @@ -21,4 +21,4 @@ prompt() { PS1="${yellow}# ${reset_color}$(last_two_dirs)$(scm_prompt_info)${reset_color}$(venv)${reset_color} ${cyan}\n> ${reset_color}" } -PROMPT_COMMAND=prompt +safe_append_prompt_command prompt diff --git a/themes/emperor/emperor.theme.bash b/themes/emperor/emperor.theme.bash index 8d9313b2..2f365f31 100644 --- a/themes/emperor/emperor.theme.bash +++ b/themes/emperor/emperor.theme.bash @@ -31,4 +31,4 @@ function prompt_command() { PS1="\n$(get_hour_color)$(date +%H) ${purple}\h ${reset_color}in ${prompt_color}\w\n${bold_cyan}$(scm_char)${green}$(scm_prompt_info) ${green}→${reset_color} " } -PROMPT_COMMAND=prompt_command; +safe_append_prompt_command prompt_command diff --git a/themes/envy/envy.theme.bash b/themes/envy/envy.theme.bash index a0b8a993..277e3751 100644 --- a/themes/envy/envy.theme.bash +++ b/themes/envy/envy.theme.bash @@ -13,4 +13,4 @@ function prompt_command() { PS1="\n${yellow}$(ruby_version_prompt) ${purple}\h ${reset_color}in ${green}\w\n${bold_cyan}$(scm_char)${green}$(scm_prompt_info) ${green}→${reset_color} " } -PROMPT_COMMAND=prompt_command; +safe_append_prompt_command prompt_command diff --git a/themes/gallifrey/gallifrey.theme.bash b/themes/gallifrey/gallifrey.theme.bash index a601db12..ddb89778 100644 --- a/themes/gallifrey/gallifrey.theme.bash +++ b/themes/gallifrey/gallifrey.theme.bash @@ -38,4 +38,4 @@ pure_prompt() { esac } -PROMPT_COMMAND=pure_prompt; +safe_append_prompt_command pure_prompt diff --git a/themes/hawaii50/hawaii50.theme.bash b/themes/hawaii50/hawaii50.theme.bash index 21b3ab4f..eaa6b1eb 100644 --- a/themes/hawaii50/hawaii50.theme.bash +++ b/themes/hawaii50/hawaii50.theme.bash @@ -197,4 +197,4 @@ function prompt() { PS4='+ ' } -PROMPT_COMMAND=prompt +safe_append_prompt_command prompt diff --git a/themes/iterate/iterate.theme.bash b/themes/iterate/iterate.theme.bash index 7b375f44..2031b7fc 100644 --- a/themes/iterate/iterate.theme.bash +++ b/themes/iterate/iterate.theme.bash @@ -56,4 +56,4 @@ function prompt_command() { PS1="${new_PS1}${green}${wrap_char}→${reset_color} " } -PROMPT_COMMAND=prompt_command; +safe_append_prompt_command prompt_command diff --git a/themes/luan/luan.theme.bash b/themes/luan/luan.theme.bash index eccef2a0..cb122e50 100644 --- a/themes/luan/luan.theme.bash +++ b/themes/luan/luan.theme.bash @@ -26,4 +26,4 @@ function prompt_command() { $arrow $prompt" } -PROMPT_COMMAND=prompt_command; +safe_append_prompt_command prompt_command diff --git a/themes/mairan/mairan.theme.bash b/themes/mairan/mairan.theme.bash index 3451d3cb..5c5dfef1 100644 --- a/themes/mairan/mairan.theme.bash +++ b/themes/mairan/mairan.theme.bash @@ -127,4 +127,4 @@ PS2="└─▪ " -PROMPT_COMMAND=prompt +safe_append_prompt_command prompt diff --git a/themes/mbriggs/mbriggs.theme.bash b/themes/mbriggs/mbriggs.theme.bash index 674085b6..169f8d7c 100644 --- a/themes/mbriggs/mbriggs.theme.bash +++ b/themes/mbriggs/mbriggs.theme.bash @@ -31,4 +31,4 @@ function prompt() { PS1="\n${n_commands} ${user_host} ${prompt_symbol} ${ruby} ${open}${current_path}${git_branch}${close}${return_status}\n${prompt_char}" } -PROMPT_COMMAND=prompt \ No newline at end of file +safe_append_prompt_command prompt \ No newline at end of file diff --git a/themes/minimal/minimal.theme.bash b/themes/minimal/minimal.theme.bash index 76cb24d5..72fb2200 100644 --- a/themes/minimal/minimal.theme.bash +++ b/themes/minimal/minimal.theme.bash @@ -9,4 +9,4 @@ prompt() { PS1="$(scm_prompt_info)${reset_color} ${cyan}\W${reset_color} " } -PROMPT_COMMAND=prompt +safe_append_prompt_command prompt diff --git a/themes/modern-t/modern-t.theme.bash b/themes/modern-t/modern-t.theme.bash index 12e5b041..da5f9446 100644 --- a/themes/modern-t/modern-t.theme.bash +++ b/themes/modern-t/modern-t.theme.bash @@ -53,4 +53,4 @@ PS2="└─▪ " -PROMPT_COMMAND=prompt +safe_append_prompt_command prompt diff --git a/themes/modern/modern.theme.bash b/themes/modern/modern.theme.bash index 32c7cabb..583764e2 100644 --- a/themes/modern/modern.theme.bash +++ b/themes/modern/modern.theme.bash @@ -53,4 +53,4 @@ PS2="└─▪ " -PROMPT_COMMAND=prompt +safe_append_prompt_command prompt diff --git a/themes/morris/morris.theme.bash b/themes/morris/morris.theme.bash index da51e55a..d6b0258d 100644 --- a/themes/morris/morris.theme.bash +++ b/themes/morris/morris.theme.bash @@ -25,4 +25,4 @@ SCM_THEME_PROMPT_PREFIX="${green}(" SCM_THEME_PROMPT_SUFFIX="${green})${reset_color}" -PROMPT_COMMAND=prompt_command; +safe_append_prompt_command prompt_command diff --git a/themes/n0qorg/n0qorg.theme.bash b/themes/n0qorg/n0qorg.theme.bash index dd39fafd..291e4518 100644 --- a/themes/n0qorg/n0qorg.theme.bash +++ b/themes/n0qorg/n0qorg.theme.bash @@ -9,7 +9,7 @@ function prompt_command() { PS1="${bold_blue}[$(hostname)]${normal} \w${normal} ${bold_white}[$(git_prompt_info)]${normal}» " } -PROMPT_COMMAND=prompt_command; +safe_append_prompt_command prompt_command ## git-theme # feel free to change git chars. diff --git a/themes/nwinkler/nwinkler.theme.bash b/themes/nwinkler/nwinkler.theme.bash index b8bcc226..d1d3f503 100644 --- a/themes/nwinkler/nwinkler.theme.bash +++ b/themes/nwinkler/nwinkler.theme.bash @@ -37,7 +37,7 @@ prompt_setter() { PS4='+ ' } -PROMPT_COMMAND=prompt_setter +safe_append_prompt_command prompt_setter SCM_THEME_PROMPT_DIRTY=" ${bold_red}✗${normal}" SCM_THEME_PROMPT_CLEAN=" ${bold_green}✓${normal}" diff --git a/themes/nwinkler_random_colors/nwinkler_random_colors.theme.bash b/themes/nwinkler_random_colors/nwinkler_random_colors.theme.bash index 23634276..20da931f 100644 --- a/themes/nwinkler_random_colors/nwinkler_random_colors.theme.bash +++ b/themes/nwinkler_random_colors/nwinkler_random_colors.theme.bash @@ -102,7 +102,7 @@ prompt_setter() { PS4='+ ' } -PROMPT_COMMAND=prompt_setter +safe_append_prompt_command prompt_setter SCM_THEME_PROMPT_DIRTY=" ${bold_red}✗${normal}" SCM_THEME_PROMPT_CLEAN=" ${bold_green}✓${normal}" diff --git a/themes/pete/pete.theme.bash b/themes/pete/pete.theme.bash index 7968e53b..b573cb81 100644 --- a/themes/pete/pete.theme.bash +++ b/themes/pete/pete.theme.bash @@ -10,7 +10,7 @@ prompt_setter() { PS4='+ ' } -PROMPT_COMMAND=prompt_setter +safe_append_prompt_command prompt_setter SCM_THEME_PROMPT_DIRTY=" ✗" SCM_THEME_PROMPT_CLEAN=" ✓" diff --git a/themes/powerline-multiline/powerline-multiline.theme.bash b/themes/powerline-multiline/powerline-multiline.theme.bash index c4833756..604c022f 100644 --- a/themes/powerline-multiline/powerline-multiline.theme.bash +++ b/themes/powerline-multiline/powerline-multiline.theme.bash @@ -240,4 +240,4 @@ function __powerline_prompt_command { SEGMENTS_AT_LEFT SEGMENTS_AT_RIGHT } -PROMPT_COMMAND=__powerline_prompt_command +safe_append_prompt_command __powerline_prompt_command diff --git a/themes/powerline-naked/powerline-naked.theme.bash b/themes/powerline-naked/powerline-naked.theme.bash index a599aa59..f1f7b40a 100644 --- a/themes/powerline-naked/powerline-naked.theme.bash +++ b/themes/powerline-naked/powerline-naked.theme.bash @@ -106,5 +106,5 @@ function powerline_prompt_command() { PS1="${SHELL_PROMPT}${VIRTUALENV_PROMPT}${SCM_PROMPT}${CWD_PROMPT}${LAST_STATUS_PROMPT} " } -PROMPT_COMMAND=powerline_prompt_command +safe_append_prompt_command powerline_prompt_command diff --git a/themes/powerline-plain/powerline-plain.theme.bash b/themes/powerline-plain/powerline-plain.theme.bash index 5c3ca826..9393d742 100644 --- a/themes/powerline-plain/powerline-plain.theme.bash +++ b/themes/powerline-plain/powerline-plain.theme.bash @@ -120,5 +120,5 @@ function powerline_prompt_command() { PS1="${SHELL_PROMPT}${GEMSET_PROMPT}${VIRTUALENV_PROMPT}${SCM_PROMPT}${CWD_PROMPT}${LAST_STATUS_PROMPT} " } -PROMPT_COMMAND=powerline_prompt_command +safe_append_prompt_command powerline_prompt_command diff --git a/themes/powerline/powerline.theme.bash b/themes/powerline/powerline.theme.bash index f486eedf..967a412c 100644 --- a/themes/powerline/powerline.theme.bash +++ b/themes/powerline/powerline.theme.bash @@ -129,5 +129,5 @@ function powerline_prompt_command() { PS1="${SHELL_PROMPT}${IN_VIM_PROMPT}${VIRTUALENV_PROMPT}${SCM_PROMPT}${CWD_PROMPT}${LAST_STATUS_PROMPT} " } -PROMPT_COMMAND=powerline_prompt_command +safe_append_prompt_command powerline_prompt_command diff --git a/themes/primer/primer.theme.bash b/themes/primer/primer.theme.bash index 0b01088e..cc5ba536 100644 --- a/themes/primer/primer.theme.bash +++ b/themes/primer/primer.theme.bash @@ -5,4 +5,4 @@ function prompt_command() { PS1="${blue}\T ${reset_color}${white}\w${reset_color}$(scm_prompt_info)${blue} →${bold_blue} ${reset_color} "; } -PROMPT_COMMAND=prompt_command; \ No newline at end of file +safe_append_prompt_command prompt_command \ No newline at end of file diff --git a/themes/pro/pro.theme.bash b/themes/pro/pro.theme.bash index 6ac697bf..1c7de29a 100644 --- a/themes/pro/pro.theme.bash +++ b/themes/pro/pro.theme.bash @@ -19,4 +19,4 @@ function prompt() { PS1="\h: \W $(scm_prompt_info)${reset_color} $ " } -PROMPT_COMMAND=prompt +safe_append_prompt_command prompt diff --git a/themes/pure/pure.theme.bash b/themes/pure/pure.theme.bash index 9b145cc4..b75d3f8f 100644 --- a/themes/pure/pure.theme.bash +++ b/themes/pure/pure.theme.bash @@ -40,4 +40,4 @@ pure_prompt() { esac } -PROMPT_COMMAND=pure_prompt; +safe_append_prompt_command pure_prompt diff --git a/themes/rainbowbrite/rainbowbrite.theme.bash b/themes/rainbowbrite/rainbowbrite.theme.bash index 3d92db7f..63c64b72 100644 --- a/themes/rainbowbrite/rainbowbrite.theme.bash +++ b/themes/rainbowbrite/rainbowbrite.theme.bash @@ -18,7 +18,7 @@ prompt_setter() { PS4='+ ' } -PROMPT_COMMAND=prompt_setter +safe_append_prompt_command prompt_setter SCM_NONE_CHAR='·' SCM_THEME_PROMPT_DIRTY=" ${red}✗" diff --git a/themes/rana/rana.theme.bash b/themes/rana/rana.theme.bash index d29e52ab..c1122429 100644 --- a/themes/rana/rana.theme.bash +++ b/themes/rana/rana.theme.bash @@ -211,4 +211,4 @@ ${D_INTERMEDIATE_COLOR}$ ${D_DEFAULT_COLOR}" } # Runs prompt (this bypasses bash_it $PROMPT setting) -PROMPT_COMMAND=prompt +safe_append_prompt_command prompt diff --git a/themes/rjorgenson/rjorgenson.theme.bash b/themes/rjorgenson/rjorgenson.theme.bash index 2ef151ae..e866f0ea 100644 --- a/themes/rjorgenson/rjorgenson.theme.bash +++ b/themes/rjorgenson/rjorgenson.theme.bash @@ -97,4 +97,4 @@ PS2="└─$(my_prompt_char)" -PROMPT_COMMAND=prompt +safe_append_prompt_command prompt diff --git a/themes/roderik/roderik.theme.bash b/themes/roderik/roderik.theme.bash index 1c71ab44..2f32e4d1 100644 --- a/themes/roderik/roderik.theme.bash +++ b/themes/roderik/roderik.theme.bash @@ -14,4 +14,4 @@ function prompt_command() { fi } -PROMPT_COMMAND=prompt_command; +safe_append_prompt_command prompt_command diff --git a/themes/sexy/sexy.theme.bash b/themes/sexy/sexy.theme.bash index b7cbbf03..60e00ec7 100644 --- a/themes/sexy/sexy.theme.bash +++ b/themes/sexy/sexy.theme.bash @@ -43,4 +43,4 @@ function prompt_command() { PS1="\[${BOLD}${MAGENTA}\]\u \[$WHITE\]at \[$ORANGE\]\h \[$WHITE\]in \[$GREEN\]\w\[$WHITE\]\$([[ -n \$(git branch 2> /dev/null) ]] && echo \" on \")\[$PURPLE\]\$(parse_git_branch)\[$WHITE\]\n\$ \[$RESET\]" } -PROMPT_COMMAND=prompt_command +safe_append_prompt_command prompt_command diff --git a/themes/simple/simple.theme.bash b/themes/simple/simple.theme.bash index 8b897ddc..f4d152fb 100644 --- a/themes/simple/simple.theme.bash +++ b/themes/simple/simple.theme.bash @@ -22,4 +22,4 @@ SCM_THEME_PROMPT_CLEAN=" ✓" SCM_THEME_PROMPT_PREFIX="(" SCM_THEME_PROMPT_SUFFIX=")" -PROMPT_COMMAND=prompt_command; +safe_append_prompt_command prompt_command diff --git a/themes/sirup/sirup.theme.bash b/themes/sirup/sirup.theme.bash index 146cc356..38fcab41 100644 --- a/themes/sirup/sirup.theme.bash +++ b/themes/sirup/sirup.theme.bash @@ -19,4 +19,4 @@ function prompt_command() { PS1="$blue\W/$bold_blue$(rvm_version_prompt)$bold_green$(__git_ps1 " (%s)") ${normal}$ " } -PROMPT_COMMAND=prompt_command; +safe_append_prompt_command prompt_command diff --git a/themes/slick/slick.theme.bash b/themes/slick/slick.theme.bash index bccc1666..aafdc25d 100644 --- a/themes/slick/slick.theme.bash +++ b/themes/slick/slick.theme.bash @@ -83,4 +83,4 @@ PS2="> " -PROMPT_COMMAND=prompt +safe_append_prompt_command prompt diff --git a/themes/standard/standard.theme.bash b/themes/standard/standard.theme.bash index 87402c73..561a97cb 100644 --- a/themes/standard/standard.theme.bash +++ b/themes/standard/standard.theme.bash @@ -21,4 +21,4 @@ function prompt_command() { PROMPT='${green}\u${normal}@${green}\h${normal}:${blue}\w${normal}${red}$(prompt_char)$(git_prompt_info)${normal}\$ ' } -PROMPT_COMMAND=prompt_command; +safe_append_prompt_command prompt_command diff --git a/themes/tonka/tonka.theme.bash b/themes/tonka/tonka.theme.bash index 2b28c968..53fbd64c 100644 --- a/themes/tonka/tonka.theme.bash +++ b/themes/tonka/tonka.theme.bash @@ -30,7 +30,7 @@ PS2="$LIGHT_BLUE-$YELLOW-$YELLOW-$NO_COLOUR " } -PROMPT_COMMAND=prompt_setter +safe_append_prompt_command prompt_setter export PS3=">> " diff --git a/themes/tonotdo/tonotdo.theme.bash b/themes/tonotdo/tonotdo.theme.bash index a1e18ba6..347e586b 100644 --- a/themes/tonotdo/tonotdo.theme.bash +++ b/themes/tonotdo/tonotdo.theme.bash @@ -10,4 +10,4 @@ function prompt_command() { PS1="${yellow}\u${normal}${cyan}@\h${normal}${purple} ${normal}${green}\w${normal}$(scm_prompt_info)> " } -PROMPT_COMMAND=prompt_command +safe_append_prompt_command prompt_command diff --git a/themes/tylenol/tylenol.theme.bash b/themes/tylenol/tylenol.theme.bash index 4c88e217..a48dceb4 100644 --- a/themes/tylenol/tylenol.theme.bash +++ b/themes/tylenol/tylenol.theme.bash @@ -17,4 +17,4 @@ function prompt_command() { PS1="\n${green}$(virtualenv_prompt)${red}$(ruby_version_prompt) ${reset_color}\h ${orange}in ${reset_color}\w\n${yellow}$(scm_char)$(scm_prompt_info) ${yellow}→${white} " } -PROMPT_COMMAND=prompt_command; +safe_append_prompt_command prompt_command diff --git a/themes/zitron/zitron.theme.bash b/themes/zitron/zitron.theme.bash index 7737d070..56b7bfa6 100644 --- a/themes/zitron/zitron.theme.bash +++ b/themes/zitron/zitron.theme.bash @@ -21,4 +21,4 @@ function prompt_command() { PS1="${no_color}\u:$(hostname)${normal}:${bold_yellow}\W/${normal} $(git_prompt_info)${reset_color}$ " } -PROMPT_COMMAND=prompt_command; +safe_append_prompt_command prompt_command diff --git a/themes/zork/zork.theme.bash b/themes/zork/zork.theme.bash index c022a408..75bc17d6 100644 --- a/themes/zork/zork.theme.bash +++ b/themes/zork/zork.theme.bash @@ -94,4 +94,4 @@ PS2="└─▪ " -PROMPT_COMMAND=prompt +safe_append_prompt_command prompt From 62e07f8f7043f774010f294e6da08105dfcc23e8 Mon Sep 17 00:00:00 2001 From: Cheong Yip Date: Sun, 10 Jul 2016 12:36:17 +1000 Subject: [PATCH 8/8] Update docker & add docker-compose/docker-machine CLI completion CLI completions are from: - docker : https://github.com/docker/docker/blob/master/contrib/completion/bash/docker - docker-compose : https://github.com/docker/compose/blob/master/contrib/completion/bash/docker-compose - docker-machine : https://github.com/docker/machine/blob/master/contrib/completion/bash/docker-machine.bash --- completion/available/docker-compose.bash | 561 ++++++++ completion/available/docker-machine.bash | 252 ++++ completion/available/docker.completion.bash | 1285 ++++++++++++++++--- 3 files changed, 1919 insertions(+), 179 deletions(-) create mode 100644 completion/available/docker-compose.bash create mode 100644 completion/available/docker-machine.bash diff --git a/completion/available/docker-compose.bash b/completion/available/docker-compose.bash new file mode 100644 index 00000000..0201bcb2 --- /dev/null +++ b/completion/available/docker-compose.bash @@ -0,0 +1,561 @@ +#!bash +# +# bash completion for docker-compose +# +# This work is based on the completion for the docker command. +# +# This script provides completion of: +# - commands and their options +# - service names +# - filepaths +# +# To enable the completions either: +# - place this file in /etc/bash_completion.d +# or +# - copy this file to e.g. ~/.docker-compose-completion.sh and add the line +# below to your .bashrc after bash completion features are loaded +# . ~/.docker-compose-completion.sh + + +__docker_compose_q() { + docker-compose 2>/dev/null $daemon_options "$@" +} + +# Transforms a multiline list of strings into a single line string +# with the words separated by "|". +__docker_compose_to_alternatives() { + local parts=( $1 ) + local IFS='|' + echo "${parts[*]}" +} + +# Transforms a multiline list of options into an extglob pattern +# suitable for use in case statements. +__docker_compose_to_extglob() { + local extglob=$( __docker_compose_to_alternatives "$1" ) + echo "@($extglob)" +} + +# suppress trailing whitespace +__docker_compose_nospace() { + # compopt is not available in ancient bash versions + type compopt &>/dev/null && compopt -o nospace +} + +# Extracts all service names from the compose file. +___docker_compose_all_services_in_compose_file() { + __docker_compose_q config --services +} + +# All services, even those without an existing container +__docker_compose_services_all() { + COMPREPLY=( $(compgen -W "$(___docker_compose_all_services_in_compose_file)" -- "$cur") ) +} + +# All services that have an entry with the given key in their compose_file section +___docker_compose_services_with_key() { + # flatten sections under "services" to one line, then filter lines containing the key and return section name + __docker_compose_q config \ + | sed -n -e '/^services:/,/^[^ ]/p' \ + | sed -n 's/^ //p' \ + | awk '/^[a-zA-Z0-9]/{printf "\n"};{printf $0;next;}' \ + | awk -F: -v key=": +$1:" '$0 ~ key {print $1}' +} + +# All services that are defined by a Dockerfile reference +__docker_compose_services_from_build() { + COMPREPLY=( $(compgen -W "$(___docker_compose_services_with_key build)" -- "$cur") ) +} + +# All services that are defined by an image +__docker_compose_services_from_image() { + COMPREPLY=( $(compgen -W "$(___docker_compose_services_with_key image)" -- "$cur") ) +} + +# The services for which containers have been created, optionally filtered +# by a boolean expression passed in as argument. +__docker_compose_services_with() { + local containers names + containers="$(__docker_compose_q ps -q)" + names=$(docker 2>/dev/null inspect -f "{{if ${1:-true}}}{{range \$k, \$v := .Config.Labels}}{{if eq \$k \"com.docker.compose.service\"}}{{\$v}}{{end}}{{end}}{{end}}" $containers) + COMPREPLY=( $(compgen -W "$names" -- "$cur") ) +} + +# The services for which at least one paused container exists +__docker_compose_services_paused() { + __docker_compose_services_with '.State.Paused' +} + +# The services for which at least one running container exists +__docker_compose_services_running() { + __docker_compose_services_with '.State.Running' +} + +# The services for which at least one stopped container exists +__docker_compose_services_stopped() { + __docker_compose_services_with 'not .State.Running' +} + + +_docker_compose_build() { + case "$cur" in + -*) + COMPREPLY=( $( compgen -W "--force-rm --help --no-cache --pull" -- "$cur" ) ) + ;; + *) + __docker_compose_services_from_build + ;; + esac +} + + +_docker_compose_bundle() { + case "$prev" in + --output|-o) + _filedir + return + ;; + esac + + COMPREPLY=( $( compgen -W "--fetch-digests --help --output -o" -- "$cur" ) ) +} + + +_docker_compose_config() { + COMPREPLY=( $( compgen -W "--help --quiet -q --services" -- "$cur" ) ) +} + + +_docker_compose_create() { + case "$cur" in + -*) + COMPREPLY=( $( compgen -W "--force-recreate --help --no-build --no-recreate" -- "$cur" ) ) + ;; + *) + __docker_compose_services_all + ;; + esac +} + + +_docker_compose_docker_compose() { + case "$prev" in + --tlscacert|--tlscert|--tlskey) + _filedir + return + ;; + --file|-f) + _filedir "y?(a)ml" + return + ;; + $(__docker_compose_to_extglob "$daemon_options_with_args") ) + return + ;; + esac + + case "$cur" in + -*) + COMPREPLY=( $( compgen -W "$daemon_boolean_options $daemon_options_with_args --help -h --verbose --version -v" -- "$cur" ) ) + ;; + *) + COMPREPLY=( $( compgen -W "${commands[*]}" -- "$cur" ) ) + ;; + esac +} + + +_docker_compose_down() { + case "$prev" in + --rmi) + COMPREPLY=( $( compgen -W "all local" -- "$cur" ) ) + return + ;; + esac + + case "$cur" in + -*) + COMPREPLY=( $( compgen -W "--help --rmi --volumes -v --remove-orphans" -- "$cur" ) ) + ;; + esac +} + + +_docker_compose_events() { + case "$prev" in + --json) + return + ;; + esac + + case "$cur" in + -*) + COMPREPLY=( $( compgen -W "--help --json" -- "$cur" ) ) + ;; + *) + __docker_compose_services_all + ;; + esac +} + + +_docker_compose_exec() { + case "$prev" in + --index|--user) + return + ;; + esac + + case "$cur" in + -*) + COMPREPLY=( $( compgen -W "-d --help --index --privileged -T --user" -- "$cur" ) ) + ;; + *) + __docker_compose_services_running + ;; + esac +} + + +_docker_compose_help() { + COMPREPLY=( $( compgen -W "${commands[*]}" -- "$cur" ) ) +} + + +_docker_compose_kill() { + case "$prev" in + -s) + COMPREPLY=( $( compgen -W "SIGHUP SIGINT SIGKILL SIGUSR1 SIGUSR2" -- "$(echo $cur | tr '[:lower:]' '[:upper:]')" ) ) + return + ;; + esac + + case "$cur" in + -*) + COMPREPLY=( $( compgen -W "--help -s" -- "$cur" ) ) + ;; + *) + __docker_compose_services_running + ;; + esac +} + + +_docker_compose_logs() { + case "$prev" in + --tail) + return + ;; + esac + + case "$cur" in + -*) + COMPREPLY=( $( compgen -W "--follow -f --help --no-color --tail --timestamps -t" -- "$cur" ) ) + ;; + *) + __docker_compose_services_all + ;; + esac +} + + +_docker_compose_pause() { + case "$cur" in + -*) + COMPREPLY=( $( compgen -W "--help" -- "$cur" ) ) + ;; + *) + __docker_compose_services_running + ;; + esac +} + + +_docker_compose_port() { + case "$prev" in + --protocol) + COMPREPLY=( $( compgen -W "tcp udp" -- "$cur" ) ) + return; + ;; + --index) + return; + ;; + esac + + case "$cur" in + -*) + COMPREPLY=( $( compgen -W "--help --index --protocol" -- "$cur" ) ) + ;; + *) + __docker_compose_services_all + ;; + esac +} + + +_docker_compose_ps() { + case "$cur" in + -*) + COMPREPLY=( $( compgen -W "--help -q" -- "$cur" ) ) + ;; + *) + __docker_compose_services_all + ;; + esac +} + + +_docker_compose_pull() { + case "$cur" in + -*) + COMPREPLY=( $( compgen -W "--help --ignore-pull-failures" -- "$cur" ) ) + ;; + *) + __docker_compose_services_from_image + ;; + esac +} + + +_docker_compose_push() { + case "$cur" in + -*) + COMPREPLY=( $( compgen -W "--help --ignore-push-failures" -- "$cur" ) ) + ;; + *) + __docker_compose_services_all + ;; + esac +} + + +_docker_compose_restart() { + case "$prev" in + --timeout|-t) + return + ;; + esac + + case "$cur" in + -*) + COMPREPLY=( $( compgen -W "--help --timeout -t" -- "$cur" ) ) + ;; + *) + __docker_compose_services_running + ;; + esac +} + + +_docker_compose_rm() { + case "$cur" in + -*) + COMPREPLY=( $( compgen -W "--force -f --help -v" -- "$cur" ) ) + ;; + *) + __docker_compose_services_stopped + ;; + esac +} + + +_docker_compose_run() { + case "$prev" in + -e) + COMPREPLY=( $( compgen -e -- "$cur" ) ) + __docker_compose_nospace + return + ;; + --entrypoint|--name|--user|-u|--workdir|-w) + return + ;; + esac + + case "$cur" in + -*) + COMPREPLY=( $( compgen -W "-d --entrypoint -e --help --name --no-deps --publish -p --rm --service-ports -T --user -u --workdir -w" -- "$cur" ) ) + ;; + *) + __docker_compose_services_all + ;; + esac +} + + +_docker_compose_scale() { + case "$prev" in + =) + COMPREPLY=("$cur") + return + ;; + --timeout|-t) + return + ;; + esac + + case "$cur" in + -*) + COMPREPLY=( $( compgen -W "--help --timeout -t" -- "$cur" ) ) + ;; + *) + COMPREPLY=( $(compgen -S "=" -W "$(___docker_compose_all_services_in_compose_file)" -- "$cur") ) + __docker_compose_nospace + ;; + esac +} + + +_docker_compose_start() { + case "$cur" in + -*) + COMPREPLY=( $( compgen -W "--help" -- "$cur" ) ) + ;; + *) + __docker_compose_services_stopped + ;; + esac +} + + +_docker_compose_stop() { + case "$prev" in + --timeout|-t) + return + ;; + esac + + case "$cur" in + -*) + COMPREPLY=( $( compgen -W "--help --timeout -t" -- "$cur" ) ) + ;; + *) + __docker_compose_services_running + ;; + esac +} + + +_docker_compose_unpause() { + case "$cur" in + -*) + COMPREPLY=( $( compgen -W "--help" -- "$cur" ) ) + ;; + *) + __docker_compose_services_paused + ;; + esac +} + + +_docker_compose_up() { + case "$prev" in + --timeout|-t) + return + ;; + esac + + case "$cur" in + -*) + COMPREPLY=( $( compgen -W "--abort-on-container-exit --build -d --force-recreate --help --no-build --no-color --no-deps --no-recreate --timeout -t --remove-orphans" -- "$cur" ) ) + ;; + *) + __docker_compose_services_all + ;; + esac +} + + +_docker_compose_version() { + case "$cur" in + -*) + COMPREPLY=( $( compgen -W "--short" -- "$cur" ) ) + ;; + esac +} + + +_docker_compose() { + local previous_extglob_setting=$(shopt -p extglob) + shopt -s extglob + + local commands=( + build + bundle + config + create + down + events + exec + help + kill + logs + pause + port + ps + pull + push + restart + rm + run + scale + start + stop + unpause + up + version + ) + + # options for the docker daemon that have to be passed to secondary calls to + # docker-compose executed by this script + local daemon_boolean_options=" + --skip-hostname-check + --tls + --tlsverify + " + local daemon_options_with_args=" + --file -f + --host -H + --project-name -p + --tlscacert + --tlscert + --tlskey + " + + COMPREPLY=() + local cur prev words cword + _get_comp_words_by_ref -n : cur prev words cword + + # search subcommand and invoke its handler. + # special treatment of some top-level options + local command='docker_compose' + local daemon_options=() + local counter=1 + + while [ $counter -lt $cword ]; do + case "${words[$counter]}" in + $(__docker_compose_to_extglob "$daemon_boolean_options") ) + local opt=${words[counter]} + daemon_options+=($opt) + ;; + $(__docker_compose_to_extglob "$daemon_options_with_args") ) + local opt=${words[counter]} + local arg=${words[++counter]} + daemon_options+=($opt $arg) + ;; + -*) + ;; + *) + command="${words[$counter]}" + break + ;; + esac + (( counter++ )) + done + + local completions_func=_docker_compose_${command//-/_} + declare -F $completions_func >/dev/null && $completions_func + + eval "$previous_extglob_setting" + return 0 +} + +complete -F _docker_compose docker-compose diff --git a/completion/available/docker-machine.bash b/completion/available/docker-machine.bash new file mode 100644 index 00000000..a1ed9f87 --- /dev/null +++ b/completion/available/docker-machine.bash @@ -0,0 +1,252 @@ +# +# bash completion file for docker-machine commands +# +# This script provides completion of: +# - commands and their options +# - machine names +# - filepaths +# +# To enable the completions either: +# - place this file in /etc/bash_completion.d +# or +# - copy this file to e.g. ~/.docker-machine-completion.sh and add the line +# below to your .bashrc after bash completion features are loaded +# . ~/.docker-machine-completion.sh +# + +_docker_machine_active() { + if [[ "${cur}" == -* ]]; then + COMPREPLY=($(compgen -W "--help" -- "${cur}")) + else + COMPREPLY=() + fi +} + +_docker_machine_config() { + if [[ "${cur}" == -* ]]; then + COMPREPLY=($(compgen -W "--swarm --help" -- "${cur}")) + else + COMPREPLY=($(compgen -W "$(docker-machine ls -q)" -- "${cur}")) + fi +} + +_docker_machine_create() { + # cheating, b/c there are approximately one zillion options to create + COMPREPLY=($(compgen -W "$(docker-machine create --help | grep '^ -' | sed 's/^ //; s/[^a-z0-9-].*$//')" -- "${cur}")) +} + +_docker_machine_env() { + case "${prev}" in + --shell) + # What are the options for --shell? + COMPREPLY=() + ;; + *) + if [[ "${cur}" == -* ]]; then + COMPREPLY=($(compgen -W "--swarm --shell --unset --no-proxy --help" -- "${cur}")) + else + COMPREPLY=($(compgen -W "$(docker-machine ls -q)" -- "${cur}")) + fi + esac +} + +# See docker-machine-wrapper.bash for the use command +_docker_machine_use() { + if [[ "${cur}" == -* ]]; then + COMPREPLY=($(compgen -W "--swarm --unset --help" -- "${cur}")) + else + COMPREPLY=($(compgen -W "$(docker-machine ls -q)" -- "${cur}")) + fi +} + +_docker_machine_inspect() { + case "${prev}" in + -f|--format) + COMPREPLY=() + ;; + *) + if [[ "${cur}" == -* ]]; then + COMPREPLY=($(compgen -W "--format --help" -- "${cur}")) + else + COMPREPLY=($(compgen -W "$(docker-machine ls -q)" -- "${cur}")) + fi + ;; + esac +} + +_docker_machine_ip() { + if [[ "${cur}" == -* ]]; then + COMPREPLY=($(compgen -W "--help" -- "${cur}")) + else + COMPREPLY=($(compgen -W "$(docker-machine ls -q)" -- "${cur}")) + fi +} + +_docker_machine_kill() { + if [[ "${cur}" == -* ]]; then + COMPREPLY=($(compgen -W "--help" -- "${cur}")) + else + COMPREPLY=($(compgen -W "$(docker-machine ls -q)" -- "${cur}")) + fi +} + +_docker_machine_ls() { + case "${prev}" in + --filter) + COMPREPLY=() + ;; + *) + COMPREPLY=($(compgen -W "--quiet --filter --format --timeout --help" -- "${cur}")) + ;; + esac +} + +_docker_machine_regenerate_certs() { + if [[ "${cur}" == -* ]]; then + COMPREPLY=($(compgen -W "--help --force" -- "${cur}")) + else + COMPREPLY=($(compgen -W "$(docker-machine ls -q)" -- "${cur}")) + fi +} + +_docker_machine_restart() { + if [[ "${cur}" == -* ]]; then + COMPREPLY=($(compgen -W "--help" -- "${cur}")) + else + COMPREPLY=($(compgen -W "$(docker-machine ls -q)" -- "${cur}")) + fi +} + +_docker_machine_rm() { + if [[ "${cur}" == -* ]]; then + COMPREPLY=($(compgen -W "--help --force -y" -- "${cur}")) + else + # For rm, it's best to be explicit + COMPREPLY=() + fi +} + +_docker_machine_ssh() { + if [[ "${cur}" == -* ]]; then + COMPREPLY=($(compgen -W "--help" -- "${cur}")) + else + COMPREPLY=($(compgen -W "$(docker-machine ls -q)" -- "${cur}")) + fi +} + +_docker_machine_scp() { + if [[ "${cur}" == -* ]]; then + COMPREPLY=($(compgen -W "--help --recursive" -- "${cur}")) + else + _filedir + # It would be really nice to ssh to the machine and ls to complete + # remote files. + COMPREPLY=($(compgen -W "$(docker-machine ls -q | sed 's/$/:/')" -- "${cur}") "${COMPREPLY[@]}") + fi +} + +_docker_machine_start() { + if [[ "${cur}" == -* ]]; then + COMPREPLY=($(compgen -W "--help" -- "${cur}")) + else + COMPREPLY=($(compgen -W "$(docker-machine ls -q)" -- "${cur}")) + fi +} + +_docker_machine_status() { + if [[ "${cur}" == -* ]]; then + COMPREPLY=($(compgen -W "--help" -- "${cur}")) + else + COMPREPLY=($(compgen -W "$(docker-machine ls -q)" -- "${cur}")) + fi +} + +_docker_machine_stop() { + if [[ "${cur}" == -* ]]; then + COMPREPLY=($(compgen -W "--help" -- "${cur}")) + else + COMPREPLY=($(compgen -W "$(docker-machine ls -q)" -- "${cur}")) + fi +} + +_docker_machine_upgrade() { + if [[ "${cur}" == -* ]]; then + COMPREPLY=($(compgen -W "--help" -- "${cur}")) + else + COMPREPLY=($(compgen -W "$(docker-machine ls -q)" -- "${cur}")) + fi +} + +_docker_machine_url() { + if [[ "${cur}" == -* ]]; then + COMPREPLY=($(compgen -W "--help" -- "${cur}")) + else + COMPREPLY=($(compgen -W "$(docker-machine ls -q)" -- "${cur}")) + fi +} + +_docker_machine_version() { + if [[ "${cur}" == -* ]]; then + COMPREPLY=($(compgen -W "--help" -- "${cur}")) + else + COMPREPLY=($(compgen -W "$(docker-machine ls -q)" -- "${cur}")) + fi +} + +_docker_machine_help() { + if [[ "${cur}" == -* ]]; then + COMPREPLY=($(compgen -W "--help" -- "${cur}")) + else + COMPREPLY=($(compgen -W "${commands[*]}" -- "${cur}")) + fi +} + +_docker_machine_docker_machine() { + if [[ " ${wants_file[*]} " =~ " ${prev} " ]]; then + _filedir + elif [[ " ${wants_dir[*]} " =~ " ${prev} " ]]; then + _filedir -d + elif [[ "${cur}" == -* ]]; then + COMPREPLY=($(compgen -W "${flags[*]} ${wants_dir[*]} ${wants_file[*]}" -- "${cur}")) + else + COMPREPLY=($(compgen -W "${commands[*]}" -- "${cur}")) + fi +} + +_docker_machine() { + COMPREPLY=() + local commands=(active config create env inspect ip kill ls regenerate-certs restart rm ssh scp start status stop upgrade url version help) + + local flags=(--debug --native-ssh --github-api-token --bugsnag-api-token --help --version) + local wants_dir=(--storage-path) + local wants_file=(--tls-ca-cert --tls-ca-key --tls-client-cert --tls-client-key) + + # Add the use subcommand, if we have an alias loaded + if [[ ${DOCKER_MACHINE_WRAPPED} = true ]]; then + commands=("${commands[@]}" use) + fi + + local cur prev words cword + _get_comp_words_by_ref -n : cur prev words cword + local i + local command=docker-machine + + for (( i=1; i < ${cword}; ++i)); do + local word=${words[i]} + if [[ " ${wants_file[*]} ${wants_dir[*]} " =~ " ${word} " ]]; then + # skip the next option + (( ++i )) + elif [[ " ${commands[*]} " =~ " ${word} " ]]; then + command=${word} + fi + done + + local completion_func=_docker_machine_"${command//-/_}" + if declare -F "${completion_func}" > /dev/null; then + ${completion_func} + fi + + return 0 +} + +complete -F _docker_machine docker-machine diff --git a/completion/available/docker.completion.bash b/completion/available/docker.completion.bash index 0e9d4b79..1495b854 100644 --- a/completion/available/docker.completion.bash +++ b/completion/available/docker.completion.bash @@ -21,6 +21,8 @@ # setting environment variables. # # DOCKER_COMPLETION_SHOW_NETWORK_IDS +# DOCKER_COMPLETION_SHOW_NODE_IDS +# DOCKER_COMPLETION_SHOW_SERVICE_IDS # "no" - Show names only (default) # "yes" - Show names and ids # @@ -148,16 +150,20 @@ __docker_complete_containers_and_images() { COMPREPLY+=( "${containers[@]}" ) } +# Returns the names and optionally IDs of networks. +# The selection can be narrowed by an optional filter parameter, e.g. 'type=custom' __docker_networks() { + local filter="$1" # By default, only network names are completed. # Set DOCKER_COMPLETION_SHOW_NETWORK_IDS=yes to also complete network IDs. local fields='$2' [ "${DOCKER_COMPLETION_SHOW_NETWORK_IDS}" = yes ] && fields='$1,$2' - __docker_q network ls --no-trunc | awk "NR>1 {print $fields}" + __docker_q network ls --no-trunc ${filter:+-f "$filter"} | awk "NR>1 {print $fields}" + #__docker_q network ls --no-trunc | awk "NR>1 {print $fields}" } __docker_complete_networks() { - COMPREPLY=( $(compgen -W "$(__docker_networks)" -- "$cur") ) + COMPREPLY=( $(compgen -W "$(__docker_networks $@)" -- "$cur") ) } __docker_complete_network_ids() { @@ -185,6 +191,94 @@ __docker_complete_plugins() { COMPREPLY=( $(compgen -W "$(__docker_plugins $1)" -- "$cur") ) } +__docker_runtimes() { + __docker_q info | sed -n 's/^Runtimes: \(.*\)/\1/p' +} + +__docker_complete_runtimes() { + COMPREPLY=( $(compgen -W "$(__docker_runtimes)" -- "$cur") ) +} + +# Returns a list of all nodes. Additional arguments to `docker node` +# may be specified in order to filter the node list, e.g. +# `__docker_nodes --filter role=manager` +# By default, only node names are completed. +# Set DOCKER_COMPLETION_SHOW_NODE_IDS=yes to also complete node IDs. +# An optional first argument `--id|--name` may be used to limit +# the output to the IDs or names of matching nodes. This setting takes +# precedence over the environment setting. +__docker_nodes() { + local fields='$2' # default: node name only + [ "${DOCKER_COMPLETION_SHOW_NODE_IDS}" = yes ] && fields='$1,$2' # ID and name + + if [ "$1" = "--id" ] ; then + fields='$1' # IDs only + shift + elif [ "$1" = "--name" ] ; then + fields='$2' # names only + shift + fi + __docker_q node ls "$@" | tr -d '*' | awk "NR>1 {print $fields}" +} + +# Applies completion of nodes based on the current value of `$cur` or +# the value of the optional first argument `--cur`, if given. +# Additional filters may be appended, see `__docker_nodes`. +__docker_complete_nodes() { + local current=$cur + if [ "$1" = "--cur" ] ; then + current="$2" + shift 2 + fi + COMPREPLY=( $(compgen -W "$(__docker_nodes "$@")" -- "$current") ) +} + +__docker_complete_nodes_plus_self() { + __docker_complete_nodes "$@" + COMPREPLY+=( self ) +} + +# Returns a list of all services. Additional arguments to `docker service ls` +# may be specified in order to filter the service list, e.g. +# `__docker_services --filter name=xxx` +# By default, only node names are completed. +# Set DOCKER_COMPLETION_SHOW_SERVICE_IDS=yes to also complete service IDs. +# An optional first argument `--id|--name` may be used to limit +# the output to the IDs or names of matching services. This setting takes +# precedence over the environment setting. +__docker_services() { + local fields='$2' # default: service name only + [ "${DOCKER_COMPLETION_SHOW_SERVICE_IDS}" = yes ] && fields='$1,$2' # ID & name + + if [ "$1" = "--id" ] ; then + fields='$1' # IDs only + shift + elif [ "$1" = "--name" ] ; then + fields='$2' # names only + shift + fi + __docker_q service ls "$@" | awk "NR>1 {print $fields}" +} + +# Applies completion of services based on the current value of `$cur` or +# the value of the optional first argument `--cur`, if given. +# Additional filters may be appended, see `__docker_services`. +__docker_complete_services() { + local current=$cur + if [ "$1" = "--cur" ] ; then + current="$2" + shift 2 + fi + COMPREPLY=( $(compgen -W "$(__docker_services "$@")" -- "$current") ) +} + +# Appends the word passed as an argument to every word in `$COMPREPLY`. +# Normally you do this with `compgen -S`. This function exists so that you can use +# the __docker_complete_XXX functions in cases where you need a suffix. +__docker_append_to_completions() { + COMPREPLY=( ${COMPREPLY[@]/%/"$1"} ) +} + # Finds the position of the first word that is neither option nor an option's argument. # If there are options that require arguments, you should pass a glob describing those # options, e.g. "--option1|-o|--option2" @@ -220,6 +314,31 @@ __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. +__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' @@ -340,6 +459,25 @@ __docker_complete_capabilities() { " -- "$cur" ) ) } +__docker_complete_detach-keys() { + case "$prev" in + --detach-keys) + case "$cur" in + *,) + COMPREPLY=( $( compgen -W "${cur}ctrl-" -- "$cur" ) ) + ;; + *) + COMPREPLY=( $( compgen -W "ctrl-" -- "$cur" ) ) + ;; + esac + + __docker_nospace + return + ;; + esac + return 1 +} + __docker_complete_isolation() { COMPREPLY=( $( compgen -W "default hyperv process" -- "$cur" ) ) } @@ -347,7 +485,9 @@ __docker_complete_isolation() { __docker_complete_log_drivers() { COMPREPLY=( $( compgen -W " awslogs + etwlogs fluentd + gcplogs gelf journald json-file @@ -360,14 +500,15 @@ __docker_complete_log_drivers() { __docker_complete_log_options() { # see docs/reference/logging/index.md local awslogs_options="awslogs-region awslogs-group awslogs-stream" - local fluentd_options="env fluentd-address labels tag" - local gelf_options="env gelf-address labels tag" - local journald_options="env labels" + local fluentd_options="env fluentd-address fluentd-async-connect fluentd-buffer-limit fluentd-retry-wait fluentd-max-retries labels tag" + local gcplogs_options="env gcp-log-cmd gcp-project labels" + local gelf_options="env gelf-address gelf-compression-level gelf-compression-type labels tag" + local journald_options="env labels tag" local json_file_options="env labels max-file max-size" - local syslog_options="syslog-address syslog-facility tag" + local syslog_options="syslog-address syslog-format syslog-tls-ca-cert syslog-tls-cert syslog-tls-key syslog-tls-skip-verify syslog-facility tag" local splunk_options="env labels splunk-caname splunk-capath splunk-index splunk-insecureskipverify splunk-source splunk-sourcetype splunk-token splunk-url tag" - local all_options="$fluentd_options $gelf_options $journald_options $json_file_options $syslog_options $splunk_options" + local all_options="$fluentd_options $gcplogs_options $gelf_options $journald_options $json_file_options $syslog_options $splunk_options" case $(__docker_value_of_option --log-driver) in '') @@ -379,6 +520,9 @@ __docker_complete_log_options() { fluentd) COMPREPLY=( $( compgen -W "$fluentd_options" -S = -- "$cur" ) ) ;; + gcplogs) + COMPREPLY=( $( compgen -W "$gcplogs_options" -S = -- "$cur" ) ) + ;; gelf) COMPREPLY=( $( compgen -W "$gelf_options" -S = -- "$cur" ) ) ;; @@ -403,20 +547,32 @@ __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 + fluentd-async-connect) + COMPREPLY=( $( compgen -W "false true" -- "${cur##*=}" ) ) + return + ;; + gelf-address) + COMPREPLY=( $( compgen -W "udp" -S "://" -- "${cur##*=}" ) ) __docker_nospace return ;; - *syslog-address=*) - COMPREPLY=( $( compgen -W "tcp udp unix" -S "://" -- "${cur#=}" ) ) - __docker_nospace + gelf-compression-level) + COMPREPLY=( $( compgen -W "1 2 3 4 5 6 7 8 9" -- "${cur##*=}" ) ) return ;; - *syslog-facility=*) + gelf-compression-type) + COMPREPLY=( $( compgen -W "gzip none zlib" -- "${cur##*=}" ) ) + return + ;; + syslog-address) + COMPREPLY=( $( compgen -W "tcp:// tcp+tls:// udp:// unix://" -- "${cur##*=}" ) ) + __docker_nospace + __ltrim_colon_completions "${cur}" + return + ;; + syslog-facility) COMPREPLY=( $( compgen -W " auth authpriv @@ -438,18 +594,29 @@ __docker_complete_log_driver_options() { syslog user uucp - " -- "${cur#=}" ) ) + " -- "${cur##*=}" ) ) return ;; - *splunk-url=*) - COMPREPLY=( $( compgen -W "http:// https://" -- "${cur#=}" ) ) - compopt -o nospace + syslog-format) + COMPREPLY=( $( compgen -W "rfc3164 rfc5424 rfc5424micro" -- "${cur##*=}" ) ) + return + ;; + syslog-tls-ca-cert|syslog-tls-cert|syslog-tls-key) + _filedir + return + ;; + syslog-tls-skip-verify) + COMPREPLY=( $( compgen -W "true" -- "${cur##*=}" ) ) + return + ;; + splunk-url) + COMPREPLY=( $( compgen -W "http:// https://" -- "${cur##*=}" ) ) + __docker_nospace __ltrim_colon_completions "${cur}" return ;; - *splunk-insecureskipverify=*) - COMPREPLY=( $( compgen -W "true false" -- "${cur#=}" ) ) - compopt -o nospace + splunk-insecureskipverify) + COMPREPLY=( $( compgen -W "false true" -- "${cur##*=}" ) ) return ;; esac @@ -460,6 +627,22 @@ __docker_complete_log_levels() { COMPREPLY=( $( compgen -W "debug info warn error fatal" -- "$cur" ) ) } +__docker_complete_restart() { + case "$prev" in + --restart) + case "$cur" in + on-failure:*) + ;; + *) + COMPREPLY=( $( compgen -W "always no on-failure on-failure: unless-stopped" -- "$cur") ) + ;; + esac + return + ;; + esac + return 1 +} + # a selection of the available signals that is most likely of interest in the # context of docker containers. __docker_complete_signals() { @@ -477,6 +660,15 @@ __docker_complete_signals() { COMPREPLY=( $( compgen -W "${signals[*]} ${signals[*]#SIG}" -- "$( echo $cur | tr '[:lower:]' '[:upper:]')" ) ) } +__docker_complete_user_group() { + if [[ $cur == *:* ]] ; then + COMPREPLY=( $(compgen -g -- "${cur#*:}") ) + else + COMPREPLY=( $(compgen -u -S : -- "$cur") ) + __docker_nospace + fi +} + # global options that may appear after the docker command _docker_docker() { local boolean_options=" @@ -504,7 +696,7 @@ _docker_docker() { COMPREPLY=( $( compgen -W "$boolean_options $global_options_with_args" -- "$cur" ) ) ;; *) - local counter=$( __docker_pos_first_nonflag $(__docker_to_extglob "$global_options_with_args") ) + local counter=$( __docker_pos_first_nonflag "$(__docker_to_extglob "$global_options_with_args")" ) if [ $cword -eq $counter ]; then COMPREPLY=( $( compgen -W "${commands[*]} help" -- "$cur" ) ) fi @@ -513,12 +705,14 @@ _docker_docker() { } _docker_attach() { - case "$cur" in + __docker_complete_detach-keys && return + + case "$cur" in -*) - COMPREPLY=( $( compgen -W "--help --no-stdin --sig-proxy" -- "$cur" ) ) + COMPREPLY=( $( compgen -W "--detach-keys --help --no-stdin --sig-proxy=false" -- "$cur" ) ) ;; *) - local counter="$(__docker_pos_first_nonflag)" + local counter=$(__docker_pos_first_nonflag '--detach-keys') if [ $cword -eq $counter ]; then __docker_complete_containers_running fi @@ -532,13 +726,15 @@ _docker_build() { --cgroup-parent --cpuset-cpus --cpuset-mems - --cpu-shares + --cpu-shares -c --cpu-period --cpu-quota --file -f --isolation + --label --memory -m --memory-swap + --shm-size --tag -t --ulimit " @@ -600,7 +796,7 @@ _docker_commit() { case "$cur" in -*) - COMPREPLY=( $( compgen -W "--author -a --change -c --help --message -m --pause -p" -- "$cur" ) ) + COMPREPLY=( $( compgen -W "--author -a --change -c --help --message -m --pause=false -p=false" -- "$cur" ) ) ;; *) local counter=$(__docker_pos_first_nonflag '--author|-a|--change|-c|--message|-m') @@ -622,7 +818,7 @@ _docker_commit() { _docker_cp() { case "$cur" in -*) - COMPREPLY=( $( compgen -W "--help" -- "$cur" ) ) + COMPREPLY=( $( compgen -W "--follow-link -L --help" -- "$cur" ) ) ;; *) local counter=$(__docker_pos_first_nonflag) @@ -678,19 +874,24 @@ _docker_daemon() { --ip-masq=false --iptables=false --ipv6 + --live-restore + --raw-logs --selinux-enabled --userland-proxy=false " local options_with_args=" $global_options_with_args + --add-runtime --api-cors-header - --authz-plugin + --authorization-plugin --bip --bridge -b --cgroup-parent --cluster-advertise --cluster-store --cluster-store-opt + --config-file + --containerd --default-gateway --default-gateway-v6 --default-ulimit @@ -708,15 +909,46 @@ _docker_daemon() { --label --log-driver --log-opt + --max-concurrent-downloads + --max-concurrent-uploads --mtu --pidfile -p --registry-mirror --storage-driver -s --storage-opt + --userns-remap " + __docker_complete_log_driver_options && return + + 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|dm.override_udev_sync_check|dm.use_deferred_removal|dm.use_deferred_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 - --authz-plugin) + --authorization-plugin) __docker_complete_plugins Authorization return ;; @@ -726,7 +958,7 @@ _docker_daemon() { return ;; --cluster-store-opt) - COMPREPLY=( $( compgen -W "kv.cacertfile kv.certfile kv.keyfile" -S = -- "$cur" ) ) + COMPREPLY=( $( compgen -W "discovery.heartbeat discovery.ttl kv.cacertfile kv.certfile kv.keyfile kv.path" -S = -- "$cur" ) ) __docker_nospace return ;; @@ -738,15 +970,16 @@ _docker_daemon() { __docker_complete_log_drivers return ;; - --pidfile|-p|--tlscacert|--tlscert|--tlskey) + --config-file|--containerd|--pidfile|-p|--tlscacert|--tlscert|--tlskey) _filedir return ;; --storage-driver|-s) - COMPREPLY=( $( compgen -W "aufs btrfs devicemapper overlay vfs zfs" -- "$(echo $cur | tr '[:upper:]' '[:lower:]')" ) ) + COMPREPLY=( $( compgen -W "aufs btrfs devicemapper overlay overlay2 vfs zfs" -- "$(echo $cur | tr '[:upper:]' '[:lower:]')" ) ) return ;; --storage-opt) + local btrfs_options="btrfs.min_space" local devicemapper_options=" dm.basesize dm.blkdiscard @@ -754,6 +987,7 @@ _docker_daemon() { dm.fs dm.loopdatasize dm.loopmetadatasize + dm.min_free_space dm.mkfsarg dm.mountopt dm.override_udev_sync_check @@ -765,7 +999,10 @@ _docker_daemon() { case $(__docker_value_of_option '--storage-driver|-s') in '') - COMPREPLY=( $( compgen -W "$devicemapper_options $zfs_options" -S = -- "$cur" ) ) + COMPREPLY=( $( compgen -W "$btrfs_options $devicemapper_options $zfs_options" -S = -- "$cur" ) ) + ;; + btrfs) + COMPREPLY=( $( compgen -W "$btrfs_options" -S = -- "$cur" ) ) ;; devicemapper) COMPREPLY=( $( compgen -W "$devicemapper_options" -S = -- "$cur" ) ) @@ -788,34 +1025,15 @@ _docker_daemon() { __docker_complete_log_options return ;; + --userns-remap) + __docker_complete_user_group + return + ;; $(__docker_to_extglob "$options_with_args") ) return ;; 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" ) ) @@ -838,58 +1056,88 @@ _docker_diff() { } _docker_events() { - case "$prev" in - --filter|-f) - COMPREPLY=( $( compgen -S = -W "container event image" -- "$cur" ) ) - __docker_nospace - return - ;; - --since|--until) - return - ;; - esac - - case "${words[$cword-2]}$prev=" in - *container=*) - cur="${cur#=}" + local key=$(__docker_map_key_of_current_option '-f|--filter') + case "$key" in + container) + cur="${cur##*=}" __docker_complete_containers_all return ;; - *event=*) + daemon) + local name=$(__docker_q info | sed -n 's/^\(ID\|Name\): //p') + COMPREPLY=( $( compgen -W "$name" -- "${cur##*=}" ) ) + return + ;; + event) COMPREPLY=( $( compgen -W " attach commit + connect copy create delete destroy + detach die + disconnect exec_create + exec_detach exec_start export import kill + load + mount oom pause pull push + reload rename resize restart + save start stop tag top + unmount unpause untag - " -- "${cur#=}" ) ) + update + " -- "${cur##*=}" ) ) return ;; - *image=*) - cur="${cur#=}" + image) + cur="${cur##*=}" __docker_complete_images return ;; + network) + cur="${cur##*=}" + __docker_complete_networks + return + ;; + type) + COMPREPLY=( $( compgen -W "container daemon image network volume" -- "${cur##*=}" ) ) + return + ;; + volume) + cur="${cur##*=}" + __docker_complete_volumes + return + ;; + esac + + case "$prev" in + --filter|-f) + COMPREPLY=( $( compgen -S = -W "container daemon event image label network type volume" -- "$cur" ) ) + __docker_nospace + return + ;; + --since|--until) + return + ;; esac case "$cur" in @@ -900,15 +1148,18 @@ _docker_events() { } _docker_exec() { + __docker_complete_detach-keys && return + case "$prev" in --user|-u) + __docker_complete_user_group return ;; esac case "$cur" in -*) - COMPREPLY=( $( compgen -W "--detach -d --help --interactive -i --privileged -t --tty -u --user" -- "$cur" ) ) + COMPREPLY=( $( compgen -W "--detach -d --detach-keys --help --interactive -i --privileged -t --tty -u --user" -- "$cur" ) ) ;; *) __docker_complete_containers_running @@ -940,7 +1191,7 @@ _docker_help() { _docker_history() { case "$cur" in -*) - COMPREPLY=( $( compgen -W "--help --no-trunc --quiet -q" -- "$cur" ) ) + COMPREPLY=( $( compgen -W "--help --human=false -H=false --no-trunc --quiet -q" -- "$cur" ) ) ;; *) local counter=$(__docker_pos_first_nonflag) @@ -952,25 +1203,34 @@ _docker_history() { } _docker_images() { - case "$prev" in - --filter|-f) - COMPREPLY=( $( compgen -W "dangling=true label=" -- "$cur" ) ) - if [ "$COMPREPLY" = "label=" ]; then - __docker_nospace - fi + local key=$(__docker_map_key_of_current_option '--filter|-f') + case "$key" in + before) + cur="${cur##*=}" + __docker_complete_images return ;; - --format) + dangling) + COMPREPLY=( $( compgen -W "false true" -- "${cur##*=}" ) ) + return + ;; + label) + return + ;; + since) + cur="${cur##*=}" + __docker_complete_images return ;; esac - case "${words[$cword-2]}$prev=" in - *dangling=*) - COMPREPLY=( $( compgen -W "true false" -- "${cur#=}" ) ) + case "$prev" in + --filter|-f) + COMPREPLY=( $( compgen -S = -W "before dangling label since" -- "$cur" ) ) + __docker_nospace return ;; - *label=*) + --format) return ;; esac @@ -1081,21 +1341,21 @@ _docker_load() { case "$cur" in -*) - COMPREPLY=( $( compgen -W "--help --input -i" -- "$cur" ) ) + COMPREPLY=( $( compgen -W "--help --input -i --quiet -q" -- "$cur" ) ) ;; esac } _docker_login() { case "$prev" in - --email|-e|--password|-p|--username|-u) + --password|-p|--username|-u) return ;; esac case "$cur" in -*) - COMPREPLY=( $( compgen -W "--email -e --help --password -p --username -u" -- "$cur" ) ) + COMPREPLY=( $( compgen -W "--help --password -p --username -u" -- "$cur" ) ) ;; esac } @@ -1117,7 +1377,7 @@ _docker_logs() { case "$cur" in -*) - COMPREPLY=( $( compgen -W "--follow -f --help --since --tail --timestamps -t" -- "$cur" ) ) + COMPREPLY=( $( compgen -W "--details --follow -f --help --since --tail --timestamps -t" -- "$cur" ) ) ;; *) local counter=$(__docker_pos_first_nonflag '--tail') @@ -1129,16 +1389,46 @@ _docker_logs() { } _docker_network_connect() { + local options_with_args=" + --alias + --ip + --ip6 + --link + --link-local-ip + " + + local boolean_options=" + --help + " + + case "$prev" in + --link) + case "$cur" in + *:*) + ;; + *) + __docker_complete_containers_running + COMPREPLY=( $( compgen -W "${COMPREPLY[*]}" -S ':' ) ) + __docker_nospace + ;; + esac + return + ;; + $(__docker_to_extglob "$options_with_args") ) + return + ;; + esac + case "$cur" in -*) - COMPREPLY=( $( compgen -W "--help" -- "$cur" ) ) + COMPREPLY=( $( compgen -W "$boolean_options $options_with_args" -- "$cur" ) ) ;; *) - local counter=$(__docker_pos_first_nonflag) + local counter=$( __docker_pos_first_nonflag $( __docker_to_alternatives "$options_with_args" ) ) if [ $cword -eq $counter ]; then __docker_complete_networks elif [ $cword -eq $(($counter + 1)) ]; then - __docker_complete_containers_running + __docker_complete_containers_all fi ;; esac @@ -1146,7 +1436,7 @@ _docker_network_connect() { _docker_network_create() { case "$prev" in - --aux-address|--gateway|--ip-range|--opt|-o|--subnet) + --aux-address|--gateway|--internal|--ip-range|--ipam-opt|--ipv6|--opt|-o|--subnet) return ;; --ipam-driver) @@ -1161,11 +1451,14 @@ _docker_network_create() { COMPREPLY=( $(compgen -W "$plugins" -- "$cur") ) return ;; + --label) + return + ;; esac case "$cur" in -*) - COMPREPLY=( $( compgen -W "--aux-address --driver -d --gateway --help --ip-range --ipam-driver --opt -o --subnet" -- "$cur" ) ) + COMPREPLY=( $( compgen -W "--aux-address --driver -d --gateway --help --internal --ip-range --ipam-driver --ipam-opt --ipv6 --label --opt -o --subnet" -- "$cur" ) ) ;; esac } @@ -1203,27 +1496,33 @@ _docker_network_inspect() { } _docker_network_ls() { - case "$prev" in - --filter|-f) - COMPREPLY=( $( compgen -S = -W "id name type" -- "$cur" ) ) - __docker_nospace + local key=$(__docker_map_key_of_current_option '--filter|-f') + case "$key" in + driver) + local plugins=" $(__docker_plugins Network) " + COMPREPLY=( $(compgen -W "$plugins" -- "${cur##*=}") ) + return + ;; + id) + cur="${cur##*=}" + __docker_complete_network_ids + return + ;; + name) + cur="${cur##*=}" + __docker_complete_network_names + return + ;; + type) + COMPREPLY=( $( compgen -W "builtin custom" -- "${cur##*=}" ) ) return ;; esac - case "${words[$cword-2]}$prev=" in - *id=*) - cur="${cur#=}" - __docker_complete_network_ids - return - ;; - *name=*) - cur="${cur#=}" - __docker_complete_network_names - return - ;; - *type=*) - COMPREPLY=( $( compgen -W "builtin custom" -- "${cur#=}" ) ) + case "$prev" in + --filter|-f) + COMPREPLY=( $( compgen -S = -W "driver id label name type" -- "$cur" ) ) + __docker_nospace return ;; esac @@ -1241,7 +1540,7 @@ _docker_network_rm() { COMPREPLY=( $( compgen -W "--help" -- "$cur" ) ) ;; *) - __docker_complete_networks + __docker_complete_networks type=custom esac } @@ -1266,6 +1565,512 @@ _docker_network() { esac } +_docker_service() { + local subcommands=" + create + inspect + ls list + rm remove + scale + tasks + update + " + __docker_subcommands "$subcommands" && return + + case "$cur" in + -*) + COMPREPLY=( $( compgen -W "--help" -- "$cur" ) ) + ;; + *) + COMPREPLY=( $( compgen -W "$subcommands" -- "$cur" ) ) + ;; + esac +} + +_docker_service_create() { + _docker_service_update +} + +_docker_service_inspect() { + case "$prev" in + --format|-f) + return + ;; + esac + + case "$cur" in + -*) + COMPREPLY=( $( compgen -W "--format -f --help --pretty -p" -- "$cur" ) ) + ;; + *) + __docker_complete_services + esac +} + +_docker_service_list() { + _docker_service_ls +} + +_docker_service_ls() { + local key=$(__docker_map_key_of_current_option '--filter|-f') + case "$key" in + id) + __docker_complete_services --cur "${cur##*=}" --id + return + ;; + name) + __docker_complete_services --cur "${cur##*=}" --name + return + ;; + esac + + case "$prev" in + --filter|-f) + COMPREPLY=( $( compgen -W "id label name" -S = -- "$cur" ) ) + __docker_nospace + return + ;; + esac + + case "$cur" in + -*) + COMPREPLY=( $( compgen -W "--filter -f --help --quiet -q" -- "$cur" ) ) + ;; + esac +} + +_docker_service_remove() { + _docker_service_rm +} + +_docker_service_rm() { + case "$cur" in + -*) + COMPREPLY=( $( compgen -W "--help" -- "$cur" ) ) + ;; + *) + __docker_complete_services + esac +} + +_docker_service_scale() { + case "$cur" in + -*) + COMPREPLY=( $( compgen -W "--help" -- "$cur" ) ) + ;; + *) + __docker_complete_services + __docker_append_to_completions "=" + __docker_nospace + ;; + esac +} + +_docker_service_tasks() { + local key=$(__docker_map_key_of_current_option '--filter|-f') + case "$key" in + desired-state) + COMPREPLY=( $( compgen -W "accepted running" -- "${cur##*=}" ) ) + return + ;; + name) + __docker_complete_services --cur "${cur##*=}" --name + return + ;; + esac + + case "$prev" in + --filter|-f) + COMPREPLY=( $( compgen -W "desired-state id name" -S = -- "$cur" ) ) + __docker_nospace + return + ;; + esac + + case "$cur" in + -*) + COMPREPLY=( $( compgen -W "--all -a --filter -f --help --no-resolve -n" -- "$cur" ) ) + ;; + *) + local counter=$(__docker_pos_first_nonflag '--filter|-f') + if [ $cword -eq $counter ]; then + __docker_complete_services + fi + ;; + esac +} + +_docker_service_update() { + local $subcommand="${words[$subcommand_pos]}" + + local options_with_args=" + --constraint + --endpoint-mode + --env -e + --label -l + --limit-cpu + --limit-memory + --mode + --mount -m + --name + --network + --publish -p + --replicas + --reserve-cpu + --reserve-memory + --restart-condition + --restart-delay + --restart-max-attempts + --restart-window + --stop-grace-period + --update-delay + --update-parallelism + --user -u + --workdir -w + " + + local boolean_options=" + --help + " + + if [ "$subcommand" = "update" ] ; then + options_with_args="$options_with_args + --arg + --command + --image + " + + case "$prev" in + --image) + __docker_complete_image_repos_and_tags + return + ;; + esac + fi + + case "$prev" in + --endpoint-mode) + COMPREPLY=( $( compgen -W "DNSRR VIP" -- "$cur" ) ) + return + ;; + --env|-e) + COMPREPLY=( $( compgen -e -S = -- "$cur" ) ) + __docker_nospace + return + ;; + --mode) + COMPREPLY=( $( compgen -W "global replicated" -- "$cur" ) ) + return + ;; + --network) + __docker_complete_networks + return + ;; + --restart-condition) + COMPREPLY=( $( compgen -W "any none on-failure" -- "$cur" ) ) + return + ;; + --user|-u) + __docker_complete_user_group + return + ;; + $(__docker_to_extglob "$options_with_args") ) + return + ;; + esac + + case "$cur" in + -*) + COMPREPLY=( $( compgen -W "$boolean_options $options_with_args" -- "$cur" ) ) + ;; + *) + if [ "$subcommand" = "update" ] ; then + __docker_complete_services + fi + esac +} + +_docker_swarm() { + local subcommands=" + init + inspect + join + leave + update + " + __docker_subcommands "$subcommands" && return + + case "$cur" in + -*) + COMPREPLY=( $( compgen -W "--help" -- "$cur" ) ) + ;; + *) + COMPREPLY=( $( compgen -W "$subcommands" -- "$cur" ) ) + ;; + esac +} + +_docker_swarm_init() { + case "$prev" in + --auto-accept) + COMPREPLY=( $( compgen -W "manager none worker" -- "$cur" ) ) + return + ;; + --listen-addr) + if [[ $cur == *: ]] ; then + COMPREPLY=( $( compgen -W "2377" -- "${cur##*:}" ) ) + fi + return + ;; + --secret) + return + ;; + esac + + case "$cur" in + -*) + COMPREPLY=( $( compgen -W "--auto-accept --force-new-cluster --help --listen-addr --secret" -- "$cur" ) ) + ;; + esac +} + +_docker_swarm_inspect() { + case "$prev" in + --format|-f) + return + ;; + esac + + case "$cur" in + -*) + COMPREPLY=( $( compgen -W "--format -f --help" -- "$cur" ) ) + ;; + esac +} + +_docker_swarm_join() { + case "$prev" in + --ca-hash|--secret) + return + ;; + --listen-addr) + if [[ $cur == *: ]] ; then + COMPREPLY=( $( compgen -W "2377" -- "${cur##*:}" ) ) + fi + return + ;; + esac + + case "$cur" in + -*) + COMPREPLY=( $( compgen -W "--ca-hash --help --listen-addr --manager --secret" -- "$cur" ) ) + ;; + *:) + COMPREPLY=( $( compgen -W "2377" -- "${cur##*:}" ) ) + ;; + esac +} + +_docker_swarm_leave() { + case "$cur" in + -*) + COMPREPLY=( $( compgen -W "--force --help" -- "$cur" ) ) + ;; + esac +} + +_docker_swarm_update() { + case "$prev" in + --auto-accept) + COMPREPLY=( $( compgen -W "manager none worker" -- "$cur" ) ) + return + ;; + --cert-expiry|--dispatcher-heartbeat|--secret|--task-history-limit) + return + ;; + esac + + case "$cur" in + -*) + COMPREPLY=( $( compgen -W "--auto-accept --cert-expiry --dispatcher-heartbeat --help --secret --task-history-limit" -- "$cur" ) ) + ;; + esac +} + +_docker_node() { + local subcommands=" + accept + demote + inspect + ls list + promote + rm remove + tasks + update + " + __docker_subcommands "$subcommands" && return + + case "$cur" in + -*) + COMPREPLY=( $( compgen -W "--help" -- "$cur" ) ) + ;; + *) + COMPREPLY=( $( compgen -W "$subcommands" -- "$cur" ) ) + ;; + esac +} + +_docker_node_accept() { + case "$cur" in + -*) + COMPREPLY=( $( compgen -W "--help" -- "$cur" ) ) + ;; + *) + __docker_complete_nodes --id --filter membership=pending + esac +} + +_docker_node_demote() { + case "$cur" in + -*) + COMPREPLY=( $( compgen -W "--help" -- "$cur" ) ) + ;; + *) + __docker_complete_nodes --filter role=manager + esac +} + +_docker_node_inspect() { + case "$prev" in + --format|-f) + return + ;; + esac + + case "$cur" in + -*) + COMPREPLY=( $( compgen -W "--format -f --help --pretty -p" -- "$cur" ) ) + ;; + *) + __docker_complete_nodes + esac +} + +_docker_node_list() { + _docker_node_ls +} + +_docker_node_ls() { + local key=$(__docker_map_key_of_current_option '--filter|-f') + case "$key" in + id) + __docker_complete_nodes --cur "${cur##*=}" --id + return + ;; + name) + __docker_complete_nodes --cur "${cur##*=}" --name + return + ;; + esac + + case "$prev" in + --filter|-f) + COMPREPLY=( $( compgen -W "id label name" -S = -- "$cur" ) ) + __docker_nospace + return + ;; + esac + + case "$cur" in + -*) + COMPREPLY=( $( compgen -W "--filter -f --help --quiet -q" -- "$cur" ) ) + ;; + esac +} + +_docker_node_promote() { + case "$cur" in + -*) + COMPREPLY=( $( compgen -W "--help" -- "$cur" ) ) + ;; + *) + __docker_complete_nodes --filter role=worker + esac +} + +_docker_node_remove() { + _docker_node_rm +} + +_docker_node_rm() { + case "$cur" in + -*) + COMPREPLY=( $( compgen -W "--help" -- "$cur" ) ) + ;; + *) + __docker_complete_nodes + esac +} + +_docker_node_tasks() { + local key=$(__docker_map_key_of_current_option '--filter|-f') + case "$key" in + desired-state) + COMPREPLY=( $( compgen -W "accepted running" -- "${cur##*=}" ) ) + return + ;; + name) + __docker_complete_services --cur "${cur##*=}" --name + return + ;; + esac + + case "$prev" in + --filter|-f) + COMPREPLY=( $( compgen -W "desired-state id label name" -S = -- "$cur" ) ) + __docker_nospace + return + ;; + esac + + case "$cur" in + -*) + COMPREPLY=( $( compgen -W "--all -a --filter -f --help --no-resolve -n" -- "$cur" ) ) + ;; + *) + local counter=$(__docker_pos_first_nonflag '--filter|-f') + if [ $cword -eq $counter ]; then + __docker_complete_nodes_plus_self + fi + ;; + esac +} + +_docker_node_update() { + case "$prev" in + --availability) + COMPREPLY=( $( compgen -W "active drain pause" -- "$cur" ) ) + return + ;; + --membership) + COMPREPLY=( $( compgen -W "accepted rejected" -- "$cur" ) ) + return + ;; + --role) + COMPREPLY=( $( compgen -W "manager worker" -- "$cur" ) ) + return + ;; + esac + + case "$cur" in + -*) + COMPREPLY=( $( compgen -W "--availability --help --membership --role" -- "$cur" ) ) + ;; + *) + __docker_complete_nodes + esac +} + _docker_pause() { case "$cur" in -*) @@ -1295,45 +2100,63 @@ _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 + local key=$(__docker_map_key_of_current_option '--filter|-f') + case "$key" in + ancestor) + cur="${cur##*=}" + __docker_complete_images return ;; - --format|-n) + before) + cur="${cur##*=}" + __docker_complete_containers_all + return + ;; + id) + cur="${cur##*=}" + __docker_complete_container_ids + return + ;; + name) + cur="${cur##*=}" + __docker_complete_container_names + return + ;; + network) + cur="${cur##*=}" + __docker_complete_networks + return + ;; + since) + cur="${cur##*=}" + __docker_complete_containers_all + return + ;; + status) + COMPREPLY=( $( compgen -W "created dead exited paused restarting running" -- "${cur##*=}" ) ) + return + ;; + volume) + cur="${cur##*=}" + __docker_complete_volumes return ;; esac - case "${words[$cword-2]}$prev=" in - *ancestor=*) - cur="${cur#=}" - __docker_complete_images + case "$prev" in + --filter|-f) + COMPREPLY=( $( compgen -S = -W "ancestor before exited id label name network since status volume" -- "$cur" ) ) + __docker_nospace return ;; - *id=*) - cur="${cur#=}" - __docker_complete_container_ids - return - ;; - *name=*) - cur="${cur#=}" - __docker_complete_container_names - return - ;; - *status=*) - COMPREPLY=( $( compgen -W "exited paused restarting running" -- "${cur#=}" ) ) + --format|--last|-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" ) ) + COMPREPLY=( $( compgen -W "--all -a --filter -f --format --help --last -n --latest -l --no-trunc --quiet -q --size -s" -- "$cur" ) ) ;; esac } @@ -1341,7 +2164,7 @@ _docker_ps() { _docker_pull() { case "$cur" in -*) - COMPREPLY=( $( compgen -W "--all-tags -a --help" -- "$cur" ) ) + COMPREPLY=( $( compgen -W "--all-tags -a --disable-content-trust=false --help" -- "$cur" ) ) ;; *) local counter=$(__docker_pos_first_nonflag) @@ -1363,7 +2186,7 @@ _docker_pull() { _docker_push() { case "$cur" in -*) - COMPREPLY=( $( compgen -W "--help" -- "$cur" ) ) + COMPREPLY=( $( compgen -W "--disable-content-trust=false --help" -- "$cur" ) ) ;; *) local counter=$(__docker_pos_first_nonflag) @@ -1449,7 +2272,7 @@ _docker_run() { --cpu-quota --cpuset-cpus --cpuset-mems - --cpu-shares + --cpu-shares -c --device --device-read-bps --device-read-iops @@ -1464,12 +2287,15 @@ _docker_run() { --expose --group-add --hostname -h + --ip + --ip6 --ipc --isolation --kernel-memory --label-file --label -l --link + --link-local-ip --log-driver --log-opt --mac-address @@ -1479,15 +2305,22 @@ _docker_run() { --memory-reservation --name --net + --net-alias --oom-score-adj --pid + --pids-limit --publish -p --restart + --runtime --security-opt + --shm-size --stop-signal + --storage-opt --tmpfs + --sysctl --ulimit --user -u + --userns --uts --volume-driver --volumes-from @@ -1506,13 +2339,46 @@ _docker_run() { --tty -t " + if [ "$command" = "run" ] ; then + options_with_args="$options_with_args + --detach-keys + --health-cmd + --health-interval + --health-retries + --health-timeout + " + boolean_options="$boolean_options + --detach -d + --no-healthcheck + --rm + --sig-proxy=false + " + __docker_complete_detach-keys && return + fi + local all_options="$options_with_args $boolean_options" - [ "$command" = "run" ] && all_options="$all_options - --detach -d - --rm - --sig-proxy=false - " + + __docker_complete_log_driver_options && return + __docker_complete_restart && return + + local key=$(__docker_map_key_of_current_option '--security-opt') + case "$key" in + label) + [[ $cur == *: ]] && return + COMPREPLY=( $( compgen -W "user: role: type: level: disable" -- "${cur##*=}") ) + if [ "${COMPREPLY[*]}" != "disable" ] ; then + __docker_nospace + fi + return + ;; + seccomp) + local cur=${cur##*=} + _filedir + COMPREPLY+=( $( compgen -W "unconfined" -- "$cur" ) ) + return + ;; + esac case "$prev" in --add-host) @@ -1610,32 +2476,43 @@ _docker_run() { esac return ;; - --restart) + --pid) case "$cur" in - on-failure:*) + *:*) + cur="${cur#*:}" + __docker_complete_containers_running ;; *) - COMPREPLY=( $( compgen -W "always no on-failure on-failure: unless-stopped" -- "$cur") ) + COMPREPLY=( $( compgen -W 'host container:' -- "$cur" ) ) + if [ "$COMPREPLY" = "container:" ]; then + __docker_nospace + fi ;; esac return ;; + --runtime) + __docker_complete_runtimes + return + ;; --security-opt) - case "$cur" in - label:*:*) - ;; - label:*) - local cur=${cur##*:} - COMPREPLY=( $( compgen -W "user: role: type: level: disable" -- "$cur") ) - if [ "${COMPREPLY[*]}" != "disable" ] ; then - __docker_nospace - fi - ;; - *) - COMPREPLY=( $( compgen -W "label apparmor seccomp" -S ":" -- "$cur") ) - __docker_nospace - ;; - esac + COMPREPLY=( $( compgen -W "apparmor= label= no-new-privileges seccomp=" -- "$cur") ) + if [ "${COMPREPLY[*]}" != "no-new-privileges" ] ; then + __docker_nospace + fi + return + ;; + --storage-opt) + COMPREPLY=( $( compgen -W "size" -S = -- "$cur") ) + __docker_nospace + return + ;; + --user|-u) + __docker_complete_user_group + return + ;; + --userns) + COMPREPLY=( $( compgen -W "host" -- "$cur" ) ) return ;; --volume-driver) @@ -1651,8 +2528,6 @@ _docker_run() { ;; esac - __docker_complete_log_driver_options && return - case "$cur" in -*) COMPREPLY=( $( compgen -W "$all_options" -- "$cur" ) ) @@ -1685,23 +2560,42 @@ _docker_save() { } _docker_search() { + local key=$(__docker_map_key_of_current_option '--filter|-f') + case "$key" in + is-automated) + COMPREPLY=( $( compgen -W "false true" -- "${cur##*=}" ) ) + return + ;; + is-official) + COMPREPLY=( $( compgen -W "false true" -- "${cur##*=}" ) ) + return + ;; + esac + case "$prev" in - --stars|-s) + --filter|-f) + COMPREPLY=( $( compgen -S = -W "is-automated is-official stars" -- "$cur" ) ) + __docker_nospace + return + ;; + --limit) return ;; esac case "$cur" in -*) - COMPREPLY=( $( compgen -W "--automated --help --no-trunc --stars -s" -- "$cur" ) ) + COMPREPLY=( $( compgen -W "--filter --help --limit --no-trunc" -- "$cur" ) ) ;; esac } _docker_start() { + __docker_complete_detach-keys && return + case "$cur" in -*) - COMPREPLY=( $( compgen -W "--attach -a --help --interactive -i" -- "$cur" ) ) + COMPREPLY=( $( compgen -W "--attach -a --detach-keys --help --interactive -i" -- "$cur" ) ) ;; *) __docker_complete_containers_stopped @@ -1740,7 +2634,7 @@ _docker_stop() { _docker_tag() { case "$cur" in -*) - COMPREPLY=( $( compgen -W "--force -f --help" -- "$cur" ) ) + COMPREPLY=( $( compgen -W "--help" -- "$cur" ) ) ;; *) local counter=$(__docker_pos_first_nonflag) @@ -1780,11 +2674,12 @@ _docker_update() { --cpu-quota --cpuset-cpus --cpuset-mems - --cpu-shares + --cpu-shares -c --kernel-memory --memory -m --memory-reservation --memory-swap + --restart " local boolean_options=" @@ -1793,6 +2688,8 @@ _docker_update() { local all_options="$options_with_args $boolean_options" + __docker_complete_restart && return + case "$prev" in $(__docker_to_extglob "$options_with_args") ) return @@ -1837,14 +2734,14 @@ _docker_volume_create() { __docker_complete_plugins Volume return ;; - --name|--opt|-o) + --label|--name|--opt|-o) return ;; esac case "$cur" in -*) - COMPREPLY=( $( compgen -W "--driver -d --help --name --opt -o" -- "$cur" ) ) + COMPREPLY=( $( compgen -W "--driver -d --help --label --name --opt -o" -- "$cur" ) ) ;; esac } @@ -1867,9 +2764,28 @@ _docker_volume_inspect() { } _docker_volume_ls() { + local key=$(__docker_map_key_of_current_option '--filter|-f') + case "$key" in + dangling) + COMPREPLY=( $( compgen -W "true false" -- "${cur##*=}" ) ) + return + ;; + driver) + cur=${cur##*=} + __docker_complete_plugins Volume + return + ;; + name) + cur=${cur##*=} + __docker_complete_volumes + return + ;; + esac + case "$prev" in --filter|-f) - COMPREPLY=( $( compgen -W "dangling=true" -- "$cur" ) ) + COMPREPLY=( $( compgen -S = -W "dangling driver name" -- "$cur" ) ) + __docker_nospace return ;; esac @@ -1948,6 +2864,7 @@ _docker() { logout logs network + node pause port ps @@ -1960,9 +2877,11 @@ _docker() { run save search + service start stats stop + swarm tag top unpause @@ -2025,6 +2944,14 @@ _docker() { (( counter++ )) done + local binary="${words[0]}" + if [[ $binary == ?(*/)dockerd ]] ; then + # for the dockerd binary, we reuse completion of `docker daemon`. + # dockerd does not have subcommands and global options. + command=daemon + command_pos=0 + fi + local completions_func=_docker_${command} declare -F $completions_func >/dev/null && $completions_func @@ -2035,4 +2962,4 @@ _docker() { eval "$__docker_previous_extglob_setting" unset __docker_previous_extglob_setting -complete -F _docker docker +complete -F _docker docker dockerd