diff --git a/README.md b/README.md index 2c078699..022ce442 100644 --- a/README.md +++ b/README.md @@ -200,7 +200,7 @@ export BASH_IT_THEME="powerline-multiline" export BASH_IT_THEME="/home/foo/my_theme/my_theme.theme.bash" ``` -You can easily preview the themes in your own shell using `BASH_PREVIEW=true reload`. +You can easily preview the themes in your own shell using `BASH_PREVIEW=true bash-it reload`. If you've created your own custom prompts, we'd love it if you shared with everyone else! Just submit a Pull Request. You can see theme screenshots on [wiki/Themes](https://github.com/Bash-it/bash-it/wiki/Themes). diff --git a/aliases/available/clipboard.aliases.bash b/aliases/available/clipboard.aliases.bash index 21b770a6..528e2d0e 100644 --- a/aliases/available/clipboard.aliases.bash +++ b/aliases/available/clipboard.aliases.bash @@ -4,7 +4,9 @@ about-alias 'pbcopy and pbpaste shortcuts to linux' case $OSTYPE in linux*) XCLIP=$(command -v xclip) - [[ $XCLIP ]] && alias pbcopy="$XCLIP -selection clipboard" && alias pbpaste="$XCLIP -selection clipboard -o" + [[ $XCLIP ]] && \ + alias pbcopy="$XCLIP -selection clipboard" && \ + alias pbpaste="$XCLIP -selection clipboard -o" ;; esac diff --git a/aliases/available/git.aliases.bash b/aliases/available/git.aliases.bash index cfd4bb91..fa411346 100644 --- a/aliases/available/git.aliases.bash +++ b/aliases/available/git.aliases.bash @@ -30,6 +30,7 @@ alias gup='git fetch && git rebase' alias gp='git push' alias gpo='git push origin' alias gpu='git push --set-upstream' +alias gpuo='git push --set-upstream origin' alias gpom='git push origin master' alias gr='git remote' alias grv='git remote -v' diff --git a/aliases/available/homebrew-cask.aliases.bash b/aliases/available/homebrew-cask.aliases.bash index 090622b0..57d8161c 100644 --- a/aliases/available/homebrew-cask.aliases.bash +++ b/aliases/available/homebrew-cask.aliases.bash @@ -7,7 +7,6 @@ alias bcin='brew cask install' alias bcrm='brew cask uninstall' alias bczp='brew cask zap' alias bccl='brew cask cleanup' -alias bcsr='brew cask search' alias bcls='brew cask list' alias bcinf='brew cask info' alias bcdr='brew cask doctor' diff --git a/aliases/available/kubectl.aliases.bash b/aliases/available/kubectl.aliases.bash new file mode 100644 index 00000000..58670ce5 --- /dev/null +++ b/aliases/available/kubectl.aliases.bash @@ -0,0 +1,24 @@ +#!/bin/bash +# +# -binaryanomaly + +cite 'about-alias' +about-alias 'kubectl aliases' + +# set apt aliases +function _set_pkg_aliases() +{ + if [ -x $(which kubectl) ]; then + alias kc='kubectl' + alias kcgp='kubectl get pods' + alias kcgd='kubectl get deployments' + alias kcgn='kubectl get nodes' + alias kcdp='kubectl describe pod' + alias kcdd='kubectl describe deployment' + alias kcdn='kubectl describe node' + alias kcgpan='kubectl get pods --all-namespaces' + alias kcgdan='kubectl get deployments --all-namespaces' + fi +} + +_set_pkg_aliases diff --git a/aliases/available/maven.aliases.bash b/aliases/available/maven.aliases.bash index 4cd89d27..f8a44a1c 100644 --- a/aliases/available/maven.aliases.bash +++ b/aliases/available/maven.aliases.bash @@ -3,9 +3,12 @@ about-alias 'maven abbreviations' alias mci='mvn clean install' alias mi='mvn install' +alias mcp='mvn clean package' +alias mp='mvn package' alias mrprep='mvn release:prepare' alias mrperf='mvn release:perform' alias mrrb='mvn release:rollback' alias mdep='mvn dependency:tree' alias mpom='mvn help:effective-pom' alias mcisk='mci -Dmaven.test.skip=true' +alias mcpsk='mcp -Dmaven.test.skip=true' diff --git a/aliases/available/npm.aliases.bash b/aliases/available/npm.aliases.bash index 4623c738..2266fe22 100644 --- a/aliases/available/npm.aliases.bash +++ b/aliases/available/npm.aliases.bash @@ -18,5 +18,5 @@ alias nod='npm outdated' alias nrb='npm rebuild' alias nud='npm update' alias nr='npm run' -alias nls='npm list' -alias nlsg='npm list --global' +alias nls='npm list --depth=0 2>/dev/null' +alias nlsg='npm list -g --depth=0 2>/dev/null' diff --git a/aliases/available/vault.aliases.bash b/aliases/available/vault.aliases.bash index 7c98aa58..d2ad8e74 100644 --- a/aliases/available/vault.aliases.bash +++ b/aliases/available/vault.aliases.bash @@ -11,5 +11,5 @@ alias vasrv="vault server" alias vas="vault status" alias vav="vault version" alias vaw="vault write" -alias vag="vault auth -method=github" +alias vag="vault login -method=github" alias varv="vault read -field=value" diff --git a/aliases/available/yarn.aliases.bash b/aliases/available/yarn.aliases.bash index c189aa8d..b50535b9 100644 --- a/aliases/available/yarn.aliases.bash +++ b/aliases/available/yarn.aliases.bash @@ -5,15 +5,18 @@ about-alias 'yarn package manager aliases' alias ya='yarn' alias yai='yarn init' alias yaa='yarn add' +alias yaga='yarn global add' alias yaad='yarn add --dev' alias yau='yarn upgrade' alias yarm='yarn remove' +alias yagrm='yarn global remove' alias yaod='yarn outdated' alias yapa='yarn pack' alias yap='yarn publish' alias yasu='yarn self-update' alias yaru='yarn run' alias yat='yarn test' +alias yas='yarn serve' alias yacc='yarn cache clean' alias yack='yarn check' alias yals='yarn list' diff --git a/bash_it.sh b/bash_it.sh index 70082205..8eea4c6a 100755 --- a/bash_it.sh +++ b/bash_it.sh @@ -1,31 +1,22 @@ #!/usr/bin/env bash # Initialize Bash It -# Reload Library -case $OSTYPE in - darwin*) - alias reload='source ~/.bash_profile' - ;; - *) - alias reload='source ~/.bashrc' - ;; -esac - # Only set $BASH_IT if it's not already set if [ -z "$BASH_IT" ]; then - # Setting $BASH to maintain backwards compatibility - # TODO: warn users that they should upgrade their .bash_profile - export BASH_IT=$BASH - export BASH="$(bash -c 'echo $BASH')" + # Setting $BASH to maintain backwards compatibility + # TODO: warn users that they should upgrade their .bash_profile + export BASH_IT=$BASH + BASH="$(bash -c 'echo $BASH')" + export BASH fi # For backwards compatibility, look in old BASH_THEME location if [ -z "$BASH_IT_THEME" ]; then - # TODO: warn users that they should upgrade their .bash_profile - export BASH_IT_THEME="$BASH_THEME"; - unset $BASH_THEME; + # TODO: warn users that they should upgrade their .bash_profile + export BASH_IT_THEME="$BASH_THEME"; + unset BASH_THEME; fi # Load composure first, so we support function metadata @@ -40,9 +31,9 @@ LIB="${BASH_IT}/lib/*.bash" APPEARANCE_LIB="${BASH_IT}/lib/appearance.bash" for config_file in $LIB do - if [ $config_file != $APPEARANCE_LIB ]; then + if [ "$config_file" != "$APPEARANCE_LIB" ]; then # shellcheck disable=SC1090 - source $config_file + source "$config_file" fi done @@ -60,12 +51,14 @@ done source "${BASH_IT}/themes/colors.theme.bash" # shellcheck source=./themes/githelpers.theme.bash source "${BASH_IT}/themes/githelpers.theme.bash" +# shellcheck source=./themes/p4helpers.theme.bash +source "${BASH_IT}/themes/p4helpers.theme.bash" # shellcheck source=./themes/base.theme.bash source "${BASH_IT}/themes/base.theme.bash" # appearance (themes) now, after all dependencies # shellcheck source=./lib/appearance.bash -source $APPEARANCE_LIB +source "$APPEARANCE_LIB" # Load custom aliases, completion, plugins for file_type in "aliases" "completion" "plugins" @@ -83,13 +76,13 @@ for config_file in $CUSTOM do if [ -e "${config_file}" ]; then # shellcheck disable=SC1090 - source $config_file + source "$config_file" fi done unset config_file if [[ $PROMPT ]]; then - export PS1="\[""$PROMPT""\]" + export PS1="\[""$PROMPT""\]" fi # Adding Support for other OSes @@ -110,5 +103,17 @@ then . "$HOME/.jekyllconfig" fi +# BASH_IT_RELOAD_LEGACY is set. +if ! command -v reload &>/dev/null && [ -n "$BASH_IT_RELOAD_LEGACY" ]; then + case $OSTYPE in + darwin*) + alias reload='source ~/.bash_profile' + ;; + *) + alias reload='source ~/.bashrc' + ;; + esac +fi + # Disable trap DEBUG on subshells - https://github.com/Bash-it/bash-it/pull/1040 set +T diff --git a/completion/available/bash-it.completion.bash b/completion/available/bash-it.completion.bash index 20a94e5b..71ec8418 100644 --- a/completion/available/bash-it.completion.bash +++ b/completion/available/bash-it.completion.bash @@ -65,7 +65,7 @@ _bash-it-comp() prev="${COMP_WORDS[COMP_CWORD-1]}" chose_opt="${COMP_WORDS[1]}" file_type="${COMP_WORDS[2]}" - opts="disable enable help migrate search show update version" + opts="disable enable help migrate reload search show update version" case "${chose_opt}" in show) local show_args="aliases completions plugins" @@ -82,7 +82,7 @@ _bash-it-comp() return 0 fi ;; - update | search | migrate | version) + migrate | reload | search | update | version) return 0 ;; enable | disable) diff --git a/completion/available/capistrano.completion.bash b/completion/available/capistrano.completion.bash old mode 100755 new mode 100644 diff --git a/completion/available/docker-compose.completion.bash b/completion/available/docker-compose.completion.bash index 1fdb2770..87161d0a 100644 --- a/completion/available/docker-compose.completion.bash +++ b/completion/available/docker-compose.completion.bash @@ -120,7 +120,7 @@ _docker_compose_build() { case "$cur" in -*) - COMPREPLY=( $( compgen -W "--build-arg --force-rm --help --no-cache --pull" -- "$cur" ) ) + COMPREPLY=( $( compgen -W "--build-arg --force-rm --help --memory --no-cache --pull" -- "$cur" ) ) ;; *) __docker_compose_services_from_build @@ -403,14 +403,14 @@ _docker_compose_run() { __docker_compose_nospace return ;; - --entrypoint|--name|--user|-u|--volume|-v|--workdir|-w) + --entrypoint|--label|-l|--name|--user|-u|--volume|-v|--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 --volume -v --workdir -w" -- "$cur" ) ) + COMPREPLY=( $( compgen -W "-d --entrypoint -e --help --label -l --name --no-deps --publish -p --rm --service-ports -T --user -u --volume -v --workdir -w" -- "$cur" ) ) ;; *) __docker_compose_services_all diff --git a/completion/available/docker-machine.completion.bash b/completion/available/docker-machine.completion.bash index a1ed9f87..e92bd4cf 100644 --- a/completion/available/docker-machine.completion.bash +++ b/completion/available/docker-machine.completion.bash @@ -14,71 +14,160 @@ # . ~/.docker-machine-completion.sh # -_docker_machine_active() { - if [[ "${cur}" == -* ]]; then - COMPREPLY=($(compgen -W "--help" -- "${cur}")) +# --- helper functions ------------------------------------------------------- + +_docker_machine_q() { + docker-machine 2>/dev/null "$@" +} + +# suppresses trailing whitespace +_docker_machine_nospace() { + # compopt is not available in ancient bash versions (OSX) + # so only call it if it's available + type compopt &>/dev/null && compopt -o nospace +} + +_docker_machine_machines() { + _docker_machine_q ls --format '{{.Name}}' "$@" +} + +_docker_machine_drivers() { + local drivers=( + amazonec2 + azure + digitalocean + exoscale + generic + google + hyperv + openstack + rackspace + softlayer + virtualbox + vmwarefusion + vmwarevcloudair + vmwarevsphere + ) + echo "${drivers[@]}" +} + +_docker_machine_value_of_option() { + local pattern="$1" + for (( i=2; i < ${cword}; ++i)); do + if [[ ${words[$i]} =~ ^($pattern)$ ]] ; then + echo ${words[$i + 1]} + break + fi + done +} + +# Returns `key` if we are currently completing the value of a map option +# (`key=value`) which matches the glob passed in as an argument. +# This function is needed for key-specific argument completions. +_docker_machine_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 - COMPREPLY=() + return + fi + + [ "${words[$glob_pos]}" = "=" ] && ((glob_pos--)) # --option=key=value syntax + + [[ ${words[$glob_pos]} == $glob ]] && echo "$key" +} + +# --- completion functions --------------------------------------------------- + +_docker_machine_active() { + case "${prev}" in + --timeout|-t) + return + ;; + esac + + if [[ "${cur}" == -* ]]; then + COMPREPLY=($(compgen -W "--help --timeout -t" -- "${cur}")) fi } _docker_machine_config() { if [[ "${cur}" == -* ]]; then - COMPREPLY=($(compgen -W "--swarm --help" -- "${cur}")) + COMPREPLY=($(compgen -W "--help --swarm" -- "${cur}")) else - COMPREPLY=($(compgen -W "$(docker-machine ls -q)" -- "${cur}")) + COMPREPLY=($(compgen -W "$(_docker_machine_machines)" -- "${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}")) + case "${prev}" in + --driver|-d) + COMPREPLY=($(compgen -W "$(_docker_machine_drivers)" -- "${cur}")) + return + ;; + esac + + # driver specific options are only included in help output if --driver is given, + # so we have to pass that option when calling docker-machine to harvest options. + local driver="$(_docker_machine_value_of_option '--driver|-d')" + local parsed_options="$(_docker_machine_q create ${driver:+--driver $driver} --help | grep '^ -' | sed 's/^ //; s/[^a-z0-9-].*$//')" + if [[ ${cur} == -* ]]; then + COMPREPLY=($(compgen -W "${parsed_options} -d --help" -- "${cur}")) + fi } _docker_machine_env() { case "${prev}" in --shell) - # What are the options for --shell? - COMPREPLY=() + COMPREPLY=($(compgen -W "cmd fish powershell tcsh" -- "${cur}")) + return ;; - *) - if [[ "${cur}" == -* ]]; then - COMPREPLY=($(compgen -W "--swarm --shell --unset --no-proxy --help" -- "${cur}")) - else - COMPREPLY=($(compgen -W "$(docker-machine ls -q)" -- "${cur}")) - fi esac + + if [[ "${cur}" == -* ]]; then + COMPREPLY=($(compgen -W "--help --no-proxy --shell --swarm --unset -u" -- "${cur}")) + else + COMPREPLY=($(compgen -W "$(_docker_machine_machines)" -- "${cur}")) + fi } # See docker-machine-wrapper.bash for the use command _docker_machine_use() { if [[ "${cur}" == -* ]]; then - COMPREPLY=($(compgen -W "--swarm --unset --help" -- "${cur}")) + COMPREPLY=($(compgen -W "--help --swarm --unset" -- "${cur}")) else - COMPREPLY=($(compgen -W "$(docker-machine ls -q)" -- "${cur}")) + COMPREPLY=($(compgen -W "$(_docker_machine_machines)" -- "${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 + --format|-f) + return ;; esac + + if [[ "${cur}" == -* ]]; then + COMPREPLY=($(compgen -W "--format -f --help" -- "${cur}")) + else + COMPREPLY=($(compgen -W "$(_docker_machine_machines)" -- "${cur}")) + fi } _docker_machine_ip() { if [[ "${cur}" == -* ]]; then COMPREPLY=($(compgen -W "--help" -- "${cur}")) else - COMPREPLY=($(compgen -W "$(docker-machine ls -q)" -- "${cur}")) + COMPREPLY=($(compgen -W "$(_docker_machine_machines)" -- "${cur}")) fi } @@ -86,26 +175,52 @@ _docker_machine_kill() { if [[ "${cur}" == -* ]]; then COMPREPLY=($(compgen -W "--help" -- "${cur}")) else - COMPREPLY=($(compgen -W "$(docker-machine ls -q)" -- "${cur}")) + COMPREPLY=($(compgen -W "$(_docker_machine_machines)" -- "${cur}")) fi } _docker_machine_ls() { - case "${prev}" in - --filter) - COMPREPLY=() + local key=$(_docker_machine_map_key_of_current_option '--filter') + case "$key" in + driver) + COMPREPLY=($(compgen -W "$(_docker_machine_drivers)" -- "${cur##*=}")) + return ;; - *) - COMPREPLY=($(compgen -W "--quiet --filter --format --timeout --help" -- "${cur}")) + state) + COMPREPLY=($(compgen -W "Error Paused Running Saved Starting Stopped Stopping" -- "${cur##*=}")) + return ;; esac + + case "${prev}" in + --filter) + COMPREPLY=($(compgen -W "driver label name state swarm" -S= -- "${cur}")) + _docker_machine_nospace + return + ;; + --format|-f|--timeout|-t) + return + ;; + esac + + if [[ "${cur}" == -* ]]; then + COMPREPLY=($(compgen -W "--filter --format -f --help --quiet -q --timeout -t" -- "${cur}")) + fi +} + +_docker_machine_provision() { + if [[ "${cur}" == -* ]]; then + COMPREPLY=($(compgen -W "--help" -- "${cur}")) + else + COMPREPLY=($(compgen -W "$(_docker_machine_machines --filter state=Running)" -- "${cur}")) + fi } _docker_machine_regenerate_certs() { if [[ "${cur}" == -* ]]; then - COMPREPLY=($(compgen -W "--help --force" -- "${cur}")) + COMPREPLY=($(compgen -W "--force -f --help" -- "${cur}")) else - COMPREPLY=($(compgen -W "$(docker-machine ls -q)" -- "${cur}")) + COMPREPLY=($(compgen -W "$(_docker_machine_machines --filter state=Running)" -- "${cur}")) fi } @@ -113,16 +228,15 @@ _docker_machine_restart() { if [[ "${cur}" == -* ]]; then COMPREPLY=($(compgen -W "--help" -- "${cur}")) else - COMPREPLY=($(compgen -W "$(docker-machine ls -q)" -- "${cur}")) + COMPREPLY=($(compgen -W "$(_docker_machine_machines)" -- "${cur}")) fi } _docker_machine_rm() { if [[ "${cur}" == -* ]]; then - COMPREPLY=($(compgen -W "--help --force -y" -- "${cur}")) + COMPREPLY=($(compgen -W "--force -f --help -y" -- "${cur}")) else - # For rm, it's best to be explicit - COMPREPLY=() + COMPREPLY=($(compgen -W "$(_docker_machine_machines)" -- "${cur}")) fi } @@ -130,18 +244,18 @@ _docker_machine_ssh() { if [[ "${cur}" == -* ]]; then COMPREPLY=($(compgen -W "--help" -- "${cur}")) else - COMPREPLY=($(compgen -W "$(docker-machine ls -q)" -- "${cur}")) + COMPREPLY=($(compgen -W "$(_docker_machine_machines)" -- "${cur}")) fi } _docker_machine_scp() { if [[ "${cur}" == -* ]]; then - COMPREPLY=($(compgen -W "--help --recursive" -- "${cur}")) + COMPREPLY=($(compgen -W "--delta -d --help --recursive -r" -- "${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[@]}") + COMPREPLY=($(compgen -W "$(_docker_machine_machines | sed 's/$/:/')" -- "${cur}") "${COMPREPLY[@]}") fi } @@ -149,7 +263,7 @@ _docker_machine_start() { if [[ "${cur}" == -* ]]; then COMPREPLY=($(compgen -W "--help" -- "${cur}")) else - COMPREPLY=($(compgen -W "$(docker-machine ls -q)" -- "${cur}")) + COMPREPLY=($(compgen -W "$(_docker_machine_machines --filter state=Stopped)" -- "${cur}")) fi } @@ -157,7 +271,7 @@ _docker_machine_status() { if [[ "${cur}" == -* ]]; then COMPREPLY=($(compgen -W "--help" -- "${cur}")) else - COMPREPLY=($(compgen -W "$(docker-machine ls -q)" -- "${cur}")) + COMPREPLY=($(compgen -W "$(_docker_machine_machines)" -- "${cur}")) fi } @@ -165,7 +279,7 @@ _docker_machine_stop() { if [[ "${cur}" == -* ]]; then COMPREPLY=($(compgen -W "--help" -- "${cur}")) else - COMPREPLY=($(compgen -W "$(docker-machine ls -q)" -- "${cur}")) + COMPREPLY=($(compgen -W "$(_docker_machine_machines --filter state=Running)" -- "${cur}")) fi } @@ -173,7 +287,7 @@ _docker_machine_upgrade() { if [[ "${cur}" == -* ]]; then COMPREPLY=($(compgen -W "--help" -- "${cur}")) else - COMPREPLY=($(compgen -W "$(docker-machine ls -q)" -- "${cur}")) + COMPREPLY=($(compgen -W "$(_docker_machine_machines)" -- "${cur}")) fi } @@ -181,7 +295,7 @@ _docker_machine_url() { if [[ "${cur}" == -* ]]; then COMPREPLY=($(compgen -W "--help" -- "${cur}")) else - COMPREPLY=($(compgen -W "$(docker-machine ls -q)" -- "${cur}")) + COMPREPLY=($(compgen -W "$(_docker_machine_machines)" -- "${cur}")) fi } @@ -189,7 +303,7 @@ _docker_machine_version() { if [[ "${cur}" == -* ]]; then COMPREPLY=($(compgen -W "--help" -- "${cur}")) else - COMPREPLY=($(compgen -W "$(docker-machine ls -q)" -- "${cur}")) + COMPREPLY=($(compgen -W "$(_docker_machine_machines)" -- "${cur}")) fi } @@ -215,7 +329,7 @@ _docker_machine_docker_machine() { _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 commands=(active config create env inspect ip kill ls provision 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) @@ -249,4 +363,4 @@ _docker_machine() { return 0 } -complete -F _docker_machine docker-machine +complete -F _docker_machine docker-machine docker-machine.exe diff --git a/completion/available/docker.completion.bash b/completion/available/docker.completion.bash index 96a8360c..3a4fbe3d 100644 --- a/completion/available/docker.completion.bash +++ b/completion/available/docker.completion.bash @@ -1,4 +1,13 @@ -#!/bin/bash +#!/usr/bin/env bash +# shellcheck disable=SC2016,SC2119,SC2155 +# +# Shellcheck ignore list: +# - SC2016: Expressions don't expand in single quotes, use double quotes for that. +# - SC2119: Use foo "$@" if function's $1 should mean script's $1. +# - SC2155: Declare and assign separately to avoid masking return values. +# +# You can find more details for each warning at the following page: +# https://github.com/koalaman/shellcheck/wiki/ # # bash completion file for core docker commands # @@ -20,8 +29,12 @@ # For several commands, the amount of completions can be configured by # setting environment variables. # +# DOCKER_COMPLETION_SHOW_CONFIG_IDS +# DOCKER_COMPLETION_SHOW_CONTAINER_IDS # DOCKER_COMPLETION_SHOW_NETWORK_IDS # DOCKER_COMPLETION_SHOW_NODE_IDS +# DOCKER_COMPLETION_SHOW_PLUGIN_IDS +# DOCKER_COMPLETION_SHOW_SECRET_IDS # DOCKER_COMPLETION_SHOW_SERVICE_IDS # "no" - Show names only (default) # "yes" - Show names and ids @@ -58,32 +71,99 @@ __docker_q() { docker ${host:+-H "$host"} ${config:+--config "$config"} 2>/dev/null "$@" } -__docker_complete_containers_all() { - local IFS=$'\n' - local containers=( $(__docker_q ps -aq --no-trunc) ) - if [ "$1" ]; then - containers=( $(__docker_q inspect --format "{{if $1}}{{.Id}}{{end}}" "${containers[@]}") ) +# __docker_configs returns a list of configs. Additional options to +# `docker config ls` may be specified in order to filter the list, e.g. +# `__docker_configs --filter label=stage=production`. +# By default, only names are returned. +# Set DOCKER_COMPLETION_SHOW_CONFIG_IDS=yes to also complete IDs. +# An optional first option `--id|--name` may be used to limit the +# output to the IDs or names of matching items. This setting takes +# precedence over the environment setting. +__docker_configs() { + local format + if [ "$1" = "--id" ] ; then + format='{{.ID}}' + shift + elif [ "$1" = "--name" ] ; then + format='{{.Name}}' + shift + elif [ "$DOCKER_COMPLETION_SHOW_CONFIG_IDS" = yes ] ; then + format='{{.ID}} {{.Name}}' + else + format='{{.Name}}' fi - local names=( $(__docker_q inspect --format '{{.Name}}' "${containers[@]}") ) - names=( "${names[@]#/}" ) # trim off the leading "/" from the container names - unset IFS - COMPREPLY=( $(compgen -W "${names[*]} ${containers[*]}" -- "$cur") ) + + __docker_q config ls --format "$format" "$@" +} + +# __docker_complete_configs applies completion of configs based on the current value +# of `$cur` or the value of the optional first option `--cur`, if given. +__docker_complete_configs() { + local current="$cur" + if [ "$1" = "--cur" ] ; then + current="$2" + shift 2 + fi + COMPREPLY=( $(compgen -W "$(__docker_configs "$@")" -- "$current") ) +} + +# __docker_containers returns a list of containers. Additional options to +# `docker ps` may be specified in order to filter the list, e.g. +# `__docker_containers --filter status=running` +# By default, only names are returned. +# Set DOCKER_COMPLETION_SHOW_CONTAINER_IDS=yes to also complete IDs. +# An optional first option `--id|--name` may be used to limit the +# output to the IDs or names of matching items. This setting takes +# precedence over the environment setting. +__docker_containers() { + local format + if [ "$1" = "--id" ] ; then + format='{{.ID}}' + shift + elif [ "$1" = "--name" ] ; then + format='{{.Names}}' + shift + elif [ "${DOCKER_COMPLETION_SHOW_CONTAINER_IDS}" = yes ] ; then + format='{{.ID}} {{.Names}}' + else + format='{{.Names}}' + fi + __docker_q ps --format "$format" "$@" +} + +# __docker_complete_containers applies completion of containers based on the current +# value of `$cur` or the value of the optional first option `--cur`, if given. +# Additional filters may be appended, see `__docker_containers`. +__docker_complete_containers() { + local current="$cur" + if [ "$1" = "--cur" ] ; then + current="$2" + shift 2 + fi + COMPREPLY=( $(compgen -W "$(__docker_containers "$@")" -- "$current") ) +} + +__docker_complete_containers_all() { + __docker_complete_containers "$@" --all +} + +# shellcheck disable=SC2120 +__docker_complete_containers_removable() { + __docker_complete_containers "$@" --filter status=created --filter status=exited } __docker_complete_containers_running() { - __docker_complete_containers_all '.State.Running' + __docker_complete_containers "$@" --filter status=running } +# shellcheck disable=SC2120 __docker_complete_containers_stopped() { - __docker_complete_containers_all 'not .State.Running' -} - -__docker_complete_containers_pauseable() { - __docker_complete_containers_all 'and .State.Running (not .State.Paused)' + __docker_complete_containers "$@" --filter status=exited } +# shellcheck disable=SC2120 __docker_complete_containers_unpauseable() { - __docker_complete_containers_all '.State.Paused' + __docker_complete_containers "$@" --filter status=paused } __docker_complete_container_names() { @@ -98,7 +178,7 @@ __docker_complete_container_ids() { COMPREPLY=( $(compgen -W "${containers[*]}" -- "$cur") ) } -__docker_complete_images() { +__docker_images() { local images_args="" case "$DOCKER_COMPLETION_SHOW_IMAGE_IDS" in @@ -127,8 +207,11 @@ __docker_complete_images() { ;; esac - local images=$(__docker_q images $images_args | awk "$awk_script") - COMPREPLY=( $(compgen -W "$images" -- "$cur") ) + __docker_q images $images_args | awk "$awk_script" | grep -v '$' +} + +__docker_complete_images() { + COMPREPLY=( $(compgen -W "$(__docker_images)" -- "$cur") ) __ltrim_colon_completions "$cur" } @@ -143,52 +226,149 @@ __docker_complete_image_repos_and_tags() { __ltrim_colon_completions "$cur" } -__docker_complete_containers_and_images() { - __docker_complete_containers_all - local containers=( "${COMPREPLY[@]}" ) - __docker_complete_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 returns a list of all networks. Additional options to +# `docker network ls` may be specified in order to filter the list, e.g. +# `__docker_networks --filter type=custom` +# By default, only names are returned. +# Set DOCKER_COMPLETION_SHOW_NETWORK_IDS=yes to also complete IDs. +# An optional first option `--id|--name` may be used to limit the +# output to the IDs or names of matching items. This setting takes +# precedence over the environment setting. __docker_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 ${filter:+-f "$filter"} | awk "NR>1 {print $fields}" - #__docker_q network ls --no-trunc | awk "NR>1 {print $fields}" + local format + if [ "$1" = "--id" ] ; then + format='{{.ID}}' + shift + elif [ "$1" = "--name" ] ; then + format='{{.Name}}' + shift + elif [ "${DOCKER_COMPLETION_SHOW_NETWORK_IDS}" = yes ] ; then + format='{{.ID}} {{.Name}}' + else + format='{{.Name}}' + fi + __docker_q network ls --format "$format" "$@" } +# __docker_complete_networks applies completion of networks based on the current +# value of `$cur` or the value of the optional first option `--cur`, if given. +# Additional filters may be appended, see `__docker_networks`. __docker_complete_networks() { - COMPREPLY=( $(compgen -W "$(__docker_networks $@)" -- "$cur") ) -} - -__docker_complete_network_ids() { - COMPREPLY=( $(compgen -W "$(__docker_q network ls -q --no-trunc)" -- "$cur") ) -} - -__docker_complete_network_names() { - COMPREPLY=( $(compgen -W "$(__docker_q network ls | awk 'NR>1 {print $2}')" -- "$cur") ) + local current="$cur" + if [ "$1" = "--cur" ] ; then + current="$2" + shift 2 + fi + COMPREPLY=( $(compgen -W "$(__docker_networks "$@")" -- "$current") ) } +# shellcheck disable=SC2128,SC2178 __docker_complete_containers_in_network() { local containers=$(__docker_q network inspect -f '{{range $i, $c := .Containers}}{{$i}} {{$c.Name}} {{end}}' "$1") COMPREPLY=( $(compgen -W "$containers" -- "$cur") ) } +# __docker_volumes returns a list of all volumes. Additional options to +# `docker volume ls` may be specified in order to filter the list, e.g. +# `__docker_volumes --filter dangling=true` +# Because volumes do not have IDs, this function does not distinguish between +# IDs and names. +__docker_volumes() { + __docker_q volume ls -q "$@" +} + +# __docker_complete_volumes applies completion of volumes based on the current +# value of `$cur` or the value of the optional first option `--cur`, if given. +# Additional filters may be appended, see `__docker_volumes`. __docker_complete_volumes() { - COMPREPLY=( $(compgen -W "$(__docker_q volume ls -q)" -- "$cur") ) + local current="$cur" + if [ "$1" = "--cur" ] ; then + current="$2" + shift 2 + fi + COMPREPLY=( $(compgen -W "$(__docker_volumes "$@")" -- "$current") ) } -__docker_plugins() { - __docker_q info | sed -n "/^Plugins/,/^[^ ]/s/ $1: //p" +# __docker_plugins_bundled returns a list of all plugins of a given type. +# The type has to be specified with the mandatory option `--type`. +# Valid types are: Network, Volume, Authorization. +# Completions may be added or removed with `--add` and `--remove` +# This function only deals with plugins that come bundled with Docker. +# For plugins managed by `docker plugin`, see `__docker_plugins_installed`. +__docker_plugins_bundled() { + local type add=() remove=() + while true ; do + case "$1" in + --type) + type="$2" + shift 2 + ;; + --add) + add+=("$2") + shift 2 + ;; + --remove) + remove+=("$2") + shift 2 + ;; + *) + break + ;; + esac + done + + local plugins=($(__docker_q info --format "{{range \$i, \$p := .Plugins.$type}}{{.}} {{end}}")) + for del in "${remove[@]}" ; do + plugins=(${plugins[@]/$del/}) + done + # shellcheck disable=SC2145 + echo "${plugins[@]} ${add[@]}" } -__docker_complete_plugins() { - COMPREPLY=( $(compgen -W "$(__docker_plugins $1)" -- "$cur") ) +# __docker_complete_plugins_bundled applies completion of plugins based on the current +# value of `$cur` or the value of the optional first option `--cur`, if given. +# The plugin type has to be specified with the next option `--type`. +# This function only deals with plugins that come bundled with Docker. +# For completion of plugins managed by `docker plugin`, see +# `__docker_complete_plugins_installed`. +__docker_complete_plugins_bundled() { + local current="$cur" + if [ "$1" = "--cur" ] ; then + current="$2" + shift 2 + fi + COMPREPLY=( $(compgen -W "$(__docker_plugins_bundled "$@")" -- "$current") ) +} + +# __docker_plugins_installed returns a list of all plugins that were installed with +# the Docker plugin API. +# By default, only names are returned. +# Set DOCKER_COMPLETION_SHOW_PLUGIN_IDS=yes to also complete IDs. +# Additional options to `docker plugin ls` may be specified in order to filter the list, +# e.g. `__docker_plugins_installed --filter enabled=true` +# For built-in pugins, see `__docker_plugins_bundled`. +__docker_plugins_installed() { + local format + if [ "$DOCKER_COMPLETION_SHOW_PLUGIN_IDS" = yes ] ; then + format='{{.ID}} {{.Name}}' + else + format='{{.Name}}' + fi + __docker_q plugin ls --format "$format" "$@" +} + +# __docker_complete_plugins_installed applies completion of plugins that were installed +# with the Docker plugin API, based on the current value of `$cur` or the value of +# the optional first option `--cur`, if given. +# Additional filters may be appended, see `__docker_plugins_installed`. +# For completion of built-in pugins, see `__docker_complete_plugins_bundled`. +__docker_complete_plugins_installed() { + local current="$cur" + if [ "$1" = "--cur" ] ; then + current="$2" + shift 2 + fi + COMPREPLY=( $(compgen -W "$(__docker_plugins_installed "$@")" -- "$current") ) } __docker_runtimes() { @@ -199,33 +379,105 @@ __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 +# __docker_secrets returns a list of secrets. Additional options to +# `docker secret ls` may be specified in order to filter the list, e.g. +# `__docker_secrets --filter label=stage=production` +# By default, only names are returned. +# Set DOCKER_COMPLETION_SHOW_SECRET_IDS=yes to also complete IDs. +# An optional first option `--id|--name` may be used to limit the +# output to the IDs or names of matching items. This setting takes # precedence over the environment setting. -__docker_nodes() { - local fields='$2' # default: node name only - [ "${DOCKER_COMPLETION_SHOW_NODE_IDS}" = yes ] && fields='$1,$2' # ID and name - +__docker_secrets() { + local format if [ "$1" = "--id" ] ; then - fields='$1' # IDs only + format='{{.ID}}' shift elif [ "$1" = "--name" ] ; then - fields='$2' # names only + format='{{.Name}}' shift + elif [ "$DOCKER_COMPLETION_SHOW_SECRET_IDS" = yes ] ; then + format='{{.ID}} {{.Name}}' + else + format='{{.Name}}' fi - __docker_q node ls "$@" | tr -d '*' | awk "NR>1 {print $fields}" + + __docker_q secret ls --format "$format" "$@" } -# Applies completion of nodes based on the current value of `$cur` or -# the value of the optional first argument `--cur`, if given. +# __docker_complete_secrets applies completion of secrets based on the current value +# of `$cur` or the value of the optional first option `--cur`, if given. +__docker_complete_secrets() { + local current="$cur" + if [ "$1" = "--cur" ] ; then + current="$2" + shift 2 + fi + COMPREPLY=( $(compgen -W "$(__docker_secrets "$@")" -- "$current") ) +} + +# __docker_stacks returns a list of all stacks. +__docker_stacks() { + __docker_q stack ls | awk 'NR>1 {print $1}' +} + +# __docker_complete_stacks applies completion of stacks based on the current value +# of `$cur` or the value of the optional first option `--cur`, if given. +__docker_complete_stacks() { + local current="$cur" + if [ "$1" = "--cur" ] ; then + current="$2" + shift 2 + fi + COMPREPLY=( $(compgen -W "$(__docker_stacks "$@")" -- "$current") ) +} + +# __docker_nodes returns a list of all nodes. Additional options to +# `docker node ls` may be specified in order to filter the list, e.g. +# `__docker_nodes --filter role=manager` +# By default, only node names are returned. +# Set DOCKER_COMPLETION_SHOW_NODE_IDS=yes to also complete node IDs. +# An optional first option `--id|--name` may be used to limit the +# output to the IDs or names of matching items. This setting takes +# precedence over the environment setting. +# Completions may be added with `--add`, e.g. `--add self`. +__docker_nodes() { + local format + if [ "$DOCKER_COMPLETION_SHOW_NODE_IDS" = yes ] ; then + format='{{.ID}} {{.Hostname}}' + else + format='{{.Hostname}}' + fi + + local add=() + + while true ; do + case "$1" in + --id) + format='{{.ID}}' + shift + ;; + --name) + format='{{.Hostname}}' + shift + ;; + --add) + add+=("$2") + shift 2 + ;; + *) + break + ;; + esac + done + + echo "$(__docker_q node ls --format "$format" "$@")" "${add[@]}" +} + +# __docker_complete_nodes applies completion of nodes based on the current +# value of `$cur` or the value of the optional first option `--cur`, if given. # Additional filters may be appended, see `__docker_nodes`. __docker_complete_nodes() { - local current=$cur + local current="$cur" if [ "$1" = "--cur" ] ; then current="$2" shift 2 @@ -233,18 +485,13 @@ __docker_complete_nodes() { 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 returns a list of all services. Additional options to +# `docker service ls` may be specified in order to filter the 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 +# By default, only node names are returned. +# Set DOCKER_COMPLETION_SHOW_SERVICE_IDS=yes to also complete IDs. +# An optional first option `--id|--name` may be used to limit the +# output to the IDs or names of matching items. This setting takes # precedence over the environment setting. __docker_services() { local fields='$2' # default: service name only @@ -260,11 +507,11 @@ __docker_services() { __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. +# __docker_complete_services applies completion of services based on the current +# value of `$cur` or the value of the optional first option `--cur`, if given. # Additional filters may be appended, see `__docker_services`. __docker_complete_services() { - local current=$cur + local current="$cur" if [ "$1" = "--cur" ] ; then current="$2" shift 2 @@ -272,22 +519,54 @@ __docker_complete_services() { 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 +# __docker_tasks returns a list of all task IDs. +__docker_tasks() { + __docker_q service ps --format '{{.ID}}' "" +} + +# __docker_complete_services_and_tasks applies completion of services and task IDs. +# shellcheck disable=SC2120 +__docker_complete_services_and_tasks() { + COMPREPLY=( $(compgen -W "$(__docker_services "$@") $(__docker_tasks)" -- "$cur") ) +} + +# __docker_append_to_completions appends the word passed as an argument to every +# word in `$COMPREPLY`. +# Normally you do this with `compgen -S` while generating the completions. +# This function allows you to append a suffix later. It allows you to 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" +# __docker_daemon_is_experimental tests whether the currently configured Docker +# daemon runs in experimental mode. If so, the function exits with 0 (true). +# Otherwise, or if the result cannot be determined, the exit value is 1 (false). +__docker_daemon_is_experimental() { + [ "$(__docker_q version -f '{{.Server.Experimental}}')" = "true" ] +} + +# __docker_daemon_os_is tests whether the currently configured Docker daemon runs +# on the operating system passed in as the first argument. +# It does so by querying the daemon for its OS. The result is cached for the duration +# of one invocation of bash completion so that this function can be used to test for +# several different operating systems without additional costs. +# Known operating systems: linux, windows. +__docker_daemon_os_is() { + local expected_os="$1" + local actual_os=${daemon_os=$(__docker_q version -f '{{.Server.Os}}')} + [ "$actual_os" = "$expected_os" ] +} + +# __docker_pos_first_nonflag 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" # Use this function to restrict completions to exact positions after the argument list. __docker_pos_first_nonflag() { local argument_flags=$1 local counter=$((${subcommand_pos:-${command_pos}} + 1)) - while [ $counter -le $cword ]; do + while [ "$counter" -le "$cword" ]; do if [ -n "$argument_flags" ] && eval "case '${words[$counter]}' in $argument_flags) true ;; *) false ;; esac"; then (( counter++ )) # eat "=" in case of --option=arg syntax @@ -314,8 +593,8 @@ __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. +# __docker_map_key_of_current_option returns `key` if we are currently completing the +# value of a map option (`key=value`) which matches the extglob given as an argument. # This function is needed for key-specific completions. __docker_map_key_of_current_option() { local glob="$1" @@ -339,18 +618,18 @@ __docker_map_key_of_current_option() { [[ ${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' +# __docker_value_of_option 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` # Only positions between the command and the current word are considered. __docker_value_of_option() { local option_extglob=$(__docker_to_extglob "$1") local counter=$((command_pos + 1)) - while [ $counter -lt $cword ]; do + while [ "$counter" -lt "$cword" ]; do case ${words[$counter]} in $option_extglob ) - echo ${words[$counter + 1]} + echo "${words[$counter + 1]}" break ;; esac @@ -358,8 +637,8 @@ __docker_value_of_option() { done } -# Transforms a multiline list of strings into a single line string -# with the words separated by "|". +# __docker_to_alternatives transforms a multiline list of strings into a single line +# string with the words separated by `|`. # This is used to prepare arguments to __docker_pos_first_nonflag(). __docker_to_alternatives() { local parts=( $1 ) @@ -367,14 +646,14 @@ __docker_to_alternatives() { echo "${parts[*]}" } -# Transforms a multiline list of options into an extglob pattern +# __docker_to_extglob transforms a multiline list of options into an extglob pattern # suitable for use in case statements. __docker_to_extglob() { local extglob=$( __docker_to_alternatives "$1" ) echo "@($extglob)" } -# Subcommand processing. +# __docker_subcommands processes subcommands # Locates the first occurrence of any of the subcommands contained in the # first argument. In case of a match, calls the corresponding completion # function and returns 0. @@ -387,14 +666,14 @@ __docker_to_extglob() { __docker_subcommands() { local subcommands="$1" - local counter=$(($command_pos + 1)) - while [ $counter -lt $cword ]; do + local counter=$((command_pos + 1)) + while [ "$counter" -lt "$cword" ]; do case "${words[$counter]}" in $(__docker_to_extglob "$subcommands") ) subcommand_pos=$counter local subcommand=${words[$counter]} - local completions_func=_docker_${command}_${subcommand} - declare -F $completions_func >/dev/null && $completions_func + local completions_func=_docker_${command}_${subcommand//-/_} + declare -F "$completions_func" >/dev/null && "$completions_func" return 0 ;; esac @@ -403,7 +682,7 @@ __docker_subcommands() { return 1 } -# suppress trailing whitespace +# __docker_nospace suppresses trailing whitespace __docker_nospace() { # compopt is not available in ancient bash versions type compopt &>/dev/null && compopt -o nospace @@ -414,38 +693,61 @@ __docker_complete_resolved_hostname() { COMPREPLY=( $(host 2>/dev/null "${cur%:}" | awk '/has address/ {print $4}') ) } -__docker_complete_capabilities() { - # The list of capabilities is defined in types.go, ALL was added manually. +# __docker_local_interfaces returns a list of the names and addresses of all +# local network interfaces. +# If `--ip-only` is passed as a first argument, only addresses are returned. +__docker_local_interfaces() { + command -v ip >/dev/null 2>&1 || return + + local format + if [ "$1" = "--ip-only" ] ; then + format='\1' + shift + else + format='\1 \2' + fi + + ip addr show scope global 2>/dev/null | sed -n "s| \+inet \([0-9.]\+\).* \([^ ]\+\)|$format|p" +} + +# __docker_complete_local_interfaces applies completion of the names and addresses of all +# local network interfaces based on the current value of `$cur`. +# An additional value can be added to the possible completions with an `--add` argument. +__docker_complete_local_interfaces() { + local additional_interface + if [ "$1" = "--add" ] ; then + additional_interface="$2" + shift 2 + fi + + COMPREPLY=( $( compgen -W "$(__docker_local_interfaces "$@") $additional_interface" -- "$cur" ) ) +} + +# __docker_complete_local_ips applies completion of the addresses of all local network +# interfaces based on the current value of `$cur`. +__docker_complete_local_ips() { + __docker_complete_local_interfaces --ip-only +} + +# __docker_complete_capabilities_addable completes Linux capabilities which are +# not granted by default and may be added. +# see https://docs.docker.com/engine/reference/run/#/runtime-privilege-and-linux-capabilities +__docker_complete_capabilities_addable() { COMPREPLY=( $( compgen -W " ALL AUDIT_CONTROL - AUDIT_WRITE - AUDIT_READ BLOCK_SUSPEND - CHOWN - DAC_OVERRIDE DAC_READ_SEARCH - FOWNER - FSETID IPC_LOCK IPC_OWNER - KILL LEASE LINUX_IMMUTABLE MAC_ADMIN MAC_OVERRIDE - MKNOD NET_ADMIN - NET_BIND_SERVICE NET_BROADCAST - NET_RAW - SETFCAP - SETGID - SETPCAP - SETUID SYS_ADMIN SYS_BOOT - SYS_CHROOT SYSLOG SYS_MODULE SYS_NICE @@ -459,7 +761,30 @@ __docker_complete_capabilities() { " -- "$cur" ) ) } -__docker_complete_detach-keys() { +# __docker_complete_capabilities_droppable completes Linux capability options which are +# allowed by default and can be dropped. +# see https://docs.docker.com/engine/reference/run/#/runtime-privilege-and-linux-capabilities +__docker_complete_capabilities_droppable() { + COMPREPLY=( $( compgen -W " + ALL + AUDIT_WRITE + CHOWN + DAC_OVERRIDE + FOWNER + FSETID + KILL + MKNOD + NET_BIND_SERVICE + NET_RAW + SETFCAP + SETGID + SETPCAP + SETUID + SYS_CHROOT + " -- "$cur" ) ) +} + +__docker_complete_detach_keys() { case "$prev" in --detach-keys) case "$cur" in @@ -491,6 +816,7 @@ __docker_complete_log_drivers() { gelf journald json-file + logentries none splunk syslog @@ -498,17 +824,27 @@ __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 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-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" + # see repository docker/docker.github.io/engine/admin/logging/ - local all_options="$fluentd_options $gcplogs_options $gelf_options $journald_options $json_file_options $syslog_options $splunk_options" + # really global options, defined in https://github.com/moby/moby/blob/master/daemon/logger/factory.go + local common_options1="max-buffer-size mode" + # common options defined in https://github.com/moby/moby/blob/master/daemon/logger/loginfo.go + # but not implemented in all log drivers + local common_options2="env env-regex labels" + + # awslogs does not implement the $common_options2. + local awslogs_options="$common_options1 awslogs-create-group awslogs-credentials-endpoint awslogs-datetime-format awslogs-group awslogs-multiline-pattern awslogs-region awslogs-stream tag" + + local fluentd_options="$common_options1 $common_options2 fluentd-address fluentd-async-connect fluentd-buffer-limit fluentd-retry-wait fluentd-max-retries fluentd-sub-second-precision tag" + local gcplogs_options="$common_options1 $common_options2 gcp-log-cmd gcp-meta-id gcp-meta-name gcp-meta-zone gcp-project" + local gelf_options="$common_options1 $common_options2 gelf-address gelf-compression-level gelf-compression-type gelf-tcp-max-reconnect gelf-tcp-reconnect-delay tag" + local journald_options="$common_options1 $common_options2 tag" + local json_file_options="$common_options1 $common_options2 max-file max-size" + local logentries_options="$common_options1 $common_options2 line-only logentries-token tag" + local splunk_options="$common_options1 $common_options2 splunk-caname splunk-capath splunk-format splunk-gzip splunk-gzip-level splunk-index splunk-insecureskipverify splunk-source splunk-sourcetype splunk-token splunk-url splunk-verify-connection tag" + local syslog_options="$common_options1 $common_options2 syslog-address syslog-facility syslog-format syslog-tls-ca-cert syslog-tls-cert syslog-tls-key syslog-tls-skip-verify tag" + + local all_options="$fluentd_options $gcplogs_options $gelf_options $journald_options $logentries_options $json_file_options $syslog_options $splunk_options" case $(__docker_value_of_option --log-driver) in '') @@ -532,6 +868,9 @@ __docker_complete_log_options() { json-file) COMPREPLY=( $( compgen -W "$json_file_options" -S = -- "$cur" ) ) ;; + logentries) + COMPREPLY=( $( compgen -W "$logentries_options" -S = -- "$cur" ) ) + ;; syslog) COMPREPLY=( $( compgen -W "$syslog_options" -S = -- "$cur" ) ) ;; @@ -549,12 +888,25 @@ __docker_complete_log_options() { __docker_complete_log_driver_options() { local key=$(__docker_map_key_of_current_option '--log-opt') case "$key" in + awslogs-create-group) + COMPREPLY=( $( compgen -W "false true" -- "${cur##*=}" ) ) + return + ;; + awslogs-credentials-endpoint) + COMPREPLY=( $( compgen -W "/" -- "${cur##*=}" ) ) + __docker_nospace + return + ;; fluentd-async-connect) COMPREPLY=( $( compgen -W "false true" -- "${cur##*=}" ) ) return ;; + fluentd-sub-second-precision) + COMPREPLY=( $( compgen -W "false true" -- "${cur##*=}" ) ) + return + ;; gelf-address) - COMPREPLY=( $( compgen -W "udp" -S "://" -- "${cur##*=}" ) ) + COMPREPLY=( $( compgen -W "tcp udp" -S "://" -- "${cur##*=}" ) ) __docker_nospace return ;; @@ -566,6 +918,14 @@ __docker_complete_log_driver_options() { COMPREPLY=( $( compgen -W "gzip none zlib" -- "${cur##*=}" ) ) return ;; + line-only) + COMPREPLY=( $( compgen -W "false true" -- "${cur##*=}" ) ) + return + ;; + mode) + COMPREPLY=( $( compgen -W "blocking non-blocking" -- "${cur##*=}" ) ) + return + ;; syslog-address) COMPREPLY=( $( compgen -W "tcp:// tcp+tls:// udp:// unix://" -- "${cur##*=}" ) ) __docker_nospace @@ -615,10 +975,14 @@ __docker_complete_log_driver_options() { __ltrim_colon_completions "${cur}" return ;; - splunk-insecureskipverify) + splunk-gzip|splunk-insecureskipverify|splunk-verify-connection) COMPREPLY=( $( compgen -W "false true" -- "${cur##*=}" ) ) return ;; + splunk-format) + COMPREPLY=( $( compgen -W "inline json raw" -- "${cur##*=}" ) ) + return + ;; esac return 1 } @@ -643,8 +1007,8 @@ __docker_complete_restart() { return 1 } -# a selection of the available signals that is most likely of interest in the -# context of docker containers. +# __docker_complete_signals returns a subset of the available signals that is most likely +# relevant in the context of docker containers __docker_complete_signals() { local signals=( SIGCONT @@ -657,7 +1021,7 @@ __docker_complete_signals() { SIGUSR1 SIGUSR2 ) - COMPREPLY=( $( compgen -W "${signals[*]} ${signals[*]#SIG}" -- "$( echo $cur | tr '[:lower:]' '[:upper:]')" ) ) + COMPREPLY=( $( compgen -W "${signals[*]} ${signals[*]#SIG}" -- "$( echo "$cur" | tr '[:lower:]' '[:upper:]')" ) ) } __docker_complete_user_group() { @@ -669,8 +1033,8 @@ __docker_complete_user_group() { fi } -# global options that may appear after the docker command _docker_docker() { + # global options that may appear after the docker command local boolean_options=" $global_boolean_options --help @@ -697,7 +1061,8 @@ _docker_docker() { ;; *) local counter=$( __docker_pos_first_nonflag "$(__docker_to_extglob "$global_options_with_args")" ) - if [ $cword -eq $counter ]; then + if [ "$cword" -eq "$counter" ]; then + __docker_daemon_is_experimental && commands+=(${experimental_commands[*]}) COMPREPLY=( $( compgen -W "${commands[*]} help" -- "$cur" ) ) fi ;; @@ -705,89 +1070,274 @@ _docker_docker() { } _docker_attach() { - __docker_complete_detach-keys && return + _docker_container_attach +} - case "$cur" in +_docker_build() { + _docker_image_build +} + + +_docker_checkpoint() { + local subcommands=" + create + ls + rm + " + local aliases=" + list + remove + " + __docker_subcommands "$subcommands $aliases" && return + + case "$cur" in -*) - COMPREPLY=( $( compgen -W "--detach-keys --help --no-stdin --sig-proxy=false" -- "$cur" ) ) + COMPREPLY=( $( compgen -W "--help" -- "$cur" ) ) ;; *) - local counter=$(__docker_pos_first_nonflag '--detach-keys') - if [ $cword -eq $counter ]; then - __docker_complete_containers_running - fi + COMPREPLY=( $( compgen -W "$subcommands" -- "$cur" ) ) ;; esac } -_docker_build() { - local options_with_args=" - --build-arg - --cgroup-parent - --cpuset-cpus - --cpuset-mems - --cpu-shares -c - --cpu-period - --cpu-quota - --file -f - --isolation - --label - --memory -m - --memory-swap - --shm-size - --tag -t - --ulimit - " - - local boolean_options=" - --disable-content-trust=false - --force-rm - --help - --no-cache - --pull - --quiet -q - --rm - " - - local all_options="$options_with_args $boolean_options" - +_docker_checkpoint_create() { case "$prev" in - --build-arg) - COMPREPLY=( $( compgen -e -- "$cur" ) ) - __docker_nospace - return - ;; - --file|-f) - _filedir - return - ;; - --isolation) - __docker_complete_isolation - return - ;; - --tag|-t) - __docker_complete_image_repos_and_tags - return - ;; - $(__docker_to_extglob "$options_with_args") ) + --checkpoint-dir) + _filedir -d return ;; esac case "$cur" in -*) - COMPREPLY=( $( compgen -W "$all_options" -- "$cur" ) ) + COMPREPLY=( $( compgen -W "--checkpoint-dir --help --leave-running" -- "$cur" ) ) ;; *) - local counter=$( __docker_pos_first_nonflag $( __docker_to_alternatives "$options_with_args" ) ) - if [ $cword -eq $counter ]; then - _filedir -d + local counter=$(__docker_pos_first_nonflag '--checkpoint-dir') + if [ "$cword" -eq "$counter" ]; then + __docker_complete_containers_running fi ;; esac } -_docker_commit() { +_docker_checkpoint_ls() { + case "$prev" in + --checkpoint-dir) + _filedir -d + return + ;; + esac + + case "$cur" in + -*) + COMPREPLY=( $( compgen -W "--checkpoint-dir --help" -- "$cur" ) ) + ;; + *) + local counter=$(__docker_pos_first_nonflag '--checkpoint-dir') + if [ "$cword" -eq "$counter" ]; then + __docker_complete_containers_all + fi + ;; + esac +} + +_docker_checkpoint_rm() { + case "$prev" in + --checkpoint-dir) + _filedir -d + return + ;; + esac + + case "$cur" in + -*) + COMPREPLY=( $( compgen -W "--checkpoint-dir --help" -- "$cur" ) ) + ;; + *) + local counter=$(__docker_pos_first_nonflag '--checkpoint-dir') + if [ "$cword" -eq "$counter" ]; then + __docker_complete_containers_all + elif [ "$cword" -eq "$((counter + 1))" ]; then + COMPREPLY=( $( compgen -W "$(__docker_q checkpoint ls "$prev" | sed 1d)" -- "$cur" ) ) + fi + ;; + esac +} + + +_docker_config() { + local subcommands=" + create + inspect + ls + rm + " + local aliases=" + list + remove + " + __docker_subcommands "$subcommands $aliases" && return + + case "$cur" in + -*) + COMPREPLY=( $( compgen -W "--help" -- "$cur" ) ) + ;; + *) + COMPREPLY=( $( compgen -W "$subcommands" -- "$cur" ) ) + ;; + esac +} + +_docker_config_create() { + case "$prev" in + --label|-l) + return + ;; + esac + + case "$cur" in + -*) + COMPREPLY=( $( compgen -W "--help --label -l" -- "$cur" ) ) + ;; + *) + local counter=$(__docker_pos_first_nonflag '--label|-l') + if [ "$cword" -eq "$((counter + 1))" ]; then + _filedir + fi + ;; + esac +} + +_docker_config_inspect() { + case "$prev" in + --format|-f) + return + ;; + esac + + case "$cur" in + -*) + COMPREPLY=( $( compgen -W "--format -f --help --pretty" -- "$cur" ) ) + ;; + *) + __docker_complete_configs + ;; + esac +} + +_docker_config_list() { + _docker_config_ls +} + +_docker_config_ls() { + local key=$(__docker_map_key_of_current_option '--filter|-f') + case "$key" in + id) + __docker_complete_configs --cur "${cur##*=}" --id + return + ;; + name) + __docker_complete_configs --cur "${cur##*=}" --name + return + ;; + esac + + case "$prev" in + --filter|-f) + COMPREPLY=( $( compgen -S = -W "id label name" -- "$cur" ) ) + __docker_nospace + return + ;; + --format) + return + ;; + esac + + case "$cur" in + -*) + COMPREPLY=( $( compgen -W "--format --filter -f --help --quiet -q" -- "$cur" ) ) + ;; + esac +} + +_docker_config_remove() { + _docker_config_rm +} + +_docker_config_rm() { + case "$cur" in + -*) + COMPREPLY=( $( compgen -W "--help" -- "$cur" ) ) + ;; + *) + __docker_complete_configs + ;; + esac +} + + +_docker_container() { + local subcommands=" + attach + commit + cp + create + diff + exec + export + inspect + kill + logs + ls + pause + port + prune + rename + restart + rm + run + start + stats + stop + top + unpause + update + wait + " + local aliases=" + list + ps + " + __docker_subcommands "$subcommands $aliases" && return + + case "$cur" in + -*) + COMPREPLY=( $( compgen -W "--help" -- "$cur" ) ) + ;; + *) + COMPREPLY=( $( compgen -W "$subcommands" -- "$cur" ) ) + ;; + esac +} + +_docker_container_attach() { + __docker_complete_detach_keys && return + + case "$cur" in + -*) + COMPREPLY=( $( compgen -W "--detach-keys --help --no-stdin --sig-proxy=false" -- "$cur" ) ) + ;; + *) + local counter=$(__docker_pos_first_nonflag '--detach-keys') + if [ "$cword" -eq "$counter" ]; then + __docker_complete_containers_running + fi + ;; + esac +} + +_docker_container_commit() { case "$prev" in --author|-a|--change|-c|--message|-m) return @@ -801,13 +1351,13 @@ _docker_commit() { *) local counter=$(__docker_pos_first_nonflag '--author|-a|--change|-c|--message|-m') - if [ $cword -eq $counter ]; then + if [ "$cword" -eq "$counter" ]; then __docker_complete_containers_all return fi (( counter++ )) - if [ $cword -eq $counter ]; then + if [ "$cword" -eq "$counter" ]; then __docker_complete_image_repos_and_tags return fi @@ -815,14 +1365,14 @@ _docker_commit() { esac } -_docker_cp() { +_docker_container_cp() { case "$cur" in -*) COMPREPLY=( $( compgen -W "--follow-link -L --help" -- "$cur" ) ) ;; *) local counter=$(__docker_pos_first_nonflag) - if [ $cword -eq $counter ]; then + if [ "$cword" -eq "$counter" ]; then case "$cur" in *:) return @@ -837,6 +1387,7 @@ _docker_cp() { local containers=( ${COMPREPLY[@]} ) COMPREPLY=( $( compgen -W "${files[*]} ${containers[*]}" -- "$cur" ) ) + # shellcheck disable=SC2128 if [[ "$COMPREPLY" == *: ]]; then __docker_nospace fi @@ -846,7 +1397,7 @@ _docker_cp() { fi (( counter++ )) - if [ $cword -eq $counter ]; then + if [ "$cword" -eq "$counter" ]; then if [ -e "$prev" ]; then __docker_complete_containers_all COMPREPLY=( $( compgen -W "${COMPREPLY[*]}" -S ':' ) ) @@ -860,306 +1411,46 @@ _docker_cp() { esac } -_docker_create() { - _docker_run +_docker_container_create() { + _docker_container_run_and_create } -_docker_daemon() { - local boolean_options=" - $global_boolean_options - --disable-legacy-registry - --help - --icc=false - --ip-forward=false - --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 - --authorization-plugin - --bip - --bridge -b - --cgroup-parent - --cluster-advertise - --cluster-store - --cluster-store-opt - --config-file - --containerd - --default-gateway - --default-gateway-v6 - --default-ulimit - --dns - --dns-search - --dns-opt - --exec-opt - --exec-root - --fixed-cidr - --fixed-cidr-v6 - --graph -g - --group -G - --insecure-registry - --ip - --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 - --authorization-plugin) - __docker_complete_plugins Authorization - return - ;; - --cluster-store) - COMPREPLY=( $( compgen -W "consul etcd zk" -S "://" -- "$cur" ) ) - __docker_nospace - return - ;; - --cluster-store-opt) - COMPREPLY=( $( compgen -W "discovery.heartbeat discovery.ttl kv.cacertfile kv.certfile kv.keyfile kv.path" -S = -- "$cur" ) ) - __docker_nospace - return - ;; - --exec-root|--graph|-g) - _filedir -d - return - ;; - --log-driver) - __docker_complete_log_drivers - return - ;; - --config-file|--containerd|--pidfile|-p|--tlscacert|--tlscert|--tlskey) - _filedir - return - ;; - --storage-driver|-s) - 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 - dm.blocksize - dm.fs - dm.loopdatasize - dm.loopmetadatasize - dm.min_free_space - dm.mkfsarg - dm.mountopt - dm.override_udev_sync_check - dm.thinpooldev - dm.use_deferred_deletion - dm.use_deferred_removal - " - local zfs_options="zfs.fsname" - - case $(__docker_value_of_option '--storage-driver|-s') in - '') - 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" ) ) - ;; - zfs) - COMPREPLY=( $( compgen -W "$zfs_options" -S = -- "$cur" ) ) - ;; - *) - return - ;; - esac - __docker_nospace - return - ;; - --log-level|-l) - __docker_complete_log_levels - return - ;; - --log-opt) - __docker_complete_log_options - return - ;; - --userns-remap) - __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" ) ) - ;; - esac -} - -_docker_diff() { +_docker_container_diff() { case "$cur" in -*) COMPREPLY=( $( compgen -W "--help" -- "$cur" ) ) ;; *) local counter=$(__docker_pos_first_nonflag) - if [ $cword -eq $counter ]; then + if [ "$cword" -eq "$counter" ]; then __docker_complete_containers_all fi ;; esac } -_docker_events() { - local key=$(__docker_map_key_of_current_option '-f|--filter') - case "$key" in - container) - cur="${cur##*=}" - __docker_complete_containers_all - return - ;; - 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 - update - " -- "${cur##*=}" ) ) - return - ;; - 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 +_docker_container_exec() { + __docker_complete_detach_keys && return case "$prev" in - --filter|-f) - COMPREPLY=( $( compgen -S = -W "container daemon event image label network type volume" -- "$cur" ) ) + --env|-e) + # we do not append a "=" here because "-e VARNAME" is legal syntax, too + COMPREPLY=( $( compgen -e -- "$cur" ) ) __docker_nospace return ;; - --since|--until) - return - ;; - esac - - case "$cur" in - -*) - COMPREPLY=( $( compgen -W "--filter -f --help --since --until" -- "$cur" ) ) - ;; - esac -} - -_docker_exec() { - __docker_complete_detach-keys && return - - case "$prev" in --user|-u) __docker_complete_user_group return ;; + --workdir|-w) + return + ;; esac case "$cur" in -*) - COMPREPLY=( $( compgen -W "--detach -d --detach-keys --help --interactive -i --privileged -t --tty -u --user" -- "$cur" ) ) + COMPREPLY=( $( compgen -W "--detach -d --detach-keys --env -e --help --interactive -i --privileged -t --tty -u --user --workdir -w" -- "$cur" ) ) ;; *) __docker_complete_containers_running @@ -1167,153 +1458,32 @@ _docker_exec() { esac } -_docker_export() { +_docker_container_export() { + case "$prev" in + --output|-o) + _filedir + return + ;; + esac + case "$cur" in -*) - COMPREPLY=( $( compgen -W "--help" -- "$cur" ) ) + COMPREPLY=( $( compgen -W "--help --output -o" -- "$cur" ) ) ;; *) local counter=$(__docker_pos_first_nonflag) - if [ $cword -eq $counter ]; then + if [ "$cword" -eq "$counter" ]; then __docker_complete_containers_all fi ;; esac } -_docker_help() { - local counter=$(__docker_pos_first_nonflag) - if [ $cword -eq $counter ]; then - COMPREPLY=( $( compgen -W "${commands[*]}" -- "$cur" ) ) - fi +_docker_container_inspect() { + _docker_inspect --type container } -_docker_history() { - case "$cur" in - -*) - COMPREPLY=( $( compgen -W "--help --human=false -H=false --no-trunc --quiet -q" -- "$cur" ) ) - ;; - *) - local counter=$(__docker_pos_first_nonflag) - if [ $cword -eq $counter ]; then - __docker_complete_images - fi - ;; - esac -} - -_docker_images() { - local key=$(__docker_map_key_of_current_option '--filter|-f') - case "$key" in - before) - cur="${cur##*=}" - __docker_complete_images - return - ;; - dangling) - COMPREPLY=( $( compgen -W "false true" -- "${cur##*=}" ) ) - return - ;; - label) - return - ;; - since) - cur="${cur##*=}" - __docker_complete_images - return - ;; - esac - - case "$prev" in - --filter|-f) - COMPREPLY=( $( compgen -S = -W "before dangling label since" -- "$cur" ) ) - __docker_nospace - return - ;; - --format) - return - ;; - esac - - case "$cur" in - -*) - COMPREPLY=( $( compgen -W "--all -a --digests --filter -f --format --help --no-trunc --quiet -q" -- "$cur" ) ) - ;; - =) - return - ;; - *) - __docker_complete_image_repos - ;; - esac -} - -_docker_import() { - case "$prev" in - --change|-c|--message|-m) - return - ;; - esac - - case "$cur" in - -*) - COMPREPLY=( $( compgen -W "--change -c --help --message -m" -- "$cur" ) ) - ;; - *) - local counter=$(__docker_pos_first_nonflag '--change|-c|--message|-m') - if [ $cword -eq $counter ]; then - return - fi - (( counter++ )) - - if [ $cword -eq $counter ]; then - __docker_complete_image_repos_and_tags - return - fi - ;; - esac -} - -_docker_info() { - case "$cur" in - -*) - COMPREPLY=( $( compgen -W "--help" -- "$cur" ) ) - ;; - esac -} - -_docker_inspect() { - case "$prev" in - --format|-f) - return - ;; - --type) - COMPREPLY=( $( compgen -W "image container" -- "$cur" ) ) - return - ;; - - esac - - case "$cur" in - -*) - COMPREPLY=( $( compgen -W "--format -f --help --size -s --type" -- "$cur" ) ) - ;; - *) - case $(__docker_value_of_option --type) in - '') - __docker_complete_containers_and_images - ;; - container) - __docker_complete_containers_all - ;; - image) - __docker_complete_images - ;; - esac - esac -} - -_docker_kill() { +_docker_container_kill() { case "$prev" in --signal|-s) __docker_complete_signals @@ -1331,775 +1501,31 @@ _docker_kill() { esac } -_docker_load() { +_docker_container_logs() { case "$prev" in - --input|-i) - _filedir + --since|--tail|--until) return ;; esac case "$cur" in -*) - COMPREPLY=( $( compgen -W "--help --input -i --quiet -q" -- "$cur" ) ) - ;; - esac -} - -_docker_login() { - case "$prev" in - --password|-p|--username|-u) - return - ;; - esac - - case "$cur" in - -*) - COMPREPLY=( $( compgen -W "--help --password -p --username -u" -- "$cur" ) ) - ;; - esac -} - -_docker_logout() { - case "$cur" in - -*) - COMPREPLY=( $( compgen -W "--help" -- "$cur" ) ) - ;; - esac -} - -_docker_logs() { - case "$prev" in - --since|--tail) - return - ;; - esac - - case "$cur" in - -*) - COMPREPLY=( $( compgen -W "--details --follow -f --help --since --tail --timestamps -t" -- "$cur" ) ) + COMPREPLY=( $( compgen -W "--details --follow -f --help --since --tail --timestamps -t --until" -- "$cur" ) ) ;; *) - local counter=$(__docker_pos_first_nonflag '--tail') - if [ $cword -eq $counter ]; then + local counter=$(__docker_pos_first_nonflag '--since|--tail|--until') + if [ "$cword" -eq "$counter" ]; then __docker_complete_containers_all fi ;; esac } -_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 "$boolean_options $options_with_args" -- "$cur" ) ) - ;; - *) - 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_all - fi - ;; - esac +_docker_container_list() { + _docker_container_ls } -_docker_network_create() { - case "$prev" in - --aux-address|--gateway|--internal|--ip-range|--ipam-opt|--ipv6|--opt|-o|--subnet) - return - ;; - --ipam-driver) - COMPREPLY=( $( compgen -W "default" -- "$cur" ) ) - return - ;; - --driver|-d) - local plugins=" $(__docker_plugins Network) " - # remove drivers that allow one instance only - plugins=${plugins/ host / } - plugins=${plugins/ null / } - COMPREPLY=( $(compgen -W "$plugins" -- "$cur") ) - return - ;; - --label) - return - ;; - esac - - case "$cur" in - -*) - COMPREPLY=( $( compgen -W "--aux-address --driver -d --gateway --help --internal --ip-range --ipam-driver --ipam-opt --ipv6 --label --opt -o --subnet" -- "$cur" ) ) - ;; - esac -} - -_docker_network_disconnect() { - case "$cur" in - -*) - COMPREPLY=( $( compgen -W "--help" -- "$cur" ) ) - ;; - *) - local counter=$(__docker_pos_first_nonflag) - if [ $cword -eq $counter ]; then - __docker_complete_networks - elif [ $cword -eq $(($counter + 1)) ]; then - __docker_complete_containers_in_network "$prev" - fi - ;; - esac -} - -_docker_network_inspect() { - case "$prev" in - --format|-f) - return - ;; - esac - - case "$cur" in - -*) - COMPREPLY=( $( compgen -W "--format -f --help" -- "$cur" ) ) - ;; - *) - __docker_complete_networks - esac -} - -_docker_network_ls() { - 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 "$prev" in - --filter|-f) - COMPREPLY=( $( compgen -S = -W "driver id label name type" -- "$cur" ) ) - __docker_nospace - return - ;; - esac - - case "$cur" in - -*) - COMPREPLY=( $( compgen -W "--filter -f --help --no-trunc --quiet -q" -- "$cur" ) ) - ;; - esac -} - -_docker_network_rm() { - case "$cur" in - -*) - COMPREPLY=( $( compgen -W "--help" -- "$cur" ) ) - ;; - *) - __docker_complete_networks type=custom - esac -} - -_docker_network() { - local subcommands=" - connect - create - disconnect - inspect - ls - rm - " - __docker_subcommands "$subcommands" && return - - case "$cur" in - -*) - COMPREPLY=( $( compgen -W "--help" -- "$cur" ) ) - ;; - *) - COMPREPLY=( $( compgen -W "$subcommands" -- "$cur" ) ) - ;; - esac -} - -_docker_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 - -*) - COMPREPLY=( $( compgen -W "--help" -- "$cur" ) ) - ;; - *) - local counter=$(__docker_pos_first_nonflag) - if [ $cword -eq $counter ]; then - __docker_complete_containers_pauseable - fi - ;; - esac -} - -_docker_port() { - case "$cur" in - -*) - COMPREPLY=( $( compgen -W "--help" -- "$cur" ) ) - ;; - *) - local counter=$(__docker_pos_first_nonflag) - if [ $cword -eq $counter ]; then - __docker_complete_containers_all - fi - ;; - esac -} - -_docker_ps() { +_docker_container_ls() { local key=$(__docker_map_key_of_current_option '--filter|-f') case "$key" in ancestor) @@ -2108,44 +1534,49 @@ _docker_ps() { return ;; before) - cur="${cur##*=}" - __docker_complete_containers_all + __docker_complete_containers_all --cur "${cur##*=}" + return + ;; + expose|publish) return ;; id) - cur="${cur##*=}" - __docker_complete_container_ids + __docker_complete_containers_all --cur "${cur##*=}" --id + return + ;; + health) + COMPREPLY=( $( compgen -W "healthy starting none unhealthy" -- "${cur##*=}" ) ) + return + ;; + is-task) + COMPREPLY=( $( compgen -W "true false" -- "${cur##*=}" ) ) return ;; name) - cur="${cur##*=}" - __docker_complete_container_names + __docker_complete_containers_all --cur "${cur##*=}" --name return ;; network) - cur="${cur##*=}" - __docker_complete_networks + __docker_complete_networks --cur "${cur##*=}" return ;; since) - cur="${cur##*=}" - __docker_complete_containers_all + __docker_complete_containers_all --cur "${cur##*=}" return ;; status) - COMPREPLY=( $( compgen -W "created dead exited paused restarting running" -- "${cur##*=}" ) ) + COMPREPLY=( $( compgen -W "created dead exited paused restarting running removing" -- "${cur##*=}" ) ) return ;; volume) - cur="${cur##*=}" - __docker_complete_volumes + __docker_complete_volumes --cur "${cur##*=}" return ;; esac case "$prev" in --filter|-f) - COMPREPLY=( $( compgen -S = -W "ancestor before exited id label name network since status volume" -- "$cur" ) ) + COMPREPLY=( $( compgen -S = -W "ancestor before exited expose health id is-task label name network publish since status volume" -- "$cur" ) ) __docker_nospace return ;; @@ -2161,57 +1592,66 @@ _docker_ps() { esac } -_docker_pull() { +_docker_container_pause() { case "$cur" in -*) - COMPREPLY=( $( compgen -W "--all-tags -a --disable-content-trust=false --help" -- "$cur" ) ) + COMPREPLY=( $( compgen -W "--help" -- "$cur" ) ) ;; *) - local counter=$(__docker_pos_first_nonflag) - if [ $cword -eq $counter ]; then - for arg in "${COMP_WORDS[@]}"; do - case "$arg" in - --all-tags|-a) - __docker_complete_image_repos - return - ;; - esac - done - __docker_complete_image_repos_and_tags - fi + __docker_complete_containers_running ;; esac } -_docker_push() { - case "$cur" in - -*) - COMPREPLY=( $( compgen -W "--disable-content-trust=false --help" -- "$cur" ) ) - ;; - *) - local counter=$(__docker_pos_first_nonflag) - if [ $cword -eq $counter ]; then - __docker_complete_image_repos_and_tags - fi - ;; - esac -} - -_docker_rename() { +_docker_container_port() { case "$cur" in -*) COMPREPLY=( $( compgen -W "--help" -- "$cur" ) ) ;; *) local counter=$(__docker_pos_first_nonflag) - if [ $cword -eq $counter ]; then + if [ "$cword" -eq "$counter" ]; then __docker_complete_containers_all fi ;; esac } -_docker_restart() { +_docker_container_prune() { + case "$prev" in + --filter) + COMPREPLY=( $( compgen -W "label label! until" -S = -- "$cur" ) ) + __docker_nospace + return + ;; + esac + + case "$cur" in + -*) + COMPREPLY=( $( compgen -W "--force -f --filter --help" -- "$cur" ) ) + ;; + esac +} + +_docker_container_ps() { + _docker_container_ls +} + +_docker_container_rename() { + case "$cur" in + -*) + COMPREPLY=( $( compgen -W "--help" -- "$cur" ) ) + ;; + *) + local counter=$(__docker_pos_first_nonflag) + if [ "$cword" -eq "$counter" ]; then + __docker_complete_containers_all + fi + ;; + esac +} + +_docker_container_restart() { case "$prev" in --time|-t) return @@ -2228,7 +1668,7 @@ _docker_restart() { esac } -_docker_rm() { +_docker_container_rm() { case "$cur" in -*) COMPREPLY=( $( compgen -W "--force -f --help --link -l --volumes -v" -- "$cur" ) ) @@ -2242,23 +1682,18 @@ _docker_rm() { ;; esac done - __docker_complete_containers_stopped + __docker_complete_containers_removable ;; esac } -_docker_rmi() { - case "$cur" in - -*) - COMPREPLY=( $( compgen -W "--force -f --help --no-prune" -- "$cur" ) ) - ;; - *) - __docker_complete_images - ;; - esac +_docker_container_run() { + _docker_container_run_and_create } -_docker_run() { +# _docker_container_run_and_create is the combined completion for `_docker_container_run` +# and `_docker_container_create` +_docker_container_run_and_create() { local options_with_args=" --add-host --attach -a @@ -2270,27 +1705,35 @@ _docker_run() { --cidfile --cpu-period --cpu-quota + --cpu-rt-period + --cpu-rt-runtime --cpuset-cpus + --cpus --cpuset-mems --cpu-shares -c --device + --device-cgroup-rule --device-read-bps --device-read-iops --device-write-bps --device-write-iops --dns - --dns-opt + --dns-option --dns-search --entrypoint --env -e --env-file --expose --group-add + --health-cmd + --health-interval + --health-retries + --health-start-period + --health-timeout --hostname -h --ip --ip6 --ipc - --isolation --kernel-memory --label-file --label -l @@ -2303,9 +1746,10 @@ _docker_run() { --memory-swap --memory-swappiness --memory-reservation + --mount --name - --net - --net-alias + --network + --network-alias --oom-score-adj --pid --pids-limit @@ -2315,6 +1759,7 @@ _docker_run() { --security-opt --shm-size --stop-signal + --stop-timeout --storage-opt --tmpfs --sysctl @@ -2327,11 +1772,23 @@ _docker_run() { --volume -v --workdir -w " + __docker_daemon_os_is windows && options_with_args+=" + --cpu-count + --cpu-percent + --io-maxbandwidth + --io-maxiops + --isolation + " + __docker_daemon_is_experimental && options_with_args+=" + --platform + " local boolean_options=" --disable-content-trust=false --help + --init --interactive -i + --no-healthcheck --oom-kill-disable --privileged --publish-all -P @@ -2339,21 +1796,16 @@ _docker_run() { --tty -t " - if [ "$command" = "run" ] ; then + if [ "$command" = "run" ] || [ "$subcommand" = "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 + __docker_complete_detach_keys && return fi local all_options="$options_with_args $boolean_options" @@ -2393,8 +1845,12 @@ _docker_run() { COMPREPLY=( $( compgen -W 'stdin stdout stderr' -- "$cur" ) ) return ;; - --cap-add|--cap-drop) - __docker_complete_capabilities + --cap-add) + __docker_complete_capabilities_addable + return + ;; + --cap-drop) + __docker_complete_capabilities_droppable return ;; --cidfile|--env-file|--label-file) @@ -2418,6 +1874,7 @@ _docker_run() { return ;; --env|-e) + # we do not append a "=" here because "-e VARNAME" is legal syntax, too COMPREPLY=( $( compgen -e -- "$cur" ) ) __docker_nospace return @@ -2429,7 +1886,8 @@ _docker_run() { __docker_complete_containers_running ;; *) - COMPREPLY=( $( compgen -W 'host container:' -- "$cur" ) ) + COMPREPLY=( $( compgen -W 'none host private shareable container:' -- "$cur" ) ) + # shellcheck disable=SC2128 if [ "$COMPREPLY" = "container:" ]; then __docker_nospace fi @@ -2438,8 +1896,10 @@ _docker_run() { return ;; --isolation) - __docker_complete_isolation - return + if __docker_daemon_os_is windows ; then + __docker_complete_isolation + return + fi ;; --link) case "$cur" in @@ -2461,14 +1921,13 @@ _docker_run() { __docker_complete_log_options return ;; - --net) + --network) case "$cur" in container:*) - local cur=${cur#*:} - __docker_complete_containers_all + __docker_complete_containers_all --cur "${cur#*:}" ;; *) - COMPREPLY=( $( compgen -W "$(__docker_plugins Network) $(__docker_networks) container:" -- "$cur") ) + COMPREPLY=( $( compgen -W "$(__docker_plugins_bundled --type Network) $(__docker_networks) container:" -- "$cur") ) if [ "${COMPREPLY[*]}" = "container:" ] ; then __docker_nospace fi @@ -2479,11 +1938,11 @@ _docker_run() { --pid) case "$cur" in *:*) - cur="${cur#*:}" - __docker_complete_containers_running + __docker_complete_containers_running --cur "${cur#*:}" ;; *) COMPREPLY=( $( compgen -W 'host container:' -- "$cur" ) ) + # shellcheck disable=SC2128 if [ "$COMPREPLY" = "container:" ]; then __docker_nospace fi @@ -2502,6 +1961,10 @@ _docker_run() { fi return ;; + --stop-signal) + __docker_complete_signals + return + ;; --storage-opt) COMPREPLY=( $( compgen -W "size" -S = -- "$cur") ) __docker_nospace @@ -2516,7 +1979,7 @@ _docker_run() { return ;; --volume-driver) - __docker_complete_plugins Volume + __docker_complete_plugins_bundled --type Volume return ;; --volumes-from) @@ -2533,69 +1996,36 @@ _docker_run() { COMPREPLY=( $( compgen -W "$all_options" -- "$cur" ) ) ;; *) - local counter=$( __docker_pos_first_nonflag $( __docker_to_alternatives "$options_with_args" ) ) - if [ $cword -eq $counter ]; then + local counter=$( __docker_pos_first_nonflag "$( __docker_to_alternatives "$options_with_args" )" ) + if [ "$cword" -eq "$counter" ]; then __docker_complete_images fi ;; esac } -_docker_save() { +_docker_container_start() { + __docker_complete_detach_keys && return + # shellcheck disable=SC2078 case "$prev" in - --output|-o) - _filedir - return + --checkpoint) + if [ __docker_daemon_is_experimental ] ; then + return + fi + ;; + --checkpoint-dir) + if [ __docker_daemon_is_experimental ] ; then + _filedir -d + return + fi ;; esac case "$cur" in -*) - COMPREPLY=( $( compgen -W "--help --output -o" -- "$cur" ) ) - ;; - *) - __docker_complete_images - ;; - esac -} - -_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 - --filter|-f) - COMPREPLY=( $( compgen -S = -W "is-automated is-official stars" -- "$cur" ) ) - __docker_nospace - return - ;; - --limit) - return - ;; - esac - - case "$cur" in - -*) - 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 --detach-keys --help --interactive -i" -- "$cur" ) ) + local options="--attach -a --detach-keys --help --interactive -i" + __docker_daemon_is_experimental && options+=" --checkpoint --checkpoint-dir" + COMPREPLY=( $( compgen -W "$options" -- "$cur" ) ) ;; *) __docker_complete_containers_stopped @@ -2603,10 +2033,16 @@ _docker_start() { esac } -_docker_stats() { +_docker_container_stats() { + case "$prev" in + --format) + return + ;; + esac + case "$cur" in -*) - COMPREPLY=( $( compgen -W "--all -a --help --no-stream" -- "$cur" ) ) + COMPREPLY=( $( compgen -W "--all -a --format --help --no-stream --no-trunc" -- "$cur" ) ) ;; *) __docker_complete_containers_running @@ -2614,7 +2050,7 @@ _docker_stats() { esac } -_docker_stop() { +_docker_container_stop() { case "$prev" in --time|-t) return @@ -2631,47 +2067,42 @@ _docker_stop() { esac } -_docker_tag() { +_docker_container_top() { case "$cur" in -*) COMPREPLY=( $( compgen -W "--help" -- "$cur" ) ) ;; *) local counter=$(__docker_pos_first_nonflag) - - if [ $cword -eq $counter ]; then - __docker_complete_image_repos_and_tags - return - fi - (( counter++ )) - - if [ $cword -eq $counter ]; then - __docker_complete_image_repos_and_tags - return + if [ "$cword" -eq "$counter" ]; then + __docker_complete_containers_running fi ;; esac } -_docker_unpause() { +_docker_container_unpause() { case "$cur" in -*) COMPREPLY=( $( compgen -W "--help" -- "$cur" ) ) ;; *) local counter=$(__docker_pos_first_nonflag) - if [ $cword -eq $counter ]; then + if [ "$cword" -eq "$counter" ]; then __docker_complete_containers_unpauseable fi ;; esac } -_docker_update() { +_docker_container_update() { local options_with_args=" --blkio-weight --cpu-period --cpu-quota + --cpu-rt-period + --cpu-rt-runtime + --cpus --cpuset-cpus --cpuset-mems --cpu-shares -c @@ -2706,21 +2137,788 @@ _docker_update() { esac } -_docker_top() { +_docker_container_wait() { + case "$cur" in + -*) + COMPREPLY=( $( compgen -W "--help" -- "$cur" ) ) + ;; + *) + __docker_complete_containers_all + ;; + esac +} + + +_docker_commit() { + _docker_container_commit +} + +_docker_cp() { + _docker_container_cp +} + +_docker_create() { + _docker_container_create +} + +_docker_daemon() { + local boolean_options=" + $global_boolean_options + --experimental + --help + --icc=false + --init + --ip-forward=false + --ip-masq=false + --iptables=false + --ipv6 + --live-restore + --no-new-privileges + --raw-logs + --selinux-enabled + --userland-proxy=false + --version -v + " + local options_with_args=" + $global_options_with_args + --add-runtime + --allow-nondistributable-artifacts + --api-cors-header + --authorization-plugin + --bip + --bridge -b + --cgroup-parent + --cluster-advertise + --cluster-store + --cluster-store-opt + --config-file + --containerd + --cpu-rt-period + --cpu-rt-runtime + --data-root + --default-gateway + --default-gateway-v6 + --default-runtime + --default-shm-size + --default-ulimit + --dns + --dns-search + --dns-opt + --exec-opt + --exec-root + --fixed-cidr + --fixed-cidr-v6 + --group -G + --init-path + --insecure-registry + --ip + --label + --log-driver + --log-opt + --max-concurrent-downloads + --max-concurrent-uploads + --metrics-addr + --mtu + --network-control-plane-mtu + --node-generic-resource + --oom-score-adjust + --pidfile -p + --registry-mirror + --seccomp-profile + --shutdown-timeout + --storage-driver -s + --storage-opt + --swarm-default-advertise-addr + --userland-proxy-path + --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.directlvm_device|dm.thinpooldev) + cur=${cur##*=} + _filedir + return + ;; + dm.fs) + COMPREPLY=( $( compgen -W "ext4 xfs" -- "${cur##*=}" ) ) + return + ;; + dm.libdm_log_level) + COMPREPLY=( $( compgen -W "2 3 4 5 6 7" -- "${cur##*=}" ) ) + return + ;; + esac + + case "$prev" in + --authorization-plugin) + __docker_complete_plugins_bundled --type Authorization + return + ;; + --cluster-store) + COMPREPLY=( $( compgen -W "consul etcd zk" -S "://" -- "$cur" ) ) + __docker_nospace + return + ;; + --cluster-store-opt) + COMPREPLY=( $( compgen -W "discovery.heartbeat discovery.ttl kv.cacertfile kv.certfile kv.keyfile kv.path" -S = -- "$cur" ) ) + __docker_nospace + return + ;; + --config-file|--containerd|--init-path|--pidfile|-p|--tlscacert|--tlscert|--tlskey|--userland-proxy-path) + _filedir + return + ;; + --exec-root|--data-root) + _filedir -d + return + ;; + --log-driver) + __docker_complete_log_drivers + return + ;; + --storage-driver|-s) + 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 + dm.blocksize + dm.directlvm_device + dm.fs + dm.libdm_log_level + dm.loopdatasize + dm.loopmetadatasize + dm.min_free_space + dm.mkfsarg + dm.mountopt + dm.override_udev_sync_check + dm.thinpooldev + dm.thinp_autoextend_percent + dm.thinp_autoextend_threshold + dm.thinp_metapercent + dm.thinp_percent + dm.use_deferred_deletion + dm.use_deferred_removal + " + local overlay2_options="overlay2.size" + local zfs_options="zfs.fsname" + + local all_options="$btrfs_options $devicemapper_options $overlay2_options $zfs_options" + + case $(__docker_value_of_option '--storage-driver|-s') in + '') + COMPREPLY=( $( compgen -W "$all_options" -S = -- "$cur" ) ) + ;; + btrfs) + COMPREPLY=( $( compgen -W "$btrfs_options" -S = -- "$cur" ) ) + ;; + devicemapper) + COMPREPLY=( $( compgen -W "$devicemapper_options" -S = -- "$cur" ) ) + ;; + overlay2) + COMPREPLY=( $( compgen -W "$overlay2_options" -S = -- "$cur" ) ) + ;; + zfs) + COMPREPLY=( $( compgen -W "$zfs_options" -S = -- "$cur" ) ) + ;; + *) + return + ;; + esac + __docker_nospace + return + ;; + --log-level|-l) + __docker_complete_log_levels + return + ;; + --log-opt) + __docker_complete_log_options + return + ;; + --metrics-addr) + __docker_complete_local_ips + __docker_append_to_completions ":" + __docker_nospace + return + ;; + --seccomp-profile) + _filedir json + return + ;; + --swarm-default-advertise-addr) + __docker_complete_local_interfaces + return + ;; + --userns-remap) + __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" ) ) + ;; + esac +} + +_docker_deploy() { + __docker_daemon_is_experimental && _docker_stack_deploy +} + +_docker_diff() { + _docker_container_diff +} + +_docker_events() { + _docker_system_events +} + +_docker_exec() { + _docker_container_exec +} + +_docker_export() { + _docker_container_export +} + +_docker_help() { + local counter=$(__docker_pos_first_nonflag) + if [ "$cword" -eq "$counter" ]; then + COMPREPLY=( $( compgen -W "${commands[*]}" -- "$cur" ) ) + fi +} + +_docker_history() { + _docker_image_history +} + + +_docker_image() { + local subcommands=" + build + history + import + inspect + load + ls + prune + pull + push + rm + save + tag + " + local aliases=" + images + list + remove + rmi + " + __docker_subcommands "$subcommands $aliases" && return + + case "$cur" in + -*) + COMPREPLY=( $( compgen -W "--help" -- "$cur" ) ) + ;; + *) + COMPREPLY=( $( compgen -W "$subcommands" -- "$cur" ) ) + ;; + esac +} + +_docker_image_build() { + local options_with_args=" + --add-host + --build-arg + --cache-from + --cgroup-parent + --cpuset-cpus + --cpuset-mems + --cpu-shares -c + --cpu-period + --cpu-quota + --file -f + --iidfile + --label + --memory -m + --memory-swap + --network + --shm-size + --tag -t + --target + --ulimit + " + __docker_daemon_os_is windows && options_with_args+=" + --isolation + " + + local boolean_options=" + --compress + --disable-content-trust=false + --force-rm + --help + --no-cache + --pull + --quiet -q + --rm + " + if __docker_daemon_is_experimental ; then + options_with_args+=" + --platform + " + boolean_options+=" + --squash + --stream + " + fi + + local all_options="$options_with_args $boolean_options" + + case "$prev" in + --add-host) + case "$cur" in + *:) + __docker_complete_resolved_hostname + return + ;; + esac + ;; + --build-arg) + COMPREPLY=( $( compgen -e -- "$cur" ) ) + __docker_nospace + return + ;; + --cache-from) + __docker_complete_image_repos_and_tags + return + ;; + --file|-f|--iidfile) + _filedir + return + ;; + --isolation) + if __docker_daemon_os_is windows ; then + __docker_complete_isolation + return + fi + ;; + --network) + case "$cur" in + container:*) + __docker_complete_containers_all --cur "${cur#*:}" + ;; + *) + COMPREPLY=( $( compgen -W "$(__docker_plugins_bundled --type Network) $(__docker_networks) container:" -- "$cur") ) + if [ "${COMPREPLY[*]}" = "container:" ] ; then + __docker_nospace + fi + ;; + esac + return + ;; + --tag|-t) + __docker_complete_image_repos_and_tags + return + ;; + --target) + local context_pos=$( __docker_pos_first_nonflag "$( __docker_to_alternatives "$options_with_args" )" ) + local context="${words[$context_pos]}" + context="${context:-.}" + + local file="$( __docker_value_of_option '--file|f' )" + local default_file="${context%/}/Dockerfile" + local dockerfile="${file:-$default_file}" + + local targets="$( sed -n 's/^FROM .\+ AS \(.\+\)/\1/p' "$dockerfile" 2>/dev/null )" + COMPREPLY=( $( compgen -W "$targets" -- "$cur" ) ) + return + ;; + $(__docker_to_extglob "$options_with_args") ) + return + ;; + esac + + case "$cur" in + -*) + COMPREPLY=( $( compgen -W "$all_options" -- "$cur" ) ) + ;; + *) + local counter=$( __docker_pos_first_nonflag "$( __docker_to_alternatives "$options_with_args" )" ) + if [ "$cword" -eq "$counter" ]; then + _filedir -d + fi + ;; + esac +} + +_docker_image_history() { + case "$prev" in + --format) + return + ;; + esac + + case "$cur" in + -*) + COMPREPLY=( $( compgen -W "--format --help --human=false -H=false --no-trunc --quiet -q" -- "$cur" ) ) + ;; + *) + local counter=$(__docker_pos_first_nonflag) + if [ "$cword" -eq "$counter" ]; then + __docker_complete_images + fi + ;; + esac +} + +_docker_image_images() { + _docker_image_ls +} + +_docker_image_import() { + case "$prev" in + --change|-c|--message|-m) + return + ;; + esac + + case "$cur" in + -*) + COMPREPLY=( $( compgen -W "--change -c --help --message -m" -- "$cur" ) ) + ;; + *) + local counter=$(__docker_pos_first_nonflag '--change|-c|--message|-m') + if [ "$cword" -eq "$counter" ]; then + return + fi + (( counter++ )) + + if [ "$cword" -eq "$counter" ]; then + __docker_complete_image_repos_and_tags + return + fi + ;; + esac +} + +_docker_image_inspect() { + _docker_inspect --type image +} + +_docker_image_load() { + case "$prev" in + --input|-i|"<") + _filedir + return + ;; + esac + + case "$cur" in + -*) + COMPREPLY=( $( compgen -W "--help --input -i --quiet -q" -- "$cur" ) ) + ;; + esac +} + +_docker_image_list() { + _docker_image_ls +} + +_docker_image_ls() { + local key=$(__docker_map_key_of_current_option '--filter|-f') + case "$key" in + before|since|reference) + cur="${cur##*=}" + __docker_complete_images + return + ;; + dangling) + COMPREPLY=( $( compgen -W "false true" -- "${cur##*=}" ) ) + return + ;; + label) + return + ;; + esac + + case "$prev" in + --filter|-f) + COMPREPLY=( $( compgen -S = -W "before dangling label reference since" -- "$cur" ) ) + __docker_nospace + return + ;; + --format) + return + ;; + esac + + case "$cur" in + -*) + COMPREPLY=( $( compgen -W "--all -a --digests --filter -f --format --help --no-trunc --quiet -q" -- "$cur" ) ) + ;; + =) + return + ;; + *) + __docker_complete_image_repos + ;; + esac +} + +_docker_image_prune() { + case "$prev" in + --filter) + COMPREPLY=( $( compgen -W "label label! until" -S = -- "$cur" ) ) + __docker_nospace + return + ;; + esac + + case "$cur" in + -*) + COMPREPLY=( $( compgen -W "--all -a --force -f --filter --help" -- "$cur" ) ) + ;; + esac +} + +_docker_image_pull() { + case "$prev" in + --platform) + return + ;; + esac + + case "$cur" in + -*) + local options="--all-tags -a --disable-content-trust=false --help" + __docker_daemon_is_experimental && options+=" --platform" + + COMPREPLY=( $( compgen -W "$options" -- "$cur" ) ) + ;; + *) + local counter=$(__docker_pos_first_nonflag --platform) + if [ "$cword" -eq "$counter" ]; then + for arg in "${COMP_WORDS[@]}"; do + case "$arg" in + --all-tags|-a) + __docker_complete_image_repos + return + ;; + esac + done + __docker_complete_image_repos_and_tags + fi + ;; + esac +} + +_docker_image_push() { + case "$cur" in + -*) + COMPREPLY=( $( compgen -W "--disable-content-trust=false --help" -- "$cur" ) ) + ;; + *) + local counter=$(__docker_pos_first_nonflag) + if [ "$cword" -eq "$counter" ]; then + __docker_complete_image_repos_and_tags + fi + ;; + esac +} + +_docker_image_remove() { + _docker_image_rm +} + +_docker_image_rm() { + case "$cur" in + -*) + COMPREPLY=( $( compgen -W "--force -f --help --no-prune" -- "$cur" ) ) + ;; + *) + __docker_complete_images + ;; + esac +} + +_docker_image_rmi() { + _docker_image_rm +} + +_docker_image_save() { + case "$prev" in + --output|-o|">") + _filedir + return + ;; + esac + + case "$cur" in + -*) + COMPREPLY=( $( compgen -W "--help --output -o" -- "$cur" ) ) + ;; + *) + __docker_complete_images + ;; + esac +} + +_docker_image_tag() { case "$cur" in -*) COMPREPLY=( $( compgen -W "--help" -- "$cur" ) ) ;; *) local counter=$(__docker_pos_first_nonflag) - if [ $cword -eq $counter ]; then - __docker_complete_containers_running + + if [ "$cword" -eq "$counter" ]; then + __docker_complete_image_repos_and_tags + return + fi + (( counter++ )) + + if [ "$cword" -eq "$counter" ]; then + __docker_complete_image_repos_and_tags + return fi ;; esac } -_docker_version() { + +_docker_images() { + _docker_image_ls +} + +_docker_import() { + _docker_image_import +} + +_docker_info() { + _docker_system_info +} + +_docker_inspect() { + local preselected_type + local type + + if [ "$1" = "--type" ] ; then + preselected_type=yes + type="$2" + else + type=$(__docker_value_of_option --type) + fi + + case "$prev" in + --format|-f) + return + ;; + --type) + if [ -z "$preselected_type" ] ; then + COMPREPLY=( $( compgen -W "container image network node plugin secret service volume" -- "$cur" ) ) + return + fi + ;; + esac + + case "$cur" in + -*) + local options="--format -f --help --size -s" + if [ -z "$preselected_type" ] ; then + options+=" --type" + fi + COMPREPLY=( $( compgen -W "$options" -- "$cur" ) ) + ;; + *) + case "$type" in + '') + COMPREPLY=( $( compgen -W " + $(__docker_containers --all) + $(__docker_images) + $(__docker_networks) + $(__docker_nodes) + $(__docker_plugins_installed) + $(__docker_secrets) + $(__docker_services) + $(__docker_volumes) + " -- "$cur" ) ) + __ltrim_colon_completions "$cur" + ;; + container) + __docker_complete_containers_all + ;; + image) + __docker_complete_images + ;; + network) + __docker_complete_networks + ;; + node) + __docker_complete_nodes + ;; + plugin) + __docker_complete_plugins_installed + ;; + secret) + __docker_complete_secrets + ;; + service) + __docker_complete_services + ;; + volume) + __docker_complete_volumes + ;; + esac + esac +} + +_docker_kill() { + _docker_container_kill +} + +_docker_load() { + _docker_image_load +} + +_docker_login() { + case "$prev" in + --password|-p|--username|-u) + return + ;; + esac + + case "$cur" in + -*) + COMPREPLY=( $( compgen -W "--help --password -p --password-stdin --username -u" -- "$cur" ) ) + ;; + esac +} + +_docker_logout() { case "$cur" in -*) COMPREPLY=( $( compgen -W "--help" -- "$cur" ) ) @@ -2728,20 +2926,1892 @@ _docker_version() { esac } +_docker_logs() { + _docker_container_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 "$boolean_options $options_with_args" -- "$cur" ) ) + ;; + *) + 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_all + fi + ;; + esac +} + +_docker_network_create() { + case "$prev" in + --aux-address|--gateway|--ip-range|--ipam-opt|--ipv6|--opt|-o|--subnet) + return + ;; + --config-from) + __docker_complete_networks + return + ;; + --driver|-d) + # remove drivers that allow one instance only, add drivers missing in `docker info` + __docker_complete_plugins_bundled --type Network --remove host --remove null --add macvlan + return + ;; + --ipam-driver) + COMPREPLY=( $( compgen -W "default" -- "$cur" ) ) + return + ;; + --label) + return + ;; + --scope) + COMPREPLY=( $( compgen -W "local swarm" -- "$cur" ) ) + return + ;; + esac + + case "$cur" in + -*) + COMPREPLY=( $( compgen -W "--attachable --aux-address --config-from --config-only --driver -d --gateway --help --ingress --internal --ip-range --ipam-driver --ipam-opt --ipv6 --label --opt -o --scope --subnet" -- "$cur" ) ) + ;; + esac +} + +_docker_network_disconnect() { + case "$cur" in + -*) + COMPREPLY=( $( compgen -W "--help" -- "$cur" ) ) + ;; + *) + local counter=$(__docker_pos_first_nonflag) + if [ "$cword" -eq "$counter" ]; then + __docker_complete_networks + elif [ "$cword" -eq "$((counter + 1))" ]; then + __docker_complete_containers_in_network "$prev" + fi + ;; + esac +} + +_docker_network_inspect() { + case "$prev" in + --format|-f) + return + ;; + esac + + case "$cur" in + -*) + COMPREPLY=( $( compgen -W "--format -f --help --verbose" -- "$cur" ) ) + ;; + *) + __docker_complete_networks + esac +} + +_docker_network_ls() { + local key=$(__docker_map_key_of_current_option '--filter|-f') + case "$key" in + driver) + __docker_complete_plugins_bundled --cur "${cur##*=}" --type Network --add macvlan + return + ;; + id) + __docker_complete_networks --cur "${cur##*=}" --id + return + ;; + name) + __docker_complete_networks --cur "${cur##*=}" --name + return + ;; + scope) + COMPREPLY=( $( compgen -W "global local swarm" -- "${cur##*=}" ) ) + return + ;; + type) + COMPREPLY=( $( compgen -W "builtin custom" -- "${cur##*=}" ) ) + return + ;; + esac + + case "$prev" in + --filter|-f) + COMPREPLY=( $( compgen -S = -W "driver id label name scope type" -- "$cur" ) ) + __docker_nospace + return + ;; + --format) + return + ;; + esac + + case "$cur" in + -*) + COMPREPLY=( $( compgen -W "--filter -f --format --help --no-trunc --quiet -q" -- "$cur" ) ) + ;; + esac +} + +_docker_network_prune() { + case "$prev" in + --filter) + COMPREPLY=( $( compgen -W "label label! until" -S = -- "$cur" ) ) + __docker_nospace + return + ;; + esac + + case "$cur" in + -*) + COMPREPLY=( $( compgen -W "--force -f --filter --help" -- "$cur" ) ) + ;; + esac +} + +_docker_network_rm() { + case "$cur" in + -*) + COMPREPLY=( $( compgen -W "--help" -- "$cur" ) ) + ;; + *) + __docker_complete_networks --filter type=custom + esac +} + +_docker_network() { + local subcommands=" + connect + create + disconnect + inspect + ls + prune + rm + " + local aliases=" + list + remove + " + __docker_subcommands "$subcommands $aliases" && return + + case "$cur" in + -*) + COMPREPLY=( $( compgen -W "--help" -- "$cur" ) ) + ;; + *) + COMPREPLY=( $( compgen -W "$subcommands" -- "$cur" ) ) + ;; + esac +} + +_docker_service() { + local subcommands=" + create + inspect + logs + ls + rm + rollback + scale + ps + update + " + + local aliases=" + list + remove + " + __docker_subcommands "$subcommands $aliases" && return + + case "$cur" in + -*) + COMPREPLY=( $( compgen -W "--help" -- "$cur" ) ) + ;; + *) + COMPREPLY=( $( compgen -W "$subcommands" -- "$cur" ) ) + ;; + esac +} + +_docker_service_create() { + _docker_service_update_and_create +} + +_docker_service_inspect() { + case "$prev" in + --format|-f) + return + ;; + esac + + case "$cur" in + -*) + COMPREPLY=( $( compgen -W "--format -f --help --pretty" -- "$cur" ) ) + ;; + *) + __docker_complete_services + esac +} + +_docker_service_logs() { + case "$prev" in + --since|--tail) + return + ;; + esac + + case "$cur" in + -*) + COMPREPLY=( $( compgen -W "--follow -f --help --no-resolve --no-task-ids --no-trunc --since --tail --timestamps -t" -- "$cur" ) ) + ;; + *) + local counter=$(__docker_pos_first_nonflag '--since|--tail') + if [ "$cword" -eq "$counter" ]; then + __docker_complete_services_and_tasks + fi + ;; + 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 + ;; + mode) + COMPREPLY=( $( compgen -W "global replicated" -- "${cur##*=}" ) ) + return + ;; + name) + __docker_complete_services --cur "${cur##*=}" --name + return + ;; + esac + + case "$prev" in + --filter|-f) + COMPREPLY=( $( compgen -W "id label mode name" -S = -- "$cur" ) ) + __docker_nospace + return + ;; + --format) + return + ;; + esac + + case "$cur" in + -*) + COMPREPLY=( $( compgen -W "--filter -f --format --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_rollback() { + case "$cur" in + -*) + COMPREPLY=( $( compgen -W "--detach -d --help --quit -q" -- "$cur" ) ) + ;; + *) + local counter=$( __docker_pos_first_nonflag ) + if [ "$cword" -eq "$counter" ]; then + __docker_complete_services + fi + ;; + esac +} + +_docker_service_scale() { + case "$cur" in + -*) + COMPREPLY=( $( compgen -W "--detach -d --help" -- "$cur" ) ) + ;; + *) + __docker_complete_services + __docker_append_to_completions "=" + __docker_nospace + ;; + esac +} + +_docker_service_ps() { + local key=$(__docker_map_key_of_current_option '--filter|-f') + case "$key" in + desired-state) + COMPREPLY=( $( compgen -W "accepted running shutdown" -- "${cur##*=}" ) ) + return + ;; + name) + __docker_complete_services --cur "${cur##*=}" --name + return + ;; + node) + __docker_complete_nodes --cur "${cur##*=}" --add self + return + ;; + esac + + case "$prev" in + --filter|-f) + COMPREPLY=( $( compgen -W "desired-state id name node" -S = -- "$cur" ) ) + __docker_nospace + return + ;; + --format) + return + ;; + esac + + case "$cur" in + -*) + COMPREPLY=( $( compgen -W "--filter -f --format --help --no-resolve --no-trunc --quiet -q" -- "$cur" ) ) + ;; + *) + __docker_complete_services + ;; + esac +} + +_docker_service_update() { + _docker_service_update_and_create +} + +# _docker_service_update_and_create is the combined completion for `docker service create` +# and `docker service update` +_docker_service_update_and_create() { + local options_with_args=" + --endpoint-mode + --entrypoint + --env -e + --force + --health-cmd + --health-interval + --health-retries + --health-start-period + --health-timeout + --hostname + --isolation + --label -l + --limit-cpu + --limit-memory + --log-driver + --log-opt + --mount + --replicas + --reserve-cpu + --reserve-memory + --restart-condition + --restart-delay + --restart-max-attempts + --restart-window + --rollback-delay + --rollback-failure-action + --rollback-max-failure-ratio + --rollback-monitor + --rollback-order + --rollback-parallelism + --stop-grace-period + --stop-signal + --update-delay + --update-failure-action + --update-max-failure-ratio + --update-monitor + --update-order + --update-parallelism + --user -u + --workdir -w + " + __docker_daemon_os_is windows && options_with_args+=" + --credential-spec + " + + local boolean_options=" + --detach -d + --help + --no-healthcheck + --read-only + --tty -t + --with-registry-auth + " + + __docker_complete_log_driver_options && return + + if [ "$subcommand" = "create" ] ; then + options_with_args="$options_with_args + --config + --constraint + --container-label + --dns + --dns-option + --dns-search + --env-file + --generic-resource + --group + --host + --mode + --name + --network + --placement-pref + --publish -p + --secret + " + + case "$prev" in + --config) + __docker_complete_configs + return + ;; + --env-file) + _filedir + return + ;; + --group) + COMPREPLY=( $(compgen -g -- "$cur") ) + return + ;; + --host) + case "$cur" in + *:) + __docker_complete_resolved_hostname + return + ;; + esac + ;; + --mode) + COMPREPLY=( $( compgen -W "global replicated" -- "$cur" ) ) + return + ;; + --placement-pref) + COMPREPLY=( $( compgen -W "spread" -S = -- "$cur" ) ) + __docker_nospace + return + ;; + --secret) + __docker_complete_secrets + return + ;; + esac + fi + if [ "$subcommand" = "update" ] ; then + options_with_args="$options_with_args + --args + --config-add + --config-rm + --constraint-add + --constraint-rm + --container-label-add + --container-label-rm + --dns-add + --dns-option-add + --dns-option-rm + --dns-rm + --dns-search-add + --dns-search-rm + --generic-resource-add + --generic-resource-rm + --group-add + --group-rm + --host-add + --host-rm + --image + --network-add + --network-rm + --placement-pref-add + --placement-pref-rm + --publish-add + --publish-rm + --rollback + --secret-add + --secret-rm + " + + case "$prev" in + --config-add|--config-rm) + __docker_complete_configs + return + ;; + --group-add|--group-rm) + COMPREPLY=( $(compgen -g -- "$cur") ) + return + ;; + --host-add|--host-rm) + case "$cur" in + *:) + __docker_complete_resolved_hostname + return + ;; + esac + ;; + --image) + __docker_complete_image_repos_and_tags + return + ;; + --network-add|--network-rm) + __docker_complete_networks + return + ;; + --placement-pref-add|--placement-pref-rm) + COMPREPLY=( $( compgen -W "spread" -S = -- "$cur" ) ) + __docker_nospace + return + ;; + --secret-add|--secret-rm) + __docker_complete_secrets + return + ;; + esac + fi + + local strategy=$(__docker_map_key_of_current_option '--placement-pref|--placement-pref-add|--placement-pref-rm') + case "$strategy" in + spread) + COMPREPLY=( $( compgen -W "engine.labels node.labels" -S . -- "${cur##*=}" ) ) + __docker_nospace + return + ;; + esac + + case "$prev" in + --endpoint-mode) + COMPREPLY=( $( compgen -W "dnsrr vip" -- "$cur" ) ) + return + ;; + --env|-e) + # we do not append a "=" here because "-e VARNAME" is legal systax, too + COMPREPLY=( $( compgen -e -- "$cur" ) ) + __docker_nospace + return + ;; + --isolation) + __docker_complete_isolation + return + ;; + --log-driver) + __docker_complete_log_drivers + return + ;; + --log-opt) + __docker_complete_log_options + return + ;; + --network) + __docker_complete_networks + return + ;; + --restart-condition) + COMPREPLY=( $( compgen -W "any none on-failure" -- "$cur" ) ) + return + ;; + --rollback-failure-action) + COMPREPLY=( $( compgen -W "continue pause" -- "$cur" ) ) + return + ;; + --stop-signal) + __docker_complete_signals + return + ;; + --update-failure-action) + COMPREPLY=( $( compgen -W "continue pause rollback" -- "$cur" ) ) + return + ;; + --update-order|--rollback-order) + COMPREPLY=( $( compgen -W "start-first stop-first" -- "$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" ) ) + ;; + *) + local counter=$( __docker_pos_first_nonflag "$( __docker_to_alternatives "$options_with_args" )" ) + if [ "$subcommand" = "update" ] ; then + if [ "$cword" -eq "$counter" ]; then + __docker_complete_services + fi + else + if [ "$cword" -eq "$counter" ]; then + __docker_complete_images + fi + fi + ;; + esac +} + +_docker_swarm() { + local subcommands=" + ca + init + join + join-token + leave + unlock + unlock-key + update + " + __docker_subcommands "$subcommands" && return + + case "$cur" in + -*) + COMPREPLY=( $( compgen -W "--help" -- "$cur" ) ) + ;; + *) + COMPREPLY=( $( compgen -W "$subcommands" -- "$cur" ) ) + ;; + esac +} + +_docker_swarm_ca() { + case "$prev" in + --ca-cert|--ca-key) + _filedir + return + ;; + --cert-expiry|--external-ca) + return + ;; + esac + + case "$cur" in + -*) + COMPREPLY=( $( compgen -W "--ca-cert --ca-key --cert-expiry --detach -d --external-ca --help --quiet -q --rotate" -- "$cur" ) ) + ;; + esac +} + +_docker_swarm_init() { + case "$prev" in + --advertise-addr) + if [[ $cur == *: ]] ; then + COMPREPLY=( $( compgen -W "2377" -- "${cur##*:}" ) ) + else + __docker_complete_local_interfaces + __docker_nospace + fi + return + ;; + --availability) + COMPREPLY=( $( compgen -W "active drain pause" -- "$cur" ) ) + return + ;; + --cert-expiry|--dispatcher-heartbeat|--external-ca|--max-snapshots|--snapshot-interval|--task-history-limit) + return + ;; + --data-path-addr) + __docker_complete_local_interfaces + return + ;; + --listen-addr) + if [[ $cur == *: ]] ; then + COMPREPLY=( $( compgen -W "2377" -- "${cur##*:}" ) ) + else + __docker_complete_local_interfaces --add 0.0.0.0 + __docker_nospace + fi + return + ;; + esac + + case "$cur" in + -*) + COMPREPLY=( $( compgen -W "--advertise-addr --autolock --availability --cert-expiry --data-path-addr --dispatcher-heartbeat --external-ca --force-new-cluster --help --listen-addr --max-snapshots --snapshot-interval --task-history-limit" -- "$cur" ) ) + ;; + esac +} + +_docker_swarm_join() { + case "$prev" in + --advertise-addr) + if [[ $cur == *: ]] ; then + COMPREPLY=( $( compgen -W "2377" -- "${cur##*:}" ) ) + else + __docker_complete_local_interfaces + __docker_nospace + fi + return + ;; + --availability) + COMPREPLY=( $( compgen -W "active drain pause" -- "$cur" ) ) + return + ;; + --data-path-addr) + __docker_complete_local_interfaces + return + ;; + --listen-addr) + if [[ $cur == *: ]] ; then + COMPREPLY=( $( compgen -W "2377" -- "${cur##*:}" ) ) + else + __docker_complete_local_interfaces --add 0.0.0.0 + __docker_nospace + fi + return + ;; + --token) + return + ;; + esac + + case "$cur" in + -*) + COMPREPLY=( $( compgen -W "--advertise-addr --availability --data-path-addr --help --listen-addr --token" -- "$cur" ) ) + ;; + *:) + COMPREPLY=( $( compgen -W "2377" -- "${cur##*:}" ) ) + ;; + esac +} + +_docker_swarm_join_token() { + case "$cur" in + -*) + COMPREPLY=( $( compgen -W "--help --quiet -q --rotate" -- "$cur" ) ) + ;; + *) + local counter=$( __docker_pos_first_nonflag ) + if [ "$cword" -eq "$counter" ]; then + COMPREPLY=( $( compgen -W "manager worker" -- "$cur" ) ) + fi + ;; + esac +} + +_docker_swarm_leave() { + case "$cur" in + -*) + COMPREPLY=( $( compgen -W "--force -f --help" -- "$cur" ) ) + ;; + esac +} + +_docker_swarm_unlock() { + case "$cur" in + -*) + COMPREPLY=( $( compgen -W "--help" -- "$cur" ) ) + ;; + esac +} + +_docker_swarm_unlock_key() { + case "$cur" in + -*) + COMPREPLY=( $( compgen -W "--help --quiet -q --rotate" -- "$cur" ) ) + ;; + esac +} + +_docker_swarm_update() { + case "$prev" in + --cert-expiry|--dispatcher-heartbeat|--external-ca|--max-snapshots|--snapshot-interval|--task-history-limit) + return + ;; + esac + + case "$cur" in + -*) + COMPREPLY=( $( compgen -W "--autolock --cert-expiry --dispatcher-heartbeat --external-ca --help --max-snapshots --snapshot-interval --task-history-limit" -- "$cur" ) ) + ;; + esac +} + +_docker_node() { + local subcommands=" + demote + inspect + ls + promote + rm + ps + update + " + local aliases=" + list + remove + " + __docker_subcommands "$subcommands $aliases" && return + + case "$cur" in + -*) + COMPREPLY=( $( compgen -W "--help" -- "$cur" ) ) + ;; + *) + COMPREPLY=( $( compgen -W "$subcommands" -- "$cur" ) ) + ;; + 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" -- "$cur" ) ) + ;; + *) + __docker_complete_nodes --add self + 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 + ;; + membership) + COMPREPLY=( $( compgen -W "accepted pending" -- "${cur##*=}" ) ) + return + ;; + name) + __docker_complete_nodes --cur "${cur##*=}" --name + return + ;; + role) + COMPREPLY=( $( compgen -W "manager worker" -- "${cur##*=}" ) ) + return + ;; + esac + + case "$prev" in + --filter|-f) + COMPREPLY=( $( compgen -W "id label membership name role" -S = -- "$cur" ) ) + __docker_nospace + return + ;; + --format) + return + ;; + esac + + case "$cur" in + -*) + COMPREPLY=( $( compgen -W "--filter -f --format --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 "--force -f --help" -- "$cur" ) ) + ;; + *) + __docker_complete_nodes + esac +} + +_docker_node_ps() { + local key=$(__docker_map_key_of_current_option '--filter|-f') + case "$key" in + desired-state) + COMPREPLY=( $( compgen -W "accepted running shutdown" -- "${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 + ;; + --format) + return + ;; + esac + + case "$cur" in + -*) + COMPREPLY=( $( compgen -W "--filter -f --format --help --no-resolve --no-trunc --quiet -q" -- "$cur" ) ) + ;; + *) + __docker_complete_nodes --add self + ;; + esac +} + +_docker_node_update() { + case "$prev" in + --availability) + COMPREPLY=( $( compgen -W "active drain pause" -- "$cur" ) ) + return + ;; + --role) + COMPREPLY=( $( compgen -W "manager worker" -- "$cur" ) ) + return + ;; + --label-add|--label-rm) + return + ;; + esac + + case "$cur" in + -*) + COMPREPLY=( $( compgen -W "--availability --help --label-add --label-rm --role" -- "$cur" ) ) + ;; + *) + local counter=$(__docker_pos_first_nonflag '--availability|--label-add|--label-rm|--role') + if [ "$cword" -eq "$counter" ]; then + __docker_complete_nodes + fi + ;; + esac +} + +_docker_pause() { + _docker_container_pause +} + +_docker_plugin() { + local subcommands=" + create + disable + enable + inspect + install + ls + push + rm + set + upgrade + " + local aliases=" + list + remove + " + __docker_subcommands "$subcommands $aliases" && return + + case "$cur" in + -*) + COMPREPLY=( $( compgen -W "--help" -- "$cur" ) ) + ;; + *) + COMPREPLY=( $( compgen -W "$subcommands" -- "$cur" ) ) + ;; + esac +} + +_docker_plugin_create() { + case "$cur" in + -*) + COMPREPLY=( $( compgen -W "--compress --help" -- "$cur" ) ) + ;; + *) + local counter=$(__docker_pos_first_nonflag) + if [ "$cword" -eq "$counter" ]; then + # reponame + return + elif [ "$cword" -eq "$((counter + 1))" ]; then + _filedir -d + fi + ;; + esac +} + +_docker_plugin_disable() { + case "$cur" in + -*) + COMPREPLY=( $( compgen -W "--force -f --help" -- "$cur" ) ) + ;; + *) + local counter=$(__docker_pos_first_nonflag) + if [ "$cword" -eq "$counter" ]; then + __docker_complete_plugins_installed --filter enabled=true + fi + ;; + esac +} + +_docker_plugin_enable() { + case "$prev" in + --timeout) + return + ;; + esac + + case "$cur" in + -*) + COMPREPLY=( $( compgen -W "--help --timeout" -- "$cur" ) ) + ;; + *) + local counter=$(__docker_pos_first_nonflag '--timeout') + if [ "$cword" -eq "$counter" ]; then + __docker_complete_plugins_installed --filter enabled=false + fi + ;; + esac +} + +_docker_plugin_inspect() { + case "$prev" in + --format|f) + return + ;; + esac + + case "$cur" in + -*) + COMPREPLY=( $( compgen -W "--format -f --help" -- "$cur" ) ) + ;; + *) + __docker_complete_plugins_installed + ;; + esac +} + +_docker_plugin_install() { + case "$prev" in + --alias) + return + ;; + esac + + case "$cur" in + -*) + COMPREPLY=( $( compgen -W "--alias --disable --disable-content-trust=false --grant-all-permissions --help" -- "$cur" ) ) + ;; + esac +} + +_docker_plugin_list() { + _docker_plugin_ls +} + +_docker_plugin_ls() { + local key=$(__docker_map_key_of_current_option '--filter|-f') + case "$key" in + capability) + COMPREPLY=( $( compgen -W "authz ipamdriver logdriver metricscollector networkdriver volumedriver" -- "${cur##*=}" ) ) + return + ;; + enabled) + COMPREPLY=( $( compgen -W "false true" -- "${cur##*=}" ) ) + return + ;; + esac + + case "$prev" in + --filter|-f) + COMPREPLY=( $( compgen -S = -W "capability enabled" -- "$cur" ) ) + __docker_nospace + return + ;; + --format) + return + ;; + esac + + case "$cur" in + -*) + COMPREPLY=( $( compgen -W "--filter -f --format --help --no-trunc --quiet -q" -- "$cur" ) ) + ;; + esac +} + +_docker_plugin_push() { + case "$cur" in + -*) + COMPREPLY=( $( compgen -W "--help" -- "$cur" ) ) + ;; + *) + local counter=$(__docker_pos_first_nonflag) + if [ "$cword" -eq "$counter" ]; then + __docker_complete_plugins_installed + fi + ;; + esac +} + +_docker_plugin_remove() { + _docker_plugin_rm +} + +_docker_plugin_rm() { + case "$cur" in + -*) + COMPREPLY=( $( compgen -W "--force -f --help" -- "$cur" ) ) + ;; + *) + __docker_complete_plugins_installed + ;; + esac +} + +_docker_plugin_set() { + case "$cur" in + -*) + COMPREPLY=( $( compgen -W "--help" -- "$cur" ) ) + ;; + *) + local counter=$(__docker_pos_first_nonflag) + if [ "$cword" -eq "$counter" ]; then + __docker_complete_plugins_installed + fi + ;; + esac +} + +_docker_plugin_upgrade() { + case "$cur" in + -*) + COMPREPLY=( $( compgen -W "--disable-content-trust --grant-all-permissions --help --skip-remote-check" -- "$cur" ) ) + ;; + *) + local counter=$(__docker_pos_first_nonflag) + if [ "$cword" -eq "$counter" ]; then + __docker_complete_plugins_installed + __ltrim_colon_completions "$cur" + elif [ "$cword" -eq "$((counter + 1))" ]; then + local plugin_images="$(__docker_plugins_installed)" + COMPREPLY=( $(compgen -S : -W "${plugin_images%:*}" -- "$cur") ) + __docker_nospace + fi + ;; + esac +} + + +_docker_port() { + _docker_container_port +} + +_docker_ps() { + _docker_container_ls +} + +_docker_pull() { + _docker_image_pull +} + +_docker_push() { + _docker_image_push +} + +_docker_rename() { + _docker_container_rename +} + +_docker_restart() { + _docker_container_restart +} + +_docker_rm() { + _docker_container_rm +} + +_docker_rmi() { + _docker_image_rm +} + +_docker_run() { + _docker_container_run +} + +_docker_save() { + _docker_image_save +} + + +_docker_secret() { + local subcommands=" + create + inspect + ls + rm + " + local aliases=" + list + remove + " + __docker_subcommands "$subcommands $aliases" && return + + case "$cur" in + -*) + COMPREPLY=( $( compgen -W "--help" -- "$cur" ) ) + ;; + *) + COMPREPLY=( $( compgen -W "$subcommands" -- "$cur" ) ) + ;; + esac +} + +_docker_secret_create() { + case "$prev" in + --driver|-d|--label|-l) + return + ;; + esac + + case "$cur" in + -*) + COMPREPLY=( $( compgen -W "--driver -d --help --label -l" -- "$cur" ) ) + ;; + *) + local counter=$(__docker_pos_first_nonflag '--driver|-d|--label|-l') + if [ "$cword" -eq "$((counter + 1))" ]; then + _filedir + fi + ;; + esac +} + +_docker_secret_inspect() { + case "$prev" in + --format|-f) + return + ;; + esac + + case "$cur" in + -*) + COMPREPLY=( $( compgen -W "--format -f --help --pretty" -- "$cur" ) ) + ;; + *) + __docker_complete_secrets + ;; + esac +} + +_docker_secret_list() { + _docker_secret_ls +} + +_docker_secret_ls() { + local key=$(__docker_map_key_of_current_option '--filter|-f') + case "$key" in + id) + __docker_complete_secrets --cur "${cur##*=}" --id + return + ;; + name) + __docker_complete_secrets --cur "${cur##*=}" --name + return + ;; + esac + + case "$prev" in + --filter|-f) + COMPREPLY=( $( compgen -S = -W "id label name" -- "$cur" ) ) + __docker_nospace + return + ;; + --format) + return + ;; + esac + + case "$cur" in + -*) + COMPREPLY=( $( compgen -W "--format --filter -f --help --quiet -q" -- "$cur" ) ) + ;; + esac +} + +_docker_secret_remove() { + _docker_secret_rm +} + +_docker_secret_rm() { + case "$cur" in + -*) + COMPREPLY=( $( compgen -W "--help" -- "$cur" ) ) + ;; + *) + __docker_complete_secrets + ;; + esac +} + + + +_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 + --filter|-f) + COMPREPLY=( $( compgen -S = -W "is-automated is-official stars" -- "$cur" ) ) + __docker_nospace + return + ;; + --format|--limit) + return + ;; + esac + + case "$cur" in + -*) + COMPREPLY=( $( compgen -W "--filter -f --format --help --limit --no-trunc" -- "$cur" ) ) + ;; + esac +} + + +_docker_stack() { + local subcommands=" + deploy + ls + ps + rm + services + " + local aliases=" + down + list + remove + up + " + __docker_subcommands "$subcommands $aliases" && return + + case "$cur" in + -*) + COMPREPLY=( $( compgen -W "--help" -- "$cur" ) ) + ;; + *) + COMPREPLY=( $( compgen -W "$subcommands" -- "$cur" ) ) + ;; + esac +} + +_docker_stack_deploy() { + case "$prev" in + --bundle-file) + if __docker_daemon_is_experimental ; then + _filedir dab + return + fi + ;; + --compose-file|-c) + _filedir yml + return + ;; + --resolve-image) + COMPREPLY=( $( compgen -W "always changed never" -- "$cur" ) ) + return + ;; + esac + + case "$cur" in + -*) + local options="--compose-file -c --help --prune --resolve-image --with-registry-auth" + __docker_daemon_is_experimental && options+=" --bundle-file" + COMPREPLY=( $( compgen -W "$options" -- "$cur" ) ) + ;; + *) + local counter=$(__docker_pos_first_nonflag '--bundle-file|--compose-file|-c|--resolve-image') + if [ "$cword" -eq "$counter" ]; then + __docker_complete_stacks + fi + ;; + esac +} + +_docker_stack_down() { + _docker_stack_rm +} + +_docker_stack_list() { + _docker_stack_ls +} + +_docker_stack_ls() { + case "$prev" in + --format) + return + ;; + esac + + case "$cur" in + -*) + COMPREPLY=( $( compgen -W "--format --help" -- "$cur" ) ) + ;; + esac +} + +_docker_stack_ps() { + local key=$(__docker_map_key_of_current_option '--filter|-f') + case "$key" in + desired-state) + COMPREPLY=( $( compgen -W "accepted running shutdown" -- "${cur##*=}" ) ) + return + ;; + id) + __docker_complete_stacks --cur "${cur##*=}" --id + return + ;; + name) + __docker_complete_stacks --cur "${cur##*=}" --name + return + ;; + esac + + case "$prev" in + --filter|-f) + COMPREPLY=( $( compgen -S = -W "id name desired-state" -- "$cur" ) ) + __docker_nospace + return + ;; + --format) + return + ;; + esac + + case "$cur" in + -*) + COMPREPLY=( $( compgen -W "--filter -f --format --help --no-resolve --no-trunc --quiet -q" -- "$cur" ) ) + ;; + *) + local counter=$(__docker_pos_first_nonflag '--filter|-f') + if [ "$cword" -eq "$counter" ]; then + __docker_complete_stacks + fi + ;; + esac +} + +_docker_stack_remove() { + _docker_stack_rm +} + +_docker_stack_rm() { + case "$cur" in + -*) + COMPREPLY=( $( compgen -W "--help" -- "$cur" ) ) + ;; + *) + __docker_complete_stacks + ;; + esac +} + +_docker_stack_services() { + local key=$(__docker_map_key_of_current_option '--filter|-f') + case "$key" in + id) + __docker_complete_services --cur "${cur##*=}" --id + return + ;; + label) + return + ;; + name) + __docker_complete_services --cur "${cur##*=}" --name + return + ;; + esac + + case "$prev" in + --filter|-f) + COMPREPLY=( $( compgen -S = -W "id label name" -- "$cur" ) ) + __docker_nospace + return + ;; + --format) + return + ;; + esac + + case "$cur" in + -*) + COMPREPLY=( $( compgen -W "--filter -f --format --help --quiet -q" -- "$cur" ) ) + ;; + *) + local counter=$(__docker_pos_first_nonflag '--filter|-f|--format') + if [ "$cword" -eq "$counter" ]; then + __docker_complete_stacks + fi + ;; + esac +} + +_docker_stack_up() { + _docker_stack_deploy +} + + +_docker_start() { + _docker_container_start +} + +_docker_stats() { + _docker_container_stats +} + +_docker_stop() { + _docker_container_stop +} + + +_docker_system() { + local subcommands=" + df + events + info + prune + " + __docker_subcommands "$subcommands" && return + + case "$cur" in + -*) + COMPREPLY=( $( compgen -W "--help" -- "$cur" ) ) + ;; + *) + COMPREPLY=( $( compgen -W "$subcommands" -- "$cur" ) ) + ;; + esac +} + +_docker_system_df() { + case "$prev" in + --format) + return + ;; + esac + + case "$cur" in + -*) + COMPREPLY=( $( compgen -W "--format --help --verbose -v" -- "$cur" ) ) + ;; + esac +} + +_docker_system_events() { + local key=$(__docker_map_key_of_current_option '-f|--filter') + case "$key" in + container) + __docker_complete_containers_all --cur "${cur##*=}" + return + ;; + 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 + disable + disconnect + enable + exec_create + exec_detach + exec_start + export + health_status + import + install + kill + load + mount + oom + pause + pull + push + reload + remove + rename + resize + restart + save + start + stop + tag + top + unmount + unpause + untag + update + " -- "${cur##*=}" ) ) + return + ;; + image) + cur="${cur##*=}" + __docker_complete_images + return + ;; + network) + __docker_complete_networks --cur "${cur##*=}" + return + ;; + type) + COMPREPLY=( $( compgen -W "container daemon image network plugin volume" -- "${cur##*=}" ) ) + return + ;; + volume) + __docker_complete_volumes --cur "${cur##*=}" + 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 + -*) + COMPREPLY=( $( compgen -W "--filter -f --help --since --until --format" -- "$cur" ) ) + ;; + esac +} + +_docker_system_info() { + case "$prev" in + --format|-f) + return + ;; + esac + + case "$cur" in + -*) + COMPREPLY=( $( compgen -W "--format -f --help" -- "$cur" ) ) + ;; + esac +} + +_docker_system_prune() { + case "$prev" in + --filter) + COMPREPLY=( $( compgen -W "label label! until" -S = -- "$cur" ) ) + __docker_nospace + return + ;; + esac + + case "$cur" in + -*) + COMPREPLY=( $( compgen -W "--all -a --force -f --filter --help --volumes" -- "$cur" ) ) + ;; + esac +} + + +_docker_tag() { + _docker_image_tag +} + + +_docker_trust() { + local subcommands=" + revoke + sign + view + " + __docker_subcommands "$subcommands" && return + + case "$cur" in + -*) + COMPREPLY=( $( compgen -W "--help" -- "$cur" ) ) + ;; + *) + COMPREPLY=( $( compgen -W "$subcommands" -- "$cur" ) ) + ;; + esac +} + +_docker_trust_revoke() { + case "$cur" in + -*) + COMPREPLY=( $( compgen -W "--help --yes -y" -- "$cur" ) ) + ;; + *) + local counter=$(__docker_pos_first_nonflag) + if [ "$cword" -eq "$counter" ]; then + __docker_complete_images + fi + ;; + esac +} + +_docker_trust_sign() { + case "$cur" in + -*) + COMPREPLY=( $( compgen -W "--help --local" -- "$cur" ) ) + ;; + *) + local counter=$(__docker_pos_first_nonflag) + if [ "$cword" -eq "$counter" ]; then + __docker_complete_images + fi + ;; + esac +} + +_docker_trust_view() { + case "$cur" in + -*) + COMPREPLY=( $( compgen -W "--help" -- "$cur" ) ) + ;; + *) + local counter=$(__docker_pos_first_nonflag) + if [ "$cword" -eq "$counter" ]; then + __docker_complete_images + fi + ;; + esac +} + + +_docker_unpause() { + _docker_container_unpause +} + +_docker_update() { + _docker_container_update +} + +_docker_top() { + _docker_container_top +} + +_docker_version() { + case "$prev" in + --format|-f) + return + ;; + esac + + case "$cur" in + -*) + COMPREPLY=( $( compgen -W "--format -f --help" -- "$cur" ) ) + ;; + esac +} + _docker_volume_create() { case "$prev" in --driver|-d) - __docker_complete_plugins Volume + __docker_complete_plugins_bundled --type Volume return ;; - --label|--name|--opt|-o) + --label|--opt|-o) return ;; esac case "$cur" in -*) - COMPREPLY=( $( compgen -W "--driver -d --help --label --name --opt -o" -- "$cur" ) ) + COMPREPLY=( $( compgen -W "--driver -d --help --label --opt -o" -- "$cur" ) ) ;; esac } @@ -2763,6 +4833,10 @@ _docker_volume_inspect() { esac } +_docker_volume_list() { + _docker_volume_ls +} + _docker_volume_ls() { local key=$(__docker_map_key_of_current_option '--filter|-f') case "$key" in @@ -2771,20 +4845,37 @@ _docker_volume_ls() { return ;; driver) - cur=${cur##*=} - __docker_complete_plugins Volume + __docker_complete_plugins_bundled --cur "${cur##*=}" --type Volume return ;; name) - cur=${cur##*=} - __docker_complete_volumes + __docker_complete_volumes --cur "${cur##*=}" return ;; esac case "$prev" in --filter|-f) - COMPREPLY=( $( compgen -S = -W "dangling driver name" -- "$cur" ) ) + COMPREPLY=( $( compgen -S = -W "dangling driver label name" -- "$cur" ) ) + __docker_nospace + return + ;; + --format) + return + ;; + esac + + case "$cur" in + -*) + COMPREPLY=( $( compgen -W "--filter -f --format --help --quiet -q" -- "$cur" ) ) + ;; + esac +} + +_docker_volume_prune() { + case "$prev" in + --filter) + COMPREPLY=( $( compgen -W "label label!" -S = -- "$cur" ) ) __docker_nospace return ;; @@ -2792,15 +4883,19 @@ _docker_volume_ls() { case "$cur" in -*) - COMPREPLY=( $( compgen -W "--filter -f --help --quiet -q" -- "$cur" ) ) + COMPREPLY=( $( compgen -W "--filter --force -f --help" -- "$cur" ) ) ;; esac } +_docker_volume_remove() { + _docker_volume_rm +} + _docker_volume_rm() { case "$cur" in -*) - COMPREPLY=( $( compgen -W "--help" -- "$cur" ) ) + COMPREPLY=( $( compgen -W "--force -f --help" -- "$cur" ) ) ;; *) __docker_complete_volumes @@ -2813,9 +4908,14 @@ _docker_volume() { create inspect ls + prune rm " - __docker_subcommands "$subcommands" && return + local aliases=" + list + remove + " + __docker_subcommands "$subcommands $aliases" && return case "$cur" in -*) @@ -2828,27 +4928,42 @@ _docker_volume() { } _docker_wait() { - case "$cur" in - -*) - COMPREPLY=( $( compgen -W "--help" -- "$cur" ) ) - ;; - *) - __docker_complete_containers_all - ;; - esac + _docker_container_wait } _docker() { local previous_extglob_setting=$(shopt -p extglob) shopt -s extglob - local commands=( - attach + local management_commands=( + config + container + image + network + node + plugin + secret + service + stack + swarm + system + volume + ) + + local top_level_commands=( build + login + logout + run + search + version + ) + + local legacy_commands=( + attach commit cp create - daemon diff events exec @@ -2860,11 +4975,7 @@ _docker() { inspect kill load - login - logout logs - network - node pause port ps @@ -2874,23 +4985,26 @@ _docker() { restart rm rmi - run save - search - service start stats stop - swarm tag top unpause update - version - volume wait ) + local experimental_commands=( + checkpoint + deploy + trust + ) + + local commands=(${management_commands[*]} ${top_level_commands[*]}) + [ -z "$DOCKER_HIDE_LEGACY_COMMANDS" ] && commands+=(${legacy_commands[*]}) + # These options are valid as global options for all client commands # and valid as command options for `docker daemon` local global_boolean_options=" @@ -2907,7 +5021,7 @@ _docker() { --tlskey " - local host config + local host config daemon_os COMPREPLY=() local cur prev words cword @@ -2915,7 +5029,7 @@ _docker() { local command='docker' command_pos=0 subcommand_pos local counter=1 - while [ $counter -lt $cword ]; do + while [ "$counter" -lt "$cword" ]; do case "${words[$counter]}" in # save host so that completion can use custom daemon --host|-H) @@ -2952,7 +5066,7 @@ _docker() { command_pos=0 fi - local completions_func=_docker_${command} + local completions_func=_docker_${command//-/_} declare -F $completions_func >/dev/null && $completions_func eval "$previous_extglob_setting" @@ -2962,4 +5076,4 @@ _docker() { eval "$__docker_previous_extglob_setting" unset __docker_previous_extglob_setting -complete -F _docker docker dockerd +complete -F _docker docker docker.exe dockerd dockerd.exe diff --git a/completion/available/invoke.completion.bash b/completion/available/invoke.completion.bash new file mode 100644 index 00000000..f062bcab --- /dev/null +++ b/completion/available/invoke.completion.bash @@ -0,0 +1,31 @@ +# Invoke (pyinvoke.org) tab-completion script to be sourced with Bash shell. +# https://github.com/pyinvoke/invoke/blob/master/completion/bash + +_complete_invoke() { + local candidates + + # COMP_WORDS contains the entire command string up til now (including + # program name). + # We hand it to Invoke so it can figure out the current context: spit back + # core options, task names, the current task's options, or some combo. + candidates=`invoke --complete -- ${COMP_WORDS[*]}` + + # `compgen -W` takes list of valid options & a partial word & spits back + # possible matches. Necessary for any partial word completions (vs + # completions performed when no partial words are present). + # + # $2 is the current word or token being tabbed on, either empty string or a + # partial word, and thus wants to be compgen'd to arrive at some subset of + # our candidate list which actually matches. + # + # COMPREPLY is the list of valid completions handed back to `complete`. + COMPREPLY=( $(compgen -W "${candidates}" -- $2) ) +} + + +# Tell shell builtin to use the above for completing 'inv'/'invoke': +# * -F: use given function name to generate completions. +# * -o default: when function generates no results, use filenames. +# * positional args: program names to complete for. +complete -F _complete_invoke -o default invoke inv + diff --git a/completion/available/minikube.completion.bash b/completion/available/minikube.completion.bash new file mode 100644 index 00000000..f1d19b87 --- /dev/null +++ b/completion/available/minikube.completion.bash @@ -0,0 +1,8 @@ +#!/usr/bin/env bash + +# minikube (Local Kubernetes) completion + +if command -v minikube &>/dev/null +then + eval "$(minikube completion bash)" +fi diff --git a/completion/available/pipenv.completion.bash b/completion/available/pipenv.completion.bash index 95ae87b7..339509f2 100644 --- a/completion/available/pipenv.completion.bash +++ b/completion/available/pipenv.completion.bash @@ -1 +1 @@ -[[ -x "$(which pipenv)" ]] && source <(env _PIPENV_COMPLETE="source-bash" pipenv) +[[ -x "$(which pipenv)" ]] && eval "$(pipenv --completion)" diff --git a/completion/available/sdkman.completion.bash b/completion/available/sdkman.completion.bash index f5af6c6a..b4d62da1 100644 --- a/completion/available/sdkman.completion.bash +++ b/completion/available/sdkman.completion.bash @@ -27,10 +27,14 @@ _sdkman_complete() esac elif [ $COMP_CWORD -eq 3 ]; then case "${COMP_WORDS[COMP_CWORD-2]}" in - "install" | "uninstall" | "rm" | "use" | "default" ) + "uninstall" | "rm" | "use" | "default" ) _sdkman_candidate_versions ${COMP_WORDS[COMP_CWORD-1]} COMPREPLY=( $(compgen -W "$CANDIDATE_VERSIONS" -- ${COMP_WORDS[COMP_CWORD]}) ) ;; + "install") + _sdkman_candidate_not_installed_versions ${COMP_WORDS[COMP_CWORD-1]} + COMPREPLY=( $(compgen -W "$CANDIDATE_VERSIONS" -- ${COMP_WORDS[COMP_CWORD]}) ) + ;; *) ;; esac @@ -51,6 +55,14 @@ _sdkman_candidate_versions(){ } +_sdkman_candidate_not_installed_versions(){ + CANDIDATE_LOCAL_VERSIONS=$(__sdkman_cleanup_local_versions $1) + if [ "$SDKMAN_OFFLINE_MODE" = "false" ]; then + CANDIDATE_ONLINE_VERSIONS="$(__sdkman_list_versions $1 | grep " " | grep "\." | cut -c 6-)" + CANDIDATE_VERSIONS="$(echo $CANDIDATE_ONLINE_VERSIONS $CANDIDATE_LOCAL_VERSIONS | tr ' ' '\n' | sort | uniq -u) " + fi +} + __sdkman_cleanup_local_versions(){ __sdkman_build_version_csv $1 | tr ',' ' ' diff --git a/completion/available/ssh.completion.bash b/completion/available/ssh.completion.bash index b54202bd..d5cd6e61 100644 --- a/completion/available/ssh.completion.bash +++ b/completion/available/ssh.completion.bash @@ -11,11 +11,16 @@ _sshcomplete() { local OPTIONS=" -- ${CURRENT_PROMPT}" fi - - # parse all defined hosts from .ssh/config - if [ -r "$HOME/.ssh/config" ]; then - COMPREPLY=($(compgen -W "$(grep -i ^Host "$HOME/.ssh/config" | awk '{for (i=2; i<=NF; i++) print $i}' )" ${OPTIONS}) ) - fi + # parse all defined hosts from .ssh/config and files included there + for fl in "$HOME/.ssh/config" \ + $(grep "^\s*Include" "$HOME/.ssh/config" | + awk '{for (i=2; i<=NF; i++) print $i}' | + sed "s|^~/|$HOME/|") + do + if [ -r "$fl" ]; then + COMPREPLY=( ${COMPREPLY[@]} $(compgen -W "$(grep -i ^Host "$fl" |grep -v '[*!]' | awk '{for (i=2; i<=NF; i++) print $i}' )" ${OPTIONS}) ) + fi + done # parse all hosts found in .ssh/known_hosts if [ -r "$HOME/.ssh/known_hosts" ]; then diff --git a/completion/available/system.completion.bash b/completion/available/system.completion.bash index b044627c..f9a3b29f 100644 --- a/completion/available/system.completion.bash +++ b/completion/available/system.completion.bash @@ -20,8 +20,8 @@ if [ $(uname) = "Darwin" ] && command -v brew &>/dev/null ; then . "$BREW_PREFIX"/etc/bash_completion fi - # homebrew/versions/bash-completion2 (required for projects.completion.bash) is installed to this path - if [ -f "$BREW_PREFIX"/share/bash-completion/bash_completion ]; then + # homebrew/versions/bash-completion2 (required for projects.completion.bash) is installed to this path + if [ "${BASH_VERSINFO}" -ge 4 ] && [ -f "$BREW_PREFIX"/share/bash-completion/bash_completion ]; then . "$BREW_PREFIX"/share/bash-completion/bash_completion fi fi diff --git a/completion/available/terraform.completion.bash b/completion/available/terraform.completion.bash index 807a709a..201b7267 100644 --- a/completion/available/terraform.completion.bash +++ b/completion/available/terraform.completion.bash @@ -1,26 +1,65 @@ #!/usr/bin/env bash -# Bash Terraform completion +# +# Bash completion for the terraform command +# +# Copyright (C) 2018 Vangelis Tasoulas +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License +# as published by the Free Software Foundation; either version 2 +# of the License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. _terraform() { - local cmds cur colonprefixes - cmds="apply destroy fmt get graph import init \ - output plan push refresh remote show taint \ - untaint validate version state" + local cur prev words cword opts + _get_comp_words_by_ref -n : cur prev words cword + COMPREPLY=() + opts="" - COMPREPLY=() - cur=${COMP_WORDS[COMP_CWORD]} - # Work-around bash_completion issue where bash interprets a colon - # as a separator. - # Work-around borrowed from the darcs work-around for the same - # issue. - colonprefixes=${cur%"${cur##*:}"} - COMPREPLY=( $(compgen -W '$cmds' -- $cur)) - local i=${#COMPREPLY[*]} - while [ $((--i)) -ge 0 ]; do - COMPREPLY[$i]=${COMPREPLY[$i]#"$colonprefixes"} - done + if [[ ${cword} -eq 1 ]] ; then + + # Options that do not start with a hyphen, are always starting with four spaces. + opts="$(terraform --help | grep -E '^\s\s\s\s\S' | awk '{print $1}')" + opts="${opts} --help --version" + + elif [[ ${cword} -gt 1 ]] ; then + + if [[ ${cword} -eq 2 && ${prev} == '--help' ]] ; then + + opts="$(terraform --help | grep -E '^\s\s\s\s\S' | awk '{print $1}')" + + elif [[ ${words[1]} != "--help" && ${words[1]} != "--version" && ${words[1]} != "version" ]] ; then + + # Some commands accept hyphened parameters, ... + opts="$(terraform --help "${words[1]}" | grep -E '^\s+-' | awk '{print $1}' | awk -F '=' '{ if ($0 ~ /=/) {print $1"="} else {print $1} }')" + # but some other commands accept non-hyphened parameters. + opts="${opts} $(terraform --help "${words[1]}" | grep -E '^\s\s\s\s\S' | awk '{print $1}')" + # All of the commands accept the --help parameter which is not listed + # by the 'terraform --help + opts="${opts} --help" + + fi + fi + + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + + if [[ ${#COMPREPLY[*]} -eq 1 ]] ; then + if [[ ${COMPREPLY[0]} == *= ]] ; then + # When only one completion is left, check if there is an equal sign. + # If an equal sign, then add no space after the autocompleted word. + compopt -o nospace + fi + fi + return 0 +} - return 0 -} && complete -F _terraform terraform diff --git a/completion/available/virsh.completion.bash b/completion/available/virsh.completion.bash new file mode 100644 index 00000000..14f03d73 --- /dev/null +++ b/completion/available/virsh.completion.bash @@ -0,0 +1,148 @@ +#!/usr/bin/env bash +# bash completion for virsh - main CLI of libvirt + +# This script provides bash completion for virsh, +# borrowed from https://github.com/LuyaoHuang/virsh-bash-completion + + + +_contain_cmd() +{ + local e f + local array1=($1) array2=($2) + + for e in "${array1[@]}" + do + for f in "${array2[@]}" + do + if [[ "$e" == "$f" ]] ; then + echo $e + return + fi + done + done + + echo "notfound" + return +} + +_virsh_list_networks() +{ + local flag_all=$1 flags + + if [ "$flag_all" -eq 1 ]; then + flags="--all" + else + flags="--inactive" + fi + virsh -q net-list $flags | cut -d\ -f2 | awk '{print $1}' +} + +_virsh_list_domains() +{ + local flag_all=$1 flags + + if [ "$flag_all" -eq 1 ]; then + flags="--all" + else + flags="--inactive" + fi + virsh -q list $flags | cut -d\ -f7 | awk '{print $1}' +} + +_virsh_list_pools() +{ + local flag_all=$1 flags + + if [ "$flag_all" -eq 1 ]; then + flags="--all" + else + flags="--inactive" + fi + virsh -q pool-list $flags | cut -d\ -f2 | awk '{print $1}' +} + +_virsh_list_ifaces() +{ + local flag_all=$1 flags + + if [ "$flag_all" -eq 1 ]; then + flags="--all" + else + flags="--inactive" + fi + virsh -q iface-list $flags | cut -d\ -f2 | awk '{print $1}' +} + +_virsh_list_nwfilters() +{ + + virsh -q nwfilter-list | cut -d\ -f4 | awk '{print $1}' +} + +_virsh() +{ + local cur prev cmds doms options nets pools cmds_help + local flag_all=1 array ret a b ifaces nwfilters files + +# not must use bash-completion now :) +# _init_completion -s || return + COMPREPLY=() + cur="${COMP_WORDS[COMP_CWORD]}" + prev="${COMP_WORDS[COMP_CWORD-1]}" + + cmds=$( echo "$(virsh -h| grep '^ ' | cut -d\ -f5)" \ + "$(virsh -h| grep '\--' | cut -d\ -f7 | cut -d= -f1)") + cmds_help=$(virsh help| grep '^ ' | cut -d\ -f5) + case "$prev" in + --domain) + doms=$(_virsh_list_domains "$flag_all") + COMPREPLY=( $(compgen -W "$doms" -- "$cur") ) + return 0 + ;; + --network) + nets=$(_virsh_list_networks "$flag_all") + COMPREPLY=( $(compgen -W "$nets" -- "$cur") ) + return 0 + ;; + --pool) + pools=$(_virsh_list_pools "$flag_all") + COMPREPLY=( $(compgen -W "$pools" -- "$cur") ) + return 0 + ;; + --interface) + ifaces=$(_virsh_list_ifaces "$flag_all") + COMPREPLY=( $(compgen -W "$ifaces" -- "$cur") ) + return 0 + ;; + --nwfilter) + nwfilters=$(_virsh_list_nwfilters) + COMPREPLY=( $(compgen -W "$nwfilters" -- "$cur") ) + return 0 + ;; + --file|--xml) + files=$(ls) + COMPREPLY=( $(compgen -W "$files" -- "$cur") ) + return 0 + ;; + esac + + array=$(IFS=$'\n'; echo "${COMP_WORDS[*]}") + ret=$(_contain_cmd "$array" "$cmds_help") + + if [[ "$ret" != "notfound" && "$ret" != "$cur" ]]; then + a=$(virsh help "$ret" |grep '^ --'|cut -d\ -f5) + b=$(virsh help "$ret" |grep '^ \[--'|cut -d\ -f5|cut -d[ -f2|cut -d] -f1) + options=$( echo $a $b ) + COMPREPLY=( $(compgen -W "$options" -- "$cur") ) + return 0 + fi + + case "$cur" in + *) + COMPREPLY=( $(compgen -W "$cmds" -- "$cur") ) + return 0 + ;; + esac +} && +complete -o default -F _virsh virsh diff --git a/install.sh b/install.sh index 7fa8cacf..c0848cdb 100755 --- a/install.sh +++ b/install.sh @@ -167,7 +167,7 @@ then done else echo "" - echo -e "\033[0;32mEnabling sane defaults\033[0m" + echo -e "\033[0;32mEnabling reasonable defaults\033[0m" _enable-completion bash-it _enable-completion system _enable-plugin base diff --git a/lib/helpers.bash b/lib/helpers.bash index 81f7280b..a2c0d3aa 100644 --- a/lib/helpers.bash +++ b/lib/helpers.bash @@ -61,7 +61,7 @@ function reload_plugins() { bash-it () { about 'Bash-it help and maintenance' - param '1: verb [one of: help | show | enable | disable | migrate | update | search | version ] ' + param '1: verb [one of: help | show | enable | disable | migrate | update | search | version | reload ] ' param '2: component type [one of: alias(es) | completion(s) | plugin(s) ] or search term(s)' param '3: specific component [optional]' example '$ bash-it show plugins' @@ -72,32 +72,35 @@ bash-it () example '$ bash-it update' example '$ bash-it search ruby [[-]rake]... [--enable | --disable]' example '$ bash-it version' + example '$ bash-it reload' typeset verb=${1:-} shift typeset component=${1:-} shift typeset func case $verb in - show) - func=_bash-it-$component;; - enable) - func=_enable-$component;; - disable) - func=_disable-$component;; - help) - func=_help-$component;; - search) - _bash-it-search $component "$@" - return;; - update) - func=_bash-it_update;; - migrate) - func=_bash-it-migrate;; - version) - func=_bash-it-version;; - *) - reference bash-it - return;; + show) + func=_bash-it-$component;; + enable) + func=_enable-$component;; + disable) + func=_disable-$component;; + help) + func=_help-$component;; + search) + _bash-it-search $component "$@" + return;; + update) + func=_bash-it_update;; + migrate) + func=_bash-it-migrate;; + version) + func=_bash-it-version;; + reload) + func=_bash-it-reload;; + *) + reference bash-it + return;; esac # pluralize component if necessary @@ -184,7 +187,7 @@ _bash-it_update() { _bash-it-migrate echo "" echo "All done, enjoy!" - reload + bash-it reload else echo "Error updating Bash-it, please, check if your Bash-it installation folder (${BASH_IT}) is clean." fi @@ -248,6 +251,25 @@ _bash-it-version() { echo "Current git SHA: $BASH_IT_GIT_VERSION_INFO" echo "$BASH_IT_GIT_URL/commit/$BASH_IT_GIT_SHA" + echo "Compare to latest: $BASH_IT_GIT_URL/compare/$BASH_IT_GIT_SHA...master" + + cd - &> /dev/null || return +} + +_bash-it-reload() { + _about 'reloads a profile file' + _group 'lib' + + cd "${BASH_IT}" || return + + case $OSTYPE in + darwin*) + source ~/.bash_profile + ;; + *) + source ~/.bashrc + ;; + esac cd - &> /dev/null || return } diff --git a/plugins/available/alias-completion.plugin.bash b/plugins/available/alias-completion.plugin.bash index b14131b4..e1c4ade7 100644 --- a/plugins/available/alias-completion.plugin.bash +++ b/plugins/available/alias-completion.plugin.bash @@ -29,7 +29,7 @@ function alias_completion { (( ${#completions[@]} == 0 )) && return 0 # create temporary file for wrapper functions and completions - local tmp_file; tmp_file="$(mktemp -t "${namespace}-${RANDOM}XXX.tmp")" || return 1 + local tmp_file; tmp_file="$(mktemp -t "${namespace}-${RANDOM}XXXXXX")" || return 1 local completion_loader; completion_loader="$(complete -p -D 2>/dev/null | sed -Ene 's/.* -F ([^ ]*).*/\1/p')" @@ -56,7 +56,7 @@ function alias_completion { continue fi fi - local new_completion="$(complete -p "$alias_cmd")" + local new_completion="$(complete -p "$alias_cmd" 2>/dev/null)" # create a wrapper inserting the alias arguments if any if [[ -n $alias_args ]]; then @@ -77,8 +77,10 @@ function alias_completion { fi # replace completion trigger by alias - new_completion="${new_completion% *} $alias_name" - echo "$new_completion" >> "$tmp_file" + if [[ -n $new_completion ]]; then + new_completion="${new_completion% *} $alias_name" + echo "$new_completion" >> "$tmp_file" + fi done < <(alias -p | sed -Ene "s/$alias_regex/\2 '\3' '\4'/p") source "$tmp_file" && rm -f "$tmp_file" }; alias_completion diff --git a/plugins/available/explain.plugin.bash b/plugins/available/explain.plugin.bash index d57b78e2..1fb38bdd 100644 --- a/plugins/available/explain.plugin.bash +++ b/plugins/available/explain.plugin.bash @@ -5,7 +5,7 @@ explain () { about 'explain any bash command via mankier.com manpage API' param '1: Name of the command to explain' example '$ explain # interactive mode. Type commands to explain in REPL' - example '$ explain 'cmd -o | ...' # one quoted command to explain it.' + example '$ explain '"'"'cmd -o | ...'"'"' # one quoted command to explain it.' group 'explain' if [ "$#" -eq 0 ]; then diff --git a/plugins/available/fzf.plugin.bash b/plugins/available/fzf.plugin.bash index c4fa451e..f2eddeb1 100644 --- a/plugins/available/fzf.plugin.bash +++ b/plugins/available/fzf.plugin.bash @@ -6,6 +6,10 @@ about-plugin 'load fzf, if you are using it' [ -f ~/.fzf.bash ] && source ~/.fzf.bash +if [ -z ${FZF_DEFAULT_COMMAND+x} ]; then + command -v fd &> /dev/null && export FZF_DEFAULT_COMMAND='fd --type f' +fi + fe() { about "Open the selected file in the default editor" group "fzf" @@ -18,11 +22,11 @@ fe() { [[ -n "$files" ]] && ${EDITOR:-vim} "${files[@]}" } -fd() { +fcd() { about "cd to the selected directory" group "fzf" param "1: Directory to browse, or . if omitted" - example "fd aliases" + example "fcd aliases" local dir dir=$(find ${1:-.} -path '*/\.*' -prune \ diff --git a/plugins/available/gif.plugin.bash b/plugins/available/gif.plugin.bash index 9e7e95c0..bdfa4f4b 100644 --- a/plugins/available/gif.plugin.bash +++ b/plugins/available/gif.plugin.bash @@ -33,8 +33,14 @@ function v2gif { # Parse the options local args=$(getopt -l "alert:" -l "lossy:" -l "width:" -l del,delete -l high -l tag -l "fps:" -l webm -o "a:l:w:f:dhmt" -- "$@") + if [ $? -ne 0 ]; then + echo 'Terminating...' >&2 + return 2 + fi + + eval set -- "$args" local use_gifski="" - local del_after="" + local opt_del_after="" local maxsize="" local lossiness="" local maxwidthski="" @@ -45,7 +51,6 @@ function v2gif { local fps="" local make_webm="" local alert=5000 - eval set -- "$args" while [ $# -ge 1 ]; do case "$1" in --) @@ -55,7 +60,7 @@ function v2gif { ;; -d|--del|--delete) # Delete after - del_after="true" + opt_del_after="true" shift ;; -h|--high) @@ -100,10 +105,7 @@ function v2gif { esac done - # Done Parsing, all that's left are the filenames - local movies="$*" - - if [[ -z "$movies" ]]; then + if [[ -z "$*" ]]; then echo "$(tput setaf 1)No input files given. Example: v2gif file [file...] [-w ] [-l ] < $(tput sgr 0)" return 1 fi @@ -112,14 +114,15 @@ function v2gif { [[ -z "$giftag" ]] && giftag="-default" [[ -z "$giftagopt" ]] && giftag="" - for file in $movies ; do + for file ; do local output_file="${file%.*}${giftag}.gif" + local del_after=$opt_del_after if [[ "$make_webm" ]] ; then ffmpeg -loglevel panic -i "$file" \ - -c:v libvpx -crf 4 -threads 0 -an -b:v 2M -auto-alt-ref 0 -quality best \ - "${file%.*}.webm" || return 2 + -c:v libvpx -crf 4 -threads 0 -an -b:v 2M -auto-alt-ref 0 \ + -quality best -loop 0 "${file%.*}.webm" || return 2 fi # Set FPS to match the video if possible, otherwise fallback to default. @@ -151,7 +154,8 @@ function v2gif { if [[ $alert -gt 0 ]] ; then local out_size=$(wc --bytes < "$output_file") if [[ $out_size -gt $(( alert * 1000 )) ]] ; then - echo "$(tput setaf 3)Warning: '$output_file' is $((out_size/1000))kb, keeping '$file' even if --del requested.$(tput sgr 0)" + echo "$(tput setaf 3)Warning: '$output_file' is $((out_size/1000))kb.$(tput sgr 0)" + [[ "$del_after" == "true" ]] && echo "$(tput setaf 3)Warning: Keeping '$file' even though --del requested.$(tput sgr 0)" del_after="" fi fi @@ -179,7 +183,13 @@ function any2webm() { # Parse the options local args=$(getopt -l alert -l "bandwidth:" -l "width:" -l del,delete -l tag -l "fps:" -l webm -o "a:b:w:f:dt" -- "$@") - local del_after="" + if [ $? -ne 0 ]; then + echo 'Terminating...' >&2 + return 2 + fi + + eval set -- "$args" + local opt_del_after="" local size="" local webmtagopt="" local webmtag="" @@ -187,7 +197,6 @@ function any2webm() { local fps="" local bandwidth="2M" local alert=5000 - eval set -- "$args" while [ $# -ge 1 ]; do case "$1" in --) @@ -197,7 +206,7 @@ function any2webm() { ;; -d|--del|--delete) # Delete after - del_after="true" + opt_del_after="true" shift ;; -s|--size) @@ -230,10 +239,7 @@ function any2webm() { esac done - # Done Parsing, all that's left are the filenames - local movies="$*" - - if [[ -z "$movies" ]]; then + if [[ -z "$*" ]]; then echo "$(tput setaf 1)No input files given. Example: any2webm file [file...] [-w ] < $(tput sgr 0)" return 1 fi @@ -242,21 +248,23 @@ function any2webm() { [[ -z "$webmtag" ]] && webmtag="-default" [[ -z "$webmtagopt" ]] && webmtag="" - for file in $movies ; do + for file ; do local output_file="${file%.*}${webmtag}.webm" + local del_after=$opt_del_after echo "$(tput setaf 2)Creating '$output_file' ...$(tput sgr 0)" ffmpeg -loglevel panic -i "$file" \ -c:v libvpx -crf 4 -threads 0 -an -b:v $bandwidth -auto-alt-ref 0 \ - -quality best $fps $size -pix_fmt yuva420p "$output_file" || return 2 + -quality best $fps $size -loop 0 -pix_fmt yuva420p "$output_file" || return 2 # Checking if the file is bigger than Twitter likes and warn if [[ $alert -gt 0 ]] ; then local out_size=$(wc --bytes < "$output_file") if [[ $out_size -gt $(( alert * 1000 )) ]] ; then - echo "$(tput setaf 3)Warning: '$output_file' is $((out_size/1000))kb, keeping '$file' even if --del requested.$(tput sgr 0)" + echo "$(tput setaf 3)Warning: '$output_file' is $((out_size/1000))kb.$(tput sgr 0)" + [[ "$del_after" == "true" ]] && echo "$(tput setaf 3)Warning: Keeping '$file' even though --del requested.$(tput sgr 0)" del_after="" fi fi diff --git a/plugins/available/jgitflow.plugin.bash b/plugins/available/jgitflow.plugin.bash new file mode 100644 index 00000000..83ee8a23 --- /dev/null +++ b/plugins/available/jgitflow.plugin.bash @@ -0,0 +1,47 @@ +cite about-plugin +about-plugin 'Maven jgitflow build helpers' + +function hotfix-start { + about 'helper function for starting a new hotfix' + group 'jgitflow' + + mvn jgitflow:hotfix-start ${JGITFLOW_MVN_ARGUMENTS} +} + +function hotfix-finish { + about 'helper function for finishing a hotfix' + group 'jgitflow' + + mvn jgitflow:hotfix-finish -Darguments="${JGITFLOW_MVN_ARGUMENTS}" && git push && git push origin master && git push --tags +} + +function feature-start { + about 'helper function for starting a new feature' + group 'jgitflow' + + mvn jgitflow:feature-start ${JGITFLOW_MVN_ARGUMENTS} +} + +function feature-finish { + about 'helper function for finishing a feature' + group 'jgitflow' + + mvn jgitflow:feature-finish ${JGITFLOW_MVN_ARGUMENTS} + echo -e '\033[32m----------------------------------------------------------------\033[0m' + echo -e '\033[32m===== REMEMBER TO CREATE A NEW RELEASE TO DEPLOY THIS FEATURE ====\033[0m' + echo -e '\033[32m----------------------------------------------------------------\033[0m' +} + +function release-start { + about 'helper function for starting a new release' + group 'jgitflow' + + mvn jgitflow:release-start ${JGITFLOW_MVN_ARGUMENTS} +} + +function release-finish { + about 'helper function for finishing a release' + group 'jgitflow' + + mvn jgitflow:release-finish -Darguments="${JGITFLOW_MVN_ARGUMENTS}" && git push && git push origin master && git push --tags +} diff --git a/plugins/available/jump.plugin.bash b/plugins/available/jump.plugin.bash new file mode 100755 index 00000000..bc6f85e1 --- /dev/null +++ b/plugins/available/jump.plugin.bash @@ -0,0 +1,9 @@ +cite about-plugin +about-plugin 'initialize jump (see https://github.com/gsamokovarov/jump)' + +__init_jump() { + command -v jump &> /dev/null || return + eval "$(jump shell --bind=z)" +} + +__init_jump diff --git a/plugins/available/nodenv.plugin.bash b/plugins/available/nodenv.plugin.bash new file mode 100644 index 00000000..f28e4045 --- /dev/null +++ b/plugins/available/nodenv.plugin.bash @@ -0,0 +1,10 @@ +cite about-plugin +about-plugin 'load nodenv, if you are using it' + +export NODENV_ROOT="$HOME/.nodenv" +pathmunge "$NODENV_ROOT/bin" + +[[ `which nodenv` ]] && eval "$(nodenv init -)" + +# Load the auto-completion script if nodenv was loaded. +[[ -e $NODENV_ROOT/completions/nodenv.bash ]] && source $NODENV_ROOT/completions/nodenv.bash diff --git a/plugins/available/osx.plugin.bash b/plugins/available/osx.plugin.bash index 8a638b14..0e74ab8d 100644 --- a/plugins/available/osx.plugin.bash +++ b/plugins/available/osx.plugin.bash @@ -5,7 +5,7 @@ about-plugin 'osx-specific functions' if [ $(uname) = "Darwin" ]; then if type update_terminal_cwd > /dev/null 2>&1 ; then if ! [[ $PROMPT_COMMAND =~ (^|;)update_terminal_cwd($|;) ]] ; then - PROMPT_COMMAND="$PROMPT_COMMAND;update_terminal_cwd" + PROMPT_COMMAND="${PROMPT_COMMAND%;};update_terminal_cwd" declared="$(declare -p PROMPT_COMMAND)" [[ "$declared" =~ \ -[aAilrtu]*x[aAilrtu]*\ ]] 2>/dev/null [[ $? -eq 0 ]] && export PROMPT_COMMAND @@ -98,5 +98,18 @@ function prevcurl() { curl "$*" | open -fa $PREVIEW } +function refresh-launchpad() { + about 'Reset launchpad layout in macOS' + example '$ refresh-launchpad' + group 'osx' + + if [ $(uname) = "Darwin" ];then + defaults write com.apple.dock ResetLaunchPad -bool TRUE + killall Dock + else + echo "Sorry, this only works on Mac OS X" + fi +} + # Make this backwards compatible alias pcurl='prevcurl' diff --git a/plugins/available/percol.plugin.bash b/plugins/available/percol.plugin.bash index 2aea3b0d..27b98708 100644 --- a/plugins/available/percol.plugin.bash +++ b/plugins/available/percol.plugin.bash @@ -35,7 +35,10 @@ if command -v percol>/dev/null; then bind -x '"\C-r": _replace_by_history' # bind zz to percol if fasd enable - unalias zz + if [[ $(type -t zz) == 'alias' ]]; then + unalias zz + fi + if command -v fasd>/dev/null; then function zz() { local l=$(fasd -d | awk '{print $2}' | percol) diff --git a/plugins/available/powerline.plugin.bash b/plugins/available/powerline.plugin.bash new file mode 100644 index 00000000..0388aa37 --- /dev/null +++ b/plugins/available/powerline.plugin.bash @@ -0,0 +1,26 @@ +#!/usr/bin/env bash + +cite about-plugin +about-plugin 'enables powerline daemon' + +command -v powerline-daemon &>/dev/null || return +powerline-daemon -q + +#the following should not be executed if bashit powerline themes in use +case "$BASH_IT_THEME" in + *powerline*) + return + ;; +esac +POWERLINE_BASH_CONTINUATION=1 +POWERLINE_BASH_SELECT=1 +bashPowerlineInit=$(python -c \ + "import os; \ + import powerline;\ + print(os.path.join(os.path.dirname(\ + powerline.__file__),\ + 'bindings', \ + 'bash', \ + 'powerline.sh'))") +[ -e $bashPowerlineInit ] || return +. $bashPowerlineInit diff --git a/plugins/available/proxy.plugin.bash b/plugins/available/proxy.plugin.bash index f524940e..4f4bcbac 100644 --- a/plugins/available/proxy.plugin.bash +++ b/plugins/available/proxy.plugin.bash @@ -236,11 +236,11 @@ svn-show-proxy () about 'Shows SVN proxy settings' group 'proxy' - if $(command -v svn &> /dev/null) && $(command -v python &> /dev/null) ; then + if $(command -v svn &> /dev/null) && $(command -v python2 &> /dev/null) ; then echo "" echo "SVN Proxy Settings" echo "==================" - python - < /dev/null) && $(command -v python &> /dev/null) ; then - python - < /dev/null) && $(command -v python2 &> /dev/null) ; then + python2 - < /dev/null) && $(command -v python &> /dev/null) ; then + if $(command -v svn &> /dev/null) && $(command -v python2 &> /dev/null) ; then local my_http_proxy=${1:-$BASH_IT_HTTP_PROXY} - python - "$my_http_proxy" "$BASH_IT_NO_PROXY" < /dev/null; then SCM=$SCM_GIT elif which git &> /dev/null && [[ -n "$(git rev-parse --is-inside-work-tree 2> /dev/null)" ]]; then SCM=$SCM_GIT - elif [[ -d .hg ]]; then SCM=$SCM_HG + elif which p4 &> /dev/null && [[ -n "$(p4 set P4CLIENT 2> /dev/null)" ]]; then SCM=$SCM_P4 + elif [[ -d .hg ]] && which hg &> /dev/null; then SCM=$SCM_HG elif which hg &> /dev/null && [[ -n "$(hg root 2> /dev/null)" ]]; then SCM=$SCM_HG - elif [[ -d .svn ]]; then SCM=$SCM_SVN + elif [[ -d .svn ]] && which svn &> /dev/null; then SCM=$SCM_SVN else SCM=$SCM_NONE fi } @@ -81,6 +92,7 @@ function scm { function scm_prompt_char { if [[ -z $SCM ]]; then scm; fi if [[ $SCM == $SCM_GIT ]]; then SCM_CHAR=$SCM_GIT_CHAR + elif [[ $SCM == $SCM_P4 ]]; then SCM_CHAR=$SCM_P4_CHAR elif [[ $SCM == $SCM_HG ]]; then SCM_CHAR=$SCM_HG_CHAR elif [[ $SCM == $SCM_SVN ]]; then SCM_CHAR=$SCM_SVN_CHAR else SCM_CHAR=$SCM_NONE_CHAR @@ -93,6 +105,7 @@ function scm_prompt_vars { SCM_DIRTY=0 SCM_STATE='' [[ $SCM == $SCM_GIT ]] && git_prompt_vars && return + [[ $SCM == $SCM_P4 ]] && p4_prompt_vars && return [[ $SCM == $SCM_HG ]] && hg_prompt_vars && return [[ $SCM == $SCM_SVN ]] && svn_prompt_vars && return } @@ -125,6 +138,7 @@ function scm_prompt_info_common { fi # TODO: consider adding minimal status information for hg and svn + [[ ${SCM} == ${SCM_P4} ]] && p4_prompt_info && return [[ ${SCM} == ${SCM_HG} ]] && hg_prompt_info && return [[ ${SCM} == ${SCM_SVN} ]] && svn_prompt_info && return } @@ -193,6 +207,26 @@ function git_prompt_vars { SCM_CHANGE=$(_git-short-sha 2>/dev/null || echo "") } +function p4_prompt_vars { + IFS=$'\t' read -r \ + opened_count non_default_changes default_count \ + add_file_count edit_file_count delete_file_count \ + <<< "$(_p4-opened-counts)" + if [[ "${opened_count}" -gt 0 ]]; then + SCM_DIRTY=1 + SCM_STATE=${SCM_THEME_PROMPT_DIRTY} + [[ "${opened_count}" -gt 0 ]] && SCM_BRANCH+=" ${SCM_P4_OPENED_CHAR}${opened_count}" + [[ "${non_default_changes}" -gt 0 ]] && SCM_BRANCH+=" ${SCM_P4_CHANGES_CHAR}${non_default_changes}" + [[ "${default_count}" -gt 0 ]] && SCM_BRANCH+=" ${SCM_P4_DEFAULT_CHAR}${default_count}" + else + SCM_DIRTY=0 + SCM_STATE=${SCM_THEME_PROMPT_DIRTY} + fi + + SCM_PREFIX=${P4_THEME_PROMPT_PREFIX:-$SCM_THEME_PROMPT_PREFIX} + SCM_SUFFIX=${P4_THEME_PROMPT_SUFFIX:-$SCM_THEME_PROMPT_SUFFIX} +} + function svn_prompt_vars { if [[ -n $(svn status 2> /dev/null) ]]; then SCM_DIRTY=1 @@ -313,7 +347,7 @@ function condaenv_prompt { } function py_interp_prompt { - py_version=$(python --version 2>&1 | awk '{print "py-"$2;}') || return + py_version=$(python --version 2>&1 | awk 'NR==1{print "py-"$2;}') || return echo -e "${PYTHON_THEME_PROMPT_PREFIX}${py_version}${PYTHON_THEME_PROMPT_SUFFIX}" } @@ -359,10 +393,16 @@ function user_host_prompt { # backwards-compatibility function git_prompt_info { + _git-hide-status && return git_prompt_vars echo -e "${SCM_PREFIX}${SCM_BRANCH}${SCM_STATE}${SCM_SUFFIX}" } +function p4_prompt_info() { + p4_prompt_vars + echo -e "${SCM_PREFIX}${SCM_BRANCH}:${SCM_CHANGE}${SCM_STATE}${SCM_SUFFIX}" +} + function svn_prompt_info { svn_prompt_vars echo -e "${SCM_PREFIX}${SCM_BRANCH}${SCM_STATE}${SCM_SUFFIX}" diff --git a/themes/candy/candy.theme.bash b/themes/candy/candy.theme.bash index f3f0abfc..60bde3cd 100644 --- a/themes/candy/candy.theme.bash +++ b/themes/candy/candy.theme.bash @@ -1,7 +1,7 @@ #!/usr/bin/env bash function prompt_command() { - PS1="${green}\u@\h $(clock_prompt) ${reset_color}${white}\w${reset_color}$(scm_prompt_info)${blue} →${bold_blue} ${reset_color} "; + PS1="${green}\u@\h $(clock_prompt) ${reset_color}${white}\w${reset_color}$(scm_prompt_info)${blue} →${bold_blue} ${reset_color} ${normal}"; } THEME_CLOCK_COLOR=${THEME_CLOCK_COLOR:-"$blue"} diff --git a/themes/codeword/README.md b/themes/codeword/README.md new file mode 100644 index 00000000..38201dbf --- /dev/null +++ b/themes/codeword/README.md @@ -0,0 +1,22 @@ +# Single line PS1 theme w/realtime history among windows + + +Minimal theme overrides from bash_it base theming + + +## `user@host:path[virt-env][scm] $` +Breakdown of the segments: + +- **user@host:path** - *convienient for LAN based `ssh` and `scp` tasks* +- [**virtualenv**] - *only appears when activated* +- [**scm**] - *only appears when activated* +- **marker** - *$ or # depending on current user* + +### Examples + +```bash +user@example.lan:~ $ cd /tmp/foo/bar/baz +user@example.lan:/tmp/foo/bar/baz $ cd $HOME/workspace +user@example.lan:~/workspace $ cd sampleRepo/ +user@example.lan:~/workspace/sampleRepo [± |master ↑1 ↓3 {1} S:2 ?:1 ✗|] $ +``` diff --git a/themes/codeword/codeword.theme.bash b/themes/codeword/codeword.theme.bash new file mode 100644 index 00000000..96723ce3 --- /dev/null +++ b/themes/codeword/codeword.theme.bash @@ -0,0 +1,38 @@ +SCM_THEME_PROMPT_PREFIX=${SCM_THEME_PROMPT_SUFFIX} +SCM_THEME_PROMPT_DIRTY="${bold_red} ✗${normal}" +SCM_THEME_PROMPT_CLEAN="${bold_green} ✓${normal}" +SCM_GIT_CHAR="${green}±${normal}" + +scm_prompt() { + CHAR=$(scm_char) + if [ $CHAR = $SCM_NONE_CHAR ] + then + return + else + echo " [$(scm_char)$(scm_prompt_info)]" + fi +} + +mark_prompt() { + echo "${green}\$${normal}" +} + +user_host_path_prompt() { + ps_user="${green}\u${normal}"; + ps_host="${blue}\H${normal}"; + ps_path="${yellow}\w${normal}"; + echo "$ps_user@$ps_host:$ps_path" +} + +prompt() { + PS1="$(user_host_path_prompt)$(virtualenv_prompt)$(scm_prompt) $(mark_prompt) " +} + +share_history() { + history -a + history -c + history -r +} + +safe_append_prompt_command share_history +safe_append_prompt_command prompt diff --git a/themes/demula/demula.theme.bash b/themes/demula/demula.theme.bash index 515d096d..e85c18f7 100644 --- a/themes/demula/demula.theme.bash +++ b/themes/demula/demula.theme.bash @@ -100,8 +100,7 @@ prompt() { if [ $(uname) = "Linux" ]; then - PS1="${TITLEBAR} -${SAVE_CURSOR}${MOVE_CURSOR_RIGHTMOST}${MOVE_CURSOR_5_LEFT}\ + PS1="${TITLEBAR}${SAVE_CURSOR}${MOVE_CURSOR_RIGHTMOST}${MOVE_CURSOR_5_LEFT} $(safe_battery_charge)${RESTORE_CURSOR}\ ${D_USER_COLOR}\u ${D_INTERMEDIATE_COLOR}\ at ${D_MACHINE_COLOR}\h ${D_INTERMEDIATE_COLOR}\ @@ -113,7 +112,7 @@ ${D_INTERMEDIATE_COLOR}$ ${D_DEFAULT_COLOR}" else PS1="${TITLEBAR} ${D_USER_COLOR}\u ${D_INTERMEDIATE_COLOR}\ -at ${D_MACHINE_COLOR}\h ${D_INTERMEDIATE_COLOR}\ +at ${D_MACHINE_COLOR}\h ${D_INTERMEDIATE_COLOR}\ in ${D_DIR_COLOR}\w ${D_INTERMEDIATE_COLOR}\ ${LAST_COMMAND_FAILED}\ $(demula_vcprompt)\ diff --git a/themes/elixr/elixr.theme.bash b/themes/elixr/elixr.theme.bash new file mode 100644 index 00000000..266abbad --- /dev/null +++ b/themes/elixr/elixr.theme.bash @@ -0,0 +1,23 @@ +#!/usr/bin/env bash + +SCM_THEME_PROMPT_DIRTY=" ${red}✗" +SCM_THEME_PROMPT_CLEAN=" ${bold_green}✓" +SCM_THEME_PROMPT_PREFIX=" ${green}| " +SCM_THEME_PROMPT_SUFFIX="${green} |" +SCM_NONE_CHAR='◐ ' +SCM_GIT_SHOW_MINIMAL_INFO=true +GIT_THEME_PROMPT_DIRTY=" ${red}✗" +GIT_THEME_PROMPT_CLEAN=" ${bold_green}✓" +GIT_THEME_PROMPT_PREFIX=" ${green}|" +GIT_THEME_PROMPT_SUFFIX="${green}|" + +RVM_THEME_PROMPT_PREFIX="|" +RVM_THEME_PROMPT_SUFFIX=" d|" + +BOLD="\[\e[1m\]" + +function prompt_command() { + PS1="\n${bold_cyan}$(scm_prompt_char_info)$(virtualenv_prompt) ${bold_cyan}\w :${reset_color}${normal}${BOLD} " +} + +safe_append_prompt_command prompt_command diff --git a/themes/githelpers.theme.bash b/themes/githelpers.theme.bash index e6bda810..1f43382d 100644 --- a/themes/githelpers.theme.bash +++ b/themes/githelpers.theme.bash @@ -71,7 +71,8 @@ function _git-hide-status { } function _git-status { - [[ "${SCM_GIT_IGNORE_UNTRACKED}" = "true" ]] && local git_status_flags='-uno' + local git_status_flags= + [[ "${SCM_GIT_IGNORE_UNTRACKED}" = "true" ]] && git_status_flags='-uno' git status --porcelain ${git_status_flags} 2> /dev/null } @@ -102,7 +103,8 @@ function _git-status-counts { function _git-remote-info { [[ "$(_git-upstream)" == "" ]] && return - [[ "$(_git-branch)" == "$(_git-upstream-branch)" ]] && local same_branch_name=true + local same_branch_name= + [[ "$(_git-branch)" == "$(_git-upstream-branch)" ]] && same_branch_name=true if ([[ "${SCM_GIT_SHOW_REMOTE_INFO}" = "auto" ]] && [[ "$(_git-num-remotes)" -ge 2 ]]) || [[ "${SCM_GIT_SHOW_REMOTE_INFO}" = "true" ]]; then if [[ "${same_branch_name}" != "true" ]]; then diff --git a/themes/norbu/norbu.theme.bash b/themes/norbu/norbu.theme.bash new file mode 100644 index 00000000..184c13c9 --- /dev/null +++ b/themes/norbu/norbu.theme.bash @@ -0,0 +1,27 @@ +#!/usr/bin/env bash + +function set_prompt_symbol () { + if test $1 -eq 0 ; then + PROMPT_SYMBOL=">_" + else + PROMPT_SYMBOL="${orange}>_${normal}" + fi +} +function prompt_command() { + set_prompt_symbol $? + if test -z "$VIRTUAL_ENV" ; then + PYTHON_VIRTUALENV="" + else + PYTHON_VIRTUALENV="${bold_yellow}[`basename \"$VIRTUAL_ENV\"`]" + fi + + PS1="${bold_orange}${PYTHON_VIRTUALENV}${reset_color}${bold_green}[\w]${bold_blue}\[$(scm_prompt_info)\]${normal} \n${PROMPT_SYMBOL} " +} + +# scm themeing +SCM_THEME_PROMPT_DIRTY=" ✗" +SCM_THEME_PROMPT_CLEAN=" ✓" +SCM_THEME_PROMPT_PREFIX="[" +SCM_THEME_PROMPT_SUFFIX="]" + +safe_append_prompt_command prompt_command diff --git a/themes/p4helpers.theme.bash b/themes/p4helpers.theme.bash new file mode 100644 index 00000000..27a777ac --- /dev/null +++ b/themes/p4helpers.theme.bash @@ -0,0 +1,45 @@ +#!/usr/bin/env bash + +function _p4-opened { + timeout 2.0s p4 opened -s 2> /dev/null +} + +function _p4-opened-counts { + # Return the following counts seperated by tabs: + # - count of opened files + # - count of pending changesets (other than defaults) + # - count of files in the default changeset + # - count of opened files in add mode + # - count of opened files in edit mode + # - count of opened files in delete mode + _p4-opened | awk ' + BEGIN { + opened=0; + type_array["edit"]=0; + type_array["add"]=0; + type_array["delete"]=0; + change_array["change"]=0; + } + { + # p4 opened prints one file per line, and all lines begin with "//" + # Here is an examples: + # + # $ p4 opened + # //depot/some/file.py#4 - edit change 716431 (text) + # //depot/another/file.py - edit default change (text) + # //now/add/a/newfile.sh - add change 435645 (text+k) + # + # + if ($1 ~ /^\/\//) { + opened += 1 + change_array[$5] += 1 + type_array[$3] += 1 + } + } + END { + default_changes=change_array["change"]; + non_default_changes=length(change_array) - 1; + print opened "\t" non_default_changes "\t" default_changes "\t" type_array["add"] "\t" type_array["edit"] "\t" type_array["delete"] + } +' +} diff --git a/themes/powerline-multiline/README.md b/themes/powerline-multiline/README.md index 4ceebec6..acc199ac 100644 --- a/themes/powerline-multiline/README.md +++ b/themes/powerline-multiline/README.md @@ -46,14 +46,19 @@ The time/date is printed by the `date` command, so refer to its man page to chan The contents of both prompt sides can be "reordered", all the "segments" (every piece of information) can take any place. The currently available segments are: -* battery -* clock -* cwd -* in_vim -* python_venv -* ruby -* scm -* user_info +* `battery` - Battery information (you'll need to enable the `battery` plugin) +* `clock` - Current time in `HH:MM:SS` format +* `cwd` - Current working directory including full folder hierarchy (c.f. `wd`) +* `hostname` - Host name of machine +* `in_vim` - Show identifier if running in `:terminal` from vim +* `last_status` - Exit status of last run command +* `python_venv` - Python virtual environment information (`virtualenv`, `venv` + and `conda` supported) +* `ruby` - Current ruby version if using `rvm` +* `scm` - Version control information, `git` +* `user_info` - Current user +* `wd` - Working directory, like `cwd` but doesn't show the full folder + hierarchy, only the directory you're currently in. Two variables can be defined to set the order of the prompt segments: diff --git a/themes/powerline-multiline/powerline-multiline.base.bash b/themes/powerline-multiline/powerline-multiline.base.bash index b78f5b74..ac442f73 100644 --- a/themes/powerline-multiline/powerline-multiline.base.bash +++ b/themes/powerline-multiline/powerline-multiline.base.bash @@ -46,11 +46,13 @@ function __powerline_prompt_command { ## right prompt ## if [[ -n "${POWERLINE_RIGHT_PROMPT}" ]]; then - LEFT_PROMPT+="${move_cursor_rightmost}" + # LEFT_PROMPT+="${move_cursor_rightmost}" for segment in $POWERLINE_RIGHT_PROMPT; do local info="$(__powerline_${segment}_prompt)" [[ -n "${info}" ]] && __powerline_right_segment "${info}" done + RIGHT_PAD=$(printf "%.s " $(seq 1 $RIGHT_PROMPT_LENGTH)) + LEFT_PROMPT+="${RIGHT_PAD}${move_cursor_rightmost}" LEFT_PROMPT+="\033[${RIGHT_PROMPT_LENGTH}D" fi diff --git a/themes/powerline-multiline/powerline-multiline.theme.bash b/themes/powerline-multiline/powerline-multiline.theme.bash index 4f4f8917..a62a7060 100644 --- a/themes/powerline-multiline/powerline-multiline.theme.bash +++ b/themes/powerline-multiline/powerline-multiline.theme.bash @@ -51,6 +51,8 @@ THEME_CLOCK_FORMAT=${THEME_CLOCK_FORMAT:="%H:%M:%S"} IN_VIM_THEME_PROMPT_COLOR=245 IN_VIM_THEME_PROMPT_TEXT="vim" +HOST_THEME_PROMPT_COLOR=0 + POWERLINE_LEFT_PROMPT=${POWERLINE_LEFT_PROMPT:="scm python_venv ruby cwd"} POWERLINE_RIGHT_PROMPT=${POWERLINE_RIGHT_PROMPT:="in_vim clock battery user_info"} diff --git a/themes/powerline-naked/README.md b/themes/powerline-naked/README.md index 9ee38271..510e0301 100644 --- a/themes/powerline-naked/README.md +++ b/themes/powerline-naked/README.md @@ -42,16 +42,21 @@ The time/date is printed by the `date` command, so refer to its man page to chan The contents of the prompt can be "reordered", all the "segments" (every piece of information) can take any place. The currently available segments are: -* battery -* clock -* cwd -* in_vim -* python_venv -* ruby -* scm -* user_info +* `battery` - Battery information (you'll need to enable the `battery` plugin) +* `clock` - Current time in `HH:MM:SS` format +* `cwd` - Current working directory including full folder hierarchy (c.f. `wd`) +* `hostname` - Host name of machine +* `in_vim` - Show identifier if running in `:terminal` from vim +* `last_status` - Exit status of last run command +* `python_venv` - Python virtual environment information (`virtualenv`, `venv` + and `conda` supported) +* `ruby` - Current ruby version if using `rvm` +* `scm` - Version control information, `git` +* `user_info` - Current user +* `wd` - Working directory, like `cwd` but doesn't show the full folder + hierarchy, only the directory you're currently in. -A variables can be defined to set the order of the prompt segments: +A variable can be defined to set the order of the prompt segments: POWERLINE_PROMPT="user_info scm python_venv ruby cwd" diff --git a/themes/powerline-naked/powerline-naked.base.bash b/themes/powerline-naked/powerline-naked.base.bash index 1939dfca..f6b11f42 100644 --- a/themes/powerline-naked/powerline-naked.base.bash +++ b/themes/powerline-naked/powerline-naked.base.bash @@ -4,7 +4,7 @@ function __powerline_left_segment { local OLD_IFS="${IFS}"; IFS="|" local params=( $1 ) IFS="${OLD_IFS}" - local separator_char="" + local separator_char="${POWERLINE_LEFT_SEPARATOR}" local separator="" if [[ "${SEGMENTS_AT_LEFT}" -gt 0 ]]; then diff --git a/themes/powerline-naked/powerline-naked.theme.bash b/themes/powerline-naked/powerline-naked.theme.bash index 26633108..1897a6ba 100644 --- a/themes/powerline-naked/powerline-naked.theme.bash +++ b/themes/powerline-naked/powerline-naked.theme.bash @@ -1,9 +1,10 @@ #!/usr/bin/env bash +POWERLINE_LEFT_SEPARATOR=${POWERLINE_LEFT_SEPARATOR:=""} + . "$BASH_IT/themes/powerline-naked/powerline-naked.base.bash" PROMPT_CHAR=${POWERLINE_PROMPT_CHAR:=""} -POWERLINE_LEFT_SEPARATOR=${POWERLINE_LEFT_SEPARATOR:=""} USER_INFO_SSH_CHAR=${POWERLINE_USER_INFO_SSH_CHAR:=" "} USER_INFO_THEME_PROMPT_COLOR=240 @@ -47,6 +48,8 @@ THEME_CLOCK_FORMAT=${THEME_CLOCK_FORMAT:="%H:%M:%S"} IN_VIM_THEME_PROMPT_COLOR=245 IN_VIM_THEME_PROMPT_TEXT="vim" +HOST_THEME_PROMPT_COLOR=254 + POWERLINE_PROMPT=${POWERLINE_PROMPT:="user_info scm python_venv ruby cwd"} safe_append_prompt_command __powerline_prompt_command diff --git a/themes/powerline-plain/README.md b/themes/powerline-plain/README.md index 6347d991..8c8647e3 100644 --- a/themes/powerline-plain/README.md +++ b/themes/powerline-plain/README.md @@ -40,16 +40,21 @@ The time/date is printed by the `date` command, so refer to its man page to chan The contents of the prompt can be "reordered", all the "segments" (every piece of information) can take any place. The currently available segments are: -* battery -* clock -* cwd -* in_vim -* python_venv -* ruby -* scm -* user_info +* `battery` - Battery information (you'll need to enable the `battery` plugin) +* `clock` - Current time in `HH:MM:SS` format +* `cwd` - Current working directory including full folder hierarchy (c.f. `wd`) +* `hostname` - Host name of machine +* `in_vim` - Show identifier if running in `:terminal` from vim +* `last_status` - Exit status of last run command +* `python_venv` - Python virtual environment information (`virtualenv`, `venv` + and `conda` supported) +* `ruby` - Current ruby version if using `rvm` +* `scm` - Version control information, `git` +* `user_info` - Current user +* `wd` - Working directory, like `cwd` but doesn't show the full folder + hierarchy, only the directory you're currently in. -A variables can be defined to set the order of the prompt segments: +A variable can be defined to set the order of the prompt segments: POWERLINE_PROMPT="user_info scm python_venv ruby cwd" diff --git a/themes/powerline-plain/powerline-plain.theme.bash b/themes/powerline-plain/powerline-plain.theme.bash index 6e0796d7..53da88b4 100644 --- a/themes/powerline-plain/powerline-plain.theme.bash +++ b/themes/powerline-plain/powerline-plain.theme.bash @@ -25,7 +25,7 @@ RVM_THEME_PROMPT_SUFFIX="" RBENV_THEME_PROMPT_PREFIX="" RBENV_THEME_PROMPT_SUFFIX="" RUBY_THEME_PROMPT_COLOR=161 -RUBY_CHAR=${POWERLINE_RUBY_CHAR:="ⓔ "} +RUBY_CHAR=${POWERLINE_RUBY_CHAR:="💎 "} CWD_THEME_PROMPT_COLOR=240 @@ -43,6 +43,8 @@ THEME_CLOCK_FORMAT=${THEME_CLOCK_FORMAT:="%H:%M:%S"} IN_VIM_THEME_PROMPT_COLOR=245 IN_VIM_THEME_PROMPT_TEXT="vim" +HOST_THEME_PROMPT_COLOR=0 + POWERLINE_PROMPT=${POWERLINE_PROMPT:="user_info scm python_venv ruby cwd"} safe_append_prompt_command __powerline_prompt_command diff --git a/themes/powerline/README.md b/themes/powerline/README.md index d0a46815..7c1a135c 100644 --- a/themes/powerline/README.md +++ b/themes/powerline/README.md @@ -44,16 +44,21 @@ The time/date is printed by the `date` command, so refer to its man page to chan The contents of the prompt can be "reordered", all the "segments" (every piece of information) can take any place. The currently available segments are: -* battery -* clock -* cwd -* in_vim -* python_venv -* ruby -* scm -* user_info +* `battery` - Battery information (you'll need to enable the `battery` plugin) +* `clock` - Current time in `HH:MM:SS` format +* `cwd` - Current working directory including full folder hierarchy (c.f. `wd`) +* `hostname` - Host name of machine +* `in_vim` - Show identifier if running in `:terminal` from vim +* `last_status` - Exit status of last run command +* `python_venv` - Python virtual environment information (`virtualenv`, `venv` + and `conda` supported) +* `ruby` - Current ruby version if using `rvm` +* `scm` - Version control information, `git` +* `user_info` - Current user +* `wd` - Working directory, like `cwd` but doesn't show the full folder + hierarchy, only the directory you're currently in. -A variables can be defined to set the order of the prompt segments: +A variable can be defined to set the order of the prompt segments: POWERLINE_PROMPT="user_info scm python_venv ruby cwd" diff --git a/themes/powerline/powerline.base.bash b/themes/powerline/powerline.base.bash index c352a87a..ade246e9 100644 --- a/themes/powerline/powerline.base.bash +++ b/themes/powerline/powerline.base.bash @@ -84,6 +84,8 @@ function __powerline_scm_prompt { fi if [[ "${SCM_GIT_CHAR}" == "${SCM_CHAR}" ]]; then scm_prompt+="${SCM_CHAR}${SCM_BRANCH}${SCM_STATE}" + elif [[ "${SCM_P4_CHAR}" == "${SCM_CHAR}" ]]; then + scm_prompt+="${SCM_CHAR}${SCM_BRANCH}${SCM_STATE}" fi echo "${scm_prompt}${scm}|${color}" fi diff --git a/themes/powerline/powerline.theme.bash b/themes/powerline/powerline.theme.bash index 12de9cbe..df72a73f 100644 --- a/themes/powerline/powerline.theme.bash +++ b/themes/powerline/powerline.theme.bash @@ -46,6 +46,8 @@ THEME_CLOCK_FORMAT=${THEME_CLOCK_FORMAT:="%H:%M:%S"} IN_VIM_THEME_PROMPT_COLOR=245 IN_VIM_THEME_PROMPT_TEXT="vim" +HOST_THEME_PROMPT_COLOR=0 + POWERLINE_PROMPT=${POWERLINE_PROMPT:="user_info scm python_venv ruby cwd"} safe_append_prompt_command __powerline_prompt_command diff --git a/themes/powerturk/powerturk.theme.bash b/themes/powerturk/powerturk.theme.bash new file mode 100644 index 00000000..35404360 --- /dev/null +++ b/themes/powerturk/powerturk.theme.bash @@ -0,0 +1,185 @@ +#!/usr/bin/env bash +# Power-Turk theme for bash-it +# Author (C) 2015 Ahmed Seref Guneysu + +THEME_PROMPT_SEPARATOR="" + +SHELL_SSH_CHAR=" " +SHELL_THEME_PROMPT_COLOR=2 +SHELL_SSH_THEME_PROMPT_COLOR=208 + +VIRTUALENV_CHAR="ⓔ " +VIRTUALENV_THEME_PROMPT_COLOR=35 + +SCM_NONE_CHAR="" + +SCM_GIT_CHAR=" " # " " + +SCM_THEME_PROMPT_CLEAN="" +SCM_THEME_PROMPT_DIRTY="" + +SCM_THEME_PROMPT_COLOR=16 +SCM_THEME_PROMPT_CLEAN_COLOR=231 +SCM_THEME_PROMPT_DIRTY_COLOR=196 +SCM_THEME_PROMPT_STAGED_COLOR=220 +SCM_THEME_PROMPT_UNSTAGED_COLOR=166 + +CWD_THEME_PROMPT_COLOR=240 + +LAST_STATUS_THEME_PROMPT_COLOR=52 + +_collapsed_wd() { + # echo -e "\u2771\u276d\u276f" + echo $(pwd | perl -pe " + BEGIN { + binmode STDIN, ':encoding(UTF-8)'; + binmode STDOUT, ':encoding(UTF-8)'; + }; s|^$HOME||g; s|/([^/])[^/]*(?=/)|/\$1|g") | \ + sed -re "s/\//  /g" +} + +_swd(){ +# Adapted from http://stackoverflow.com/a/2951707/1766716 + begin="" # The unshortened beginning of the path. + shortbegin="" # The shortened beginning of the path. + current="" # The section of the path we're currently working on. + end="${2:-$(pwd)}/" # The unmodified rest of the path. + + if [[ "$end" =~ "$HOME" ]]; then + INHOME=1 + end="${end#$HOME}" #strip /home/username from start of string + begin="$HOME" #start expansion from the right spot + else + INHOME=0 + fi + + end="${end#/}" # Strip the first / + shortenedpath="$end" # The whole path, to check the length. + maxlength="${1:-0}" + + shopt -q nullglob && NGV="-s" || NGV="-u" # Store the value for later. + shopt -s nullglob # Without this, anything that doesn't exist in the filesystem turns into */*/*/... + + while [[ "$end" ]] && (( ${#shortenedpath} > maxlength )) + do + current="${end%%/*}" # everything before the first / + end="${end#*/}" # everything after the first / + + shortcur="$current" + shortcurstar="$current" # No star if we don't shorten it. + + for ((i=${#current}-2; i>=0; i--)); do + subcurrent="${current:0:i}" + matching=("$begin/$subcurrent"*) # Array of all files that start with $subcurrent. + (( ${#matching[*]} != 1 )) && break # Stop shortening if more than one file matches. + shortcur="$subcurrent" + shortcurstar="$subcurrent*" + done + + #advance + begin="$begin/$current" + shortbegin="$shortbegin/$shortcurstar" + shortenedpath="$shortbegin/$end" + done + + shortenedpath="${shortenedpath%/}" # strip trailing / + shortenedpath="${shortenedpath#/}" # strip leading / + + # Replaces slashes with  except first occurence. + if [ $INHOME -eq 1 ]; then + echo "~/$shortenedpath" | sed "s/\///2g" # make sure it starts with ~/ + else + echo "/$shortenedpath" | sed "s/\///2g" # Make sure it starts with / + fi + + shopt "$NGV" nullglob # Reset nullglob in case this is being used as a function. + +} +function set_rgb_color { + if [[ "${1}" != "-" ]]; then + fg="38;5;${1}" + fi + if [[ "${2}" != "-" ]]; then + bg="48;5;${2}" + [[ -n "${fg}" ]] && bg=";${bg}" + fi + echo -e "\[\033[${fg}${bg}m\]" +} + +function powerline_shell_prompt { + if [[ -n "${SSH_CLIENT}" ]]; then + SHELL_PROMPT="${bold_white}$(set_rgb_color - ${SHELL_SSH_THEME_PROMPT_COLOR}) ${SHELL_SSH_CHAR}\u@\h ${normal}" + LAST_THEME_COLOR=${SHELL_SSH_THEME_PROMPT_COLOR} + else + SHELL_PROMPT="${bold_white}$(set_rgb_color - ${SHELL_THEME_PROMPT_COLOR}) ${normal}" + LAST_THEME_COLOR=${SHELL_THEME_PROMPT_COLOR} + fi +} + +function powerline_virtualenv_prompt { + local environ="" + + if [[ -n "$CONDA_DEFAULT_ENV" ]]; then + environ="conda: $CONDA_DEFAULT_ENV" + elif [[ -n "$VIRTUAL_ENV" ]]; then + environ=$(basename "$VIRTUAL_ENV") + fi + + if [[ -n "$environ" ]]; then + VIRTUALENV_PROMPT="$(set_rgb_color ${LAST_THEME_COLOR} ${VIRTUALENV_THEME_PROMPT_COLOR})${THEME_PROMPT_SEPARATOR}${normal}$(set_rgb_color - ${VIRTUALENV_THEME_PROMPT_COLOR}) ${VIRTUALENV_CHAR}$environ ${normal}" + LAST_THEME_COLOR=${VIRTUALENV_THEME_PROMPT_COLOR} + else + VIRTUALENV_PROMPT="" + fi +} + +function powerline_scm_prompt { + scm_prompt_vars + + if [[ "${SCM_NONE_CHAR}" != "${SCM_CHAR}" ]]; then + if [[ "${SCM_DIRTY}" -eq 3 ]]; then + SCM_PROMPT="$(set_rgb_color ${SCM_THEME_PROMPT_STAGED_COLOR} ${SCM_THEME_PROMPT_COLOR})" + elif [[ "${SCM_DIRTY}" -eq 2 ]]; then + SCM_PROMPT="$(set_rgb_color ${SCM_THEME_PROMPT_UNSTAGED_COLOR} ${SCM_THEME_PROMPT_COLOR})" + elif [[ "${SCM_DIRTY}" -eq 1 ]]; then + SCM_PROMPT="$(set_rgb_color ${SCM_THEME_PROMPT_DIRTY_COLOR} ${SCM_THEME_PROMPT_COLOR})" + else + SCM_PROMPT="$(set_rgb_color ${SCM_THEME_PROMPT_CLEAN_COLOR} ${SCM_THEME_PROMPT_COLOR})" + fi + if [[ "${SCM_GIT_CHAR}" == "${SCM_CHAR}" ]]; then + SCM_PROMPT+=" ${SCM_CHAR}${SCM_BRANCH}${SCM_STATE}" + fi + SCM_PROMPT="$(set_rgb_color ${LAST_THEME_COLOR} ${SCM_THEME_PROMPT_COLOR})${THEME_PROMPT_SEPARATOR}${normal}${SCM_PROMPT} ${normal}" + LAST_THEME_COLOR=${SCM_THEME_PROMPT_COLOR} + else + SCM_PROMPT="" + fi +} + +function powerline_cwd_prompt { +CWD_PROMPT="$(set_rgb_color ${LAST_THEME_COLOR} ${CWD_THEME_PROMPT_COLOR})${THEME_PROMPT_SEPARATOR}$(set_rgb_color 0 ${CWD_THEME_PROMPT_COLOR}) $(_swd)${normal}$(set_rgb_color ${CWD_THEME_PROMPT_COLOR} -)${normal}" + LAST_THEME_COLOR=${CWD_THEME_PROMPT_COLOR} +} + +function powerline_last_status_prompt { + if [[ "$1" -eq 0 ]]; then + LAST_STATUS_PROMPT="$(set_rgb_color ${LAST_THEME_COLOR} -)${THEME_PROMPT_SEPARATOR}${normal}" + else + LAST_STATUS_PROMPT="$(set_rgb_color ${LAST_THEME_COLOR} ${LAST_STATUS_THEME_PROMPT_COLOR})${THEME_PROMPT_SEPARATOR}${normal}$(set_rgb_color - ${LAST_STATUS_THEME_PROMPT_COLOR}) ${LAST_STATUS} ${normal}$(set_rgb_color ${LAST_STATUS_THEME_PROMPT_COLOR} -)${THEME_PROMPT_SEPARATOR}${normal}" + fi +} + +function powerline_prompt_command() { + local LAST_STATUS="$?" + + powerline_shell_prompt + powerline_virtualenv_prompt + powerline_scm_prompt + powerline_cwd_prompt + powerline_last_status_prompt LAST_STATUS + + PS1="${SHELL_PROMPT}${VIRTUALENV_PROMPT}${SCM_PROMPT}${CWD_PROMPT}${LAST_STATUS_PROMPT} " +} + +PROMPT_COMMAND=powerline_prompt_command + diff --git a/themes/zork/zork.theme.bash b/themes/zork/zork.theme.bash index 75bc17d6..07f30e12 100644 --- a/themes/zork/zork.theme.bash +++ b/themes/zork/zork.theme.bash @@ -57,7 +57,12 @@ chroot(){ # show virtualenvwrapper my_ve(){ - if [ -n "$VIRTUAL_ENV" ] + + if [ -n "$CONDA_DEFAULT_ENV" ] + then + my_ps_ve="${bold_purple}${CONDA_DEFAULT_ENV}${normal}"; + echo "($my_ps_ve)"; + elif [ -n "$VIRTUAL_ENV" ] then my_ps_ve="${bold_purple}$ve${normal}"; echo "($my_ps_ve)"; diff --git a/uninstall.sh b/uninstall.sh index 18d88e80..17712610 100755 --- a/uninstall.sh +++ b/uninstall.sh @@ -16,7 +16,7 @@ esac BACKUP_FILE=$CONFIG_FILE.bak if [ ! -e "$HOME/$BACKUP_FILE" ]; then - echo -e "\033[0;33mBackup file "$HOME/$BACKUP_FILE" not found.\033[0m" >&2 + echo -e "\033[0;33mBackup file $HOME/$BACKUP_FILE not found.\033[0m" >&2 test -w "$HOME/$CONFIG_FILE" && mv "$HOME/$CONFIG_FILE" "$HOME/$CONFIG_FILE.uninstall" &&