diff --git a/README.md b/README.md index 2c078699..13a991da 100644 --- a/README.md +++ b/README.md @@ -59,10 +59,10 @@ When you run without the `--no-modify-config` switch, the Bash-it installer auto Use the `--no-modify-config` switch to avoid unwanted modifications, e.g. if your Bash config file already contains the code that loads Bash-it. **NOTE**: Keep in mind how Bash load its configuration files, -`.bash_profile` for login shells (and in macOS in terminal emulators like [Terminal.app](http://www.apple.com/osx/apps/) or +`.bash_profile` for login shells (and in macOS in terminal emulators like [Terminal.app](http://www.apple.com/osx/apps/) or [iTerm2](https://www.iterm2.com/)) and `.bashrc` for interactive shells (default mode in most of the GNU/Linux terminal emulators), to ensure that Bash-it is loaded correctly. -A good "practice" is sourcing `.bashrc` into `.bash_profile` to keep things working in all the scenarios. +A good "practice" is sourcing `.bashrc` into `.bash_profile` to keep things working in all the scenarios. To achieve this, you can add this snippet in your `.bash_profile`: ``` @@ -76,8 +76,8 @@ Refer to the official [Bash documentation](https://www.gnu.org/software/bash/man ### Install using Docker -You can try Bash-it in an isolated environment without changing any local files via a [Docker](https://www.docker.com/) Container. -(Bash Shell v4.4 with Bash-it, [bats](https://github.com/sstephenson/bats) and bash-completion based on [Alpine Linux](https://alpinelinux.org/)). +You can try Bash-it in an isolated environment without changing any local files via a [Docker](https://www.docker.com/) Container. +(Bash Shell v4.4 with Bash-it, [bats](https://github.com/sstephenson/bats) and bash-completion based on [Alpine Linux](https://alpinelinux.org/)). `docker pull ellerbrock/bash-it` @@ -140,7 +140,7 @@ Currently enabled modules will be shown in green. ### Searching with Negations -You can prefix a search term with a "-" to exclude it from the results. +You can prefix a search term with a "-" to exclude it from the results. In the above example, if we wanted to hide `chruby` and `chruby-auto`, we could change the command as follows: @@ -189,6 +189,7 @@ There are over 50+ Bash-it themes to pick from in `$BASH_IT/themes`. The default theme is `bobby`. Set `BASH_IT_THEME` to the theme name you want, or if you've developed your own custom theme outside of `$BASH_IT/themes`, point the `BASH_IT_THEME` variable directly to the theme file. +To disable theming completely, leave the variable empty. Examples: @@ -198,9 +199,12 @@ export BASH_IT_THEME="powerline-multiline" # Use a theme outside of the Bash-it folder export BASH_IT_THEME="/home/foo/my_theme/my_theme.theme.bash" + +# Disable theming +export BASH_IT_THEME="" ``` -You can easily preview the themes in your own shell using `BASH_PREVIEW=true reload`. +You can easily preview the themes in your own shell using `BASH_PREVIEW=true bash-it reload`. If you've created your own custom prompts, we'd love it if you shared with everyone else! Just submit a Pull Request. You can see theme screenshots on [wiki/Themes](https://github.com/Bash-it/bash-it/wiki/Themes). @@ -294,8 +298,8 @@ Set `SCM_GIT_SHOW_REMOTE_INFO` to 'false' to **disable the feature**: ### Untracked files -By default, the `git status` command shows information about *untracked* files. -This behavior can be controlled through command-line flags or git configuration files. +By default, the `git status` command shows information about *untracked* files. +This behavior can be controlled through command-line flags or git configuration files. For big repositories, ignoring *untracked* files can make git faster. Bash-it uses `git status` to gather the repo information it shows in the prompt, so in some circumstances, it can be useful to instruct Bash-it to ignore these files. You can control this behavior with the flag `SCM_GIT_IGNORE_UNTRACKED`: @@ -312,6 +316,19 @@ Also, with this flag to false, Bash-it will not show the repository as dirty whe **NOTE:** If you set in git configuration file the option to ignore *untracked* files, this flag has no effect, and Bash-it will ignore *untracked* files always. +### Stash item count + +When `SCM_GIT_SHOW_DETAILS` is enabled, you can get the count of *stashed* items. This feature can be useful when a user has a lot of stash items. +This feature is controlled through the flag `SCM_GIT_SHOW_STASH_INFO` as follows: + +Set `SCM_GIT_SHOW_STASH_INFO` to 'true' (the default value) to **show** the count of stashed items: + +* `export SCM_GIT_SHOW_STASH_INFO=true` + +Set `SCM_GIT_SHOW_STASH_INFO` to 'false' to **don't show** it: + +* `export SCM_GIT_SHOW_STASH_INFO=false` + ### Git user In some environments, it is useful to know the value of the current git user, which is used to mark all new commits. @@ -333,7 +350,7 @@ You can control the prefix and the suffix of this component using the two variab And -* `export SCM_THEME_CURRENT_USER_SUFFIX=' ☺︎ '` +* `export SCM_THEME_CURRENT_USER_SUFFIX=' ☺︎ '` **NOTE:** If using `SCM_GIT_SHOW_MINIMAL_INFO=true`, then the value of `SCM_GIT_SHOW_CURRENT_USER` is ignored. diff --git a/aliases/available/bolt.aliases.bash b/aliases/available/bolt.aliases.bash new file mode 100644 index 00000000..8490f710 --- /dev/null +++ b/aliases/available/bolt.aliases.bash @@ -0,0 +1,8 @@ +cite 'about-alias' +about-alias 'puppet bolt aliases' + +# Aliases +alias bolt='bolt command run --tty --no-host-key-check' +alias boltas='bolt -p -u' +alias sudobolt='bolt --run-as root --sudo-password' +alias sudoboltas='sudobolt -p -u' diff --git a/aliases/available/clipboard.aliases.bash b/aliases/available/clipboard.aliases.bash index 21b770a6..528e2d0e 100644 --- a/aliases/available/clipboard.aliases.bash +++ b/aliases/available/clipboard.aliases.bash @@ -4,7 +4,9 @@ about-alias 'pbcopy and pbpaste shortcuts to linux' case $OSTYPE in linux*) XCLIP=$(command -v xclip) - [[ $XCLIP ]] && alias pbcopy="$XCLIP -selection clipboard" && alias pbpaste="$XCLIP -selection clipboard -o" + [[ $XCLIP ]] && \ + alias pbcopy="$XCLIP -selection clipboard" && \ + alias pbpaste="$XCLIP -selection clipboard -o" ;; esac diff --git a/aliases/available/composer.aliases.bash b/aliases/available/composer.aliases.bash new file mode 100644 index 00000000..5ccb2e24 --- /dev/null +++ b/aliases/available/composer.aliases.bash @@ -0,0 +1,39 @@ +cite 'about-alias' +about-alias 'common composer abbreviations' + +# Aliases +alias coab='composer about' +alias coar='composer archive' +alias cob='composer browser' +alias cocpr='composer check-platform-reqs' +alias cocc='composer clear-cache' +alias cocfg='composer config' +alias cocp='composer create-project' +alias codp='composer depends' +alias codiag='composer diagnose' +alias codmp='composer dump-autoload' +alias coex='composer exec' +alias coglob='composer global' +alias coh='composer help' +alias cohome='composer home' +alias coi='composer install' +alias coinf='composer info' +alias coini='composer init' +alias coli='composer license' +alias colis='composer list' +alias coout='composer outdated' +alias cop='composer prohibits' +alias corem='composer remove' +alias coreq='composer require' +alias coreqd='composer require --dev' +alias cors='composer run-script' +alias cos='composer search' +alias cosu='composer self-update' +alias coshow='composer show' +alias costat='composer status' +alias cosugg='composer suggest' +alias coup='composer update' +alias coupg='composer upgrade' +alias coval='composer validate' +alias cowhy='composer why' +alias cowhyn='composer why-not' diff --git a/aliases/available/docker-compose.aliases.bash b/aliases/available/docker-compose.aliases.bash index 01eb62fb..f23c2689 100644 --- a/aliases/available/docker-compose.aliases.bash +++ b/aliases/available/docker-compose.aliases.bash @@ -4,3 +4,4 @@ about-alias 'docker-compose abbreviations' alias dco="docker-compose" alias dcofresh="docker-compose-fresh" alias dcol="docker-compose logs -f --tail 100" +alias dcou="docker-compose up" diff --git a/aliases/available/docker.aliases.bash b/aliases/available/docker.aliases.bash index e3601d6f..5606b619 100644 --- a/aliases/available/docker.aliases.bash +++ b/aliases/available/docker.aliases.bash @@ -1,6 +1,7 @@ cite 'about-alias' about-alias 'docker abbreviations' +alias dk='docker' alias dklc='docker ps -l' # List last Docker container alias dklcid='docker ps -l -q' # List last Docker container ID alias dklcip='docker inspect -f "{{.NetworkSettings.IPAddress}}" $(docker ps -l -q)' # Get IP of last Docker container @@ -25,3 +26,11 @@ alias dkrmi='docker-remove-images' # Delete images for supplied IDs or all if n alias dkideps='docker-image-dependencies' # Output a graph of image dependencies using Graphiz alias dkre='docker-runtime-environment' # List environmental variables of the supplied image ID alias dkelc='docker exec -it `dklcid` bash' # Enter last container (works with Docker 1.3 and above) +alias dkex='docker exec -it ' # Useful to run any commands into container without leaving host +alias dkri='docker run --rm -i ' +alias dkrit='docker run --rm -it ' + +# Added more recent cleanup options from newer docker versions +alias dkip='docker image prune -a -f' +alias dkvp='docker volume prune -f' +alias dksp='docker system prune -a -f' diff --git a/aliases/available/git.aliases.bash b/aliases/available/git.aliases.bash index 51717f40..169fe7b8 100644 --- a/aliases/available/git.aliases.bash +++ b/aliases/available/git.aliases.bash @@ -30,6 +30,7 @@ alias gup='git fetch && git rebase' alias gp='git push' alias gpo='git push origin' alias gpu='git push --set-upstream' +alias gpuo='git push --set-upstream origin' alias gpom='git push origin master' alias gr='git remote' alias grv='git remote -v' diff --git a/aliases/available/homebrew-cask.aliases.bash b/aliases/available/homebrew-cask.aliases.bash index 090622b0..57d8161c 100644 --- a/aliases/available/homebrew-cask.aliases.bash +++ b/aliases/available/homebrew-cask.aliases.bash @@ -7,7 +7,6 @@ alias bcin='brew cask install' alias bcrm='brew cask uninstall' alias bczp='brew cask zap' alias bccl='brew cask cleanup' -alias bcsr='brew cask search' alias bcls='brew cask list' alias bcinf='brew cask info' alias bcdr='brew cask doctor' diff --git a/aliases/available/kubectl.aliases.bash b/aliases/available/kubectl.aliases.bash new file mode 100644 index 00000000..58670ce5 --- /dev/null +++ b/aliases/available/kubectl.aliases.bash @@ -0,0 +1,24 @@ +#!/bin/bash +# +# -binaryanomaly + +cite 'about-alias' +about-alias 'kubectl aliases' + +# set apt aliases +function _set_pkg_aliases() +{ + if [ -x $(which kubectl) ]; then + alias kc='kubectl' + alias kcgp='kubectl get pods' + alias kcgd='kubectl get deployments' + alias kcgn='kubectl get nodes' + alias kcdp='kubectl describe pod' + alias kcdd='kubectl describe deployment' + alias kcdn='kubectl describe node' + alias kcgpan='kubectl get pods --all-namespaces' + alias kcgdan='kubectl get deployments --all-namespaces' + fi +} + +_set_pkg_aliases diff --git a/aliases/available/maven.aliases.bash b/aliases/available/maven.aliases.bash index 4cd89d27..f8a44a1c 100644 --- a/aliases/available/maven.aliases.bash +++ b/aliases/available/maven.aliases.bash @@ -3,9 +3,12 @@ about-alias 'maven abbreviations' alias mci='mvn clean install' alias mi='mvn install' +alias mcp='mvn clean package' +alias mp='mvn package' alias mrprep='mvn release:prepare' alias mrperf='mvn release:perform' alias mrrb='mvn release:rollback' alias mdep='mvn dependency:tree' alias mpom='mvn help:effective-pom' alias mcisk='mci -Dmaven.test.skip=true' +alias mcpsk='mcp -Dmaven.test.skip=true' diff --git a/aliases/available/npm.aliases.bash b/aliases/available/npm.aliases.bash index 4623c738..2266fe22 100644 --- a/aliases/available/npm.aliases.bash +++ b/aliases/available/npm.aliases.bash @@ -18,5 +18,5 @@ alias nod='npm outdated' alias nrb='npm rebuild' alias nud='npm update' alias nr='npm run' -alias nls='npm list' -alias nlsg='npm list --global' +alias nls='npm list --depth=0 2>/dev/null' +alias nlsg='npm list -g --depth=0 2>/dev/null' diff --git a/aliases/available/phoenix.aliases.bash b/aliases/available/phoenix.aliases.bash index 2a4ec5e1..64728a2e 100644 --- a/aliases/available/phoenix.aliases.bash +++ b/aliases/available/phoenix.aliases.bash @@ -3,7 +3,7 @@ about-alias 'phoenix abbreviations' # Phoenix Commands alias i='iex' -alias ips='iex -S mix phoenix.server' +alias ips='iex -S mix phx.server' alias ism='iex -S mix' alias m='mix' alias mab='mix archive.build' @@ -32,14 +32,14 @@ alias mho='mix hex.outdated' alias mlh='mix local.hex' alias mn='mix new' alias mns='mix new --sup' -alias mpgc='mix phoenix.gen.channel' -alias mpgh='mix phoenix.gen.html' -alias mpgj='mix phoenix.gen.json' -alias mpgm='mix phoenix.gen.model' -alias mpgs='mix phoenix.gen.secret' -alias mpn='mix phoenix.new' -alias mpr='mix phoenix.routes' -alias mps='mix phoenix.server' +alias mpgc='mix phx.gen.channel' +alias mpgh='mix phx.gen.html' +alias mpgj='mix phx.gen.json' +alias mpgm='mix phx.gen.model' +alias mpgs='mix phx.gen.secret' +alias mpn='mix phx.new' +alias mpr='mix phx.routes' +alias mps='mix phx.server' alias mr='mix run' alias mrnh='mix run --no-halt' alias mrl='mix release' diff --git a/aliases/available/puppet.aliases.bash b/aliases/available/puppet.aliases.bash new file mode 100644 index 00000000..bb5b4a1a --- /dev/null +++ b/aliases/available/puppet.aliases.bash @@ -0,0 +1,10 @@ +cite 'about-alias' +about-alias 'puppet aliases' + +# Aliases +alias pupval="puppet parser validate *.pp" +alias puplint="puppet-lint *.pp" +alias pupagt="puppet agent -t" +alias pupagtd="puppet agent -t --debug" +alias pupapp="puppet apply" + diff --git a/aliases/available/vault.aliases.bash b/aliases/available/vault.aliases.bash index 7c98aa58..d2ad8e74 100644 --- a/aliases/available/vault.aliases.bash +++ b/aliases/available/vault.aliases.bash @@ -11,5 +11,5 @@ alias vasrv="vault server" alias vas="vault status" alias vav="vault version" alias vaw="vault write" -alias vag="vault auth -method=github" +alias vag="vault login -method=github" alias varv="vault read -field=value" diff --git a/aliases/available/yarn.aliases.bash b/aliases/available/yarn.aliases.bash index c189aa8d..b50535b9 100644 --- a/aliases/available/yarn.aliases.bash +++ b/aliases/available/yarn.aliases.bash @@ -5,15 +5,18 @@ about-alias 'yarn package manager aliases' alias ya='yarn' alias yai='yarn init' alias yaa='yarn add' +alias yaga='yarn global add' alias yaad='yarn add --dev' alias yau='yarn upgrade' alias yarm='yarn remove' +alias yagrm='yarn global remove' alias yaod='yarn outdated' alias yapa='yarn pack' alias yap='yarn publish' alias yasu='yarn self-update' alias yaru='yarn run' alias yat='yarn test' +alias yas='yarn serve' alias yacc='yarn cache clean' alias yack='yarn check' alias yals='yarn list' diff --git a/bash_it.sh b/bash_it.sh index 70082205..e2b00de7 100755 --- a/bash_it.sh +++ b/bash_it.sh @@ -1,31 +1,22 @@ #!/usr/bin/env bash # Initialize Bash It -# Reload Library -case $OSTYPE in - darwin*) - alias reload='source ~/.bash_profile' - ;; - *) - alias reload='source ~/.bashrc' - ;; -esac - # Only set $BASH_IT if it's not already set if [ -z "$BASH_IT" ]; then - # Setting $BASH to maintain backwards compatibility - # TODO: warn users that they should upgrade their .bash_profile - export BASH_IT=$BASH - export BASH="$(bash -c 'echo $BASH')" + # Setting $BASH to maintain backwards compatibility + # TODO: warn users that they should upgrade their .bash_profile + export BASH_IT=$BASH + BASH="$(bash -c 'echo $BASH')" + export BASH fi # For backwards compatibility, look in old BASH_THEME location if [ -z "$BASH_IT_THEME" ]; then - # TODO: warn users that they should upgrade their .bash_profile - export BASH_IT_THEME="$BASH_THEME"; - unset $BASH_THEME; + # TODO: warn users that they should upgrade their .bash_profile + export BASH_IT_THEME="$BASH_THEME"; + unset BASH_THEME; fi # Load composure first, so we support function metadata @@ -40,9 +31,9 @@ LIB="${BASH_IT}/lib/*.bash" APPEARANCE_LIB="${BASH_IT}/lib/appearance.bash" for config_file in $LIB do - if [ $config_file != $APPEARANCE_LIB ]; then + if [ "$config_file" != "$APPEARANCE_LIB" ]; then # shellcheck disable=SC1090 - source $config_file + source "$config_file" fi done @@ -55,17 +46,22 @@ do _load_bash_it_files $file_type done -# Load colors and helpers first so they can be used in base theme -# shellcheck source=./themes/colors.theme.bash -source "${BASH_IT}/themes/colors.theme.bash" -# shellcheck source=./themes/githelpers.theme.bash -source "${BASH_IT}/themes/githelpers.theme.bash" -# shellcheck source=./themes/base.theme.bash -source "${BASH_IT}/themes/base.theme.bash" +# Load theme, if a theme was set +if [[ ! -z "${BASH_IT_THEME}" ]]; then + # Load colors and helpers first so they can be used in base theme + # shellcheck source=./themes/colors.theme.bash + source "${BASH_IT}/themes/colors.theme.bash" + # shellcheck source=./themes/githelpers.theme.bash + source "${BASH_IT}/themes/githelpers.theme.bash" + # shellcheck source=./themes/p4helpers.theme.bash + source "${BASH_IT}/themes/p4helpers.theme.bash" + # shellcheck source=./themes/base.theme.bash + source "${BASH_IT}/themes/base.theme.bash" -# appearance (themes) now, after all dependencies -# shellcheck source=./lib/appearance.bash -source $APPEARANCE_LIB + # appearance (themes) now, after all dependencies + # shellcheck source=./lib/appearance.bash + source "$APPEARANCE_LIB" +fi # Load custom aliases, completion, plugins for file_type in "aliases" "completion" "plugins" @@ -83,13 +79,13 @@ for config_file in $CUSTOM do if [ -e "${config_file}" ]; then # shellcheck disable=SC1090 - source $config_file + source "$config_file" fi done unset config_file if [[ $PROMPT ]]; then - export PS1="\[""$PROMPT""\]" + export PS1="\[""$PROMPT""\]" fi # Adding Support for other OSes @@ -110,5 +106,17 @@ then . "$HOME/.jekyllconfig" fi +# BASH_IT_RELOAD_LEGACY is set. +if ! command -v reload &>/dev/null && [ -n "$BASH_IT_RELOAD_LEGACY" ]; then + case $OSTYPE in + darwin*) + alias reload='source ~/.bash_profile' + ;; + *) + alias reload='source ~/.bashrc' + ;; + esac +fi + # Disable trap DEBUG on subshells - https://github.com/Bash-it/bash-it/pull/1040 set +T diff --git a/completion/available/bash-it.completion.bash b/completion/available/bash-it.completion.bash index 20a94e5b..71ec8418 100644 --- a/completion/available/bash-it.completion.bash +++ b/completion/available/bash-it.completion.bash @@ -65,7 +65,7 @@ _bash-it-comp() prev="${COMP_WORDS[COMP_CWORD-1]}" chose_opt="${COMP_WORDS[1]}" file_type="${COMP_WORDS[2]}" - opts="disable enable help migrate search show update version" + opts="disable enable help migrate reload search show update version" case "${chose_opt}" in show) local show_args="aliases completions plugins" @@ -82,7 +82,7 @@ _bash-it-comp() return 0 fi ;; - update | search | migrate | version) + migrate | reload | search | update | version) return 0 ;; enable | disable) diff --git a/completion/available/bundler.completion.bash b/completion/available/bundler.completion.bash index 274a4a36..cdb7cf54 100644 --- a/completion/available/bundler.completion.bash +++ b/completion/available/bundler.completion.bash @@ -21,6 +21,9 @@ __bundle() { if [[ -z $bundle_command ]]; then options="$options --version --help" fi + elif [[ $bundle_command = "exec" ]]; then + _bundle_exec_completions + return else if [[ -z $bundle_command || $bundle_command = help ]]; then options="help install update package exec config check list show @@ -53,3 +56,10 @@ __bundle_get_command() { complete -F __bundle -o bashdefault -o default bundle # vim: ai ft=sh sw=4 sts=2 et + +_bundle_exec_completions() +{ + if [[ $COMP_CWORD = 2 ]]; then + COMPREPLY=($(compgen -c -- "$2")) + fi +} diff --git a/completion/available/capistrano.completion.bash b/completion/available/capistrano.completion.bash old mode 100755 new mode 100644 diff --git a/completion/available/crystal.completion.bash b/completion/available/crystal.completion.bash new file mode 100644 index 00000000..cbc891d7 --- /dev/null +++ b/completion/available/crystal.completion.bash @@ -0,0 +1,11 @@ +if which crystal >/dev/null 2>&1; then + + if which brew >/dev/null 2>&1; then + BREW_PREFIX=$(brew --prefix) + + if [ -f "$BREW_PREFIX"/etc/bash_completion.d/crystal ]; then + . "$BREW_PREFIX"/etc/bash_completion.d/crystal + fi + fi + +fi diff --git a/completion/available/fabric-completion.bash b/completion/available/fabric.completion.bash similarity index 100% rename from completion/available/fabric-completion.bash rename to completion/available/fabric.completion.bash diff --git a/completion/available/invoke.completion.bash b/completion/available/invoke.completion.bash new file mode 100644 index 00000000..f062bcab --- /dev/null +++ b/completion/available/invoke.completion.bash @@ -0,0 +1,31 @@ +# Invoke (pyinvoke.org) tab-completion script to be sourced with Bash shell. +# https://github.com/pyinvoke/invoke/blob/master/completion/bash + +_complete_invoke() { + local candidates + + # COMP_WORDS contains the entire command string up til now (including + # program name). + # We hand it to Invoke so it can figure out the current context: spit back + # core options, task names, the current task's options, or some combo. + candidates=`invoke --complete -- ${COMP_WORDS[*]}` + + # `compgen -W` takes list of valid options & a partial word & spits back + # possible matches. Necessary for any partial word completions (vs + # completions performed when no partial words are present). + # + # $2 is the current word or token being tabbed on, either empty string or a + # partial word, and thus wants to be compgen'd to arrive at some subset of + # our candidate list which actually matches. + # + # COMPREPLY is the list of valid completions handed back to `complete`. + COMPREPLY=( $(compgen -W "${candidates}" -- $2) ) +} + + +# Tell shell builtin to use the above for completing 'inv'/'invoke': +# * -F: use given function name to generate completions. +# * -o default: when function generates no results, use filenames. +# * positional args: program names to complete for. +complete -F _complete_invoke -o default invoke inv + diff --git a/completion/available/knife.completion.bash b/completion/available/knife.completion.bash new file mode 100644 index 00000000..6316ce08 --- /dev/null +++ b/completion/available/knife.completion.bash @@ -0,0 +1,207 @@ +#!/usr/bin/env bash + +############## +### CONFIG ### +############## +### feel free to change those constants +# the dir where to store the cache (must be writable and readable by the current user) +# must be an absolute path +_KNIFE_AUTOCOMPLETE_CACHE_DIR="$HOME/.knife_autocomplete_cache" +# the maximum # of _seconds_ after which a cache will be considered stale +# (a cache is refreshed whenever it is used! this is only for caches that might not have been used for a long time) +# WARNING: keep that value > 100 +_KNIFE_AUTOCOMPLETE_MAX_CACHE_AGE=86400 + +############################################### +### END OF CONFIG - DON'T CHANGE CODE BELOW ### +############################################### + +### init +_KAC_CACHE_TMP_DIR="$_KNIFE_AUTOCOMPLETE_CACHE_DIR/tmp" +# make sure the cache dir exists +mkdir -p $_KAC_CACHE_TMP_DIR + +############################## +### Cache helper functions ### +############################## + +# GNU or BSD stat? +stat -c %Y /dev/null > /dev/null 2>&1 && _KAC_STAT_COMMAND="stat -c %Y" || _KAC_STAT_COMMAND="stat -f %m" + +# returns 0 iff the file whose path is given as 1st argument +# exists and has last been modified in the last $2 seconds +# returns 1 otherwise +_KAC_is_file_newer_than() +{ + [ -f "$1" ] || return 1 + [ $(( $(date +%s) - $($_KAC_STAT_COMMAND "$1") )) -gt $2 ] && return 1 || return 0 +} + +# helper function for _KAC_get_and_regen_cache, see doc below +_KAC_regen_cache() +{ + local CACHE_NAME=$1 + local CACHE_PATH="$_KNIFE_AUTOCOMPLETE_CACHE_DIR/$CACHE_NAME" + local TMP_FILE=$(mktemp "$_KAC_CACHE_TMP_DIR/$CACHE_NAME.XXXX") + shift 1 + "$@" > $TMP_FILE 2> /dev/null + # discard the temp file if it's empty AND the previous command didn't exit successfully, but still mark the cache as updated + [[ $? != 0 ]] && [[ $(cat $TMP_FILE | wc -l) == 0 ]] && rm -f $TMP_FILE && touch $CACHE_PATH && return 1 \ + || mv -f $TMP_FILE $CACHE_PATH +} + +# cached files can't have spaces in their names +_KAC_get_cache_name_from_command() +{ + echo "$@" | sed 's/ /_SPACE_/g' +} + +# the reverse operation from the function above +_KAC_get_command_from_cache_name() +{ + echo "$@" | sed 's/_SPACE_/ /g' +} + +# given a command as argument, it fetches the cache for that command if it can find it +# otherwise it waits for the cache to be generated +# in either case, it regenerates the cache, and sets the _KAC_CACHE_PATH env variable +# for obvious reason, do NOT call that in a sub-shell (in particular, no piping) +_KAC_get_and_regen_cache() +{ + # the cache name can't have space in it + local CACHE_NAME=$(_KAC_get_cache_name_from_command "$@") + local REGEN_CMD="_KAC_regen_cache $CACHE_NAME $@" + _KAC_CACHE_PATH="$_KNIFE_AUTOCOMPLETE_CACHE_DIR/$CACHE_NAME" + # no need to wait for the regen if the file already exists + [ -f $_KAC_CACHE_PATH ] && ($REGEN_CMD &) || $REGEN_CMD +} + +# performs two things: first, deletes all obsolete temp files +# then refreshes stale caches that haven't been called in a long time +_KAC_clean_cache() +{ + local FILE CMD + # delete all obsolete temp files, could be lingering there for any kind of crash in the caching process + for FILE in $(ls $_KAC_CACHE_TMP_DIR) + do + _KAC_is_file_newer_than $FILE $_KNIFE_AUTOCOMPLETE_MAX_CACHE_AGE || rm -f $FILE + done + # refresh really stale caches + for FILE in $(find $_KNIFE_AUTOCOMPLETE_CACHE_DIR -maxdepth 1 -type f -not -name '.*') + do + _KAC_is_file_newer_than $FILE $_KNIFE_AUTOCOMPLETE_MAX_CACHE_AGE && continue + # first let's get the original command + CMD=$(_KAC_get_command_from_cache_name $(basename "$FILE")) + # then regen the cache + _KAC_get_and_regen_cache "$CMD" > /dev/null + done +} + +# perform a cache cleaning when loading this file +_KAC_clean_cache + +##################################### +### End of cache helper functions ### +##################################### + + +# returns all the possible knife sub-commands +_KAC_knife_commands() +{ + knife --help | grep -E "^knife" | sed -E 's/ \(options\)//g' +} + +# rebuilds the knife base command currently being completed, and assigns it to $_KAC_CURRENT_COMMAND +# additionnally, returns 1 iff the current base command is not complete, 0 otherwise +# also sets $_KAC_CURRENT_COMMAND_NB_WORDS if the base command is complete +_KAC_get_current_base_command() +{ + local PREVIOUS="knife" + local I=1 + local CURRENT + while [ $I -le $COMP_CWORD ] + do + # command words are all lower-case + echo ${COMP_WORDS[$I]} | grep -E "^[a-z]+$" > /dev/null || break + CURRENT="$PREVIOUS ${COMP_WORDS[$I]}" + cat $_KAC_CACHE_PATH | grep -E "^$CURRENT" > /dev/null || break + PREVIOUS=$CURRENT + I=$(( $I + 1)) + done + _KAC_CURRENT_COMMAND=$PREVIOUS + [ $I -le $COMP_CWORD ] && _KAC_CURRENT_COMMAND_NB_WORDS=$I +} + +# searches the position of the currently completed argument in the current base command +# (i.e. handles "plural" arguments such as knife cookbook upload cookbook1 cookbook2 and so on...) +# assumes the current base command is complete +_KAC_get_current_arg_position() +{ + local CURRENT_ARG_POS=$(( $_KAC_CURRENT_COMMAND_NB_WORDS + 1 )) + local COMPLETE_COMMAND=$(cat $_KAC_CACHE_PATH | grep -E "^$_KAC_CURRENT_COMMAND") + local CURRENT_ARG + while [ $CURRENT_ARG_POS -le $COMP_CWORD ] + do + CURRENT_ARG=$(echo $COMPLETE_COMMAND | cut -d ' ' -f $CURRENT_ARG_POS) + # we break if the current arg is a "plural" arg + echo $CURRENT_ARG | grep -E "^\\[[^]]+(\\.\\.\\.\\]|$)" > /dev/null && break + CURRENT_ARG_POS=$(( $CURRENT_ARG_POS + 1 )) + done + echo $CURRENT_ARG_POS +} + +# the actual auto-complete function +_knife() +{ + _KAC_get_and_regen_cache _KAC_knife_commands + local RAW_LIST ITEM REGEN_CMD ARG_POSITION + COMREPLY=() + # get correct command & arg pos + _KAC_get_current_base_command && ARG_POSITION=$(_KAC_get_current_arg_position) || ARG_POSITION=$(( $COMP_CWORD + 1 )) + RAW_LIST=$(cat $_KAC_CACHE_PATH | grep -E "^$_KAC_CURRENT_COMMAND" | cut -d ' ' -f $ARG_POSITION | uniq) + + # we need to process that raw list a bit, most notably for placeholders + # NOTE: I chose to explicitely fetch & cache _certain_ informations for the server (cookbooks & node names, etc) + # as opposed to a generic approach by trying to find a 'list' knife command corresponding to the + # current base command - that might limit my script in some situation, but that way I'm sure it caches only + # not-sensitive stuff (a generic approach could be pretty bad e.g. with the knife-rackspace plugin) + LIST="" + for ITEM in $RAW_LIST + do + # always relevant if only lower-case chars : continuation of the base command + echo $ITEM | grep -E "^[a-z]+$" > /dev/null && LIST="$LIST $ITEM" && continue + case $ITEM in + *COOKBOOK*) + # special case for cookbooks : from site or local + [[ ${COMP_WORDS[2]} == 'site' ]] && REGEN_CMD="knife cookbook site list" || REGEN_CMD="knife cookbook list" + _KAC_get_and_regen_cache $REGEN_CMD + LIST="$LIST $(cat $_KAC_CACHE_PATH | cut -d ' ' -f 1)" + continue + ;; + *ITEM*) + # data bag item : another special case + local DATA_BAG_NAME=${COMP_WORDS[$(( COMP_CWORD-1 ))]} + REGEN_CMD="knife data bag show $DATA_BAG_NAME" + ;; + *INDEX*) + # see doc @ http://docs.opscode.com/knife_search.html + LIST="$LIST client environment node role" + REGEN_CMD="knife data bag list" + ;; + *BAG*) REGEN_CMD="knife data bag list";; + *CLIENT*) REGEN_CMD="knife client list";; + *NODE*) REGEN_CMD="knife node list";; + *ENVIRONMENT*) REGEN_CMD="knife environment list";; + *ROLE*) REGEN_CMD="knife role list";; + *USER*) REGEN_CMD="knife user list";; + # not a generic argument we support... + *) continue;; + esac + _KAC_get_and_regen_cache $REGEN_CMD + LIST="$LIST $(cat $_KAC_CACHE_PATH)" + done + COMPREPLY=( $(compgen -W "${LIST}" -- ${COMP_WORDS[COMP_CWORD]})) +} + +#complete -f -F _knife knife +complete -F _knife knife diff --git a/completion/available/lerna.completion.bash b/completion/available/lerna.completion.bash new file mode 100644 index 00000000..792ea27b --- /dev/null +++ b/completion/available/lerna.completion.bash @@ -0,0 +1,19 @@ +#!/bin/bash +# Lerna autocompletion. +function _lerna_completions() { + local cur compls + + # The currently-being-completed word. + cur="${COMP_WORDS[COMP_CWORD]}" + + # Options + compls="add bootstrap changed clean create diff exec \ + import init link list publish run version \ + --loglevel --concurrency --reject-cycles \ + --progress --sort --no-sort --help \ + --version" + + # Tell complete what stuff to show. + COMPREPLY=($(compgen -W "$compls" -- "$cur")) +} +complete -o default -F _lerna_completions lerna diff --git a/completion/available/minikube.completion.bash b/completion/available/minikube.completion.bash new file mode 100644 index 00000000..f1d19b87 --- /dev/null +++ b/completion/available/minikube.completion.bash @@ -0,0 +1,8 @@ +#!/usr/bin/env bash + +# minikube (Local Kubernetes) completion + +if command -v minikube &>/dev/null +then + eval "$(minikube completion bash)" +fi diff --git a/completion/available/pipenv.completion.bash b/completion/available/pipenv.completion.bash index 95ae87b7..339509f2 100644 --- a/completion/available/pipenv.completion.bash +++ b/completion/available/pipenv.completion.bash @@ -1 +1 @@ -[[ -x "$(which pipenv)" ]] && source <(env _PIPENV_COMPLETE="source-bash" pipenv) +[[ -x "$(which pipenv)" ]] && eval "$(pipenv --completion)" diff --git a/completion/available/sdkman.completion.bash b/completion/available/sdkman.completion.bash index f5af6c6a..b4d62da1 100644 --- a/completion/available/sdkman.completion.bash +++ b/completion/available/sdkman.completion.bash @@ -27,10 +27,14 @@ _sdkman_complete() esac elif [ $COMP_CWORD -eq 3 ]; then case "${COMP_WORDS[COMP_CWORD-2]}" in - "install" | "uninstall" | "rm" | "use" | "default" ) + "uninstall" | "rm" | "use" | "default" ) _sdkman_candidate_versions ${COMP_WORDS[COMP_CWORD-1]} COMPREPLY=( $(compgen -W "$CANDIDATE_VERSIONS" -- ${COMP_WORDS[COMP_CWORD]}) ) ;; + "install") + _sdkman_candidate_not_installed_versions ${COMP_WORDS[COMP_CWORD-1]} + COMPREPLY=( $(compgen -W "$CANDIDATE_VERSIONS" -- ${COMP_WORDS[COMP_CWORD]}) ) + ;; *) ;; esac @@ -51,6 +55,14 @@ _sdkman_candidate_versions(){ } +_sdkman_candidate_not_installed_versions(){ + CANDIDATE_LOCAL_VERSIONS=$(__sdkman_cleanup_local_versions $1) + if [ "$SDKMAN_OFFLINE_MODE" = "false" ]; then + CANDIDATE_ONLINE_VERSIONS="$(__sdkman_list_versions $1 | grep " " | grep "\." | cut -c 6-)" + CANDIDATE_VERSIONS="$(echo $CANDIDATE_ONLINE_VERSIONS $CANDIDATE_LOCAL_VERSIONS | tr ' ' '\n' | sort | uniq -u) " + fi +} + __sdkman_cleanup_local_versions(){ __sdkman_build_version_csv $1 | tr ',' ' ' diff --git a/completion/available/ssh.completion.bash b/completion/available/ssh.completion.bash index b54202bd..d5cd6e61 100644 --- a/completion/available/ssh.completion.bash +++ b/completion/available/ssh.completion.bash @@ -11,11 +11,16 @@ _sshcomplete() { local OPTIONS=" -- ${CURRENT_PROMPT}" fi - - # parse all defined hosts from .ssh/config - if [ -r "$HOME/.ssh/config" ]; then - COMPREPLY=($(compgen -W "$(grep -i ^Host "$HOME/.ssh/config" | awk '{for (i=2; i<=NF; i++) print $i}' )" ${OPTIONS}) ) - fi + # parse all defined hosts from .ssh/config and files included there + for fl in "$HOME/.ssh/config" \ + $(grep "^\s*Include" "$HOME/.ssh/config" | + awk '{for (i=2; i<=NF; i++) print $i}' | + sed "s|^~/|$HOME/|") + do + if [ -r "$fl" ]; then + COMPREPLY=( ${COMPREPLY[@]} $(compgen -W "$(grep -i ^Host "$fl" |grep -v '[*!]' | awk '{for (i=2; i<=NF; i++) print $i}' )" ${OPTIONS}) ) + fi + done # parse all hosts found in .ssh/known_hosts if [ -r "$HOME/.ssh/known_hosts" ]; then diff --git a/completion/available/system.completion.bash b/completion/available/system.completion.bash index b044627c..f9a3b29f 100644 --- a/completion/available/system.completion.bash +++ b/completion/available/system.completion.bash @@ -20,8 +20,8 @@ if [ $(uname) = "Darwin" ] && command -v brew &>/dev/null ; then . "$BREW_PREFIX"/etc/bash_completion fi - # homebrew/versions/bash-completion2 (required for projects.completion.bash) is installed to this path - if [ -f "$BREW_PREFIX"/share/bash-completion/bash_completion ]; then + # homebrew/versions/bash-completion2 (required for projects.completion.bash) is installed to this path + if [ "${BASH_VERSINFO}" -ge 4 ] && [ -f "$BREW_PREFIX"/share/bash-completion/bash_completion ]; then . "$BREW_PREFIX"/share/bash-completion/bash_completion fi fi diff --git a/completion/available/terraform.completion.bash b/completion/available/terraform.completion.bash index 11985f1d..201b7267 100644 --- a/completion/available/terraform.completion.bash +++ b/completion/available/terraform.completion.bash @@ -1,35 +1,65 @@ #!/usr/bin/env bash -# Bash Terraform completion -# Source: https://gist.github.com/cornfeedhobo/8bc08747ec3add1fc5adb2edb7cd68d3 +# +# Bash completion for the terraform command +# +# Copyright (C) 2018 Vangelis Tasoulas +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License +# as published by the Free Software Foundation; either version 2 +# of the License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. -_terraform() { - local cur prev words cword opts - _get_comp_words_by_ref -n : cur prev words cword - COMPREPLY=() - opts="" +_terraform() +{ + local cur prev words cword opts + _get_comp_words_by_ref -n : cur prev words cword + COMPREPLY=() + opts="" - if [[ ${cur} == -* ]] ; then - compopt -o nospace - fi + if [[ ${cword} -eq 1 ]] ; then - if [[ ${cword} -eq 1 ]] ; then - if [[ ${cur} == -* ]] ; then - opts="--help --version" - else - opts="$(terraform --help | grep -vE '(usage|Available|^$)' | awk '{print $1}')" - fi - fi + # Options that do not start with a hyphen, are always starting with four spaces. + opts="$(terraform --help | grep -E '^\s\s\s\s\S' | awk '{print $1}')" + opts="${opts} --help --version" - if [[ ${cword} -gt 1 ]] ; then - if [[ ${cword} -eq 2 && ${prev} == '--help' ]] ; then - opts="$(terraform --help | grep -vE '(usage|Available|^$)' | awk '{print $1}')" - else - opts="$(terraform --help "${words[1]}" | grep '^ *-[a-z]' | awk '{print $1}' | awk -F '=' '{if ($0 ~ /=/) {print $1"="} else {print $1" "}}')" - fi - fi + elif [[ ${cword} -gt 1 ]] ; then - COMPREPLY=( $(compgen -W "${opts}" -- ${cur}) ) - return 0 + if [[ ${cword} -eq 2 && ${prev} == '--help' ]] ; then + + opts="$(terraform --help | grep -E '^\s\s\s\s\S' | awk '{print $1}')" + + elif [[ ${words[1]} != "--help" && ${words[1]} != "--version" && ${words[1]} != "version" ]] ; then + + # Some commands accept hyphened parameters, ... + opts="$(terraform --help "${words[1]}" | grep -E '^\s+-' | awk '{print $1}' | awk -F '=' '{ if ($0 ~ /=/) {print $1"="} else {print $1} }')" + # but some other commands accept non-hyphened parameters. + opts="${opts} $(terraform --help "${words[1]}" | grep -E '^\s\s\s\s\S' | awk '{print $1}')" + # All of the commands accept the --help parameter which is not listed + # by the 'terraform --help + opts="${opts} --help" + + fi + fi + + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + + if [[ ${#COMPREPLY[*]} -eq 1 ]] ; then + if [[ ${COMPREPLY[0]} == *= ]] ; then + # When only one completion is left, check if there is an equal sign. + # If an equal sign, then add no space after the autocompleted word. + compopt -o nospace + fi + fi + return 0 } complete -F _terraform terraform diff --git a/install.sh b/install.sh index 7fa8cacf..c0848cdb 100755 --- a/install.sh +++ b/install.sh @@ -167,7 +167,7 @@ then done else echo "" - echo -e "\033[0;32mEnabling sane defaults\033[0m" + echo -e "\033[0;32mEnabling reasonable defaults\033[0m" _enable-completion bash-it _enable-completion system _enable-plugin base diff --git a/lib/helpers.bash b/lib/helpers.bash index 81f7280b..4cc2d574 100644 --- a/lib/helpers.bash +++ b/lib/helpers.bash @@ -61,7 +61,7 @@ function reload_plugins() { bash-it () { about 'Bash-it help and maintenance' - param '1: verb [one of: help | show | enable | disable | migrate | update | search | version ] ' + param '1: verb [one of: help | show | enable | disable | migrate | update | search | version | reload ] ' param '2: component type [one of: alias(es) | completion(s) | plugin(s) ] or search term(s)' param '3: specific component [optional]' example '$ bash-it show plugins' @@ -72,32 +72,35 @@ bash-it () example '$ bash-it update' example '$ bash-it search ruby [[-]rake]... [--enable | --disable]' example '$ bash-it version' + example '$ bash-it reload' typeset verb=${1:-} shift typeset component=${1:-} shift typeset func case $verb in - show) - func=_bash-it-$component;; - enable) - func=_enable-$component;; - disable) - func=_disable-$component;; - help) - func=_help-$component;; - search) - _bash-it-search $component "$@" - return;; - update) - func=_bash-it_update;; - migrate) - func=_bash-it-migrate;; - version) - func=_bash-it-version;; - *) - reference bash-it - return;; + show) + func=_bash-it-$component;; + enable) + func=_enable-$component;; + disable) + func=_disable-$component;; + help) + func=_help-$component;; + search) + _bash-it-search $component "$@" + return;; + update) + func=_bash-it_update;; + migrate) + func=_bash-it-migrate;; + version) + func=_bash-it-version;; + reload) + func=_bash-it-reload;; + *) + reference bash-it + return;; esac # pluralize component if necessary @@ -164,6 +167,8 @@ _bash-it_update() { _about 'updates Bash-it' _group 'lib' + local old_pwd="${PWD}" + cd "${BASH_IT}" || return if [ -z $BASH_IT_REMOTE ]; then @@ -176,22 +181,44 @@ _bash-it_update() { status="$(git rev-list master..${BASH_IT_REMOTE}/master 2> /dev/null)" if [[ -n "${status}" ]]; then - git pull --rebase &> /dev/null - if [[ $? -eq 0 ]]; then - echo "Bash-it successfully updated." - echo "" - echo "Migrating your installation to the latest version now..." - _bash-it-migrate - echo "" - echo "All done, enjoy!" - reload - else - echo "Error updating Bash-it, please, check if your Bash-it installation folder (${BASH_IT}) is clean." - fi + + for i in $(git rev-list --merges master..${BASH_IT_REMOTE}); do + num_of_lines=$(git log -1 --format=%B $i | awk 'NF' | wc -l) + if [ $num_of_lines -eq 1 ]; then + description="%s" + else + description="%b" + fi + git log --format="%h: $description (%an)" -1 $i + done + echo "" + read -e -n 1 -p "Would you like to update to $(git log -1 --format=%h origin/master)? [Y/n] " RESP + case $RESP in + [yY]|"") + git pull --rebase &> /dev/null + if [[ $? -eq 0 ]]; then + echo "Bash-it successfully updated." + echo "" + echo "Migrating your installation to the latest version now..." + _bash-it-migrate + echo "" + echo "All done, enjoy!" + bash-it reload + else + echo "Error updating Bash-it, please, check if your Bash-it installation folder (${BASH_IT}) is clean." + fi + ;; + [nN]) + echo "Not upgrading…" + ;; + *) + echo -e "\033[91mPlease choose y or n.\033[m" + ;; + esac else echo "Bash-it is up to date, nothing to do!" fi - cd - &> /dev/null || return + cd "${old_pwd}" &> /dev/null || return } _bash-it-migrate() { @@ -248,6 +275,25 @@ _bash-it-version() { echo "Current git SHA: $BASH_IT_GIT_VERSION_INFO" echo "$BASH_IT_GIT_URL/commit/$BASH_IT_GIT_SHA" + echo "Compare to latest: $BASH_IT_GIT_URL/compare/$BASH_IT_GIT_SHA...master" + + cd - &> /dev/null || return +} + +_bash-it-reload() { + _about 'reloads a profile file' + _group 'lib' + + cd "${BASH_IT}" || return + + case $OSTYPE in + darwin*) + source ~/.bash_profile + ;; + *) + source ~/.bashrc + ;; + esac cd - &> /dev/null || return } diff --git a/plugins/available/alias-completion.plugin.bash b/plugins/available/alias-completion.plugin.bash index b14131b4..e1c4ade7 100644 --- a/plugins/available/alias-completion.plugin.bash +++ b/plugins/available/alias-completion.plugin.bash @@ -29,7 +29,7 @@ function alias_completion { (( ${#completions[@]} == 0 )) && return 0 # create temporary file for wrapper functions and completions - local tmp_file; tmp_file="$(mktemp -t "${namespace}-${RANDOM}XXX.tmp")" || return 1 + local tmp_file; tmp_file="$(mktemp -t "${namespace}-${RANDOM}XXXXXX")" || return 1 local completion_loader; completion_loader="$(complete -p -D 2>/dev/null | sed -Ene 's/.* -F ([^ ]*).*/\1/p')" @@ -56,7 +56,7 @@ function alias_completion { continue fi fi - local new_completion="$(complete -p "$alias_cmd")" + local new_completion="$(complete -p "$alias_cmd" 2>/dev/null)" # create a wrapper inserting the alias arguments if any if [[ -n $alias_args ]]; then @@ -77,8 +77,10 @@ function alias_completion { fi # replace completion trigger by alias - new_completion="${new_completion% *} $alias_name" - echo "$new_completion" >> "$tmp_file" + if [[ -n $new_completion ]]; then + new_completion="${new_completion% *} $alias_name" + echo "$new_completion" >> "$tmp_file" + fi done < <(alias -p | sed -Ene "s/$alias_regex/\2 '\3' '\4'/p") source "$tmp_file" && rm -f "$tmp_file" }; alias_completion diff --git a/plugins/available/aws.plugin.bash b/plugins/available/aws.plugin.bash index 1519f77b..66021267 100644 --- a/plugins/available/aws.plugin.bash +++ b/plugins/available/aws.plugin.bash @@ -1,11 +1,14 @@ cite about-plugin about-plugin 'AWS helper functions' +AWS_CONFIG_FILE="${AWS_CONFIG_FILE:-$HOME/.aws/config}" +AWS_SHARED_CREDENTIALS_FILE="${AWS_SHARED_CREDENTIALS_FILE:-$HOME/.aws/credentials}" + function awskeys { about 'helper function for AWS credentials file' group 'aws' - if [[ ! -f ~/.aws/credentials ]]; then + if [[ ! -f "${AWS_SHARED_CREDENTIALS_FILE}" ]]; then echo "AWS credentials file not found" return 1 fi @@ -35,14 +38,14 @@ function __awskeys_help { } function __awskeys_get { - local ln=$(grep -n "\[ *$1 *\]" ~/.aws/credentials | cut -d ":" -f 1) + local ln=$(grep -n "\[ *$1 *\]" "${AWS_SHARED_CREDENTIALS_FILE}" | cut -d ":" -f 1) if [[ -n "${ln}" ]]; then - tail -n +${ln} ~/.aws/credentials | egrep -m 2 "aws_access_key_id|aws_secret_access_key" + tail -n +${ln} "${AWS_SHARED_CREDENTIALS_FILE}" | egrep -m 3 "aws_access_key_id|aws_secret_access_key|aws_session_token" fi } function __awskeys_list { - local credentials_list="$((egrep '^\[ *[a-zA-Z0-9_-]+ *\]$' ~/.aws/credentials; grep "\[profile" ~/.aws/config | sed "s|\[profile |\[|g") | sort | uniq)" + local credentials_list="$((egrep '^\[ *[a-zA-Z0-9_-]+ *\]$' "${AWS_SHARED_CREDENTIALS_FILE}"; grep "\[profile" "${AWS_CONFIG_FILE}" | sed "s|\[profile |\[|g") | sort | uniq)" if [[ -n $"{credentials_list}" ]]; then echo -e "Available credentials profiles:\n" for profile in ${credentials_list}; do @@ -72,14 +75,14 @@ function __awskeys_export { export "$(echo ${key} | tr [:lower:] [:upper:])=${p_key#*=}" done fi - export AWS_DEFAULT_PROFILE="$1" + export AWS_PROFILE="$1" else echo "Profile $1 not found in credentials file" fi } function __awskeys_unset { - unset AWS_DEFAULT_PROFILE AWS_ACCESS_KEY_ID AWS_SECRET_ACCESS_KEY + unset AWS_PROFILE AWS_ACCESS_KEY_ID AWS_SECRET_ACCESS_KEY AWS_SESSION_TOKEN } function __awskeys_comp { diff --git a/plugins/available/explain.plugin.bash b/plugins/available/explain.plugin.bash index d57b78e2..1fb38bdd 100644 --- a/plugins/available/explain.plugin.bash +++ b/plugins/available/explain.plugin.bash @@ -5,7 +5,7 @@ explain () { about 'explain any bash command via mankier.com manpage API' param '1: Name of the command to explain' example '$ explain # interactive mode. Type commands to explain in REPL' - example '$ explain 'cmd -o | ...' # one quoted command to explain it.' + example '$ explain '"'"'cmd -o | ...'"'"' # one quoted command to explain it.' group 'explain' if [ "$#" -eq 0 ]; then diff --git a/plugins/available/fzf.plugin.bash b/plugins/available/fzf.plugin.bash index c4fa451e..def60825 100644 --- a/plugins/available/fzf.plugin.bash +++ b/plugins/available/fzf.plugin.bash @@ -4,7 +4,15 @@ cite about-plugin about-plugin 'load fzf, if you are using it' -[ -f ~/.fzf.bash ] && source ~/.fzf.bash +if [ -f ~/.fzf.bash ]; then + source ~/.fzf.bash +elif [ -f "${XDG_CONFIG_HOME:-$HOME/.config}"/fzf/fzf.bash ]; then + source "${XDG_CONFIG_HOME:-$HOME/.config}"/fzf/fzf.bash +fi + +if [ -z ${FZF_DEFAULT_COMMAND+x} ]; then + command -v fd &> /dev/null && export FZF_DEFAULT_COMMAND='fd --type f' +fi fe() { about "Open the selected file in the default editor" @@ -18,11 +26,11 @@ fe() { [[ -n "$files" ]] && ${EDITOR:-vim} "${files[@]}" } -fd() { +fcd() { about "cd to the selected directory" group "fzf" param "1: Directory to browse, or . if omitted" - example "fd aliases" + example "fcd aliases" local dir dir=$(find ${1:-.} -path '*/\.*' -prune \ diff --git a/plugins/available/go.plugin.bash b/plugins/available/go.plugin.bash old mode 100644 new mode 100755 index c9fcdff8..827ac388 --- a/plugins/available/go.plugin.bash +++ b/plugins/available/go.plugin.bash @@ -5,7 +5,7 @@ about-plugin 'go environment variables & path configuration' [ ! command -v go &>/dev/null ] && return -export GOROOT=${GOROOT:-$(go env | grep GOROOT | cut -d'"' -f2)} +export GOROOT=${GOROOT:-$(go env GOROOT)} pathmunge "${GOROOT}/bin" -export GOPATH=${GOPATH:-"$HOME/go"} +export GOPATH=${GOPATH:-$(go env GOPATH)} pathmunge "${GOPATH}/bin" diff --git a/plugins/available/jenv.plugin.bash b/plugins/available/jenv.plugin.bash index 3cb2bcfc..08470688 100644 --- a/plugins/available/jenv.plugin.bash +++ b/plugins/available/jenv.plugin.bash @@ -4,6 +4,4 @@ about-plugin 'load jenv, if you are using it' export JENV_ROOT="$HOME/.jenv" pathmunge "$JENV_ROOT/bin" -if which jenv > /dev/null; then eval "$(jenv init -)"; fi - -[[ -e $JENV_ROOT/completions/jenv.bash ]] && source $JENV_ROOT/completions/jenv.bash +if which jenv > /dev/null; then eval "$(jenv init - bash)"; fi diff --git a/plugins/available/jgitflow.plugin.bash b/plugins/available/jgitflow.plugin.bash new file mode 100644 index 00000000..83ee8a23 --- /dev/null +++ b/plugins/available/jgitflow.plugin.bash @@ -0,0 +1,47 @@ +cite about-plugin +about-plugin 'Maven jgitflow build helpers' + +function hotfix-start { + about 'helper function for starting a new hotfix' + group 'jgitflow' + + mvn jgitflow:hotfix-start ${JGITFLOW_MVN_ARGUMENTS} +} + +function hotfix-finish { + about 'helper function for finishing a hotfix' + group 'jgitflow' + + mvn jgitflow:hotfix-finish -Darguments="${JGITFLOW_MVN_ARGUMENTS}" && git push && git push origin master && git push --tags +} + +function feature-start { + about 'helper function for starting a new feature' + group 'jgitflow' + + mvn jgitflow:feature-start ${JGITFLOW_MVN_ARGUMENTS} +} + +function feature-finish { + about 'helper function for finishing a feature' + group 'jgitflow' + + mvn jgitflow:feature-finish ${JGITFLOW_MVN_ARGUMENTS} + echo -e '\033[32m----------------------------------------------------------------\033[0m' + echo -e '\033[32m===== REMEMBER TO CREATE A NEW RELEASE TO DEPLOY THIS FEATURE ====\033[0m' + echo -e '\033[32m----------------------------------------------------------------\033[0m' +} + +function release-start { + about 'helper function for starting a new release' + group 'jgitflow' + + mvn jgitflow:release-start ${JGITFLOW_MVN_ARGUMENTS} +} + +function release-finish { + about 'helper function for finishing a release' + group 'jgitflow' + + mvn jgitflow:release-finish -Darguments="${JGITFLOW_MVN_ARGUMENTS}" && git push && git push origin master && git push --tags +} diff --git a/plugins/available/jump.plugin.bash b/plugins/available/jump.plugin.bash new file mode 100755 index 00000000..bc6f85e1 --- /dev/null +++ b/plugins/available/jump.plugin.bash @@ -0,0 +1,9 @@ +cite about-plugin +about-plugin 'initialize jump (see https://github.com/gsamokovarov/jump)' + +__init_jump() { + command -v jump &> /dev/null || return + eval "$(jump shell --bind=z)" +} + +__init_jump diff --git a/plugins/available/nodenv.plugin.bash b/plugins/available/nodenv.plugin.bash new file mode 100644 index 00000000..1bbe7fbd --- /dev/null +++ b/plugins/available/nodenv.plugin.bash @@ -0,0 +1,7 @@ +cite about-plugin +about-plugin 'load nodenv, if you are using it' + +export NODENV_ROOT="$HOME/.nodenv" +pathmunge "$NODENV_ROOT/bin" + +[[ `which nodenv` ]] && eval "$(nodenv init - bash)" diff --git a/plugins/available/osx.plugin.bash b/plugins/available/osx.plugin.bash index 8a638b14..0e74ab8d 100644 --- a/plugins/available/osx.plugin.bash +++ b/plugins/available/osx.plugin.bash @@ -5,7 +5,7 @@ about-plugin 'osx-specific functions' if [ $(uname) = "Darwin" ]; then if type update_terminal_cwd > /dev/null 2>&1 ; then if ! [[ $PROMPT_COMMAND =~ (^|;)update_terminal_cwd($|;) ]] ; then - PROMPT_COMMAND="$PROMPT_COMMAND;update_terminal_cwd" + PROMPT_COMMAND="${PROMPT_COMMAND%;};update_terminal_cwd" declared="$(declare -p PROMPT_COMMAND)" [[ "$declared" =~ \ -[aAilrtu]*x[aAilrtu]*\ ]] 2>/dev/null [[ $? -eq 0 ]] && export PROMPT_COMMAND @@ -98,5 +98,18 @@ function prevcurl() { curl "$*" | open -fa $PREVIEW } +function refresh-launchpad() { + about 'Reset launchpad layout in macOS' + example '$ refresh-launchpad' + group 'osx' + + if [ $(uname) = "Darwin" ];then + defaults write com.apple.dock ResetLaunchPad -bool TRUE + killall Dock + else + echo "Sorry, this only works on Mac OS X" + fi +} + # Make this backwards compatible alias pcurl='prevcurl' diff --git a/plugins/available/plenv.plugin.bash b/plugins/available/plenv.plugin.bash index 1e527b72..1da2d61b 100644 --- a/plugins/available/plenv.plugin.bash +++ b/plugins/available/plenv.plugin.bash @@ -4,18 +4,15 @@ cite about-plugin about-plugin 'plenv plugin for Perl' if [[ -e "${HOME}/.plenv/bin" ]] ; then - + # load plenv bin dir into path if it exists pathmunge "${HOME}/.plenv/bin" - + fi if [[ `which plenv` ]] ; then # init plenv - eval "$(plenv init -)" - - # Load the auto-completion script if it exists. - [[ -e "${HOME}/.plenv/completions/plenv.bash" ]] && source "${HOME}/.plenv/completions/plenv.bash" + eval "$(plenv init - bash)" fi diff --git a/plugins/available/postgres.plugin.bash b/plugins/available/postgres.plugin.bash index b90d8d76..e481d734 100644 --- a/plugins/available/postgres.plugin.bash +++ b/plugins/available/postgres.plugin.bash @@ -20,23 +20,23 @@ done function postgres_start { - about 'Starts PostgresSQL server' + about 'Starts PostgreSQL server' group 'postgres' - echo 'Starting PostgresSQL Server....'; + echo 'Starting Postgres....'; $POSTGRES_BIN/pg_ctl -D $PGDATA -l $PGDATA/logfile start } function postgres_stop { - about 'Steps PostgresSQL server' + about 'Stops PostgreSQL server' group 'postgres' - echo 'Stopping PostgresSQL Server....'; + echo 'Stopping Postgres....'; $POSTGRES_BIN/pg_ctl -D $PGDATA -l $PGDATA/logfile stop -s -m fast } function postgres_status { - about 'Returns status of PostgresSQL server' + about 'Returns status of PostgreSQL server' group 'postgres' # $POSTGRES_BIN/pg_ctl -D $PGDATA status @@ -55,7 +55,7 @@ function is_postgres_running { function postgres_restart { - about 'Restarts status of PostgresSQL server' + about 'Restarts status of PostgreSQL server' group 'postgres' echo 'Restarting Postgres....'; diff --git a/plugins/available/powerline.plugin.bash b/plugins/available/powerline.plugin.bash new file mode 100644 index 00000000..0388aa37 --- /dev/null +++ b/plugins/available/powerline.plugin.bash @@ -0,0 +1,26 @@ +#!/usr/bin/env bash + +cite about-plugin +about-plugin 'enables powerline daemon' + +command -v powerline-daemon &>/dev/null || return +powerline-daemon -q + +#the following should not be executed if bashit powerline themes in use +case "$BASH_IT_THEME" in + *powerline*) + return + ;; +esac +POWERLINE_BASH_CONTINUATION=1 +POWERLINE_BASH_SELECT=1 +bashPowerlineInit=$(python -c \ + "import os; \ + import powerline;\ + print(os.path.join(os.path.dirname(\ + powerline.__file__),\ + 'bindings', \ + 'bash', \ + 'powerline.sh'))") +[ -e $bashPowerlineInit ] || return +. $bashPowerlineInit diff --git a/plugins/available/pyenv.plugin.bash b/plugins/available/pyenv.plugin.bash index 0f6bffb8..dced31a8 100644 --- a/plugins/available/pyenv.plugin.bash +++ b/plugins/available/pyenv.plugin.bash @@ -4,12 +4,9 @@ about-plugin 'load pyenv, if you are using it' export PYENV_ROOT="$HOME/.pyenv" pathmunge "$PYENV_ROOT/bin" -[[ `which pyenv` ]] && eval "$(pyenv init -)" +[[ `which pyenv` ]] && eval "$(pyenv init - bash)" #Load pyenv virtualenv if the virtualenv plugin is installed. if pyenv virtualenv-init - &> /dev/null; then - eval "$(pyenv virtualenv-init -)" + eval "$(pyenv virtualenv-init - bash)" fi - -# Load the auto-completion script if pyenv was loaded. -[[ -e $PYENV_ROOT/completions/pyenv.bash ]] && source $PYENV_ROOT/completions/pyenv.bash diff --git a/plugins/available/rbenv.plugin.bash b/plugins/available/rbenv.plugin.bash index b1388017..ecba0c89 100644 --- a/plugins/available/rbenv.plugin.bash +++ b/plugins/available/rbenv.plugin.bash @@ -1,9 +1,7 @@ -# Load rbebv, if you are using it - cite about-plugin about-plugin 'load rbenv, if you are using it' -pathmunge "$HOME"/.rbenv/bin -[ -x `which rbenv` ] && eval "$(rbenv init -)" +export RBENV_ROOT="$HOME/.rbenv" +pathmunge "$RBENV_ROOT/bin" -[ -d "$HOME"/.rbenv/plugins/ruby-build ] && pathmunge "$HOME"/.rbenv/plugins/ruby-build/bin +[[ `which rbenv` ]] && eval "$(rbenv init - bash)" diff --git a/plugins/available/virtualenv.plugin.bash b/plugins/available/virtualenv.plugin.bash index 651bfec7..468870cd 100644 --- a/plugins/available/virtualenv.plugin.bash +++ b/plugins/available/virtualenv.plugin.bash @@ -1,9 +1,13 @@ # make sure virtualenvwrapper is enabled if available cite about-plugin -about-plugin 'virtualenvwrapper helper functions' +about-plugin 'virtualenvwrapper and pyenv-virtualenvwrapper helper functions' -[[ `which virtualenvwrapper.sh` ]] && . virtualenvwrapper.sh +if _command_exists pyenv; then + pyenv virtualenvwrapper +else + [[ `which virtualenvwrapper.sh` ]] && . virtualenvwrapper.sh +fi function mkvenv { diff --git a/template/bash_profile.template.bash b/template/bash_profile.template.bash index a052e91e..5e877900 100755 --- a/template/bash_profile.template.bash +++ b/template/bash_profile.template.bash @@ -3,7 +3,8 @@ # Path to the bash it configuration export BASH_IT="{{BASH_IT}}" -# Lock and Load a custom theme file +# Lock and Load a custom theme file. +# Leave empty to disable theming. # location /.bash_it/themes/ export BASH_IT_THEME='bobby' @@ -48,5 +49,8 @@ export SCM_CHECK=true # after enabling or disabling aliases, plugins, and completions. # export BASH_IT_AUTOMATIC_RELOAD_AFTER_CONFIG_CHANGE=1 +# Uncomment this to make Bash-it create alias reload. +# export BASH_IT_RELOAD_LEGACY=1 + # Load Bash It source "$BASH_IT"/bash_it.sh diff --git a/test/completion/bash-it.completion.bats b/test/completion/bash-it.completion.bats index 3cdc84ba..f35b180b 100644 --- a/test/completion/bash-it.completion.bats +++ b/test/completion/bash-it.completion.bats @@ -99,32 +99,32 @@ function __check_completion () { @test "completion bash-it: show options" { run __check_completion 'bash-it ' - assert_line -n 0 "disable enable help migrate search show update version" + assert_line -n 0 "disable enable help migrate reload search show update version" } @test "completion bash-it: bash-ti - show options" { run __check_completion 'bash-ti ' - assert_line -n 0 "disable enable help migrate search show update version" + assert_line -n 0 "disable enable help migrate reload search show update version" } @test "completion bash-it: shit - show options" { run __check_completion 'shit ' - assert_line -n 0 "disable enable help migrate search show update version" + assert_line -n 0 "disable enable help migrate reload search show update version" } @test "completion bash-it: bashit - show options" { run __check_completion 'bashit ' - assert_line -n 0 "disable enable help migrate search show update version" + assert_line -n 0 "disable enable help migrate reload search show update version" } @test "completion bash-it: batshit - show options" { run __check_completion 'batshit ' - assert_line -n 0 "disable enable help migrate search show update version" + assert_line -n 0 "disable enable help migrate reload search show update version" } @test "completion bash-it: bash_it - show options" { run __check_completion 'bash_it ' - assert_line -n 0 "disable enable help migrate search show update version" + assert_line -n 0 "disable enable help migrate reload search show update version" } @test "completion bash-it: show - show options" { diff --git a/test/test_helper.bash b/test/test_helper.bash index e2bb9442..9784cdf8 100644 --- a/test/test_helper.bash +++ b/test/test_helper.bash @@ -4,6 +4,7 @@ unset NGINX_PATH unset IRC_CLIENT unset TODO unset SCM_CHECK +unset BASH_IT_AUTOMATIC_RELOAD_AFTER_CONFIG_CHANGE BASH_IT_TEST_DIR="${BATS_TMPDIR}/.bash_it" diff --git a/themes/base.theme.bash b/themes/base.theme.bash index e27cd5f1..2761b632 100644 --- a/themes/base.theme.bash +++ b/themes/base.theme.bash @@ -7,6 +7,8 @@ CLOCK_THEME_PROMPT_SUFFIX='' THEME_PROMPT_HOST='\H' +SCM= + SCM_CHECK=${SCM_CHECK:=true} SCM_THEME_PROMPT_DIRTY=' ✗' @@ -30,6 +32,7 @@ SCM_GIT_SHOW_REMOTE_INFO=${SCM_GIT_SHOW_REMOTE_INFO:=auto} SCM_GIT_IGNORE_UNTRACKED=${SCM_GIT_IGNORE_UNTRACKED:=false} SCM_GIT_SHOW_CURRENT_USER=${SCM_GIT_SHOW_CURRENT_USER:=false} SCM_GIT_SHOW_MINIMAL_INFO=${SCM_GIT_SHOW_MINIMAL_INFO:=false} +SCM_GIT_SHOW_STASH_INFO=${SCM_GIT_SHOW_STASH_INFO:=true} SCM_GIT='git' SCM_GIT_CHAR='±' @@ -42,6 +45,12 @@ SCM_GIT_STAGED_CHAR="S:" SCM_GIT_STASH_CHAR_PREFIX="{" SCM_GIT_STASH_CHAR_SUFFIX="}" +SCM_P4='p4' +SCM_P4_CHAR='⌛' +SCM_P4_CHANGES_CHAR='C:' +SCM_P4_DEFAULT_CHAR='D:' +SCM_P4_OPENED_CHAR='O:' + SCM_HG='hg' SCM_HG_CHAR='☿' @@ -58,6 +67,8 @@ THEME_SHOW_USER_HOST=${THEME_SHOW_USER_HOST:=false} USER_HOST_THEME_PROMPT_PREFIX='' USER_HOST_THEME_PROMPT_SUFFIX='' +VIRTUAL_ENV= + VIRTUALENV_THEME_PROMPT_PREFIX=' |' VIRTUALENV_THEME_PROMPT_SUFFIX='|' @@ -69,11 +80,12 @@ RBFU_THEME_PROMPT_SUFFIX='|' function scm { if [[ "$SCM_CHECK" = false ]]; then SCM=$SCM_NONE - elif [[ -f .git/HEAD ]]; then SCM=$SCM_GIT + elif [[ -f .git/HEAD ]] && which git &> /dev/null; then SCM=$SCM_GIT elif which git &> /dev/null && [[ -n "$(git rev-parse --is-inside-work-tree 2> /dev/null)" ]]; then SCM=$SCM_GIT - elif [[ -d .hg ]]; then SCM=$SCM_HG + elif which p4 &> /dev/null && [[ -n "$(p4 set P4CLIENT 2> /dev/null)" ]]; then SCM=$SCM_P4 + elif [[ -d .hg ]] && which hg &> /dev/null; then SCM=$SCM_HG elif which hg &> /dev/null && [[ -n "$(hg root 2> /dev/null)" ]]; then SCM=$SCM_HG - elif [[ -d .svn ]]; then SCM=$SCM_SVN + elif [[ -d .svn ]] && which svn &> /dev/null; then SCM=$SCM_SVN else SCM=$SCM_NONE fi } @@ -81,6 +93,7 @@ function scm { function scm_prompt_char { if [[ -z $SCM ]]; then scm; fi if [[ $SCM == $SCM_GIT ]]; then SCM_CHAR=$SCM_GIT_CHAR + elif [[ $SCM == $SCM_P4 ]]; then SCM_CHAR=$SCM_P4_CHAR elif [[ $SCM == $SCM_HG ]]; then SCM_CHAR=$SCM_HG_CHAR elif [[ $SCM == $SCM_SVN ]]; then SCM_CHAR=$SCM_SVN_CHAR else SCM_CHAR=$SCM_NONE_CHAR @@ -93,6 +106,7 @@ function scm_prompt_vars { SCM_DIRTY=0 SCM_STATE='' [[ $SCM == $SCM_GIT ]] && git_prompt_vars && return + [[ $SCM == $SCM_P4 ]] && p4_prompt_vars && return [[ $SCM == $SCM_HG ]] && hg_prompt_vars && return [[ $SCM == $SCM_SVN ]] && svn_prompt_vars && return } @@ -125,8 +139,9 @@ function scm_prompt_info_common { fi # TODO: consider adding minimal status information for hg and svn - { [[ ${SCM:-} == ${SCM_HG} ]] && hg_prompt_info && return; } || true - { [[ ${SCM:-} == ${SCM_SVN} ]] && svn_prompt_info && return; } || true + { [[ ${SCM} == ${SCM_P4} ]] && p4_prompt_info && return; } || true + { [[ ${SCM} == ${SCM_HG} ]] && hg_prompt_info && return; } || true + { [[ ${SCM} == ${SCM_SVN} ]] && svn_prompt_info && return; } || true } function git_prompt_minimal_info { @@ -167,9 +182,11 @@ function git_prompt_vars { [[ "${commits_ahead}" -gt 0 ]] && SCM_BRANCH+=" ${SCM_GIT_AHEAD_CHAR}${commits_ahead}" [[ "${commits_behind}" -gt 0 ]] && SCM_BRANCH+=" ${SCM_GIT_BEHIND_CHAR}${commits_behind}" - local stash_count - stash_count="$(git stash list 2> /dev/null | wc -l | tr -d ' ')" - [[ "${stash_count}" -gt 0 ]] && SCM_BRANCH+=" ${SCM_GIT_STASH_CHAR_PREFIX}${stash_count}${SCM_GIT_STASH_CHAR_SUFFIX}" + if [[ "${SCM_GIT_SHOW_STASH_INFO}" = "true" ]]; then + local stash_count + stash_count="$(git stash list 2> /dev/null | wc -l | tr -d ' ')" + [[ "${stash_count}" -gt 0 ]] && SCM_BRANCH+=" ${SCM_GIT_STASH_CHAR_PREFIX}${stash_count}${SCM_GIT_STASH_CHAR_SUFFIX}" + fi SCM_STATE=${GIT_THEME_PROMPT_CLEAN:-$SCM_THEME_PROMPT_CLEAN} if ! _git-hide-status; then @@ -193,6 +210,26 @@ function git_prompt_vars { SCM_CHANGE=$(_git-short-sha 2>/dev/null || echo "") } +function p4_prompt_vars { + IFS=$'\t' read -r \ + opened_count non_default_changes default_count \ + add_file_count edit_file_count delete_file_count \ + <<< "$(_p4-opened-counts)" + if [[ "${opened_count}" -gt 0 ]]; then + SCM_DIRTY=1 + SCM_STATE=${SCM_THEME_PROMPT_DIRTY} + [[ "${opened_count}" -gt 0 ]] && SCM_BRANCH+=" ${SCM_P4_OPENED_CHAR}${opened_count}" + [[ "${non_default_changes}" -gt 0 ]] && SCM_BRANCH+=" ${SCM_P4_CHANGES_CHAR}${non_default_changes}" + [[ "${default_count}" -gt 0 ]] && SCM_BRANCH+=" ${SCM_P4_DEFAULT_CHAR}${default_count}" + else + SCM_DIRTY=0 + SCM_STATE=${SCM_THEME_PROMPT_DIRTY} + fi + + SCM_PREFIX=${P4_THEME_PROMPT_PREFIX:-$SCM_THEME_PROMPT_PREFIX} + SCM_SUFFIX=${P4_THEME_PROMPT_SUFFIX:-$SCM_THEME_PROMPT_SUFFIX} +} + function svn_prompt_vars { if [[ -n $(svn status 2> /dev/null) ]]; then SCM_DIRTY=1 @@ -299,6 +336,10 @@ function ruby_version_prompt { echo -e "$(rbfu_version_prompt)$(rbenv_version_prompt)$(rvm_version_prompt)$(chruby_version_prompt)" } +function k8s_context_prompt { + echo -e "$(kubectl config current-context)" +} + function virtualenv_prompt { if [[ -n "$VIRTUAL_ENV" ]]; then virtualenv=`basename "$VIRTUAL_ENV"` @@ -313,7 +354,7 @@ function condaenv_prompt { } function py_interp_prompt { - py_version=$(python --version 2>&1 | awk '{print "py-"$2;}') || return + py_version=$(python --version 2>&1 | awk 'NR==1{print "py-"$2;}') || return echo -e "${PYTHON_THEME_PROMPT_PREFIX}${py_version}${PYTHON_THEME_PROMPT_SUFFIX}" } @@ -359,10 +400,16 @@ function user_host_prompt { # backwards-compatibility function git_prompt_info { + _git-hide-status && return git_prompt_vars echo -e "${SCM_PREFIX}${SCM_BRANCH}${SCM_STATE}${SCM_SUFFIX}" } +function p4_prompt_info() { + p4_prompt_vars + echo -e "${SCM_PREFIX}${SCM_BRANCH}:${SCM_CHANGE}${SCM_STATE}${SCM_SUFFIX}" +} + function svn_prompt_info { svn_prompt_vars echo -e "${SCM_PREFIX}${SCM_BRANCH}${SCM_STATE}${SCM_SUFFIX}" diff --git a/themes/candy/candy.theme.bash b/themes/candy/candy.theme.bash index f3f0abfc..60bde3cd 100644 --- a/themes/candy/candy.theme.bash +++ b/themes/candy/candy.theme.bash @@ -1,7 +1,7 @@ #!/usr/bin/env bash function prompt_command() { - PS1="${green}\u@\h $(clock_prompt) ${reset_color}${white}\w${reset_color}$(scm_prompt_info)${blue} →${bold_blue} ${reset_color} "; + PS1="${green}\u@\h $(clock_prompt) ${reset_color}${white}\w${reset_color}$(scm_prompt_info)${blue} →${bold_blue} ${reset_color} ${normal}"; } THEME_CLOCK_COLOR=${THEME_CLOCK_COLOR:-"$blue"} diff --git a/themes/codeword/README.md b/themes/codeword/README.md new file mode 100644 index 00000000..38201dbf --- /dev/null +++ b/themes/codeword/README.md @@ -0,0 +1,22 @@ +# Single line PS1 theme w/realtime history among windows + + +Minimal theme overrides from bash_it base theming + + +## `user@host:path[virt-env][scm] $` +Breakdown of the segments: + +- **user@host:path** - *convienient for LAN based `ssh` and `scp` tasks* +- [**virtualenv**] - *only appears when activated* +- [**scm**] - *only appears when activated* +- **marker** - *$ or # depending on current user* + +### Examples + +```bash +user@example.lan:~ $ cd /tmp/foo/bar/baz +user@example.lan:/tmp/foo/bar/baz $ cd $HOME/workspace +user@example.lan:~/workspace $ cd sampleRepo/ +user@example.lan:~/workspace/sampleRepo [± |master ↑1 ↓3 {1} S:2 ?:1 ✗|] $ +``` diff --git a/themes/codeword/codeword.theme.bash b/themes/codeword/codeword.theme.bash new file mode 100644 index 00000000..96723ce3 --- /dev/null +++ b/themes/codeword/codeword.theme.bash @@ -0,0 +1,38 @@ +SCM_THEME_PROMPT_PREFIX=${SCM_THEME_PROMPT_SUFFIX} +SCM_THEME_PROMPT_DIRTY="${bold_red} ✗${normal}" +SCM_THEME_PROMPT_CLEAN="${bold_green} ✓${normal}" +SCM_GIT_CHAR="${green}±${normal}" + +scm_prompt() { + CHAR=$(scm_char) + if [ $CHAR = $SCM_NONE_CHAR ] + then + return + else + echo " [$(scm_char)$(scm_prompt_info)]" + fi +} + +mark_prompt() { + echo "${green}\$${normal}" +} + +user_host_path_prompt() { + ps_user="${green}\u${normal}"; + ps_host="${blue}\H${normal}"; + ps_path="${yellow}\w${normal}"; + echo "$ps_user@$ps_host:$ps_path" +} + +prompt() { + PS1="$(user_host_path_prompt)$(virtualenv_prompt)$(scm_prompt) $(mark_prompt) " +} + +share_history() { + history -a + history -c + history -r +} + +safe_append_prompt_command share_history +safe_append_prompt_command prompt diff --git a/themes/demula/demula.theme.bash b/themes/demula/demula.theme.bash index 515d096d..e85c18f7 100644 --- a/themes/demula/demula.theme.bash +++ b/themes/demula/demula.theme.bash @@ -100,8 +100,7 @@ prompt() { if [ $(uname) = "Linux" ]; then - PS1="${TITLEBAR} -${SAVE_CURSOR}${MOVE_CURSOR_RIGHTMOST}${MOVE_CURSOR_5_LEFT}\ + PS1="${TITLEBAR}${SAVE_CURSOR}${MOVE_CURSOR_RIGHTMOST}${MOVE_CURSOR_5_LEFT} $(safe_battery_charge)${RESTORE_CURSOR}\ ${D_USER_COLOR}\u ${D_INTERMEDIATE_COLOR}\ at ${D_MACHINE_COLOR}\h ${D_INTERMEDIATE_COLOR}\ @@ -113,7 +112,7 @@ ${D_INTERMEDIATE_COLOR}$ ${D_DEFAULT_COLOR}" else PS1="${TITLEBAR} ${D_USER_COLOR}\u ${D_INTERMEDIATE_COLOR}\ -at ${D_MACHINE_COLOR}\h ${D_INTERMEDIATE_COLOR}\ +at ${D_MACHINE_COLOR}\h ${D_INTERMEDIATE_COLOR}\ in ${D_DIR_COLOR}\w ${D_INTERMEDIATE_COLOR}\ ${LAST_COMMAND_FAILED}\ $(demula_vcprompt)\ diff --git a/themes/elixr/elixr.theme.bash b/themes/elixr/elixr.theme.bash new file mode 100644 index 00000000..266abbad --- /dev/null +++ b/themes/elixr/elixr.theme.bash @@ -0,0 +1,23 @@ +#!/usr/bin/env bash + +SCM_THEME_PROMPT_DIRTY=" ${red}✗" +SCM_THEME_PROMPT_CLEAN=" ${bold_green}✓" +SCM_THEME_PROMPT_PREFIX=" ${green}| " +SCM_THEME_PROMPT_SUFFIX="${green} |" +SCM_NONE_CHAR='◐ ' +SCM_GIT_SHOW_MINIMAL_INFO=true +GIT_THEME_PROMPT_DIRTY=" ${red}✗" +GIT_THEME_PROMPT_CLEAN=" ${bold_green}✓" +GIT_THEME_PROMPT_PREFIX=" ${green}|" +GIT_THEME_PROMPT_SUFFIX="${green}|" + +RVM_THEME_PROMPT_PREFIX="|" +RVM_THEME_PROMPT_SUFFIX=" d|" + +BOLD="\[\e[1m\]" + +function prompt_command() { + PS1="\n${bold_cyan}$(scm_prompt_char_info)$(virtualenv_prompt) ${bold_cyan}\w :${reset_color}${normal}${BOLD} " +} + +safe_append_prompt_command prompt_command diff --git a/themes/githelpers.theme.bash b/themes/githelpers.theme.bash index ca4f88cd..24c4b1f4 100644 --- a/themes/githelpers.theme.bash +++ b/themes/githelpers.theme.bash @@ -71,7 +71,8 @@ function _git-hide-status { } function _git-status { - [[ "${SCM_GIT_IGNORE_UNTRACKED}" = "true" ]] && local git_status_flags='-uno' || true + local git_status_flags= + [[ "${SCM_GIT_IGNORE_UNTRACKED}" = "true" ]] && git_status_flags='-uno' || true git status --porcelain ${git_status_flags} 2> /dev/null } @@ -103,6 +104,8 @@ function _git-remote-info { [[ "$(_git-upstream)" == "" ]] && return || true [[ "$(_git-branch)" == "$(_git-upstream-branch)" ]] && local same_branch_name=true || true + local same_branch_name= + [[ "$(_git-branch)" == "$(_git-upstream-branch)" ]] && same_branch_name=true if ([[ "${SCM_GIT_SHOW_REMOTE_INFO}" = "auto" ]] && [[ "$(_git-num-remotes)" -ge 2 ]]) || [[ "${SCM_GIT_SHOW_REMOTE_INFO}" = "true" ]]; then if [[ "${same_branch_name}" != "true" ]]; then diff --git a/themes/norbu/norbu.theme.bash b/themes/norbu/norbu.theme.bash new file mode 100644 index 00000000..184c13c9 --- /dev/null +++ b/themes/norbu/norbu.theme.bash @@ -0,0 +1,27 @@ +#!/usr/bin/env bash + +function set_prompt_symbol () { + if test $1 -eq 0 ; then + PROMPT_SYMBOL=">_" + else + PROMPT_SYMBOL="${orange}>_${normal}" + fi +} +function prompt_command() { + set_prompt_symbol $? + if test -z "$VIRTUAL_ENV" ; then + PYTHON_VIRTUALENV="" + else + PYTHON_VIRTUALENV="${bold_yellow}[`basename \"$VIRTUAL_ENV\"`]" + fi + + PS1="${bold_orange}${PYTHON_VIRTUALENV}${reset_color}${bold_green}[\w]${bold_blue}\[$(scm_prompt_info)\]${normal} \n${PROMPT_SYMBOL} " +} + +# scm themeing +SCM_THEME_PROMPT_DIRTY=" ✗" +SCM_THEME_PROMPT_CLEAN=" ✓" +SCM_THEME_PROMPT_PREFIX="[" +SCM_THEME_PROMPT_SUFFIX="]" + +safe_append_prompt_command prompt_command diff --git a/themes/p4helpers.theme.bash b/themes/p4helpers.theme.bash new file mode 100644 index 00000000..27a777ac --- /dev/null +++ b/themes/p4helpers.theme.bash @@ -0,0 +1,45 @@ +#!/usr/bin/env bash + +function _p4-opened { + timeout 2.0s p4 opened -s 2> /dev/null +} + +function _p4-opened-counts { + # Return the following counts seperated by tabs: + # - count of opened files + # - count of pending changesets (other than defaults) + # - count of files in the default changeset + # - count of opened files in add mode + # - count of opened files in edit mode + # - count of opened files in delete mode + _p4-opened | awk ' + BEGIN { + opened=0; + type_array["edit"]=0; + type_array["add"]=0; + type_array["delete"]=0; + change_array["change"]=0; + } + { + # p4 opened prints one file per line, and all lines begin with "//" + # Here is an examples: + # + # $ p4 opened + # //depot/some/file.py#4 - edit change 716431 (text) + # //depot/another/file.py - edit default change (text) + # //now/add/a/newfile.sh - add change 435645 (text+k) + # + # + if ($1 ~ /^\/\//) { + opened += 1 + change_array[$5] += 1 + type_array[$3] += 1 + } + } + END { + default_changes=change_array["change"]; + non_default_changes=length(change_array) - 1; + print opened "\t" non_default_changes "\t" default_changes "\t" type_array["add"] "\t" type_array["edit"] "\t" type_array["delete"] + } +' +} diff --git a/themes/powerline-multiline/README.md b/themes/powerline-multiline/README.md index 4ceebec6..ee6095dd 100644 --- a/themes/powerline-multiline/README.md +++ b/themes/powerline-multiline/README.md @@ -46,14 +46,20 @@ The time/date is printed by the `date` command, so refer to its man page to chan The contents of both prompt sides can be "reordered", all the "segments" (every piece of information) can take any place. The currently available segments are: -* battery -* clock -* cwd -* in_vim -* python_venv -* ruby -* scm -* user_info +* `aws_profile` - Show the current value of the `AWS_PROFILE` environment variable +* `battery` - Battery information (you'll need to enable the `battery` plugin) +* `clock` - Current time in `HH:MM:SS` format +* `cwd` - Current working directory including full folder hierarchy (c.f. `wd`) +* `hostname` - Host name of machine +* `in_vim` - Show identifier if running in `:terminal` from vim +* `last_status` - Exit status of last run command +* `python_venv` - Python virtual environment information (`virtualenv`, `venv` + and `conda` supported) +* `ruby` - Current ruby version if using `rvm` +* `scm` - Version control information, `git` +* `user_info` - Current user +* `wd` - Working directory, like `cwd` but doesn't show the full folder + hierarchy, only the directory you're currently in. Two variables can be defined to set the order of the prompt segments: diff --git a/themes/powerline-multiline/powerline-multiline.base.bash b/themes/powerline-multiline/powerline-multiline.base.bash index b78f5b74..ac442f73 100644 --- a/themes/powerline-multiline/powerline-multiline.base.bash +++ b/themes/powerline-multiline/powerline-multiline.base.bash @@ -46,11 +46,13 @@ function __powerline_prompt_command { ## right prompt ## if [[ -n "${POWERLINE_RIGHT_PROMPT}" ]]; then - LEFT_PROMPT+="${move_cursor_rightmost}" + # LEFT_PROMPT+="${move_cursor_rightmost}" for segment in $POWERLINE_RIGHT_PROMPT; do local info="$(__powerline_${segment}_prompt)" [[ -n "${info}" ]] && __powerline_right_segment "${info}" done + RIGHT_PAD=$(printf "%.s " $(seq 1 $RIGHT_PROMPT_LENGTH)) + LEFT_PROMPT+="${RIGHT_PAD}${move_cursor_rightmost}" LEFT_PROMPT+="\033[${RIGHT_PROMPT_LENGTH}D" fi diff --git a/themes/powerline-multiline/powerline-multiline.theme.bash b/themes/powerline-multiline/powerline-multiline.theme.bash index 4f4f8917..ad64fb18 100644 --- a/themes/powerline-multiline/powerline-multiline.theme.bash +++ b/themes/powerline-multiline/powerline-multiline.theme.bash @@ -20,6 +20,7 @@ PYTHON_VENV_THEME_PROMPT_COLOR=35 SCM_NONE_CHAR="" SCM_GIT_CHAR=${POWERLINE_SCM_GIT_CHAR:=" "} +SCM_HG_CHAR=${POWERLINE_SCM_HG_CHAR:="☿ "} SCM_THEME_PROMPT_CLEAN="" SCM_THEME_PROMPT_DIRTY="" SCM_THEME_PROMPT_CLEAN_COLOR=25 @@ -35,6 +36,9 @@ RBENV_THEME_PROMPT_SUFFIX="" RUBY_THEME_PROMPT_COLOR=161 RUBY_CHAR=${POWERLINE_RUBY_CHAR:="❲r❳ "} +AWS_PROFILE_CHAR="${POWERLINE_AWS_PROFILE_CHAR:=❲aws❳ }" +AWS_PROFILE_PROMPT_COLOR=208 + CWD_THEME_PROMPT_COLOR=240 LAST_STATUS_THEME_PROMPT_COLOR=196 @@ -51,6 +55,8 @@ THEME_CLOCK_FORMAT=${THEME_CLOCK_FORMAT:="%H:%M:%S"} IN_VIM_THEME_PROMPT_COLOR=245 IN_VIM_THEME_PROMPT_TEXT="vim" +HOST_THEME_PROMPT_COLOR=0 + POWERLINE_LEFT_PROMPT=${POWERLINE_LEFT_PROMPT:="scm python_venv ruby cwd"} POWERLINE_RIGHT_PROMPT=${POWERLINE_RIGHT_PROMPT:="in_vim clock battery user_info"} diff --git a/themes/powerline-naked/README.md b/themes/powerline-naked/README.md index 9ee38271..da5e254b 100644 --- a/themes/powerline-naked/README.md +++ b/themes/powerline-naked/README.md @@ -14,6 +14,7 @@ A colorful theme, where shows a lot information about your shell session. * 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 Kubernetes environment * The current Python environment (Virtualenv, venv, and Conda are supported) in use * The current Ruby environment (rvm and rbenv are supported) in use * Last command exit code (only shown when the exit code is greater than 0) @@ -42,16 +43,23 @@ The time/date is printed by the `date` command, so refer to its man page to chan The contents of the prompt can be "reordered", all the "segments" (every piece of information) can take any place. The currently available segments are: -* battery -* clock -* cwd -* in_vim -* python_venv -* ruby -* scm -* user_info +* `aws_profile` - Show the current value of the `AWS_PROFILE` environment variable +* `battery` - Battery information (you'll need to enable the `battery` plugin) +* `clock` - Current time in `HH:MM:SS` format +* `cwd` - Current working directory including full folder hierarchy (c.f. `wd`) +* `hostname` - Host name of machine +* `in_vim` - Show identifier if running in `:terminal` from vim +* `k8s_context` - Show current kubernetes context +* `last_status` - Exit status of last run command +* `python_venv` - Python virtual environment information (`virtualenv`, `venv` + and `conda` supported) +* `ruby` - Current ruby version if using `rvm` +* `scm` - Version control information, `git` +* `user_info` - Current user +* `wd` - Working directory, like `cwd` but doesn't show the full folder + hierarchy, only the directory you're currently in. -A variables can be defined to set the order of the prompt segments: +A variable can be defined to set the order of the prompt segments: POWERLINE_PROMPT="user_info scm python_venv ruby cwd" diff --git a/themes/powerline-naked/powerline-naked.base.bash b/themes/powerline-naked/powerline-naked.base.bash index 1939dfca..f6b11f42 100644 --- a/themes/powerline-naked/powerline-naked.base.bash +++ b/themes/powerline-naked/powerline-naked.base.bash @@ -4,7 +4,7 @@ function __powerline_left_segment { local OLD_IFS="${IFS}"; IFS="|" local params=( $1 ) IFS="${OLD_IFS}" - local separator_char="" + local separator_char="${POWERLINE_LEFT_SEPARATOR}" local separator="" if [[ "${SEGMENTS_AT_LEFT}" -gt 0 ]]; then diff --git a/themes/powerline-naked/powerline-naked.theme.bash b/themes/powerline-naked/powerline-naked.theme.bash index 26633108..81025c84 100644 --- a/themes/powerline-naked/powerline-naked.theme.bash +++ b/themes/powerline-naked/powerline-naked.theme.bash @@ -1,9 +1,10 @@ #!/usr/bin/env bash +POWERLINE_LEFT_SEPARATOR=${POWERLINE_LEFT_SEPARATOR:=""} + . "$BASH_IT/themes/powerline-naked/powerline-naked.base.bash" PROMPT_CHAR=${POWERLINE_PROMPT_CHAR:=""} -POWERLINE_LEFT_SEPARATOR=${POWERLINE_LEFT_SEPARATOR:=""} USER_INFO_SSH_CHAR=${POWERLINE_USER_INFO_SSH_CHAR:=" "} USER_INFO_THEME_PROMPT_COLOR=240 @@ -15,6 +16,7 @@ PYTHON_VENV_THEME_PROMPT_COLOR=35 SCM_NONE_CHAR="" SCM_GIT_CHAR=${POWERLINE_SCM_GIT_CHAR:=" "} +SCM_HG_CHAR=${POWERLINE_SCM_HG_CHAR:="☿ "} SCM_THEME_PROMPT_CLEAN="" SCM_THEME_PROMPT_DIRTY="" SCM_THEME_PROMPT_COLOR=238 @@ -31,6 +33,12 @@ RBENV_THEME_PROMPT_SUFFIX="" RUBY_THEME_PROMPT_COLOR=161 RUBY_CHAR=${POWERLINE_RUBY_CHAR:="❲r❳ "} +KUBERNETES_CONTEXT_THEME_CHAR=${POWERLINE_KUBERNETES_CONTEXT_CHAR:="⎈ "} +KUBERNETES_CONTEXT_THEME_PROMPT_COLOR=26 + +AWS_PROFILE_CHAR="${POWERLINE_AWS_PROFILE_CHAR:=❲aws❳ }" +AWS_PROFILE_PROMPT_COLOR=208 + CWD_THEME_PROMPT_COLOR=254 LAST_STATUS_THEME_PROMPT_COLOR=124 @@ -47,6 +55,8 @@ THEME_CLOCK_FORMAT=${THEME_CLOCK_FORMAT:="%H:%M:%S"} IN_VIM_THEME_PROMPT_COLOR=245 IN_VIM_THEME_PROMPT_TEXT="vim" +HOST_THEME_PROMPT_COLOR=254 + POWERLINE_PROMPT=${POWERLINE_PROMPT:="user_info scm python_venv ruby cwd"} safe_append_prompt_command __powerline_prompt_command diff --git a/themes/powerline-plain/README.md b/themes/powerline-plain/README.md index 6347d991..701b9fa1 100644 --- a/themes/powerline-plain/README.md +++ b/themes/powerline-plain/README.md @@ -12,6 +12,7 @@ A colorful theme, where shows a lot information about your shell session. * 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 Kubernetes environment * The current Python environment (Virtualenv, venv, and Conda are supported) in use * The current Ruby environment (rvm and rbenv are supported) in use * Last command exit code (only shown when the exit code is greater than 0) @@ -40,16 +41,23 @@ The time/date is printed by the `date` command, so refer to its man page to chan The contents of the prompt can be "reordered", all the "segments" (every piece of information) can take any place. The currently available segments are: -* battery -* clock -* cwd -* in_vim -* python_venv -* ruby -* scm -* user_info +* `aws_profile` - Show the current value of the `AWS_PROFILE` environment variable +* `battery` - Battery information (you'll need to enable the `battery` plugin) +* `clock` - Current time in `HH:MM:SS` format +* `cwd` - Current working directory including full folder hierarchy (c.f. `wd`) +* `hostname` - Host name of machine +* `in_vim` - Show identifier if running in `:terminal` from vim +* `k8s_context` - Show current kubernetes context +* `last_status` - Exit status of last run command +* `python_venv` - Python virtual environment information (`virtualenv`, `venv` + and `conda` supported) +* `ruby` - Current ruby version if using `rvm` +* `scm` - Version control information, `git` +* `user_info` - Current user +* `wd` - Working directory, like `cwd` but doesn't show the full folder + hierarchy, only the directory you're currently in. -A variables can be defined to set the order of the prompt segments: +A variable can be defined to set the order of the prompt segments: POWERLINE_PROMPT="user_info scm python_venv ruby cwd" diff --git a/themes/powerline-plain/powerline-plain.theme.bash b/themes/powerline-plain/powerline-plain.theme.bash index 6e0796d7..bddb6450 100644 --- a/themes/powerline-plain/powerline-plain.theme.bash +++ b/themes/powerline-plain/powerline-plain.theme.bash @@ -12,6 +12,7 @@ PYTHON_VENV_THEME_PROMPT_COLOR=35 SCM_NONE_CHAR="" SCM_GIT_CHAR=${POWERLINE_SCM_GIT_CHAR:="⎇ "} +SCM_HG_CHAR=${POWERLINE_SCM_HG_CHAR:="☿ "} SCM_THEME_PROMPT_CLEAN="" SCM_THEME_PROMPT_DIRTY="" SCM_THEME_PROMPT_CLEAN_COLOR=25 @@ -25,7 +26,13 @@ RVM_THEME_PROMPT_SUFFIX="" RBENV_THEME_PROMPT_PREFIX="" RBENV_THEME_PROMPT_SUFFIX="" RUBY_THEME_PROMPT_COLOR=161 -RUBY_CHAR=${POWERLINE_RUBY_CHAR:="ⓔ "} +RUBY_CHAR=${POWERLINE_RUBY_CHAR:="💎 "} + +KUBERNETES_CONTEXT_THEME_CHAR=${POWERLINE_KUBERNETES_CONTEXT_CHAR:="⎈ "} +KUBERNETES_CONTEXT_THEME_PROMPT_COLOR=26 + +AWS_PROFILE_CHAR="${POWERLINE_AWS_PROFILE_CHAR:=❲aws❳ }" +AWS_PROFILE_PROMPT_COLOR=208 CWD_THEME_PROMPT_COLOR=240 @@ -43,6 +50,8 @@ THEME_CLOCK_FORMAT=${THEME_CLOCK_FORMAT:="%H:%M:%S"} IN_VIM_THEME_PROMPT_COLOR=245 IN_VIM_THEME_PROMPT_TEXT="vim" +HOST_THEME_PROMPT_COLOR=0 + POWERLINE_PROMPT=${POWERLINE_PROMPT:="user_info scm python_venv ruby cwd"} safe_append_prompt_command __powerline_prompt_command diff --git a/themes/powerline/README.md b/themes/powerline/README.md index d0a46815..974bcbeb 100644 --- a/themes/powerline/README.md +++ b/themes/powerline/README.md @@ -16,6 +16,7 @@ A colorful theme, where shows a lot information about your shell session. * 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 Kubernetes environment * The current Python environment (Virtualenv, venv, and Conda are supported) in use * The current Ruby environment (rvm and rbenv are supported) in use * Last command exit code (only shown when the exit code is greater than 0) @@ -44,16 +45,23 @@ The time/date is printed by the `date` command, so refer to its man page to chan The contents of the prompt can be "reordered", all the "segments" (every piece of information) can take any place. The currently available segments are: -* battery -* clock -* cwd -* in_vim -* python_venv -* ruby -* scm -* user_info +* `aws_profile` - Show the current value of the `AWS_PROFILE` environment variable +* `battery` - Battery information (you'll need to enable the `battery` plugin) +* `clock` - Current time in `HH:MM:SS` format +* `cwd` - Current working directory including full folder hierarchy (c.f. `wd`) +* `hostname` - Host name of machine +* `in_vim` - Show identifier if running in `:terminal` from vim +* `k8s_context` - Show current kubernetes context +* `last_status` - Exit status of last run command +* `python_venv` - Python virtual environment information (`virtualenv`, `venv` + and `conda` supported) +* `ruby` - Current ruby version if using `rvm` +* `scm` - Version control information, `git` +* `user_info` - Current user +* `wd` - Working directory, like `cwd` but doesn't show the full folder + hierarchy, only the directory you're currently in. -A variables can be defined to set the order of the prompt segments: +A variable can be defined to set the order of the prompt segments: POWERLINE_PROMPT="user_info scm python_venv ruby cwd" diff --git a/themes/powerline/powerline.base.bash b/themes/powerline/powerline.base.bash index c352a87a..08da5f7c 100644 --- a/themes/powerline/powerline.base.bash +++ b/themes/powerline/powerline.base.bash @@ -52,6 +52,16 @@ function __powerline_ruby_prompt { [[ -n "${ruby_version}" ]] && echo "${RUBY_CHAR}${ruby_version}|${RUBY_THEME_PROMPT_COLOR}" } +function __powerline_k8s_context_prompt { + local kubernetes_context="" + + if _command_exists kubectl; then + kubernetes_context="$(k8s_context_prompt)" + fi + + [[ -n "${kubernetes_context}" ]] && echo "${KUBERNETES_CONTEXT_THEME_CHAR}${kubernetes_context}|${KUBERNETES_CONTEXT_THEME_PROMPT_COLOR}" +} + function __powerline_python_venv_prompt { set +u local python_venv="" @@ -84,6 +94,10 @@ function __powerline_scm_prompt { fi if [[ "${SCM_GIT_CHAR}" == "${SCM_CHAR}" ]]; then scm_prompt+="${SCM_CHAR}${SCM_BRANCH}${SCM_STATE}" + elif [[ "${SCM_P4_CHAR}" == "${SCM_CHAR}" ]]; then + scm_prompt+="${SCM_CHAR}${SCM_BRANCH}${SCM_STATE}" + elif [[ "${SCM_HG_CHAR}" == "${SCM_CHAR}" ]]; then + scm_prompt+="${SCM_CHAR}${SCM_BRANCH}${SCM_STATE}" fi echo "${scm_prompt}${scm}|${color}" fi @@ -132,6 +146,12 @@ function __powerline_in_vim_prompt { fi } +function __powerline_aws_profile_prompt { + if [[ -n "${AWS_PROFILE}" ]]; then + echo "${AWS_PROFILE_CHAR}${AWS_PROFILE}|${AWS_PROFILE_PROMPT_COLOR}" + fi +} + function __powerline_left_segment { local OLD_IFS="${IFS}"; IFS="|" local params=( $1 ) diff --git a/themes/powerline/powerline.theme.bash b/themes/powerline/powerline.theme.bash index 12de9cbe..482b3464 100644 --- a/themes/powerline/powerline.theme.bash +++ b/themes/powerline/powerline.theme.bash @@ -15,6 +15,7 @@ PYTHON_VENV_THEME_PROMPT_COLOR=35 SCM_NONE_CHAR="" SCM_GIT_CHAR=${POWERLINE_SCM_GIT_CHAR:=" "} +SCM_HG_CHAR=${POWERLINE_SCM_HG_CHAR:="☿ "} SCM_THEME_PROMPT_CLEAN="" SCM_THEME_PROMPT_DIRTY="" SCM_THEME_PROMPT_CLEAN_COLOR=25 @@ -30,6 +31,12 @@ RBENV_THEME_PROMPT_SUFFIX="" RUBY_THEME_PROMPT_COLOR=161 RUBY_CHAR=${POWERLINE_RUBY_CHAR:="❲r❳ "} +KUBERNETES_CONTEXT_THEME_CHAR=${POWERLINE_KUBERNETES_CONTEXT_CHAR:="⎈ "} +KUBERNETES_CONTEXT_THEME_PROMPT_COLOR=26 + +AWS_PROFILE_CHAR="${POWERLINE_AWS_PROFILE_CHAR:=❲aws❳ }" +AWS_PROFILE_PROMPT_COLOR=208 + CWD_THEME_PROMPT_COLOR=240 LAST_STATUS_THEME_PROMPT_COLOR=52 @@ -46,6 +53,8 @@ THEME_CLOCK_FORMAT=${THEME_CLOCK_FORMAT:="%H:%M:%S"} IN_VIM_THEME_PROMPT_COLOR=245 IN_VIM_THEME_PROMPT_TEXT="vim" +HOST_THEME_PROMPT_COLOR=0 + POWERLINE_PROMPT=${POWERLINE_PROMPT:="user_info scm python_venv ruby cwd"} safe_append_prompt_command __powerline_prompt_command diff --git a/themes/powerturk/powerturk.theme.bash b/themes/powerturk/powerturk.theme.bash new file mode 100644 index 00000000..35404360 --- /dev/null +++ b/themes/powerturk/powerturk.theme.bash @@ -0,0 +1,185 @@ +#!/usr/bin/env bash +# Power-Turk theme for bash-it +# Author (C) 2015 Ahmed Seref Guneysu + +THEME_PROMPT_SEPARATOR="" + +SHELL_SSH_CHAR=" " +SHELL_THEME_PROMPT_COLOR=2 +SHELL_SSH_THEME_PROMPT_COLOR=208 + +VIRTUALENV_CHAR="ⓔ " +VIRTUALENV_THEME_PROMPT_COLOR=35 + +SCM_NONE_CHAR="" + +SCM_GIT_CHAR=" " # " " + +SCM_THEME_PROMPT_CLEAN="" +SCM_THEME_PROMPT_DIRTY="" + +SCM_THEME_PROMPT_COLOR=16 +SCM_THEME_PROMPT_CLEAN_COLOR=231 +SCM_THEME_PROMPT_DIRTY_COLOR=196 +SCM_THEME_PROMPT_STAGED_COLOR=220 +SCM_THEME_PROMPT_UNSTAGED_COLOR=166 + +CWD_THEME_PROMPT_COLOR=240 + +LAST_STATUS_THEME_PROMPT_COLOR=52 + +_collapsed_wd() { + # echo -e "\u2771\u276d\u276f" + echo $(pwd | perl -pe " + BEGIN { + binmode STDIN, ':encoding(UTF-8)'; + binmode STDOUT, ':encoding(UTF-8)'; + }; s|^$HOME||g; s|/([^/])[^/]*(?=/)|/\$1|g") | \ + sed -re "s/\//  /g" +} + +_swd(){ +# Adapted from http://stackoverflow.com/a/2951707/1766716 + begin="" # The unshortened beginning of the path. + shortbegin="" # The shortened beginning of the path. + current="" # The section of the path we're currently working on. + end="${2:-$(pwd)}/" # The unmodified rest of the path. + + if [[ "$end" =~ "$HOME" ]]; then + INHOME=1 + end="${end#$HOME}" #strip /home/username from start of string + begin="$HOME" #start expansion from the right spot + else + INHOME=0 + fi + + end="${end#/}" # Strip the first / + shortenedpath="$end" # The whole path, to check the length. + maxlength="${1:-0}" + + shopt -q nullglob && NGV="-s" || NGV="-u" # Store the value for later. + shopt -s nullglob # Without this, anything that doesn't exist in the filesystem turns into */*/*/... + + while [[ "$end" ]] && (( ${#shortenedpath} > maxlength )) + do + current="${end%%/*}" # everything before the first / + end="${end#*/}" # everything after the first / + + shortcur="$current" + shortcurstar="$current" # No star if we don't shorten it. + + for ((i=${#current}-2; i>=0; i--)); do + subcurrent="${current:0:i}" + matching=("$begin/$subcurrent"*) # Array of all files that start with $subcurrent. + (( ${#matching[*]} != 1 )) && break # Stop shortening if more than one file matches. + shortcur="$subcurrent" + shortcurstar="$subcurrent*" + done + + #advance + begin="$begin/$current" + shortbegin="$shortbegin/$shortcurstar" + shortenedpath="$shortbegin/$end" + done + + shortenedpath="${shortenedpath%/}" # strip trailing / + shortenedpath="${shortenedpath#/}" # strip leading / + + # Replaces slashes with  except first occurence. + if [ $INHOME -eq 1 ]; then + echo "~/$shortenedpath" | sed "s/\///2g" # make sure it starts with ~/ + else + echo "/$shortenedpath" | sed "s/\///2g" # Make sure it starts with / + fi + + shopt "$NGV" nullglob # Reset nullglob in case this is being used as a function. + +} +function set_rgb_color { + if [[ "${1}" != "-" ]]; then + fg="38;5;${1}" + fi + if [[ "${2}" != "-" ]]; then + bg="48;5;${2}" + [[ -n "${fg}" ]] && bg=";${bg}" + fi + echo -e "\[\033[${fg}${bg}m\]" +} + +function powerline_shell_prompt { + if [[ -n "${SSH_CLIENT}" ]]; then + SHELL_PROMPT="${bold_white}$(set_rgb_color - ${SHELL_SSH_THEME_PROMPT_COLOR}) ${SHELL_SSH_CHAR}\u@\h ${normal}" + LAST_THEME_COLOR=${SHELL_SSH_THEME_PROMPT_COLOR} + else + SHELL_PROMPT="${bold_white}$(set_rgb_color - ${SHELL_THEME_PROMPT_COLOR}) ${normal}" + LAST_THEME_COLOR=${SHELL_THEME_PROMPT_COLOR} + fi +} + +function powerline_virtualenv_prompt { + local environ="" + + if [[ -n "$CONDA_DEFAULT_ENV" ]]; then + environ="conda: $CONDA_DEFAULT_ENV" + elif [[ -n "$VIRTUAL_ENV" ]]; then + environ=$(basename "$VIRTUAL_ENV") + fi + + if [[ -n "$environ" ]]; then + VIRTUALENV_PROMPT="$(set_rgb_color ${LAST_THEME_COLOR} ${VIRTUALENV_THEME_PROMPT_COLOR})${THEME_PROMPT_SEPARATOR}${normal}$(set_rgb_color - ${VIRTUALENV_THEME_PROMPT_COLOR}) ${VIRTUALENV_CHAR}$environ ${normal}" + LAST_THEME_COLOR=${VIRTUALENV_THEME_PROMPT_COLOR} + else + VIRTUALENV_PROMPT="" + fi +} + +function powerline_scm_prompt { + scm_prompt_vars + + if [[ "${SCM_NONE_CHAR}" != "${SCM_CHAR}" ]]; then + if [[ "${SCM_DIRTY}" -eq 3 ]]; then + SCM_PROMPT="$(set_rgb_color ${SCM_THEME_PROMPT_STAGED_COLOR} ${SCM_THEME_PROMPT_COLOR})" + elif [[ "${SCM_DIRTY}" -eq 2 ]]; then + SCM_PROMPT="$(set_rgb_color ${SCM_THEME_PROMPT_UNSTAGED_COLOR} ${SCM_THEME_PROMPT_COLOR})" + elif [[ "${SCM_DIRTY}" -eq 1 ]]; then + SCM_PROMPT="$(set_rgb_color ${SCM_THEME_PROMPT_DIRTY_COLOR} ${SCM_THEME_PROMPT_COLOR})" + else + SCM_PROMPT="$(set_rgb_color ${SCM_THEME_PROMPT_CLEAN_COLOR} ${SCM_THEME_PROMPT_COLOR})" + fi + if [[ "${SCM_GIT_CHAR}" == "${SCM_CHAR}" ]]; then + SCM_PROMPT+=" ${SCM_CHAR}${SCM_BRANCH}${SCM_STATE}" + fi + SCM_PROMPT="$(set_rgb_color ${LAST_THEME_COLOR} ${SCM_THEME_PROMPT_COLOR})${THEME_PROMPT_SEPARATOR}${normal}${SCM_PROMPT} ${normal}" + LAST_THEME_COLOR=${SCM_THEME_PROMPT_COLOR} + else + SCM_PROMPT="" + fi +} + +function powerline_cwd_prompt { +CWD_PROMPT="$(set_rgb_color ${LAST_THEME_COLOR} ${CWD_THEME_PROMPT_COLOR})${THEME_PROMPT_SEPARATOR}$(set_rgb_color 0 ${CWD_THEME_PROMPT_COLOR}) $(_swd)${normal}$(set_rgb_color ${CWD_THEME_PROMPT_COLOR} -)${normal}" + LAST_THEME_COLOR=${CWD_THEME_PROMPT_COLOR} +} + +function powerline_last_status_prompt { + if [[ "$1" -eq 0 ]]; then + LAST_STATUS_PROMPT="$(set_rgb_color ${LAST_THEME_COLOR} -)${THEME_PROMPT_SEPARATOR}${normal}" + else + LAST_STATUS_PROMPT="$(set_rgb_color ${LAST_THEME_COLOR} ${LAST_STATUS_THEME_PROMPT_COLOR})${THEME_PROMPT_SEPARATOR}${normal}$(set_rgb_color - ${LAST_STATUS_THEME_PROMPT_COLOR}) ${LAST_STATUS} ${normal}$(set_rgb_color ${LAST_STATUS_THEME_PROMPT_COLOR} -)${THEME_PROMPT_SEPARATOR}${normal}" + fi +} + +function powerline_prompt_command() { + local LAST_STATUS="$?" + + powerline_shell_prompt + powerline_virtualenv_prompt + powerline_scm_prompt + powerline_cwd_prompt + powerline_last_status_prompt LAST_STATUS + + PS1="${SHELL_PROMPT}${VIRTUALENV_PROMPT}${SCM_PROMPT}${CWD_PROMPT}${LAST_STATUS_PROMPT} " +} + +PROMPT_COMMAND=powerline_prompt_command + diff --git a/themes/zork/zork.theme.bash b/themes/zork/zork.theme.bash index 75bc17d6..07f30e12 100644 --- a/themes/zork/zork.theme.bash +++ b/themes/zork/zork.theme.bash @@ -57,7 +57,12 @@ chroot(){ # show virtualenvwrapper my_ve(){ - if [ -n "$VIRTUAL_ENV" ] + + if [ -n "$CONDA_DEFAULT_ENV" ] + then + my_ps_ve="${bold_purple}${CONDA_DEFAULT_ENV}${normal}"; + echo "($my_ps_ve)"; + elif [ -n "$VIRTUAL_ENV" ] then my_ps_ve="${bold_purple}$ve${normal}"; echo "($my_ps_ve)"; diff --git a/uninstall.sh b/uninstall.sh index 18d88e80..17712610 100755 --- a/uninstall.sh +++ b/uninstall.sh @@ -16,7 +16,7 @@ esac BACKUP_FILE=$CONFIG_FILE.bak if [ ! -e "$HOME/$BACKUP_FILE" ]; then - echo -e "\033[0;33mBackup file "$HOME/$BACKUP_FILE" not found.\033[0m" >&2 + echo -e "\033[0;33mBackup file $HOME/$BACKUP_FILE not found.\033[0m" >&2 test -w "$HOME/$CONFIG_FILE" && mv "$HOME/$CONFIG_FILE" "$HOME/$CONFIG_FILE.uninstall" &&