diff --git a/.editorconfig b/.editorconfig index 0f5876c4..e35a1b04 100755 --- a/.editorconfig +++ b/.editorconfig @@ -23,7 +23,7 @@ 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 +keep_padding = false # like -kp end_of_line = lf charset = utf-8 trim_trailing_whitespace = true diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index caed0df9..f80494e0 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -28,3 +28,17 @@ repos: # - id: forbid-crlf - id: remove-crlf exclude: ".bat$" + - repo: local + hooks: + - id: dot-sh + name: Check .sh files against bash-it requirements + entry: ./hooks/dot-sh.sh + language: system + files: "\\.sh$" + types: [file] + - id: dot-bash + name: Check .bash files against bash-it requirements + entry: ./hooks/dot-bash.sh + language: system + files: "\\.bash$" + types: [file] diff --git a/aliases/available/clipboard.aliases.bash b/aliases/available/clipboard.aliases.bash index c6c15519..4c7e6f5b 100644 --- a/aliases/available/clipboard.aliases.bash +++ b/aliases/available/clipboard.aliases.bash @@ -1,20 +1,17 @@ +# shellcheck shell=bash cite 'about-alias' -about-alias 'pbcopy and pbpaste shortcuts to linux' +about-alias 'xclip shortcuts' -case $OSTYPE in - linux*) - XCLIP=$(command -v xclip) - [[ $XCLIP ]] && \ - alias pbcopy="$XCLIP -selection clipboard" && \ - alias pbpaste="$XCLIP -selection clipboard -o" - ;; -esac +alias pbcopy="xclip -selection clipboard" +alias pbpaste="xclip -selection clipboard -o" +alias xcpy="xclip -selection clipboard" +alias xpst="xclip -selection clipboard -o" # to use it just install xclip on your distribution and it would work like: -# $ echo "hello" | pbcopy -# $ pbpaste +# $ echo "hello" | xcpy +# $ xpst # hello # very useful for things like: -# cat ~/.ssh/id_rsa.pub | pbcopy +# cat ~/.ssh/id_rsa.pub | xcpy # have fun! diff --git a/aliases/available/dnf.aliases.bash b/aliases/available/dnf.aliases.bash new file mode 100644 index 00000000..9d9f0267 --- /dev/null +++ b/aliases/available/dnf.aliases.bash @@ -0,0 +1,18 @@ +# shellcheck shell=bash +cite 'about-alias' +about-alias 'dnf aliases for fedora 22+ distros' + +alias dnfl="dnf list" # List packages +alias dnfli="dnf list installed" # List installed packages +alias dnfgl="dnf grouplist" # List package groups +alias dnfmc="dnf makecache" # Generate metadata cache +alias dnfp="dnf info" # Show package information +alias dnfs="dnf search" # Search package + +alias dnfu="sudo dnf upgrade" # Upgrade package +alias dnfi="sudo dnf install" # Install package +alias dnfri='sudo dnf reinstall' # Reinstall package +alias dnfgi="sudo dnf groupinstall" # Install package group +alias dnfr="sudo dnf remove" # Remove package +alias dnfgr="sudo dnf groupremove" # Remove package group +alias dnfc="sudo dnf clean all" # Clean cache diff --git a/aliases/available/git.aliases.bash b/aliases/available/git.aliases.bash index a46b44fa..bcb3887d 100644 --- a/aliases/available/git.aliases.bash +++ b/aliases/available/git.aliases.bash @@ -1,137 +1,197 @@ +# shellcheck shell=bash cite 'about-alias' about-alias 'common git abbreviations' -# Aliases -alias gcl='git clone' -alias ga='git add' -alias grm='git rm' -alias gap='git add -p' -alias gall='git add -A' -alias gf='git fetch --all --prune' -alias gft='git fetch --all --prune --tags' -alias gfv='git fetch --all --prune --verbose' -alias gftv='git fetch --all --prune --tags --verbose' -alias gus='git reset HEAD' -alias gpristine='git reset --hard && git clean -dfx' -alias gclean='git clean -fd' -alias gm="git merge" -alias gmv='git mv' alias g='git' alias get='git' -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' -alias gup='git fetch && git rebase' -alias gp='git push' -alias gpd='git push --delete' -alias gpo='git push origin HEAD' -alias gpu='git push --set-upstream' -alias gpuo='git push --set-upstream origin' -alias gpuoc='git push --set-upstream origin $(git symbolic-ref --short HEAD)' -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' + +# add +alias ga='git add' +alias gall='git add -A' +alias gap='git add -p' + +# branch +alias gb='git branch' +alias gbD='git branch -D' +alias gba='git branch -a' +alias gbd='git branch -d' +alias gbm='git branch -m' +alias gbt='git branch --track' +alias gdel='git branch -D' + +# for-each-ref +alias gbc='git for-each-ref --format="%(authorname) %09 %(if)%(HEAD)%(then)*%(else)%(refname:short)%(end) %09 %(creatordate)" refs/remotes/ --sort=authorname DESC' # FROM https://stackoverflow.com/a/58623139/10362396 + +# commit +alias gc='git commit -v' +alias gca='git commit -v -a' +alias gcaa='git commit -a --amend -C HEAD' # Add uncommitted and unstaged changes to the last commit +alias gcam='git commit -v -am' +alias gcamd='git commit --amend' +alias gcm='git commit -v -m' +alias gci='git commit --interactive' +alias gcsam='git commit -S -am' + +# checkout +alias gcb='git checkout -b' +alias gco='git checkout' +alias gcob='git checkout -b' +alias gcobu='git checkout -b ${USER}/' +alias gcom='git checkout master' +alias gcpd='git checkout master; git pull; git branch -D' +alias gct='git checkout --track' + +# clone +alias gcl='git clone' + +# clean +alias gclean='git clean -fd' + +# cherry-pick +alias gcp='git cherry-pick' +alias gcpx='git cherry-pick -x' + +# diff 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' -alias gcm='git commit -v -m' -alias gcam="git commit -v -am" -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' -alias gbD='git branch -D' -alias gcount='git shortlog -sn' -alias gcp='git cherry-pick' -alias gcpx='git cherry-pick -x' -alias gco='git checkout' -alias gcom='git checkout master' -alias gcb='git checkout -b' -alias gcob='git checkout -b' -alias gcobu='git checkout -b ${USER}/' -alias gct='git checkout --track' -alias gcpd='git checkout master; git pull; git branch -D' -alias gexport='git archive --format zip --output' -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" -alias gta="git tag -a" -alias gtd="git tag -d" -alias gtl="git tag -l" -alias gpatch="git format-patch -1" -# From http://blogs.atlassian.com/2014/10/advanced-git-aliases/ -# Show commits since last pull -alias gnew="git log HEAD@{1}..HEAD@{0}" -# Add uncommitted and unstaged changes to the last commit -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" -# 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' -# Git SVN -alias gsr='git svn rebase' +# archive +alias gexport='git archive --format zip --output' + +# fetch +alias gf='git fetch --all --prune' +alias gft='git fetch --all --prune --tags' +alias gftv='git fetch --all --prune --tags --verbose' +alias gfv='git fetch --all --prune --verbose' +alias gmu='git fetch origin -v; git fetch upstream -v; git merge upstream/master' +alias gup='git fetch && git rebase' + +# log +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 gll='git log --graph --pretty=oneline --abbrev-commit' +alias gnew='git log HEAD@{1}..HEAD@{0}' # Show commits since last pull, see http://blogs.atlassian.com/2014/10/advanced-git-aliases/ +alias gwc='git whatchanged' + +# ls-files +alias gu='git ls-files . --exclude-standard --others' # Show untracked files +alias glsut='gu' +alias glsum='git diff --name-only --diff-filter=U' # Show unmerged (conflicted) files + +# gui +alias ggui='git gui' + +# home +alias ghm='cd '\''$(git rev-parse --show-toplevel)'\''' # Git home +# appendage to ghm +if ! _command_exists gh; then + alias gh='ghm' +fi + +# merge +alias gm='git merge' + +# mv +alias gmv='git mv' + +# patch +alias gpatch='git format-patch -1' + +# push +alias gp='git push' +alias gpd='git push --delete' +alias gpf='git push --force' +alias gpo='git push origin HEAD' +alias gpom='git push origin master' +alias gpu='git push --set-upstream' +alias gpunch='git push --force-with-lease' +alias gpuo='git push --set-upstream origin' +alias gpuoc='git push --set-upstream origin $(git symbolic-ref --short HEAD)' + +# pull +alias gl='git pull' +alias glum='git pull upstream master' +alias gpl='git pull' +alias gpp='git pull && git push' +alias gpr='git pull --rebase' + +# remote +alias gr='git remote' +alias gra='git remote add' +alias grv='git remote -v' + +# rm +alias grm='git rm' + +# rebase +alias grb='git rebase' +alias grm='git rebase master' +alias grmi='git rebase master -i' +alias gprom='git fetch origin master && git rebase origin/master && git update-ref refs/heads/master origin/master' # Rebase with latest remote master + +# reset +alias gus='git reset HEAD' +alias gpristine='git reset --hard && git clean -dfx' + +# status +alias gs='git status' +alias gss='git status -s' + +# shortlog +alias gcount='git shortlog -sn' +alias gsl='git shortlog -sn' + +# show +alias gsh='git show' + +# svn alias gsd='git svn dcommit' +alias gsr='git svn rebase' # Git SVN + +# stash +alias gst='git stash' +alias gstb='git stash branch' +alias gstd='git stash drop' +alias gstl='git stash list' +alias gstp='git stash pop' # kept due to long-standing usage +alias gstpo='git stash pop' # recommended for it's symmetry with gstpu (push) + +## 'stash push' introduced in git v2.13.2 +alias gstpu='git stash push' +alias gstpum='git stash push -m' + +## 'stash save' deprecated since git v2.16.0, alias is now push +alias gsts='git stash push' +alias gstsm='git stash push -m' + +# submodules +alias gsu='git submodule update --init --recursive' + +# switch +# these aliases requires git v2.23+ +alias gsw='git switch' +alias gswc='git switch --create' +alias gswm='git switch master' +alias gswt='git switch --track' + +# tag +alias gt='git tag' +alias gta='git tag -a' +alias gtd='git tag -d' +alias gtl='git tag -l' case $OSTYPE in - darwin*) - alias gtls="git tag -l | gsort -V" - ;; - *) - alias gtls='git tag -l | sort -V' - ;; + darwin*) + alias gtls="git tag -l | gsort -V" + ;; + *) + alias gtls='git tag -l | sort -V' + ;; esac + +# functions +function gdv() { + git diff --ignore-all-space "$@" | vim -R - +} diff --git a/aliases/available/vim.aliases.bash b/aliases/available/vim.aliases.bash index 72a37809..d19057d0 100644 --- a/aliases/available/vim.aliases.bash +++ b/aliases/available/vim.aliases.bash @@ -1,3 +1,4 @@ +# shellcheck shell=bash cite 'about-alias' about-alias 'vim abbreviations' diff --git a/clean_files.txt b/clean_files.txt index ddf8fdf9..f94b2dca 100644 --- a/clean_files.txt +++ b/clean_files.txt @@ -17,18 +17,28 @@ # root directories # docs +hooks # root files # .gitattributes lint_clean_files.sh +# plugins +# +plugins/available/history.plugin.bash +plugins/available/history-search.plugin.bash +plugins/available/history-substring-search.plugin.bash + # themes # themes/agnoster themes/90210 themes/powerline themes/barbuk +themes/atomic +themes/axin +themes/base.theme.bash # plugins # @@ -42,6 +52,10 @@ completion/available/packer.completion.bash completion/available/pipx.completion.bash completion/available/rustup.completion.bash completion/available/vault.completion.bash +completion/available/sdkman.completion.bash # aliases +# +aliases/available/dnf.aliases.bash aliases/available/vim.aliases.bash +aliases/available/git.aliases.bash diff --git a/completion/available/cargo.completion.bash b/completion/available/cargo.completion.bash index 46b399e4..d276ee72 100644 --- a/completion/available/cargo.completion.bash +++ b/completion/available/cargo.completion.bash @@ -1,5 +1,4 @@ -#!/usr/bin/env bash - +# shellcheck shell=bash # cargo (Rust package manager) completion if _binary_exists rustup && _binary_exists cargo; then diff --git a/completion/available/knife.completion.bash b/completion/available/knife.completion.bash index cf050e36..83b332f9 100644 --- a/completion/available/knife.completion.bash +++ b/completion/available/knife.completion.bash @@ -1,4 +1,4 @@ -#!/usr/bin/env bash +# shellcheck shell=bash # Published originally as public domain code at https://github.com/wk8/knife-bash-autocomplete diff --git a/completion/available/packer.completion.bash b/completion/available/packer.completion.bash index ea4b7b8c..2301f0f2 100644 --- a/completion/available/packer.completion.bash +++ b/completion/available/packer.completion.bash @@ -1,4 +1,4 @@ -#!/usr/bin/env bash +# shellcheck shell=bash cite "about-completion" about-completion "packer completion" diff --git a/completion/available/pipx.completion.bash b/completion/available/pipx.completion.bash index 9e34f076..16fd844d 100644 --- a/completion/available/pipx.completion.bash +++ b/completion/available/pipx.completion.bash @@ -1,4 +1,4 @@ -#!/usr/bin/env bash +# shellcheck shell=bash # pipx completion if _command_exists register-python-argcomplete && _command_exists pipx; then diff --git a/completion/available/rustup.completion.bash b/completion/available/rustup.completion.bash index 96822031..1cf8bc95 100644 --- a/completion/available/rustup.completion.bash +++ b/completion/available/rustup.completion.bash @@ -1,4 +1,4 @@ -#!/usr/bin/env bash +# shellcheck shell=bash # rustup (Rust toolchain installer) completion diff --git a/completion/available/sdkman.completion.bash b/completion/available/sdkman.completion.bash index ce4b3673..7f0157f3 100644 --- a/completion/available/sdkman.completion.bash +++ b/completion/available/sdkman.completion.bash @@ -1,72 +1,83 @@ -_sdkman_complete() -{ - local CANDIDATES - local CANDIDATE_VERSIONS +# shellcheck shell=bash +_sdkman_complete() { + local CANDIDATES + local CANDIDATE_VERSIONS - COMPREPLY=() + COMPREPLY=() - if [ $COMP_CWORD -eq 1 ]; then - COMPREPLY=( $(compgen -W "install uninstall rm list ls use default home env current upgrade ug version broadcast help offline selfupdate update flush" -- ${COMP_WORDS[COMP_CWORD]}) ) - elif [ $COMP_CWORD -eq 2 ]; then - case "${COMP_WORDS[COMP_CWORD-1]}" in - "install" | "i" | "uninstall" | "rm" | "list" | "ls" | "use" | "u" | "default" | "d" | "home" | "h" | "current" | "c" | "upgrade" | "ug" ) - CANDIDATES=$(echo "${SDKMAN_CANDIDATES_CSV}" | tr ',' ' ') - COMPREPLY=( $(compgen -W "$CANDIDATES" -- ${COMP_WORDS[COMP_CWORD]}) ) - ;; - "env" ) - COMPREPLY=( $(compgen -W "init" -- ${COMP_WORDS[COMP_CWORD]}) ) - ;; - "offline" ) - COMPREPLY=( $(compgen -W "enable disable" -- ${COMP_WORDS[COMP_CWORD]}) ) - ;; - "selfupdate" ) - COMPREPLY=( $(compgen -W "force" -- ${COMP_WORDS[COMP_CWORD]}) ) - ;; - "flush" ) - COMPREPLY=( $(compgen -W "archives tmp broadcast version" -- ${COMP_WORDS[COMP_CWORD]}) ) - ;; - *) - ;; - esac - elif [ $COMP_CWORD -eq 3 ]; then - case "${COMP_WORDS[COMP_CWORD-2]}" in - "uninstall" | "rm" | "use" | "u" | "default" | "d" | "home" | "h" ) - _sdkman_candidate_local_versions ${COMP_WORDS[COMP_CWORD-1]} - COMPREPLY=( $(compgen -W "$CANDIDATE_VERSIONS" -- ${COMP_WORDS[COMP_CWORD]}) ) - ;; - "install" | "i" ) - _sdkman_candidate_all_versions ${COMP_WORDS[COMP_CWORD-1]} - COMPREPLY=( $(compgen -W "$CANDIDATE_VERSIONS" -- ${COMP_WORDS[COMP_CWORD]}) ) - ;; - *) - ;; - esac - fi + if [ "$COMP_CWORD" -eq 1 ]; then + mapfile -t COMPREPLY < <(compgen -W "install uninstall rm list ls use default home env current upgrade ug version broadcast help offline selfupdate update flush" -- "${COMP_WORDS[COMP_CWORD]}") + elif [ "$COMP_CWORD" -eq 2 ]; then + case "${COMP_WORDS[COMP_CWORD - 1]}" in + "install" | "i" | "uninstall" | "rm" | "list" | "ls" | "use" | "u" | "default" | "d" | "home" | "h" | "current" | "c" | "upgrade" | "ug") + CANDIDATES=$(echo "${SDKMAN_CANDIDATES_CSV}" | tr ',' ' ') + mapfile -t COMPREPLY < <(compgen -W "$CANDIDATES" -- "${COMP_WORDS[COMP_CWORD]}") + ;; + "env") + mapfile -t COMPREPLY < <(compgen -W "init" -- "${COMP_WORDS[COMP_CWORD]}") + ;; + "offline") + mapfile -t COMPREPLY < <(compgen -W "enable disable" -- "${COMP_WORDS[COMP_CWORD]}") + ;; + "selfupdate") + mapfile -t COMPREPLY < <(compgen -W "force" -- "${COMP_WORDS[COMP_CWORD]}") + ;; + "flush") + mapfile -t COMPREPLY < <(compgen -W "archives tmp broadcast version" -- "${COMP_WORDS[COMP_CWORD]}") + ;; + *) ;; - return 0 + esac + elif [ "$COMP_CWORD" -eq 3 ]; then + case "${COMP_WORDS[COMP_CWORD - 2]}" in + "uninstall" | "rm" | "use" | "u" | "default" | "d" | "home" | "h") + _sdkman_candidate_local_versions "${COMP_WORDS[COMP_CWORD - 1]}" + mapfile -t COMPREPLY < <(compgen -W "$CANDIDATE_VERSIONS" -- "${COMP_WORDS[COMP_CWORD]}") + ;; + "install" | "i") + _sdkman_candidate_all_versions "${COMP_WORDS[COMP_CWORD - 1]}" + mapfile -t COMPREPLY < <(compgen -W "$CANDIDATE_VERSIONS" -- "${COMP_WORDS[COMP_CWORD]}") + ;; + *) ;; + + esac + fi + + return 0 } -_sdkman_candidate_local_versions(){ +_sdkman_candidate_local_versions() { - CANDIDATE_VERSIONS=$(__sdkman_cleanup_local_versions $1) + CANDIDATE_VERSIONS=$(__sdkman_cleanup_local_versions "$1") } -_sdkman_candidate_all_versions(){ +_sdkman_candidate_all_versions() { - CANDIDATE_LOCAL_VERSIONS=$(__sdkman_cleanup_local_versions $1) - if [ "$SDKMAN_OFFLINE_MODE" = "true" ]; then - CANDIDATE_VERSIONS=$CANDIDATE_LOCAL_VERSIONS - else - CANDIDATE_ONLINE_VERSIONS="$(__sdkman_list_versions $1 | grep " " | grep "\." | cut -c 62-)" - CANDIDATE_VERSIONS="$(echo $CANDIDATE_ONLINE_VERSIONS $CANDIDATE_LOCAL_VERSIONS | tr ' ' '\n' | sort | uniq -u) " - fi + candidate="$1" + CANDIDATE_LOCAL_VERSIONS=$(__sdkman_cleanup_local_versions "$candidate") + if [ "$SDKMAN_OFFLINE_MODE" = "true" ]; then + CANDIDATE_VERSIONS=$CANDIDATE_LOCAL_VERSIONS + else + # sdkman has a specific output format for Java candidate since + # there are multiple vendors and builds. + if [ "$candidate" = "java" ]; then + CANDIDATE_ONLINE_VERSIONS="$(__sdkman_list_versions "$candidate" | grep " " | grep "\." | cut -c 62-)" + else + CANDIDATE_ONLINE_VERSIONS="$(__sdkman_list_versions "$candidate" | grep " " | grep "\." | cut -c 6-)" + fi + # the last grep is used to filter out sdkman flags, such as: + # "+" - local version + # "*" - installed + # ">" - currently in use + CANDIDATE_VERSIONS="$(echo "$CANDIDATE_ONLINE_VERSIONS $CANDIDATE_LOCAL_VERSIONS" | tr ' ' '\n' | grep -v -e '^[[:space:]|\*|\>|\+]*$' | sort | uniq -u) " + fi } -__sdkman_cleanup_local_versions(){ +__sdkman_cleanup_local_versions() { - __sdkman_build_version_csv $1 | tr ',' ' ' + __sdkman_build_version_csv "$1" | tr ',' ' ' } diff --git a/completion/available/vault.completion.bash b/completion/available/vault.completion.bash index 7d082ee7..9520f166 100644 --- a/completion/available/vault.completion.bash +++ b/completion/available/vault.completion.bash @@ -1,4 +1,4 @@ -#!/usr/bin/env bash +# shellcheck shell=bash cite "about-completion" about-completion "vault completion" diff --git a/completion/available/vuejs.completion.bash b/completion/available/vuejs.completion.bash index 69794785..78c277db 100644 --- a/completion/available/vuejs.completion.bash +++ b/completion/available/vuejs.completion.bash @@ -1,14 +1,48 @@ #!/usr/bin/bash -if command -v vue > /dev/null; then +if _command_exists vue; then __vuejs_completion() { - local OPTS=("--version --help create add invoke inspect serve build ui init config upgrade info") - COMPREPLY=() - for _opt_ in ${OPTS[@]}; do - if [[ "$_opt_" == "$2"* ]]; then - COMPREPLY+=("$_opt_") - fi - done + local prev=$(_get_pword) + local curr=$(_get_cword) + + case $prev in + create) + COMPREPLY=($(compgen -W "-p -d -i -m -r -g -n -f -c -x -b -h --help --preset --default --inilinePreset --packageManager --registry --git --no-git --force --merge --clone --proxy --bare --skipGetStarted" -- "$curr")) + ;; + add|invoke) + COMPREPLY=($(compgen -W "--registry -h --help" -- "$curr")) + ;; + inspect) + COMPREPLY=($(compgen -W "-v --help --verbose --mode --rule --plugin --plugins --rules" -- "$curr")) + ;; + serve) + COMPREPLY=($(compgen -W "-o -h --help --open -c --copy -p --port" -- "$curr")) + ;; + build) + COMPREPLY=($(compgen -W "-t --target -n --name -d --dest -h --help" -- "$curr")) + ;; + ui) + COMPREPLY=($(compgen -W "-H --host -p --port -D --dev --quiet --headless -h --help" -- "$curr")) + ;; + init) + COMPREPLY=($(compgen -W "-c --clone --offline -h --help" -- "$curr")) + ;; + config) + COMPREPLY=($(compgen -W "-g --get -s --set -d --delete -e --edit --json -h --help" -- "$curr")) + ;; + outdated) + COMPREPLY=($(compgen -W "--next -h --help" -- "$curr")) + ;; + upgrade) + COMPREPLY=($(compgen -W "-t --to -f --from -r --registry --all --next -h --help" -- "$curr")) + ;; + migrate) + COMPREPLY=($(compgen -W "-f --from -h --help" -- "$curr")) + ;; + *) + COMPREPLY=($(compgen -W "-h --help -v --version create add invoke inspect serve build ui init config outdated upgrade migrate info" -- "$curr")) + ;; + esac } complete -F __vuejs_completion vue diff --git a/hooks/dot-bash.sh b/hooks/dot-bash.sh new file mode 100755 index 00000000..7a9dc8bc --- /dev/null +++ b/hooks/dot-bash.sh @@ -0,0 +1,21 @@ +#!/usr/bin/env bash + +exit_code=0 +for file in "$@"; do + # Confirm file is not executable + # + if [[ -x "${file}" ]]; then + echo "Bash include file \`${file}\` should not be executable" + exit_code=1 + fi + + # Confirm expected schellcheck header + # + LINE1="$(head -n 1 "${file}")" + if [[ "${LINE1}" != "# shellcheck shell=bash" ]]; then + echo "Bash include file \`${file}\` has bad/missing shellcheck header" + exit_code=1 + fi +done + +exit $exit_code diff --git a/hooks/dot-sh.sh b/hooks/dot-sh.sh new file mode 100755 index 00000000..3fa63216 --- /dev/null +++ b/hooks/dot-sh.sh @@ -0,0 +1,21 @@ +#!/usr/bin/env bash + +exit_code=0 +for file in "$@"; do + # Confirm file is executable + # + if [[ ! -x "${file}" ]]; then + echo "Bash file \`${file}\` is not executable" + exit_code=1 + fi + + # Confirm expected #! header + # + LINE1="$(head -n 1 "${file}")" + if [[ "${LINE1}" != "#!/usr/bin/env bash" ]]; then + echo "Bash file \`${file}\` has bad/missing #! header" + exit_code=1 + fi +done + +exit $exit_code diff --git a/lib/history.bash b/lib/history.bash deleted file mode 100644 index a1a7cb04..00000000 --- a/lib/history.bash +++ /dev/null @@ -1,12 +0,0 @@ -#!/usr/bin/env bash - -# Bash History Handling - -shopt -s histappend # append to bash_history if Terminal.app quits -export HISTCONTROL=${HISTCONTROL:-ignorespace:erasedups} # erase duplicates; alternative option: export HISTCONTROL=ignoredups -export HISTSIZE=${HISTSIZE:-5000} # resize history size -export AUTOFEATURE=${AUTOFEATURE:-true autotest} # Cucumber / Autotest integration - -function rh { - history | awk '{a[$2]++}END{for(i in a){print a[i] " " i}}' | sort -rn | head -} diff --git a/plugins/available/basher.plugin.bash b/plugins/available/basher.plugin.bash index d226ffcb..2c77cbfa 100644 --- a/plugins/available/basher.plugin.bash +++ b/plugins/available/basher.plugin.bash @@ -1,3 +1,4 @@ +# shellcheck shell=bash cite about-plugin about-plugin 'initializes basher, the shell package manager' diff --git a/plugins/available/history-search.plugin.bash b/plugins/available/history-search.plugin.bash new file mode 100644 index 00000000..ea02eb74 --- /dev/null +++ b/plugins/available/history-search.plugin.bash @@ -0,0 +1,10 @@ +# shellcheck shell=bash +cite about-plugin +about-plugin 'search history using the prefix already entered' + +# enter a few characters and press UpArrow/DownArrow +# to search backwards/forwards through the history +if [[ ${SHELLOPTS} =~ (vi|emacs) ]]; then + bind '"\e[A":history-search-backward' + bind '"\e[B":history-search-forward' +fi diff --git a/plugins/available/history-substring-search.plugin.bash b/plugins/available/history-substring-search.plugin.bash new file mode 100644 index 00000000..e0e37f43 --- /dev/null +++ b/plugins/available/history-substring-search.plugin.bash @@ -0,0 +1,10 @@ +# shellcheck shell=bash +cite about-plugin +about-plugin 'search history using the substring already entered' + +# enter a few characters and press UpArrow/DownArrow +# to search backwards/forwards through the history +if [[ ${SHELLOPTS} =~ (vi|emacs) ]]; then + bind '"\e[A":history-substring-search-backward' + bind '"\e[B":history-substring-search-forward' +fi diff --git a/plugins/available/history.plugin.bash b/plugins/available/history.plugin.bash index 528548ef..08ca8de6 100644 --- a/plugins/available/history.plugin.bash +++ b/plugins/available/history.plugin.bash @@ -1,9 +1,39 @@ +# shellcheck shell=bash cite about-plugin -about-plugin 'history manipulation' -# enter a few characters and press UpArrow/DownArrow -# to search backwards/forwards through the history -if [[ ${SHELLOPTS} =~ (vi|emacs) ]] -then - bind '"":history-search-backward' - bind '"":history-search-forward' -fi +about-plugin 'improve history handling with sane defaults' + +# append to bash_history if Terminal.app quits +shopt -s histappend + +# erase duplicates; alternative option: export HISTCONTROL=ignoredups +export HISTCONTROL=${HISTCONTROL:-ignorespace:erasedups} + +# resize history to 100x the default (500) +export HISTSIZE=${HISTSIZE:-50000} + +top-history() { + about 'print the name and count of the most commonly run tools' + + if [[ -n $HISTTIMEFORMAT ]]; then + # To parse history we need a predictable format, which HISTTIMEFORMAT + # gets in the way of. So we unset it and set a trap to guarantee the + # user's environment returns to normal even if the pipeline below fails. + # shellcheck disable=SC2064 + trap "export HISTTIMEFORMAT='$HISTTIMEFORMAT'" RETURN + unset HISTTIMEFORMAT + fi + + history \ + | awk '{ + a[$2]++ + }END{ + for(i in a) + printf("%s\t%s\n", a[i], i) + }' \ + | sort --reverse --numeric-sort \ + | head \ + | column \ + --table \ + --table-columns 'Command Count,Command Name' \ + --output-separator ' | ' +} diff --git a/themes/90210/90210.theme.bash b/themes/90210/90210.theme.bash index 97c23f0e..180764c8 100644 --- a/themes/90210/90210.theme.bash +++ b/themes/90210/90210.theme.bash @@ -1,4 +1,4 @@ -#!/usr/bin/env bash +# shellcheck shell=bash SCM_THEME_PROMPT_DIRTY=" ${red}✗" SCM_THEME_PROMPT_CLEAN=" ${bold_green}✓" SCM_THEME_PROMPT_PREFIX=" |" diff --git a/themes/agnoster/agnoster.theme.bash b/themes/agnoster/agnoster.theme.bash index 1f3a5acb..ba3e2c9a 100644 --- a/themes/agnoster/agnoster.theme.bash +++ b/themes/agnoster/agnoster.theme.bash @@ -1,4 +1,4 @@ -#!/usr/bin/env bash +# shellcheck shell=bash # vim: ft=bash ts=2 sw=2 sts=2 # # agnoster's Theme - https://gist.github.com/3712874 diff --git a/themes/atomic/atomic.theme.bash b/themes/atomic/atomic.theme.bash index 129bcbb6..fb4e15af 100644 --- a/themes/atomic/atomic.theme.bash +++ b/themes/atomic/atomic.theme.bash @@ -1,4 +1,4 @@ -#!/usr/bin/env bash +# shellcheck shell=bash # Atomic Bash Prompt for Bash-it # By lfelipe base on the theme brainy of MunifTanjim @@ -28,79 +28,79 @@ Face="\342\230\273" ############# ____atomic_top_left_parse() { - ifs_old="${IFS}" - IFS="|" - args=( $1 ) - IFS="${ifs_old}" - if [ -n "${args[3]}" ]; then - _TOP_LEFT+="${args[2]}${args[3]}" - fi - _TOP_LEFT+="${args[0]}${args[1]}" - if [ -n "${args[4]}" ]; then - _TOP_LEFT+="${args[2]}${args[4]}" - fi - _TOP_LEFT+="" + ifs_old="${IFS}" + IFS="|" + read -r -a args <<< "$@" + IFS="${ifs_old}" + if [ -n "${args[3]}" ]; then + _TOP_LEFT+="${args[2]}${args[3]}" + fi + _TOP_LEFT+="${args[0]}${args[1]}" + if [ -n "${args[4]}" ]; then + _TOP_LEFT+="${args[2]}${args[4]}" + fi + _TOP_LEFT+="" } ____atomic_top_right_parse() { - ifs_old="${IFS}" - IFS="|" - args=( $1 ) - IFS="${ifs_old}" - _TOP_RIGHT+=" " - if [ -n "${args[3]}" ]; then - _TOP_RIGHT+="${args[2]}${args[3]}" - fi - _TOP_RIGHT+="${args[0]}${args[1]}" - 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 )) + ifs_old="${IFS}" + IFS="|" + read -r -a args <<< "$@" + IFS="${ifs_old}" + _TOP_RIGHT+=" " + if [ -n "${args[3]}" ]; then + _TOP_RIGHT+="${args[2]}${args[3]}" + fi + _TOP_RIGHT+="${args[0]}${args[1]}" + 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)) } ____atomic_bottom_parse() { - ifs_old="${IFS}" - IFS="|" - args=( $1 ) - IFS="${ifs_old}" - _BOTTOM+="${args[0]}${args[1]}" - [ ${#args[1]} -gt 0 ] && _BOTTOM+=" " + ifs_old="${IFS}" + IFS="|" + read -r -a args <<< "$@" + IFS="${ifs_old}" + _BOTTOM+="${args[0]}${args[1]}" + [ ${#args[1]} -gt 0 ] && _BOTTOM+=" " } ____atomic_top() { - _TOP_LEFT="" - _TOP_RIGHT="" - __TOP_RIGHT_LEN=0 - __SEG_AT_RIGHT=0 + _TOP_LEFT="" + _TOP_RIGHT="" + __TOP_RIGHT_LEN=0 + __SEG_AT_RIGHT=0 - for seg in ${___ATOMIC_TOP_LEFT}; do - info="$(___atomic_prompt_"${seg}")" - [ -n "${info}" ] && ____atomic_top_left_parse "${info}" - done + for seg in ${___ATOMIC_TOP_LEFT}; do + info="$(___atomic_prompt_"${seg}")" + [ -n "${info}" ] && ____atomic_top_left_parse "${info}" + done - ___cursor_right="\e[500C" - _TOP_LEFT+="${___cursor_right}" + ___cursor_right="\e[500C" + _TOP_LEFT+="${___cursor_right}" - for seg in ${___ATOMIC_TOP_RIGHT}; do - info="$(___atomic_prompt_"${seg}")" - [ -n "${info}" ] && ____atomic_top_right_parse "${info}" - done + for seg in ${___ATOMIC_TOP_RIGHT}; do + info="$(___atomic_prompt_"${seg}")" + [ -n "${info}" ] && ____atomic_top_right_parse "${info}" + done - [ $__TOP_RIGHT_LEN -gt 0 ] && __TOP_RIGHT_LEN=$(( __TOP_RIGHT_LEN - 0 )) - ___cursor_adjust="\e[${__TOP_RIGHT_LEN}D" - _TOP_LEFT+="${___cursor_adjust}" + [ $__TOP_RIGHT_LEN -gt 0 ] && __TOP_RIGHT_LEN=$((__TOP_RIGHT_LEN - 0)) + ___cursor_adjust="\e[${__TOP_RIGHT_LEN}D" + _TOP_LEFT+="${___cursor_adjust}" - printf "%s%s" "${_TOP_LEFT}" "${_TOP_RIGHT}" + printf "%s%s" "${_TOP_LEFT}" "${_TOP_RIGHT}" } ____atomic_bottom() { - _BOTTOM="" - for seg in $___ATOMIC_BOTTOM; do - info="$(___atomic_prompt_"${seg}")" - [ -n "${info}" ] && ____atomic_bottom_parse "${info}" - done - printf "\n%s" "${_BOTTOM}" + _BOTTOM="" + for seg in $___ATOMIC_BOTTOM; do + info="$(___atomic_prompt_"${seg}")" + [ -n "${info}" ] && ____atomic_bottom_parse "${info}" + done + printf "\n%s" "${_BOTTOM}" } ############## @@ -108,97 +108,97 @@ ____atomic_bottom() { ############## ___atomic_prompt_user_info() { - color=$white - box="${normal}${LineA}\$([[ \$? != 0 ]] && echo \"${BIWhite}[${IRed}${SX}${BIWhite}]${normal}${Line}\")${Line}${BIWhite}[|${BIWhite}]${normal}${Line}" - info="${IYellow}\u${IRed}@${IGreen}\h" + color=$white + box="${normal}${LineA}\$([[ \$? != 0 ]] && echo \"${BIWhite}[${IRed}${SX}${BIWhite}]${normal}${Line}\")${Line}${BIWhite}[|${BIWhite}]${normal}${Line}" + info="${IYellow}\u${IRed}@${IGreen}\h" - printf "%s|%s|%s|%s" "${color}" "${info}" "${white}" "${box}" + printf "%s|%s|%s|%s" "${color}" "${info}" "${white}" "${box}" } ___atomic_prompt_dir() { - color=${IRed} - box="[|]${normal}" - info="\w" - printf "%s|%s|%s|%s" "${color}" "${info}" "${bold_white}" "${box}" + color=${IRed} + box="[|]${normal}" + info="\w" + printf "%s|%s|%s|%s" "${color}" "${info}" "${bold_white}" "${box}" } ___atomic_prompt_scm() { - [ "${THEME_SHOW_SCM}" != "true" ] && return - color=$bold_green - box="${Line}[${IWhite}$(scm_char)] " - info="$(scm_prompt_info)" - printf "%s|%s|%s|%s" "${color}" "${info}" "${bold_white}" "${box}" + [ "${THEME_SHOW_SCM}" != "true" ] && return + color=$bold_green + box="${Line}[${IWhite}$(scm_char)] " + info="$(scm_prompt_info)" + printf "%s|%s|%s|%s" "${color}" "${info}" "${bold_white}" "${box}" } ___atomic_prompt_python() { - [ "${THEME_SHOW_PYTHON}" != "true" ] && return - color=$bold_yellow - box="[|]" - info="$(python_version_prompt)" - printf "%s|%s|%s|%s" "${color}" "${info}" "${bold_blue}" "${box}" + [ "${THEME_SHOW_PYTHON}" != "true" ] && return + color=$bold_yellow + box="[|]" + info="$(python_version_prompt)" + printf "%s|%s|%s|%s" "${color}" "${info}" "${bold_blue}" "${box}" } ___atomic_prompt_ruby() { - [ "${THEME_SHOW_RUBY}" != "true" ] && return - color=$bold_white - box="[|]" - info="rb-$(ruby_version_prompt)" - printf "%s|%s|%s|%s" "${color}" "${info}" "${bold_red}" "${box}" + [ "${THEME_SHOW_RUBY}" != "true" ] && return + color=$bold_white + box="[|]" + info="rb-$(ruby_version_prompt)" + printf "%s|%s|%s|%s" "${color}" "${info}" "${bold_red}" "${box}" } ___atomic_prompt_todo() { - [ "${THEME_SHOW_TODO}" != "true" ] || - [ -z "$(which todo.sh)" ] && return - color=$bold_white - box="[|]" - 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}" + [ "${THEME_SHOW_TODO}" != "true" ] \ + || [ -z "$(which todo.sh)" ] && return + color=$bold_white + box="[|]" + info="t:$(todo.sh ls | grep -E "TODO: [0-9]+ of ([0-9]+)" | awk '{ print $4 }')" + printf "%s|%s|%s|%s" "${color}" "${info}" "${bold_green}" "${box}" } ___atomic_prompt_clock() { - [ "${THEME_SHOW_CLOCK}" != "true" ] && return - color=$THEME_CLOCK_COLOR - box="[|]" - info="$(date +"${THEME_CLOCK_FORMAT}")" - printf "%s|%s|%s|%s" "${color}" "${info}" "${bold_white}" "${box}" + [ "${THEME_SHOW_CLOCK}" != "true" ] && return + color=$THEME_CLOCK_COLOR + box="[|]" + info="$(date +"${THEME_CLOCK_FORMAT}")" + printf "%s|%s|%s|%s" "${color}" "${info}" "${bold_white}" "${box}" } ___atomic_prompt_battery() { - ! _command_exists battery_percentage || - [ "${THEME_SHOW_BATTERY}" != "true" ] || - [ "$(battery_percentage)" = "no" ] && return + ! _command_exists battery_percentage \ + || [ "${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 - color=$bold_yellow - elif [ "$batp" -eq 25 ] || [ "$batp" -lt 25 ]; then - color=$IRed - fi - box="[|]" - ac_adapter_connected && info="+" - ac_adapter_disconnected && info="-" - info+=$batp - [ "$batp" -eq 100 ] || [ "$batp" -gt 100 ] && info="AC" - printf "%s|%s|%s|%s" "${color}" "${info}" "${bold_white}" "${box}" + batp=$(battery_percentage) + if [ "$batp" -eq 50 ] || [ "$batp" -gt 50 ]; then + color=$bold_green + elif [ "$batp" -lt 50 ] && [ "$batp" -gt 25 ]; then + color=$bold_yellow + elif [ "$batp" -eq 25 ] || [ "$batp" -lt 25 ]; then + color=$IRed + fi + box="[|]" + ac_adapter_connected && info="+" + ac_adapter_disconnected && info="-" + info+=$batp + [ "$batp" -eq 100 ] || [ "$batp" -gt 100 ] && info="AC" + printf "%s|%s|%s|%s" "${color}" "${info}" "${bold_white}" "${box}" } ___atomic_prompt_exitcode() { - [ "${THEME_SHOW_EXITCODE}" != "true" ] && return - color=$bold_purple - [ "$exitcode" -ne 0 ] && printf "%s|%s" "${color}" "${exitcode}" + [ "${THEME_SHOW_EXITCODE}" != "true" ] && return + color=$bold_purple + [ "$exitcode" -ne 0 ] && printf "%s|%s" "${color}" "${exitcode}" } ___atomic_prompt_char() { - color=$white - prompt_char="${__ATOMIC_PROMPT_CHAR_PS1}" - if [ "${THEME_SHOW_SUDO}" == "true" ]; then - if sudo -vn 1>/dev/null 2>&1; then - prompt_char="${__ATOMIC_PROMPT_CHAR_PS1_SUDO}" - fi - fi - printf "%s|%s" "${color}" "${prompt_char}" + color=$white + prompt_char="${__ATOMIC_PROMPT_CHAR_PS1}" + if [ "${THEME_SHOW_SUDO}" == "true" ]; then + if sudo -vn 1> /dev/null 2>&1; then + prompt_char="${__ATOMIC_PROMPT_CHAR_PS1_SUDO}" + fi + fi + printf "%s|%s" "${color}" "${prompt_char}" } ######### @@ -206,54 +206,56 @@ ___atomic_prompt_char() { ######### __atomic_show() { - typeset _seg=${1:-} - shift - export THEME_SHOW_${_seg}=true + typeset _seg=${1:-} + shift + export "THEME_SHOW_${_seg}"=true } __atomic_hide() { - typeset _seg=${1:-} - shift - export THEME_SHOW_${_seg}=false + typeset _seg=${1:-} + shift + export "THEME_SHOW_${_seg}"=false } _atomic_completion() { - local cur _action actions segments - COMPREPLY=() - cur="${COMP_WORDS[COMP_CWORD]}" - _action="${COMP_WORDS[1]}" - actions="show hide" - segments="battery clock exitcode python ruby scm sudo todo" - case "${_action}" in - show) - COMPREPLY=( $(compgen -W "${segments}" -- "${cur}") ) - return 0 - ;; - hide) - COMPREPLY=( $(compgen -W "${segments}" -- "${cur}") ) - return 0 - ;; - esac + local cur _action actions segments + COMPREPLY=() + cur="${COMP_WORDS[COMP_CWORD]}" + _action="${COMP_WORDS[1]}" + actions="show hide" + segments="battery clock exitcode python ruby scm sudo todo" + case "${_action}" in + show) + read -r -a COMPREPLY <<< "$(compgen -W "${segments}" -- "${cur}")" + return 0 + ;; + hide) + read -r -a COMPREPLY <<< "$(compgen -W "${segments}" -- "${cur}")" + return 0 + ;; + esac - COMPREPLY=( $(compgen -W "${actions}" -- "${cur}") ) - return 0 + read -r -a COMPREPLY <<< "$(compgen -W "${actions}" -- "${cur}")" + return 0 } atomic() { - typeset action=${1:-} - shift - typeset segs=${*:-} - typeset func - case $action in - show) - func=__atomic_show;; - hide) - func=__atomic_hide;; - esac - for seg in ${segs}; do - seg=$(printf "%s" "${seg}" | tr '[:lower:]' '[:upper:]') - $func "${seg}" - done + typeset action=${1:-} + shift + typeset segs=${*:-} + typeset func + case $action in + show) + func=__atomic_show + ;; + hide) + func=__atomic_hide + ;; + esac + for seg in ${segs}; do + seg=$(printf "%s" "${seg}" | tr '[:lower:]' '[:upper:]') + $func "${seg}" + done } complete -F _atomic_completion atomic @@ -302,19 +304,19 @@ ___ATOMIC_BOTTOM=${___ATOMIC_BOTTOM:-"char"} ############ __atomic_ps1() { - printf "%s%s%s" "$(____atomic_top)" "$(____atomic_bottom)" "${normal}" + printf "%s%s%s" "$(____atomic_top)" "$(____atomic_bottom)" "${normal}" } __atomic_ps2() { - color=$bold_white - printf "%s%s%s" "${color}" "${__ATOMIC_PROMPT_CHAR_PS2} " "${normal}" + color=$bold_white + printf "%s%s%s" "${color}" "${__ATOMIC_PROMPT_CHAR_PS2} " "${normal}" } _atomic_prompt() { - exitcode="$?" + exitcode="$?" - PS1="$(__atomic_ps1)" - PS2="$(__atomic_ps2)" + PS1="$(__atomic_ps1)" + PS2="$(__atomic_ps2)" } safe_append_prompt_command _atomic_prompt diff --git a/themes/axin/axin.theme.bash b/themes/axin/axin.theme.bash index d5e91753..7e90aded 100644 --- a/themes/axin/axin.theme.bash +++ b/themes/axin/axin.theme.bash @@ -1,36 +1,36 @@ -#!/usr/bin/env bash +# shellcheck shell=bash # Axin Bash Prompt, inspired by theme "Sexy" and "Bobby" # thanks to them if tput setaf 1 &> /dev/null; then - if [[ $(tput colors) -ge 256 ]] 2>/dev/null; then - MAGENTA=$(tput setaf 9) - ORANGE=$(tput setaf 172) - GREEN=$(tput setaf 190) - PURPLE=$(tput setaf 141) - WHITE=$(tput setaf 0) - else - MAGENTA=$(tput setaf 5) - ORANGE=$(tput setaf 4) - GREEN=$(tput setaf 2) - PURPLE=$(tput setaf 1) - WHITE=$(tput setaf 7) - fi - BOLD=$(tput bold) - RESET=$(tput sgr0) + if [[ $(tput colors) -ge 256 ]] 2> /dev/null; then + MAGENTA=$(tput setaf 9) + ORANGE=$(tput setaf 172) + GREEN=$(tput setaf 190) + PURPLE=$(tput setaf 141) + WHITE=$(tput setaf 0) + else + MAGENTA=$(tput setaf 5) + ORANGE=$(tput setaf 4) + GREEN=$(tput setaf 2) + PURPLE=$(tput setaf 1) + WHITE=$(tput setaf 7) + fi + BOLD=$(tput bold) + RESET=$(tput sgr0) else - MAGENTA="\033[1;31m" - ORANGE="\033[1;33m" - GREEN="\033[1;32m" - PURPLE="\033[1;35m" - WHITE="\033[1;37m" - BOLD="" - RESET="\033[m" + MAGENTA="\033[1;31m" + ORANGE="\033[1;33m" + GREEN="\033[1;32m" + PURPLE="\033[1;35m" + WHITE="\033[1;37m" + BOLD="" + RESET="\033[m" fi function prompt_command() { - PS1="\[${BOLD}${MAGENTA}\]\u \[$WHITE\]@ \[$ORANGE\]\h \[$WHITE\]in \[$GREEN\]\w\[$WHITE\]\[$SCM_THEME_PROMPT_PREFIX\]$(clock_prompt) \[$PURPLE\]$(scm_prompt_info) \n\$ \[$RESET\]" + PS1="\[${BOLD}${MAGENTA}\]\u \[$WHITE\]@ \[$ORANGE\]\h \[$WHITE\]in \[$GREEN\]\w\[$WHITE\]\[$SCM_THEME_PROMPT_PREFIX\]$(clock_prompt) \[$PURPLE\]$(scm_prompt_info) \n\$ \[$RESET\]" } THEME_CLOCK_COLOR=${THEME_CLOCK_COLOR:-"${white}"} diff --git a/themes/barbuk/barbuk.theme.bash b/themes/barbuk/barbuk.theme.bash index c7229997..8e09d4be 100644 --- a/themes/barbuk/barbuk.theme.bash +++ b/themes/barbuk/barbuk.theme.bash @@ -1,5 +1,4 @@ -#!/usr/bin/env bash -# shellcheck disable=2034,2154 +# shellcheck shell=bash # Theme custom glyphs SCM_GIT_CHAR_GITLAB=${BARBUK_GITLAB_CHAR:=' '} diff --git a/themes/base.theme.bash b/themes/base.theme.bash index 58246720..30305957 100644 --- a/themes/base.theme.bash +++ b/themes/base.theme.bash @@ -1,4 +1,4 @@ -#!/usr/bin/env bash +# shellcheck shell=bash CLOCK_CHAR_THEME_PROMPT_PREFIX='' CLOCK_CHAR_THEME_PROMPT_SUFFIX='' @@ -87,219 +87,235 @@ 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) +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 +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 - elif [[ -f .git/HEAD ]] && [[ -x "$GIT_EXE" ]]; then SCM=$SCM_GIT - elif [[ -x "$GIT_EXE" ]] && [[ -n "$(git rev-parse --is-inside-work-tree 2> /dev/null)" ]]; then SCM=$SCM_GIT - elif [[ -x "$P4_EXE" ]] && [[ -n "$(p4 set P4CLIENT 2> /dev/null)" ]]; then SCM=$SCM_P4 - elif [[ -d .hg ]] && [[ -x "$HG_EXE" ]]; then SCM=$SCM_HG - elif [[ -x "$HG_EXE" ]] && [[ -n "$(hg root 2> /dev/null)" ]]; then SCM=$SCM_HG - elif [[ -d .svn ]] && [[ -x "$SVN_EXE" ]]; then SCM=$SCM_SVN - elif [[ -x "$SVN_EXE" ]] && [[ -n "$(svn info --show-item wc-root 2>/dev/null)" ]]; then SCM=$SCM_SVN - else SCM=$SCM_NONE - fi + if [[ "$SCM_CHECK" = false ]]; then + SCM=$SCM_NONE + elif [[ -f .git/HEAD ]] && [[ -x "$GIT_EXE" ]]; then + SCM=$SCM_GIT + elif [[ -x "$GIT_EXE" ]] && [[ -n "$(git rev-parse --is-inside-work-tree 2> /dev/null)" ]]; then + SCM=$SCM_GIT + elif [[ -x "$P4_EXE" ]] && [[ -n "$(p4 set P4CLIENT 2> /dev/null)" ]]; then + SCM=$SCM_P4 + elif [[ -d .hg ]] && [[ -x "$HG_EXE" ]]; then + SCM=$SCM_HG + elif [[ -x "$HG_EXE" ]] && [[ -n "$(hg root 2> /dev/null)" ]]; then + SCM=$SCM_HG + elif [[ -d .svn ]] && [[ -x "$SVN_EXE" ]]; then + SCM=$SCM_SVN + elif [[ -x "$SVN_EXE" ]] && [[ -n "$(svn info --show-item wc-root 2> /dev/null)" ]]; then + SCM=$SCM_SVN + else + SCM=$SCM_NONE + fi } function scm_prompt_char { - if [[ -z $SCM ]]; then scm; fi - if [[ $SCM == $SCM_GIT ]]; then SCM_CHAR=$SCM_GIT_CHAR - elif [[ $SCM == $SCM_P4 ]]; then SCM_CHAR=$SCM_P4_CHAR - elif [[ $SCM == $SCM_HG ]]; then SCM_CHAR=$SCM_HG_CHAR - elif [[ $SCM == $SCM_SVN ]]; then SCM_CHAR=$SCM_SVN_CHAR - else SCM_CHAR=$SCM_NONE_CHAR - fi + if [[ -z $SCM ]]; then scm; fi + if [[ $SCM == "$SCM_GIT" ]]; then + SCM_CHAR=$SCM_GIT_CHAR + elif [[ $SCM == "$SCM_P4" ]]; then + SCM_CHAR=$SCM_P4_CHAR + elif [[ $SCM == "$SCM_HG" ]]; then + SCM_CHAR=$SCM_HG_CHAR + elif [[ $SCM == "$SCM_SVN" ]]; then + SCM_CHAR=$SCM_SVN_CHAR + else + SCM_CHAR=$SCM_NONE_CHAR + fi } function scm_prompt_vars { - scm - scm_prompt_char - SCM_DIRTY=0 - SCM_STATE='' - [[ $SCM == $SCM_GIT ]] && git_prompt_vars && return - [[ $SCM == $SCM_P4 ]] && p4_prompt_vars && return - [[ $SCM == $SCM_HG ]] && hg_prompt_vars && return - [[ $SCM == $SCM_SVN ]] && svn_prompt_vars && return + scm + scm_prompt_char + SCM_DIRTY=0 + SCM_STATE='' + [[ $SCM == "$SCM_GIT" ]] && git_prompt_vars && return + [[ $SCM == "$SCM_P4" ]] && p4_prompt_vars && return + [[ $SCM == "$SCM_HG" ]] && hg_prompt_vars && return + [[ $SCM == "$SCM_SVN" ]] && svn_prompt_vars && return } function scm_prompt_info { - scm - scm_prompt_char - scm_prompt_info_common + scm + scm_prompt_char + scm_prompt_info_common } function scm_prompt_char_info { - scm_prompt_char - echo -ne "${SCM_THEME_CHAR_PREFIX}${SCM_CHAR}${SCM_THEME_CHAR_SUFFIX}" - scm_prompt_info_common + scm_prompt_char + echo -ne "${SCM_THEME_CHAR_PREFIX}${SCM_CHAR}${SCM_THEME_CHAR_SUFFIX}" + scm_prompt_info_common } function scm_prompt_info_common { - SCM_DIRTY=0 - SCM_STATE='' + SCM_DIRTY=0 + SCM_STATE='' - if [[ ${SCM} == ${SCM_GIT} ]]; then - if [[ ${SCM_GIT_SHOW_MINIMAL_INFO} == true ]]; then - # user requests minimal git status information - git_prompt_minimal_info - else - # more detailed git status - git_prompt_info - fi - return - fi + if [[ ${SCM} == "${SCM_GIT}" ]]; then + if [[ ${SCM_GIT_SHOW_MINIMAL_INFO} == true ]]; then + # user requests minimal git status information + git_prompt_minimal_info + else + # more detailed git status + git_prompt_info + fi + return + fi - # TODO: consider adding minimal status information for hg and svn - { [[ ${SCM} == ${SCM_P4} ]] && p4_prompt_info && return; } || true - { [[ ${SCM} == ${SCM_HG} ]] && hg_prompt_info && return; } || true - { [[ ${SCM} == ${SCM_SVN} ]] && svn_prompt_info && return; } || true + # TODO: consider adding minimal status information for hg and svn + { [[ ${SCM} == "${SCM_P4}" ]] && p4_prompt_info && return; } || true + { [[ ${SCM} == "${SCM_HG}" ]] && hg_prompt_info && return; } || true + { [[ ${SCM} == "${SCM_SVN}" ]] && svn_prompt_info && return; } || true } function terraform_workspace_prompt { - if _command_exists terraform ; then - if [ -d .terraform ]; then - echo -e "$(terraform workspace show 2>/dev/null)" - fi - fi + if _command_exists terraform; then + if [ -d .terraform ]; then + echo -e "$(terraform workspace show 2> /dev/null)" + fi + fi } function git_prompt_minimal_info { - SCM_STATE=${SCM_THEME_PROMPT_CLEAN} + SCM_STATE=${SCM_THEME_PROMPT_CLEAN} - _git-hide-status && return + _git-hide-status && return - SCM_BRANCH="${SCM_THEME_BRANCH_PREFIX}\$(_git-friendly-ref)" + SCM_BRANCH="${SCM_THEME_BRANCH_PREFIX}\$(_git-friendly-ref)" - if [[ -n "$(_git-status | tail -n1)" ]]; then - SCM_DIRTY=1 - SCM_STATE=${SCM_THEME_PROMPT_DIRTY} - fi + if [[ -n "$(_git-status | tail -n1)" ]]; then + SCM_DIRTY=1 + SCM_STATE=${SCM_THEME_PROMPT_DIRTY} + fi - # Output the git prompt - SCM_PREFIX=${SCM_THEME_PROMPT_PREFIX} - SCM_SUFFIX=${SCM_THEME_PROMPT_SUFFIX} - echo -e "${SCM_PREFIX}${SCM_BRANCH}${SCM_STATE}${SCM_SUFFIX}" + # Output the git prompt + SCM_PREFIX=${SCM_THEME_PROMPT_PREFIX} + SCM_SUFFIX=${SCM_THEME_PROMPT_SUFFIX} + echo -e "${SCM_PREFIX}${SCM_BRANCH}${SCM_STATE}${SCM_SUFFIX}" } 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 ${SCM_GIT_USE_GITSTATUS} && _command_exists gitstatus_query && gitstatus_query && [[ "${VCS_STATUS_RESULT}" == "ok-sync" ]]; then + # we can use faster gitstatus + # use this variable in githelpers and below to choose gitstatus output + SCM_GIT_GITSTATUS_RAN=true + 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)" - else - SCM_GIT_DETACHED="true" + if _git-branch &> /dev/null; then + SCM_GIT_DETACHED="false" + SCM_BRANCH="${SCM_THEME_BRANCH_PREFIX}\$(_git-friendly-ref)$(_git-remote-info)" + else + SCM_GIT_DETACHED="true" - local detached_prefix - if _git-tag &> /dev/null; then - detached_prefix=${SCM_THEME_TAG_PREFIX} - else - detached_prefix=${SCM_THEME_DETACHED_PREFIX} - fi - SCM_BRANCH="${detached_prefix}\$(_git-friendly-ref)" - fi + local detached_prefix + if _git-tag &> /dev/null; then + detached_prefix=${SCM_THEME_TAG_PREFIX} + else + detached_prefix=${SCM_THEME_DETACHED_PREFIX} + fi + SCM_BRANCH="${detached_prefix}\$(_git-friendly-ref)" + fi - 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}" - fi - if [[ "${commits_behind}" -gt 0 ]]; then - SCM_BRANCH+="${SCM_GIT_AHEAD_BEHIND_PREFIX_CHAR}${SCM_GIT_BEHIND_CHAR}" - [[ "${SCM_GIT_SHOW_COMMIT_COUNT}" = "true" ]] && SCM_BRANCH+="${commits_behind}" - fi + 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}" + fi + if [[ "${commits_behind}" -gt 0 ]]; then + SCM_BRANCH+="${SCM_GIT_AHEAD_BEHIND_PREFIX_CHAR}${SCM_GIT_BEHIND_CHAR}" + [[ "${SCM_GIT_SHOW_COMMIT_COUNT}" = "true" ]] && SCM_BRANCH+="${commits_behind}" + fi - if [[ "${SCM_GIT_SHOW_STASH_INFO}" = "true" ]]; then - local stash_count - 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 + if [[ "${SCM_GIT_SHOW_STASH_INFO}" = "true" ]]; then + local stash_count + 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 - 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 - [[ "${staged_count}" -gt 0 ]] && SCM_BRANCH+=" ${SCM_GIT_STAGED_CHAR}${staged_count}" && SCM_DIRTY=3 - [[ "${unstaged_count}" -gt 0 ]] && SCM_BRANCH+=" ${SCM_GIT_UNSTAGED_CHAR}${unstaged_count}" && SCM_DIRTY=2 - [[ "${untracked_count}" -gt 0 ]] && SCM_BRANCH+=" ${SCM_GIT_UNTRACKED_CHAR}${untracked_count}" && SCM_DIRTY=1 - fi - SCM_STATE=${GIT_THEME_PROMPT_DIRTY:-$SCM_THEME_PROMPT_DIRTY} - fi - fi + SCM_STATE=${GIT_THEME_PROMPT_CLEAN:-$SCM_THEME_PROMPT_CLEAN} + if ! _git-hide-status; then + 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 + [[ "${staged_count}" -gt 0 ]] && SCM_BRANCH+=" ${SCM_GIT_STAGED_CHAR}${staged_count}" && SCM_DIRTY=3 + [[ "${unstaged_count}" -gt 0 ]] && SCM_BRANCH+=" ${SCM_GIT_UNSTAGED_CHAR}${unstaged_count}" && SCM_DIRTY=2 + [[ "${untracked_count}" -gt 0 ]] && SCM_BRANCH+=" ${SCM_GIT_UNTRACKED_CHAR}${untracked_count}" && SCM_DIRTY=1 + fi + SCM_STATE=${GIT_THEME_PROMPT_DIRTY:-$SCM_THEME_PROMPT_DIRTY} + 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)" + # 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} - SCM_SUFFIX=${GIT_THEME_PROMPT_SUFFIX:-$SCM_THEME_PROMPT_SUFFIX} + SCM_PREFIX=${GIT_THEME_PROMPT_PREFIX:-$SCM_THEME_PROMPT_PREFIX} + SCM_SUFFIX=${GIT_THEME_PROMPT_SUFFIX:-$SCM_THEME_PROMPT_SUFFIX} - SCM_CHANGE=$(_git-short-sha 2>/dev/null || echo "") + SCM_CHANGE=$(_git-short-sha 2> /dev/null || echo "") } function p4_prompt_vars { - IFS=$'\t' read -r \ - opened_count non_default_changes default_count \ - add_file_count edit_file_count delete_file_count \ - <<< "$(_p4-opened-counts)" - if [[ "${opened_count}" -gt 0 ]]; then - SCM_DIRTY=1 - SCM_STATE=${SCM_THEME_PROMPT_DIRTY} - [[ "${opened_count}" -gt 0 ]] && SCM_BRANCH+=" ${SCM_P4_OPENED_CHAR}${opened_count}" - [[ "${non_default_changes}" -gt 0 ]] && SCM_BRANCH+=" ${SCM_P4_CHANGES_CHAR}${non_default_changes}" - [[ "${default_count}" -gt 0 ]] && SCM_BRANCH+=" ${SCM_P4_DEFAULT_CHAR}${default_count}" - else - SCM_DIRTY=0 - SCM_STATE=${SCM_THEME_PROMPT_DIRTY} - fi + IFS=$'\t' read -r \ + opened_count non_default_changes default_count \ + add_file_count edit_file_count delete_file_count \ + <<< "$(_p4-opened-counts)" + if [[ "${opened_count}" -gt 0 ]]; then + SCM_DIRTY=1 + SCM_STATE=${SCM_THEME_PROMPT_DIRTY} + [[ "${opened_count}" -gt 0 ]] && SCM_BRANCH+=" ${SCM_P4_OPENED_CHAR}${opened_count}" + [[ "${non_default_changes}" -gt 0 ]] && SCM_BRANCH+=" ${SCM_P4_CHANGES_CHAR}${non_default_changes}" + [[ "${default_count}" -gt 0 ]] && SCM_BRANCH+=" ${SCM_P4_DEFAULT_CHAR}${default_count}" + else + SCM_DIRTY=0 + SCM_STATE=${SCM_THEME_PROMPT_DIRTY} + fi - SCM_PREFIX=${P4_THEME_PROMPT_PREFIX:-$SCM_THEME_PROMPT_PREFIX} - SCM_SUFFIX=${P4_THEME_PROMPT_SUFFIX:-$SCM_THEME_PROMPT_SUFFIX} + SCM_PREFIX=${P4_THEME_PROMPT_PREFIX:-$SCM_THEME_PROMPT_PREFIX} + SCM_SUFFIX=${P4_THEME_PROMPT_SUFFIX:-$SCM_THEME_PROMPT_SUFFIX} } function svn_prompt_vars { - if [[ -n $(svn status |head -c1 2> /dev/null) ]]; then - SCM_DIRTY=1 - SCM_STATE=${SVN_THEME_PROMPT_DIRTY:-$SCM_THEME_PROMPT_DIRTY} - else - SCM_DIRTY=0 - SCM_STATE=${SVN_THEME_PROMPT_CLEAN:-$SCM_THEME_PROMPT_CLEAN} - fi - SCM_PREFIX=${SVN_THEME_PROMPT_PREFIX:-$SCM_THEME_PROMPT_PREFIX} - SCM_SUFFIX=${SVN_THEME_PROMPT_SUFFIX:-$SCM_THEME_PROMPT_SUFFIX} - SCM_BRANCH=$(svn info --show-item=url 2> /dev/null | awk -F/ '{ for (i=0; i<=NF; i++) { if ($i == "branches" || $i == "tags" ) { print $(i+1); break }; if ($i == "trunk") { print $i; break } } }') || return - SCM_CHANGE=$(svn info --show-item=revision 2> /dev/null) + if [[ -n $(svn status | head -c1 2> /dev/null) ]]; then + SCM_DIRTY=1 + SCM_STATE=${SVN_THEME_PROMPT_DIRTY:-$SCM_THEME_PROMPT_DIRTY} + else + SCM_DIRTY=0 + SCM_STATE=${SVN_THEME_PROMPT_CLEAN:-$SCM_THEME_PROMPT_CLEAN} + fi + SCM_PREFIX=${SVN_THEME_PROMPT_PREFIX:-$SCM_THEME_PROMPT_PREFIX} + SCM_SUFFIX=${SVN_THEME_PROMPT_SUFFIX:-$SCM_THEME_PROMPT_SUFFIX} + SCM_BRANCH=$(svn info --show-item=url 2> /dev/null | awk -F/ '{ for (i=0; i<=NF; i++) { if ($i == "branches" || $i == "tags" ) { print $(i+1); break }; if ($i == "trunk") { print $i; break } } }') || return + SCM_CHANGE=$(svn info --show-item=revision 2> /dev/null) } # this functions returns absolute location of .hg directory if one exists @@ -310,268 +326,268 @@ function svn_prompt_vars { # - .hg is located in ~/Projects/Foo/.hg # - get_hg_root starts at ~/Projects/Foo/Bar and sees that there is no .hg directory, so then it goes into ~/Projects/Foo function get_hg_root { - local CURRENT_DIR=$(pwd) + local CURRENT_DIR=$(pwd) - while [ "$CURRENT_DIR" != "/" ]; do - if [ -d "$CURRENT_DIR/.hg" ]; then - echo "$CURRENT_DIR/.hg" - return - fi + while [ "$CURRENT_DIR" != "/" ]; do + if [ -d "$CURRENT_DIR/.hg" ]; then + echo "$CURRENT_DIR/.hg" + return + fi - CURRENT_DIR=$(dirname $CURRENT_DIR) - done + CURRENT_DIR=$(dirname "$CURRENT_DIR") + done } function hg_prompt_vars { - if [[ -n $(hg status 2> /dev/null) ]]; then - SCM_DIRTY=1 - SCM_STATE=${HG_THEME_PROMPT_DIRTY:-$SCM_THEME_PROMPT_DIRTY} - else - SCM_DIRTY=0 - SCM_STATE=${HG_THEME_PROMPT_CLEAN:-$SCM_THEME_PROMPT_CLEAN} - fi - SCM_PREFIX=${HG_THEME_PROMPT_PREFIX:-$SCM_THEME_PROMPT_PREFIX} - SCM_SUFFIX=${HG_THEME_PROMPT_SUFFIX:-$SCM_THEME_PROMPT_SUFFIX} + if [[ -n $(hg status 2> /dev/null) ]]; then + SCM_DIRTY=1 + SCM_STATE=${HG_THEME_PROMPT_DIRTY:-$SCM_THEME_PROMPT_DIRTY} + else + SCM_DIRTY=0 + SCM_STATE=${HG_THEME_PROMPT_CLEAN:-$SCM_THEME_PROMPT_CLEAN} + fi + SCM_PREFIX=${HG_THEME_PROMPT_PREFIX:-$SCM_THEME_PROMPT_PREFIX} + SCM_SUFFIX=${HG_THEME_PROMPT_SUFFIX:-$SCM_THEME_PROMPT_SUFFIX} - HG_ROOT=$(get_hg_root) + HG_ROOT=$(get_hg_root) - if [ -f "$HG_ROOT/branch" ]; then - # Mercurial holds it's current branch in .hg/branch file - SCM_BRANCH=$(cat "$HG_ROOT/branch") - else - SCM_BRANCH=$(hg summary 2> /dev/null | grep branch: | awk '{print $2}') - fi + if [ -f "$HG_ROOT/branch" ]; then + # Mercurial holds it's current branch in .hg/branch file + SCM_BRANCH=$(cat "$HG_ROOT/branch") + else + SCM_BRANCH=$(hg summary 2> /dev/null | grep branch: | awk '{print $2}') + fi - 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 -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 + 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 -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 } function nvm_version_prompt { - local node - if declare -f -F nvm &> /dev/null; then - node=$(nvm current 2> /dev/null) - [[ "${node}" == "system" ]] && return - echo -e "${NVM_THEME_PROMPT_PREFIX}${node}${NVM_THEME_PROMPT_SUFFIX}" - fi + local node + if declare -f -F nvm &> /dev/null; then + node=$(nvm current 2> /dev/null) + [[ "${node}" == "system" ]] && return + echo -e "${NVM_THEME_PROMPT_PREFIX}${node}${NVM_THEME_PROMPT_SUFFIX}" + fi } function node_version_prompt { - echo -e "$(nvm_version_prompt)" + echo -e "$(nvm_version_prompt)" } function rvm_version_prompt { - if which rvm &> /dev/null; then - rvm=$(rvm-prompt) || return - if [ -n "$rvm" ]; then - echo -e "$RVM_THEME_PROMPT_PREFIX$rvm$RVM_THEME_PROMPT_SUFFIX" - fi - fi + if which rvm &> /dev/null; then + rvm=$(rvm-prompt) || return + if [ -n "$rvm" ]; then + echo -e "$RVM_THEME_PROMPT_PREFIX$rvm$RVM_THEME_PROMPT_SUFFIX" + fi + fi } function rbenv_version_prompt { - if which rbenv &> /dev/null; then - rbenv=$(rbenv version-name) || return - $(rbenv commands | grep -q gemset) && gemset=$(rbenv gemset active 2> /dev/null) && rbenv="$rbenv@${gemset%% *}" - if [ $rbenv != "system" ]; then - echo -e "$RBENV_THEME_PROMPT_PREFIX$rbenv$RBENV_THEME_PROMPT_SUFFIX" - fi - fi + if which rbenv &> /dev/null; then + rbenv=$(rbenv version-name) || return + rbenv commands | grep -q gemset && gemset=$(rbenv gemset active 2> /dev/null) && rbenv="$rbenv@${gemset%% *}" + if [ "$rbenv" != "system" ]; then + echo -e "$RBENV_THEME_PROMPT_PREFIX$rbenv$RBENV_THEME_PROMPT_SUFFIX" + fi + fi } function rbfu_version_prompt { - if [[ $RBFU_RUBY_VERSION ]]; then - echo -e "${RBFU_THEME_PROMPT_PREFIX}${RBFU_RUBY_VERSION}${RBFU_THEME_PROMPT_SUFFIX}" - fi + if [[ $RBFU_RUBY_VERSION ]]; then + echo -e "${RBFU_THEME_PROMPT_PREFIX}${RBFU_RUBY_VERSION}${RBFU_THEME_PROMPT_SUFFIX}" + fi } function chruby_version_prompt { - if declare -f -F chruby &> /dev/null; then - if declare -f -F chruby_auto &> /dev/null; then - chruby_auto - fi + if declare -f -F chruby &> /dev/null; then + if declare -f -F chruby_auto &> /dev/null; then + chruby_auto + fi - ruby_version=$(ruby --version | awk '{print $1, $2;}') || return + ruby_version=$(ruby --version | awk '{print $1, $2;}') || return - if [[ ! $(chruby | grep '\*') ]]; then - ruby_version="${ruby_version} (system)" - fi - echo -e "${CHRUBY_THEME_PROMPT_PREFIX}${ruby_version}${CHRUBY_THEME_PROMPT_SUFFIX}" - fi + if ! chruby | grep -q '\*'; then + ruby_version="${ruby_version} (system)" + fi + echo -e "${CHRUBY_THEME_PROMPT_PREFIX}${ruby_version}${CHRUBY_THEME_PROMPT_SUFFIX}" + fi } function ruby_version_prompt { - if [[ "${THEME_SHOW_RUBY_PROMPT}" = "true" ]]; then - echo -e "$(rbfu_version_prompt)$(rbenv_version_prompt)$(rvm_version_prompt)$(chruby_version_prompt)" - fi + if [[ "${THEME_SHOW_RUBY_PROMPT}" = "true" ]]; then + echo -e "$(rbfu_version_prompt)$(rbenv_version_prompt)$(rvm_version_prompt)$(chruby_version_prompt)" + fi } function k8s_context_prompt { - echo -e "$(kubectl config current-context 2> /dev/null)" + echo -e "$(kubectl config current-context 2> /dev/null)" } function virtualenv_prompt { - if [[ -n "$VIRTUAL_ENV" ]]; then - virtualenv=`basename "$VIRTUAL_ENV"` - echo -e "$VIRTUALENV_THEME_PROMPT_PREFIX$virtualenv$VIRTUALENV_THEME_PROMPT_SUFFIX" - fi + if [[ -n "$VIRTUAL_ENV" ]]; then + virtualenv=$(basename "$VIRTUAL_ENV") + echo -e "$VIRTUALENV_THEME_PROMPT_PREFIX$virtualenv$VIRTUALENV_THEME_PROMPT_SUFFIX" + fi } function condaenv_prompt { - if [[ $CONDA_DEFAULT_ENV ]]; then - echo -e "${CONDAENV_THEME_PROMPT_PREFIX}${CONDA_DEFAULT_ENV}${CONDAENV_THEME_PROMPT_SUFFIX}" - fi + if [[ $CONDA_DEFAULT_ENV ]]; then + echo -e "${CONDAENV_THEME_PROMPT_PREFIX}${CONDA_DEFAULT_ENV}${CONDAENV_THEME_PROMPT_SUFFIX}" + fi } function py_interp_prompt { - py_version=$(python --version 2>&1 | awk 'NR==1{print "py-"$2;}') || return - echo -e "${PYTHON_THEME_PROMPT_PREFIX}${py_version}${PYTHON_THEME_PROMPT_SUFFIX}" + py_version=$(python --version 2>&1 | awk 'NR==1{print "py-"$2;}') || return + echo -e "${PYTHON_THEME_PROMPT_PREFIX}${py_version}${PYTHON_THEME_PROMPT_SUFFIX}" } function python_version_prompt { - echo -e "$(virtualenv_prompt)$(condaenv_prompt)$(py_interp_prompt)" + echo -e "$(virtualenv_prompt)$(condaenv_prompt)$(py_interp_prompt)" } function git_user_info { - # support two or more initials, set by 'git pair' plugin - SCM_CURRENT_USER=$(git config user.initials | sed 's% %+%') - # if `user.initials` weren't set, attempt to extract initials from `user.name` - [[ -z "${SCM_CURRENT_USER}" ]] && SCM_CURRENT_USER=$(printf "%s" $(for word in $(git config user.name | PERLIO=:utf8 perl -pe '$_=lc'); do printf "%s" "${word:0:1}"; done)) - [[ -n "${SCM_CURRENT_USER}" ]] && printf "%s" "$SCM_THEME_CURRENT_USER_PREFFIX$SCM_CURRENT_USER$SCM_THEME_CURRENT_USER_SUFFIX" + # support two or more initials, set by 'git pair' plugin + SCM_CURRENT_USER=$(git config user.initials | sed 's% %+%') + # if `user.initials` weren't set, attempt to extract initials from `user.name` + [[ -z "${SCM_CURRENT_USER}" ]] && SCM_CURRENT_USER=$(printf "%s" "$(for word in $(git config user.name | PERLIO=:utf8 perl -pe '$_=lc'); do printf "%s" "${word:0:1}"; done)") + [[ -n "${SCM_CURRENT_USER}" ]] && printf "%s" "$SCM_THEME_CURRENT_USER_PREFFIX$SCM_CURRENT_USER$SCM_THEME_CURRENT_USER_SUFFIX" } function clock_char { - CLOCK_CHAR=${THEME_CLOCK_CHAR:-"⌚"} - CLOCK_CHAR_COLOR=${THEME_CLOCK_CHAR_COLOR:-"$normal"} - SHOW_CLOCK_CHAR=${THEME_SHOW_CLOCK_CHAR:-"true"} + CLOCK_CHAR=${THEME_CLOCK_CHAR:-"⌚"} + CLOCK_CHAR_COLOR=${THEME_CLOCK_CHAR_COLOR:-"$normal"} + SHOW_CLOCK_CHAR=${THEME_SHOW_CLOCK_CHAR:-"true"} - if [[ "${SHOW_CLOCK_CHAR}" = "true" ]]; then - echo -e "${CLOCK_CHAR_COLOR}${CLOCK_CHAR_THEME_PROMPT_PREFIX}${CLOCK_CHAR}${CLOCK_CHAR_THEME_PROMPT_SUFFIX}" - fi + if [[ "${SHOW_CLOCK_CHAR}" = "true" ]]; then + echo -e "${CLOCK_CHAR_COLOR}${CLOCK_CHAR_THEME_PROMPT_PREFIX}${CLOCK_CHAR}${CLOCK_CHAR_THEME_PROMPT_SUFFIX}" + fi } function clock_prompt { - CLOCK_COLOR=${THEME_CLOCK_COLOR:-"$normal"} - CLOCK_FORMAT=${THEME_CLOCK_FORMAT:-"%H:%M:%S"} - [ -z $THEME_SHOW_CLOCK ] && THEME_SHOW_CLOCK=${THEME_CLOCK_CHECK:-"true"} - SHOW_CLOCK=$THEME_SHOW_CLOCK + CLOCK_COLOR=${THEME_CLOCK_COLOR:-"$normal"} + CLOCK_FORMAT=${THEME_CLOCK_FORMAT:-"%H:%M:%S"} + [ -z "$THEME_SHOW_CLOCK" ] && THEME_SHOW_CLOCK=${THEME_CLOCK_CHECK:-"true"} + SHOW_CLOCK=$THEME_SHOW_CLOCK - if [[ "${SHOW_CLOCK}" = "true" ]]; then - CLOCK_STRING=$(date +"${CLOCK_FORMAT}") - echo -e "${CLOCK_COLOR}${CLOCK_THEME_PROMPT_PREFIX}${CLOCK_STRING}${CLOCK_THEME_PROMPT_SUFFIX}" - fi + if [[ "${SHOW_CLOCK}" = "true" ]]; then + CLOCK_STRING=$(date +"${CLOCK_FORMAT}") + echo -e "${CLOCK_COLOR}${CLOCK_THEME_PROMPT_PREFIX}${CLOCK_STRING}${CLOCK_THEME_PROMPT_SUFFIX}" + fi } function user_host_prompt { - if [[ "${THEME_SHOW_USER_HOST}" = "true" ]]; then - echo -e "${USER_HOST_THEME_PROMPT_PREFIX}\u@\h${USER_HOST_THEME_PROMPT_SUFFIX}" - fi + if [[ "${THEME_SHOW_USER_HOST}" = "true" ]]; then + echo -e "${USER_HOST_THEME_PROMPT_PREFIX}\u@\h${USER_HOST_THEME_PROMPT_SUFFIX}" + fi } # backwards-compatibility function git_prompt_info { - _git-hide-status && return - git_prompt_vars - echo -e "${SCM_PREFIX}${SCM_BRANCH}${SCM_STATE}${SCM_SUFFIX}" + _git-hide-status && return + git_prompt_vars + echo -e "${SCM_PREFIX}${SCM_BRANCH}${SCM_STATE}${SCM_SUFFIX}" } function p4_prompt_info() { - p4_prompt_vars - echo -e "${SCM_PREFIX}${SCM_BRANCH}:${SCM_CHANGE}${SCM_STATE}${SCM_SUFFIX}" + p4_prompt_vars + echo -e "${SCM_PREFIX}${SCM_BRANCH}:${SCM_CHANGE}${SCM_STATE}${SCM_SUFFIX}" } function svn_prompt_info { - svn_prompt_vars - echo -e "${SCM_PREFIX}${SCM_BRANCH}${SCM_STATE}${SCM_SUFFIX}" + svn_prompt_vars + echo -e "${SCM_PREFIX}${SCM_BRANCH}${SCM_STATE}${SCM_SUFFIX}" } function hg_prompt_info() { - hg_prompt_vars - echo -e "${SCM_PREFIX}${SCM_BRANCH}:${SCM_CHANGE#*:}${SCM_STATE}${SCM_SUFFIX}" + hg_prompt_vars + echo -e "${SCM_PREFIX}${SCM_BRANCH}:${SCM_CHANGE#*:}${SCM_STATE}${SCM_SUFFIX}" } function scm_char { - scm_prompt_char - echo -e "${SCM_THEME_CHAR_PREFIX}${SCM_CHAR}${SCM_THEME_CHAR_SUFFIX}" + scm_prompt_char + echo -e "${SCM_THEME_CHAR_PREFIX}${SCM_CHAR}${SCM_THEME_CHAR_SUFFIX}" } function prompt_char { - scm_char + scm_char } function battery_char { - if [[ "${THEME_BATTERY_PERCENTAGE_CHECK}" = true ]]; then - echo -e "${bold_red}$(battery_percentage)%" - fi + if [[ "${THEME_BATTERY_PERCENTAGE_CHECK}" = true ]]; then + echo -e "${bold_red}$(battery_percentage)%" + fi } -if ! _command_exists battery_charge ; then - # if user has installed battery plugin, skip this... - function battery_charge (){ - # no op - echo -n - } +if ! _command_exists battery_charge; then + # if user has installed battery plugin, skip this... + function battery_charge() { + # no op + echo -n + } fi # The battery_char function depends on the presence of the battery_percentage function. # If battery_percentage is not defined, then define battery_char as a no-op. -if ! _command_exists battery_percentage ; then - function battery_char (){ - # no op - echo -n - } +if ! _command_exists battery_percentage; then + function battery_char() { + # no op + echo -n + } fi function aws_profile { - if [[ $AWS_DEFAULT_PROFILE ]]; then - echo -e "${AWS_DEFAULT_PROFILE}" - else - echo -e "default" - fi + if [[ $AWS_DEFAULT_PROFILE ]]; then + echo -e "${AWS_DEFAULT_PROFILE}" + else + echo -e "default" + fi } function __check_precmd_conflict() { - local f - for f in "${precmd_functions[@]}"; do - if [[ "${f}" == "${1}" ]]; then - return 0 - fi - done - return 1 + local f + for f in "${precmd_functions[@]}"; do + if [[ "${f}" == "${1}" ]]; then + return 0 + fi + done + return 1 } function safe_append_prompt_command { - local prompt_re + local prompt_re - if [ "${__bp_imported}" == "defined" ]; then - # We are using bash-preexec - if ! __check_precmd_conflict "${1}" ; then - precmd_functions+=("${1}") - fi - else - # Set OS dependent exact match regular expression - if [[ ${OSTYPE} == darwin* ]]; then - # macOS - prompt_re="[[:<:]]${1}[[:>:]]" - else - # Linux, FreeBSD, etc. - prompt_re="\<${1}\>" - fi + if [ "${__bp_imported}" == "defined" ]; then + # We are using bash-preexec + if ! __check_precmd_conflict "${1}"; then + precmd_functions+=("${1}") + fi + else + # Set OS dependent exact match regular expression + if [[ ${OSTYPE} == darwin* ]]; then + # macOS + prompt_re="[[:<:]]${1}[[:>:]]" + else + # Linux, FreeBSD, etc. + prompt_re="\<${1}\>" + fi - if [[ ${PROMPT_COMMAND} =~ ${prompt_re} ]]; then - return - elif [[ -z ${PROMPT_COMMAND} ]]; then - PROMPT_COMMAND="${1}" - else - PROMPT_COMMAND="${1};${PROMPT_COMMAND}" - fi - fi + if [[ ${PROMPT_COMMAND} =~ ${prompt_re} ]]; then + return + elif [[ -z ${PROMPT_COMMAND} ]]; then + PROMPT_COMMAND="${1}" + else + PROMPT_COMMAND="${1};${PROMPT_COMMAND}" + fi + fi } function _save-and-reload-history() { - local autosave=${1:-0} - [[ $autosave -eq 1 ]] && history -a && history -c && history -r + local autosave=${1:-0} + [[ $autosave -eq 1 ]] && history -a && history -c && history -r } diff --git a/themes/powerline/powerline.base.bash b/themes/powerline/powerline.base.bash index 38c5c895..dd39337e 100644 --- a/themes/powerline/powerline.base.bash +++ b/themes/powerline/powerline.base.bash @@ -1,3 +1,4 @@ +# shellcheck shell=bash # Define this here so it can be used by all of the Powerline themes THEME_CHECK_SUDO=${THEME_CHECK_SUDO:=true} diff --git a/themes/powerline/powerline.theme.bash b/themes/powerline/powerline.theme.bash index 83731614..3239b360 100644 --- a/themes/powerline/powerline.theme.bash +++ b/themes/powerline/powerline.theme.bash @@ -1,4 +1,4 @@ -#!/usr/bin/env bash +# shellcheck shell=bash # shellcheck source=../../themes/powerline/powerline.base.bash . "$BASH_IT/themes/powerline/powerline.base.bash"