Merge branch 'feature/pre-commit-hook' into enforce-pre-commit

* feature/pre-commit-hook: (186 commits)
  added git alias to list remote branch creators with date and time
  Add Kind support
  Fix the commandline for gifski
  Add Terraform and Terragrunt aliases
  lib: helpers: Handle stable revert update
  lib: helpers: Rename Upgrading -> Updating
  lib: Fetch from remote before calculating latest tag in bash-it update
  test: Add completion test for -s --silent flag
  completion: Add --silent and -s completion
  doc: Add --silent flag documentation
  helpers: Add --slient option to bash-it update
  lib: Update no-op message in case of stable update
  lib: Add BASH_IT_DEVELOPMENT_BRANCH variable
  lib: Update to stable now correctly fails if no tags are present
  doc: Add stable/dev option to update section
  completion: Update completion for new bash-it update
  lib: Improve bash-it update so it can update to latest tag
  alias: git: Add new pretty git log alias (ggf)
  alias: git: Add git pull / git push --force aliases
  Add bash-it restart command
  ...
pull/1434/head
Ira Abramov 2020-10-17 12:22:07 +03:00
commit 388d632a1c
91 changed files with 2097 additions and 10186 deletions

View File

@ -1,32 +1,15 @@
# EditorConfig is awesome: http://EditorConfig.org
[*]
indent_style = tab
indent_size = 4
shell_variant = bash
binary_next_line = true # like -bn
switch_case_indent = true # like -ci
space_redirects = true # like -sr
keep_padding = true # like -kp
end_of_line = lf
charset = utf-8
indent_style = space
indent_size = 2
end_of_line = lf
charset = utf-8
trim_trailing_whitespace = true
insert_final_newline = true
[*.md]
trim_trailing_whitespace = false
[*.*sh]
[.git*]
indent_style = tab
indent_size = 4
shell_variant = bash
binary_next_line = true # like -bn
switch_case_indent = true # like -ci
space_redirects = true # like -sr
keep_padding = true # like -kp
end_of_line = lf
charset = utf-8
trim_trailing_whitespace = true
insert_final_newline = true

10
.gitmodules vendored
View File

@ -1,12 +1,16 @@
[submodule "test_lib/bats-core"]
path = test_lib/bats-core
url = https://github.com/bats-core/bats-core
branch = tags/v1.2.0
[submodule "test_lib/bats-support"]
path = test_lib/bats-support
url = https://github.com/ztombol/bats-support
url = https://github.com/bats-core/bats-support
branch = tags/v0.3.0
[submodule "test_lib/bats-assert"]
path = test_lib/bats-assert
url = https://github.com/ztombol/bats-assert
url = https://github.com/bats-core/bats-assert
branch = tags/v2.0.0
[submodule "test_lib/bats-file"]
path = test_lib/bats-file
url = https://github.com/ztombol/bats-file
url = https://github.com/bats-core/bats-file
branch = tags/v0.3.0

View File

@ -1,6 +1,31 @@
sudo: false
script: test/run
language: c
os:
- linux
- osx
# YAML anchors need to appear first.
# Keys starting with an underscore are the custom ones, refer to
# https://docs.travis-ci.com/user/build-config-yaml#private-keys-as-yaml-anchors-and-aliases-and-external-tooling
_native_job: &native_job
script: |
test/run
language: shell
os: linux
dist: xenial
jobs:
- <<: *native_job
name: Ubuntu 16.04
- <<: *native_job
name: Ubuntu 18.04
dist: bionic
- <<: *native_job
name: MacOS xcode9.4
os: osx
osx_image: xcode9.4 # Default xcode on Travis.
- <<: *native_job
name: MacOS xcode11.5
os: osx
osx_image: xcode11.5 # Latest xcode on Travis.

View File

@ -2,6 +2,22 @@
This page summarizes a couple of rules to keep in mind when developing features or making changes in Bash-it.
## Debugging and Logging
### General Logging
While developing feature or making changes in general, you can log error/warning/debug
using `_log_error` `_log_warning` and `_log_debug`. This will help you solve problems quicker
and also propagate important notes to other users of Bash-it.
You can see the logs by using `bash-it doctor` command to reload and see the logs.
Alternatively, you can set `BASH_IT_LOG_LEVEL` to `BASH_IT_LOG_LEVEL_ERROR`, `BASH_IT_LOG_LEVEL_WARNING` or `BASH_IT_LOG_LEVEL_ALL`.
### Log Prefix/Context
You can define `BASH_IT_LOG_PREFIX` in your files in order to a have a constant prefix before your logs.
Note that we prefer to uses "tags" based logging, i.e `plugins: git: DEBUG: Loading git plugin`.
## Load Order
### General Load Order
@ -44,6 +60,11 @@ Having the order based on a numeric priority in a common directory allows for mo
These items are subject to change. When making changes to the internal functionality, this page needs to be updated as well.
## Plugin Disable Callbacks
Plugins can define a function that will be called when the plugin is being disabled.
The callback name should be `{PLUGIN_NAME}_on_disable`, you can see `gitstatus` for usage example.
## Using the pre-commit hook
Note the file .pre-commit-config.yaml at the top of the repo.

View File

