diff --git a/.editorconfig b/.editorconfig new file mode 100644 index 00000000..4dc96bd5 --- /dev/null +++ b/.editorconfig @@ -0,0 +1,14 @@ +# EditorConfig is awesome: http://EditorConfig.org + +root = true + +[*] +indent_style = space +indent_size = 2 +end_of_line = lf +charset = utf-8 +trim_trailing_whitespace = true +insert_final_newline = true + +[*.md] +trim_trailing_whitespace = false diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md new file mode 100644 index 00000000..b9bd7d91 --- /dev/null +++ b/CONTRIBUTING.md @@ -0,0 +1,34 @@ +# Contribution Guidelines + +When contributing a new feature, a bug fix, a new theme, or any other change to Bash-it, please consider the following guidelines. Most of this is common sense, but please try to stick to the conventions listed here. + +## Issues + +* When opening a new issue in the issue tracker, please include information about which _Operating System_ you're using, and which version of _Bash_. +* In many cases, it also makes sense to show which Bash-it plugins you are using. This information can be obtained using `bash-it show plugins`. +* If the issue happens while loading Bash-it, please also include your `~/.bash_profile` or `~/.bashrc` file, as well as the install location of Bash-it (default should be `~/.bash_it`). +* When reporting a bug or requesting a new feature, consider providing a Pull Request that fixes the issue or can be used as a starting point for the new feature. Don't be afraid, most things aren't that complex... + +## Pull Requests + +* Fork the Bash-it repo, create a new feature branch from _master_ and apply your changes there. Create a _Pull Request_ from your feature branch against Bash-it's _master_ branch. +* Limit each Pull Request to one feature. Don't bundle multiple features/changes (e.g. a new _Theme_ and a fix to an existing plugin) into a single Pull Request - create one PR for the theme, and a separate PR for the fix. +* For complex changes, try to _squash_ your changes into a single commit. Don't create a PR consisting of 20 commits that show your work in progress. Before you create the PR, _squash_ your changes into a single commit. + +## Code Style + +* Try to stick to the existing code style. Please don't reformat or change the syntax of existing code simply because you don't like that style. +* Indentation is using spaces, not tabs. Most of the code is indented with 2 spaces, some with 4 spaces. Please try to stick to 2 spaces. If you're using an editor that supports [EditorConfig](http://EditorConfig.org), the editor should automatically use the settings defined in Bash-it's [.editorconfig file](.editorconfig). +* When creating new functions, please use a dash ("-") to separate the words of the function's name, e.g. `my-new-function`. Don't use underscores, e.g. `my_new_function`. +* Internal functions that aren't to be used by the end user should start with an underscore, e.g. `_my-new-internal-function`. +* Use the provided meta functions to document your code, e.g. `about-plugin`, `about`, `group`, `param`, `example`. This will make it easier for other people to use your new functionality. Take a look at the existing code for an example (e.g. [the base plugin](plugins/available/base.plugin.bash)). +* When adding files, please use the existing file naming conventions, e.g. plugin files need to end in `.plugin.bash`. This is important for the installation functionality. + +## Features + +* When adding new completions or plugins, please don't simply copy existing tools into the Bash-it codebase, try to load/integrate the tools instead. An example is using `nvm`: Instead of copying the existing `nvm` script into Bash-it, the `nvm.plugin.bash` file tries to load an existing installation of `nvm`. This means an additional step for the user (installing `nvm` from its own repo, or through a package manager), but it will also ensure that `nvm` can be upgraded in an easy way. + +## Themes + +* When adding a new theme, please include a screenshot and a short description about what makes this theme unique in the Pull Request. +* Ideally, each theme's folder should contain a `README.md` file describing the theme and its configuration options. diff --git a/README.md b/README.md index 49f54a33..a7bf87ed 100644 --- a/README.md +++ b/README.md @@ -33,7 +33,7 @@ bash-it help completions # shows help for installed completions bash-it help plugins # shows help for installed plugins ``` -## Your Custom scripts, aliases, and functions +## Your Custom scripts, aliases, themes, and functions For custom scripts, and aliases, just create the following files (they'll be ignored by the git repo): @@ -41,6 +41,7 @@ For custom scripts, and aliases, just create the following files (they'll be ign * `completion/custom.completion.bash` * `lib/custom.bash` * `plugins/custom.plugins.bash` +* `custom/themes//.theme.bash` Anything in the custom directory will be ignored, with the exception of `custom/example.bash`. @@ -63,6 +64,10 @@ cd $BASH_IT This will restore your previous Bash profile. After the uninstall script finishes, remove the Bash it directory from your machine (`rm -rf $BASH_IT`) and start a new shell. +## Contributing + +Please take a look at the [Contribution Guidelines](CONTRIBUTING.md) before reporting a bug or providing a new feature. + ## Misc ### Bash Profile Aliases @@ -208,6 +213,8 @@ We think everyone has their own custom scripts accumulated over time. And so, fo Send us a pull request and we'll merge it as long as it looks good. If you change an existing command, please give an explanation why. That will help a lot when we merge your changes in. +Please take a look at the [Contribution Guidelines](CONTRIBUTING.md) before reporting a bug or providing a new feature. + Thanks, and happing bashing! diff --git a/aliases/available/ag.aliases.bash b/aliases/available/ag.aliases.bash new file mode 100644 index 00000000..e3157f94 --- /dev/null +++ b/aliases/available/ag.aliases.bash @@ -0,0 +1,12 @@ +cite 'about-alias' +about-alias 'the silver searcher (ag) aliases' + +## Summary for args to less: +# less(1) +# -M (-M or --LONG-PROMPT) Prompt very verbosely +# -I (-I or --IGNORE-CASE) Searches with '/' ignore case +# -R (-R or --RAW-CONTROL-CHARS) For handling ANSI colors +# -F (-F or --quit-if-one-screen) Auto exit if <1 screen +# -X (-X or --no-init) Disable termcap init & deinit + +alias ag='ag --smart-case --pager="less -MIRFX"' diff --git a/aliases/available/atom.aliases.bash b/aliases/available/atom.aliases.bash index f067697d..8d70cffa 100644 --- a/aliases/available/atom.aliases.bash +++ b/aliases/available/atom.aliases.bash @@ -4,3 +4,4 @@ about-alias 'Atom.io editor abbreviations' alias a='atom' alias ah='atom .' alias apmup='apm update --no-confirm' +alias apmi='apm install' diff --git a/aliases/available/homebrew-cask.aliases.bash b/aliases/available/homebrew-cask.aliases.bash index 37114bb1..f4c4836b 100644 --- a/aliases/available/homebrew-cask.aliases.bash +++ b/aliases/available/homebrew-cask.aliases.bash @@ -3,13 +3,13 @@ cite 'about-alias' about-alias 'homebrew-cask abbreviations' -alias bcup='brew-cask update' -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' -alias bced='brew-cask edit' +alias bcup='brew cask update' +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' +alias bced='brew cask edit' diff --git a/completion/available/docker.completion.bash b/completion/available/docker.completion.bash new file mode 100644 index 00000000..0e9d4b79 --- /dev/null +++ b/completion/available/docker.completion.bash @@ -0,0 +1,2038 @@ +#!/bin/bash +# +# bash completion file for core docker commands +# +# This script provides completion of: +# - commands and their options +# - container ids and names +# - image repos and tags +# - filepaths +# +# To enable the completions either: +# - place this file in /etc/bash_completion.d +# or +# - copy this file to e.g. ~/.docker-completion.sh and add the line +# below to your .bashrc after bash completion features are loaded +# . ~/.docker-completion.sh +# +# Configuration: +# +# For several commands, the amount of completions can be configured by +# setting environment variables. +# +# DOCKER_COMPLETION_SHOW_NETWORK_IDS +# "no" - Show names only (default) +# "yes" - Show names and ids +# +# You can tailor completion for the "events", "history", "inspect", "run", +# "rmi" and "save" commands by settings the following environment +# variables: +# +# DOCKER_COMPLETION_SHOW_IMAGE_IDS +# "none" - Show names only (default) +# "non-intermediate" - Show names and ids, but omit intermediate image IDs +# "all" - Show names and ids, including intermediate image IDs +# +# DOCKER_COMPLETION_SHOW_TAGS +# "yes" - include tags in completion options (default) +# "no" - don't include tags in completion options + +# +# Note: +# Currently, the completions will not work if the docker daemon is not +# bound to the default communication port/socket +# If the docker daemon is using a unix socket for communication your user +# must have access to the socket for the completions to function correctly +# +# Note for developers: +# Please arrange options sorted alphabetically by long name with the short +# options immediately following their corresponding long form. +# This order should be applied to lists, alternatives and code blocks. + +__docker_previous_extglob_setting=$(shopt -p extglob) +shopt -s extglob + +__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[@]}") ) + 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_complete_containers_running() { + __docker_complete_containers_all '.State.Running' +} + +__docker_complete_containers_stopped() { + __docker_complete_containers_all 'not .State.Running' +} + +__docker_complete_containers_pauseable() { + __docker_complete_containers_all 'and .State.Running (not .State.Paused)' +} + +__docker_complete_containers_unpauseable() { + __docker_complete_containers_all '.State.Paused' +} + +__docker_complete_container_names() { + local containers=( $(__docker_q ps -aq --no-trunc) ) + local names=( $(__docker_q inspect --format '{{.Name}}' "${containers[@]}") ) + names=( "${names[@]#/}" ) # trim off the leading "/" from the container names + COMPREPLY=( $(compgen -W "${names[*]}" -- "$cur") ) +} + +__docker_complete_container_ids() { + local containers=( $(__docker_q ps -aq) ) + COMPREPLY=( $(compgen -W "${containers[*]}" -- "$cur") ) +} + +__docker_complete_images() { + local images_args="" + + case "$DOCKER_COMPLETION_SHOW_IMAGE_IDS" in + all) + images_args="--no-trunc -a" + ;; + non-intermediate) + images_args="--no-trunc" + ;; + esac + + local repo_print_command + if [ "${DOCKER_COMPLETION_SHOW_TAGS:-yes}" = "yes" ]; then + repo_print_command='print $1; print $1":"$2' + else + repo_print_command='print $1' + fi + + local awk_script + case "$DOCKER_COMPLETION_SHOW_IMAGE_IDS" in + all|non-intermediate) + awk_script='NR>1 { print $3; if ($1 != "") { '"$repo_print_command"' } }' + ;; + none|*) + awk_script='NR>1 && $1 != "" { '"$repo_print_command"' }' + ;; + esac + + local images=$(__docker_q images $images_args | awk "$awk_script") + COMPREPLY=( $(compgen -W "$images" -- "$cur") ) + __ltrim_colon_completions "$cur" +} + +__docker_complete_image_repos() { + local repos="$(__docker_q images | awk 'NR>1 && $1 != "" { print $1 }')" + COMPREPLY=( $(compgen -W "$repos" -- "$cur") ) +} + +__docker_complete_image_repos_and_tags() { + local reposAndTags="$(__docker_q images | awk 'NR>1 && $1 != "" { print $1; print $1":"$2 }')" + COMPREPLY=( $(compgen -W "$reposAndTags" -- "$cur") ) + __ltrim_colon_completions "$cur" +} + +__docker_complete_containers_and_images() { + __docker_complete_containers_all + local containers=( "${COMPREPLY[@]}" ) + __docker_complete_images + COMPREPLY+=( "${containers[@]}" ) +} + +__docker_networks() { + # By default, only network names are completed. + # Set DOCKER_COMPLETION_SHOW_NETWORK_IDS=yes to also complete network IDs. + local fields='$2' + [ "${DOCKER_COMPLETION_SHOW_NETWORK_IDS}" = yes ] && fields='$1,$2' + __docker_q network ls --no-trunc | awk "NR>1 {print $fields}" +} + +__docker_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") ) +} + +__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_complete_volumes() { + COMPREPLY=( $(compgen -W "$(__docker_q volume ls -q)" -- "$cur") ) +} + +__docker_plugins() { + __docker_q info | sed -n "/^Plugins/,/^[^ ]/s/ $1: //p" +} + +__docker_complete_plugins() { + COMPREPLY=( $(compgen -W "$(__docker_plugins $1)" -- "$cur") ) +} + +# 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 + if [ -n "$argument_flags" ] && eval "case '${words[$counter]}' in $argument_flags) true ;; *) false ;; esac"; then + (( counter++ )) + # eat "=" in case of --option=arg syntax + [ "${words[$counter]}" = "=" ] && (( counter++ )) + else + case "${words[$counter]}" in + -*) + ;; + *) + break + ;; + esac + fi + + # Bash splits words at "=", retaining "=" as a word, examples: + # "--debug=false" => 3 words, "--log-opt syslog-facility=daemon" => 4 words + while [ "${words[$counter + 1]}" = "=" ] ; do + counter=$(( counter + 2)) + done + + (( counter++ )) + done + + echo $counter +} + +# 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 + case ${words[$counter]} in + $option_extglob ) + echo ${words[$counter + 1]} + break + ;; + esac + (( counter++ )) + done +} + +# 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 ) + local IFS='|' + echo "${parts[*]}" +} + +# 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. +# Locates the first occurrence of any of the subcommands contained in the +# first argument. In case of a match, calls the corresponding completion +# function and returns 0. +# If no match is found, 1 is returned. The calling function can then +# continue processing its completion. +# +# TODO if the preceding command has options that accept arguments and an +# argument is equal ot one of the subcommands, this is falsely detected as +# a match. +__docker_subcommands() { + local subcommands="$1" + + local counter=$(($command_pos + 1)) + while [ $counter -lt $cword ]; do + case "${words[$counter]}" in + $(__docker_to_extglob "$subcommands") ) + subcommand_pos=$counter + local subcommand=${words[$counter]} + local completions_func=_docker_${command}_${subcommand} + declare -F $completions_func >/dev/null && $completions_func + return 0 + ;; + esac + (( counter++ )) + done + return 1 +} + +# suppress trailing whitespace +__docker_nospace() { + # compopt is not available in ancient bash versions + type compopt &>/dev/null && compopt -o nospace +} + +__docker_complete_resolved_hostname() { + command -v host >/dev/null 2>&1 || return + 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. + 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 + SYS_PACCT + SYS_PTRACE + SYS_RAWIO + SYS_RESOURCE + SYS_TIME + SYS_TTY_CONFIG + WAKE_ALARM + " -- "$cur" ) ) +} + +__docker_complete_isolation() { + COMPREPLY=( $( compgen -W "default hyperv process" -- "$cur" ) ) +} + +__docker_complete_log_drivers() { + COMPREPLY=( $( compgen -W " + awslogs + fluentd + gelf + journald + json-file + none + splunk + syslog + " -- "$cur" ) ) +} + +__docker_complete_log_options() { + # see docs/reference/logging/index.md + local awslogs_options="awslogs-region awslogs-group awslogs-stream" + local fluentd_options="env fluentd-address labels tag" + local gelf_options="env gelf-address labels tag" + local journald_options="env labels" + local json_file_options="env labels max-file max-size" + local syslog_options="syslog-address syslog-facility tag" + local splunk_options="env labels splunk-caname splunk-capath splunk-index splunk-insecureskipverify splunk-source splunk-sourcetype splunk-token splunk-url tag" + + local all_options="$fluentd_options $gelf_options $journald_options $json_file_options $syslog_options $splunk_options" + + case $(__docker_value_of_option --log-driver) in + '') + COMPREPLY=( $( compgen -W "$all_options" -S = -- "$cur" ) ) + ;; + awslogs) + COMPREPLY=( $( compgen -W "$awslogs_options" -S = -- "$cur" ) ) + ;; + fluentd) + COMPREPLY=( $( compgen -W "$fluentd_options" -S = -- "$cur" ) ) + ;; + gelf) + COMPREPLY=( $( compgen -W "$gelf_options" -S = -- "$cur" ) ) + ;; + journald) + COMPREPLY=( $( compgen -W "$journald_options" -S = -- "$cur" ) ) + ;; + json-file) + COMPREPLY=( $( compgen -W "$json_file_options" -S = -- "$cur" ) ) + ;; + syslog) + COMPREPLY=( $( compgen -W "$syslog_options" -S = -- "$cur" ) ) + ;; + splunk) + COMPREPLY=( $( compgen -W "$splunk_options" -S = -- "$cur" ) ) + ;; + *) + return + ;; + esac + + __docker_nospace +} + +__docker_complete_log_driver_options() { + # "=" gets parsed to a word and assigned to either $cur or $prev depending on whether + # it is the last character or not. So we search for "xxx=" in the the last two words. + case "${words[$cword-2]}$prev=" in + *gelf-address=*) + COMPREPLY=( $( compgen -W "udp" -S "://" -- "${cur#=}" ) ) + __docker_nospace + return + ;; + *syslog-address=*) + COMPREPLY=( $( compgen -W "tcp udp unix" -S "://" -- "${cur#=}" ) ) + __docker_nospace + return + ;; + *syslog-facility=*) + COMPREPLY=( $( compgen -W " + auth + authpriv + cron + daemon + ftp + kern + local0 + local1 + local2 + local3 + local4 + local5 + local6 + local7 + lpr + mail + news + syslog + user + uucp + " -- "${cur#=}" ) ) + return + ;; + *splunk-url=*) + COMPREPLY=( $( compgen -W "http:// https://" -- "${cur#=}" ) ) + compopt -o nospace + __ltrim_colon_completions "${cur}" + return + ;; + *splunk-insecureskipverify=*) + COMPREPLY=( $( compgen -W "true false" -- "${cur#=}" ) ) + compopt -o nospace + return + ;; + esac + return 1 +} + +__docker_complete_log_levels() { + COMPREPLY=( $( compgen -W "debug info warn error fatal" -- "$cur" ) ) +} + +# a selection of the available signals that is most likely of interest in the +# context of docker containers. +__docker_complete_signals() { + local signals=( + SIGCONT + SIGHUP + SIGINT + SIGKILL + SIGQUIT + SIGSTOP + SIGTERM + SIGUSR1 + SIGUSR2 + ) + COMPREPLY=( $( compgen -W "${signals[*]} ${signals[*]#SIG}" -- "$( echo $cur | tr '[:lower:]' '[:upper:]')" ) ) +} + +# global options that may appear after the docker command +_docker_docker() { + local boolean_options=" + $global_boolean_options + --help + --version -v + " + + case "$prev" in + --config) + _filedir -d + return + ;; + --log-level|-l) + __docker_complete_log_levels + return + ;; + $(__docker_to_extglob "$global_options_with_args") ) + return + ;; + esac + + case "$cur" in + -*) + COMPREPLY=( $( compgen -W "$boolean_options $global_options_with_args" -- "$cur" ) ) + ;; + *) + local counter=$( __docker_pos_first_nonflag $(__docker_to_extglob "$global_options_with_args") ) + if [ $cword -eq $counter ]; then + COMPREPLY=( $( compgen -W "${commands[*]} help" -- "$cur" ) ) + fi + ;; + esac +} + +_docker_attach() { + case "$cur" in + -*) + COMPREPLY=( $( compgen -W "--help --no-stdin --sig-proxy" -- "$cur" ) ) + ;; + *) + local counter="$(__docker_pos_first_nonflag)" + if [ $cword -eq $counter ]; then + __docker_complete_containers_running + fi + ;; + esac +} + +_docker_build() { + local options_with_args=" + --build-arg + --cgroup-parent + --cpuset-cpus + --cpuset-mems + --cpu-shares + --cpu-period + --cpu-quota + --file -f + --isolation + --memory -m + --memory-swap + --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" + + 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") ) + 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_commit() { + case "$prev" in + --author|-a|--change|-c|--message|-m) + return + ;; + esac + + case "$cur" in + -*) + COMPREPLY=( $( compgen -W "--author -a --change -c --help --message -m --pause -p" -- "$cur" ) ) + ;; + *) + local counter=$(__docker_pos_first_nonflag '--author|-a|--change|-c|--message|-m') + + if [ $cword -eq $counter ]; then + __docker_complete_containers_all + return + fi + (( counter++ )) + + if [ $cword -eq $counter ]; then + __docker_complete_image_repos_and_tags + return + fi + ;; + esac +} + +_docker_cp() { + case "$cur" in + -*) + COMPREPLY=( $( compgen -W "--help" -- "$cur" ) ) + ;; + *) + local counter=$(__docker_pos_first_nonflag) + if [ $cword -eq $counter ]; then + case "$cur" in + *:) + return + ;; + *) + # combined container and filename completion + _filedir + local files=( ${COMPREPLY[@]} ) + + __docker_complete_containers_all + COMPREPLY=( $( compgen -W "${COMPREPLY[*]}" -S ':' ) ) + local containers=( ${COMPREPLY[@]} ) + + COMPREPLY=( $( compgen -W "${files[*]} ${containers[*]}" -- "$cur" ) ) + if [[ "$COMPREPLY" == *: ]]; then + __docker_nospace + fi + return + ;; + esac + fi + (( counter++ )) + + if [ $cword -eq $counter ]; then + if [ -e "$prev" ]; then + __docker_complete_containers_all + COMPREPLY=( $( compgen -W "${COMPREPLY[*]}" -S ':' ) ) + __docker_nospace + else + _filedir + fi + return + fi + ;; + esac +} + +_docker_create() { + _docker_run +} + +_docker_daemon() { + local boolean_options=" + $global_boolean_options + --disable-legacy-registry + --help + --icc=false + --ip-forward=false + --ip-masq=false + --iptables=false + --ipv6 + --selinux-enabled + --userland-proxy=false + " + local options_with_args=" + $global_options_with_args + --api-cors-header + --authz-plugin + --bip + --bridge -b + --cgroup-parent + --cluster-advertise + --cluster-store + --cluster-store-opt + --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 + --mtu + --pidfile -p + --registry-mirror + --storage-driver -s + --storage-opt + " + + case "$prev" in + --authz-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 "kv.cacertfile kv.certfile kv.keyfile" -S = -- "$cur" ) ) + __docker_nospace + return + ;; + --exec-root|--graph|-g) + _filedir -d + return + ;; + --log-driver) + __docker_complete_log_drivers + return + ;; + --pidfile|-p|--tlscacert|--tlscert|--tlskey) + _filedir + return + ;; + --storage-driver|-s) + COMPREPLY=( $( compgen -W "aufs btrfs devicemapper overlay vfs zfs" -- "$(echo $cur | tr '[:upper:]' '[:lower:]')" ) ) + return + ;; + --storage-opt) + local devicemapper_options=" + dm.basesize + dm.blkdiscard + dm.blocksize + dm.fs + dm.loopdatasize + dm.loopmetadatasize + 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 "$devicemapper_options $zfs_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 + ;; + $(__docker_to_extglob "$options_with_args") ) + return + ;; + esac + + __docker_complete_log_driver_options && return + + case "${words[$cword-2]}$prev=" in + # completions for --storage-opt + *dm.@(blkdiscard|override_udev_sync_check|use_deferred_@(removal|deletion))=*) + COMPREPLY=( $( compgen -W "false true" -- "${cur#=}" ) ) + return + ;; + *dm.fs=*) + COMPREPLY=( $( compgen -W "ext4 xfs" -- "${cur#=}" ) ) + return + ;; + *dm.thinpooldev=*) + _filedir + return + ;; + # completions for --cluster-store-opt + *kv.*file=*) + _filedir + return + ;; + esac + + case "$cur" in + -*) + COMPREPLY=( $( compgen -W "$boolean_options $options_with_args" -- "$cur" ) ) + ;; + esac +} + +_docker_diff() { + 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_events() { + case "$prev" in + --filter|-f) + COMPREPLY=( $( compgen -S = -W "container event image" -- "$cur" ) ) + __docker_nospace + return + ;; + --since|--until) + return + ;; + esac + + case "${words[$cword-2]}$prev=" in + *container=*) + cur="${cur#=}" + __docker_complete_containers_all + return + ;; + *event=*) + COMPREPLY=( $( compgen -W " + attach + commit + copy + create + delete + destroy + die + exec_create + exec_start + export + import + kill + oom + pause + pull + push + rename + resize + restart + start + stop + tag + top + unpause + untag + " -- "${cur#=}" ) ) + return + ;; + *image=*) + cur="${cur#=}" + __docker_complete_images + return + ;; + esac + + case "$cur" in + -*) + COMPREPLY=( $( compgen -W "--filter -f --help --since --until" -- "$cur" ) ) + ;; + esac +} + +_docker_exec() { + case "$prev" in + --user|-u) + return + ;; + esac + + case "$cur" in + -*) + COMPREPLY=( $( compgen -W "--detach -d --help --interactive -i --privileged -t --tty -u --user" -- "$cur" ) ) + ;; + *) + __docker_complete_containers_running + ;; + esac +} + +_docker_export() { + 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_help() { + local counter=$(__docker_pos_first_nonflag) + if [ $cword -eq $counter ]; then + COMPREPLY=( $( compgen -W "${commands[*]}" -- "$cur" ) ) + fi +} + +_docker_history() { + case "$cur" in + -*) + COMPREPLY=( $( compgen -W "--help --no-trunc --quiet -q" -- "$cur" ) ) + ;; + *) + local counter=$(__docker_pos_first_nonflag) + if [ $cword -eq $counter ]; then + __docker_complete_images + fi + ;; + esac +} + +_docker_images() { + case "$prev" in + --filter|-f) + COMPREPLY=( $( compgen -W "dangling=true label=" -- "$cur" ) ) + if [ "$COMPREPLY" = "label=" ]; then + __docker_nospace + fi + return + ;; + --format) + return + ;; + esac + + case "${words[$cword-2]}$prev=" in + *dangling=*) + COMPREPLY=( $( compgen -W "true false" -- "${cur#=}" ) ) + return + ;; + *label=*) + return + ;; + esac + + case "$cur" in + -*) + COMPREPLY=( $( compgen -W "--all -a --digests --filter -f --format --help --no-trunc --quiet -q" -- "$cur" ) ) + ;; + =) + 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() { + case "$prev" in + --signal|-s) + __docker_complete_signals + return + ;; + esac + + case "$cur" in + -*) + COMPREPLY=( $( compgen -W "--help --signal -s" -- "$cur" ) ) + ;; + *) + __docker_complete_containers_running + ;; + esac +} + +_docker_load() { + case "$prev" in + --input|-i) + _filedir + return + ;; + esac + + case "$cur" in + -*) + COMPREPLY=( $( compgen -W "--help --input -i" -- "$cur" ) ) + ;; + esac +} + +_docker_login() { + case "$prev" in + --email|-e|--password|-p|--username|-u) + return + ;; + esac + + case "$cur" in + -*) + COMPREPLY=( $( compgen -W "--email -e --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 "--follow -f --help --since --tail --timestamps -t" -- "$cur" ) ) + ;; + *) + local counter=$(__docker_pos_first_nonflag '--tail') + if [ $cword -eq $counter ]; then + __docker_complete_containers_all + fi + ;; + esac +} + +_docker_network_connect() { + 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_running + fi + ;; + esac +} + +_docker_network_create() { + case "$prev" in + --aux-address|--gateway|--ip-range|--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 + ;; + esac + + case "$cur" in + -*) + COMPREPLY=( $( compgen -W "--aux-address --driver -d --gateway --help --ip-range --ipam-driver --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() { + case "$prev" in + --filter|-f) + COMPREPLY=( $( compgen -S = -W "id name type" -- "$cur" ) ) + __docker_nospace + return + ;; + esac + + case "${words[$cword-2]}$prev=" in + *id=*) + cur="${cur#=}" + __docker_complete_network_ids + return + ;; + *name=*) + cur="${cur#=}" + __docker_complete_network_names + return + ;; + *type=*) + COMPREPLY=( $( compgen -W "builtin custom" -- "${cur#=}" ) ) + 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 + 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_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() { + case "$prev" in + --before|--since) + __docker_complete_containers_all + ;; + --filter|-f) + COMPREPLY=( $( compgen -S = -W "ancestor exited id label name status" -- "$cur" ) ) + __docker_nospace + return + ;; + --format|-n) + return + ;; + esac + + case "${words[$cword-2]}$prev=" in + *ancestor=*) + cur="${cur#=}" + __docker_complete_images + return + ;; + *id=*) + cur="${cur#=}" + __docker_complete_container_ids + return + ;; + *name=*) + cur="${cur#=}" + __docker_complete_container_names + return + ;; + *status=*) + COMPREPLY=( $( compgen -W "exited paused restarting running" -- "${cur#=}" ) ) + return + ;; + esac + + case "$cur" in + -*) + COMPREPLY=( $( compgen -W "--all -a --before --filter -f --format --help --latest -l -n --no-trunc --quiet -q --size -s --since" -- "$cur" ) ) + ;; + esac +} + +_docker_pull() { + case "$cur" in + -*) + COMPREPLY=( $( compgen -W "--all-tags -a --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 + ;; + esac +} + +_docker_push() { + 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 + fi + ;; + esac +} + +_docker_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_restart() { + case "$prev" in + --time|-t) + return + ;; + esac + + case "$cur" in + -*) + COMPREPLY=( $( compgen -W "--help --time -t" -- "$cur" ) ) + ;; + *) + __docker_complete_containers_all + ;; + esac +} + +_docker_rm() { + case "$cur" in + -*) + COMPREPLY=( $( compgen -W "--force -f --help --link -l --volumes -v" -- "$cur" ) ) + ;; + *) + for arg in "${COMP_WORDS[@]}"; do + case "$arg" in + --force|-f) + __docker_complete_containers_all + return + ;; + esac + done + __docker_complete_containers_stopped + ;; + esac +} + +_docker_rmi() { + case "$cur" in + -*) + COMPREPLY=( $( compgen -W "--force -f --help --no-prune" -- "$cur" ) ) + ;; + *) + __docker_complete_images + ;; + esac +} + +_docker_run() { + local options_with_args=" + --add-host + --attach -a + --blkio-weight + --blkio-weight-device + --cap-add + --cap-drop + --cgroup-parent + --cidfile + --cpu-period + --cpu-quota + --cpuset-cpus + --cpuset-mems + --cpu-shares + --device + --device-read-bps + --device-read-iops + --device-write-bps + --device-write-iops + --dns + --dns-opt + --dns-search + --entrypoint + --env -e + --env-file + --expose + --group-add + --hostname -h + --ipc + --isolation + --kernel-memory + --label-file + --label -l + --link + --log-driver + --log-opt + --mac-address + --memory -m + --memory-swap + --memory-swappiness + --memory-reservation + --name + --net + --oom-score-adj + --pid + --publish -p + --restart + --security-opt + --stop-signal + --tmpfs + --ulimit + --user -u + --uts + --volume-driver + --volumes-from + --volume -v + --workdir -w + " + + local boolean_options=" + --disable-content-trust=false + --help + --interactive -i + --oom-kill-disable + --privileged + --publish-all -P + --read-only + --tty -t + " + + local all_options="$options_with_args $boolean_options" + + [ "$command" = "run" ] && all_options="$all_options + --detach -d + --rm + --sig-proxy=false + " + + case "$prev" in + --add-host) + case "$cur" in + *:) + __docker_complete_resolved_hostname + return + ;; + esac + ;; + --attach|-a) + COMPREPLY=( $( compgen -W 'stdin stdout stderr' -- "$cur" ) ) + return + ;; + --cap-add|--cap-drop) + __docker_complete_capabilities + return + ;; + --cidfile|--env-file|--label-file) + _filedir + return + ;; + --device|--tmpfs|--volume|-v) + case "$cur" in + *:*) + # TODO somehow do _filedir for stuff inside the image, if it's already specified (which is also somewhat difficult to determine) + ;; + '') + COMPREPLY=( $( compgen -W '/' -- "$cur" ) ) + __docker_nospace + ;; + /*) + _filedir + __docker_nospace + ;; + esac + return + ;; + --env|-e) + COMPREPLY=( $( compgen -e -- "$cur" ) ) + __docker_nospace + return + ;; + --ipc) + case "$cur" in + *:*) + cur="${cur#*:}" + __docker_complete_containers_running + ;; + *) + COMPREPLY=( $( compgen -W 'host container:' -- "$cur" ) ) + if [ "$COMPREPLY" = "container:" ]; then + __docker_nospace + fi + ;; + esac + return + ;; + --isolation) + __docker_complete_isolation + return + ;; + --link) + case "$cur" in + *:*) + ;; + *) + __docker_complete_containers_running + COMPREPLY=( $( compgen -W "${COMPREPLY[*]}" -S ':' ) ) + __docker_nospace + ;; + esac + return + ;; + --log-driver) + __docker_complete_log_drivers + return + ;; + --log-opt) + __docker_complete_log_options + return + ;; + --net) + case "$cur" in + container:*) + local cur=${cur#*:} + __docker_complete_containers_all + ;; + *) + COMPREPLY=( $( compgen -W "$(__docker_plugins Network) $(__docker_networks) container:" -- "$cur") ) + if [ "${COMPREPLY[*]}" = "container:" ] ; then + __docker_nospace + fi + ;; + esac + return + ;; + --restart) + case "$cur" in + on-failure:*) + ;; + *) + COMPREPLY=( $( compgen -W "always no on-failure on-failure: unless-stopped" -- "$cur") ) + ;; + esac + return + ;; + --security-opt) + case "$cur" in + label:*:*) + ;; + label:*) + local cur=${cur##*:} + COMPREPLY=( $( compgen -W "user: role: type: level: disable" -- "$cur") ) + if [ "${COMPREPLY[*]}" != "disable" ] ; then + __docker_nospace + fi + ;; + *) + COMPREPLY=( $( compgen -W "label apparmor seccomp" -S ":" -- "$cur") ) + __docker_nospace + ;; + esac + return + ;; + --volume-driver) + __docker_complete_plugins Volume + return + ;; + --volumes-from) + __docker_complete_containers_all + return + ;; + $(__docker_to_extglob "$options_with_args") ) + return + ;; + esac + + __docker_complete_log_driver_options && return + + 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 + __docker_complete_images + fi + ;; + esac +} + +_docker_save() { + case "$prev" in + --output|-o) + _filedir + return + ;; + esac + + case "$cur" in + -*) + COMPREPLY=( $( compgen -W "--help --output -o" -- "$cur" ) ) + ;; + *) + __docker_complete_images + ;; + esac +} + +_docker_search() { + case "$prev" in + --stars|-s) + return + ;; + esac + + case "$cur" in + -*) + COMPREPLY=( $( compgen -W "--automated --help --no-trunc --stars -s" -- "$cur" ) ) + ;; + esac +} + +_docker_start() { + case "$cur" in + -*) + COMPREPLY=( $( compgen -W "--attach -a --help --interactive -i" -- "$cur" ) ) + ;; + *) + __docker_complete_containers_stopped + ;; + esac +} + +_docker_stats() { + case "$cur" in + -*) + COMPREPLY=( $( compgen -W "--all -a --help --no-stream" -- "$cur" ) ) + ;; + *) + __docker_complete_containers_running + ;; + esac +} + +_docker_stop() { + case "$prev" in + --time|-t) + return + ;; + esac + + case "$cur" in + -*) + COMPREPLY=( $( compgen -W "--help --time -t" -- "$cur" ) ) + ;; + *) + __docker_complete_containers_running + ;; + esac +} + +_docker_tag() { + case "$cur" in + -*) + COMPREPLY=( $( compgen -W "--force -f --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 + fi + ;; + esac +} + +_docker_unpause() { + case "$cur" in + -*) + COMPREPLY=( $( compgen -W "--help" -- "$cur" ) ) + ;; + *) + local counter=$(__docker_pos_first_nonflag) + if [ $cword -eq $counter ]; then + __docker_complete_containers_unpauseable + fi + ;; + esac +} + +_docker_update() { + local options_with_args=" + --blkio-weight + --cpu-period + --cpu-quota + --cpuset-cpus + --cpuset-mems + --cpu-shares + --kernel-memory + --memory -m + --memory-reservation + --memory-swap + " + + local boolean_options=" + --help + " + + local all_options="$options_with_args $boolean_options" + + case "$prev" in + $(__docker_to_extglob "$options_with_args") ) + return + ;; + esac + + case "$cur" in + -*) + COMPREPLY=( $( compgen -W "$all_options" -- "$cur" ) ) + ;; + *) + __docker_complete_containers_all + ;; + esac +} + +_docker_top() { + case "$cur" in + -*) + COMPREPLY=( $( compgen -W "--help" -- "$cur" ) ) + ;; + *) + local counter=$(__docker_pos_first_nonflag) + if [ $cword -eq $counter ]; then + __docker_complete_containers_running + fi + ;; + esac +} + +_docker_version() { + case "$cur" in + -*) + COMPREPLY=( $( compgen -W "--help" -- "$cur" ) ) + ;; + esac +} + +_docker_volume_create() { + case "$prev" in + --driver|-d) + __docker_complete_plugins Volume + return + ;; + --name|--opt|-o) + return + ;; + esac + + case "$cur" in + -*) + COMPREPLY=( $( compgen -W "--driver -d --help --name --opt -o" -- "$cur" ) ) + ;; + esac +} + +_docker_volume_inspect() { + case "$prev" in + --format|-f) + return + ;; + esac + + case "$cur" in + -*) + COMPREPLY=( $( compgen -W "--format -f --help" -- "$cur" ) ) + ;; + *) + __docker_complete_volumes + ;; + esac +} + +_docker_volume_ls() { + case "$prev" in + --filter|-f) + COMPREPLY=( $( compgen -W "dangling=true" -- "$cur" ) ) + return + ;; + esac + + case "$cur" in + -*) + COMPREPLY=( $( compgen -W "--filter -f --help --quiet -q" -- "$cur" ) ) + ;; + esac +} + +_docker_volume_rm() { + case "$cur" in + -*) + COMPREPLY=( $( compgen -W "--help" -- "$cur" ) ) + ;; + *) + __docker_complete_volumes + ;; + esac +} + +_docker_volume() { + local subcommands=" + create + inspect + ls + rm + " + __docker_subcommands "$subcommands" && return + + case "$cur" in + -*) + COMPREPLY=( $( compgen -W "--help" -- "$cur" ) ) + ;; + *) + COMPREPLY=( $( compgen -W "$subcommands" -- "$cur" ) ) + ;; + esac +} + +_docker_wait() { + case "$cur" in + -*) + COMPREPLY=( $( compgen -W "--help" -- "$cur" ) ) + ;; + *) + __docker_complete_containers_all + ;; + esac +} + +_docker() { + local previous_extglob_setting=$(shopt -p extglob) + shopt -s extglob + + local commands=( + attach + build + commit + cp + create + daemon + diff + events + exec + export + history + images + import + info + inspect + kill + load + login + logout + logs + network + pause + port + ps + pull + push + rename + restart + rm + rmi + run + save + search + start + stats + stop + tag + top + unpause + update + version + volume + wait + ) + + # These options are valid as global options for all client commands + # and valid as command options for `docker daemon` + local global_boolean_options=" + --debug -D + --tls + --tlsverify + " + local global_options_with_args=" + --config + --host -H + --log-level -l + --tlscacert + --tlscert + --tlskey + " + + local host config + + COMPREPLY=() + local cur prev words cword + _get_comp_words_by_ref -n : cur prev words cword + + local command='docker' command_pos=0 subcommand_pos + local counter=1 + while [ $counter -lt $cword ]; do + case "${words[$counter]}" in + # save host so that completion can use custom daemon + --host|-H) + (( counter++ )) + host="${words[$counter]}" + ;; + # save config so that completion can use custom configuration directories + --config) + (( counter++ )) + config="${words[$counter]}" + ;; + $(__docker_to_extglob "$global_options_with_args") ) + (( counter++ )) + ;; + -*) + ;; + =) + (( counter++ )) + ;; + *) + command="${words[$counter]}" + command_pos=$counter + break + ;; + esac + (( counter++ )) + done + + local completions_func=_docker_${command} + declare -F $completions_func >/dev/null && $completions_func + + eval "$previous_extglob_setting" + return 0 +} + +eval "$__docker_previous_extglob_setting" +unset __docker_previous_extglob_setting + +complete -F _docker docker diff --git a/completion/available/jboss7.completion.bash b/completion/available/jboss7.completion.bash new file mode 100644 index 00000000..66d07179 --- /dev/null +++ b/completion/available/jboss7.completion.bash @@ -0,0 +1,141 @@ +# Completions for JBoss Application Server 7 (EAP 6) +# VERSION: 0.6 +# DATE: 2012-10-30 +# rparree-at-edc4it-dot-com + + + + +_serverProfiles(){ + if [[ $COMP_WORDS == *standalone.sh* ]] + then + serverdir="../standalone/configuration/" + else + # assume is domain.sh + serverdir="../domain/configuration/" + fi + + for i in ${!COMP_WORDS[*]} + do + if [[ "${COMP_WORDS[i]}" == "-Djboss.server.base.dir" || "${COMP_WORDS[i]}" == "-Djboss.domain.base.dir" ]]; then + serverdir="${COMP_WORDS[i+2]}/configuration" + fi + + done + if [ -d "${serverdir}" ] + then + + IFS=$'\n' tmp="$(ls "${serverdir}" | grep xml)" + local fls="${tmp[@]// /\ }" + unset IFS + COMPREPLY=( $(compgen -W "${fls} initial boot last v" -- "$cur" )) + fi +} + +_bindingAddress(){ + # from /etc/bash_completion.d/ssh + COMPREPLY=( "${COMPREPLY[@]}" $( compgen -W \ + "0.0.0.0 $( PATH="$PATH:/sbin" ifconfig -a | \ + sed -ne 's/.*addr:\([^[:space:]]*\).*/\1/p' \ + -ne 's/.*inet[[:space:]]\{1,\}\([^[:space:]]*\).*/\1/p' )" \ + -- "$cur" ) ) +} + +_jboss(){ + + local cur prev words cword + COMPREPLY=() + _get_comp_words_by_ref -n = cur prev words cword + + case $cur in + + -Djboss.socket.binding.port-offset=*) + cur=${cur#*=} + #static list of common bindings sets + local bindings="100 200 300 400 10000 20000 30000 40000" + COMPREPLY=( $(compgen -W "${bindings}" -- ${cur}) ) + return 0 + ;; + -Djboss.default.jgroups.stack=*) + cur=${cur#*=} + #static list of standard JGroups stacks + local stacks="udp udp-async udp-sync tcp tcp-sync" + COMPREPLY=( $(compgen -W "${stacks}" -- ${cur}) ) + return 0 + ;; + + -Dorg.jboss.ejb3.remoting.IsLocalInterceptor.passByRef=*|-Dcom.sun.management.jmxremote.authenticate=*|-Dcom.sun.management.jmxremote.ssl=*) + cur=${cur#*=} + local booleans="true false" + COMPREPLY=( $(compgen -W "${booleans}" -- ${cur}) ) + return 0 + ;; + + -Djboss.server.base.dir=*|-Djboss.home.dir=*|-Djboss.domain.base.dir=*) + cur=${cur#*=} + _filedir -d + return 0 + ;; + + -Djboss.domain.master.address=*|-Djboss.bind.address*=*) + cur=${cur#*=} + _bindingAddress + return 0 + ;; + --server-config=*|-c=|--host-config=*) + cur=${cur#*=} + _serverProfiles + return 0 + + + esac + + + case $prev in + -u) + # a few from RFC 2365 IPv4 Local Scope () + local addresses="239.255.0.1 239.255.0.2 239.255.0.3" + COMPREPLY=( $(compgen -W "${addresses}" -- ${cur}) ) + return 0 + ;; + -b*) + _bindingAddress + return 0 + ;; + -c) + _serverProfiles + return 0 + ;; + *) + ;; + esac + # *** from jboss5 ******************** + # *** -modulepath -c -m -g -l -d -p -n -B -L -C -Djboss.platform.mbeanserver -Djboss.server.base.directory + # *** -Djboss.Domain -Djboss.modcluster.proxyList -Djboss.jvmRoute -Djboss.default.jgroups.stack -Dorg.jboss.ejb3.remoting.IsLocalInterceptor.passByRef -Djboss.platform.mbeanserver -Dcom.sun.management.jmxremote.port -Dcom.sun.management.jmxremote.ssl + # ************************************* + + # standard commands for standalone and domain mode + local commandsWithoutEqualSign='-b -bmanagement -bunsecure -bpublic --admin-only -h -help -u -version -V -v' + local commandsWithEqualSign='-P -Djboss.node.name -Djboss.home.dir -Djboss.socket.binding.port-offset -Djboss.bind.address.management -Djboss.bind.address -Djboss.bind.address.unsecure' + + if [[ $COMP_WORDS == *standalone.sh* ]] + then + commandsWithoutEqualSign="${commandsWithoutEqualSign} -c" + commandsWithEqualSign="${commandsWithEqualSign} --server-config -Djboss.server.base.dir -c" + else + # assume is domain.sh + commandsWithoutEqualSign="${commandsWithoutEqualSign} --backup --cached-dc" + commandsWithEqualSign="${commandsWithEqualSign} -Djboss.domain.master.address --host-config -Djboss.domain.master.port -Djboss.domain.base.dir " + fi + + + + + COMPREPLY=( $( compgen -W "$commandsWithoutEqualSign" -- "$cur" ) + $( compgen -W "$commandsWithEqualSign" -S '=' -- "$cur" ) ) + return 0 + + +} +complete -o nospace -F _jboss standalone.sh +complete -o nospace -F _jboss domain.sh diff --git a/completion/available/system.completion.bash b/completion/available/system.completion.bash new file mode 100644 index 00000000..aeaa5375 --- /dev/null +++ b/completion/available/system.completion.bash @@ -0,0 +1,16 @@ +#!/usr/bin/env bash + +# Loads the system's Bash completion modules. +# If Homebrew is installed (OS X), its Bash completion modules are loaded. + +if [ -f /etc/bash_completion ]; then + . /etc/bash_completion +fi + +if [ $(uname) = "Darwin" ] && command -v brew &>/dev/null ; then + BREW_PREFIX=$(brew --prefix) + + if [ -f "$BREW_PREFIX"/etc/bash_completion ]; then + . "$BREW_PREFIX"/etc/bash_completion + fi +fi diff --git a/completion/available/terraform.completion.bash b/completion/available/terraform.completion.bash new file mode 100644 index 00000000..729c72b6 --- /dev/null +++ b/completion/available/terraform.completion.bash @@ -0,0 +1,25 @@ +#!/usr/bin/env bash +# Bash Terraform completion + +_terraform() +{ + local cmds cur colonprefixes + cmds="apply destroy get graph init output plan push \ + refresh remote show taint version" + + 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 + + return 0 +} && +complete -F _terraform terraform diff --git a/install.sh b/install.sh index 791abe79..17250eb0 100755 --- a/install.sh +++ b/install.sh @@ -13,30 +13,50 @@ esac BACKUP_FILE=$CONFIG_FILE.bak if [ -e "$HOME/$BACKUP_FILE" ]; then - echo -e "\033[0;33mBackup file already exists. Make sure to backup your .bashrc before running this installation.\033[0m" >&2 - while true - do - read -e -n 1 -r -p "Would you like to overwrite the existing backup? This will delete your existing backup file ($HOME/$BACKUP_FILE) [y/N] " RESP - case $RESP in - [yY]) - break - ;; - [nN]|"") - echo -e "\033[91mInstallation aborted. Please come back soon!\033[m" - exit 1 - ;; - *) - echo -e "\033[91mPlease choose y or n.\033[m" - ;; - esac - done + echo -e "\033[0;33mBackup file already exists. Make sure to backup your .bashrc before running this installation.\033[0m" >&2 + while true + do + read -e -n 1 -r -p "Would you like to overwrite the existing backup? This will delete your existing backup file ($HOME/$BACKUP_FILE) [y/N] " RESP + case $RESP in + [yY]) + break + ;; + [nN]|"") + echo -e "\033[91mInstallation aborted. Please come back soon!\033[m" + exit 1 + ;; + *) + echo -e "\033[91mPlease choose y or n.\033[m" + ;; + esac + done fi -test -w "$HOME/$CONFIG_FILE" && - cp -a "$HOME/$CONFIG_FILE" "$HOME/$CONFIG_FILE.bak" && - echo -e "\033[0;32mYour original $CONFIG_FILE has been backed up to $CONFIG_FILE.bak\033[0m" +while true +do + read -e -n 1 -r -p "Would you like to keep your $CONFIG_FILE and append bash-it templates at the end? [y/N] " choice + case $choice in + [yY]) + test -w "$HOME/$CONFIG_FILE" && + cp -aL "$HOME/$CONFIG_FILE" "$HOME/$CONFIG_FILE.bak" && + echo -e "\033[0;32mYour original $CONFIG_FILE has been backed up to $CONFIG_FILE.bak\033[0m" -sed "s|{{BASH_IT}}|$BASH_IT|" "$BASH_IT/template/bash_profile.template.bash" > "$HOME/$CONFIG_FILE" + (sed "s|{{BASH_IT}}|$BASH_IT|" "$BASH_IT/template/bash_profile.template.bash" | tail -n +2) >> "$HOME/$CONFIG_FILE" + echo -e "\033[0;32mBash-it template has been added to your $CONFIG_FILE\033[0m" + break + ;; + [nN]|"") + test -w "$HOME/$CONFIG_FILE" && + cp -aL "$HOME/$CONFIG_FILE" "$HOME/$CONFIG_FILE.bak" && + echo -e "\033[0;32mYour original $CONFIG_FILE has been backed up to $CONFIG_FILE.bak\033[0m" + sed "s|{{BASH_IT}}|$BASH_IT|" "$BASH_IT/template/bash_profile.template.bash" > "$HOME/$CONFIG_FILE" + break + ;; + *) + echo -e "\033[91mPlease choose y or n.\033[m" + ;; + esac +done echo -e "\033[0;32mCopied the template $CONFIG_FILE into ~/$CONFIG_FILE, edit this file to customize bash-it\033[0m" @@ -47,9 +67,9 @@ function load_one() { dest="${BASH_IT}/${file_type}/enabled/${file_to_enable}" if [ ! -e "${dest}" ]; then - ln -sf "../available/${file_to_enable}" "${dest}" + ln -sf "../available/${file_to_enable}" "${dest}" else - echo "File ${dest} exists, skipping" + echo "File ${dest} exists, skipping" fi } @@ -89,6 +109,8 @@ else echo "" echo -e "\033[0;32mEnabling sane defaults\033[0m" load_one completion bash-it.completion.bash + load_one completion system.completion.bash + load_one plugins base.plugin.bash load_one plugins alias-completion.plugin.bash load_one aliases general.aliases.bash fi diff --git a/lib/appearance.bash b/lib/appearance.bash index fecb4686..05e0e40a 100644 --- a/lib/appearance.bash +++ b/lib/appearance.bash @@ -7,7 +7,15 @@ export GREP_COLOR='1;33' # colored ls export LSCOLORS='Gxfxcxdxdxegedabagacad' +if [[ -z "$CUSTOM_THEME_DIR" ]]; then + CUSTOM_THEME_DIR="${BASH_IT}/custom/themes" +fi + # Load the theme if [[ $BASH_IT_THEME ]]; then - source "$BASH_IT/themes/$BASH_IT_THEME/$BASH_IT_THEME.theme.bash" + if [[ -f "$CUSTOM_THEME_DIR/$BASH_IT_THEME/$BASH_IT_THEME.theme.bash" ]]; then + source "$CUSTOM_THEME_DIR/$BASH_IT_THEME/$BASH_IT_THEME.theme.bash" + else + source "$BASH_IT/themes/$BASH_IT_THEME/$BASH_IT_THEME.theme.bash" + fi fi diff --git a/plugins/available/docker-machine.plugin.bash b/plugins/available/docker-machine.plugin.bash index fc2dc44d..95827f42 100644 --- a/plugins/available/docker-machine.plugin.bash +++ b/plugins/available/docker-machine.plugin.bash @@ -1,11 +1,13 @@ cite about-plugin about-plugin 'Helpers to get Docker setup correctly for docker-machine' +[ -z ${BASH_IT_DOCKER_MACHINE+x} ] && BASH_IT_DOCKER_MACHINE='dev' + # Note, this might need to be different if you use a machine other than 'dev' if [[ `uname -s` == "Darwin" ]]; then # check if dev machine is running - docker-machine ls | grep --quiet 'dev.*Running' + docker-machine ls | grep --quiet "$BASH_IT_DOCKER_MACHINE.*Running" if [[ "$?" = "0" ]]; then - eval "$(docker-machine env dev)" + eval "$(docker-machine env $BASH_IT_DOCKER_MACHINE)" fi fi diff --git a/plugins/available/extract.plugin.bash b/plugins/available/extract.plugin.bash index bb520451..e357814a 100644 --- a/plugins/available/extract.plugin.bash +++ b/plugins/available/extract.plugin.bash @@ -1,27 +1,59 @@ cite about-plugin about-plugin 'one command to extract them all...' -extract () { - if [ $# -ne 1 ] - then - echo "Error: No file specified." - return 1 - fi - if [ -f $1 ] ; then - case $1 in - *.tar.bz2) tar xvjf $1 ;; - *.tar.gz) tar xvzf $1 ;; - *.bz2) bunzip2 $1 ;; - *.rar) unrar x $1 ;; - *.gz) gunzip $1 ;; - *.tar) tar xvf $1 ;; - *.tbz2) tar xvjf $1 ;; - *.tgz) tar xvzf $1 ;; - *.zip) unzip $1 ;; - *.Z) uncompress $1 ;; - *.7z) 7z x $1 ;; - *) echo "'$1' cannot be extracted via extract" ;; - esac - else - echo "'$1' is not a valid file" - fi + +# extract file(s) from compressed status +extract() { + local opt + local OPTIND=1 + while getopts "hv" opt; do + case "$opt" in + h) + cat < + options: + -h show this message and exit + -v verbosely list files processed +End-Of-Usage + return + ;; + v) + local -r verbose='v' + ;; + ?) + extract -h >&2 + return 1 + ;; + esac + done + shift $((OPTIND-1)) + + [ $# -eq 0 ] && extract -h && return 1 + while [ $# -gt 0 ]; do + if [ -f "$1" ]; then + case "$1" in + *.tar.bz2|*.tbz|*.tbz2) tar "x${verbose}jf" "$1" ;; + *.tar.gz|*.tgz) tar "x${verbose}zf" "$1" ;; + *.tar.xz) xz --decompress "$1"; set -- "$@" "${1:0:-3}" ;; + *.tar.Z) uncompress "$1"; set -- "$@" "${1:0:-2}" ;; + *.bz2) bunzip2 "$1" ;; + *.deb) dpkg-deb -x${verbose} "$1" "${1:0:-4}" ;; + *.pax.gz) gunzip "$1"; set -- "$@" "${1:0:-3}" ;; + *.gz) gunzip "$1" ;; + *.pax) pax -r -f "$1" ;; + *.pkg) pkgutil --expand "$1" "${1:0:-4}" ;; + *.rar) unrar x "$1" ;; + *.rpm) rpm2cpio "$1" | cpio -idm${verbose} ;; + *.tar) tar "x${verbose}f" "$1" ;; + *.txz) mv "$1" "${1:0:-4}.tar.xz"; set -- "$@" "${1:0:-4}.tar.xz" ;; + *.xz) xz --decompress "$1" ;; + *.zip|*.war|*.jar) unzip "$1" ;; + *.Z) uncompress "$1" ;; + *.7z) 7za x "$1" ;; + *) echo "'$1' cannot be extracted via extract" >&2;; + esac + else + echo "extract: '$1' is not a valid file" >&2 + fi + shift + done } diff --git a/plugins/available/nvm.plugin.bash b/plugins/available/nvm.plugin.bash index 632de967..3959c236 100644 --- a/plugins/available/nvm.plugin.bash +++ b/plugins/available/nvm.plugin.bash @@ -1,318 +1,28 @@ -# Node Version Manager -# Implemented as a bash function -# To use source this file from your bash profile +# Bash-it no longer bundles nvm, as this was quickly becoming outdated. # -# Implemented by Tim Caswell -# with much bash help from Matthew Ranney +# Please install nvm from https://github.com/creationix/nvm.git if you want to use it. cite about-plugin -about-plugin 'node version manager, as a bash function' +about-plugin 'node version manager configuration' export NVM_DIR="$HOME/.nvm" - -if [ ! -d "$NVM_DIR" ]; then - mkdir $NVM_DIR +# This loads nvm +if command -v brew &>/dev/null && [ -s $(brew --prefix nvm)/nvm.sh ] +then + . $(brew --prefix nvm)/nvm.sh +else + [ -s "$NVM_DIR/nvm.sh" ] && . "$NVM_DIR/nvm.sh" fi -# Auto detect the NVM_DIR -if [ ! -d "$NVM_DIR" ]; then - export NVM_DIR=$(cd $(dirname ${BASH_SOURCE[0]:-$0}); pwd) +if ! command -v nvm &>/dev/null +then + function nvm() { + echo "Bash-it no longer bundles the nvm script. Please install the latest version from" + echo "" + echo "https://github.com/creationix/nvm.git" + echo "" + echo "if you want to use nvm. You can keep this plugin enabled once you have installed nvm." + } + + nvm fi - -# Expand a version using the version cache -nvm_version() -{ - PATTERN=$1 - # The default version is the current one - if [ ! "$PATTERN" ]; then - PATTERN='current' - fi - - VERSION=`nvm_ls $PATTERN | tail -n1` - echo "$VERSION" - - if [ "$VERSION" = 'N/A' ]; then - return 13 - fi -} - -nvm_ls() -{ - PATTERN=$1 - VERSIONS='' - if [ "$PATTERN" = 'current' ]; then - echo `node -v 2>/dev/null` - return - fi - - if [ -f "$NVM_DIR/alias/$PATTERN" ]; then - nvm_version `cat $NVM_DIR/alias/$PATTERN` - return - fi - # If it looks like an explicit version, don't do anything funny - if [[ "$PATTERN" == v?*.?*.?* ]]; then - VERSIONS="$PATTERN" - else - VERSIONS=`(cd $NVM_DIR; \ls -d v${PATTERN}* 2>/dev/null) | sort -t. -k 1.2,1n -k 2,2n -k 3,3n` - fi - if [ ! "$VERSIONS" ]; then - echo "N/A" - return - fi - echo "$VERSIONS" - return -} - -print_versions() -{ - OUTPUT='' - for VERSION in $1; do - PADDED_VERSION=`printf '%10s' $VERSION` - if [[ -d "$NVM_DIR/$VERSION" ]]; then - PADDED_VERSION="\033[0;34m$PADDED_VERSION\033[0m" - fi - OUTPUT="$OUTPUT\n$PADDED_VERSION" - done - echo -e "$OUTPUT" | column -} - -nvm() -{ - about 'Node Version Manager' - param '1: command, see nvm help' - group 'nvm' - - if [ $# -lt 1 ]; then - nvm help - return - fi - case $1 in - "help" ) - echo - echo "Node Version Manager" - echo - echo "Usage:" - echo " nvm help Show this message" - echo " nvm install Download and install a " - echo " nvm uninstall Uninstall a version" - echo " nvm use Modify PATH to use " - echo " nvm run [] Run with as arguments" - echo " nvm ls List installed versions" - echo " nvm ls List versions matching a given description" - echo " nvm deactivate Undo effects of NVM on current shell" - echo " nvm alias [] Show all aliases beginning with " - echo " nvm alias Set an alias named pointing to " - echo " nvm unalias Deletes the alias named " - echo " nvm copy-packages Install global NPM packages contained in to current version" - echo - echo "Example:" - echo " nvm install v0.4.12 Install a specific version number" - echo " nvm use 0.2 Use the latest available 0.2.x release" - echo " nvm run 0.4.12 myApp.js Run myApp.js using node v0.4.12" - echo " nvm alias default 0.4 Auto use the latest installed v0.4.x version" - echo - ;; - "install" ) - if [ ! `which curl` ]; then - echo 'NVM Needs curl to proceed.' >&2; - fi - - if [ $# -ne 2 ]; then - nvm help - return - fi - VERSION=`nvm_version $2` - - [ -d "$NVM_DIR/$VERSION" ] && echo "$VERSION is already installed." && return - - tarball='' - if [ "`curl -Is "http://nodejs.org/dist/$VERSION/node-$VERSION.tar.gz" | grep '200 OK'`" != '' ]; then - tarball="http://nodejs.org/dist/$VERSION/node-$VERSION.tar.gz" - elif [ "`curl -Is "http://nodejs.org/dist/node-$VERSION.tar.gz" | grep '200 OK'`" != '' ]; then - tarball="http://nodejs.org/dist/node-$VERSION.tar.gz" - fi - if ( - [ ! -z $tarball ] && \ - mkdir -p "$NVM_DIR/src" && \ - cd "$NVM_DIR/src" && \ - curl -C - --progress-bar $tarball -o "node-$VERSION.tar.gz" && \ - tar -xzf "node-$VERSION.tar.gz" && \ - cd "node-$VERSION" && \ - ./configure --prefix="$NVM_DIR/$VERSION" && \ - make && \ - rm -f "$NVM_DIR/$VERSION" 2>/dev/null && \ - make install - ) - then - nvm use $VERSION - if ! which npm ; then - echo "Installing npm..." - if [[ "`expr match $VERSION '\(^v0\.1\.\)'`" != '' ]]; then - echo "npm requires node v0.2.3 or higher" - elif [[ "`expr match $VERSION '\(^v0\.2\.\)'`" != '' ]]; then - if [[ "`expr match $VERSION '\(^v0\.2\.[0-2]$\)'`" != '' ]]; then - echo "npm requires node v0.2.3 or higher" - else - curl http://npmjs.org/install.sh | clean=yes npm_install=0.2.19 sh - fi - else - curl http://npmjs.org/install.sh | clean=yes sh - fi - fi - else - echo "nvm: install $VERSION failed!" - fi - ;; - "uninstall" ) - [ $# -ne 2 ] && nvm help && return - if [[ $2 == `nvm_version` ]]; then - echo "nvm: Cannot uninstall currently-active node version, $2." - return - fi - VERSION=`nvm_version $2` - if [ ! -d $NVM_DIR/$VERSION ]; then - echo "$VERSION version is not installed yet" - return; - fi - - # Delete all files related to target version. - (mkdir -p "$NVM_DIR/src" && \ - cd "$NVM_DIR/src" && \ - rm -rf "node-$VERSION" 2>/dev/null && \ - rm -f "node-$VERSION.tar.gz" 2>/dev/null && \ - rm -rf "$NVM_DIR/$VERSION" 2>/dev/null) - echo "Uninstalled node $VERSION" - - # Rm any aliases that point to uninstalled version. - for A in `grep -l $VERSION $NVM_DIR/alias/*` - do - nvm unalias `basename $A` - done - - ;; - "deactivate" ) - if [[ $PATH == *$NVM_DIR/*/bin* ]]; then - export PATH=${PATH%$NVM_DIR/*/bin*}${PATH#*$NVM_DIR/*/bin:} - hash -r - echo "$NVM_DIR/*/bin removed from \$PATH" - else - echo "Could not find $NVM_DIR/*/bin in \$PATH" - fi - if [[ $MANPATH == *$NVM_DIR/*/share/man* ]]; then - export MANPATH=${MANPATH%$NVM_DIR/*/share/man*}${MANPATH#*$NVM_DIR/*/share/man:} - echo "$NVM_DIR/*/share/man removed from \$MANPATH" - else - echo "Could not find $NVM_DIR/*/share/man in \$MANPATH" - fi - ;; - "use" ) - if [ $# -ne 2 ]; then - nvm help - return - fi - VERSION=`nvm_version $2` - if [ ! -d $NVM_DIR/$VERSION ]; then - echo "$VERSION version is not installed yet" - return; - fi - if [[ $PATH == *$NVM_DIR/*/bin* ]]; then - PATH=${PATH%$NVM_DIR/*/bin*}$NVM_DIR/$VERSION/bin${PATH#*$NVM_DIR/*/bin} - else - PATH="$NVM_DIR/$VERSION/bin:$PATH" - fi - if [[ $MANPATH == *$NVM_DIR/*/share/man* ]]; then - MANPATH=${MANPATH%$NVM_DIR/*/share/man*}$NVM_DIR/$VERSION/share/man${MANPATH#*$NVM_DIR/*/share/man} - else - MANPATH="$NVM_DIR/$VERSION/share/man:$MANPATH" - fi - export PATH - hash -r - export MANPATH - export NVM_PATH="$NVM_DIR/$VERSION/lib/node" - export NVM_BIN="$NVM_DIR/$VERSION/bin" - echo "Now using node $VERSION" - ;; - "run" ) - # run given version of node - if [ $# -lt 2 ]; then - nvm help - return - fi - VERSION=`nvm_version $2` - if [ ! -d $NVM_DIR/$VERSION ]; then - echo "$VERSION version is not installed yet" - return; - fi - echo "Running node $VERSION" - $NVM_DIR/$VERSION/bin/node "${@:3}" - ;; - "ls" | "list" ) - print_versions "`nvm_ls $2`" - if [ $# -eq 1 ]; then - echo -ne "current: \t"; nvm_version current - nvm alias - fi - return - ;; - "alias" ) - mkdir -p $NVM_DIR/alias - if [ $# -le 2 ]; then - (cd $NVM_DIR/alias && for ALIAS in `\ls $2* 2>/dev/null`; do - DEST=`cat $ALIAS` - VERSION=`nvm_version $DEST` - if [ "$DEST" = "$VERSION" ]; then - echo "$ALIAS -> $DEST" - else - echo "$ALIAS -> $DEST (-> $VERSION)" - fi - done) - return - fi - if [ ! "$3" ]; then - rm -f $NVM_DIR/alias/$2 - echo "$2 -> *poof*" - return - fi - mkdir -p $NVM_DIR/alias - VERSION=`nvm_version $3` - if [ $? -ne 0 ]; then - echo "! WARNING: Version '$3' does not exist." >&2 - fi - echo $3 > "$NVM_DIR/alias/$2" - if [ ! "$3" = "$VERSION" ]; then - echo "$2 -> $3 (-> $VERSION)" - else - echo "$2 -> $3" - fi - ;; - "unalias" ) - mkdir -p $NVM_DIR/alias - [ $# -ne 2 ] && nvm help && return - [ ! -f $NVM_DIR/alias/$2 ] && echo "Alias $2 doesn't exist!" && return - rm -f $NVM_DIR/alias/$2 - echo "Deleted alias $2" - ;; - "copy-packages" ) - if [ $# -ne 2 ]; then - nvm help - return - fi - VERSION=`nvm_version $2` - ROOT=`nvm use $VERSION && npm -g root` - INSTALLS=`nvm use $VERSION > /dev/null && npm -g -p ll | grep "$ROOT\/[^/]\+$" | cut -d '/' -f 8 | cut -d ":" -f 2 | grep -v npm | tr "\n" " "` - npm install -g $INSTALLS - ;; - "clear-cache" ) - rm -f $NVM_DIR/v* 2>/dev/null - echo "Cache cleared." - ;; - "version" ) - print_versions "`nvm_version $2`" - ;; - * ) - nvm help - ;; - esac -} - -nvm ls default >/dev/null 2>&1 && nvm use default >/dev/null diff --git a/plugins/available/percol.plugin.bash b/plugins/available/percol.plugin.bash new file mode 100644 index 00000000..067c6c8f --- /dev/null +++ b/plugins/available/percol.plugin.bash @@ -0,0 +1,44 @@ +cite about-plugin +about-plugin 'Search&Select history and fasd with percol' + +# Notice +## You have to upgrade bash to bash 4.x on Mac OS X. +## http://stackoverflow.com/questions/16416195/how-do-i-upgrade-bash-in-mac-osx-mountain-lion-and-set-it-the-correct-path + +# Install +## (sudo) pip install percol +## bash-it enable percol +## optional: bash-it enable fasd + +# Usage +## C-r to search&select from history +## zz to search&select from fasd + +_replace_by_history() { + if command -v tac>/dev/null; then + alias _tac=tac + else + alias _tac="tail -r" + fi + local l=$(HISTTIMEFORMAT= history | _tac | sed -e 's/^\ *[0-9]*\ *//' | percol --query "$READLINE_LINE") + READLINE_LINE="$l" + READLINE_POINT=${#l} +} + + +if command -v percol>/dev/null; then + local current_version=${BASH_VERSION%%[^0-9]*} + if [ $current_version -lt 4 ]; then + echo "Warning:You have to upgrade bash to bash 4.x to use percol plugin." + else + bind -x '"\C-r": _replace_by_history' + + # bind zz to percol if fasd enable + if command -v fasd>/dev/null; then + zz(){ + local l=$(fasd -d | awk '{print $2}' | percol) + cd $l + } + fi + fi +fi diff --git a/themes/base.theme.bash b/themes/base.theme.bash index ac83c4d2..c8dff10a 100644 --- a/themes/base.theme.bash +++ b/themes/base.theme.bash @@ -92,6 +92,32 @@ function scm_prompt_info { [[ $SCM == $SCM_SVN ]] && svn_prompt_info && return } +function git_status_summary { + awk ' + { + if (!after_first && $0 ~ /^##.+/) { + print $0 + seen_header = 1 + } else if ($0 ~ /^\?\? .+/) { + untracked += 1 + } else { + if ($0 ~ /^.[^ ] .+/) { + unstaged += 1 + } + if ($0 ~ /^[^ ]. .+/) { + staged += 1 + } + } + after_first = 1 + } + END { + if (!seen_header) { + print + } + print untracked "\t" unstaged "\t" staged + }' +} + function git_prompt_vars { local details='' @@ -102,14 +128,14 @@ function git_prompt_vars { SCM_STATE=${GIT_THEME_PROMPT_CLEAN:-$SCM_THEME_PROMPT_CLEAN} if [[ "$(git config --get bash-it.hide-status)" != "1" ]]; then [[ "${SCM_GIT_IGNORE_UNTRACKED}" = "true" ]] && local git_status_flags='-uno' - local status="$(git status -b --porcelain ${git_status_flags} 2> /dev/null || - git status --porcelain ${git_status_flags} 2> /dev/null)" - if [[ -n "${status}" ]] && [[ "${status}" != "\n" ]] && [[ -n "$(grep -v ^# <<< "${status}")" ]]; then + local status_lines=$((git status --porcelain ${git_status_flags} -b 2> /dev/null || + git status --porcelain ${git_status_flags} 2> /dev/null) | git_status_summary) + local status=$(awk 'NR==1' <<< "$status_lines") + local counts=$(awk 'NR==2' <<< "$status_lines") + IFS=$'\t' read untracked_count unstaged_count staged_count <<< "$counts" + if [[ "${untracked_count}" -gt 0 || "${unstaged_count}" -gt 0 || "${staged_count}" -gt 0 ]]; then SCM_DIRTY=1 if [[ "${SCM_GIT_SHOW_DETAILS}" = "true" ]]; then - local untracked_count="$(egrep -c '^\?\? .+' <<< "${status}")" - local unstaged_count="$(egrep -c '^.[^ ?#] .+' <<< "${status}")" - local staged_count="$(egrep -c '^[^ ?#]. .+' <<< "${status}")" [[ "${staged_count}" -gt 0 ]] && details+=" ${SCM_GIT_STAGED_CHAR}${staged_count}" && SCM_DIRTY=3 [[ "${unstaged_count}" -gt 0 ]] && details+=" ${SCM_GIT_UNSTAGED_CHAR}${unstaged_count}" && SCM_DIRTY=2 [[ "${untracked_count}" -gt 0 ]] && details+=" ${SCM_GIT_UNTRACKED_CHAR}${untracked_count}" && SCM_DIRTY=1 @@ -197,9 +223,9 @@ function svn_prompt_vars { } # this functions returns absolute location of .hg directory if one exists -# It starts in the current directory and moves its way up until it hits /. +# It starts in the current directory and moves its way up until it hits /. # If we get to / then no Mercurial repository was found. -# Example: +# Example: # - lets say we cd into ~/Projects/Foo/Bar # - .hg is located in ~/Projects/Foo/.hg # - get_hg_root starts at ~/Projects/Foo/Bar and sees that there is no .hg directory, so then it goes into ~/Projects/Foo @@ -230,7 +256,7 @@ function hg_prompt_vars { HG_ROOT=$(get_hg_root) if [ -f $HG_ROOT/branch ]; then - # Mercurial holds it's current branch in .hg/branch file + # Mercurial holds it's current branch in .hg/branch file SCM_BRANCH=$(cat $HG_ROOT/branch) else SCM_BRANCH=$(hg summary 2> /dev/null | grep branch: | awk '{print $2}') @@ -361,3 +387,11 @@ if [ ! -e $BASH_IT/plugins/enabled/battery.plugin.bash ]; then echo -n } fi + +function aws_profile { + if [[ $AWS_DEFAULT_PROFILE ]]; then + echo -e "${AWS_DEFAULT_PROFILE}" + else + echo -e "default" + fi +} diff --git a/themes/morris/morris.theme.bash b/themes/morris/morris.theme.bash new file mode 100644 index 00000000..da51e55a --- /dev/null +++ b/themes/morris/morris.theme.bash @@ -0,0 +1,28 @@ + +# prompt theming + +# added TITLEBAR for updating the tab and window titles with the pwd +case $TERM in + xterm*) + TITLEBAR=$(printf "\033]0;%s@%s:%s\007" "${USER}" "${HOSTNAME%%.*}" "${PWD/#$HOME/~}") + ;; + screen) + TITLEBAR=$(printf "\033]0;%s@%s:%s\033\\" "${USER}" "${HOSTNAME%%.*}" "${PWD/#$HOME/~}") + ;; + *) + TITLEBAR="" + ;; +esac + +function prompt_command() { + PS1="${TITLEBAR}[\u@\h \W $(scm_prompt_info)]\$ " +} + +# scm theming +SCM_THEME_PROMPT_DIRTY=" ${red}✗" +SCM_THEME_PROMPT_CLEAN=" ${bold_green}✓" +SCM_THEME_PROMPT_PREFIX="${green}(" +SCM_THEME_PROMPT_SUFFIX="${green})${reset_color}" + + +PROMPT_COMMAND=prompt_command; diff --git a/themes/powerline-multiline/README.md b/themes/powerline-multiline/README.md new file mode 100644 index 00000000..8f353ac6 --- /dev/null +++ b/themes/powerline-multiline/README.md @@ -0,0 +1,58 @@ +# Powerline Multiline Theme + +A colorful multiline theme, where the first line shows information about your shell session (divided into two parts, left and right), and the second one is where the shell commands are introduced. + +**IMPORTANT:** This theme requires that [a font with the Powerline symbols](https://github.com/powerline/fonts) needs to be used in your terminal emulator, otherwise the prompt won't be displayed correctly, i.e. some of the additional icons and characters will be missing. Please follow your operating system's instructions to install one of the fonts from the above link and select it in your terminal emulator. + +## Provided Information + +* Current path +* Current username and hostname +* An indicator when connected by SSH +* An indicator when `sudo` has the credentials cached (see the `sudo` manpage for more info about this) +* An indicator when the current shell is inside the Vim editor +* Battery charging status (depends on the [../../plugins/available/battery.plugin.bash](battery plugin)) +* SCM Repository status (e.g. Git, SVN) +* The current Python environment (Virtualenv, venv, and Conda are supported) in use +* The current Ruby environment (RVM) in use +* Last command exit code (only shown when the exit code is greater than 0) + +## Configuration + +This theme is pretty configurable, all the configuration is done by setting environment variables. + +### User Information + +By default, the username and hostname are shown on the right hand side, but you can change this behavior by setting the value of the following variable: + + POWERLINE_PROMPT_USER_INFO_MODE="sudo" + +For now, the only supported value is `sudo`, which hides the username and hostname, and shows an indicator when `sudo` has the credentials cached. Other values have no effect at this time. + +### Clock Format + +By default, the current time is shown on the right hand side, you can change the format using the following variable: + + POWERLINE_PROMPT_CLOCK_FORMAT="%H:%M:%S" + +The time/date is printed by the `date` command, so refer to its man page to change the format. + +### Segment Order + +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 +* rvm +* scm +* user_info + +Two variables can be defined to set the order of the prompt segments: + + POWERLINE_LEFT_PROMPT="scm python_venv rvm cwd" + POWERLINE_RIGHT_PROMPT="in_vim clock battery user_info" + +The example values above are the current default values, but if you want to remove anything from the prompt, simply remove the "string" that represents the segment from the corresponding variable. diff --git a/themes/powerline-multiline/powerline-multiline.theme.bash b/themes/powerline-multiline/powerline-multiline.theme.bash index 7b690683..beaf3048 100644 --- a/themes/powerline-multiline/powerline-multiline.theme.bash +++ b/themes/powerline-multiline/powerline-multiline.theme.bash @@ -1,15 +1,12 @@ #!/usr/bin/env bash -THEME_PROMPT_SEPARATOR="" -THEME_PROMPT_LEFT_SEPARATOR="" +USER_INFO_SSH_CHAR=${POWERLINE_USER_INFO_SSH_CHAR:=" "} +USER_INFO_THEME_PROMPT_COLOR=32 +USER_INFO_THEME_PROMPT_COLOR_SUDO=202 -SHELL_SSH_CHAR=${SHELL_SSH_CHAR:=" "} -SHELL_THEME_PROMPT_COLOR=32 -SHELL_THEME_PROMPT_COLOR_SUDO=202 - -VIRTUALENV_CHAR=${POWERLINE_VIRTUALENV_CHAR:="❲p❳ "} -CONDA_VIRTUALENV_CHAR=${POWERLINE_CONDA_VIRTUALENV_CHAR:="❲c❳ "} -VIRTUALENV_THEME_PROMPT_COLOR=35 +PYTHON_VENV_CHAR=${POWERLINE_PYTHON_VENV_CHAR:="❲p❳ "} +CONDA_PYTHON_VENV_CHAR=${POWERLINE_CONDA_PYTHON_VENV_CHAR:="❲c❳ "} +PYTHON_VENV_THEME_PROMPT_COLOR=35 SCM_NONE_CHAR="" SCM_GIT_CHAR=${POWERLINE_SCM_GIT_CHAR:=" "} @@ -40,226 +37,202 @@ BATTERY_STATUS_THEME_PROMPT_GOOD_COLOR=70 BATTERY_STATUS_THEME_PROMPT_LOW_COLOR=208 BATTERY_STATUS_THEME_PROMPT_CRITICAL_COLOR=160 -THEME_PROMPT_CLOCK_FORMAT=${THEME_PROMPT_CLOCK_FORMAT:="%H:%M:%S"} +THEME_PROMPT_CLOCK_FORMAT=${POWERLINE_PROMPT_CLOCK_FORMAT:="%H:%M:%S"} -THEME_PROMPT_USERINFO_MODE=${THEME_PROMPT_USERINFO_MODE:="default"} +IN_VIM_THEME_PROMPT_COLOR=245 +IN_VIM_THEME_PROMPT_TEXT="vim" -IN_VIM_PROMPT_COLOR=35 -IN_VIM_PROMPT_TEXT="vim" +POWERLINE_LEFT_PROMPT="scm python_venv rvm cwd" +POWERLINE_RIGHT_PROMPT="in_vim clock battery user_info" 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\]" + 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 { - SHELL_PROMPT="" - SHELL_PROMPT_COLOR=${SHELL_THEME_PROMPT_COLOR} - if sudo -n uptime 2>&1 | grep -q "load"; then - SHELL_PROMPT_COLOR=${SHELL_THEME_PROMPT_COLOR_SUDO} - fi - case "${THEME_PROMPT_USERINFO_MODE}" in - "default") - if [[ -n "${SSH_CLIENT}" ]]; then - SHELL_PROMPT="${SHELL_SSH_CHAR}${USER}@${HOSTNAME}" - else - SHELL_PROMPT="${USER}" - fi - RIGHT_PROMPT_LENGTH=$(( ${RIGHT_PROMPT_LENGTH} + ${#SHELL_PROMPT} + 2 )) - SHELL_PROMPT="$(set_rgb_color - ${SHELL_PROMPT_COLOR}) ${SHELL_PROMPT} ${normal}" - LAST_THEME_COLOR=${SHELL_PROMPT_COLOR} - (( SEGMENT_AT_RIGHT += 1 )) - ;; - "sudo") - if [[ "${SHELL_PROMPT_COLOR}" == "${SHELL_THEME_PROMPT_COLOR_SUDO}" ]]; then - SHELL_PROMPT="!" - RIGHT_PROMPT_LENGTH=$(( ${RIGHT_PROMPT_LENGTH} + ${#SHELL_PROMPT} + 2 )) - SHELL_PROMPT="$(set_rgb_color - ${SHELL_PROMPT_COLOR}) ${SHELL_PROMPT} ${normal}" - LAST_THEME_COLOR=${SHELL_PROMPT_COLOR} - (( SEGMENT_AT_RIGHT += 1 )) - fi - ;; - esac +function __powerline_user_info_prompt { + local user_info="" + local color=${USER_INFO_THEME_PROMPT_COLOR} + + if sudo -n uptime 2>&1 | grep -q "load"; then + color=${USER_INFO_THEME_PROMPT_COLOR_SUDO} + fi + case "${POWERLINE_PROMPT_USER_INFO_MODE}" in + "sudo") + if [[ "${color}" == "${USER_INFO_THEME_PROMPT_COLOR_SUDO}" ]]; then + user_info="!" + fi + ;; + *) + if [[ -n "${SSH_CLIENT}" ]]; then + user_info="${USER_INFO_SSH_CHAR}${USER}@${HOSTNAME}" + else + user_info="${USER}" + fi + ;; + esac + [[ -n "${user_info}" ]] && echo "${user_info}|${color}" } -function powerline_rvm_prompt { - local environ="" +function __powerline_rvm_prompt { + local rvm="" - if command_exists rvm; then - rvm_prompt=$(rvm_version_prompt) - if [[ "${rvm_prompt}" != $(rvm strings default) ]]; then - RVM_PROMPT="$(set_rgb_color - ${RVM_THEME_PROMPT_COLOR}) ${RVM_CHAR}${rvm_prompt} ${normal}" - if [[ "${SEGMENT_AT_LEFT}" -gt 0 ]]; then - RVM_PROMPT=$(set_rgb_color ${LAST_THEME_COLOR} ${RVM_THEME_PROMPT_COLOR})${THEME_PROMPT_SEPARATOR}${normal}${RVM_PROMPT} - fi - LAST_THEME_COLOR=${RVM_THEME_PROMPT_COLOR} - (( SEGMENT_AT_LEFT += 1 )) - else - RVM_PROMPT="" - fi - fi -} - -function powerline_virtualenv_prompt { - local environ="" - - if [[ -n "$CONDA_DEFAULT_ENV" ]]; then - environ="$CONDA_DEFAULT_ENV" - VIRTUALENV_CHAR=${CONDA_VIRTUALENV_CHAR} - elif [[ -n "$VIRTUAL_ENV" ]]; then - environ=$(basename "$VIRTUAL_ENV") - fi - - if [[ -n "$environ" ]]; then - VIRTUALENV_PROMPT="$(set_rgb_color - ${VIRTUALENV_THEME_PROMPT_COLOR}) ${VIRTUALENV_CHAR}$environ ${normal}" - if [[ "${SEGMENT_AT_LEFT}" -gt 0 ]]; then - VIRTUALENV_PROMPT=$(set_rgb_color ${LAST_THEME_COLOR} ${VIRTUALENV_THEME_PROMPT_COLOR})${THEME_PROMPT_SEPARATOR}${normal}${VIRTUALENV_PROMPT} - fi - LAST_THEME_COLOR=${VIRTUALENV_THEME_PROMPT_COLOR} - (( SEGMENT_AT_LEFT += 1 )) - 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_THEME_PROMPT_COLOR=${SCM_THEME_PROMPT_STAGED_COLOR} - elif [[ "${SCM_DIRTY}" -eq 2 ]]; then - SCM_THEME_PROMPT_COLOR=${SCM_THEME_PROMPT_UNSTAGED_COLOR} - elif [[ "${SCM_DIRTY}" -eq 1 ]]; then - SCM_THEME_PROMPT_COLOR=${SCM_THEME_PROMPT_DIRTY_COLOR} - else - SCM_THEME_PROMPT_COLOR=${SCM_THEME_PROMPT_CLEAN_COLOR} - fi - if [[ "${SCM_GIT_CHAR}" == "${SCM_CHAR}" ]]; then - SCM_PROMPT=" ${SCM_CHAR}${SCM_BRANCH}${SCM_STATE}" - fi - SCM_PROMPT="$(set_rgb_color - ${SCM_THEME_PROMPT_COLOR})${SCM_PROMPT} ${normal}" - LAST_THEME_COLOR=${SCM_THEME_PROMPT_COLOR} - (( SEGMENT_AT_LEFT += 1 )) - else - SCM_PROMPT="" - fi -} - -function powerline_cwd_prompt { - CWD_PROMPT="$(set_rgb_color - ${CWD_THEME_PROMPT_COLOR}) \w ${normal}$(set_rgb_color ${CWD_THEME_PROMPT_COLOR} -)${normal}$(set_rgb_color ${CWD_THEME_PROMPT_COLOR} -)${THEME_PROMPT_SEPARATOR}${normal}" - if [[ "${SEGMENT_AT_LEFT}" -gt 0 ]]; then - CWD_PROMPT=$(set_rgb_color ${LAST_THEME_COLOR} ${CWD_THEME_PROMPT_COLOR})${THEME_PROMPT_SEPARATOR}${normal}${CWD_PROMPT} - SEGMENT_AT_LEFT=0 - fi - LAST_THEME_COLOR=${CWD_THEME_PROMPT_COLOR} -} - -function powerline_last_status_prompt { - if [[ "$1" -eq 0 ]]; then - LAST_STATUS_PROMPT="" - else - LAST_STATUS_PROMPT="$(set_rgb_color ${LAST_STATUS_THEME_PROMPT_COLOR} -) ${LAST_STATUS} ${normal}" - fi -} - -function powerline_clock_prompt { - if [[ -z "${THEME_PROMPT_CLOCK_FORMAT}" ]]; then - CLOCK_PROMPT="" - else - local CLOCK=" $(date +"${THEME_PROMPT_CLOCK_FORMAT}") " - - CLOCK_PROMPT=$(set_rgb_color - ${CLOCK_THEME_PROMPT_COLOR})${CLOCK}${normal} - if [[ "${SEGMENT_AT_RIGHT}" -gt 0 ]]; then - CLOCK_PROMPT+=$(set_rgb_color ${LAST_THEME_COLOR} ${CLOCK_THEME_PROMPT_COLOR})${THEME_PROMPT_LEFT_SEPARATOR}${normal} - (( RIGHT_PROMPT_LENGTH += SEGMENT_AT_RIGHT - 1 )) - fi - RIGHT_PROMPT_LENGTH=$(( ${RIGHT_PROMPT_LENGTH} + ${#CLOCK} )) - LAST_THEME_COLOR=${CLOCK_THEME_PROMPT_COLOR} - (( SEGMENT_AT_RIGHT += 1 )) - fi -} - -function powerline_battery_status_prompt { - BATTERY_STATUS="$(battery_percentage 2> /dev/null)" - if [[ -z "${BATTERY_STATUS}" ]] || [[ "${BATTERY_STATUS}" = "-1" ]] || [[ "${BATTERY_STATUS}" = "no" ]]; then - BATTERY_PROMPT="" - else - if [[ "$((10#${BATTERY_STATUS}))" -le 5 ]]; then - BATTERY_STATUS_THEME_PROMPT_COLOR="${BATTERY_STATUS_THEME_PROMPT_CRITICAL_COLOR}" - elif [[ "$((10#${BATTERY_STATUS}))" -le 25 ]]; then - BATTERY_STATUS_THEME_PROMPT_COLOR="${BATTERY_STATUS_THEME_PROMPT_LOW_COLOR}" - else - BATTERY_STATUS_THEME_PROMPT_COLOR="${BATTERY_STATUS_THEME_PROMPT_GOOD_COLOR}" - fi - [[ "$(ac_adapter_connected)" ]] && BATTERY_STATUS="${BATTERY_AC_CHAR}${BATTERY_STATUS}" - BATTERY_PROMPT="$(set_rgb_color - ${BATTERY_STATUS_THEME_PROMPT_COLOR}) ${BATTERY_STATUS}% " - if [[ "${SEGMENT_AT_RIGHT}" -gt 0 ]]; then - BATTERY_PROMPT+=$(set_rgb_color ${LAST_THEME_COLOR} ${BATTERY_STATUS_THEME_PROMPT_COLOR})${THEME_PROMPT_LEFT_SEPARATOR}${normal} - (( RIGHT_PROMPT_LENGTH += SEGMENT_AT_RIGHT )) - else - BATTERY_STATUS+=" " - fi - RIGHT_PROMPT_LENGTH=$(( ${RIGHT_PROMPT_LENGTH} + ${#BATTERY_STATUS} + 2 )) - LAST_THEME_COLOR=${BATTERY_STATUS_THEME_PROMPT_COLOR} - (( SEGMENT_AT_RIGHT += 1 )) - fi -} - -function powerline_in_vim_prompt { - if [ -z "$VIMRUNTIME" ]; then - IN_VIM_PROMPT="" - else - IN_VIM_PROMPT="$(set_rgb_color - ${IN_VIM_PROMPT_COLOR}) ${IN_VIM_PROMPT_TEXT} " - if [[ "${SEGMENT_AT_RIGHT}" -gt 0 ]]; then - IN_VIM_PROMPT+=$(set_rgb_color ${LAST_THEME_COLOR} ${IN_VIM_PROMPT_COLOR})${THEME_PROMPT_LEFT_SEPARATOR}${normal} - (( RIGHT_PROMPT_LENGTH += SEGMENT_AT_RIGHT )) - fi - RIGHT_PROMPT_LENGTH=$(( ${RIGHT_PROMPT_LENGTH} + ${#IN_VIM_PROMPT_TEXT} )) - LAST_THEME_COLOR=${IN_VIM_PROMPT_COLOR} - (( SEGMENT_AT_RIGHT += 1 )) + if command_exists rvm; then + rvm="$(rvm_version_prompt)" + [[ -n "${rvm}" ]] && echo "${RVM_CHAR}${rvm}|${RVM_THEME_PROMPT_COLOR}" fi } +function __powerline_python_venv_prompt { + local python_venv="" -function powerline_prompt_command() { - local LAST_STATUS="$?" - local MOVE_CURSOR_RIGHTMOST='\033[500C' - SEGMENT_AT_LEFT=0 - SEGMENT_AT_RIGHT=0 - RIGHT_PROMPT_LENGTH=1 - RIGHT_PROMPT="" + if [[ -n "${CONDA_DEFAULT_ENV}" ]]; then + python_venv="${CONDA_DEFAULT_ENV}" + PYTHON_VENV_CHAR=${CONDA_PYTHON_VENV_CHAR} + elif [[ -n "${VIRTUAL_ENV}" ]]; then + python_venv=$(basename "${VIRTUAL_ENV}") + fi - ## left prompt ## - powerline_scm_prompt - powerline_virtualenv_prompt - powerline_rvm_prompt - powerline_cwd_prompt - powerline_last_status_prompt LAST_STATUS - - LEFT_PROMPT="${SCM_PROMPT}${VIRTUALENV_PROMPT}${RVM_PROMPT}${CWD_PROMPT}${MOVE_CURSOR_RIGHTMOST}" - - ## right prompt ## - LAST_THEME_COLOR="-" - powerline_shell_prompt - powerline_battery_status_prompt - powerline_clock_prompt - powerline_in_vim_prompt - - if [[ "${SEGMENT_AT_RIGHT}" -gt 0 ]]; then - LEFT_PROMPT+="${MOVE_CURSOR_RIGHTMOST}" - [[ "${SEGMENT_AT_RIGHT}" -eq 1 ]] && (( RIGHT_PROMPT_LENGTH-=1 )) - RIGHT_PROMPT="\033[${RIGHT_PROMPT_LENGTH}D$(set_rgb_color ${LAST_THEME_COLOR} -)${THEME_PROMPT_LEFT_SEPARATOR}${normal}" - RIGHT_PROMPT+="${IN_VIM_PROMPT}${CLOCK_PROMPT}${BATTERY_PROMPT}${SHELL_PROMPT}${normal}" - fi - - PS1="${LEFT_PROMPT}${RIGHT_PROMPT}\n${LAST_STATUS_PROMPT}${PROMPT_CHAR} " + [[ -n "${python_venv}" ]] && echo "${PYTHON_VENV_CHAR}${python_venv}|${PYTHON_VENV_THEME_PROMPT_COLOR}" } -PROMPT_COMMAND=powerline_prompt_command +function __powerline_scm_prompt { + local color="" + local scm_prompt="" + + scm_prompt_vars + + if [[ "${SCM_NONE_CHAR}" != "${SCM_CHAR}" ]]; then + if [[ "${SCM_DIRTY}" -eq 3 ]]; then + color=${SCM_THEME_PROMPT_STAGED_COLOR} + elif [[ "${SCM_DIRTY}" -eq 2 ]]; then + color=${SCM_THEME_PROMPT_UNSTAGED_COLOR} + elif [[ "${SCM_DIRTY}" -eq 1 ]]; then + color=${SCM_THEME_PROMPT_DIRTY_COLOR} + else + color=${SCM_THEME_PROMPT_CLEAN_COLOR} + fi + if [[ "${SCM_GIT_CHAR}" == "${SCM_CHAR}" ]]; then + scm_prompt+="${SCM_CHAR}${SCM_BRANCH}${SCM_STATE}" + fi + echo "${scm_prompt}|${color}" + fi +} + +function __powerline_cwd_prompt { + echo "$(pwd | sed "s|^${HOME}|~|")|${CWD_THEME_PROMPT_COLOR}" +} + +function __powerline_clock_prompt { + echo "$(date +"${THEME_PROMPT_CLOCK_FORMAT}")|${CLOCK_THEME_PROMPT_COLOR}" +} + +function __powerline_battery_prompt { + local color="" + local battery_status="$(battery_percentage 2> /dev/null)" + + if [[ -z "${battery_status}" ]] || [[ "${battery_status}" = "-1" ]] || [[ "${battery_status}" = "no" ]]; then + true + else + if [[ "$((10#${battery_status}))" -le 5 ]]; then + color="${BATTERY_STATUS_THEME_PROMPT_CRITICAL_COLOR}" + elif [[ "$((10#${battery_status}))" -le 25 ]]; then + color="${BATTERY_STATUS_THEME_PROMPT_LOW_COLOR}" + else + color="${BATTERY_STATUS_THEME_PROMPT_GOOD_COLOR}" + fi + [[ "$(ac_adapter_connected)" ]] && battery_status="${BATTERY_AC_CHAR}${battery_status}" + echo "${battery_status}%|${color}" + fi +} + +function __powerline_in_vim_prompt { + if [ -n "$VIMRUNTIME" ]; then + echo "${IN_VIM_THEME_PROMPT_TEXT}|${IN_VIM_THEME_PROMPT_COLOR}" + fi +} + +function __powerline_last_status_prompt { + [[ "$1" -ne 0 ]] && echo "$(set_rgb_color ${LAST_STATUS_THEME_PROMPT_COLOR} -) ${1} ${normal}" +} + +function __powerline_left_segment { + local OLD_IFS="${IFS}"; IFS="|" + local params=( $1 ) + IFS="${OLD_IFS}" + local separator_char="" + local separator="" + + if [[ "${SEGMENTS_AT_LEFT}" -gt 0 ]]; then + separator="$(set_rgb_color ${LAST_SEGMENT_COLOR} ${params[1]})${separator_char}${normal}${normal}" + fi + LEFT_PROMPT+="${separator}$(set_rgb_color - ${params[1]}) ${params[0]} ${normal}" + LAST_SEGMENT_COLOR=${params[1]} + (( SEGMENTS_AT_LEFT += 1 )) +} + +function __powerline_right_segment { + local OLD_IFS="${IFS}"; IFS="|" + local params=( $1 ) + IFS="${OLD_IFS}" + local separator_char="" + local padding=2 + local separator_color="" + + if [[ "${SEGMENTS_AT_RIGHT}" -eq 0 ]]; then + separator_color="$(set_rgb_color ${params[1]} -)" + else + separator_color="$(set_rgb_color ${params[1]} ${LAST_SEGMENT_COLOR})" + (( padding += 1 )) + fi + RIGHT_PROMPT+="${separator_color}${separator_char}${normal}$(set_rgb_color - ${params[1]}) ${params[0]} ${normal}$(set_rgb_color - ${COLOR})${normal}" + RIGHT_PROMPT_LENGTH=$(( ${#params[0]} + RIGHT_PROMPT_LENGTH + padding )) + LAST_SEGMENT_COLOR="${params[1]}" + (( SEGMENTS_AT_RIGHT += 1 )) +} + +function __powerline_prompt_command { + local last_status="$?" ## always the first + local separator_char="" + local move_cursor_rightmost='\033[500C' + + LEFT_PROMPT="" + RIGHT_PROMPT="" + RIGHT_PROMPT_LENGTH=0 + SEGMENTS_AT_LEFT=0 + SEGMENTS_AT_RIGHT=0 + LAST_SEGMENT_COLOR="" + + ## left prompt ## + for segment in $POWERLINE_LEFT_PROMPT; do + local info="$(__powerline_${segment}_prompt)" + [[ -n "${info}" ]] && __powerline_left_segment "${info}" + done + [[ -n "${LEFT_PROMPT}" ]] && LEFT_PROMPT+="$(set_rgb_color ${LAST_SEGMENT_COLOR} -)${separator_char}${normal}" + + ## right prompt ## + if [[ -n "${POWERLINE_RIGHT_PROMPT}" ]]; then + LEFT_PROMPT+="${move_cursor_rightmost}" + for segment in $POWERLINE_RIGHT_PROMPT; do + local info="$(__powerline_${segment}_prompt)" + [[ -n "${info}" ]] && __powerline_right_segment "${info}" + done + LEFT_PROMPT+="\033[${RIGHT_PROMPT_LENGTH}D" + fi + + PS1="${LEFT_PROMPT}${RIGHT_PROMPT}\n$(__powerline_last_status_prompt ${last_status})${PROMPT_CHAR} " + + ## cleanup ## + unset LAST_SEGMENT_COLOR \ + LEFT_PROMPT RIGHT_PROMPT RIGHT_PROMPT_LENGTH \ + SEGMENTS_AT_LEFT SEGMENTS_AT_RIGHT +} + +PROMPT_COMMAND=__powerline_prompt_command diff --git a/themes/primer/primer.theme.bash b/themes/primer/primer.theme.bash new file mode 100644 index 00000000..0b01088e --- /dev/null +++ b/themes/primer/primer.theme.bash @@ -0,0 +1,8 @@ +#!/usr/bin/env bash + +# based of the candy theme, but minimized by odbol +function prompt_command() { + PS1="${blue}\T ${reset_color}${white}\w${reset_color}$(scm_prompt_info)${blue} →${bold_blue} ${reset_color} "; +} + +PROMPT_COMMAND=prompt_command; \ No newline at end of file diff --git a/themes/pro/pro.theme.bash b/themes/pro/pro.theme.bash new file mode 100644 index 00000000..6ac697bf --- /dev/null +++ b/themes/pro/pro.theme.bash @@ -0,0 +1,22 @@ +#!/usr/bin/env bash + +SCM_THEME_PROMPT_DIRTY=" ${red}✗" +SCM_THEME_PROMPT_CLEAN=" ${green}✓" +SCM_THEME_PROMPT_PREFIX=" ${blue}scm:( " +SCM_THEME_PROMPT_SUFFIX="${blue} )" + +GIT_THEME_PROMPT_DIRTY=" ${red}✗" +GIT_THEME_PROMPT_CLEAN=" ${green}✓" +GIT_THEME_PROMPT_PREFIX="${green}git:( " +GIT_THEME_PROMPT_SUFFIX="${green} )" + +function git_prompt_info { + git_prompt_vars + echo -e "$SCM_PREFIX$SCM_BRANCH$SCM_STATE$SCM_SUFFIX" +} + +function prompt() { + PS1="\h: \W $(scm_prompt_info)${reset_color} $ " +} + +PROMPT_COMMAND=prompt diff --git a/themes/zork/zork.theme.bash b/themes/zork/zork.theme.bash index c71f1344..c022a408 100644 --- a/themes/zork/zork.theme.bash +++ b/themes/zork/zork.theme.bash @@ -46,27 +46,45 @@ modern_scm_prompt() { fi } +# show chroot if exist +chroot(){ + if [ -n "$debian_chroot" ] + then + my_ps_chroot="${bold_cyan}$debian_chroot${normal}"; + echo "($my_ps_chroot)"; + fi + } + +# show virtualenvwrapper +my_ve(){ + if [ -n "$VIRTUAL_ENV" ] + then + my_ps_ve="${bold_purple}$ve${normal}"; + echo "($my_ps_ve)"; + fi + echo ""; + } + prompt() { - case $HOSTNAME in - "zork"* ) my_ps_host="${green}\h${normal}"; - ;; - "pandora") my_ps_host="${red}\h${normal}"; - ;; - * ) my_ps_host="${green}\h${normal}"; - ;; - esac + my_ps_host="${green}\h${normal}"; + # yes, these are the the same for now ... + my_ps_host_root="${green}\h${normal}"; + + my_ps_user="${bold_green}\u${normal}" + my_ps_root="${bold_red}\u${normal}"; - my_ps_user="\[\033[01;32m\]\u\[\033[00m\]"; - my_ps_root="\[\033[01;31m\]\u\[\033[00m\]"; - my_ps_path="\[\033[01;36m\]\w\[\033[00m\]"; + if [ -n "$VIRTUAL_ENV" ] + then + ve=`basename $VIRTUAL_ENV`; + fi # nice prompt case "`id -u`" in - 0) PS1="${TITLEBAR}┌─[$my_ps_root][$my_ps_host]$(modern_scm_prompt)$(__my_rvm_ruby_version)[${cyan}\w${normal}]$(is_vim_shell) + 0) PS1="${TITLEBAR}┌─$(my_ve)$(chroot)[$my_ps_root][$my_ps_host_root]$(modern_scm_prompt)$(__my_rvm_ruby_version)[${cyan}\w${normal}]$(is_vim_shell) └─▪ " ;; - *) PS1="${TITLEBAR}┌─[$my_ps_user][$my_ps_host]$(modern_scm_prompt)$(__my_rvm_ruby_version)[${cyan}\w${normal}]$(is_vim_shell) + *) PS1="${TITLEBAR}┌─$(my_ve)$(chroot)[$my_ps_user][$my_ps_host]$(modern_scm_prompt)$(__my_rvm_ruby_version)[${cyan}\w${normal}]$(is_vim_shell) └─▪ " ;; esac