@ -1,6 +1,7 @@
# Bash-it
[![Build Status](https://travis-ci.org/Bash-it/bash-it.svg?branch=master)](https://travis-ci.org/Bash-it/bash-it) [![Join the chat at https://gitter.im/Bash-it/bash-it](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/Bash-it/bash-it?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
[![Build Status](https://travis-ci.com/Bash-it/bash-it.svg?branch=master)](https://travis-ci.com/Bash-it/bash-it)
[![Join the chat at https://gitter.im/Bash-it/bash-it](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/Bash-it/bash-it?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
**Bash-it** is a collection of community Bash commands and scripts for Bash 3.2+.
(And a shameless ripoff of [oh-my-zsh](https://github.com/robbyrussell/oh-my-zsh) :smiley:)
@ -86,13 +87,24 @@ Have a look at our [bash-it-docker repository](https://github.com/Bash-it/bash-i
### Updating
To update Bash-it to the latest version, simply run:
To update Bash-it to the latest stable version, simply run:
```bash
bash-it update
bash-it update stable
```
that's all.
If you want to update to the latest dev version (directly from master), run:
```bash
bash-it update dev
```
If you want to update automatically and unattended, you can add the optional
`-s/--silent` flag, for example:
```bash
bash-it update dev --silent
```
If you are using an older version of Bash-it, it's possible that some functionality has changed, or that the internal structure of how Bash-it organizes its functionality has been updated.
For these cases, we provide a `migrate` command:
@ -394,6 +406,13 @@ $ git config --global --add bash-it.hide-status 1
Setting this flag globally has the same effect as `SCM_CHECK=true`, but only for Git repos.
### Speed up git status calculations
As an alternative to ignoring repo status entirely, you can try out the `gitstatus` plugin.
This plugin speeds up all `git status` calculations by up to 10x times!
**NOTE**: You will need to clone `gitstatus` repo from [here](https://github.com/romkatv/gitstatus).
### Pass function renamed to passgen
The Bash-it `pass` function has been renamed to `passgen` in order to avoid a naming conflict with the [pass password manager](https://www.passwordstore.org/).
@ -409,6 +428,20 @@ Unset `BASH_IT_LEGACY_PASS` to have Bash-it **return to default behavior**:
* `unset BASH_IT_LEGACY_PASS`
### Debugging
If you encounter problems with any part of Bash-it, run the following command:
```bash
bash-it doctor
```
This will reload your bash profile and print out logs of various parts in Bash-it.
Note that this command at default will print all logs, including debug logs.
You can call it like this:
```bash
bash-it doctor [errors/warnings/all]
```
In order to get wanted verbosity.
### Proxy Support
If you are working in a corporate environment where you have to go through a proxy server for internet access,

View File

@ -0,0 +1,23 @@
cite about-alias
about-alias 'Aliases for the bash-it command (these aliases are automatically included with the "general" aliases)'
# Common misspellings of bash-it
alias shit='bash-it'
alias batshit='bash-it'
alias bashit='bash-it'
alias batbsh='bash-it'
alias babsh='bash-it'
alias bash_it='bash-it'
alias bash_ti='bash-it'
# Additional bash-it aliases for help/show
alias bshsa='bash-it show aliases'
alias bshsc='bash-it show completions'
alias bshsp='bash-it show plugins'
alias bshha='bash-it help aliases'
alias bshhc='bash-it help completions'
alias bshhp='bash-it help plugins'
alias bshsch="bash-it search"
alias bshenp="bash-it enable plugin"
alias bshena="bash-it enable alias"
alias bshenc="bash-it enable completion"

View File

@ -28,7 +28,6 @@ alias vbpf="vim ~/.bash_profile"
if grep --color=auto "a" "${BASH_IT}/"*.md &> /dev/null
then
alias grep='grep --color=auto'
export GREP_COLOR='1;33'
fi
if which gshuf &> /dev/null
@ -75,27 +74,6 @@ fi
alias md='mkdir -p'
alias rd='rmdir'
# Common misspellings of bash-it
alias shit='bash-it'
alias batshit='bash-it'
alias bashit='bash-it'
alias batbsh='bash-it'
alias babsh='bash-it'
alias bash_it='bash-it'
alias bash_ti='bash-it'
# Additional bash-it aliases for help/show
alias bshsa='bash-it show aliases'
alias bshsc='bash-it show completions'
alias bshsp='bash-it show plugins'
alias bshha='bash-it help aliases'
alias bshhc='bash-it help completions'
alias bshhp='bash-it help plugins'
alias bshsch="bash-it search"
alias bshenp="bash-it enable plugin"
alias bshena="bash-it enable alias"
alias bshenc="bash-it enable completion"
# Shorten extract
alias xt="extract"
@ -113,3 +91,12 @@ catt() {
fi
done
}
# The Bash-it aliases were moved to the `bash-it.aliases.bash` file. The intent of this
# is to keep the script readable and less bloated. If you don't need to use
# the `general` aliases, but you want the Bash-it aliases, you can disable the `general`
# aliases and enable just the ones for Bash-it explicitly:
# bash-it disable alias general
# bash-it enable alias bash-it
# shellcheck source=./bash-it.aliases.bash
source "$BASH_IT/aliases/available/bash-it.aliases.bash"

View File

@ -22,6 +22,7 @@ alias gs='git status'
alias gss='git status -s'
alias gsu='git submodule update --init --recursive'
alias gl='git pull'
alias gpl='git pull'
alias glum='git pull upstream master'
alias gpr='git pull --rebase'
alias gpp='git pull && git push'
@ -35,8 +36,12 @@ alias gpom='git push origin master'
alias gr='git remote'
alias grv='git remote -v'
alias gra='git remote add'
alias grb='git rebase'
alias grm='git rebase master'
alias grmi='git rebase master -i'
alias gd='git diff'
alias gds='git diff --staged'
alias gdt='git difftool'
alias gdv='git diff -w "$@" | vim -R -'
alias gc='git commit -v'
alias gca='git commit -v -a'
@ -46,6 +51,8 @@ alias gci='git commit --interactive'
alias gcamd='git commit --amend'
alias gb='git branch'
alias gba='git branch -a'
# FROM https://stackoverflow.com/a/58623139/10362396
alias gbc='git for-each-ref --format="%(authorname) %09 %(if)%(HEAD)%(then)*%(else)%(refname:short)%(end) %09 %(creatordate)" refs/remotes/ --sort=authorname DESC'
alias gbt='git branch --track'
alias gbm='git branch -m'
alias gbd='git branch -d'
@ -64,7 +71,9 @@ alias gdel='git branch -D'
alias gmu='git fetch origin -v; git fetch upstream -v; git merge upstream/master'
alias gll='git log --graph --pretty=oneline --abbrev-commit'
alias gg="git log --graph --pretty=format:'%C(bold)%h%Creset%C(magenta)%d%Creset %s %C(yellow)<%an> %C(cyan)(%cr)%Creset' --abbrev-commit --date=relative"
alias ggf="git log --graph --date=short --pretty=format:'%C(auto)%h %Cgreen%an%Creset %Cblue%cd%Creset %C(auto)%d %s'"
alias ggs="gg --stat"
alias gsh="git show"
alias gsl="git shortlog -sn"
alias gwc="git whatchanged"
alias gt="git tag"
@ -79,15 +88,36 @@ alias gnew="git log HEAD@{1}..HEAD@{0}"
alias gcaa="git commit -a --amend -C HEAD"
# Rebase with latest remote master
alias gprom="git fetch origin master && git rebase origin/master && git update-ref refs/heads/master origin/master"
alias gpf="git push --force"
alias gpunch="git push --force-with-lease"
alias ggui="git gui"
alias gcsam="git commit -S -am"
# Stash aliases
alias gst="git stash"
alias gstb="git stash branch"
alias gstd="git stash drop"
alias gstl="git stash list"
# Push introduced in git v2.13.2
alias gstpu="git stash push"
alias gstpum="git stash push -m"
# Save deprecated since git v2.16.0
# - aliases now resolve to push
alias gsts="git stash push"
alias gstsm="git stash push -m"
# Alias gstpo added for symmetry with gstpu (push)
# - gstp remains as alias for pop due to long-standing usage
alias gstpo="git stash pop"
alias gstp="git stash pop"
alias gh='cd "$(git rev-parse --show-toplevel)"'
# Switch aliases - Requires git v2.23+
alias gsw="git switch"
alias gswm="git switch master"
alias gswc="git switch --create"
alias gswt="git switch --track"
# Git home
alias ghm='cd "$(git rev-parse --show-toplevel)"'
if ! _command_exists gh; then
alias gh='ghm'
fi
# Show untracked files
alias gu='git ls-files . --exclude-standard --others'

View File

@ -5,12 +5,11 @@
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'
if _command_exists 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'
@ -18,8 +17,9 @@ function _set_pkg_aliases()
alias kcdn='kubectl describe node'
alias kcgpan='kubectl get pods --all-namespaces'
alias kcgdan='kubectl get deployments --all-namespaces'
alias kcnetshoot='kubectl run --generator=run-pod/v1 netshoot-$(uuidgen | tr A-Z a-z | sed 's/-//g') --rm -i --tty --image nicolaka/netshoot -- /bin/bash'
fi
# launches a disposable netshoot pod in the k8s cluster
alias kcnetshoot='kubectl run --generator=run-pod/v1 netshoot-$(date +%s) --rm -i --tty --image nicolaka/netshoot -- /bin/bash'
fi
}
_set_pkg_aliases

View File

@ -0,0 +1,10 @@
# Aliases for Terraform and Terragrunt
cite 'about-alias'
about-alias 'Terraform abbreviations'
alias tf='terraform'
alias tfv='terraform validate'
alias tfp='terraform plan'
alias tfa='terraform apply'
alias tfd='terraform destory'

View File

@ -0,0 +1,15 @@
# Aliases for Terraform and Terragrunt
cite 'about-alias'
about-alias 'Terragrunt abbreviations'
alias tg='terragrunt'
alias tgv='terragrunt validate'
alias tgp='terragrunt plan'
alias tga='terragrunt apply'
alias tgd='terragrunt destroy'
alias tgva='terragrunt validate-all'
alias tgpa='terragrunt plan-all'
alias tgaa='terragrunt apply-all'
alias tgda='terragrunt destroy-all'

View File

@ -1,6 +1,11 @@
cite 'uuid-alias'
about-alias 'uuidgen aliases'
alias uuidu="uuidgen"
alias uuidl="uuidgen | tr '[:upper:]' '[:lower:]'"
alias uuid=uuidl # because upper case is like YELLING
if _command_exists uuid; then # Linux
alias uuidu="uuid | tr '[:lower:]' '[:upper:]'"
alias uuidl=uuid
elif _command_exists uuidgen; then # macOS/BSD
alias uuidu="uuidgen"
alias uuid="uuidgen | tr '[:upper:]' '[:lower:]'" # because upper case is like YELLING
alias uuidl=uuid
fi

View File

@ -1,37 +1,49 @@
#!/usr/bin/env bash
# Initialize Bash It
BASH_IT_LOG_PREFIX="core: main: "
# 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
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;
BASH_IT_OLD_BASH_SETUP=true
fi
# Load composure first, so we support function metadata
# shellcheck source=./lib/composure.bash
source "${BASH_IT}/lib/composure.bash"
# We need to load logging module first as well in order to be able to log
# shellcheck source=./lib/log.bash
source "${BASH_IT}/lib/log.bash"
# We can only log it now
[ -z "$BASH_IT_OLD_BASH_SETUP" ] || _log_warning "BASH_IT variable not initialized, please upgrade your bash-it version and reinstall it!"
# For backwards compatibility, look in old BASH_THEME location
if [ -z "$BASH_IT_THEME" ];
then
_log_warning "BASH_IT_THEME variable not initialized, please upgrade your bash-it version and reinstall it!"
export BASH_IT_THEME="$BASH_THEME";
unset BASH_THEME;
fi
# support 'plumbing' metadata
cite _about _param _example _group _author _version
# libraries, but skip appearance (themes) for now
_log_debug "Loading libraries(except appearance)..."
LIB="${BASH_IT}/lib/*.bash"
APPEARANCE_LIB="${BASH_IT}/lib/appearance.bash"
for _bash_it_config_file in $LIB
do
if [ "$_bash_it_config_file" != "$APPEARANCE_LIB" ]; then
filename=${_bash_it_config_file##*/}
filename=${filename%.bash}
BASH_IT_LOG_PREFIX="lib: ${filename}: "
_log_debug "Loading library file..."
# shellcheck disable=SC1090
source "$_bash_it_config_file"
fi
@ -51,36 +63,51 @@ done
# Load theme, if a theme was set
if [[ ! -z "${BASH_IT_THEME}" ]]; then
_log_debug "Loading \"${BASH_IT_THEME}\" theme..."
# Load colors and helpers first so they can be used in base theme
BASH_IT_LOG_PREFIX="themes: colors: "
# shellcheck source=./themes/colors.theme.bash
source "${BASH_IT}/themes/colors.theme.bash"
BASH_IT_LOG_PREFIX="themes: githelpers: "
# shellcheck source=./themes/githelpers.theme.bash
source "${BASH_IT}/themes/githelpers.theme.bash"
BASH_IT_LOG_PREFIX="themes: p4helpers: "
# shellcheck source=./themes/p4helpers.theme.bash
source "${BASH_IT}/themes/p4helpers.theme.bash"
BASH_IT_LOG_PREFIX="themes: base: "
# shellcheck source=./themes/base.theme.bash
source "${BASH_IT}/themes/base.theme.bash"
BASH_IT_LOG_PREFIX="lib: appearance: "
# appearance (themes) now, after all dependencies
# shellcheck source=./lib/appearance.bash
source "$APPEARANCE_LIB"
fi
# Load custom aliases, completion, plugins
BASH_IT_LOG_PREFIX="core: main: "
_log_debug "Loading custom aliases, completion, plugins..."
for file_type in "aliases" "completion" "plugins"
do
if [ -e "${BASH_IT}/${file_type}/custom.${file_type}.bash" ]
then
BASH_IT_LOG_PREFIX="${file_type}: custom: "
_log_debug "Loading component..."
# shellcheck disable=SC1090
source "${BASH_IT}/${file_type}/custom.${file_type}.bash"
fi
done
# Custom
BASH_IT_LOG_PREFIX="core: main: "
_log_debug "Loading general custom files..."
CUSTOM="${BASH_IT_CUSTOM:=${BASH_IT}/custom}/*.bash ${BASH_IT_CUSTOM:=${BASH_IT}/custom}/**/*.bash"
for _bash_it_config_file in $CUSTOM
do
if [ -e "${_bash_it_config_file}" ]; then
filename=$(basename "${_bash_it_config_file}")
filename=${filename%*.bash}
BASH_IT_LOG_PREFIX="custom: $filename: "
_log_debug "Loading custom file..."
# shellcheck disable=SC1090
source "$_bash_it_config_file"
fi

View File

@ -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 reload search show update version"
opts="disable enable help migrate reload restart doctor search show update version"
case "${chose_opt}" in
show)
local show_args="aliases completions plugins"
@ -82,7 +82,21 @@ _bash-it-comp()
return 0
fi
;;
migrate | reload | search | update | version)
doctor)
local doctor_args="errors warnings all"
COMPREPLY=( $(compgen -W "${doctor_args}" -- ${cur}) )
return 0
;;
update)
if [[ ${cur} == -* ]];then
local update_args="-s --silent"
else
local update_args="stable dev"
fi
COMPREPLY=( $(compgen -W "${update_args}" -- ${cur}) )
return 0
;;
migrate | reload | search | version)
return 0
;;
enable | disable)

View File

@ -1,13 +1,27 @@
if which brew >/dev/null 2>&1; then
BREW_PREFIX=$(brew --prefix)
if [ -f "$BREW_PREFIX"/etc/bash_completion.d/brew ]; then
. "$BREW_PREFIX"/etc/bash_completion.d/brew
elif [ -f "$BREW_PREFIX"/Library/Contributions/brew_bash_completion.sh ]; then
. "$BREW_PREFIX"/Library/Contributions/brew_bash_completion.sh
elif [ -f "$BREW_PREFIX"/completions/bash/brew ]; then
# For the git-clone based installation, see here for more info:
# https://github.com/Bash-it/bash-it/issues/1458
# https://docs.brew.sh/Shell-Completion
. "$BREW_PREFIX"/completions/bash/brew
fi
#!/usr/bin/env bash
# Load late to make sure `system` completion loads first
# BASH_IT_LOAD_PRIORITY: 375
if [[ "$(uname -s)" != 'Darwin' ]]; then
_log_warning "unsupported operating system - only 'Darwin' is supported"
return 0
fi
# Make sure brew is installed
_command_exists brew || return 0
BREW_PREFIX=${BREW_PREFIX:-$(brew --prefix)}
if [[ -r "$BREW_PREFIX"/etc/bash_completion.d/brew ]]; then
source "$BREW_PREFIX"/etc/bash_completion.d/brew
elif [[ -r "$BREW_PREFIX"/Library/Contributions/brew_bash_completion.sh ]]; then
source "$BREW_PREFIX"/Library/Contributions/brew_bash_completion.sh
elif [[ -f "$BREW_PREFIX"/completions/bash/brew ]]; then
# For the git-clone based installation, see here for more info:
# https://github.com/Bash-it/bash-it/issues/1458
# https://docs.brew.sh/Shell-Completion
source "$BREW_PREFIX"/completions/bash/brew
fi

View File

@ -1,11 +1 @@
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
_log_warning 'Bash completion for "crystal" is now covered by "system". This completion can be disabled.'

File diff suppressed because it is too large Load Diff

View File

@ -1,365 +0,0 @@
# hub tab-completion script for bash.
# This script complements the completion script that ships with git.
# Check that git tab completion is available
if declare -F _git > /dev/null; then
# Duplicate and rename the 'list_all_commands' function
eval "$(declare -f __git_list_all_commands | \
sed 's/__git_list_all_commands/__git_list_all_commands_without_hub/')"
# Wrap the 'list_all_commands' function with extra hub commands
__git_list_all_commands() {
cat <<-EOF
alias
pull-request
fork
create
browse
compare
ci-status
release
issue
update
EOF
__git_list_all_commands_without_hub
}
# Ensure cached commands are cleared
__git_all_commands=""
##########################
# hub command completions
##########################
# hub alias [-s] [SHELL]
_git_alias() {
local i c=2 s=-s sh shells="bash zsh sh ksh csh fish"
while [ $c -lt $cword ]; do
i="${words[c]}"
case "$i" in
-s)
unset s
;;
*)
for sh in $shells; do
if [ "$sh" = "$i" ]; then
unset shells
break
fi
done
;;
esac
((c++))
done
__gitcomp "$s $shells"
}
# hub browse [-u] [--|[USER/]REPOSITORY] [SUBPAGE]
_git_browse() {
local i c=2 u=-u repo subpage
local subpages_="commits issues tree wiki pulls branches stargazers
contributors network network/ graphs graphs/"
local subpages_network="members"
local subpages_graphs="commit-activity code-frequency punch-card"
while [ $c -lt $cword ]; do
i="${words[c]}"
case "$i" in
-u)
unset u
;;
*)
if [ -z "$repo" ]; then
repo=$i
else
subpage=$i
fi
;;
esac
((c++))
done
if [ -z "$repo" ]; then
__gitcomp "$u -- $(__hub_github_repos '\p')"
elif [ -z "$subpage" ]; then
case "$cur" in
*/*)
local pfx="${cur%/*}" cur_="${cur#*/}"
local subpages_var="subpages_$pfx"
__gitcomp "${!subpages_var}" "$pfx/" "$cur_"
;;
*)
__gitcomp "$u ${subpages_}"
;;
esac
else
__gitcomp "$u"
fi
}
# hub compare [-u] [USER[/REPOSITORY]] [[START...]END]
_git_compare() {
local i c=$((cword - 1)) u=-u user remote owner repo arg_repo rev
while [ $c -gt 1 ]; do
i="${words[c]}"
case "$i" in
-u)
unset u
;;
*)
if [ -z "$rev" ]; then
# Even though the logic below is able to complete both user/repo
# and revision in the right place, when there is only one argument
# (other than -u) in the command, that argument will be taken as
# revision. For example:
# $ hub compare -u upstream
# > https://github.com/USER/REPO/compare/upstream
if __hub_github_repos '\p' | grep -Eqx "^$i(/[^/]+)?"; then
arg_repo=$i
else
rev=$i
fi
elif [ -z "$arg_repo" ]; then
arg_repo=$i
fi
;;
esac
((c--))
done
# Here we want to find out the git remote name of user/repo, in order to
# generate an appropriate revision list
if [ -z "$arg_repo" ]; then
user=$(__hub_github_user)
if [ -z "$user" ]; then
for i in $(__hub_github_repos); do
remote=${i%%:*}
repo=${i#*:}
if [ "$remote" = origin ]; then
break
fi
done
else
for i in $(__hub_github_repos); do
remote=${i%%:*}
repo=${i#*:}
owner=${repo%%/*}
if [ "$user" = "$owner" ]; then
break
fi
done
fi
else
for i in $(__hub_github_repos); do
remote=${i%%:*}
repo=${i#*:}
owner=${repo%%/*}
case "$arg_repo" in
"$repo"|"$owner")
break
;;
esac
done
fi
local pfx cur_="$cur"
case "$cur_" in
*..*)
pfx="${cur_%%..*}..."
cur_="${cur_##*..}"
__gitcomp_nl "$(__hub_revlist $remote)" "$pfx" "$cur_"
;;
*)
if [ -z "${arg_repo}${rev}" ]; then
__gitcomp "$u $(__hub_github_repos '\o\n\p') $(__hub_revlist $remote)"
elif [ -z "$rev" ]; then
__gitcomp "$u $(__hub_revlist $remote)"
else
__gitcomp "$u"
fi
;;
esac
}
# hub create [NAME] [-p] [-d DESCRIPTION] [-h HOMEPAGE]
_git_create() {
local i c=2 name repo flags="-p -d -h"
while [ $c -lt $cword ]; do
i="${words[c]}"
case "$i" in
-d|-h)
((c++))
flags=${flags/$i/}
;;
-p)
flags=${flags/$i/}
;;
*)
name=$i
;;
esac
((c++))
done
if [ -z "$name" ]; then
repo=$(basename "$(pwd)")
fi
case "$prev" in
-d|-h)
COMPREPLY=()
;;
-p|*)
__gitcomp "$repo $flags"
;;
esac
}
# hub fork [--no-remote]
_git_fork() {
local i c=2 remote=yes
while [ $c -lt $cword ]; do
i="${words[c]}"
case "$i" in
--no-remote)
unset remote
;;
esac
((c++))
done
if [ -n "$remote" ]; then
__gitcomp "--no-remote"
fi
}
# hub pull-request [-f] [-m <MESSAGE>|-F <FILE>|-i <ISSUE>|<ISSUE-URL>] [-b <BASE>] [-h <HEAD>]
_git_pull_request() {
local i c=2 flags="-f -m -F -i -b -h"
while [ $c -lt $cword ]; do
i="${words[c]}"
case "$i" in
-m|-F|-i|-b|-h)
((c++))
flags=${flags/$i/}
;;
-f)
flags=${flags/$i/}
;;
esac
((c++))
done
case "$prev" in
-i)
COMPREPLY=()
;;
-b|-h)
# (Doesn't seem to need this...)
# Uncomment the following line when 'owner/repo:[TAB]' misbehaved
#_get_comp_words_by_ref -n : cur
__gitcomp_nl "$(__hub_heads)"
# __ltrim_colon_completions "$cur"
;;
-F)
COMPREPLY=( "$cur"* )
;;
-f|*)
__gitcomp "$flags"
;;
esac
}
###################
# Helper functions
###################
# __hub_github_user [HOST]
# Return $GITHUB_USER or the default github user defined in hub config
# HOST - Host to be looked-up in hub config. Default is "github.com"
__hub_github_user() {
if [ -n "$GITHUB_USER" ]; then
echo $GITHUB_USER
return
fi
local line h k v host=${1:-github.com} config=${HUB_CONFIG:-~/.config/gh}
if [ -f "$config" ]; then
while read line; do
if [ "$line" = "---" ]; then
continue
fi
k=${line%%:*}
v=${line#*:}
if [ -z "$v" ]; then
if [ "$h" = "$host" ]; then
break
fi
h=$k
continue
fi
k=${k#* }
v=${v#* }
if [ "$h" = "$host" ] && [ "$k" = "user" ]; then
echo "$v"
break
fi
done < "$config"
fi
}
# __hub_github_repos [FORMAT]
# List all github hosted repository
# FORMAT - Format string contains multiple of these:
# \m remote
# \p owner/repo
# \o owner
# escaped characters (\n, \t ...etc) work
# If omitted, prints all github repos in the format of "remote:owner/repo"
__hub_github_repos() {
local f format=$1
if [ -z "$(__gitdir)" ]; then
return
fi
if [ -z "$format" ]; then
format='\1:\2'
else
format=${format//\m/\1}
format=${format//\p/\2}
format=${format//\o/\3}
fi
command git config --get-regexp 'remote\.[^.]*\.url' |
grep -E ' ((https?|git)://|git@)github\.com[:/][^:/]+/[^/]+$' |
sed -E 's#^remote\.([^.]+)\.url +.+[:/](([^/]+)/[^.]+)(\.git)?$#'"$format"'#'
}
# __hub_heads
# List all local "branch", and remote "owner/repo:branch"
__hub_heads() {
local i remote repo branch dir=$(__gitdir)
if [ -d "$dir" ]; then
command git --git-dir="$dir" for-each-ref --format='%(refname:short)' \
"refs/heads/"
for i in $(__hub_github_repos); do
remote=${i%%:*}
repo=${i#*:}
command git --git-dir="$dir" for-each-ref --format='%(refname:short)' \
"refs/remotes/${remote}/" | while read branch; do
echo "${repo}:${branch#${remote}/}"
done
done
fi
}
# __hub_revlist [REMOTE]
# List all tags, and branches under REMOTE, without the "remote/" prefix
# REMOTE - Remote name to search branches from. Default is "origin"
__hub_revlist() {
local i remote=${1:-origin} dir=$(__gitdir)
if [ -d "$dir" ]; then
command git --git-dir="$dir" for-each-ref --format='%(refname:short)' \
"refs/remotes/${remote}/" | while read i; do
echo "${i#${remote}/}"
done
command git --git-dir="$dir" for-each-ref --format='%(refname:short)' \
"refs/tags/"
fi
}
# Enable completion for hub even when not using the alias
complete -o bashdefault -o default -o nospace -F _git gh 2>/dev/null \
|| complete -o default -o nospace -F _git gh
fi

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,10 @@
#!/usr/bin/env bash
cite "about-completion"
about-completion "GitHub CLI completion"
if _command_exists gh; then
if _command_exists brew; then
_log_warning "You don't need github-cli completion enabled if you have system completion enabled"
fi
eval "$(gh completion --shell=bash)"
fi

View File

@ -0,0 +1,5 @@
#!/usr/bin/env bash
if _command_exists kind; then
eval "$(kind completion bash)"
fi

View File

@ -0,0 +1 @@
_command_exists minishift && source <(minishift completion bash)

View File

@ -1,2 +1,8 @@
if _command_exists ng; then
# No longer supported, please see https://github.com/angular/angular-cli/issues/11043
# Fix courtesy of https://stackoverflow.com/questions/50194674/ng-completion-no-longer-exists
# . <(ng completion --bash)
. <(ng completion --bash)
NG_COMMANDS="add build config doc e2e generate help lint new run serve test update version xi18n"
complete -W "$NG_COMMANDS" ng
fi

View File

@ -1,3 +1 @@
#!/usr/bin/env bash
[ -x "$(which oc)" ] && eval "$(oc completion bash)"
_command_exists oc && source <(oc completion bash)

View File

@ -1,9 +1,17 @@
# Ensure that we log to doctor so the user can address these issues
_is_function _init_completion ||
_log_error '_init_completion not found. Ensure bash-completion 2.0 or newer is installed and configured properly.'
_is_function _rl_enabled ||
_log_error '_rl_enabled not found. Ensure bash-completion 2.0 or newer is installed and configured properly.'
_pj() {
[ -z "$PROJECT_PATHS" ] && return
_is_function _init_completion || return
_is_function _rl_enabled || return
[ -n "$PROJECT_PATHS" ] || return
shift
[ "$1" == "open" ] && shift
local cur prev words cword
local cur
_init_completion || return
local IFS=$'\n' i j k
@ -16,8 +24,8 @@ _pj() {
for i in ${PROJECT_PATHS//:/$'\n'}; do
# create an array of matched subdirs
k="${#COMPREPLY[@]}"
for j in $( compgen -d $i/$cur ); do
if [[ ( $mark_symdirs && -h $j || $mark_dirs && ! -h $j ) && ! -d ${j#$i/} ]]; then
for j in $(compgen -d "$i/$cur"); do
if [[ ($mark_symdirs && -L $j || $mark_dirs && ! -L $j) && ! -d ${j#$i/} ]]; then
j+="/"
fi
COMPREPLY[k++]=${j#$i/}

View File

@ -11,318 +11,325 @@
# TODO: cache results of some functions? where? how long?
# TODO: is it ok to use '--timeout 2' ?
_salt_get_grains(){
if [ "$1" = 'local' ] ; then
salt-call --out=txt -- grains.ls | sed 's/^.*\[//' | tr -d ",']" |sed 's:\([a-z0-9]\) :\1\: :g'
else
salt '*' --timeout 2 --out=txt -- grains.ls | sed 's/^.*\[//' | tr -d ",']" |sed 's:\([a-z0-9]\) :\1\: :g'
fi
_salt_get_grains() {
if [ "$1" = 'local' ]; then
salt-call --out=txt -- grains.ls | sed 's/^.*\[//' | tr -d ",']" | sed 's:\([a-z0-9]\) :\1\: :g'
else
salt '*' --timeout 2 --out=txt -- grains.ls | sed 's/^.*\[//' | tr -d ",']" | sed 's:\([a-z0-9]\) :\1\: :g'
fi
}
_salt_get_grain_values(){
if [ "$1" = 'local' ] ; then
salt-call --out=txt -- grains.item $1 |sed 's/^\S*:\s//' |grep -v '^\s*$'
else
salt '*' --timeout 2 --out=txt -- grains.item $1 |sed 's/^\S*:\s//' |grep -v '^\s*$'
fi
_salt_get_grain_values() {
if [ "$1" = 'local' ]; then
salt-call --out=txt -- grains.item $1 | sed 's/^\S*:\s//' | grep -v '^\s*$'
else
salt '*' --timeout 2 --out=txt -- grains.item $1 | sed 's/^\S*:\s//' | grep -v '^\s*$'
fi
}
_salt() {
local cur prev opts _salt_grains _salt_coms pprev ppprev
COMPREPLY=()
cur="${COMP_WORDS[COMP_CWORD]}"
prev="${COMP_WORDS[COMP_CWORD - 1]}"
if [ ${COMP_CWORD} -gt 2 ]; then
pprev="${COMP_WORDS[COMP_CWORD - 2]}"
fi
if [ ${COMP_CWORD} -gt 3 ]; then
ppprev="${COMP_WORDS[COMP_CWORD - 3]}"
fi
_salt(){
local cur prev opts _salt_grains _salt_coms pprev ppprev
COMPREPLY=()
cur="${COMP_WORDS[COMP_CWORD]}"
prev="${COMP_WORDS[COMP_CWORD-1]}"
if [ ${COMP_CWORD} -gt 2 ]; then
pprev="${COMP_WORDS[COMP_CWORD-2]}"
fi
if [ ${COMP_CWORD} -gt 3 ]; then
ppprev="${COMP_WORDS[COMP_CWORD-3]}"
fi
opts="-h --help -d --doc --documentation --version --versions-report -c \
--config-dir= -v --verbose -t --timeout= -s --static -b --batch= \
--batch-size= -E --pcre -L --list -G --grain --grain-pcre -N \
--nodegroup -R --range -C --compound -I --pillar \
--return= -a --auth= --eauth= --extended-auth= -T --make-token -S \
--ipcidr --out=pprint --out=yaml --out=overstatestage --out=json \
--out=raw --out=highstate --out=key --out=txt --no-color --out-indent= "
opts="-h --help -d --doc --documentation --version --versions-report -c \
--config-dir= -v --verbose -t --timeout= -s --static -b --batch= \
--batch-size= -E --pcre -L --list -G --grain --grain-pcre -N \
--nodegroup -R --range -C --compound -I --pillar \
--return= -a --auth= --eauth= --extended-auth= -T --make-token -S \
--ipcidr --out=pprint --out=yaml --out=overstatestage --out=json \
--out=raw --out=highstate --out=key --out=txt --no-color --out-indent= "
if [[ "${cur}" == -* ]]; then
COMPREPLY=($(compgen -W "${opts}" -- ${cur}))
return 0
fi
if [[ "${cur}" == -* ]] ; then
COMPREPLY=($(compgen -W "${opts}" -- ${cur}))
# 2 special cases for filling up grain values
case "${pprev}" in
-G | --grain | --grain-pcre)
if [ "${cur}" = ":" ]; then
COMPREPLY=($(compgen -W "$(_salt_get_grain_values ${prev})"))
return 0
fi
fi
;;
esac
case "${ppprev}" in
-G | --grain | --grain-pcre)
if [ "${prev}" = ":" ]; then
COMPREPLY=($(compgen -W "$(_salt_get_grain_values ${pprev})" -- ${cur}))
return 0
fi
;;
esac
# 2 special cases for filling up grain values
case "${pprev}" in
-G|--grain|--grain-pcre)
if [ "${cur}" = ":" ]; then
COMPREPLY=($(compgen -W "`_salt_get_grain_values ${prev}`" ))
return 0
fi
;;
esac
case "${ppprev}" in
-G|--grain|--grain-pcre)
if [ "${prev}" = ":" ]; then
COMPREPLY=( $(compgen -W "`_salt_get_grain_values ${pprev}`" -- ${cur}) )
return 0
fi
;;
esac
if [ "${cur}" = "=" ] && [[ "${prev}" == --* ]]; then
cur=""
fi
if [ "${prev}" = "=" ] && [[ "${pprev}" == --* ]]; then
prev="${pprev}"
fi
if [ "${cur}" = "=" ] && [[ "${prev}" == --* ]]; then
cur=""
fi
if [ "${prev}" = "=" ] && [[ "${pprev}" == --* ]]; then
prev="${pprev}"
fi
case "${prev}" in
case "${prev}" in
-c | --config)
COMPREPLY=($(compgen -f -- ${cur}))
return 0
;;
salt)
COMPREPLY=($(compgen -W "\'*\' ${opts} $(salt-key --no-color -l acc)" -- ${cur}))
return 0
;;
-E | --pcre)
COMPREPLY=($(compgen -W "$(salt-key --no-color -l acc)" -- ${cur}))
return 0
;;
-G | --grain | --grain-pcre)
COMPREPLY=($(compgen -W "$(_salt_get_grains)" -- ${cur}))
return 0
;;
-C | --compound)
COMPREPLY=() # TODO: finish this one? how?
return 0
;;
-t | --timeout)
COMPREPLY=($(compgen -W "1 2 3 4 5 6 7 8 9 10 15 20 30 40 60 90 120 180" -- ${cur}))
return 0
;;
-b | --batch | --batch-size)
COMPREPLY=($(compgen -W "1 2 3 4 5 6 7 8 9 10 15 20 30 40 50 60 70 80 90 100 120 150 200"))
return 0
;;
-N | --nodegroup)
MASTER_CONFIG='/etc/salt/master'
COMPREPLY=($(compgen -W "$(awk -F ':' 'BEGIN {print_line = 0}; /^nodegroups/ {print_line = 1;getline } print_line && /^ */ {print $1} /^[^ ]/ {print_line = 0}' <${MASTER_CONFIG})" -- ${cur}))
return 0
;;
esac
-c|--config)
COMPREPLY=($(compgen -f -- ${cur}))
return 0
;;
salt)
COMPREPLY=($(compgen -W "\'*\' ${opts} `salt-key --no-color -l acc`" -- ${cur}))
return 0
;;
-E|--pcre)
COMPREPLY=($(compgen -W "`salt-key --no-color -l acc`" -- ${cur}))
return 0
;;
-G|--grain|--grain-pcre)
COMPREPLY=($(compgen -W "$(_salt_get_grains)" -- ${cur}))
return 0
;;
-C|--compound)
COMPREPLY=() # TODO: finish this one? how?
return 0
;;
-t|--timeout)
COMPREPLY=($( compgen -W "1 2 3 4 5 6 7 8 9 10 15 20 30 40 60 90 120 180" -- ${cur}))
return 0
;;
-b|--batch|--batch-size)
COMPREPLY=($(compgen -W "1 2 3 4 5 6 7 8 9 10 15 20 30 40 50 60 70 80 90 100 120 150 200"))
return 0
;;
-N|--nodegroup)
MASTER_CONFIG='/etc/salt/master'
COMPREPLY=($(compgen -W "`awk -F ':' 'BEGIN {print_line = 0}; /^nodegroups/ {print_line = 1;getline } print_line && /^ */ {print $1} /^[^ ]/ {print_line = 0}' <${MASTER_CONFIG}`" -- ${cur}))
return 0
;;
esac
_salt_coms="$(salt '*' --timeout 2 --out=txt -- sys.list_functions | sed 's/^.*\[//' | tr -d ",']" )"
all="${opts} ${_salt_coms}"
COMPREPLY=( $(compgen -W "${all}" -- ${cur}) )
_salt_coms="$(salt '*' --timeout 2 --out=txt -- sys.list_functions | sed 's/^.*\[//' | tr -d ",']")"
all="${opts} ${_salt_coms}"
COMPREPLY=($(compgen -W "${all}" -- ${cur}))
return 0
}
complete -F _salt salt
_saltkey(){
local cur prev opts prev pprev
COMPREPLY=()
cur="${COMP_WORDS[COMP_CWORD]}"
prev="${COMP_WORDS[COMP_CWORD-1]}"
opts="-c --config-dir= -h --help --version --versions-report -q --quiet \
-y --yes --gen-keys= --gen-keys-dir= --keysize= --key-logfile= \
-l --list= -L --list-all -a --accept= -A --accept-all \
-r --reject= -R --reject-all -p --print= -P --print-all \
-d --delete= -D --delete-all -f --finger= -F --finger-all \
--out=pprint --out=yaml --out=overstatestage --out=json --out=raw \
--out=highstate --out=key --out=txt --no-color --out-indent= "
if [ ${COMP_CWORD} -gt 2 ]; then
pprev="${COMP_WORDS[COMP_CWORD-2]}"
fi
if [ ${COMP_CWORD} -gt 3 ]; then
ppprev="${COMP_WORDS[COMP_CWORD-3]}"
fi
if [[ "${cur}" == -* ]] ; then
COMPREPLY=($(compgen -W "${opts}" -- ${cur}))
return 0
fi
if [ "${cur}" = "=" ] && [[ "${prev}" == --* ]]; then
cur=""
fi
if [ "${prev}" = "=" ] && [[ "${pprev}" == --* ]]; then
prev="${pprev}"
fi
case "${prev}" in
-a|--accept)
COMPREPLY=($(compgen -W "$(salt-key -l un --no-color; salt-key -l rej --no-color)" -- ${cur}))
return 0
;;
-r|--reject)
COMPREPLY=($(compgen -W "$(salt-key -l acc --no-color)" -- ${cur}))
return 0
;;
-d|--delete)
COMPREPLY=($(compgen -W "$(salt-key -l acc --no-color; salt-key -l un --no-color; salt-key -l rej --no-color)" -- ${cur}))
return 0
;;
-c|--config)
COMPREPLY=($(compgen -f -- ${cur}))
return 0
;;
--keysize)
COMPREPLY=($(compgen -W "2048 3072 4096 5120 6144" -- ${cur}))
return 0
;;
--gen-keys)
return 0
;;
--gen-keys-dir)
COMPREPLY=($(compgen -d -- ${cur}))
return 0
;;
-p|--print)
COMPREPLY=($(compgen -W "$(salt-key -l acc --no-color; salt-key -l un --no-color; salt-key -l rej --no-color)" -- ${cur}))
return 0
;;
-l|--list)
COMPREPLY=($(compgen -W "pre un acc accepted unaccepted rej rejected all" -- ${cur}))
return 0
;;
--accept-all)
return 0
;;
esac
COMPREPLY=($(compgen -W "${opts} " -- ${cur}))
_saltkey() {
local cur prev opts prev pprev
COMPREPLY=()
cur="${COMP_WORDS[COMP_CWORD]}"
prev="${COMP_WORDS[COMP_CWORD - 1]}"
opts="-c --config-dir= -h --help --version --versions-report -q --quiet \
-y --yes --gen-keys= --gen-keys-dir= --keysize= --key-logfile= \
-l --list= -L --list-all -a --accept= -A --accept-all \
-r --reject= -R --reject-all -p --print= -P --print-all \
-d --delete= -D --delete-all -f --finger= -F --finger-all \
--out=pprint --out=yaml --out=overstatestage --out=json --out=raw \
--out=highstate --out=key --out=txt --no-color --out-indent= "
if [ ${COMP_CWORD} -gt 2 ]; then
pprev="${COMP_WORDS[COMP_CWORD - 2]}"
fi
if [ ${COMP_CWORD} -gt 3 ]; then
ppprev="${COMP_WORDS[COMP_CWORD - 3]}"
fi
if [[ "${cur}" == -* ]]; then
COMPREPLY=($(compgen -W "${opts}" -- ${cur}))
return 0
fi
if [ "${cur}" = "=" ] && [[ "${prev}" == --* ]]; then
cur=""
fi
if [ "${prev}" = "=" ] && [[ "${pprev}" == --* ]]; then
prev="${pprev}"
fi
case "${prev}" in
-a | --accept)
COMPREPLY=($(compgen -W "$(
salt-key -l un --no-color
salt-key -l rej --no-color
)" -- ${cur}))
return 0
;;
-r | --reject)
COMPREPLY=($(compgen -W "$(salt-key -l acc --no-color)" -- ${cur}))
return 0
;;
-d | --delete)
COMPREPLY=($(compgen -W "$(
salt-key -l acc --no-color
salt-key -l un --no-color
salt-key -l rej --no-color
)" -- ${cur}))
return 0
;;
-c | --config)
COMPREPLY=($(compgen -f -- ${cur}))
return 0
;;
--keysize)
COMPREPLY=($(compgen -W "2048 3072 4096 5120 6144" -- ${cur}))
return 0
;;
--gen-keys)
return 0
;;
--gen-keys-dir)
COMPREPLY=($(compgen -d -- ${cur}))
return 0
;;
-p | --print)
COMPREPLY=($(compgen -W "$(
salt-key -l acc --no-color
salt-key -l un --no-color
salt-key -l rej --no-color
)" -- ${cur}))
return 0
;;
-l | --list)
COMPREPLY=($(compgen -W "pre un acc accepted unaccepted rej rejected all" -- ${cur}))
return 0
;;
--accept-all)
return 0
;;
esac
COMPREPLY=($(compgen -W "${opts} " -- ${cur}))
return 0
}
complete -F _saltkey salt-key
_saltcall(){
local cur prev opts _salt_coms pprev ppprev
COMPREPLY=()
cur="${COMP_WORDS[COMP_CWORD]}"
prev="${COMP_WORDS[COMP_CWORD-1]}"
opts="-h --help -d --doc --documentation --version --versions-report \
_saltcall() {
local cur prev opts _salt_coms pprev ppprev
COMPREPLY=()
cur="${COMP_WORDS[COMP_CWORD]}"
prev="${COMP_WORDS[COMP_CWORD - 1]}"
opts="-h --help -d --doc --documentation --version --versions-report \
-m --module-dirs= -g --grains --return= --local -c --config-dir= -l --log-level= \
--out=pprint --out=yaml --out=overstatestage --out=json --out=raw \
--out=highstate --out=key --out=txt --no-color --out-indent= "
if [ ${COMP_CWORD} -gt 2 ]; then
pprev="${COMP_WORDS[COMP_CWORD-2]}"
fi
if [ ${COMP_CWORD} -gt 3 ]; then
ppprev="${COMP_WORDS[COMP_CWORD-3]}"
fi
if [[ "${cur}" == -* ]] ; then
COMPREPLY=($(compgen -W "${opts}" -- ${cur}))
return 0
fi
if [ "${cur}" = "=" ] && [[ ${prev} == --* ]]; then
cur=""
fi
if [ "${prev}" = "=" ] && [[ ${pprev} == --* ]]; then
prev="${pprev}"
fi
case ${prev} in
-m|--module-dirs)
COMPREPLY=( $(compgen -d ${cur} ))
return 0
;;
-l|--log-level)
COMPREPLY=( $(compgen -W "info none garbage trace warning error debug" -- ${cur}))
return 0
;;
-g|grains)
return 0
;;
salt-call)
COMPREPLY=($(compgen -W "${opts}" -- ${cur}))
return 0
;;
esac
_salt_coms="$(salt-call --out=txt -- sys.list_functions|sed 's/^.*\[//' | tr -d ",']" )"
COMPREPLY=( $(compgen -W "${opts} ${_salt_coms}" -- ${cur} ))
if [ ${COMP_CWORD} -gt 2 ]; then
pprev="${COMP_WORDS[COMP_CWORD - 2]}"
fi
if [ ${COMP_CWORD} -gt 3 ]; then
ppprev="${COMP_WORDS[COMP_CWORD - 3]}"
fi
if [[ "${cur}" == -* ]]; then
COMPREPLY=($(compgen -W "${opts}" -- ${cur}))
return 0
fi
if [ "${cur}" = "=" ] && [[ ${prev} == --* ]]; then
cur=""
fi
if [ "${prev}" = "=" ] && [[ ${pprev} == --* ]]; then
prev="${pprev}"
fi
case ${prev} in
-m | --module-dirs)
COMPREPLY=($(compgen -d ${cur}))
return 0
;;
-l | --log-level)
COMPREPLY=($(compgen -W "info none garbage trace warning error debug" -- ${cur}))
return 0
;;
-g | grains)
return 0
;;
salt-call)
COMPREPLY=($(compgen -W "${opts}" -- ${cur}))
return 0
;;
esac
_salt_coms="$(salt-call --out=txt -- sys.list_functions | sed 's/^.*\[//' | tr -d ",']")"
COMPREPLY=($(compgen -W "${opts} ${_salt_coms}" -- ${cur}))
return 0
}
complete -F _saltcall salt-call
_saltcp() {
local cur prev opts target prefpart postpart helper filt pprev ppprev
COMPREPLY=()
cur="${COMP_WORDS[COMP_CWORD]}"
prev="${COMP_WORDS[COMP_CWORD - 1]}"
opts="-t --timeout= -s --static -b --batch= --batch-size= \
-h --help --version --versions-report -c --config-dir= \
-E --pcre -L --list -G --grain --grain-pcre -N --nodegroup \
-R --range -C --compound -I --pillar \
--out=pprint --out=yaml --out=overstatestage --out=json --out=raw \
--out=highstate --out=key --out=txt --no-color --out-indent= "
if [[ "${cur}" == -* ]]; then
COMPREPLY=($(compgen -W "${opts}" -- ${cur}))
return 0
fi
_saltcp(){
local cur prev opts target prefpart postpart helper filt pprev ppprev
COMPREPLY=()
cur="${COMP_WORDS[COMP_CWORD]}"
prev="${COMP_WORDS[COMP_CWORD-1]}"
opts="-t --timeout= -s --static -b --batch= --batch-size= \
-h --help --version --versions-report -c --config-dir= \
-E --pcre -L --list -G --grain --grain-pcre -N --nodegroup \
-R --range -C --compound -I --pillar \
--out=pprint --out=yaml --out=overstatestage --out=json --out=raw \
--out=highstate --out=key --out=txt --no-color --out-indent= "
if [[ "${cur}" == -* ]] ; then
COMPREPLY=($(compgen -W "${opts}" -- ${cur}))
return 0
fi
if [ "${cur}" = "=" ] && [[ "${prev}" == --* ]]; then
cur=""
fi
if [ "${prev}" = "=" ] && [[ "${pprev}" == --* ]]; then
prev=${pprev}
fi
if [ "${cur}" = "=" ] && [[ "${prev}" == --* ]]; then
cur=""
fi
if [ "${prev}" = "=" ] && [[ "${pprev}" == --* ]]; then
prev=${pprev}
fi
case ${prev} in
salt-cp)
COMPREPLY=($(compgen -W "${opts} $(salt-key -l acc --no-color)" -- ${cur}))
return 0
;;
-t | --timeout)
# those numbers are just a hint
COMPREPLY=($(compgen -W "2 3 4 8 10 15 20 25 30 40 60 90 120 180 240 300" -- ${cur}))
return 0
;;
-E | --pcre)
COMPREPLY=($(compgen -W "$(salt-key -l acc --no-color)" -- ${cur}))
return 0
;;
-L | --list)
# IMPROVEMENTS ARE WELCOME
prefpart="${cur%,*},"
postpart=${cur##*,}
filt="^\($(echo ${cur} | sed 's:,:\\|:g')\)$"
helper=($(salt-key -l acc --no-color | grep -v "${filt}" | sed "s/^/${prefpart}/"))
COMPREPLY=($(compgen -W "${helper[*]}" -- ${cur}))
case ${prev} in
salt-cp)
COMPREPLY=($(compgen -W "${opts} `salt-key -l acc --no-color`" -- ${cur}))
return 0
;;
-t|--timeout)
# those numbers are just a hint
COMPREPLY=($(compgen -W "2 3 4 8 10 15 20 25 30 40 60 90 120 180 240 300" -- ${cur} ))
return 0
;;
-E|--pcre)
COMPREPLY=($(compgen -W "`salt-key -l acc --no-color`" -- ${cur}))
return 0
;;
-L|--list)
# IMPROVEMENTS ARE WELCOME
prefpart="${cur%,*},"
postpart=${cur##*,}
filt="^\($(echo ${cur}| sed 's:,:\\|:g')\)$"
helper=($(salt-key -l acc --no-color | grep -v "${filt}" | sed "s/^/${prefpart}/"))
COMPREPLY=($(compgen -W "${helper[*]}" -- ${cur}))
return 0
;;
-G | --grain | --grain-pcre)
COMPREPLY=($(compgen -W "$(_salt_get_grains)" -- ${cur}))
return 0
;;
# FIXME
-R | --range)
# FIXME ??
return 0
;;
-C | --compound)
# FIXME ??
return 0
;;
-c | --config)
COMPREPLY=($(compgen -f -- ${cur}))
return 0
;;
esac
return 0
;;
-G|--grain|--grain-pcre)
COMPREPLY=($(compgen -W "$(_salt_get_grains)" -- ${cur}))
return 0
;;
# FIXME
-R|--range)
# FIXME ??
return 0
;;
-C|--compound)
# FIXME ??
return 0
;;
-c|--config)
COMPREPLY=($(compgen -f -- ${cur}))
return 0
;;
esac
# default is using opts:
COMPREPLY=( $(compgen -W "${opts}" -- ${cur}) )
# default is using opts:
COMPREPLY=($(compgen -W "${opts}" -- ${cur}))
}
complete -F _saltcp salt-cp

View File

@ -4,37 +4,36 @@
export COMP_WORDBREAKS=${COMP_WORDBREAKS/\:/}
_sshcomplete() {
local CURRENT_PROMPT="${COMP_WORDS[COMP_CWORD]}"
if [[ ${CURRENT_PROMPT} == *@* ]] ; then
local OPTIONS="-P ${CURRENT_PROMPT/@*/}@ -- ${CURRENT_PROMPT/*@/}"
else
local OPTIONS=" -- ${CURRENT_PROMPT}"
local CURRENT_PROMPT="${COMP_WORDS[COMP_CWORD]}"
if [[ ${CURRENT_PROMPT} == *@* ]]; then
local OPTIONS="-P ${CURRENT_PROMPT/@*/}@ -- ${CURRENT_PROMPT/*@/}"
else
local OPTIONS=" -- ${CURRENT_PROMPT}"
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 -Ee "s|^([^/~])|$HOME/.ssh/\1|" -e "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 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 -Ee "s|^([^/~])|$HOME/.ssh/\1|" -e "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
if grep -v -q -e '^ ssh-rsa' "$HOME/.ssh/known_hosts" ; then
COMPREPLY=( ${COMPREPLY[@]} $(compgen -W "$( awk '{print $1}' "$HOME/.ssh/known_hosts" | grep -v ^\| | cut -d, -f 1 | sed -e 's/\[//g' | sed -e 's/\]//g' | cut -d: -f1 | grep -v ssh-rsa)" ${OPTIONS}) )
fi
# parse all hosts found in .ssh/known_hosts
if [ -r "$HOME/.ssh/known_hosts" ]; then
if grep -v -q -e '^ ssh-rsa' "$HOME/.ssh/known_hosts"; then
COMPREPLY=(${COMPREPLY[@]} $(compgen -W "$(awk '{print $1}' "$HOME/.ssh/known_hosts" | grep -v ^\| | cut -d, -f 1 | sed -e 's/\[//g' | sed -e 's/\]//g' | cut -d: -f1 | grep -v ssh-rsa)" ${OPTIONS}))
fi
fi
# parse hosts defined in /etc/hosts
if [ -r /etc/hosts ]; then
COMPREPLY=( ${COMPREPLY[@]} $(compgen -W "$( grep -v '^[[:space:]]*$' /etc/hosts | grep -v '^#' | awk '{for (i=2; i<=NF; i++) print $i}' )" ${OPTIONS}) )
fi
# parse hosts defined in /etc/hosts
if [ -r /etc/hosts ]; then
COMPREPLY=(${COMPREPLY[@]} $(compgen -W "$(grep -v '^[[:space:]]*$' /etc/hosts | grep -v '^#' | awk '{for (i=2; i<=NF; i++) print $i}')" ${OPTIONS}))
fi
return 0
return 0
}
complete -o default -o nospace -F _sshcomplete ssh scp slogin
complete -o default -o nospace -F _sshcomplete ssh scp slogin sftp

View File

@ -1,28 +1,25 @@
#!/usr/bin/env bash
# Loads the system's Bash completion modules.
# If Homebrew is installed (OS X), its Bash completion modules are loaded.
# If Homebrew is installed (OS X), it's Bash completion modules are loaded.
if [ -f /etc/bash_completion ]; then
. /etc/bash_completion
fi
if [[ -r /etc/bash_completion ]] ; then
# shellcheck disable=SC1091
source /etc/bash_completion
# Some distribution makes use of a profile.d script to import completion.
if [ -f /etc/profile.d/bash_completion.sh ]; then
. /etc/profile.d/bash_completion.sh
elif [[ -r /etc/profile.d/bash_completion.sh ]] ; then
# shellcheck disable=SC1091
source /etc/profile.d/bash_completion.sh
fi
if [[ "$(uname -s)" == 'Darwin' ]] && _command_exists brew ; then
BREW_PREFIX=${BREW_PREFIX:-$(brew --prefix)}
if [ $(uname) = "Darwin" ] && command -v brew &>/dev/null ; then
BREW_PREFIX=$(brew --prefix)
if [ -f "$BREW_PREFIX"/etc/bash_completion ]; then
. "$BREW_PREFIX"/etc/bash_completion
fi
# 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
export BASH_COMPLETION_COMPAT_DIR="$BREW_PREFIX"/etc/bash_completion.d
. "$BREW_PREFIX"/share/bash-completion/bash_completion
# homebrew/versions/bash-completion2 (required for projects.completion.bash) is installed to this path
if [[ -r "$BREW_PREFIX"/etc/profile.d/bash_completion.sh ]] ; then
# shellcheck disable=SC1090
source "$BREW_PREFIX"/etc/profile.d/bash_completion.sh
fi
fi

View File

@ -1,65 +1,10 @@
#!/usr/bin/env bash
#
# 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=""
# Make sure terraform is installed
_command_exists terraform || return
if [[ ${cword} -eq 1 ]] ; then
# Don't handle completion if it's already managed
complete -p terraform &>/dev/null && return
# Options that do not start with a hyphen, are always starting with four spaces.
opts="$(terraform --help | grep -E '^\s\s\s\s\S' | awk '{print $1}')"
opts="${opts} --help --version"
elif [[ ${cword} -gt 1 ]] ; then
if [[ ${cword} -eq 2 && ${prev} == '--help' ]] ; then
opts="$(terraform --help | grep -E '^\s\s\s\s\S' | awk '{print $1}')"
elif [[ ${words[1]} != "--help" && ${words[1]} != "--version" && ${words[1]} != "version" ]] ; then
# Some commands accept hyphened parameters, ...
opts="$(terraform --help "${words[1]}" | grep -E '^\s+-' | awk '{print $1}' | awk -F '=' '{ if ($0 ~ /=/) {print $1"="} else {print $1} }')"
# but some other commands accept non-hyphened parameters.
opts="${opts} $(terraform --help "${words[1]}" | grep -E '^\s\s\s\s\S' | awk '{print $1}')"
# All of the commands accept the --help parameter which is not listed
# by the 'terraform --help <command>
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
# Terraform completes itself
complete -C terraform terraform

View File

@ -1,222 +1,221 @@
#!/usr/bin/bash
_vboxmanage_realopts() {
echo $(vboxmanage|grep -i vboxmanage|cut -d' ' -f2|grep '\['|tr -s '[\[\|\]\n' ' ')
echo " "
echo $(vboxmanage | grep -i vboxmanage | cut -d' ' -f2 | grep '\[' | tr -s '[\[\|\]\n' ' ')
echo " "
}
__vboxmanage_startvm() {
RUNNING=$(vboxmanage list runningvms | cut -d' ' -f1 | tr -d '"')
TOTAL=$(vboxmanage list vms | cut -d' ' -f1 | tr -d '"')
RUNNING=$(vboxmanage list runningvms | cut -d' ' -f1 | tr -d '"')
TOTAL=$(vboxmanage list vms | cut -d' ' -f1 | tr -d '"')
AVAILABLE=""
for VM in $TOTAL; do
MATCH=0;
for RUN in $RUNNING "x"; do
if [ "$VM" == "$RUN" ]; then
MATCH=1
fi
done
(( $MATCH == 0 )) && AVAILABLE="$AVAILABLE $VM "
AVAILABLE=""
for VM in $TOTAL; do
MATCH=0
for RUN in $RUNNING "x"; do
if [ "$VM" == "$RUN" ]; then
MATCH=1
fi
done
echo $AVAILABLE
(($MATCH == 0)) && AVAILABLE="$AVAILABLE $VM "
done
echo $AVAILABLE
}
__vboxmanage_list() {
INPUT=$(vboxmanage list | tr -s '[\[\]\|\n]' ' ' | cut -d' ' -f4-)
INPUT=$(vboxmanage list | tr -s '[\[\]\|\n]' ' ' | cut -d' ' -f4-)
PRUNED=""
if [ "$1" == "long" ]; then
for WORD in $INPUT; do
[ "$WORD" == "-l" ] && continue;
[ "$WORD" == "--long" ] && continue;
PRUNED=""
if [ "$1" == "long" ]; then
for WORD in $INPUT; do
[ "$WORD" == "-l" ] && continue
[ "$WORD" == "--long" ] && continue
PRUNED="$PRUNED $WORD"
done
else
PRUNED=$INPUT
fi
PRUNED="$PRUNED $WORD"
done
else
PRUNED=$INPUT
fi
echo $PRUNED
echo $PRUNED
}
__vboxmanage_list_vms() {
VMS=""
if [ "x$1" == "x" ]; then
SEPARATOR=" "
else
SEPARATOR=$1
fi
VMS=""
if [ "x$1" == "x" ]; then
SEPARATOR=" "
else
SEPARATOR=$1
fi
for VM in $(vboxmanage list vms | cut -d' ' -f1 | tr -d '"'); do
[ "$VMS" != "" ] && VMS="${VMS}${SEPARATOR}"
VMS="${VMS}${VM}"
done
for VM in $(vboxmanage list vms | cut -d' ' -f1 | tr -d '"'); do
[ "$VMS" != "" ] && VMS="${VMS}${SEPARATOR}"
VMS="${VMS}${VM}"
done
echo $VMS
echo $VMS
}
__vboxmanage_list_runningvms() {
VMS=""
if [ "$1" == "" ]; then
SEPARATOR=" "
else
SEPARATOR=$1
fi
VMS=""
if [ "$1" == "" ]; then
SEPARATOR=" "
else
SEPARATOR=$1
fi
for VM in $(vboxmanage list runningvms | cut -d' ' -f1 | tr -d '"'); do
[ "$VMS" != "" ] && VMS="${VMS}${SEPARATOR}"
VMS="${VMS}${VM}"
done
for VM in $(vboxmanage list runningvms | cut -d' ' -f1 | tr -d '"'); do
[ "$VMS" != "" ] && VMS="${VMS}${SEPARATOR}"
VMS="${VMS}${VM}"
done
echo $VMS
echo $VMS
}
__vboxmanage_controlvm() {
echo "pause resume reset poweroff savestate acpipowerbutton"
echo "acpisleepbutton keyboardputscancode guestmemoryballoon"
echo "gueststatisticsinterval usbattach usbdetach vrde vrdeport"
echo "vrdeproperty vrdevideochannelquality setvideomodehint"
echo "screenshotpng setcredentials teleport plugcpu unplugcpu"
echo "cpuexecutioncap"
echo "pause resume reset poweroff savestate acpipowerbutton"
echo "acpisleepbutton keyboardputscancode guestmemoryballoon"
echo "gueststatisticsinterval usbattach usbdetach vrde vrdeport"
echo "vrdeproperty vrdevideochannelquality setvideomodehint"
echo "screenshotpng setcredentials teleport plugcpu unplugcpu"
echo "cpuexecutioncap"
# setlinkstate<1-N>
# nic<1-N> null|nat|bridged|intnet|hostonly|generic
# [<devicename>] |
# nictrace<1-N> on|off
# nictracefile<1-N> <filename>
# nicproperty<1-N> name=[value]
# natpf<1-N> [<rulename>],tcp|udp,[<hostip>],
# <hostport>,[<guestip>],<guestport>
# natpf<1-N> delete <rulename>
# setlinkstate<1-N>
# nic<1-N> null|nat|bridged|intnet|hostonly|generic
# [<devicename>] |
# nictrace<1-N> on|off
# nictracefile<1-N> <filename>
# nicproperty<1-N> name=[value]
# natpf<1-N> [<rulename>],tcp|udp,[<hostip>],
# <hostport>,[<guestip>],<guestport>
# natpf<1-N> delete <rulename>
}
__vboxmanage_default() {
realopts=$(_vboxmanage_realopts)
opts=$realopts$(vboxmanage | grep -i vboxmanage | cut -d' ' -f2 | grep -v '\[' | sort | uniq)
pruned=""
realopts=$(_vboxmanage_realopts)
opts=$realopts$(vboxmanage | grep -i vboxmanage | cut -d' ' -f2 | grep -v '\[' | sort | uniq)
pruned=""
# echo ""
# echo "DEBUG: cur: $cur, prev: $prev"
# echo "DEBUG: default: |$p1|$p2|$p3|$p4|"
case ${cur} in
-*)
echo $opts
# COMPREPLY=($(compgen -W "${opts}" -- ${cur}))
return 0
;;
esac;
for WORD in $opts; do
MATCH=0
for OPT in "${COMP_WORDS[@]}"; do
# opts=$(echo ${opts} | grep -v $OPT);
if [ "$OPT" == "$WORD" ]; then
MATCH=1
break;
fi
if [ "$OPT" == "-v" ] && [ "$WORD" == "--version" ]; then
MATCH=1
break;
fi
if [ "$OPT" == "--version" ] && [ "$WORD" == "-v" ]; then
MATCH=1
break;
fi
if [ "$OPT" == "-q" ] && [ "$WORD" == "--nologo" ]; then
MATCH=1
break;
fi
if [ "$OPT" == "--nologo" ] && [ "$WORD" == "-q" ]; then
MATCH=1
break;
fi
done
(( $MATCH == 1 )) && continue;
pruned="$pruned $WORD"
# echo ""
# echo "DEBUG: cur: $cur, prev: $prev"
# echo "DEBUG: default: |$p1|$p2|$p3|$p4|"
case ${cur} in
-*)
echo $opts
# COMPREPLY=($(compgen -W "${opts}" -- ${cur}))
return 0
;;
esac
for WORD in $opts; do
MATCH=0
for OPT in "${COMP_WORDS[@]}"; do
# opts=$(echo ${opts} | grep -v $OPT);
if [ "$OPT" == "$WORD" ]; then
MATCH=1
break
fi
if [ "$OPT" == "-v" ] && [ "$WORD" == "--version" ]; then
MATCH=1
break
fi
if [ "$OPT" == "--version" ] && [ "$WORD" == "-v" ]; then
MATCH=1
break
fi
if [ "$OPT" == "-q" ] && [ "$WORD" == "--nologo" ]; then
MATCH=1
break
fi
if [ "$OPT" == "--nologo" ] && [ "$WORD" == "-q" ]; then
MATCH=1
break
fi
done
(($MATCH == 1)) && continue
pruned="$pruned $WORD"
# COMPREPLY=($(compgen -W "${pruned}" -- ${cur}))
echo $pruned
return 0
done
# COMPREPLY=($(compgen -W "${pruned}" -- ${cur}))
echo $pruned
return 0
}
_vboxmanage() {
# vboxmanage | grep -i vboxmanage | cut -d' ' -f2 | sort | uniq
local cur p1 p2 p3 p4 opts
COMPREPLY=()
cur="${COMP_WORDS[COMP_CWORD]}"
prev="${COMP_WORDS[COMP_CWORD-1]}"
# vboxmanage | grep -i vboxmanage | cut -d' ' -f2 | sort | uniq
local cur p1 p2 p3 p4 opts
COMPREPLY=()
cur="${COMP_WORDS[COMP_CWORD]}"
prev="${COMP_WORDS[COMP_CWORD - 1]}"
# echo "cur: |$cur|"
# echo "prev: |$prev|"
# echo "cur: |$cur|"
# echo "prev: |$prev|"
# In case current is complete command
case $cur in
startvm|list|controlvm)
COMPREPLY=($(compgen -W "$cur "))
return 0
;;
esac
# In case current is complete command
case $cur in
startvm | list | controlvm)
COMPREPLY=($(compgen -W "$cur "))
return 0
;;
esac
case $prev in
-v|--version)
return 0
;;
case $prev in
-v | --version)
return 0
;;
-l|--long)
opts=$(__vboxmanage_list "long")
COMPREPLY=($(compgen -W "${opts}" -- ${cur}))
return 0
;;
startvm|list)
opts=$(__vboxmanage_$prev)
COMPREPLY=($(compgen -W "${opts}" -- ${cur}))
return 0
;;
--type)
COMPREPLY=($(compgen -W "gui headless" -- ${cur}))
return 0
;;
gui|headless)
# Done. no more completion possible
return 0
;;
vboxmanage|-q|--nologo)
# echo "Got vboxmanage"
opts=$(__vboxmanage_default)
COMPREPLY=($(compgen -W "${opts}" -- ${cur}))
return 0
;;
controlvm)
opts=$(__vboxmanage_list_vms)
COMPREPLY=($(compgen -W "${opts}" -- ${cur}))
return 0
;;
esac
-l | --long)
opts=$(__vboxmanage_list "long")
COMPREPLY=($(compgen -W "${opts}" -- ${cur}))
return 0
;;
startvm | list)
opts=$(__vboxmanage_$prev)
COMPREPLY=($(compgen -W "${opts}" -- ${cur}))
return 0
;;
--type)
COMPREPLY=($(compgen -W "gui headless" -- ${cur}))
return 0
;;
gui | headless)
# Done. no more completion possible
return 0
;;
vboxmanage | -q | --nologo)
# echo "Got vboxmanage"
opts=$(__vboxmanage_default)
COMPREPLY=($(compgen -W "${opts}" -- ${cur}))
return 0
;;
controlvm)
opts=$(__vboxmanage_list_vms)
COMPREPLY=($(compgen -W "${opts}" -- ${cur}))
return 0
;;
esac
for VM in $(__vboxmanage_list_vms); do
if [ "$VM" == "$prev" ]; then
pprev=${COMP_WORDS[COMP_CWORD-2]}
# echo "previous: $pprev"
case $pprev in
startvm)
opts="--type"
COMPREPLY=($(compgen -W "${opts}" -- ${cur}))
return 0
;;
controlvm)
opts=$(__vboxmanage_controlvm)
COMPREPLY=($(compgen -W "${opts}" -- ${cur}))
return 0;
;;
esac
fi
done
for VM in $(__vboxmanage_list_vms); do
if [ "$VM" == "$prev" ]; then
pprev=${COMP_WORDS[COMP_CWORD - 2]}
# echo "previous: $pprev"
case $pprev in
startvm)
opts="--type"
COMPREPLY=($(compgen -W "${opts}" -- ${cur}))
return 0
;;
controlvm)
opts=$(__vboxmanage_controlvm)
COMPREPLY=($(compgen -W "${opts}" -- ${cur}))
return 0
;;
esac
fi
done
# echo "Got to end withoug completion"
# echo "Got to end withoug completion"
}
complete -F _vboxmanage vboxmanage

View File

@ -19,9 +19,11 @@ function _command_exists ()
{
_about 'checks for existence of a command'
_param '1: command to check'
_param '2: (optional) log message to include when command not found'
_example '$ _command_exists ls && echo exists'
_group 'lib'
type "$1" &> /dev/null ;
local msg="${2:-Command '$1' does not exist!}"
type "$1" &> /dev/null || (_log_warning "$msg" && return 1) ;
}
function _make_reload_alias() {
@ -43,7 +45,7 @@ alias reload_plugins="$(_make_reload_alias plugin plugins)"
bash-it ()
{
about 'Bash-it help and maintenance'
param '1: verb [one of: help | show | enable | disable | migrate | update | search | version | reload ] '
param '1: verb [one of: help | show | enable | disable | migrate | update | search | version | reload | restart | doctor ] '
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'
@ -55,6 +57,8 @@ bash-it ()
example '$ bash-it search [-|@]term1 [-|@]term2 ... [ -e/--enable ] [ -d/--disable ] [ -r/--refresh ] [ -c/--no-color ]'
example '$ bash-it version'
example '$ bash-it reload'
example '$ bash-it restart'
example '$ bash-it doctor errors|warnings|all'
typeset verb=${1:-}
shift
typeset component=${1:-}
@ -70,15 +74,19 @@ bash-it ()
func=_disable-$component;;
help)
func=_help-$component;;
doctor)
func=_bash-it-doctor-$component;;
search)
_bash-it-search $component "$@"
return;;
update)
func=_bash-it_update;;
func=_bash-it_update-$component;;
migrate)
func=_bash-it-migrate;;
version)
func=_bash-it-version;;
restart)
func=_bash-it-restart;;
reload)
func=_bash-it-reload;;
*)
@ -109,6 +117,10 @@ bash-it ()
do
$func $arg
done
if [ -n "$BASH_IT_AUTOMATIC_RELOAD_AFTER_CONFIG_CHANGE" ]; then
_bash-it-reload
fi
else
$func "$@"
fi
@ -146,60 +158,127 @@ _bash-it-plugins ()
_bash-it-describe "plugins" "a" "plugin" "Plugin"
}
_bash-it_update() {
_about 'updates Bash-it'
_bash-it_update-dev() {
_about 'updates Bash-it to the latest master'
_group 'lib'
_bash-it_update- dev "$@"
}
_bash-it_update-stable() {
_about 'updates Bash-it to the latest tag'
_group 'lib'
_bash-it_update- stable "$@"
}
_bash-it_pull_and_update_inner() {
git checkout "$1" &> /dev/null
if [[ $? -eq 0 ]]; then
echo "Bash-it successfully updated."
echo ""
echo "Migrating your installation to the latest $2 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
}
_bash-it_update-() {
_about 'updates Bash-it'
_param '1: What kind of update to do (stable|dev)'
_group 'lib'
declare silent
for word in $@; do
if [[ ${word} == "--silent" || ${word} == "-s" ]]; then
silent=true
fi
done
local old_pwd="${PWD}"
cd "${BASH_IT}" || return
if [ -z $BASH_IT_REMOTE ]; then
if [ -z "$BASH_IT_REMOTE" ]; then
BASH_IT_REMOTE="origin"
fi
git fetch &> /dev/null
git fetch $BASH_IT_REMOTE --tags &> /dev/null
if [ -z "$BASH_IT_DEVELOPMENT_BRANCH" ]; then
BASH_IT_DEVELOPMENT_BRANCH="master"
fi
# Defaults to stable update
if [ -z "$1" ] || [ "$1" == "stable" ]; then
version="stable"
TARGET=$(git describe --tags "$(git rev-list --tags --max-count=1)" 2> /dev/null)
if [[ -z "$TARGET" ]]; then
echo "Can not find tags, so can not update to latest stable version..."
return
fi
else
version="dev"
TARGET=${BASH_IT_REMOTE}/${BASH_IT_DEVELOPMENT_BRANCH}
fi
declare revision
revision="HEAD..${TARGET}"
declare status
status="$(git rev-list master..${BASH_IT_REMOTE}/master 2> /dev/null)"
status="$(git rev-list ${revision} 2> /dev/null)"
declare revert
if [[ -z "${status}" && ${version} == "stable" ]]; then
revision="${TARGET}..HEAD"
status="$(git rev-list ${revision} 2> /dev/null)"
revert=true
fi
if [[ -n "${status}" ]]; then
if [[ $revert ]]; then
echo "Your version is a more recent development version ($(git log -1 --format=%h HEAD))"
echo "You can continue in order to revert and update to the latest stable version"
echo ""
log_color="%Cred"
fi
for i in $(git rev-list --merges --first-parent master..${BASH_IT_REMOTE}); do
for i in $(git rev-list --merges --first-parent ${revision}); 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
git log --format="${log_color}%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
if [[ $silent ]]; then
echo "Updating to ${TARGET}($(git log -1 --format=%h "${TARGET}"))..."
_bash-it_pull_and_update_inner $TARGET $version
else
read -e -n 1 -p "Would you like to update to ${TARGET}($(git log -1 --format=%h "${TARGET}"))? [Y/n] " RESP
case $RESP in
[yY]|"")
_bash-it_pull_and_update_inner $TARGET $version
;;
[nN])
echo "Not updating…"
;;
*)
echo -e "\033[91mPlease choose y or n.\033[m"
;;
esac
fi
else
echo "Bash-it is up to date, nothing to do!"
if [[ ${version} == "stable" ]]; then
echo "You're on the latest stable version. If you want to check out the latest 'dev' version, please run \"bash-it update dev\""
else
echo "Bash-it is up to date, nothing to do!"
fi
fi
cd "${old_pwd}" &> /dev/null || return
}
@ -234,6 +313,10 @@ _bash-it-migrate() {
done
done
if [ -n "$BASH_IT_AUTOMATIC_RELOAD_AFTER_CONFIG_CHANGE" ]; then
_bash-it-reload
fi
if [ "$migrated_something" = "true" ]; then
echo ""
echo "If any migration errors were reported, please try the following: reload && bash-it migrate"
@ -263,6 +346,61 @@ _bash-it-version() {
cd - &> /dev/null || return
}
_bash-it-doctor() {
_about 'reloads a profile file with a BASH_IT_LOG_LEVEL set'
_param '1: BASH_IT_LOG_LEVEL argument: "errors" "warnings" "all"'
_group 'lib'
BASH_IT_LOG_LEVEL=$1
_bash-it-reload
unset BASH_IT_LOG_LEVEL
}
_bash-it-doctor-all() {
_about 'reloads a profile file with error, warning and debug logs'
_group 'lib'
_bash-it-doctor $BASH_IT_LOG_LEVEL_ALL
}
_bash-it-doctor-warnings() {
_about 'reloads a profile file with error and warning logs'
_group 'lib'
_bash-it-doctor $BASH_IT_LOG_LEVEL_WARNING
}
_bash-it-doctor-errors() {
_about 'reloads a profile file with error logs'
_group 'lib'
_bash-it-doctor $BASH_IT_LOG_LEVEL_ERROR
}
_bash-it-doctor-() {
_about 'default bash-it doctor behavior, behaves like bash-it doctor all'
_group 'lib'
_bash-it-doctor-all
}
_bash-it-restart() {
_about 'restarts the shell in order to fully reload it'
_group 'lib'
saved_pwd=$(pwd)
case $OSTYPE in
darwin*)
init_file=.bash_profile
;;
*)
init_file=.bashrc
;;
esac
exec "${0/-/}" --rcfile <(echo "source \"$HOME/$init_file\"; cd \"$saved_pwd\"")
}
_bash-it-reload() {
_about 'reloads a profile file'
_group 'lib'
@ -318,6 +456,17 @@ _bash-it-describe ()
printf '%s\n' "$ bash-it disable $file_type <$file_type name> [$file_type name]... -or- $ bash-it disable $file_type all"
}
_on-disable-callback()
{
_about 'Calls the disabled plugin destructor, if present'
_param '1: plugin name'
_example '$ _on-disable-callback gitstatus'
_group 'lib'
callback=$1_on_disable
_command_exists $callback && $callback
}
_disable-plugin ()
{
_about 'disables bash_it plugin'
@ -326,6 +475,7 @@ _disable-plugin ()
_group 'lib'
_disable-thing "plugins" "plugin" $1
_on-disable-callback $1
}
_disable-alias ()
@ -400,10 +550,6 @@ _disable-thing ()
_bash-it-clean-component-cache "${file_type}"
if [ -n "$BASH_IT_AUTOMATIC_RELOAD_AFTER_CONFIG_CHANGE" ]; then
exec ${0/-/}
fi
printf '%s\n' "$file_entity disabled."
}
@ -500,10 +646,6 @@ _enable-thing ()
_bash-it-clean-component-cache "${file_type}"
if [ -n "$BASH_IT_AUTOMATIC_RELOAD_AFTER_CONFIG_CHANGE" ]; then
exec ${0/-/}
fi
printf '%s\n' "$file_entity enabled with priority $use_load_priority."
}

60
lib/log.bash 100644
View File

@ -0,0 +1,60 @@
#!/usr/bin/env bash
export BASH_IT_LOG_LEVEL_ERROR=1
export BASH_IT_LOG_LEVEL_WARNING=2
export BASH_IT_LOG_LEVEL_ALL=3
function _has_colors()
{
# Check that stdout is a terminal
test -t 1 || return 1
ncolors=$(tput colors)
test -n "$ncolors" && test "$ncolors" -ge 8 || return 1
return 0
}
function _log_general()
{
about 'Internal function used for logging, uses BASH_IT_LOG_PREFIX as a prefix'
param '1: color of the message'
param '2: log level to print before the prefix'
param '3: message to log'
group 'log'
message=$2${BASH_IT_LOG_PREFIX}$3
_has_colors && echo -e "$1${message}${echo_normal}" || echo -e "${message}"
}
function _log_debug()
{
about 'log a debug message by echoing to the screen. needs BASH_IT_LOG_LEVEL >= BASH_IT_LOG_LEVEL_ALL'
param '1: message to log'
example '$ _log_debug "Loading plugin git..."'
group 'log'
[[ "$BASH_IT_LOG_LEVEL" -ge $BASH_IT_LOG_LEVEL_ALL ]] || return 0
_log_general "${echo_green}" "DEBUG: " "$1"
}
function _log_warning()
{
about 'log a message by echoing to the screen. needs BASH_IT_LOG_LEVEL >= BASH_IT_LOG_LEVEL_WARNING'
param '1: message to log'
example '$ _log_warning "git binary not found, disabling git plugin..."'
group 'log'
[[ "$BASH_IT_LOG_LEVEL" -ge $BASH_IT_LOG_LEVEL_WARNING ]] || return 0
_log_general "${echo_yellow}" " WARN: " "$1"
}
function _log_error()
{
about 'log a message by echoing to the screen. needs BASH_IT_LOG_LEVEL >= BASH_IT_LOG_LEVEL_ERROR'
param '1: message to log'
example '$ _log_error "Failed to load git plugin..."'
group 'log'
[[ "$BASH_IT_LOG_LEVEL" -ge $BASH_IT_LOG_LEVEL_ERROR ]] || return 0
_log_general "${echo_red}" "ERROR: " "$1"
}

View File

@ -6,6 +6,24 @@
# Generic utilies
###########################################################################
_bash-it-get-component-name-from-path() {
# filename without path
filename=${1##*/}
# filename without path or priority
filename=${filename##*---}
# filename without path, priority or extension
echo ${filename%.*.bash}
}
_bash-it-get-component-type-from-path() {
# filename without path
filename=${1##*/}
# filename without path or priority
filename=${filename##*---}
# extension
echo ${filename} | cut -d '.' -f 2
}
# This function searches an array for an exact match against the term passed
# as the first argument to the function. This function exits as soon as
# a match is found.

View File

@ -71,7 +71,7 @@ function alias_completion {
# with the last word in the unaliased form, i.e.,
# alias_cmd + ' ' + alias_args.
if [[ \$COMP_LINE == \"\$prec_word \$compl_word\" ]]; then
prec_word=\"$alias_cmd $alias_args\"
prec_word='$alias_cmd $alias_args'
prec_word=\${prec_word#* }
fi
(( COMP_CWORD += ${#alias_arg_words[@]} ))

View File

@ -40,7 +40,8 @@ function __awskeys_help {
function __awskeys_get {
local ln=$(grep -n "\[ *$1 *\]" "${AWS_SHARED_CREDENTIALS_FILE}" | cut -d ":" -f 1)
if [[ -n "${ln}" ]]; then
tail -n +${ln} "${AWS_SHARED_CREDENTIALS_FILE}" | egrep -m 3 "aws_access_key_id|aws_secret_access_key|aws_session_token"
tail -n +${ln} "${AWS_SHARED_CREDENTIALS_FILE}" | egrep -m 2 "aws_access_key_id|aws_secret_access_key"
tail -n +${ln} "${AWS_SHARED_CREDENTIALS_FILE}" | egrep -m 1 "aws_session_token"
fi
}

View File

@ -32,7 +32,7 @@ function myip ()
list=("http://myip.dnsomatic.com/" "http://checkip.dyndns.com/" "http://checkip.dyndns.org/")
for url in ${list[*]}
do
res=$(curl -s "${url}")
res=$(curl -fs "${url}")
if [ $? -eq 0 ];then
break;
fi

View File

@ -29,12 +29,28 @@ End-Of-Usage
[ $# -eq 0 ] && extract -h && return 1
while [ $# -gt 0 ]; do
if [ -f "$1" ]; then
case "$1" in
*.tar.bz2|*.tbz|*.tbz2) tar "x${verbose}jf" "$1" ;;
*.tar.gz|*.tgz) tar "x${verbose}zf" "$1" ;;
*.tar.xz) xz --decompress "$1"; set -- "$@" "${1:0:-3}" ;;
*.tar.Z) uncompress "$1"; set -- "$@" "${1:0:-2}" ;;
if [[ ! -f "$1" ]]; then
echo "extract: '$1' is not a valid file" >&2
shift
continue
fi
local -r filename=$(basename -- $1)
local -r filedirname=$(dirname -- $1)
local targetdirname=$(sed 's/\(\.tar\.bz2$\|\.tbz$\|\.tbz2$\|\.tar\.gz$\|\.tgz$\|\.tar$\|\.tar\.xz$\|\.txz$\|\.tar\.Z$\|\.7z$\)//g' <<< $filename)
if [ "$filename" = "$targetdirname" ]; then
# archive type either not supported or it doesn't need dir creation
targetdirname=""
else
mkdir -v "$filedirname/$targetdirname"
fi
if [ -f "$1" ]; then
case "$1" in
*.tar.bz2|*.tbz|*.tbz2) tar "x${verbose}jf" "$1" -C "$filedirname/$targetdirname" ;;
*.tar.gz|*.tgz) tar "x${verbose}zf" "$1" -C "$filedirname/$targetdirname" ;;
*.tar.xz|*.txz) tar "x${verbose}Jf" "$1" -C "$filedirname/$targetdirname" ;;
*.tar.Z) tar "x${verbose}Zf" "$1" -C "$filedirname/$targetdirname" ;;
*.bz2) bunzip2 "$1" ;;
*.deb) dpkg-deb -x${verbose} "$1" "${1:0:-4}" ;;
*.pax.gz) gunzip "$1"; set -- "$@" "${1:0:-3}" ;;
@ -43,17 +59,15 @@ End-Of-Usage
*.pkg) pkgutil --expand "$1" "${1:0:-4}" ;;
*.rar) unrar x "$1" ;;
*.rpm) rpm2cpio "$1" | cpio -idm${verbose} ;;
*.tar) tar "x${verbose}f" "$1" ;;
*.txz) mv "$1" "${1:0:-4}.tar.xz"; set -- "$@" "${1:0:-4}.tar.xz" ;;
*.tar) tar "x${verbose}f" "$1" -C "$filedirname/$targetdirname" ;;
*.xz) xz --decompress "$1" ;;
*.zip|*.war|*.jar) unzip "$1" ;;
*.Z) uncompress "$1" ;;
*.7z) 7za x "$1" ;;
*) echo "'$1' cannot be extracted via extract" >&2;;
esac
else
echo "extract: '$1' is not a valid file" >&2
fi
esac
fi
shift
done
}

View File

@ -0,0 +1,6 @@
cite about-plugin
about-plugin 'load fasd, if you are using it'
_command_exists fasd || return
eval "$(fasd --init auto)"

View File

@ -4,14 +4,16 @@
cite about-plugin
about-plugin 'load fzf, if you are using it'
if [ -f ~/.fzf.bash ]; then
_command_exists fzf || return
if [ -r ~/.fzf.bash ] ; then
source ~/.fzf.bash
elif [ -f "${XDG_CONFIG_HOME:-$HOME/.config}"/fzf/fzf.bash ]; then
elif [ -r "${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'
if [ -z ${FZF_DEFAULT_COMMAND+x} ] && _command_exists fd ; then
export FZF_DEFAULT_COMMAND='fd --type f'
fi
fe() {

View File

@ -1,4 +0,0 @@
cite about-plugin
about-plugin 'load gh, if you are using it (DEPRECATED, use hub instead)'
command -v gh 2> /dev/null && eval "$(gh alias -s)"

View File

@ -162,7 +162,7 @@ function v2gif {
if [[ "$use_gifski" = "true" ]] ; then
# I trust @pornel to do his own resizing optimization choices
$ffmpeg -loglevel panic -i "$file" -r $fps -vcodec png v2gif-tmp-%05d.png && \
$gifski $maxwidthski --fps $(printf "%.0f" $fps) -o "$output_file" v2gif-tmp-*.png || return 2
$gifski v2gif-tmp-*.png $maxwidthski --fps $(printf "%.0f" $fps) -o "$output_file" || return 2
else
$ffmpeg -loglevel panic -i "$file" $maxsize -r $fps -vcodec png v2gif-tmp-%05d.png && \
$convert +dither -layers Optimize v2gif-tmp-*.png GIF:- | \

View File

@ -0,0 +1,26 @@
cite about-plugin
about-plugin 'speeds up your life by using gitstatus for git status calculations. install from https://github.com/romkatv/gitstatus'
function gitstatus_on_disable() {
about 'Destructor of gitstatus plugin'
group 'gitstatus'
unset SCM_GIT_USE_GITSTATUS
_command_exists gitstatus_stop && gitstatus_stop
}
# No scm-check
[[ $SCM_CHECK == "true" ]] || return
# non-interactive shell
[[ $- == *i* ]] || return
: "${SCM_GIT_GITSTATUS_DIR:="$HOME/gitstatus"}"
if [[ -d ${SCM_GIT_GITSTATUS_DIR} ]]; then
source "${SCM_GIT_GITSTATUS_DIR}/gitstatus.plugin.sh"
# Start the actual gitstatus binary
gitstatus_stop && gitstatus_start -s -1 -u -1 -c -1 -d -1
export SCM_GIT_USE_GITSTATUS=true
else
_log_warning "Could not find gitstatus directory in ${SCM_GIT_GITSTATUS_DIR}. Please specify directory location using SCM_GIT_GITSTATUS_DIR."
fi

View File

@ -0,0 +1,20 @@
cite about-plugin
about-plugin 'load goenv, if you are using it'
# Don't modify the environment if we can't find the tool:
# - Check if in $PATH already
# - Check if installed manually to $GOENV_ROOT
# - Check if installed manually to $HOME
_command_exists goenv ||
[[ -n "$GOENV_ROOT" && -x "$GOENV_ROOT/bin/goenv" ]] ||
[[ -x "$HOME/.goenv/bin/goenv" ]] ||
return
# Set GOENV_ROOT, if not already set
export GOENV_ROOT="${GOENV_ROOT:-$HOME/.goenv}"
# Add GOENV_ROOT/bin to PATH, if that's where it's installed
! _command_exists goenv && [[ -x "$GOENV_ROOT/bin/goenv" ]] && pathmunge "$GOENV_ROOT/bin"
# Initialize goenv
eval "$(goenv init - bash)"

View File

@ -1,7 +1,22 @@
cite about-plugin
about-plugin 'load jenv, if you are using it'
export JENV_ROOT="$HOME/.jenv"
pathmunge "$JENV_ROOT/bin"
# Don't modify the environment if we can't find the tool:
# - Check if in $PATH already
# - Check if installed manually to $JENV_ROOT
# - Check if installed manually to $HOME
_command_exists jenv ||
[[ -n "$JENV_ROOT" && -x "$JENV_ROOT/bin/jenv" ]] ||
[[ -x "$HOME/.jenv/bin/jenv" ]] ||
return
if which jenv > /dev/null; then eval "$(jenv init - bash)"; fi
# Set JENV_ROOT, if not already set
export JENV_ROOT="${JENV_ROOT:-$HOME/.jenv}"
# Add JENV_ROOT/bin to PATH, if that's where it's installed
! _command_exists jenv &&
[[ -x "$JENV_ROOT/bin/jenv" ]] &&
pathmunge "$JENV_ROOT/bin"
# Initialize jenv
eval "$(jenv init - bash)"

View File

@ -1,7 +1,13 @@
cite about-plugin
about-plugin 'Node.js helper functions'
# Ensure local modules are preferred in PATH
pathmunge "./node_modules/.bin" "after"
# Make sure the global npm prefix is on the path
[[ `which npm 2>/dev/null` ]] && pathmunge "$(npm config get prefix)/bin" "after"
# Check that we have npm
out=$(command -v npm 2>&1) || return
# If not using nodenv, ensure global modules are in PATH
if [[ ! $out == *"nodenv/shims"* ]] ; then
pathmunge "$(npm config get prefix)/bin" "after"
fi

View File

@ -1,5 +1,5 @@
cite about-plugin
about-plugin 'add "export PROJECT_PATHS=~/projects:~/intertrode/projects" to navigate quickly to your project directories with `pj` and `pjo`'
about-plugin 'quickly navigate configured paths with `pj` and `pjo`. example: "export PROJECT_PATHS=~/projects:~/work/projects"'
function pj {
about 'navigate quickly to your various project directories'

View File

@ -94,7 +94,6 @@ function _ensure_valid_sshagent_env() {
return
fi
echo "There's a dead ssh-agent at the landing..."
ssh-agent > "${SSH_AGENT_ENV}"
return
}

View File

@ -0,0 +1,22 @@
cite about-plugin
about-plugin 'Toggle sudo at the beginning of the current or the previous command by hitting the ESC key twice'
function sudo-command-line() {
about "toggle sudo at the beginning of the current or the previous command by hitting the ESC key twice"
group "sudo"
[[ ${#READLINE_LINE} -eq 0 ]] && READLINE_LINE=$(fc -l -n -1 | xargs)
if [[ $READLINE_LINE == sudo\ * ]]; then
READLINE_LINE="${READLINE_LINE#sudo }"
else
READLINE_LINE="sudo $READLINE_LINE"
fi
READLINE_POINT=${#READLINE_LINE}
}
# Define shortcut keys: [Esc] [Esc]
# Readline library requires bash version 4 or later
if [ "${BASH_VERSINFO}" -ge 4 ]; then
bind -x '"\e\e": sudo-command-line'
fi

View File

@ -1,12 +0,0 @@
cite about-plugin
about-plugin 'Defines the `code` executable for Visual Studio Code on OS X'
# Based on https://code.visualstudio.com/Docs/editor/setup
if [[ `uname -s` == "Darwin" ]]; then
function code () {
about 'Starts Visual Studio Code in the provided directory'
group 'visual-studio-code'
VSCODE_CWD="$PWD" open -n -b "com.microsoft.VSCode" --args $* ;
}
fi

View File

@ -3,7 +3,7 @@ about-plugin 'automatically set your xterm title with host and location info'
_short-dirname () {
local dir_name=`dirs -0`
local dir_name=`dirs +0`
[ "$SHORT_TERM_LINE" = true ] && [ ${#dir_name} -gt 8 ] && echo ${dir_name##*/} || echo $dir_name
}

View File

@ -1,15 +1,26 @@
#!/bin/bash
BASH_IT_LOG_PREFIX="core: reloader: "
pushd "${BASH_IT}" >/dev/null || exit 1
# TODO: Add debugging output
function _set-prefix-based-on-path()
{
filename=$(_bash-it-get-component-name-from-path "$1")
extension=$(_bash-it-get-component-type-from-path "$1")
BASH_IT_LOG_PREFIX="$extension: $filename: "
}
if [ "$1" != "skip" ] && [ -d "./enabled" ]; then
_bash_it_config_type=""
if [[ "${1}" =~ ^(alias|completion|plugin)$ ]]; then
_bash_it_config_type=$1
_log_debug "Loading enabled $1 components..."
else
_log_debug "Loading all enabled components..."
fi
for _bash_it_config_file in $(sort <(compgen -G "./enabled/*${_bash_it_config_type}.bash")); do
if [ -e "${_bash_it_config_file}" ]; then
_set-prefix-based-on-path "${_bash_it_config_file}"
_log_debug "Loading component..."
# shellcheck source=/dev/null
source $_bash_it_config_file
else
@ -20,9 +31,11 @@ fi
if [ ! -z "${2}" ] && [[ "${2}" =~ ^(aliases|completion|plugins)$ ]] && [ -d "${2}/enabled" ]; then
# TODO: We should warn users they're using legacy enabling
_log_warning "Using legacy enabling for $2, please update your bash-it version and migrate"
for _bash_it_config_file in $(sort <(compgen -G "./${2}/enabled/*.bash")); do
if [ -e "$_bash_it_config_file" ]; then
_set-prefix-based-on-path "${_bash_it_config_file}"
_log_debug "Loading component..."
# shellcheck source=/dev/null
source "$_bash_it_config_file"
else

View File

@ -18,6 +18,10 @@ export BASH_IT_THEME='bobby'
# cloned bash-it with a remote other than origin such as `bash-it`.
# export BASH_IT_REMOTE='bash-it'
# (Advanced): Change this to the name of the main development branch if
# you renamed it or if it was changed for some reason
# export BASH_IT_DEVELOPMENT_BRANCH='master'
# Your place for hosting Git repos. I use this for private repos.
export GIT_HOSTING='git@git.domain.com'
@ -32,6 +36,10 @@ export TODO="t"
# Set this to false to turn off version control status checking within the prompt for all themes
export SCM_CHECK=true
# Set to actual location of gitstatus directory if installed
#export SCM_GIT_GITSTATUS_DIR="$HOME/gitstatus"
# per default gitstatus uses 2 times as many threads as CPU cores, you can change this here if you must
#export GITSTATUS_NUM_THREADS=8
# Set Xterm/screen/Tmux title with only a short hostname.
# Uncomment this (or set SHORT_HOSTNAME to something else),

View File

@ -1,4 +1,13 @@
## Testing with [Bats](https://github.com/sstephenson/bats#installing-bats-from-source)
# Testing with Bats
## Overview
The Bash-it unit tests leverage the [Bats unit test framework for Bash](https://github.com/bats-core/bats-core).
There is no need to install Bats explicitly, the test run script will automatically download and install Bats and its dependencies.
When making changes to Bash-it, the tests are automatically executed in a test build environment on [Travis CI](https://travis-ci.com).
## Test Execution
To execute the unit tests, please run the `run` script:
@ -10,4 +19,22 @@ To execute the unit tests, please run the `run` script:
test/run
```
The `run` script will automatically install [Bats](https://github.com/sstephenson/bats#installing-bats-from-source) if it is not already present, and will then run all tests found under the `test` directory, including subdirectories.
The `run` script will automatically install if it is not already present, and will then run all tests found under the `test` directory, including subdirectories.
To run only a subset of the tests, you can provide the name of the test subdirectory that you want to run, e.g. like this for the tests in the `test/themes` directory:
```bash
# If you are in the root `.bash_it` directory:
test/run test/themes
```
By default, the tests run in single-threaded mode.
If you want to speed up the test execution, you can install the [GNU `parallel` tool](https://www.gnu.org/software/parallel/), which is supported by Bats.
When using `parallel`, the `test/run` script will use a number of threads in parallel, depending on the available CPU cores of your system.
This can speed up test execution significantly.
## Writing Tests
When adding or modifying tests, please stick to the format and conventions of the existing test cases.
The `test_helper.bash` script provides a couple of reusable helper functions that you should use when writing a test case,
for example for setting up an isolated test environment.

View File

@ -4,36 +4,17 @@ load ../test_helper
load ../../lib/composure
function local_setup {
mkdir -p "$BASH_IT"
lib_directory="$(cd "$(dirname "$0")" && pwd)"
echo "Bi : $BASH_IT"
echo "Lib: $lib_directory"
# Use rsync to copy Bash-it to the temp folder
# rsync is faster than cp, since we can exclude the large ".git" folder
rsync -qavrKL -d --delete-excluded --exclude=.git $lib_directory/../../.. "$BASH_IT"
rm -rf "$BASH_IT"/enabled
rm -rf "$BASH_IT"/aliases/enabled
rm -rf "$BASH_IT"/completion/enabled
rm -rf "$BASH_IT"/plugins/enabled
setup_test_fixture
# Copy the test fixture to the Bash-it folder
rsync -a "$BASH_IT/test/fixtures/bash_it/" "$BASH_IT/"
# Don't pollute the user's actual $HOME directory
# Use a test home directory instead
export BASH_IT_TEST_CURRENT_HOME="${HOME}"
export BASH_IT_TEST_HOME="$(cd "${BASH_IT}/.." && pwd)/BASH_IT_TEST_HOME"
mkdir -p "${BASH_IT_TEST_HOME}"
export HOME="${BASH_IT_TEST_HOME}"
}
function local_teardown {
export HOME="${BASH_IT_TEST_CURRENT_HOME}"
rm -rf "${BASH_IT_TEST_HOME}"
assert_equal "${BASH_IT_TEST_CURRENT_HOME}" "${HOME}"
if command -v rsync &> /dev/null
then
rsync -a "$BASH_IT/test/fixtures/bash_it/" "$BASH_IT/"
else
find "$BASH_IT/test/fixtures/bash_it" \
-mindepth 1 -maxdepth 1 \
-exec cp -r {} "$BASH_IT/" \;
fi
}
@test "bash-it: verify that the test fixture is available" {

View File

@ -5,36 +5,7 @@ load ../../lib/composure
load ../../completion/available/bash-it.completion
function local_setup {
mkdir -p "$BASH_IT"
lib_directory="$(cd "$(dirname "$0")" && pwd)"
# Use rsync to copy Bash-it to the temp folder
# rsync is faster than cp, since we can exclude the large ".git" folder
rsync -qavrKL -d --delete-excluded --exclude=.git $lib_directory/../../.. "$BASH_IT"
rm -rf "$BASH_IT"/enabled
rm -rf "$BASH_IT"/aliases/enabled
rm -rf "$BASH_IT"/completion/enabled
rm -rf "$BASH_IT"/plugins/enabled
mkdir -p "$BASH_IT"/enabled
mkdir -p "$BASH_IT"/aliases/enabled
mkdir -p "$BASH_IT"/completion/enabled
mkdir -p "$BASH_IT"/plugins/enabled
# Don't pollute the user's actual $HOME directory
# Use a test home directory instead
export BASH_IT_TEST_CURRENT_HOME="${HOME}"
export BASH_IT_TEST_HOME="$(cd "${BASH_IT}/.." && pwd)/BASH_IT_TEST_HOME"
mkdir -p "${BASH_IT_TEST_HOME}"
export HOME="${BASH_IT_TEST_HOME}"
}
function local_teardown {
export HOME="${BASH_IT_TEST_CURRENT_HOME}"
rm -rf "${BASH_IT_TEST_HOME}"
assert_equal "${BASH_IT_TEST_CURRENT_HOME}" "${HOME}"
setup_test_fixture
}
@test "completion bash-it: ensure that the _bash-it-comp function is available" {
@ -72,6 +43,11 @@ function __check_completion () {
echo "${COMPREPLY[@]}"
}
@test "completion bash-it: doctor - show options" {
run __check_completion 'bash-it doctor '
assert_line -n 0 "errors warnings all"
}
@test "completion bash-it: help - show options" {
run __check_completion 'bash-it help '
assert_line -n 0 "aliases completions migrate plugins update"
@ -82,9 +58,14 @@ function __check_completion () {
assert_line -n 0 "vagrant vault vim"
}
@test "completion bash-it: update - show no options" {
@test "completion bash-it: update - show options" {
run __check_completion 'bash-it update '
assert_line -n 0 ""
assert_line -n 0 "stable dev"
}
@test "completion bash-it: update - show optional flags" {
run __check_completion 'bash-it update -'
assert_line -n 0 "-s --silent"
}
@test "completion bash-it: search - show no options" {
@ -99,32 +80,32 @@ function __check_completion () {
@test "completion bash-it: show options" {
run __check_completion 'bash-it '
assert_line -n 0 "disable enable help migrate reload search show update version"
assert_line -n 0 "disable enable help migrate reload restart doctor 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 reload search show update version"
assert_line -n 0 "disable enable help migrate reload restart doctor search show update version"
}
@test "completion bash-it: shit - show options" {
run __check_completion 'shit '
assert_line -n 0 "disable enable help migrate reload search show update version"
assert_line -n 0 "disable enable help migrate reload restart doctor search show update version"
}
@test "completion bash-it: bashit - show options" {
run __check_completion 'bashit '
assert_line -n 0 "disable enable help migrate reload search show update version"
assert_line -n 0 "disable enable help migrate reload restart doctor search show update version"
}
@test "completion bash-it: batshit - show options" {
run __check_completion 'batshit '
assert_line -n 0 "disable enable help migrate reload search show update version"
assert_line -n 0 "disable enable help migrate reload restart doctor 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 reload search show update version"
assert_line -n 0 "disable enable help migrate reload restart doctor search show update version"
}
@test "completion bash-it: show - show options" {

4
test/fixtures/svn/broken/svn vendored 100755
View File

@ -0,0 +1,4 @@
#!/usr/bin/env bash
# Simply return an error code to simulate a broken SVN installation
exit 72

10
test/fixtures/svn/working/svn vendored 100755
View File

@ -0,0 +1,10 @@
#!/usr/bin/env bash
# If the info command is called
# AND the parent folder contains the .svn folder
# THEN return the current path, similar to what `svn info` does
if [[ "$1" == "info" ]] && [[ -d "../.svn" ]]; then
echo "$PWD"
fi
exit 0

View File

@ -14,31 +14,7 @@ case $OSTYPE in
esac
function local_setup {
mkdir -p "$BASH_IT"
lib_directory="$(cd "$(dirname "$0")" && pwd)"
# Use rsync to copy Bash-it to the temp folder
# rsync is faster than cp, since we can exclude the large ".git" folder
rsync -qavrKL -d --delete-excluded --exclude=.git $lib_directory/../../.. "$BASH_IT"
rm -rf "$BASH_IT"/enabled
rm -rf "$BASH_IT"/aliases/enabled
rm -rf "$BASH_IT"/completion/enabled
rm -rf "$BASH_IT"/plugins/enabled
# Don't pollute the user's actual $HOME directory
# Use a test home directory instead
export BASH_IT_TEST_CURRENT_HOME="${HOME}"
export BASH_IT_TEST_HOME="$(cd "${BASH_IT}/.." && pwd)/BASH_IT_TEST_HOME"
mkdir -p "${BASH_IT_TEST_HOME}"
export HOME="${BASH_IT_TEST_HOME}"
}
function local_teardown {
export HOME="${BASH_IT_TEST_CURRENT_HOME}"
rm -rf "${BASH_IT_TEST_HOME}"
assert_equal "${BASH_IT_TEST_CURRENT_HOME}" "${HOME}"
setup_test_fixture
}
@test "install: verify that the install script exists" {

View File

@ -14,31 +14,7 @@ case $OSTYPE in
esac
function local_setup {
mkdir -p "$BASH_IT"
lib_directory="$(cd "$(dirname "$0")" && pwd)"
# Use rsync to copy Bash-it to the temp folder
# rsync is faster than cp, since we can exclude the large ".git" folder
rsync -qavrKL -d --delete-excluded --exclude=.git $lib_directory/../../.. "$BASH_IT"
rm -rf "$BASH_IT"/enabled
rm -rf "$BASH_IT"/aliases/enabled
rm -rf "$BASH_IT"/completion/enabled
rm -rf "$BASH_IT"/plugins/enabled
# Don't pollute the user's actual $HOME directory
# Use a test home directory instead
export BASH_IT_TEST_CURRENT_HOME="${HOME}"
export BASH_IT_TEST_HOME="$(cd "${BASH_IT}/.." && pwd)/BASH_IT_TEST_HOME"
mkdir -p "${BASH_IT_TEST_HOME}"
export HOME="${BASH_IT_TEST_HOME}"
}
function local_teardown {
export HOME="${BASH_IT_TEST_CURRENT_HOME}"
rm -rf "${BASH_IT_TEST_HOME}"
assert_equal "${BASH_IT_TEST_CURRENT_HOME}" "${HOME}"
setup_test_fixture
}
@test "uninstall: verify that the uninstall script exists" {

View File

@ -2,6 +2,7 @@
load ../test_helper
load ../../lib/composure
load ../../lib/log
load ../../lib/utilities
load ../../lib/search
load ../../plugins/available/base.plugin
@ -11,21 +12,7 @@ cite _about _param _example _group _author _version
load ../../lib/helpers
function local_setup {
mkdir -p "$BASH_IT"
lib_directory="$(cd "$(dirname "$0")" && pwd)"
# Use rsync to copy Bash-it to the temp folder
# rsync is faster than cp, since we can exclude the large ".git" folder
rsync -qavrKL -d --delete-excluded --exclude=.git $lib_directory/../../.. "$BASH_IT"
rm -rf "$BASH_IT"/enabled
rm -rf "$BASH_IT"/aliases/enabled
rm -rf "$BASH_IT"/completion/enabled
rm -rf "$BASH_IT"/plugins/enabled
mkdir -p "$BASH_IT"/enabled
mkdir -p "$BASH_IT"/aliases/enabled
mkdir -p "$BASH_IT"/completion/enabled
mkdir -p "$BASH_IT"/plugins/enabled
setup_test_fixture
}
# TODO Create global __is_enabled function
@ -33,7 +20,7 @@ function local_setup {
# TODO Create global __get_enabled_name function
@test "helpers: _command_exists function exists" {
type -a _command_exists &> /dev/null
run type -a _command_exists &> /dev/null
assert_success
}
@ -141,8 +128,8 @@ function local_setup {
@test "helpers: enable the brew completion" {
run _enable-completion "brew"
assert_line -n 0 'brew enabled with priority 350.'
assert_link_exist "$BASH_IT/enabled/350---brew.completion.bash"
assert_line -n 0 'brew enabled with priority 375.'
assert_link_exist "$BASH_IT/enabled/375---brew.completion.bash"
}
@test "helpers: enable the node plugin" {

86
test/lib/log.bats 100644
View File

@ -0,0 +1,86 @@
#!/usr/bin/env bats
load ../test_helper
load ../../lib/composure
load ../../lib/appearance
load ../../plugins/available/base.plugin
cite _about _param _example _group _author _version
load ../../lib/log
@test "lib log: basic debug logging with BASH_IT_LOG_LEVEL_ALL" {
BASH_IT_LOG_LEVEL=$BASH_IT_LOG_LEVEL_ALL
run _log_debug "test test test"
assert_output "DEBUG: test test test"
}
@test "lib log: basic warning logging with BASH_IT_LOG_LEVEL_ALL" {
BASH_IT_LOG_LEVEL=$BASH_IT_LOG_LEVEL_ALL
run _log_warning "test test test"
assert_output " WARN: test test test"
}
@test "lib log: basic error logging with BASH_IT_LOG_LEVEL_ALL" {
BASH_IT_LOG_LEVEL=$BASH_IT_LOG_LEVEL_ALL
run _log_error "test test test"
assert_output "ERROR: test test test"
}
@test "lib log: basic debug logging with BASH_IT_LOG_LEVEL_WARNING" {
BASH_IT_LOG_LEVEL=$BASH_IT_LOG_LEVEL_WARNING
run _log_debug "test test test"
refute_output
}
@test "lib log: basic warning logging with BASH_IT_LOG_LEVEL_WARNING" {
BASH_IT_LOG_LEVEL=$BASH_IT_LOG_LEVEL_WARNING
run _log_warning "test test test"
assert_output " WARN: test test test"
}
@test "lib log: basic error logging with BASH_IT_LOG_LEVEL_WARNING" {
BASH_IT_LOG_LEVEL=$BASH_IT_LOG_LEVEL_WARNING
run _log_error "test test test"
assert_output "ERROR: test test test"
}
@test "lib log: basic debug logging with BASH_IT_LOG_LEVEL_ERROR" {
BASH_IT_LOG_LEVEL=$BASH_IT_LOG_LEVEL_ERROR
run _log_debug "test test test"
refute_output
}
@test "lib log: basic warning logging with BASH_IT_LOG_LEVEL_ERROR" {
BASH_IT_LOG_LEVEL=$BASH_IT_LOG_LEVEL_ERROR
run _log_warning "test test test"
refute_output
}
@test "lib log: basic error logging with BASH_IT_LOG_LEVEL_ERROR" {
BASH_IT_LOG_LEVEL=$BASH_IT_LOG_LEVEL_ERROR
run _log_error "test test test"
assert_output "ERROR: test test test"
}
@test "lib log: basic debug silent logging" {
run _log_debug "test test test"
refute_output
}
@test "lib log: basic warning silent logging" {
run _log_warning "test test test"
refute_output
}
@test "lib log: basic error silent logging" {
run _log_error "test test test"
refute_output
}
@test "lib log: logging with prefix" {
BASH_IT_LOG_LEVEL=$BASH_IT_LOG_LEVEL_ALL
BASH_IT_LOG_PREFIX="nice: prefix: "
run _log_debug "test test test"
assert_output "DEBUG: nice: prefix: test test test"
}

View File

@ -2,9 +2,13 @@
load ../test_helper
load ../../lib/composure
load ../../lib/log
load ../../lib/helpers
load ../../lib/utilities
load ../../lib/search
cite _about _param _example _group _author _version
load ../../plugins/available/base.plugin
load ../../aliases/available/git.aliases
load ../../plugins/available/ruby.plugin
@ -13,27 +17,10 @@ load ../../completion/available/bundler.completion
load ../../completion/available/gem.completion
load ../../completion/available/rake.completion
cite _about _param _example _group _author _version
load ../../lib/helpers
function local_setup {
mkdir -p "$BASH_IT"
lib_directory="$(cd "$(dirname "$0")" && pwd)"
# Use rsync to copy Bash-it to the temp folder
# rsync is faster than cp, since we can exclude the large ".git" folder
rsync -qavrKL -d --delete-excluded --exclude=.git $lib_directory/../../.. "$BASH_IT"
rm -rf "$BASH_IT"/enabled
rm -rf "$BASH_IT"/aliases/enabled
rm -rf "$BASH_IT"/completion/enabled
rm -rf "$BASH_IT"/plugins/enabled
rm -rf "$BASH_IT"/tmp/cache
mkdir -p "$BASH_IT"/enabled
mkdir -p "$BASH_IT"/aliases/enabled
mkdir -p "$BASH_IT"/completion/enabled
mkdir -p "$BASH_IT"/plugins/enabled
setup_test_fixture
export OLD_PATH="$PATH"
export PATH="/usr/bin:/bin:/usr/sbin"
@ -53,8 +40,13 @@ function local_teardown {
@test "search: git" {
run _bash-it-search 'git' --no-color
assert_line -n 0 ' aliases: git gitsvn '
assert_line -n 1 ' plugins: autojump git git-subrepo jgitflow jump '
assert_line -n 2 ' completions: git git_flow git_flow_avh '
assert_line -n 1 -p ' plugins:'
for plugin in "autojump" "git" "gitstatus" "git-subrepo" "jgitflow" "jump"
do
echo $plugin
assert_line -n 1 -p $plugin
done
assert_line -n 2 ' completions: git git_flow git_flow_avh github-cli '
}
@test "search: ruby gem bundle rake rails" {

View File

@ -9,22 +9,7 @@ load ../../lib/search
cite _about _param _example _group _author _version
function local_setup {
mkdir -p "$BASH_IT"
lib_directory="$(cd "$(dirname "$0")" && pwd)"
# Use rsync to copy Bash-it to the temp folder
# rsync is faster than cp, since we can exclude the large ".git" folder
rsync -qavrKL -d --delete-excluded --exclude=.git $lib_directory/../../.. "$BASH_IT"
rm -rf "$BASH_IT"/enabled
rm -rf "$BASH_IT"/aliases/enabled
rm -rf "$BASH_IT"/completion/enabled
rm -rf "$BASH_IT"/plugins/enabled
rm -rf "$BASH_IT"/tmp/cache
mkdir -p "$BASH_IT"/enabled
mkdir -p "$BASH_IT"/aliases/enabled
mkdir -p "$BASH_IT"/completion/enabled
mkdir -p "$BASH_IT"/plugins/enabled
setup_test_fixture
}
function has_match() {

View File

@ -0,0 +1,24 @@
#!/usr/bin/env bats
load ../test_helper
load ../../lib/composure
load ../../lib/log
load ../../lib/helpers
cite _about _param _example _group _author _version
load ../../completion/available/git.completion
@test "alias-completion: See that aliases with double quotes and brackets do not break the plugin" {
alias gtest="git log --graph --pretty=format:'%C(bold)%h%Creset%C(magenta)%d%Creset %s %C(yellow)<%an> %C(cyan)(%cr)%Creset' --abbrev-commit --date=relative"
load ../../plugins/available/alias-completion.plugin
assert_success
}
@test "alias-completion: See that aliases with single quotes and brackets do not break the plugin" {
alias gtest='git log --graph --pretty=format:"%C(bold)%h%Creset%C(magenta)%d%Creset %s %C(yellow)<%an> %C(cyan)(%cr)%Creset" --abbrev-commit --date=relative'
load ../../plugins/available/alias-completion.plugin
assert_success
}

View File

@ -16,10 +16,6 @@ load ../../plugins/available/base.plugin
}
@test 'plugins base: myip()' {
if [[ ! $SLOW_TESTS ]]; then
skip 'myip is slow - run only with SLOW_TESTS=true'
fi
run myip
assert_success
declare -r mask_ip=$(echo $output | tr -s '[0-9]' '?')
@ -43,7 +39,7 @@ load ../../plugins/available/base.plugin
mkcd "${dir_name}"
assert_success
assert_file_exist "${BASH_IT_ROOT}/${dir_name}"
assert_dir_exist "${BASH_IT_ROOT}/${dir_name}"
assert_equal $(pwd) "${BASH_IT_ROOT}/${dir_name}"
}

View File

@ -5,12 +5,14 @@ load ../../lib/helpers
load ../../lib/composure
@test 'ensure _go_pathmunge_wrap is defined' {
{ [[ $CI ]] || _command_exists go; } || skip 'golang not found'
load ../../plugins/available/go.plugin
run type -t _go_pathmunge_wrap
assert_line 'function'
}
@test 'plugins go: single entry in GOPATH' {
{ [[ $CI ]] || _command_exists go; } || skip 'golang not found'
export GOPATH="/foo"
export GOROOT="/baz"
load ../../plugins/available/go.plugin
@ -18,6 +20,7 @@ load ../../lib/composure
}
@test 'plugins go: single entry in GOPATH, with space' {
{ [[ $CI ]] || _command_exists go; } || skip 'golang not found'
export GOPATH="/foo bar"
export GOROOT="/baz"
load ../../plugins/available/go.plugin
@ -25,6 +28,7 @@ load ../../lib/composure
}
@test 'plugins go: single entry in GOPATH, with escaped space' {
{ [[ $CI ]] || _command_exists go; } || skip 'golang not found'
export GOPATH="/foo\ bar"
export GOROOT="/baz"
load ../../plugins/available/go.plugin
@ -32,6 +36,7 @@ load ../../lib/composure
}
@test 'plugins go: multiple entries in GOPATH' {
{ [[ $CI ]] || _command_exists go; } || skip 'golang not found'
export GOPATH="/foo:/bar"
export GOROOT="/baz"
load ../../plugins/available/go.plugin
@ -39,6 +44,7 @@ load ../../lib/composure
}
@test 'plugins go: multiple entries in GOPATH, with space' {
{ [[ $CI ]] || _command_exists go; } || skip 'golang not found'
export GOPATH="/foo:/foo bar"
export GOROOT="/baz"
load ../../plugins/available/go.plugin
@ -46,6 +52,7 @@ load ../../lib/composure
}
@test 'plugins go: multiple entries in GOPATH, with escaped space' {
{ [[ $CI ]] || _command_exists go; } || skip 'golang not found'
export GOPATH="/foo:/foo\ bar"
export GOROOT="/baz"
load ../../plugins/available/go.plugin

View File

@ -6,21 +6,7 @@ load ../../lib/composure
load ../../plugins/available/ruby.plugin
function local_setup {
mkdir -p "$BASH_IT"
lib_directory="$(cd "$(dirname "$0")" && pwd)"
# Use rsync to copy Bash-it to the temp folder
# rsync is faster than cp, since we can exclude the large ".git" folder
rsync -qavrKL -d --delete-excluded --exclude=.git $lib_directory/../../.. "$BASH_IT"
rm -rf "$BASH_IT"/enabled
rm -rf "$BASH_IT"/aliases/enabled
rm -rf "$BASH_IT"/completion/enabled
rm -rf "$BASH_IT"/plugins/enabled
mkdir -p "$BASH_IT"/enabled
mkdir -p "$BASH_IT"/aliases/enabled
mkdir -p "$BASH_IT"/completion/enabled
mkdir -p "$BASH_IT"/plugins/enabled
setup_test_fixture
export OLD_PATH="$PATH"
export PATH="/usr/bin:/bin:/usr/sbin"

View File

@ -16,4 +16,33 @@ else
test_dirs=( "$1" )
fi
exec $bats_executable ${CI:+--tap} "${test_dirs[@]}"
# Make sure that the `parallel` command is installed,
# AND that it is the GNU version of `parallel`.
# If that is the case, try to guess the number of CPU cores,
# so we can run `bats` in parallel processing mode, which is a lot faster.
if command -v parallel &> /dev/null \
&& parallel -V &> /dev/null \
&& { parallel -V 2> /dev/null | grep -q '^GNU\>'; }
then
# Expect to run at least on a dual-core CPU; slightly degraded performance
# shouldn't matter otherwise.
declare -i -r test_jobs_default=2
declare -i -r test_jobs_effective="$(
if [ "${TEST_JOBS:-detect}" = "detect" ] \
&& command -v nproc &> /dev/null
then
nproc
elif [ -n "${TEST_JOBS}" ] \
&& [ "${TEST_JOBS}" != "detect" ]
then
echo "${TEST_JOBS}"
else
echo ${test_jobs_default}
fi
)"
exec "$bats_executable" ${CI:+--tap} --jobs ${test_jobs_effective} \
"${test_dirs[@]}"
else
# Run `bats` in single-threaded mode.
exec "$bats_executable" ${CI:+--tap} "${test_dirs[@]}"
fi

View File

@ -6,17 +6,12 @@ unset TODO
unset SCM_CHECK
unset BASH_IT_AUTOMATIC_RELOAD_AFTER_CONFIG_CHANGE
BASH_IT_TEST_DIR="${BATS_TMPDIR}/.bash_it"
# guard against executing this block twice due to bats internals
if [ "$BASH_IT_ROOT" != "${BASH_IT_TEST_DIR}/root" ]; then
export BASH_IT_ROOT="${BASH_IT_TEST_DIR}/root"
export BASH_IT=$BASH_IT_TEST_DIR
fi
export TEST_MAIN_DIR="${BATS_TEST_DIRNAME}/.."
export TEST_DEPS_DIR="${TEST_DEPS_DIR-${TEST_MAIN_DIR}/../test_lib}"
# be independent of git's system configuration
export GIT_CONFIG_NOSYSTEM
load "${TEST_DEPS_DIR}/bats-support/load.bash"
load "${TEST_DEPS_DIR}/bats-assert/load.bash"
load "${TEST_DEPS_DIR}/bats-file/load.bash"
@ -29,9 +24,70 @@ local_teardown() {
true
}
# This function sets up a local test fixture, i.e. a completely
# fresh and isolated Bash-it directory. This is done to avoid
# messing with your own Bash-it source directory.
# If you need this, call it in your .bats file's `local_setup` function.
setup_test_fixture() {
mkdir -p "$BASH_IT"
lib_directory="$(cd "$(dirname "$0")" && pwd)"
local src_topdir="$lib_directory/../../../.."
if command -v rsync &> /dev/null
then
# Use rsync to copy Bash-it to the temp folder
rsync -qavrKL -d --delete-excluded --exclude=.git --exclude=enabled "$src_topdir" "$BASH_IT"
else
rm -rf "$BASH_IT"
mkdir -p "$BASH_IT"
find "$src_topdir" \
-mindepth 1 -maxdepth 1 \
-not -name .git \
-exec cp -r {} "$BASH_IT" \;
fi
rm -rf "$BASH_IT"/enabled
rm -rf "$BASH_IT"/aliases/enabled
rm -rf "$BASH_IT"/completion/enabled
rm -rf "$BASH_IT"/plugins/enabled
mkdir -p "$BASH_IT"/enabled
mkdir -p "$BASH_IT"/aliases/enabled
mkdir -p "$BASH_IT"/completion/enabled
mkdir -p "$BASH_IT"/plugins/enabled
# Some tests use the BASH_IT_TEST_HOME variable, e.g. install/uninstall
export BASH_IT_TEST_HOME="$TEST_TEMP_DIR"
}
setup() {
# The `temp_make` function from "bats-file" requires the tralston/bats-file fork,
# since the original ztombol/bats-file's `temp_make` does not work on macOS.
TEST_TEMP_DIR="$(temp_make --prefix 'bash-it-test-')"
export TEST_TEMP_DIR
export BASH_IT_TEST_DIR="${TEST_TEMP_DIR}/.bash_it"
export BASH_IT_ROOT="${BASH_IT_TEST_DIR}/root"
export BASH_IT=$BASH_IT_TEST_DIR
mkdir -p -- "${BASH_IT_ROOT}"
# Some tools, e.g. `git` use configuration files from the $HOME directory,
# which interferes with our tests. The only way to keep `git` from doing this
# seems to set HOME explicitly to a separate location.
# Refer to https://git-scm.com/docs/git-config#FILES.
unset XDG_CONFIG_HOME
export HOME="${TEST_TEMP_DIR}"
mkdir -p "${HOME}"
# For `git` tests to run well, user name and email need to be set.
# Refer to https://git-scm.com/docs/git-commit#_commit_information.
# This goes to the test-specific config, due to the $HOME overridden above.
git config --global user.name "John Doe"
git config --global user.email "johndoe@example.com"
local_setup
}
@ -39,49 +95,5 @@ teardown() {
local_teardown
rm -rf "${BASH_IT_TEST_DIR}"
}
# Fail and display path of the link if it does not exist. Also fails
# if the path exists, but is not a link.
# This function is the logical complement of `assert_file_not_exist'.
# There is no dedicated function for checking that a link does not exist.
#
# Globals:
# BATSLIB_FILE_PATH_REM
# BATSLIB_FILE_PATH_ADD
# Arguments:
# $1 - path
# Returns:
# 0 - link exists and is a link
# 1 - otherwise
# Outputs:
# STDERR - details, on failure
assert_link_exist() {
local -r file="$1"
local -r target="$2"
if [[ ! -L "$file" ]]; then
local -r rem="$BATSLIB_FILE_PATH_REM"
local -r add="$BATSLIB_FILE_PATH_ADD"
if [[ -e "$file" ]]; then
batslib_print_kv_single 4 'path' "${file/$rem/$add}" \
| batslib_decorate 'exists, but is not a link' \
| fail
else
batslib_print_kv_single 4 'path' "${file/$rem/$add}" \
| batslib_decorate 'link does not exist' \
| fail
fi
else
if [ -n "$target" ]; then
local link_target=''
link_target=$(readlink "$file")
if [[ "$link_target" != "$target" ]]; then
batslib_print_kv_single_or_multi 8 'path' "${file/$rem/$add}" \
'expected' "$target" \
'actual' "$link_target" \
| batslib_decorate 'link exists, but does not point to target file' \
| fail
fi
fi
fi
temp_del "${TEST_TEMP_DIR}"
}

View File

@ -2,6 +2,7 @@
load ../test_helper
load ../../lib/composure
load ../../lib/log
cite _about _param _example _group _author _version

View File

@ -2,6 +2,7 @@
load ../test_helper
load ../../lib/composure
load ../../lib/log
cite _about _param _example _group _author _version

View File

@ -0,0 +1,129 @@
#!/usr/bin/env bats
load ../test_helper
load ../../lib/composure
load ../../lib/log
cite _about _param _example _group _author _version
load ../../lib/helpers
load ../../themes/base.theme
function local_setup {
setup_test_fixture
# Copy the test fixture to the Bash-it folder
if command -v rsync &> /dev/null
then
rsync -a "$BASH_IT/test/fixtures/bash_it/" "$BASH_IT/"
else
find "$BASH_IT/test/fixtures/bash_it" \
-mindepth 1 -maxdepth 1 \
-exec cp -r {} "$BASH_IT/" \;
fi
export OLD_PATH="$PATH"
}
function local_teardown {
export PATH="$OLD_PATH"
unset OLD_PATH
}
function setup_repo {
upstream="$(mktemp -d)"
pushd "$upstream" > /dev/null
# Create a dummy SVN folder - this will not work with an actual `svn` command,
# but will be enough to trigger the SVN check in the base theme.
mkdir .svn
echo "$upstream"
}
function setup_svn_path {
local svn_path="$1"
# Make sure that the requested SVN script is available
assert_file_exist "$svn_path/svn"
# Make sure that the requested SVN script is on the path
export PATH="$svn_path:/usr/bin:/bin:/usr/sbin"
}
@test 'themes base: SVN: detect SVN repo' {
repo="$(setup_repo)"
pushd "$repo"
setup_svn_path "$BASH_IT/test/fixtures/svn/working"
# Load the base theme again so that the working SVN script is detected
load ../../themes/base.theme
scm
# Make sure that the SVN command is used
assert_equal "$SCM" "$SCM_SVN"
}
@test 'themes base: SVN: detect SVN repo even from a subfolder' {
repo="$(setup_repo)"
pushd "$repo"
mkdir foo
pushd foo
setup_svn_path "$BASH_IT/test/fixtures/svn/working"
# Load the base theme again so that the working SVN script is detected
load ../../themes/base.theme
scm
# Make sure that the SVN command is used
assert_equal "$SCM" "$SCM_SVN"
}
@test 'themes base: SVN: no SCM if no .svn folder can be found' {
repo="$(setup_repo)"
pushd "$repo"
rm -rf .svn
setup_svn_path "$BASH_IT/test/fixtures/svn/working"
# Load the base theme again so that the working SVN script is detected
load ../../themes/base.theme
scm
# Make sure that no SVN command is used
assert_equal "$SCM" "$SCM_NONE"
}
@test 'themes base: SVN: ignore SVN repo when using broken SVN command' {
repo="$(setup_repo)"
pushd "$repo"
setup_svn_path "$BASH_IT/test/fixtures/svn/broken"
# Load the base theme again so that the broken SVN script is detected
load ../../themes/base.theme
scm
# Make sure that no SVN command is not used
assert_equal "$SCM" "$SCM_NONE"
}
@test 'themes base: SVN: ignore SVN repo even from a subfolder when using a broken SVN' {
repo="$(setup_repo)"
pushd "$repo"
mkdir foo
pushd foo
setup_svn_path "$BASH_IT/test/fixtures/svn/broken"
# Load the base theme again so that the broken SVN script is detected
load ../../themes/base.theme
scm
# Make sure that no SVN command is used
assert_equal "$SCM" "$SCM_NONE"
}

@ -1 +1 @@
Subproject commit 9f88b4207da750093baabc4e3f41bf68f0dd3630
Subproject commit d750c5a1b44bf6fc96726aea76f4621db5fd602f

@ -1 +1 @@
Subproject commit 85388685632f85d5a1c32e6bca2deec401964cf7
Subproject commit 73b8d2f95513207b319efe34685553b75c0b214e

@ -1 +1 @@
Subproject commit 2fddb2b831d65cdf2e411f3b47f4677fbb15729c
Subproject commit c128a1de53ba4a811835af410ce427f1049e2d7f

@ -1 +1 @@
Subproject commit 004e707638eedd62e0481e8cdc9223ad471f12ee
Subproject commit 24a72e14349690bcbf7c151b9d2d1cdd32d36eb1

View File

@ -30,7 +30,7 @@ Face="\342\230\273"
____atomic_top_left_parse() {
ifs_old="${IFS}"
IFS="|"
args=( $1 )
args=($1)
IFS="${ifs_old}"
if [ -n "${args[3]}" ]; then
_TOP_LEFT+="${args[2]}${args[3]}"
@ -45,7 +45,7 @@ ____atomic_top_left_parse() {
____atomic_top_right_parse() {
ifs_old="${IFS}"
IFS="|"
args=( $1 )
args=($1)
IFS="${ifs_old}"
_TOP_RIGHT+=" "
if [ -n "${args[3]}" ]; then
@ -55,14 +55,14 @@ ____atomic_top_right_parse() {
if [ -n "${args[4]}" ]; then
_TOP_RIGHT+="${args[2]}${args[4]}"
fi
__TOP_RIGHT_LEN=$(( __TOP_RIGHT_LEN + ${#args[1]} + ${#args[3]} + ${#args[4]} + 1 ))
(( __SEG_AT_RIGHT += 1 ))
__TOP_RIGHT_LEN=$((__TOP_RIGHT_LEN + ${#args[1]} + ${#args[3]} + ${#args[4]} + 1))
((__SEG_AT_RIGHT += 1))
}
____atomic_bottom_parse() {
ifs_old="${IFS}"
IFS="|"
args=( $1 )
args=($1)
IFS="${ifs_old}"
_BOTTOM+="${args[0]}${args[1]}"
[ ${#args[1]} -gt 0 ] && _BOTTOM+=" "
@ -87,7 +87,7 @@ ____atomic_top() {
[ -n "${info}" ] && ____atomic_top_right_parse "${info}"
done
[ $__TOP_RIGHT_LEN -gt 0 ] && __TOP_RIGHT_LEN=$(( __TOP_RIGHT_LEN - 0 ))
[ $__TOP_RIGHT_LEN -gt 0 ] && __TOP_RIGHT_LEN=$((__TOP_RIGHT_LEN - 0))
___cursor_adjust="\e[${__TOP_RIGHT_LEN}D"
_TOP_LEFT+="${___cursor_adjust}"
@ -148,10 +148,10 @@ ___atomic_prompt_ruby() {
___atomic_prompt_todo() {
[ "${THEME_SHOW_TODO}" != "true" ] ||
[ -z "$(which todo.sh)" ] && return
[ -z "$(which todo.sh)" ] && return
color=$bold_white
box="[|]"
info="t:$(todo.sh ls | egrep "TODO: [0-9]+ of ([0-9]+)" | awk '{ print $4 }' )"
info="t:$(todo.sh ls | egrep "TODO: [0-9]+ of ([0-9]+)" | awk '{ print $4 }')"
printf "%s|%s|%s|%s" "${color}" "${info}" "${bold_green}" "${box}"
}
@ -165,15 +165,15 @@ ___atomic_prompt_clock() {
___atomic_prompt_battery() {
! _command_exists battery_percentage ||
[ "${THEME_SHOW_BATTERY}" != "true" ] ||
[ "$(battery_percentage)" = "no" ] && return
[ "${THEME_SHOW_BATTERY}" != "true" ] ||
[ "$(battery_percentage)" = "no" ] && return
batp=$(battery_percentage)
if [ "$batp" -eq 50 ] || [ "$batp" -gt 50 ]; then
color=$bold_green
elif [ "$batp" -lt 50 ] && [ "$batp" -gt 25 ]; then
elif [ "$batp" -lt 50 ] && [ "$batp" -gt 25 ]; then
color=$bold_yellow
elif [ "$batp" -eq 25 ] || [ "$batp" -lt 25 ]; then
elif [ "$batp" -eq 25 ] || [ "$batp" -lt 25 ]; then
color=$IRed
fi
box="[|]"
@ -194,7 +194,7 @@ ___atomic_prompt_char() {
color=$white
prompt_char="${__ATOMIC_PROMPT_CHAR_PS1}"
if [ "${THEME_SHOW_SUDO}" == "true" ]; then
if [ $(sudo -n id -u 2>&1 | grep 0) ]; then
if sudo -vn 1>/dev/null 2>&1; then
prompt_char="${__ATOMIC_PROMPT_CHAR_PS1_SUDO}"
fi
fi
@ -226,16 +226,16 @@ _atomic_completion() {
segments="battery clock exitcode python ruby scm sudo todo"
case "${_action}" in
show)
COMPREPLY=( $(compgen -W "${segments}" -- "${cur}") )
COMPREPLY=($(compgen -W "${segments}" -- "${cur}"))
return 0
;;
;;
hide)
COMPREPLY=( $(compgen -W "${segments}" -- "${cur}") )
COMPREPLY=($(compgen -W "${segments}" -- "${cur}"))
return 0
;;
;;
esac
COMPREPLY=( $(compgen -W "${actions}" -- "${cur}") )
COMPREPLY=($(compgen -W "${actions}" -- "${cur}"))
return 0
}
@ -246,9 +246,11 @@ atomic() {
typeset func
case $action in
show)
func=__atomic_show;;
func=__atomic_show
;;
hide)
func=__atomic_hide;;
func=__atomic_hide
;;
esac
for seg in ${segs}; do
seg=$(printf "%s" "${seg}" | tr '[:lower:]' '[:upper:]')

View File

@ -8,6 +8,75 @@ A minimal theme with a clean git prompt
* Current path (red when user is root)
* Current git info
* Last command exit code (only shown when the exit code is greater than 0)
* user@hostname for ssh connection
## Fonts and glyphs
A font with SCM glyphs is required to display the default tool/host logos.
You can use a font from https://www.nerdfonts.com/ or patch your own font with the tool
provided by https://github.com/ryanoasis/nerd-fonts.
You can also override the default variables if you want to use different glyphs or standard ASCII characters.
### Default theme glyphs
```bash
BARBUK_GITLAB_CHAR=' '
BARBUK_BITBUCKET_CHAR=' '
BARBUK_GITHUB_CHAR=' '
BARBUK_GIT_DEFAULT_CHAR=' '
BARBUK_GIT_BRANCH_ICON=''
BARBUK_HG_CHAR='☿ '
BARBUK_SVN_CHAR='⑆ '
BARBUK_EXIT_CODE_ICON=' '
```
### Customize glyphs
Define your custom glyphs before sourcing bash-it:
```bash
export BARBUK_GITHUB_CHAR='•'
source "$BASH_IT"/bash_it.sh
```
## SSH prompt
### Usage
When using a ssh session, the theme will display `user@hostname`.
You can disable this information with `BARBUK_SSH_INFO`.
The hostname is displayed in the FQDN format by default. You
can use the short hostname format with `BARBUK_HOST_INFO`.
```bash
# short or long
export BARBUK_HOST_INFO=short
# true or false
export BARBUK_SSH_INFO=false
source "$BASH_IT"/bash_it.sh
```
### Keep theme with sudoer
If you want the theme to persist using `sudo -s` in a ssh session, you need to configure sudo to keep the `HOME` and `SSH_CONNECTION` environment variables.
`HOME` contains the path to the home directory of the current user. Keeping it will allow to use your user dotfiles when elevating privileges.
Keeping `SSH_CONNECTION` env is necessary for ssh detection in the theme.
Please refer to the following documentation for more information:
- [sudo manual](https://www.sudo.ws/man/1.8.13/sudoers.man.html) for `env_keep` configuration
- [openssh manual](https://linux.die.net/man/1/ssh) for information about `SSH_CONNECTION` environment
```bash
cat << EOF > /etc/sudoers.d/keepenv
Defaults env_keep += HOME
Defaults env_keep += SSH_CONNECTION
EOF
chmod 400 /etc/sudoers.d/keepenv
```
## Examples
@ -21,4 +90,10 @@ A minimal theme with a clean git prompt
```bash
 ~/.dotfiles on  master ⤏ origin ↑2 •7 ✗
```
```
### Ssh
```bash
user@hostname in  ~/bash-it on  master ✓
```

View File

@ -1,13 +1,21 @@
#!/usr/bin/env bash
# shellcheck disable=2034,2154
SCM_GIT_CHAR_GITLAB=' '
SCM_GIT_CHAR_BITBUCKET=' '
SCM_GIT_CHAR_GITHUB=' '
SCM_GIT_CHAR_DEFAULT=' '
SCM_GIT_CHAR_ICON_BRANCH=''
SCM_HG_CHAR='☿ '
SCM_SVN_CHAR='⑆ '
# Theme custom glyphs
SCM_GIT_CHAR_GITLAB=${BARBUK_GITLAB_CHAR:=' '}
SCM_GIT_CHAR_BITBUCKET=${BARBUK_BITBUCKET_CHAR:=' '}
SCM_GIT_CHAR_GITHUB=${BARBUK_GITHUB_CHAR:=' '}
SCM_GIT_CHAR_DEFAULT=${BARBUK_GIT_DEFAULT_CHAR:=' '}
SCM_GIT_CHAR_ICON_BRANCH=${BARBUK_GIT_BRANCH_ICON:=''}
SCM_HG_CHAR=${BARBUK_HG_CHAR:='☿ '}
SCM_SVN_CHAR=${BARBUK_SVN_CHAR:='⑆ '}
EXIT_CODE_ICON=${BARBUK_EXIT_CODE_ICON:=' '}
# Ssh user and hostname display
SSH_INFO=${BARBUK_SSH_INFO:=true}
HOST_INFO=${BARBUK_HOST_INFO:=long}
# Bash-it default glyphs customization
SCM_NONE_CHAR=
SCM_THEME_PROMPT_DIRTY=" ${bold_red}"
SCM_THEME_PROMPT_CLEAN=" ${bold_green}"
@ -25,10 +33,9 @@ GIT_THEME_PROMPT_SUFFIX="${cyan}"
SCM_THEME_BRANCH_TRACK_PREFIX="${normal}${cyan}"
SCM_THEME_CURRENT_USER_PREFFIX='  '
SCM_GIT_SHOW_CURRENT_USER=false
EXIT_CODE_ICON=' '
function _git-uptream-remote-logo {
[[ "$(_git-upstream)" == "" ]] && return
[[ "$(_git-upstream)" == "" ]] && SCM_GIT_CHAR="$SCM_GIT_CHAR_DEFAULT"
local remote remote_domain
remote=$(_git-upstream-remote)
@ -59,7 +66,7 @@ function _exit-code {
}
function _prompt {
local exit_code="$?" wrap_char=' ' dir_color=$green
local exit_code="$?" wrap_char=' ' dir_color=$green ssh_info='' python_venv='' host
_exit-code exit_code
_git-uptream-remote-logo
@ -71,7 +78,24 @@ function _prompt {
dir_color=$red
fi
PS1="\\n ${purple}$(scm_char)${dir_color}\\w${normal}$(scm_prompt_info)${exit_code}"
# Detect ssh
if [[ -n "${SSH_CONNECTION}" ]] && [ "$SSH_INFO" = true ]; then
if [ "$HOST_INFO" = long ]; then
host="\H"
else
host="\h"
fi
ssh_info="${bold_blue}\u${bold_orange}@${cyan}$host ${bold_orange}in"
fi
# Detect python venv
if [[ -n "${CONDA_DEFAULT_ENV}" ]]; then
python_venv="${CONDA_DEFAULT_ENV}"
elif [[ -n "${VIRTUAL_ENV}" ]]; then
python_venv=$(basename "${VIRTUAL_ENV}")
fi
PS1="\\n${ssh_info} ${python_venv} ${purple}$(scm_char)${dir_color}\\w${normal}$(scm_prompt_info)${exit_code}"
[[ ${#PS1} -gt $((COLUMNS*3)) ]] && wrap_char="\\n"
PS1="${PS1}${wrap_char}${normal} "

View File

@ -34,6 +34,8 @@ 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_SHOW_COMMIT_COUNT=${SCM_GIT_SHOW_COMMIT_COUNT:=true}
SCM_GIT_USE_GITSTATUS=${SCM_GIT_USE_GITSTATUS:=false}
SCM_GIT_GITSTATUS_RAN=${SCM_GIT_GITSTATUS_RAN:=false}
SCM_GIT='git'
SCM_GIT_CHAR='±'
@ -74,8 +76,6 @@ 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='|'
@ -85,10 +85,19 @@ RBENV_THEME_PROMPT_SUFFIX='|'
RBFU_THEME_PROMPT_PREFIX=' |'
RBFU_THEME_PROMPT_SUFFIX='|'
GIT_EXE=`which git 2> /dev/null || true`
P4_EXE=`which p4 2> /dev/null || true`
HG_EXE=`which hg 2> /dev/null || true`
SVN_EXE=`which svn 2> /dev/null || true`
GIT_EXE=$(which git 2> /dev/null || true)
P4_EXE=$(which p4 2> /dev/null || true)
HG_EXE=$(which hg 2> /dev/null || true)
SVN_EXE=$(which svn 2> /dev/null || true)
# Check for broken SVN exe that is caused by some versions of Xcode.
# See https://github.com/Bash-it/bash-it/issues/1612 for more details.
if [[ -x "$SVN_EXE" ]] ; then
if ! "$SVN_EXE" --version > /dev/null 2>&1 ; then
# Unset the SVN exe variable so that SVN commands are avoided.
SVN_EXE=""
fi
fi
function scm {
if [[ "$SCM_CHECK" = false ]]; then SCM=$SCM_NONE
@ -184,6 +193,12 @@ function git_prompt_minimal_info {
}
function git_prompt_vars {
if ${SCM_GIT_USE_GITSTATUS} && _command_exists gitstatus_query && gitstatus_query && [[ "${VCS_STATUS_RESULT}" == "ok-sync" ]]; then # use faster gitstatus
SCM_GIT_GITSTATUS_RAN=true # use this in githelpers and below to choose gitstatus output
else
SCM_GIT_GITSTATUS_RAN=false
fi
if _git-branch &> /dev/null; then
SCM_GIT_DETACHED="false"
SCM_BRANCH="${SCM_THEME_BRANCH_PREFIX}\$(_git-friendly-ref)$(_git-remote-info)"
@ -199,7 +214,12 @@ function git_prompt_vars {
SCM_BRANCH="${detached_prefix}\$(_git-friendly-ref)"
fi
IFS=$'\t' read -r commits_behind commits_ahead <<< "$(_git-upstream-behind-ahead)"
if [[ "${SCM_GIT_GITSTATUS_RAN}" == "true" ]]; then
commits_behind=${VCS_STATUS_COMMITS_BEHIND}
commits_ahead=${VCS_STATUS_COMMITS_AHEAD}
else
IFS=$'\t' read -r commits_behind commits_ahead <<< "$(_git-upstream-behind-ahead)"
fi
if [[ "${commits_ahead}" -gt 0 ]]; then
SCM_BRANCH+="${SCM_GIT_AHEAD_BEHIND_PREFIX_CHAR}${SCM_GIT_AHEAD_CHAR}"
[[ "${SCM_GIT_SHOW_COMMIT_COUNT}" = "true" ]] && SCM_BRANCH+="${commits_ahead}"
@ -211,13 +231,23 @@ function git_prompt_vars {
if [[ "${SCM_GIT_SHOW_STASH_INFO}" = "true" ]]; then
local stash_count
stash_count="$(git stash list 2> /dev/null | wc -l | tr -d ' ')"
if [[ "${SCM_GIT_GITSTATUS_RAN}" == "true" ]]; then
stash_count=${VCS_STATUS_STASHES}
else
stash_count="$(git stash list 2> /dev/null | wc -l | tr -d ' ')"
fi
[[ "${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
IFS=$'\t' read -r untracked_count unstaged_count staged_count <<< "$(_git-status-counts)"
if [[ "${SCM_GIT_GITSTATUS_RAN}" == "true" ]]; then
untracked_count=${VCS_STATUS_NUM_UNTRACKED}
unstaged_count=${VCS_STATUS_NUM_UNSTAGED}
staged_count=${VCS_STATUS_NUM_STAGED}
else
IFS=$'\t' read -r untracked_count unstaged_count staged_count <<< "$(_git-status-counts)"
fi
if [[ "${untracked_count}" -gt 0 || "${unstaged_count}" -gt 0 || "${staged_count}" -gt 0 ]]; then
SCM_DIRTY=1
if [[ "${SCM_GIT_SHOW_DETAILS}" = "true" ]]; then
@ -229,6 +259,7 @@ function git_prompt_vars {
fi
fi
# no if for gitstatus here, user extraction is not supported by it
[[ "${SCM_GIT_SHOW_CURRENT_USER}" == "true" ]] && SCM_BRANCH+="$(git_user_info)"
SCM_PREFIX=${GIT_THEME_PROMPT_PREFIX:-$SCM_THEME_PROMPT_PREFIX}
@ -313,7 +344,7 @@ function hg_prompt_vars {
if [ -f "$HG_ROOT/dirstate" ]; then
# Mercurial holds various information about the working directory in .hg/dirstate file. More on http://mercurial.selenic.com/wiki/DirState
SCM_CHANGE=$(hexdump -n 10 -e '1/1 "%02x"' "$HG_ROOT/dirstate" | cut -c-12)
SCM_CHANGE=$(hexdump -vn 10 -e '1/1 "%02x"' "$HG_ROOT/dirstate" | cut -c-12)
else
SCM_CHANGE=$(hg summary 2> /dev/null | grep parent: | awk '{print $2}')
fi

View File

@ -12,8 +12,13 @@ GIT_THEME_PROMPT_SUFFIX="${green}|"
CONDAENV_THEME_PROMPT_SUFFIX="|"
function prompt_command() {
#PS1="${bold_cyan}$(scm_char)${green}$(scm_prompt_info)${purple}$(ruby_version_prompt) ${yellow}\h ${reset_color}in ${green}\w ${reset_color}\n${green}→${reset_color} "
PS1="\n${yellow}$(python_version_prompt) ${purple}\h ${reset_color}in ${green}\w\n${bold_cyan}$(scm_char)${green}$(scm_prompt_info) ${green}${reset_color} "
PS1="\n${yellow}$(python_version_prompt) " # Name of virtual env followed by python version
PS1+="${purple}\h "
PS1+="${reset_color}in "
PS1+="${green}\w\n"
PS1+="${bold_cyan}$(scm_char)"
PS1+="${green}$(scm_prompt_info) "
PS1+="${green}${reset_color} "
}
safe_append_prompt_command prompt_command

View File

@ -22,8 +22,13 @@ __bobby_clock() {
}
function prompt_command() {
#PS1="${bold_cyan}$(scm_char)${green}$(scm_prompt_info)${purple}$(ruby_version_prompt) ${yellow}\h ${reset_color}in ${green}\w ${reset_color}\n${green}→${reset_color} "
PS1="\n$(battery_char) $(__bobby_clock)${yellow}$(ruby_version_prompt) ${purple}\h ${reset_color}in ${green}\w\n${bold_cyan}$(scm_prompt_char_info) ${green}${reset_color} "
PS1="\n$(battery_char) $(__bobby_clock)"
PS1+="${yellow}$(ruby_version_prompt) "
PS1+="${purple}\h "
PS1+="${reset_color}in "
PS1+="${green}\w\n"
PS1+="${bold_cyan}$(scm_prompt_char_info) "
PS1+="${green}${reset_color} "
}
THEME_SHOW_CLOCK_CHAR=${THEME_SHOW_CLOCK_CHAR:-"true"}

View File

@ -90,7 +90,7 @@ ____brainy_bottom() {
___brainy_prompt_user_info() {
color=$bold_blue
if [ "${THEME_SHOW_SUDO}" == "true" ]; then
if [ $(sudo -n id -u 2>&1 | grep 0) ]; then
if sudo -vn 1>/dev/null 2>&1; then
color=$bold_red
fi
fi

View File

@ -109,7 +109,7 @@ function __color_white {
function __color_rgb {
r=$1 && g=$2 && b=$3
[[ r == g && g == b ]] && echo $(( $r / 11 + 232 )) && return # gray range above 232
[[ $r == $g && $g == $b ]] && echo $(( $r / 11 + 232 )) && return # gray range above 232
echo "8;5;$(( ($r * 36 + $b * 6 + $g) / 51 + 16 ))"
}

View File

@ -1,45 +1,61 @@
#!/usr/bin/env bash
function _git-symbolic-ref {
git symbolic-ref -q HEAD 2> /dev/null
function _git-symbolic-ref() {
git symbolic-ref -q HEAD 2>/dev/null
}
# When on a branch, this is often the same as _git-commit-description,
# but this can be different when two branches are pointing to the
# same commit. _git-branch is used to explicitly choose the checked-out
# branch.
function _git-branch {
git symbolic-ref -q --short HEAD 2> /dev/null || return 1
function _git-branch() {
if [[ "${SCM_GIT_GITSTATUS_RAN}" == "true" ]]; then
test -n "${VCS_STATUS_LOCAL_BRANCH}" && echo "${VCS_STATUS_LOCAL_BRANCH}" || return 1
else
git symbolic-ref -q --short HEAD 2>/dev/null || return 1
fi
}
function _git-tag {
git describe --tags --exact-match 2> /dev/null
function _git-tag() {
if [[ "${SCM_GIT_GITSTATUS_RAN}" == "true" ]]; then
test -n "${VCS_STATUS_TAG}" && echo "${VCS_STATUS_TAG}"
else
git describe --tags --exact-match 2>/dev/null
fi
}
function _git-commit-description {
git describe --contains --all 2> /dev/null
function _git-commit-description() {
git describe --contains --all 2>/dev/null
}
function _git-short-sha {
git rev-parse --short HEAD
function _git-short-sha() {
if [[ "${SCM_GIT_GITSTATUS_RAN}" == "true" ]]; then
echo ${VCS_STATUS_COMMIT:0:7}
else
git rev-parse --short HEAD
fi
}
# Try the checked-out branch first to avoid collision with branches pointing to the same ref.
function _git-friendly-ref {
function _git-friendly-ref() {
if [[ "${SCM_GIT_GITSTATUS_RAN}" == "true" ]]; then
_git-branch || _git-tag || _git-short-sha # there is no tag based describe output in gitstatus
else
_git-branch || _git-tag || _git-commit-description || _git-short-sha
fi
}
function _git-num-remotes {
function _git-num-remotes() {
git remote | wc -l
}
function _git-upstream {
function _git-upstream() {
local ref
ref="$(_git-symbolic-ref)" || return 1
git for-each-ref --format="%(upstream:short)" "${ref}"
}
function _git-upstream-remote {
function _git-upstream-remote() {
local upstream
upstream="$(_git-upstream)" || return 1
@ -48,35 +64,35 @@ function _git-upstream-remote {
echo "${upstream%"/${branch}"}"
}
function _git-upstream-branch {
function _git-upstream-branch() {
local ref
ref="$(_git-symbolic-ref)" || return 1
# git versions < 2.13.0 do not support "strip" for upstream format
# regex replacement gives the wrong result for any remotes with slashes in the name,
# so only use when the strip format fails.
git for-each-ref --format="%(upstream:strip=3)" "${ref}" 2> /dev/null || git for-each-ref --format="%(upstream)" "${ref}" | sed -e "s/.*\/.*\/.*\///"
git for-each-ref --format="%(upstream:strip=3)" "${ref}" 2>/dev/null || git for-each-ref --format="%(upstream)" "${ref}" | sed -e "s/.*\/.*\/.*\///"
}
function _git-upstream-behind-ahead {
git rev-list --left-right --count "$(_git-upstream)...HEAD" 2> /dev/null
function _git-upstream-behind-ahead() {
git rev-list --left-right --count "$(_git-upstream)...HEAD" 2>/dev/null
}
function _git-upstream-branch-gone {
function _git-upstream-branch-gone() {
[[ "$(git status -s -b | sed -e 's/.* //')" == "[gone]" ]]
}
function _git-hide-status {
function _git-hide-status() {
[[ "$(git config --get bash-it.hide-status)" == "1" ]]
}
function _git-status {
function _git-status() {
local git_status_flags=
[[ "${SCM_GIT_IGNORE_UNTRACKED}" = "true" ]] && git_status_flags='-uno' || true
git status --porcelain ${git_status_flags} 2> /dev/null
git status --porcelain ${git_status_flags} 2>/dev/null
}
function _git-status-counts {
function _git-status-counts() {
_git-status | awk '
BEGIN {
untracked=0;
@ -100,35 +116,59 @@ function _git-status-counts {
}'
}
function _git-remote-info {
[[ "$(_git-upstream)" == "" ]] && return || true
function _git-remote-info() {
[[ "$(_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
remote_info="\$(_git-upstream)"
else
remote_info="$(_git-upstream-remote)"
# prompt handling only, reimplement because patching the routine below gets ugly
if [[ "${SCM_GIT_GITSTATUS_RAN}" == "true" ]]; then
[[ "${VCS_STATUS_REMOTE_NAME}" == "" ]] && return
[[ "${VCS_STATUS_LOCAL_BRANCH}" == "${VCS_STATUS_REMOTE_BRANCH}" ]] && local same_branch_name=true
local same_branch_name=
[[ "${VCS_STATUS_LOCAL_BRANCH}" == "${VCS_STATUS_REMOTE_BRANCH}" ]] && same_branch_name=true
# no multiple remote support in gitstatusd
if [[ "${SCM_GIT_SHOW_REMOTE_INFO}" = "true" || "${SCM_GIT_SHOW_REMOTE_INFO}" = "auto" ]]; then
if [[ "${same_branch_name}" != "true" ]]; then
remote_info="${VCS_STATUS_REMOTE_NAME}/${VCS_STATUS_REMOTE_BRANCH}"
else
remote_info="${VCS_STATUS_REMOTE_NAME}"
fi
elif [[ ${same_branch_name} != "true" ]]; then
remote_info="${VCS_STATUS_REMOTE_BRANCH}"
fi
elif [[ ${same_branch_name} != "true" ]]; then
remote_info="\$(_git-upstream-branch)"
fi
if [[ -n "${remote_info}" ]];then
local branch_prefix
if _git-upstream-branch-gone; then
branch_prefix="${SCM_THEME_BRANCH_GONE_PREFIX}"
else
branch_prefix="${SCM_THEME_BRANCH_TRACK_PREFIX}"
if [[ -n "${remote_info}" ]]; then
# no support for gone remote branches in gitstatusd
local branch_prefix="${SCM_THEME_BRANCH_TRACK_PREFIX}"
echo "${branch_prefix}${remote_info}"
fi
else
[[ "$(_git-upstream)" == "" ]] && return
[[ "$(_git-branch)" == "$(_git-upstream-branch)" ]] && local same_branch_name=true
local same_branch_name=
[[ "$(_git-branch)" == "$(_git-upstream-branch)" ]] && same_branch_name=true
if [[ ("${SCM_GIT_SHOW_REMOTE_INFO}" = "auto" && "$(_git-num-remotes)" -ge 2) || \
"${SCM_GIT_SHOW_REMOTE_INFO}" = "true" ]]; then
if [[ "${same_branch_name}" != "true" ]]; then
remote_info="\$(_git-upstream)"
else
remote_info="$(_git-upstream-remote)"
fi
elif [[ ${same_branch_name} != "true" ]]; then
remote_info="\$(_git-upstream-branch)"
fi
if [[ -n "${remote_info}" ]]; then
local branch_prefix
if _git-upstream-branch-gone; then
branch_prefix="${SCM_THEME_BRANCH_GONE_PREFIX}"
else
branch_prefix="${SCM_THEME_BRANCH_TRACK_PREFIX}"
fi
echo "${branch_prefix}${remote_info}"
fi
echo "${branch_prefix}${remote_info}"
fi
}
# Unused by bash-it, present for API compatibility
function git_status_summary {
function git_status_summary() {
awk '
BEGIN {
untracked=0;

View File

@ -1,37 +1,35 @@
# git branch parser
function parse_git_branch() {
echo -e "\033[1;34m$(git branch 2> /dev/null | sed -e '/^[^*]/d' -e 's/* \(.*\)/(\1)/')\033[0m"
echo -e "\033[1;34m$(git branch 2>/dev/null | sed -e '/^[^*]/d' -e 's/* \(.*\)/(\1)/')\033[0m"
}
function parse_git_branch_no_color() {
echo -e "$(git branch 2> /dev/null | sed -e '/^[^*]/d' -e 's/* \(.*\)/(\1)/')"
echo -e "$(git branch 2>/dev/null | sed -e '/^[^*]/d' -e 's/* \(.*\)/(\1)/')"
}
function prompt() {
# If not running interactively, don't do anything
[[ $- != *i* ]] && return
# If not running interactively, don't do anything
[[ $- != *i* ]] && return
local force_color_prompt=yes
if [ -n "$force_color_prompt" ]; then
if [ -x /usr/bin/tput ] && tput setaf 1 >&/dev/null; then
# We have color support; assume it's compliant with Ecma-48
# (ISO/IEC-6429). (Lack of such support is extremely rare, and such
# a case would tend to support setf rather than setaf.)
local color_prompt=yes
else
local color_prompt=
fi
fi
if [ "$color_prompt" = yes ]; then
PS1="\[\033[0;31m\]\342\224\214\342\224\200\$([[ \$? != 0 ]] && echo \"[\[\033[0;31m\]\342\234\227\[\033[0;37m\]]\342\224\200\")[$(if [[ ${EUID} == 0 ]]; then echo '\[\033[01;31m\]root\[\033[01;33m\]@\[\033[01;96m\]\h'; else echo '\[\033[0;39m\]\u\[\033[01;33m\]@\[\033[01;96m\]\h'; fi)\[\033[0;31m\]]\342\224\200[\[\033[0;32m\]\w\[\033[0;31m\]]\n\[\033[0;31m\]\342\224\224\342\224\200\342\224\200\342\225\274 \[\033[0m\]\[\e[01;33m\]$(parse_git_branch) $\[\e[0m\] "
local force_color_prompt=yes
if [ -n "$force_color_prompt" ]; then
if [ -x /usr/bin/tput ] && tput setaf 1 >&/dev/null; then
# We have color support; assume it's compliant with Ecma-48
# (ISO/IEC-6429). (Lack of such support is extremely rare, and such
# a case would tend to support setf rather than setaf.)
local color_prompt=yes
else
PS1='┌──[\u@\h]─[\w]\n└──╼ $(parse_git_branch_no_color) $ '
local color_prompt=
fi
fi
if [ "$color_prompt" = yes ]; then
PS1="\[\033[0;31m\]\342\224\214\342\224\200\$([[ \$? != 0 ]] && echo \"[\[\033[0;31m\]\342\234\227\[\033[0;37m\]]\342\224\200\")[$(if [[ ${EUID} == 0 ]]; then echo '\[\033[01;31m\]root\[\033[01;33m\]@\[\033[01;96m\]\h'; else echo '\[\033[0;39m\]\u\[\033[01;33m\]@\[\033[01;96m\]\h'; fi)\[\033[0;31m\]]\342\224\200[\[\033[0;32m\]\w\[\033[0;31m\]]\n\[\033[0;31m\]\342\224\224\342\224\200\342\224\200\342\225\274 \[\033[0m\]\[\e[01;33m\]$(parse_git_branch) $\[\e[0m\] "
else
PS1='┌──[\u@\h]─[\w]\n└──╼ $(parse_git_branch_no_color) $ '
fi
}
safe_append_prompt_command prompt

View File

@ -85,5 +85,6 @@ You can configure various aspects of the prompt to use less whitespace. Supporte
|POWERLINE_COMPACT_AFTER_LAST_SEGMENT | Removes the trailing space on the last segment
|POWERLINE_COMPACT_PROMPT | Removes the space after the prompt character
|POWERLINE_COMPACT | Enable all Compact settings (you can still override individual settings)
|POWERLINE_PROMPT_AFTER | Adds characters after the prompt
The default value for all settings is `0` (disabled). Use `1` to enable.

View File

@ -32,6 +32,7 @@ function __powerline_prompt_command {
LEFT_PROMPT=""
SEGMENTS_AT_LEFT=0
LAST_SEGMENT_COLOR=""
PROMPT_AFTER="${POWERLINE_PROMPT_AFTER}"
_save-and-reload-history "${HISTORY_AUTOSAVE:-0}"
@ -51,7 +52,7 @@ function __powerline_prompt_command {
LEFT_PROMPT+=" "
fi
PS1="${LEFT_PROMPT}"
PS1="${LEFT_PROMPT}${PROMPT_AFTER}"
## cleanup ##
unset LAST_SEGMENT_COLOR \

View File

@ -12,6 +12,7 @@ POWERLINE_COMPACT_AFTER_SEPARATOR=${POWERLINE_COMPACT_AFTER_SEPARATOR:=${POWERLI
POWERLINE_COMPACT_BEFOR_FIRST_SEGMENT=${POWERLINE_COMPACT_BEFORE_FIRST_SEGMENT:=${POWERLINE_COMPACT}}
POWERLINE_COMPACT_AFTER_LAST_SEGMENT=${POWERLINE_COMPACT_AFTER_LAST_SEGMENT:=${POWERLINE_COMPACT}}
POWERLINE_COMPACT_PROMPT=${POWERLINE_COMPACT_PROMPT:=${POWERLINE_COMPACT}}
POWERLINE_PROMPT_AFTER=${POWERLINE_PROMPT_AFTER:-""}
PYTHON_VENV_CHAR=${POWERLINE_PYTHON_VENV_CHAR:="ⓔ "}
CONDA_PYTHON_VENV_CHAR=${POWERLINE_CONDA_PYTHON_VENV_CHAR:="ⓔ "}

View File

@ -1,7 +1,7 @@
# Define this here so it can be used by all of the Powerline themes
THEME_CHECK_SUDO=${THEME_CHECK_SUDO:=true}
function set_color {
function set_color() {
set +u
if [[ "${1}" != "-" ]]; then
fg="38;5;${1}"
@ -13,14 +13,12 @@ function set_color {
echo -e "\[\033[${fg}${bg}m\]"
}
function __powerline_user_info_prompt {
function __powerline_user_info_prompt() {
local user_info=""
local color=${USER_INFO_THEME_PROMPT_COLOR}
if [[ "${THEME_CHECK_SUDO}" = true ]]; then
if sudo -n uptime 2>&1 | grep -q "load"; then
color=${USER_INFO_THEME_PROMPT_COLOR_SUDO}
fi
sudo -vn 1>/dev/null 2>&1 && color=${USER_INFO_THEME_PROMPT_COLOR_SUDO}
fi
case "${POWERLINE_PROMPT_USER_INFO_MODE}" in
@ -41,7 +39,7 @@ function __powerline_user_info_prompt {
[[ -n "${user_info}" ]] && echo "${user_info}|${color}"
}
function __powerline_terraform_prompt {
function __powerline_terraform_prompt() {
local terraform_workspace=""
if [ -d .terraform ]; then
@ -50,14 +48,14 @@ function __powerline_terraform_prompt {
fi
}
function __powerline_node_prompt {
function __powerline_node_prompt() {
local node_version=""
node_version="$(node_version_prompt)"
[[ -n "${node_version}" ]] && echo "${NODE_CHAR}${node_version}|${NODE_THEME_PROMPT_COLOR}"
}
function __powerline_ruby_prompt {
function __powerline_ruby_prompt() {
local ruby_version=""
if _command_exists rvm; then
@ -69,7 +67,7 @@ function __powerline_ruby_prompt {
[[ -n "${ruby_version}" ]] && echo "${RUBY_CHAR}${ruby_version}|${RUBY_THEME_PROMPT_COLOR}"
}
function __powerline_k8s_context_prompt {
function __powerline_k8s_context_prompt() {
local kubernetes_context=""
if _command_exists kubectl; then
@ -79,7 +77,7 @@ function __powerline_k8s_context_prompt {
[[ -n "${kubernetes_context}" ]] && echo "${KUBERNETES_CONTEXT_THEME_CHAR}${kubernetes_context}|${KUBERNETES_CONTEXT_THEME_PROMPT_COLOR}"
}
function __powerline_python_venv_prompt {
function __powerline_python_venv_prompt() {
set +u
local python_venv=""
@ -93,7 +91,7 @@ function __powerline_python_venv_prompt {
[[ -n "${python_venv}" ]] && echo "${PYTHON_VENV_CHAR}${python_venv}|${PYTHON_VENV_THEME_PROMPT_COLOR}"
}
function __powerline_scm_prompt {
function __powerline_scm_prompt() {
local color=""
local scm_prompt=""
@ -122,27 +120,27 @@ function __powerline_scm_prompt {
fi
}
function __powerline_cwd_prompt {
function __powerline_cwd_prompt() {
local cwd=$(pwd | sed "s|^${HOME}|~|")
echo "${cwd}|${CWD_THEME_PROMPT_COLOR}"
}
function __powerline_hostname_prompt {
echo "${SHORT_HOSTNAME:-$(hostname -s)}|${HOST_THEME_PROMPT_COLOR}"
function __powerline_hostname_prompt() {
echo "${SHORT_HOSTNAME:-$(hostname -s)}|${HOST_THEME_PROMPT_COLOR}"
}
function __powerline_wd_prompt {
function __powerline_wd_prompt() {
echo "\W|${CWD_THEME_PROMPT_COLOR}"
}
function __powerline_clock_prompt {
function __powerline_clock_prompt() {
echo "$(date +"${THEME_CLOCK_FORMAT}")|${CLOCK_THEME_PROMPT_COLOR}"
}
function __powerline_battery_prompt {
function __powerline_battery_prompt() {
local color=""
local battery_status="$(battery_percentage 2> /dev/null)"
local battery_status="$(battery_percentage 2>/dev/null)"
if [[ -z "${battery_status}" ]] || [[ "${battery_status}" = "-1" ]] || [[ "${battery_status}" = "no" ]]; then
true
@ -159,29 +157,29 @@ function __powerline_battery_prompt {
fi
}
function __powerline_in_vim_prompt {
function __powerline_in_vim_prompt() {
if [ -n "$VIMRUNTIME" ]; then
echo "${IN_VIM_THEME_PROMPT_TEXT}|${IN_VIM_THEME_PROMPT_COLOR}"
fi
}
function __powerline_aws_profile_prompt {
function __powerline_aws_profile_prompt() {
if [[ -n "${AWS_PROFILE}" ]]; then
echo "${AWS_PROFILE_CHAR}${AWS_PROFILE}|${AWS_PROFILE_PROMPT_COLOR}"
fi
}
function __powerline_shlvl_prompt {
function __powerline_shlvl_prompt() {
if [[ "${SHLVL}" -gt 1 ]]; then
local prompt="${SHLVL_THEME_PROMPT_CHAR}"
local level=$(( ${SHLVL} - 1))
local level=$((${SHLVL} - 1))
echo "${prompt}${level}|${SHLVL_THEME_PROMPT_COLOR}"
fi
}
function __powerline_dirstack_prompt {
function __powerline_dirstack_prompt() {
if [[ "${#DIRSTACK[@]}" -gt 1 ]]; then
local depth=$(( ${#DIRSTACK[@]} - 1 ))
local depth=$((${#DIRSTACK[@]} - 1))
local prompt="${DIRSTACK_THEME_PROMPT_CHAR}"
if [[ "${depth}" -ge 2 ]]; then
prompt+="${depth}"
@ -190,17 +188,18 @@ function __powerline_dirstack_prompt {
fi
}
function __powerline_history_number_prompt {
function __powerline_history_number_prompt() {
echo "${HISTORY_NUMBER_THEME_PROMPT_CHAR}\!|${HISTORY_NUMBER_THEME_PROMPT_COLOR}"
}
function __powerline_command_number_prompt {
function __powerline_command_number_prompt() {
echo "${COMMAND_NUMBER_THEME_PROMPT_CHAR}\#|${COMMAND_NUMBER_THEME_PROMPT_COLOR}"
}
function __powerline_left_segment {
local OLD_IFS="${IFS}"; IFS="|"
local params=( $1 )
function __powerline_left_segment() {
local OLD_IFS="${IFS}"
IFS="|"
local params=($1)
IFS="${OLD_IFS}"
local pad_before_segment=" "
@ -226,18 +225,18 @@ function __powerline_left_segment {
LEFT_PROMPT+="$(set_color - ${params[1]})${pad_before_segment}${params[0]}${normal}"
LAST_SEGMENT_COLOR=${params[1]}
(( SEGMENTS_AT_LEFT += 1 ))
((SEGMENTS_AT_LEFT += 1))
}
function __powerline_left_last_segment_padding {
function __powerline_left_last_segment_padding() {
LEFT_PROMPT+="$(set_color - ${LAST_SEGMENT_COLOR}) ${normal}"
}
function __powerline_last_status_prompt {
function __powerline_last_status_prompt() {
[[ "$1" -ne 0 ]] && echo "${1}|${LAST_STATUS_THEME_PROMPT_COLOR}"
}
function __powerline_prompt_command {
function __powerline_prompt_command() {
local last_status="$?" ## always the first
local separator_char="${POWERLINE_PROMPT_CHAR}"
@ -245,9 +244,8 @@ function __powerline_prompt_command {
SEGMENTS_AT_LEFT=0
LAST_SEGMENT_COLOR=""
if [[ -n "${POWERLINE_PROMPT_DISTRO_LOGO}" ]]; then
LEFT_PROMPT+="$(set_color ${PROMPT_DISTRO_LOGO_COLOR} ${PROMPT_DISTRO_LOGO_COLORBG})${PROMPT_DISTRO_LOGO}$(set_color - -)"
LEFT_PROMPT+="$(set_color ${PROMPT_DISTRO_LOGO_COLOR} ${PROMPT_DISTRO_LOGO_COLORBG})${PROMPT_DISTRO_LOGO}$(set_color - -)"
fi
## left prompt ##
@ -279,6 +277,6 @@ function __powerline_prompt_command {
## cleanup ##
unset LAST_SEGMENT_COLOR \
LEFT_PROMPT \
SEGMENTS_AT_LEFT
LEFT_PROMPT \
SEGMENTS_AT_LEFT
}

View File

@ -0,0 +1,25 @@
#!/usr/bin/env bash
SCM_THEME_PROMPT_DIRTY=" ${bold_yellow}"
SCM_THEME_PROMPT_CLEAN=" ${bold_green}"
SCM_THEME_PROMPT_PREFIX=" ${bold_blue}scm:("
SCM_THEME_PROMPT_SUFFIX="${bold_blue})"
GIT_THEME_PROMPT_DIRTY=" ${bold_yellow}"
GIT_THEME_PROMPT_CLEAN=" ${bold_green}"
GIT_THEME_PROMPT_PREFIX=" ${bold_blue}git:("
GIT_THEME_PROMPT_SUFFIX="${bold_blue})"
RVM_THEME_PROMPT_PREFIX="|"
RVM_THEME_PROMPT_SUFFIX="|"
function git_prompt_info() {
git_prompt_vars
echo -e "$SCM_PREFIX${bold_red}$SCM_BRANCH$SCM_STATE$SCM_SUFFIX"
}
function prompt_command() {
PS1="${bold_green}${bold_cyan}\W${reset_color}$(scm_prompt_info)${normal} "
}
PROMPT_COMMAND=prompt_command