diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 0eee145cd8..75fb9d848e 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -7,12 +7,12 @@ jobs: bats-test: strategy: matrix: - os: [ubuntu-20.04, ubuntu-18.04, macos-10.15, macos-11] + os: [ubuntu-20.04, ubuntu-22.04, macos-12, macos-11] runs-on: ${{ matrix.os }} steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v4 - name: Install greadlink if: startsWith(runner.os, 'macOS') run: brew install coreutils @@ -26,9 +26,9 @@ jobs: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v4 - name: Set up Python - uses: actions/setup-python@v2 + uses: actions/setup-python@v4 with: python-version: 3.8 - name: Install docs dependencies @@ -40,19 +40,24 @@ jobs: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v4 - name: Set up Go - uses: actions/setup-go@v2 + uses: actions/setup-go@v4 with: - go-version: 1.17 + go-version: 1.21.0 - name: Set up Python - uses: actions/setup-python@v2 + uses: actions/setup-python@v4 with: python-version: 3.8 - name: Install shfmt - run: GO111MODULE=on go get mvdan.cc/sh/v3/cmd/shfmt + run: go install mvdan.cc/sh/v3/cmd/shfmt@latest - name: Install shellcheck - run: brew install shellcheck + env: + scversion: stable # Or latest, vxx, etc + run: | + wget -qO- "https://github.com/koalaman/shellcheck/releases/download/${scversion?}/shellcheck-${scversion?}.linux.x86_64.tar.xz" | tar -xJv "shellcheck-${scversion}/shellcheck" + sudo cp "shellcheck-${scversion}/shellcheck" /usr/bin/ + shellcheck --version - name: Install pre-commit run: python3 -m pip install -r test/lint-requirements.txt - name: Run lint diff --git a/aliases/available/general.aliases.bash b/aliases/available/general.aliases.bash index 42930ab4d2..2511aab8a9 100644 --- a/aliases/available/general.aliases.bash +++ b/aliases/available/general.aliases.bash @@ -34,7 +34,7 @@ fi alias c='clear' alias cls='clear' -alias edit='${EDITOR:-${ALTERNATE_EDITOR?}}' +alias edit='${EDITOR:-${ALTERNATE_EDITOR:-nano}}' alias pager='${PAGER:=less}' alias q='exit' @@ -71,10 +71,6 @@ alias rd='rmdir' # Shorten extract alias xt='extract' -# sudo editors -alias svim='sudo ${VISUAL:-vim}' -alias snano='sudo nano' - # Display whatever file is regular file or folder function catt() { for i in "$@"; do diff --git a/aliases/available/git.aliases.bash b/aliases/available/git.aliases.bash index 507037e1d0..f3cf6fa11e 100644 --- a/aliases/available/git.aliases.bash +++ b/aliases/available/git.aliases.bash @@ -3,20 +3,25 @@ about-alias 'common git abbreviations' alias g='git' alias get='git' +alias got='git ' # add alias ga='git add' alias gall='git add -A' alias gap='git add -p' +alias gav='git add -v' # branch alias gb='git branch' -alias gbD='git branch -D' -alias gba='git branch -a' +alias gba='git branch --all' alias gbd='git branch -d' -alias gbm='git branch -m' +alias gbD='git branch -D' +alias gbl='git branch --list' +alias gbla='git branch --list --all' +alias gblr='git branch --list --remotes' +alias gbm='git branch --move' +alias gbr='git branch --remotes' 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 @@ -27,6 +32,9 @@ 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 gc!='git commit -v --amend' +alias gca!='git commit -v -a --amend' +alias gcn!='git commit -v --amend --no-edit' alias gcm='git commit -v -m' alias gci='git commit --interactive' alias gcsam='git commit -S -am' @@ -74,6 +82,8 @@ alias ggup='git log --branches --not --remotes --no-walk --decorate --oneline' # 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' +alias ghist='git log --pretty=format:'\''%h %ad | %s%d [%an]'\'' --graph --date=short' # Use it to be fast and without color. +alias gprogress='git log --pretty=format:'\''%C(yellow)%h %Cblue%ad %Creset%s%Cgreen [%cn] %Cred%d'\'' --decorate --date=short' #Usually use "git progress" in the file .gitconfig. The new alias from Git friends will be truly welcome. # ls-files alias gu='git ls-files . --exclude-standard --others' # Show untracked files @@ -92,6 +102,9 @@ fi # merge alias gm='git merge' +alias gma='git merge --abort' +alias gmc='git merge --continue' +alias gms='git merge --squash' # mv alias gmv='git mv' @@ -102,7 +115,8 @@ alias gpatch='git format-patch -1' # push alias gp='git push' alias gpd='git push --delete' -alias gpf='git push --force' +alias gpf='git push --force-with-lease' +alias gpff='git push --force' alias gpo='git push origin HEAD' alias gpom='git push origin $(get_default_branch)' alias gpu='git push --set-upstream' @@ -112,6 +126,7 @@ alias gpuoc='git push --set-upstream origin $(git symbolic-ref --short HEAD)' # pull alias gl='git pull' +alias glp='git pull --prune' alias glum='git pull upstream $(get_default_branch)' alias gpl='git pull' alias gpp='git pull && git push' @@ -124,17 +139,21 @@ alias grv='git remote -v' # rm alias grm='git rm' +alias grmc='git rm --cached' # Removes the file only from the Git repository, but not from the filesystem. This is useful to undo some of the changes you made to a file before you commit it. # rebase alias grb='git rebase' +alias grba='git rebase --abort' alias grbc='git rebase --continue' -alias grm='git rebase $(get_default_branch)' -alias grmi='git rebase $(get_default_branch) -i' -alias grma='GIT_SEQUENCE_EDITOR=: git rebase $(get_default_branch) -i --autosquash' +alias grbm='git rebase $(get_default_branch)' +alias grbmi='git rebase $(get_default_branch) --interactive' +alias grbma='GIT_SEQUENCE_EDITOR=: git rebase $(get_default_branch) --interactive --autosquash' alias gprom='git fetch origin $(get_default_branch) && git rebase origin/$(get_default_branch) && git update-ref refs/heads/$(get_default_branch) origin/$(get_default_branch)' # Rebase with latest remote # reset -alias gus='git reset HEAD' +alias gus='git reset HEAD' # read as: 'git unstage' +alias grh='git reset' # equivalent to: git reset HEAD +alias grh!='git reset --hard' alias gpristine='git reset --hard && git clean -dfx' # status @@ -147,6 +166,8 @@ alias gsl='git shortlog -sn' # show alias gsh='git show' +alias gshn='git show --name-only' +alias gshns='git show --name-status' # svn alias gsd='git svn dcommit' @@ -199,9 +220,6 @@ function gdv() { } function get_default_branch() { - if git branch | grep -q '^. main\s*$'; then - echo main - else - echo master - fi + branch=$(git symbolic-ref refs/remotes/origin/HEAD) + ${branch#refs/remotes/origin/} } diff --git a/aliases/available/kubectl.aliases.bash b/aliases/available/kubectl.aliases.bash index aaca4ca259..ce01bdafcf 100644 --- a/aliases/available/kubectl.aliases.bash +++ b/aliases/available/kubectl.aliases.bash @@ -1,20 +1,16 @@ # shellcheck shell=bash about-alias 'kubectl aliases' -function _set_pkg_aliases() { - 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' - alias kcdd='kubectl describe deployment' - alias kcdn='kubectl describe node' - alias kcgpan='kubectl get pods --all-namespaces' - alias kcgdan='kubectl get deployments --all-namespaces' - # launches a disposable netshoot pod in the k8s cluster - alias kcnetshoot='kubectl run netshoot-$(date +%s) --rm -i --tty --image nicolaka/netshoot -- /bin/bash' - fi -} - -_set_pkg_aliases +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' + alias kcdd='kubectl describe deployment' + alias kcdn='kubectl describe node' + alias kcgpan='kubectl get pods --all-namespaces' + alias kcgdan='kubectl get deployments --all-namespaces' + # launches a disposable netshoot pod in the k8s cluster + alias kcnetshoot='kubectl run netshoot-$(date +%s) --rm -i --tty --image nicolaka/netshoot -- /bin/bash' +fi diff --git a/aliases/available/maven.aliases.bash b/aliases/available/maven.aliases.bash index 737826eb47..2746da2c95 100644 --- a/aliases/available/maven.aliases.bash +++ b/aliases/available/maven.aliases.bash @@ -3,8 +3,13 @@ about-alias 'maven abbreviations' alias mci='mvn clean install' alias mi='mvn install' -alias mcp='mvn clean package' +alias mc='mvn clean' +alias mct='mvn clean test' +alias mcc='mvn clean compile' +alias mccnt='mvn clean compile -DskipTests=true' alias mp='mvn package' +alias mcp='mvn clean package' +alias mcpnt='mvn clean package -DskipTests=true' alias mrprep='mvn release:prepare' alias mrperf='mvn release:perform' alias mrrb='mvn release:rollback' @@ -12,3 +17,9 @@ alias mdep='mvn dependency:tree' alias mpom='mvn help:effective-pom' alias mcisk='mci -Dmaven.test.skip=true' alias mcpsk='mcp -Dmaven.test.skip=true' + +# Maven service plugin aliases +alias mspring='mvn spring-boot:run' +alias mjetty='mvn jetty:run' +alias mquark='mvn quarkus:dev' +alias mmicro='mvn mn:run' diff --git a/aliases/available/osx.aliases.bash b/aliases/available/osx.aliases.bash index e99bcae6b3..0a16c06f61 100644 --- a/aliases/available/osx.aliases.bash +++ b/aliases/available/osx.aliases.bash @@ -11,6 +11,7 @@ alias safari='open -a safari' alias firefox='open -a firefox' alias chrome='open -a "Google Chrome"' alias chromium='open -a chromium' +alias brave='open -a "Brave Browser"' alias dashcode='open -a dashcode' alias f='open -a Finder ' alias fh='open -a Finder .' diff --git a/aliases/available/terraform.aliases.bash b/aliases/available/terraform.aliases.bash index baa9b0c7ce..b236b5fd9f 100644 --- a/aliases/available/terraform.aliases.bash +++ b/aliases/available/terraform.aliases.bash @@ -2,7 +2,9 @@ about-alias 'Aliases for Terraform and Terragrunt' alias tf='terraform' +alias tfi='tf init' alias tfv='terraform validate' alias tfp='terraform plan' alias tfa='terraform apply' alias tfd='terraform destroy' +alias tfw='terraform workspace' diff --git a/clean_files.txt b/clean_files.txt index 82b07d7b0a..14a1d501a5 100644 --- a/clean_files.txt +++ b/clean_files.txt @@ -19,6 +19,7 @@ aliases/ docs/ hooks/ +lib/ scripts/ test/ @@ -32,8 +33,10 @@ lint_clean_files.sh # completions # +completion/available/aliases.completion.bash completion/available/apm.completion.bash completion/available/awless.completion.bash +completion/available/awscli.completion.bash completion/available/bash-it.completion.bash completion/available/brew.completion.bash completion/available/cargo.completion.bash @@ -46,6 +49,8 @@ completion/available/dmidecode.completion.bash completion/available/docker-machine.completion.bash completion/available/docker.completion.bash completion/available/dotnet.completion.bash +completion/available/export.completion.bash +completion/available/flutter.completion.bash completion/available/gcloud.completion.bash completion/available/gem.completion.bash completion/available/git.completion.bash @@ -75,18 +80,7 @@ completion/available/system.completion.bash completion/available/vault.completion.bash completion/available/vuejs.completion.bash completion/available/wpscan.completion.bash - -# libraries -lib/appearance.bash -lib/colors.bash -lib/command_duration.bash -lib/helpers.bash -lib/history.bash -lib/log.bash -lib/preexec.bash -lib/preview.bash -lib/search.bash -lib/utilities.bash +completion/available/yarn.completion.bash # plugins # @@ -96,6 +90,7 @@ plugins/available/base.plugin.bash plugins/available/basher.plugin.bash plugins/available/battery.plugin.bash plugins/available/blesh.plugin.bash +plugins/available/browser.plugin.bash plugins/available/cmd-returned-notify.plugin.bash plugins/available/colors.plugin.bash plugins/available/direnv.plugin.bash @@ -113,6 +108,7 @@ plugins/available/history.plugin.bash plugins/available/hub.plugin.bash plugins/available/java.plugin.bash plugins/available/jekyll.plugin.bash +plugins/available/jgitflow.plugin.bash plugins/available/jump.plugin.bash plugins/available/latex.plugin.bash plugins/available/less-pretty-cat.plugin.bash @@ -132,9 +128,16 @@ plugins/available/rbenv.plugin.bash plugins/available/ruby.plugin.bash plugins/available/textmate.plugin.bash plugins/available/todo.plugin.bash +plugins/available/url.plugin.bash plugins/available/xterm.plugin.bash plugins/available/zoxide.plugin.bash +# tests +# +test/completion/aliases.completion.bats +test/run +test/test_helper.bash + # themes # themes/90210 @@ -151,17 +154,23 @@ themes/bobby-python themes/brainy themes/brunton themes/candy +themes/clean themes/easy +themes/elixr themes/essential themes/githelpers.theme.bash +themes/inretio +themes/lambda themes/modern themes/norbu +themes/oh-my-posh themes/p4helpers.theme.bash themes/pete themes/powerline themes/pure themes/purity + # vendor init files # vendor/.gitattributes diff --git a/completion/available/aliases.completion.bash b/completion/available/aliases.completion.bash index f9cc1ed181..a4b15959a8 100644 --- a/completion/available/aliases.completion.bash +++ b/completion/available/aliases.completion.bash @@ -20,7 +20,7 @@ function _bash-it-component-completion-callback-on-init-aliases() { completions=("${completions[@]##complete -* * -}") # strip all but last option plus trigger(s) completions=("${completions[@]#complete -}") # strip anything missed completions=("${completions[@]#? * }") # strip last option and arg, leaving only trigger(s) - completions=("${completions[@]#? }") # strip anything missed + completions=("${completions[@]#? }") # strip anything missed #TODO: this will fail on some completions... # create temporary file for wrapper functions and completions @@ -40,17 +40,17 @@ function _bash-it-component-completion-callback-on-init-aliases() { line="${line#alias -- }" line="${line#alias }" alias_name="${line%%=*}" - alias_defn="${line#*=\'}" # alias definition + alias_defn="${line#*=\'}" # alias definition alias_defn="${alias_defn%\'}" alias_cmd="${alias_defn%%[[:space:]]*}" # first word of alias - if [[ ${alias_defn} == ${alias_cmd} ]]; then + if [[ ${alias_defn} == "${alias_cmd}" ]]; then alias_args='' else alias_args="${alias_defn#*[[:space:]]}" # everything after first word fi # skip aliases to pipes, boolean control structures and other command lists - chars='\|\&\;\)\(\n\<\>' + chars=$'|&;()<>\n' if [[ "${alias_defn}" =~ [$chars] ]]; then continue fi @@ -89,7 +89,7 @@ function _bash-it-component-completion-callback-on-init-aliases() { prec_word=\${prec_word#* } fi (( COMP_CWORD += ${#alias_arg_words[@]} )) - COMP_WORDS=(\"$alias_cmd\" \"${alias_arg_words[@]}\" \"\${COMP_WORDS[@]:1}\") + COMP_WORDS=(\"$alias_cmd\" \"${alias_arg_words[*]}\" \"\${COMP_WORDS[@]:1}\") (( COMP_POINT -= \${#COMP_LINE} )) COMP_LINE=\${COMP_LINE/$alias_name/$alias_cmd $alias_args} (( COMP_POINT += \${#COMP_LINE} )) diff --git a/completion/available/awscli.completion.bash b/completion/available/awscli.completion.bash index a30418373a..6b2c90ff5d 100644 --- a/completion/available/awscli.completion.bash +++ b/completion/available/awscli.completion.bash @@ -1,6 +1,5 @@ # shellcheck shell=bash -if _command_exists aws_completer -then +if _command_exists aws_completer; then complete -C "$(command -v aws_completer)" aws fi diff --git a/completion/available/brew.completion.bash b/completion/available/brew.completion.bash index 61998f8a71..01e5d533a7 100644 --- a/completion/available/brew.completion.bash +++ b/completion/available/brew.completion.bash @@ -14,17 +14,17 @@ fi _bash_it_homebrew_check || return 0 if [[ -r "$BASH_IT_HOMEBREW_PREFIX/etc/bash_completion.d/brew" ]]; then - # shellcheck disable=1090 + # shellcheck disable=1090,1091 source "$BASH_IT_HOMEBREW_PREFIX/etc/bash_completion.d/brew" elif [[ -r "$BASH_IT_HOMEBREW_PREFIX/Library/Contributions/brew_bash_completion.sh" ]]; then - # shellcheck disable=1090 + # shellcheck disable=1090,1091 source "$BASH_IT_HOMEBREW_PREFIX/Library/Contributions/brew_bash_completion.sh" elif [[ -f "$BASH_IT_HOMEBREW_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 - # shellcheck disable=1090 + # shellcheck disable=1090,1091 source "$BASH_IT_HOMEBREW_PREFIX/completions/bash/brew" fi diff --git a/completion/available/export.completion.bash b/completion/available/export.completion.bash index 42da3a97be..4898eb9a01 100644 --- a/completion/available/export.completion.bash +++ b/completion/available/export.completion.bash @@ -1 +1,3 @@ -complete -o nospace -S = -W '$(printenv | awk -F= "{print \$1}")' export +# shellcheck shell=bash + +complete -o nospace -S = -W "$(printenv | awk -F= "{print \$1}")" export diff --git a/completion/available/fabric.completion.bash b/completion/available/fabric.completion.bash index 6f746454dc..a8984d9cc3 100644 --- a/completion/available/fabric.completion.bash +++ b/completion/available/fabric.completion.bash @@ -1,4 +1,4 @@ -#!/usr/bin/env bash +# shellcheck shell=bash # # Bash completion support for Fabric (http://fabfile.org/) # @@ -91,7 +91,7 @@ function __fab_completion() { -*) if [[ -z "${__FAB_COMPLETION_LONG_OPT}" ]]; then export __FAB_COMPLETION_LONG_OPT=$( - fab --help | egrep -o "\-\-[A-Za-z_\-]+\=?" | sort -u) + fab --help | grep -E -o "\-\-[A-Za-z_\-]+\=?" | sort -u) fi opts="${__FAB_COMPLETION_LONG_OPT}" ;; @@ -101,7 +101,7 @@ function __fab_completion() { # -*) # if [[ -z "${__FAB_COMPLETION_SHORT_OPT}" ]]; then # export __FAB_COMPLETION_SHORT_OPT=$( - # fab --help | egrep -o "^ +\-[A-Za-z_\]" | sort -u) + # fab --help | grep -E -o "^ +\-[A-Za-z_\]" | sort -u) # fi # opts="${__FAB_COMPLETION_SHORT_OPT}" # ;; diff --git a/completion/available/flutter.completion.bash b/completion/available/flutter.completion.bash index 62befc824d..7dde5a0709 100644 --- a/completion/available/flutter.completion.bash +++ b/completion/available/flutter.completion.bash @@ -1,5 +1,5 @@ -#!/usr/bin/bash +# shellcheck shell=bash if _command_exists flutter; then - eval "$(flutter bash-completion)" + eval "$(flutter bash-completion)" fi diff --git a/completion/available/gradle.completion.bash b/completion/available/gradle.completion.bash index 35971d5075..ef9677c6de 100644 --- a/completion/available/gradle.completion.bash +++ b/completion/available/gradle.completion.bash @@ -1,3 +1,5 @@ +# shellcheck shell=bash + # Copyright (c) 2017 Eric Wendelin # Permission is hereby granted, free of charge, to any person obtaining a copy of @@ -66,7 +68,7 @@ __gradle-generate-script-cache() { if [[ ! $(find $cache_dir/$cache_name -mmin -$cache_ttl_mins 2>/dev/null) ]]; then # Cache all Gradle scripts - local gradle_build_scripts=$(find $project_root_dir -type f -name "*.gradle" -o -name "*.gradle.kts" 2>/dev/null | egrep -v "$script_exclude_pattern") + local gradle_build_scripts=$(find $project_root_dir -type f -name "*.gradle" -o -name "*.gradle.kts" 2>/dev/null | grep -E -v "$script_exclude_pattern") printf "%s\n" "${gradle_build_scripts[@]}" > $cache_dir/$cache_name fi } diff --git a/completion/available/makefile.completion.bash b/completion/available/makefile.completion.bash index e72ba6fd3b..018586cacf 100644 --- a/completion/available/makefile.completion.bash +++ b/completion/available/makefile.completion.bash @@ -1,3 +1,5 @@ +# shellcheck shell=bash + # Bash completion for Makefile # Loosely adapted from http://stackoverflow.com/a/38415982/1472048 @@ -17,7 +19,7 @@ _makecomplete() { for f in "${files[@]}" ; do while IFS='' read -r line ; do targets+=("$line") - done < <(grep -oE '^[a-zA-Z0-9_-]+:([^=]|$)' "$f" | cut -d':' -f1) + done < <(grep -E -o '^[a-zA-Z0-9_-]+:([^=]|$)' "$f" | cut -d':' -f1) done [ "${#targets[@]}" -eq 0 ] && return 0 diff --git a/completion/available/projects.completion.bash b/completion/available/projects.completion.bash index 90735ee130..df4f5754dd 100644 --- a/completion/available/projects.completion.bash +++ b/completion/available/projects.completion.bash @@ -7,7 +7,7 @@ _is_function _rl_enabled || _pj() { _is_function _init_completion || return _is_function _rl_enabled || return - [ -n "$PROJECT_PATHS" ] || return + [ -n "$BASH_IT_PROJECT_PATHS" ] || return shift [ "$1" == "open" ] && shift @@ -21,7 +21,7 @@ _pj() { local -r mark_dirs=$(_rl_enabled mark-directories && echo y) local -r mark_symdirs=$(_rl_enabled mark-symlinked-directories && echo y) - for i in ${PROJECT_PATHS//:/$'\n'}; do + for i in ${BASH_IT_PROJECT_PATHS//:/$'\n'}; do # create an array of matched subdirs k="${#COMPREPLY[@]}" for j in $( compgen -d $i/$cur ); do diff --git a/completion/available/sqlmap.completion.bash b/completion/available/sqlmap.completion.bash index 213dd81736..0ad06938dc 100644 --- a/completion/available/sqlmap.completion.bash +++ b/completion/available/sqlmap.completion.bash @@ -7,162 +7,158 @@ # | # ---------------------------------------------------------------------------+ -if _command_exists sqlmap -then +_command_exists sqlmap || return - function _sqlmap() - { - local cur prev +function _sqlmap() { + local cur prev - COMPREPLY=() - cur="$(_get_cword)" - prev="$(_get_pword)" + COMPREPLY=() + cur="$(_get_cword)" + prev="$(_get_pword)" - case $prev in + case $prev in - # List directory content - --tamper) - COMPREPLY=( $( compgen -W "$tamper" -- "$cur" ) ) - return 0 - ;; - --output-dir|-t|-l|-m|-r|--load-cookies|--proxy-file|--sql-file|--shared-lib|--file-write) - _filedir - return 0 - ;; - -c) - _filedir ini - return 0 - ;; - --method) - COMPREPLY=( $( compgen -W 'GET POST PUT' -- "$cur" ) ) - return 0 - ;; - --auth-type) - COMPREPLY=( $( compgen -W 'Basic Digest NTLM PKI' -- "$cur" ) ) - return 0 - ;; - --tor-type) - COMPREPLY=( $( compgen -W 'HTTP SOCKS4 SOCKS5' -- "$cur" ) ) - return 0 - ;; - -v) - COMPREPLY=( $( compgen -W '1 2 3 4 5 6' -- "$cur" ) ) - return 0 - ;; - --dbms) - COMPREPLY=( $( compgen -W 'mysql mssql access postgres' -- "$cur" ) ) - return 0 - ;; - --level|--crawl) - COMPREPLY=( $( compgen -W '1 2 3 4 5' -- "$cur" ) ) - return 0 - ;; - --risk) - COMPREPLY=( $( compgen -W '0 1 2 3' -- "$cur" ) ) - return 0 - ;; - --technique) - COMPREPLY=( $( compgen -W 'B E U S T Q' -- "$cur" ) ) - return 0 - ;; - -s) - _filedir sqlite - return 0 - ;; - --dump-format) - COMPREPLY=( $( compgen -W 'CSV HTML SQLITE' -- "$cur" ) ) - return 0 - ;; - -x) - _filedir xml - return 0 - ;; - esac + # List directory content + --tamper) + COMPREPLY=($(compgen -W "$tamper" -- "$cur")) + return 0 + ;; + --output-dir | -t | -l | -m | -r | --load-cookies | --proxy-file | --sql-file | --shared-lib | --file-write) + _filedir + return 0 + ;; + -c) + _filedir ini + return 0 + ;; + --method) + COMPREPLY=($(compgen -W 'GET POST PUT' -- "$cur")) + return 0 + ;; + --auth-type) + COMPREPLY=($(compgen -W 'Basic Digest NTLM PKI' -- "$cur")) + return 0 + ;; + --tor-type) + COMPREPLY=($(compgen -W 'HTTP SOCKS4 SOCKS5' -- "$cur")) + return 0 + ;; + -v) + COMPREPLY=($(compgen -W '1 2 3 4 5 6' -- "$cur")) + return 0 + ;; + --dbms) + COMPREPLY=($(compgen -W 'mysql mssql access postgres' -- "$cur")) + return 0 + ;; + --level | --crawl) + COMPREPLY=($(compgen -W '1 2 3 4 5' -- "$cur")) + return 0 + ;; + --risk) + COMPREPLY=($(compgen -W '0 1 2 3' -- "$cur")) + return 0 + ;; + --technique) + COMPREPLY=($(compgen -W 'B E U S T Q' -- "$cur")) + return 0 + ;; + -s) + _filedir sqlite + return 0 + ;; + --dump-format) + COMPREPLY=($(compgen -W 'CSV HTML SQLITE' -- "$cur")) + return 0 + ;; + -x) + _filedir xml + return 0 + ;; + esac - if [[ "$cur" == * ]]; then - COMPREPLY=( $( compgen -W '-h --help -hh --version -v -d -u --url -l -x -m -r -g -c --method \ - --data --param-del --cookie --cookie-del --load-cookies \ - --drop-set-cookie --user-agent --random-agent --host --referer \ - --headers --auth-type --auth-cred --auth-private --ignore-401 \ - --proxy --proxy-cred --proxy-file --ignore-proxy --tor --tor-port \ - --tor-type --check-tor --delay --timeout --retries --randomize \ - --safe-url --safe-freq --skip-urlencode --csrf-token --csrf-url \ - --force-ssl --hpp --eval -o --predict-output --keep-alive \ - --null-connection --threads -p --skip --dbms --dbms-cred \ - --os --invalid-bignum --invalid-logical --invalid-string \ - --no-cast --no-escape --prefix --suffix --tamper --level \ - --risk --string --not-string --regexp --code --text-only \ - --titles --technique --time-sec --union-cols --union-char \ - --union-from --dns-domain --second-order -f --fingerprint \ - -a --all -b --banner --current-user --current-db --hostname \ - --is-dba --users --passwords --privileges --roles --dbs --tables \ - --columns --schema --count --dump --dump-all --search --comments \ - -D -T -C -X -U --exclude-sysdbs --where --start --stop \ - --first --last --sql-query --sql-shell --sql-file --common-tables \ - --common-columns --udf-inject --shared-lib --file-read --file-write \ - --file-dest --os-cmd --os-shell --os-pwn --os-smbrelay --os-bof \ - --priv-esc --msf-path --tmp-path --reg-read --reg-add --reg-del \ - --reg-key --reg-value --reg-data --reg-type -s -t --batch \ - --charset --crawl --csv-del --dump-format --eta --flush-session \ - --forms --fresh-queries --hex --output-dir --parse-errors \ - --pivot-column --save --scope --test-filter --update \ - -z --alert --answers --beep --check-waf --cleanup \ - --dependencies --disable-coloring --gpage --identify-waf \ - --mobile --page-rank --purge-output --smart \ - --sqlmap-shell --wizard' -- "$cur" ) ) - # this removes any options from the list of completions that have - # already been specified somewhere on the command line, as long as - # these options can only be used once (in a word, "options", in - # opposition to "tests" and "actions", as in the find(1) manpage). - onlyonce=' -h --help -hh --version -v -d -u --url -l -x -m -r -g -c \ - --drop-set-cookie --random-agent \ - --ignore-401 \ - --ignore-proxy --tor \ - --check-tor \ - --skip-urlencode \ - --force-ssl --hpp -o --predict-output --keep-alive \ - --null-connection -p \ - --invalid-bignum --invalid-logical --invalid-string \ - --no-cast --no-escape \ - --text-only \ - --titles \ - -f --fingerprint \ - -a --all -b --banner --current-user --current-db --hostname \ - --is-dba --users --passwords --privileges --roles --dbs --tables \ - --columns --schema --count --dump --dump-all --search --comments \ - -D -T -C -X -U --exclude-sysdbs \ - --sql-shell --common-tables \ - --common-columns --udf-inject \ - --os-shell --os-pwn --os-smbrelay --os-bof \ - --priv-esc --reg-read --reg-add --reg-del \ - -s -t --batch \ - --eta --flush-session \ - --forms --fresh-queries --hex --parse-errors \ - --save --update \ - -z --beep --check-waf --cleanup \ - --dependencies --disable-coloring --identify-waf \ - --mobile --page-rank --purge-output --smart \ - --sqlmap-shell --wizard ' - COMPREPLY=( $( \ - (while read -d ' ' i; do - [[ -z "$i" || "${onlyonce/ ${i%% *} / }" == "$onlyonce" ]] && - continue - # flatten array with spaces on either side, - # otherwise we cannot grep on word boundaries of - # first and last word - COMPREPLY=" ${COMPREPLY[@]} " - # remove word from list of completions - COMPREPLY=( ${COMPREPLY/ ${i%% *} / } ) - done - printf '%s ' "${COMPREPLY[@]}") <<<"${COMP_WORDS[@]}" - ) ) + if [[ "$cur" == * ]]; then + COMPREPLY=($(compgen -W '-h --help -hh --version -v -d -u --url -l -x -m -r -g -c --method \ + --data --param-del --cookie --cookie-del --load-cookies \ + --drop-set-cookie --user-agent --random-agent --host --referer \ + --headers --auth-type --auth-cred --auth-private --ignore-401 \ + --proxy --proxy-cred --proxy-file --ignore-proxy --tor --tor-port \ + --tor-type --check-tor --delay --timeout --retries --randomize \ + --safe-url --safe-freq --skip-urlencode --csrf-token --csrf-url \ + --force-ssl --hpp --eval -o --predict-output --keep-alive \ + --null-connection --threads -p --skip --dbms --dbms-cred \ + --os --invalid-bignum --invalid-logical --invalid-string \ + --no-cast --no-escape --prefix --suffix --tamper --level \ + --risk --string --not-string --regexp --code --text-only \ + --titles --technique --time-sec --union-cols --union-char \ + --union-from --dns-domain --second-order -f --fingerprint \ + -a --all -b --banner --current-user --current-db --hostname \ + --is-dba --users --passwords --privileges --roles --dbs --tables \ + --columns --schema --count --dump --dump-all --search --comments \ + -D -T -C -X -U --exclude-sysdbs --where --start --stop \ + --first --last --sql-query --sql-shell --sql-file --common-tables \ + --common-columns --udf-inject --shared-lib --file-read --file-write \ + --file-dest --os-cmd --os-shell --os-pwn --os-smbrelay --os-bof \ + --priv-esc --msf-path --tmp-path --reg-read --reg-add --reg-del \ + --reg-key --reg-value --reg-data --reg-type -s -t --batch \ + --charset --crawl --csv-del --dump-format --eta --flush-session \ + --forms --fresh-queries --hex --output-dir --parse-errors \ + --pivot-column --save --scope --test-filter --update \ + -z --alert --answers --beep --check-waf --cleanup \ + --dependencies --disable-coloring --gpage --identify-waf \ + --mobile --page-rank --purge-output --smart \ + --sqlmap-shell --wizard' -- "$cur")) + # this removes any options from the list of completions that have + # already been specified somewhere on the command line, as long as + # these options can only be used once (in a word, "options", in + # opposition to "tests" and "actions", as in the find(1) manpage). + onlyonce=' -h --help -hh --version -v -d -u --url -l -x -m -r -g -c \ + --drop-set-cookie --random-agent \ + --ignore-401 \ + --ignore-proxy --tor \ + --check-tor \ + --skip-urlencode \ + --force-ssl --hpp -o --predict-output --keep-alive \ + --null-connection -p \ + --invalid-bignum --invalid-logical --invalid-string \ + --no-cast --no-escape \ + --text-only \ + --titles \ + -f --fingerprint \ + -a --all -b --banner --current-user --current-db --hostname \ + --is-dba --users --passwords --privileges --roles --dbs --tables \ + --columns --schema --count --dump --dump-all --search --comments \ + -D -T -C -X -U --exclude-sysdbs \ + --sql-shell --common-tables \ + --common-columns --udf-inject \ + --os-shell --os-pwn --os-smbrelay --os-bof \ + --priv-esc --reg-read --reg-add --reg-del \ + -s -t --batch \ + --eta --flush-session \ + --forms --fresh-queries --hex --parse-errors \ + --save --update \ + -z --beep --check-waf --cleanup \ + --dependencies --disable-coloring --identify-waf \ + --mobile --page-rank --purge-output --smart \ + --sqlmap-shell --wizard ' + COMPREPLY=($( + ( + while read -d ' ' i; do + [[ -z "$i" || "${onlyonce/ ${i%% *} / }" == "$onlyonce" ]] && continue + # flatten array with spaces on either side, + # otherwise we cannot grep on word boundaries of + # first and last word + COMPREPLY=" ${COMPREPLY[@]} " + # remove word from list of completions + COMPREPLY=(${COMPREPLY/ ${i%% *} / }) + done + printf '%s ' "${COMPREPLY[@]}" + ) <<< "${COMP_WORDS[@]}" + )) - # else - # _filedir bat - fi - } + #else + #_filedir bat + fi +} - - complete -F _sqlmap sqlmap - -fi +complete -F _sqlmap sqlmap diff --git a/completion/available/yarn.completion.bash b/completion/available/yarn.completion.bash new file mode 100644 index 0000000000..de1240851b --- /dev/null +++ b/completion/available/yarn.completion.bash @@ -0,0 +1,5 @@ +# shellcheck shell=bash +about-completion "yarn cli completions" + +# shellcheck disable=SC1090 source=../../vendor/github.com/dsifford/yarn-completion/yarn +source "${BASH_IT}/vendor/github.com/dsifford/yarn-completion/yarn" diff --git a/docs/README.md b/docs/README.md index f3d31a14fe..b307a7abfd 100644 --- a/docs/README.md +++ b/docs/README.md @@ -4,7 +4,6 @@ ![Docs Status](https://readthedocs.org/projects/bash-it/badge/) ![License](https://img.shields.io/github/license/Bash-it/bash-it) ![shell](https://img.shields.io/badge/Shell-Bash-blue) -[![Join the chat at https://web.libera.chat/?channel=#bash-it](https://img.shields.io/badge/chat-on%20Libera.Chat-brightgreen.svg)](https://web.libera.chat/?channel=#bash-it) **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:) diff --git a/docs/conf.py b/docs/conf.py index cacc2d5022..f96485c616 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -14,7 +14,6 @@ # import sys # sys.path.insert(0, os.path.abspath('.')) - # -- Project information ----------------------------------------------------- project = 'Bash-it' @@ -24,7 +23,6 @@ # The full version, including alpha/beta/rc tags release = '' - # -- General configuration --------------------------------------------------- # Add any Sphinx extension module names here, as strings. They can be @@ -41,8 +39,7 @@ # List of patterns, relative to source directory, that match files and # directories to ignore when looking for source files. # This pattern also affects html_static_path and html_extra_path. -exclude_patterns = ['_build', 'Thumbs.db', '.DS_Store'] - +exclude_patterns = ['_build', 'Thumbs.db', '.DS_Store', "venv"] # -- Options for HTML output ------------------------------------------------- diff --git a/docs/contributing.rst b/docs/contributing.rst index 79d8ed1c7b..2ba3ce7faf 100644 --- a/docs/contributing.rst +++ b/docs/contributing.rst @@ -79,9 +79,9 @@ The following libraries are used to help with the tests: * Test Framework: https://github.com/bats-core/bats-core -* Support library for Bats-Assert: https://github.com/ztombol/bats-support -* General ``assert`` functions: https://github.com/ztombol/bats-assert -* File ``assert`` functions: https://github.com/ztombol/bats-file +* Support library for Bats-Assert: https://github.com/bats-core/bats-support +* General ``assert`` functions: https://github.com/bats-core/bats-assert +* File ``assert`` functions: https://github.com/bats-core/bats-file When verifying test results, please try to use the ``assert`` functions found in these libraries. diff --git a/docs/requirements.txt b/docs/requirements.txt index b3015c81ce..7b7fcdd1ff 100644 --- a/docs/requirements.txt +++ b/docs/requirements.txt @@ -1,4 +1,4 @@ -sphinx==3.2.1 +sphinx==4.5.0 sphinx-rtd-theme==0.5.0 sphinxemoji==0.1.8 docutils==0.17.1 diff --git a/docs/themes-list/barbuk.rst b/docs/themes-list/barbuk.rst index 15fb0ef577..79477524b0 100644 --- a/docs/themes-list/barbuk.rst +++ b/docs/themes-list/barbuk.rst @@ -8,13 +8,35 @@ A minimal theme with a clean git prompt Provided Information -------------------- - * Current git remote tool logo (support: github, gitlab, bitbucket) * 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 +Default configuration +^^^^^^^^^^^^^^^^^^^^^ + +.. code-block:: bash + + BARBUK_PROMPT="git-uptream-remote-logo ssh path scm python_venv ruby node terraform cloud duration exit" + +You can override BARBUK_PROMPT to display only the desired information. + +available block: + +* git-uptream-remote-logo +* ssh +* path +* scm +* python_venv +* ruby +* node +* terraform +* cloud +* duration +* exit + Fonts and glyphs ---------------- @@ -39,6 +61,12 @@ Default theme glyphs BARBUK_EXIT_CODE_ICON=' ' BARBUK_PYTHON_VENV_CHAR=' ' BARBUK_COMMAND_DURATION_ICON='  ' + BARBUK_RUBY_CHAR=' ' + BARBUK_NODE_CHAR=' ' + BARBUK_TERRAFORM_CHAR="❲t❳ " + BARBUK_AWS_PROFILE_CHAR=" aws " + BARBUK_SCALEWAY_PROFILE_CHAR=" scw " + BARBUK_GCLOUD_CHAR=" gcp " Customize glyphs ^^^^^^^^^^^^^^^^ diff --git a/docs/themes-list/index.rst b/docs/themes-list/index.rst index 49c5a6236c..0196ba62ed 100644 --- a/docs/themes-list/index.rst +++ b/docs/themes-list/index.rst @@ -221,6 +221,21 @@ Envy ---- +Inretio +^^^^^^^ + + +.. image:: https://raw.githubusercontent.com/inretio/bash-it/gh-pages/docs/images/inretio-black.png + :target: https://raw.githubusercontent.com/inretio/bash-it/gh-pages/docs/images/inretio-black.png + :alt: Inretio theme in dark color scheme + + +.. image:: https://raw.githubusercontent.com/inretio/bash-it/gh-pages/docs/images/inretio-white.png + :target: https://raw.githubusercontent.com/inretio/bash-it/gh-pages/docs/images/inretio-white.png + :alt: Inretio theme in light color scheme + +---- + Iterate ^^^^^^^ @@ -346,6 +361,19 @@ NWinkler :alt: +---- + +.. _oh_my_posh_image: + +Oh-My-Posh +^^^^^^^^^^ + + +.. image:: https://bash-it.github.io/bash-it/docs/images/oh-my-posh.png + :target: https://bash-it.github.io/bash-it/docs/images/oh-my-posh.png + :alt: + + ---- Pete diff --git a/docs/themes-list/inretio.rst b/docs/themes-list/inretio.rst new file mode 100644 index 0000000000..d37287d07c --- /dev/null +++ b/docs/themes-list/inretio.rst @@ -0,0 +1,31 @@ +.. _inretio: + +Inretio Theme +============= + +Simple theme showing date and time, username and hostname, current folder, Git details and as a bonus - virtual environment along with Python version available in it. + +Inspired by existing themes: +- metal +- bobby + +Examples +-------- + +In Git-tracked folder: + +.. code-block:: bash + + ┌──[2024-03-20 12:05:07] 🐧 gytis 💻 gytis-legion 📂 bash-it on 🌵 theme-inretio ⌀1 ✗ + └> ls + aliases clean_files.txt custom hooks lib lint_clean_files.sh profiles template test_lib uninstall.sh + bash_it.sh completion docs install.sh LICENSE plugins scripts test themes vendor + + +In Python virtual environment: + +.. code-block:: bash + + ┌──[2024-03-20 12:07:32] 🐧 gytis 💻 gytis-legion 🐍 3.12.2 on [general] 📂 general + └> ls + bin include lib lib64 pyvenv.cfg share diff --git a/docs/themes-list/oh-my-posh.rst b/docs/themes-list/oh-my-posh.rst new file mode 100644 index 0000000000..974adc0f19 --- /dev/null +++ b/docs/themes-list/oh-my-posh.rst @@ -0,0 +1,15 @@ +.. _oh-my-posh: + +Oh-My-Posh Theme +================ + +The oh-my-posh ״theme״ is really a plug to a whole other system +of managing your prompt. To use it please start here: +`Oh-My-Posh homepage `_ + +It is beyond the scope of bash-it to install and manage oh-my-posh, +this theme is here just to make sure your OMP setup doesn't clash +with other bash-it themes. Once installed, OMP will load a default +OMP theme (jandedobbeleer), which you can then customize or override. + +Note: Nerd Fonts are highly recommended, as most of the themes are graphic candies. diff --git a/docs/themes-list/powerline-base.rst b/docs/themes-list/powerline-base.rst index faa1af3401..f38f940daa 100644 --- a/docs/themes-list/powerline-base.rst +++ b/docs/themes-list/powerline-base.rst @@ -81,7 +81,7 @@ The contents of the prompt can be "reordered", all the "segments" (every piece o * ``python_venv`` - Python virtual environment information (\ ``virtualenv``\ , ``venv`` and ``conda`` supported) * ``ruby`` - Current ruby version if using ``rvm`` -* ``node`` - Current node version (only ``nvm`` is supported) +* ``node`` - Current node version (``nvm`` is the default strategy; set ``NODE_VERSION_STRATEGY`` to ``node`` to use ``node --version``) * ``scm`` - Version control information, ``git`` * ``terraform`` - Current terraform workspace * ``user_info`` - Current user diff --git a/docs/troubleshooting.rst b/docs/troubleshooting.rst index 6503699a98..93d9113ab3 100644 --- a/docs/troubleshooting.rst +++ b/docs/troubleshooting.rst @@ -8,9 +8,38 @@ Table of Contents * `I'm stuck in the LightDM login screen after setting up bash-it. `_ +* `I'm getting strange line break and wrapping behaviour on macOS. `_ + I'm stuck in the LightDM login screen after setting up bash-it ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ **Possible issue**\ : `#672 `_ **Solution**\ : Check `this comment `_ for detailed information about the cause and solution for this issue. + +I'm getting strange line break and wrapping behaviour on macOS +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +**Possible issue**\ : `#1614 `_ + +**Solution**\ : Bash-it requires Bash 4.?? or later to run correctly. Any reasonably current Linux distribution should have shipped with a compatible version of Bash. However, macOS users must upgrade from the included, obsolete Bash version 3. While some functionality might work with Bash 3, there is no guarantee that everything will work perfectly. Thus, we recommend using `Homebrew `_ to ensure Bash is up to date: + +x86 Mac +^^^^^^^ + + .. code-block:: bash + + brew install bash + sudo sh -c 'echo /usr/local/bin/bash >> /etc/shells' + chsh -s /usr/local/bin/bash + +M1 Mac +^^^^^^ + +Homebrew's default installation location on M1 is ``/opt/homebrew/bin/``: + + .. code-block:: bash + + brew install bash + sudo sh -c 'echo /opt/homebrew/bin/bash >> /etc/shells' + chsh -s /opt/homebrew/bin/bash diff --git a/install.sh b/install.sh index 2bb78a3f64..58c25537b6 100755 --- a/install.sh +++ b/install.sh @@ -12,7 +12,6 @@ function _bash-it_show_usage() { echo "--no-modify-config (-n): Do not modify existing config file" echo "--append-to-config (-a): Keep existing config file and append bash-it templates at the end" echo "--overwrite-backup (-f): Overwrite existing backup" - exit 0 } # enable a thing diff --git a/lib/command_duration.bash b/lib/command_duration.bash index bc0cca8e0a..850c67649e 100644 --- a/lib/command_duration.bash +++ b/lib/command_duration.bash @@ -2,29 +2,52 @@ # # Functions for measuring and reporting how long a command takes to run. -: "${COMMAND_DURATION_START_SECONDS:=${EPOCHREALTIME:-$SECONDS}}" +# Get shell duration in decimal format regardless of runtime locale. +# Notice: This function runs as a sub-shell - notice '(' vs '{'. +function _shell_duration_en() ( + # DFARREL You would think LC_NUMERIC would do it, but not working in my local. + # Note: LC_ALL='en_US.UTF-8' has been used to enforce the decimal point to be + # a period, but the specific locale 'en_US.UTF-8' is not ensured to exist in + # the system. One should instead use the locale 'C', which is ensured by the + # C and POSIX standards. + local LC_ALL=C + printf "%s" "${EPOCHREALTIME:-$SECONDS}" +) + +: "${COMMAND_DURATION_START_SECONDS:=$(_shell_duration_en)}" : "${COMMAND_DURATION_ICON:=🕘}" : "${COMMAND_DURATION_MIN_SECONDS:=1}" function _command_duration_pre_exec() { - COMMAND_DURATION_START_SECONDS="${EPOCHREALTIME:-$SECONDS}" + COMMAND_DURATION_START_SECONDS="$(_shell_duration_en)" +} + +function _command_duration_pre_cmd() { + COMMAND_DURATION_START_SECONDS="" } function _dynamic_clock_icon { - local -i clock_hand=$(((${1:-${SECONDS}} % 12) + 90)) + local clock_hand + # clock hand value is between 90 and 9b in hexadecimal. + # so between 144 and 155 in base 10. + printf -v clock_hand '%x' $((((${1:-${SECONDS}} - 1) % 12) + 144)) printf -v 'COMMAND_DURATION_ICON' '%b' "\xf0\x9f\x95\x$clock_hand" } function _command_duration() { [[ -n "${BASH_IT_COMMAND_DURATION:-}" ]] || return + [[ -n "${COMMAND_DURATION_START_SECONDS:-}" ]] || return local command_duration=0 command_start="${COMMAND_DURATION_START_SECONDS:-0}" local -i minutes=0 seconds=0 deciseconds=0 local -i command_start_seconds="${command_start%.*}" local -i command_start_deciseconds=$((10#${command_start##*.})) - local current_time="${EPOCHREALTIME:-$SECONDS}" + command_start_deciseconds="${command_start_deciseconds:0:1}" + local current_time + current_time="$(_shell_duration_en)" local -i current_time_seconds="${current_time%.*}" local -i current_time_deciseconds="$((10#${current_time##*.}))" + current_time_deciseconds="${current_time_deciseconds:0:1}" if [[ "${command_start_seconds:-0}" -gt 0 ]]; then # seconds @@ -40,17 +63,18 @@ function _command_duration() { command_duration=0 fi - if ((command_duration > 0)); then + if ((command_duration >= COMMAND_DURATION_MIN_SECONDS)); then minutes=$((command_duration / 60)) seconds=$((command_duration % 60)) - fi - _dynamic_clock_icon "${command_duration}" - if ((minutes > 0)); then - printf "%s%s%dm %ds" "${COMMAND_DURATION_ICON:-}" "${COMMAND_DURATION_COLOR:-}" "$minutes" "$seconds" - elif ((seconds >= COMMAND_DURATION_MIN_SECONDS)); then - printf "%s%s%d.%01ds" "${COMMAND_DURATION_ICON:-}" "${COMMAND_DURATION_COLOR:-}" "$seconds" "$deciseconds" + _dynamic_clock_icon "${command_duration}" + if ((minutes > 0)); then + printf "%s %s%dm %ds" "${COMMAND_DURATION_ICON:-}" "${COMMAND_DURATION_COLOR:-}" "$minutes" "$seconds" + else + printf "%s %s%d.%01ds" "${COMMAND_DURATION_ICON:-}" "${COMMAND_DURATION_COLOR:-}" "$seconds" "$deciseconds" + fi fi } _bash_it_library_finalize_hook+=("safe_append_preexec '_command_duration_pre_exec'") +_bash_it_library_finalize_hook+=("safe_append_prompt_command '_command_duration_pre_cmd'") diff --git a/lib/helpers.bash b/lib/helpers.bash index c0ce2eb3e2..3675b0f259 100644 --- a/lib/helpers.bash +++ b/lib/helpers.bash @@ -211,7 +211,7 @@ function _is_function() { _example '$ _is_function ls && echo exists' _group 'lib' local msg="${2:-Function '$1' does not exist}" - if LC_ALL=C type -t "$1" | _bash-it-egrep -q 'function'; then + if LC_ALL=C type -t "$1" | _bash-it-fgrep -q 'function'; then return 0 else _log_debug "$msg" @@ -290,6 +290,7 @@ function _bash-it-update-() { DIFF=$(git diff --name-status) if [[ -n "$DIFF" ]]; then echo -e "Local changes detected in bash-it directory. Clean '$BASH_IT' directory to proceed.\n$DIFF" + popd > /dev/null || return return 1 fi @@ -334,7 +335,7 @@ function _bash-it-update-() { log_color="%Cred" fi - git log --format="${log_color}%h: %s (%an)" "${revision}" + git log --no-merges --format="${log_color}%h: %s (%an)" "${revision}" echo "" if [[ -n "${silent}" ]]; then diff --git a/lib/preview.bash b/lib/preview.bash index 96fafae7ab..46c1618ab4 100644 --- a/lib/preview.bash +++ b/lib/preview.bash @@ -24,7 +24,7 @@ function _bash-it-preview() { # shellcheck disable=SC2034 for BASH_IT_THEME in "${themes[@]}"; do BASH_IT_LOG_LEVEL=0 - bash --init-file "${BASH_IT_BASHRC:-${BASH_IT?}/bash_it.sh}" -i <<< '_bash-it-flash-term "${#BASH_IT_THEME}" "${BASH_IT_THEME}"' + bash --init-file "${BASH_IT?}/bash_it.sh" -i <<< '_bash-it-flash-term "${#BASH_IT_THEME}" "${BASH_IT_THEME}"' done } diff --git a/lib/search.bash b/lib/search.bash index 7073f8798b..247e6294ae 100644 --- a/lib/search.bash +++ b/lib/search.bash @@ -347,7 +347,7 @@ function _bash-it-flash-term() { local -i len="${1:-0}" # redundant local term="${2:-}" # as currently implemented, `$match` has already been printed to screen the first time - local delay=0.1 + local delay=0.2 local color [[ "${#term}" -gt 0 ]] && len="${#term}" diff --git a/lib/utilities.bash b/lib/utilities.bash index 8ea6b98c24..75e914b8c6 100644 --- a/lib/utilities.bash +++ b/lib/utilities.bash @@ -60,15 +60,21 @@ function _bash-it-array-dedup() { printf '%s\n' "$@" | sort -u } -# Outputs a full path of the grep found on the filesystem +# Runs `grep` with *just* the provided arguments function _bash-it-grep() { - : "${BASH_IT_GREP:=$(type -p egrep || type -p grep)}" - printf "%s" "${BASH_IT_GREP:-/usr/bin/grep}" + : "${BASH_IT_GREP:=$(type -P grep)}" + "${BASH_IT_GREP:-/usr/bin/grep}" "$@" } -# Runs `grep` with extended regular expressions +# Runs `grep` with fixed-string expressions (-F) +function _bash-it-fgrep() { + : "${BASH_IT_GREP:=$(type -P grep)}" + "${BASH_IT_GREP:-/usr/bin/grep}" -F "$@" +} + +# Runs `grep` with extended regular expressions (-E) function _bash-it-egrep() { - : "${BASH_IT_GREP:=$(type -p egrep || type -p grep)}" + : "${BASH_IT_GREP:=$(type -P grep)}" "${BASH_IT_GREP:-/usr/bin/grep}" -E "$@" } @@ -150,12 +156,12 @@ function _bash-it-component-list-matching() { function _bash-it-component-list-enabled() { local IFS=$'\n' component="$1" - _bash-it-component-help "${component}" | _bash-it-egrep '\[x\]' | awk '{print $1}' | sort -u + _bash-it-component-help "${component}" | _bash-it-fgrep '[x]' | awk '{print $1}' | sort -u } function _bash-it-component-list-disabled() { local IFS=$'\n' component="$1" - _bash-it-component-help "${component}" | _bash-it-egrep -v '\[x\]' | awk '{print $1}' | sort -u + _bash-it-component-help "${component}" | _bash-it-fgrep -v '[x]' | awk '{print $1}' | sort -u } # Checks if a given item is enabled for a particular component/file-type. diff --git a/lint_clean_files.sh b/lint_clean_files.sh index 26650b16de..b341f4f46f 100755 --- a/lint_clean_files.sh +++ b/lint_clean_files.sh @@ -8,9 +8,9 @@ # shellcheck disable=SC2002 # Prefer 'cat' for cleaner script mapfile -t FILES < <( cat clean_files.txt \ - | grep -v -E '^\s*$' \ - | grep -v -E '^\s*#' \ - | xargs -n1 -I{} find "{}" -type f + | grep -E -v '^\s*$' \ + | grep -E -v '^\s*#' \ + | xargs -I{} find "{}" -type f ) # We clear the BASH_IT variable to help the shellcheck checker diff --git a/plugins/available/aws.plugin.bash b/plugins/available/aws.plugin.bash index 54a8669171..14d26caefb 100644 --- a/plugins/available/aws.plugin.bash +++ b/plugins/available/aws.plugin.bash @@ -1,3 +1,4 @@ +# shellcheck shell=bash cite about-plugin about-plugin 'AWS helper functions' @@ -40,13 +41,13 @@ 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 2 "aws_access_key_id|aws_secret_access_key" - tail -n +${ln} "${AWS_SHARED_CREDENTIALS_FILE}" | egrep -m 1 "aws_session_token" + tail -n +${ln} "${AWS_SHARED_CREDENTIALS_FILE}" | grep -F -m 2 -e "aws_access_key_id" -e "aws_secret_access_key" + tail -n +${ln} "${AWS_SHARED_CREDENTIALS_FILE}" | grep -F -m 1 "aws_session_token" fi } function __awskeys_list { - local credentials_list="$((egrep '^\[ *[a-zA-Z0-9_-]+ *\]$' "${AWS_SHARED_CREDENTIALS_FILE}"; grep "\[profile" "${AWS_CONFIG_FILE}" | sed "s|\[profile |\[|g") | sort | uniq)" + local credentials_list="$((grep -E '^\[ *[a-zA-Z0-9_-]+ *\]$' "${AWS_SHARED_CREDENTIALS_FILE}"; grep "\[profile" "${AWS_CONFIG_FILE}" | sed "s|\[profile |\[|g") | sort | uniq)" if [[ -n $"{credentials_list}" ]]; then echo -e "Available credentials profiles:\n" for profile in ${credentials_list}; do diff --git a/plugins/available/browser.plugin.bash b/plugins/available/browser.plugin.bash index f7d820aa07..b65d92ca76 100644 --- a/plugins/available/browser.plugin.bash +++ b/plugins/available/browser.plugin.bash @@ -1,39 +1,40 @@ +# shellcheck shell=bash # based on https://gist.github.com/318247 cite about-plugin about-plugin 'render commandline output in your browser' +# shellcheck disable=SC2120 function browser() { - about 'pipe html to a browser' - example '$ echo "

hi mom!

" | browser' - example '$ ron -5 man/rip.5.ron | browser' - group 'browser' + about 'pipe html to a browser' + example '$ echo "

hi mom!

" | browser' + example '$ ron -5 man/rip.5.ron | browser' + group 'browser' - if [ -t 0 ]; then - if [ -n "$1" ]; then - open $1 - else - reference browser - fi + if [ -t 0 ]; then + if [ -n "$1" ]; then + open "$1" + else + reference browser + fi - else - f="/tmp/browser.$RANDOM.html" - cat /dev/stdin > $f - open $f - fi + else + f="/tmp/browser.$RANDOM.html" + cat /dev/stdin > $f + open $f + fi } - function wmate() { - about 'pipe hot spicy interwebs into textmate and cleanup!' - example '$ wmate google.com' - group 'browser' - - if [ -t 0 ]; then - if [ -n "$1" ]; then - wget -qO- $1 | /usr/bin/mate + about 'pipe hot spicy interwebs into textmate and cleanup!' + example '$ wmate google.com' + group 'browser' -TIDY=`/usr/bin/osascript << EOT + if [ -t 0 ]; then + if [ -n "$1" ]; then + wget -qO- "$1" | /usr/bin/mate + TIDY=$( + /usr/bin/osascript << EOT tell application "TextMate" activate end tell @@ -53,24 +54,26 @@ tell application "System Events" end tell end tell end tell -EOT` +EOT + ) + export TIDY - else - reference wmate - fi - fi + else + reference wmate + fi + fi } function raw() { - about 'write wget into a temp file and pump it into your browser' - example '$ raw google.com' - group 'browser' + about 'write wget into a temp file and pump it into your browser' + example '$ raw google.com' + group 'browser' - if [ -t 0 ]; then - if [ -n "$1" ]; then - wget -qO- $1 | browser - else - reference raw - fi - fi + if [ -t 0 ]; then + if [ -n "$1" ]; then + wget -qO- "$1" | browser + else + reference raw + fi + fi } diff --git a/plugins/available/cmd-returned-notify.plugin.bash b/plugins/available/cmd-returned-notify.plugin.bash index 88c07722df..e6d221faac 100644 --- a/plugins/available/cmd-returned-notify.plugin.bash +++ b/plugins/available/cmd-returned-notify.plugin.bash @@ -4,7 +4,8 @@ about-plugin 'Alert (BEL) when process ends after a threshold of seconds' function precmd_return_notification() { local command_start="${COMMAND_DURATION_START_SECONDS:=0}" - local current_time="${EPOCHREALTIME:-$SECONDS}" + local current_time + current_time="$(_shell_duration_en)" local -i command_duration="$((${current_time%.*} - ${command_start%.*}))" if [[ "${command_duration}" -gt "${NOTIFY_IF_COMMAND_RETURNS_AFTER:-5}" ]]; then printf '\a' diff --git a/plugins/available/colors.plugin.bash b/plugins/available/colors.plugin.bash index 47f55609af..73c144b88e 100644 --- a/plugins/available/colors.plugin.bash +++ b/plugins/available/colors.plugin.bash @@ -8,13 +8,13 @@ function __() { function __make_ansi() { next=$1 shift - echo "\[\e[$("__$next" "$@")m\]" + echo -e "\[\e[$("__$next" "$@")m\]" } function __make_echo() { next=$1 shift - echo "\033[$("__$next" "$@")m" + echo -e "\033[$("__$next" "$@")m" } function __reset() { diff --git a/plugins/available/dirs.plugin.bash b/plugins/available/dirs.plugin.bash index 34468fa061..55d2e88a1f 100644 --- a/plugins/available/dirs.plugin.bash +++ b/plugins/available/dirs.plugin.bash @@ -63,12 +63,15 @@ function dirs-help() { if [[ -f "${BASH_IT_DIRS_BKS?}" ]]; then # shellcheck disable=SC1090 source "${BASH_IT_DIRS_BKS?}" -elif [[ -f ~/.dirs ]]; then - mv -vn ~/.dirs "${BASH_IT_DIRS_BKS?}" - # shellcheck disable=SC1090 - source "${BASH_IT_DIRS_BKS?}" else - touch "${BASH_IT_DIRS_BKS?}" + mkdir -p "${BASH_IT_DIRS_BKS%/*}" + if [[ -f ~/.dirs ]]; then + mv -vn ~/.dirs "${BASH_IT_DIRS_BKS?}" + # shellcheck disable=SC1090 + source "${BASH_IT_DIRS_BKS?}" + else + touch "${BASH_IT_DIRS_BKS?}" + fi fi alias L='cat "${BASH_IT_DIRS_BKS?}"' diff --git a/plugins/available/gif.plugin.bash b/plugins/available/gif.plugin.bash index a04ff5c7d1..7cca37d4d2 100644 --- a/plugins/available/gif.plugin.bash +++ b/plugins/available/gif.plugin.bash @@ -64,7 +64,7 @@ function v2gif() { fi # Parse the options - args=$("$getopt" -l "alert:" -l "lossy:" -l "width:" -l del,delete -l high -l tag -l "fps:" -l webm -o "a:l:w:f:dhmt" -- "$@") || { + args=$("$getopt" -l "alert:" -l "lossy:" -l "width:" -l del,delete -l high -l help -l tag -l "fps:" -l webm -o "a:l:w:f:dhmt" -- "$@") || { echo 'Terminating...' >&2 return 2 } @@ -72,9 +72,9 @@ function v2gif() { eval set -- "$args" local use_gifski="" local opt_del_after="" - local maxsize="" - local lossiness="" - local maxwidthski="" + local maxsize=() + local lossiness=() + local maxwidthski=() local giftagopt="" local giftag="" local defaultfps=10 @@ -82,6 +82,7 @@ function v2gif() { local fps="" local make_webm="" local alert=5000 + local printhelp="" while [[ $# -ge 1 ]]; do case "$1" in --) @@ -94,6 +95,11 @@ function v2gif() { opt_del_after="true" shift ;; + --help) + # Print Help + printhelp="true" + shift + ;; -h | --high) #High Quality, use gifski gifski="$(type -p gifski)" @@ -106,8 +112,8 @@ function v2gif() { shift ;; -w | --width) - maxsize="-vf scale=$2:-1" - maxwidthski="-W $2" + maxsize=(-vf "scale=$2:-1") + maxwidthski=(-W "$2") giftag="${giftag}-w$2" shift 2 ;; @@ -118,7 +124,7 @@ function v2gif() { ;; -l | --lossy) # Use giflossy parameter - lossiness="--lossy=$2" + lossiness=("--lossy=$2") giftag="${giftag}-l$2" shift 2 ;; @@ -141,7 +147,7 @@ function v2gif() { esac done - if [[ -z "$*" ]]; then + if [[ -z "$*" || "$printhelp" ]]; then echo "$(tput setaf 1)No input files given. Example: v2gif file [file...] [-w ] [-l ] $(tput sgr 0)" echo "-d/--del/--delete Delete original vid if done suceessfully (and file not over the size limit)" echo "-h/--high High Quality - use Gifski instead of gifsicle" @@ -164,7 +170,7 @@ function v2gif() { local del_after=$opt_del_after if [[ -n "$make_webm" ]]; then - $ffmpeg -loglevel panic -i "$file" \ + $ffmpeg -loglevel warning -i "$file" \ -c:v libvpx -crf 4 -threads 0 -an -b:v 2M -auto-alt-ref 0 \ -quality best -loop 0 "${file%.*}.webm" || return 2 fi @@ -184,12 +190,12 @@ 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 v2gif-tmp-*.png "$maxwidthski" --fps "$(printf "%.0f" "$fps")" -o "$output_file" || return 2 + $ffmpeg -loglevel warning -i "$file" -r "$fps" -vcodec png v2gif-tmp-%05d.png \ + && $gifski "${maxwidthski[@]}" --fps "$(printf "%.0f" "$fps")" -o "$output_file" v2gif-tmp-*.png || return 2 else - $ffmpeg -loglevel panic -i "$file" "$maxsize" -r "$fps" -vcodec png v2gif-tmp-%05d.png \ + $ffmpeg -loglevel warning -i "$file" "${maxsize[@]}" -r "$fps" -vcodec png v2gif-tmp-%05d.png \ && $convert +dither -layers Optimize v2gif-tmp-*.png GIF:- \ - | $gifsicle "$lossiness" --no-warnings --colors 256 --delay="$(echo "100/$fps" | bc)" --loop --optimize=3 --multifile - > "$output_file" || return 2 + | $gifsicle "${lossiness[@]}" --no-warnings --colors 256 --delay="$(echo "100/$fps" | bc)" --loop --optimize=3 --multifile - > "$output_file" || return 2 fi rm v2gif-tmp-*.png @@ -299,7 +305,7 @@ function any2webm() { echo "$(tput setaf 2)Creating '$output_file' ...$(tput sgr 0)" - $ffmpeg -loglevel panic -i "$file" \ + $ffmpeg -loglevel warning -i "$file" \ -c:v libvpx -crf 4 -threads 0 -an -b:v "$bandwidth" -auto-alt-ref 0 \ -quality best "$fps" "$size" -loop 0 -pix_fmt yuva420p "$output_file" || return 2 diff --git a/plugins/available/jekyll.plugin.bash b/plugins/available/jekyll.plugin.bash index d818b07628..3c12d82662 100644 --- a/plugins/available/jekyll.plugin.bash +++ b/plugins/available/jekyll.plugin.bash @@ -30,8 +30,8 @@ function editpost() { pushd "${SITE}/_posts" > /dev/null || return for POST in *; do - DATE="$(echo "${POST}" | grep -oE "[0-9]{4}-[0-9]{1,2}-[0-9]{1,2}")" - TITLE="$(grep -oE "title: (.+)" < "${POST}")" + DATE="$(echo "${POST}" | grep -E -o "[0-9]{4}-[0-9]{1,2}-[0-9]{1,2}")" + TITLE="$(grep -E -o "title: (.+)" < "${POST}")" TITLE="${TITLE/title: /}" echo "${COUNTER}) ${DATE} ${TITLE}" POSTS[COUNTER]="$POST" diff --git a/plugins/available/jgitflow.plugin.bash b/plugins/available/jgitflow.plugin.bash index 83ee8a23f6..f0405cb916 100644 --- a/plugins/available/jgitflow.plugin.bash +++ b/plugins/available/jgitflow.plugin.bash @@ -1,47 +1,61 @@ +# shellcheck shell=bash +# shellcheck disable=SC2086 cite about-plugin about-plugin 'Maven jgitflow build helpers' +function pre-jgitflow { + about 'helper function for execute before jgitflow' + group 'jgitflow' +} + +function test-pre-jgitflow { + about 'helper function for starting a new hotfix' + group 'jgitflow' + + echo "Init pre-maven" && pre-jgitflow && echo "Finish pre-maven" +} + function hotfix-start { - about 'helper function for starting a new hotfix' - group 'jgitflow' + about 'helper function for starting a new hotfix' + group 'jgitflow' - mvn jgitflow:hotfix-start ${JGITFLOW_MVN_ARGUMENTS} + pre-jgitflow && mvn jgitflow:hotfix-start ${JGITFLOW_MVN_ARGUMENTS} } function hotfix-finish { - about 'helper function for finishing a hotfix' - group 'jgitflow' + about 'helper function for finishing a hotfix' + group 'jgitflow' - mvn jgitflow:hotfix-finish -Darguments="${JGITFLOW_MVN_ARGUMENTS}" && git push && git push origin master && git push --tags + pre-jgitflow && mvn jgitflow:hotfix-finish -Darguments="${JGITFLOW_MVN_ARGUMENTS}" && git push && git push origin master && git push --tags && mvn clean } function feature-start { - about 'helper function for starting a new feature' - group 'jgitflow' + about 'helper function for starting a new feature' + group 'jgitflow' - mvn jgitflow:feature-start ${JGITFLOW_MVN_ARGUMENTS} + pre-jgitflow && mvn jgitflow:feature-start ${JGITFLOW_MVN_ARGUMENTS} } function feature-finish { - about 'helper function for finishing a feature' - group 'jgitflow' + about 'helper function for finishing a feature' + group 'jgitflow' - mvn jgitflow:feature-finish ${JGITFLOW_MVN_ARGUMENTS} - echo -e '\033[32m----------------------------------------------------------------\033[0m' - echo -e '\033[32m===== REMEMBER TO CREATE A NEW RELEASE TO DEPLOY THIS FEATURE ====\033[0m' - echo -e '\033[32m----------------------------------------------------------------\033[0m' + pre-jgitflow && mvn jgitflow:feature-finish ${JGITFLOW_MVN_ARGUMENTS} && mvn clean + echo -e '\033[32m----------------------------------------------------------------\033[0m' + echo -e '\033[32m===== REMEMBER TO CREATE A NEW RELEASE TO DEPLOY THIS FEATURE ====\033[0m' + echo -e '\033[32m----------------------------------------------------------------\033[0m' } function release-start { - about 'helper function for starting a new release' - group 'jgitflow' + about 'helper function for starting a new release' + group 'jgitflow' - mvn jgitflow:release-start ${JGITFLOW_MVN_ARGUMENTS} + pre-jgitflow && mvn jgitflow:release-start ${JGITFLOW_MVN_ARGUMENTS} } function release-finish { - about 'helper function for finishing a release' - group 'jgitflow' + about 'helper function for finishing a release' + group 'jgitflow' - mvn jgitflow:release-finish -Darguments="${JGITFLOW_MVN_ARGUMENTS}" && git push && git push origin master && git push --tags + pre-jgitflow && mvn jgitflow:release-finish -Darguments="${JGITFLOW_MVN_ARGUMENTS}" && git push && git push origin master && git push --tags && mvn clean } diff --git a/plugins/available/nvm.plugin.bash b/plugins/available/nvm.plugin.bash index 0e6da5d8cf..4dc4c6d630 100644 --- a/plugins/available/nvm.plugin.bash +++ b/plugins/available/nvm.plugin.bash @@ -9,10 +9,18 @@ cite about-plugin about-plugin 'node version manager configuration' export NVM_DIR="${NVM_DIR:-$HOME/.nvm}" + +# first check if NVM is managed by brew +NVM_BREW_PREFIX="" +if _bash_it_homebrew_check +then + NVM_BREW_PREFIX=$(brew --prefix nvm 2>/dev/null) +fi + # This loads nvm -if _bash_it_homebrew_check && [[ -s "${BASH_IT_HOMEBREW_PREFIX}/nvm.sh" ]] +if [[ -n "$NVM_BREW_PREFIX" && -s "${NVM_BREW_PREFIX}/nvm.sh" ]] then - source "${BASH_IT_HOMEBREW_PREFIX}/nvm.sh" + source "${NVM_BREW_PREFIX}/nvm.sh" else [[ -s "$NVM_DIR/nvm.sh" ]] && source "$NVM_DIR/nvm.sh" fi diff --git a/plugins/available/postgres.plugin.bash b/plugins/available/postgres.plugin.bash index 8f239985e0..9f66152b5c 100644 --- a/plugins/available/postgres.plugin.bash +++ b/plugins/available/postgres.plugin.bash @@ -1,3 +1,4 @@ +# shellcheck shell=bash cite about-plugin about-plugin 'postgres helper functions' @@ -50,7 +51,7 @@ function postgres_status { function is_postgres_running { - $POSTGRES_BIN/pg_ctl -D $PGDATA status | egrep -o "no server running" + $POSTGRES_BIN/pg_ctl -D $PGDATA status | grep -F -o "no server running" } diff --git a/plugins/available/projects.plugin.bash b/plugins/available/projects.plugin.bash index 803864806a..34fa001e0e 100644 --- a/plugins/available/projects.plugin.bash +++ b/plugins/available/projects.plugin.bash @@ -21,7 +21,7 @@ function pj() { # with the same name in project directories IFS=':' read -ra dests <<< "${BASH_IT_PROJECT_PATHS?${FUNCNAME[0]}: project working folders must be configured}" for d in "${!dests[@]}"; do - if [[ ! -d "${dests[d]}" ]]; then + if [[ ! -d "${dests[d]}/${proj}" ]]; then unset 'dests[d]' fi done diff --git a/plugins/available/url.plugin.bash b/plugins/available/url.plugin.bash new file mode 100644 index 0000000000..72a41bfd3a --- /dev/null +++ b/plugins/available/url.plugin.bash @@ -0,0 +1,45 @@ +# shellcheck shell=bash +cite about-plugin +about-plugin 'Basic url handling and manipulation functions' + +function slugify() { + about 'takes the text and transform to slug url, also supports formats like (html,link,rst,md)' + group 'url' + param "1: Text to transform (optional)" + param "2: Output format (html,rst,link,md). Omit or pass any text to return only output" + + local TXT=$1 + local OUTPUT=$2 + local SLUG + + if [[ -z $TXT ]]; then + read -rp "Enter the valid string: " TXT + fi + + # Pass 1 - Clean the url + # Credits: https://stackoverflow.com/a/20007549/10362396 + SLUG=$(echo -n "$TXT" | tr -cd ' [:alnum:]._-' | tr -s ' ') + + # Pass 2 - Transformation + SLUG=$(echo -n "$SLUG" | tr '[:upper:]' '[:lower:]' | tr ' ' '-') + + case "$OUTPUT" in + html | htm) + echo "$TXT" + ;; + href | link) + echo "#$SLUG" + ;; + md) + echo "[$TXT](#$SLUG)" + ;; + rst) + echo "\`$TXT <#$SLUG>\`_" + ;; + + *) + echo "$SLUG" + ;; + esac + +} diff --git a/template/bash_profile.template.bash b/template/bash_profile.template.bash index 3def286612..4b90990489 100755 --- a/template/bash_profile.template.bash +++ b/template/bash_profile.template.bash @@ -11,7 +11,7 @@ export BASH_IT="{{BASH_IT}}" # Lock and Load a custom theme file. # Leave empty to disable theming. -# location /.bash_it/themes/ +# location "$BASH_IT"/themes/ export BASH_IT_THEME='bobby' # Some themes can show whether `sudo` has a current token or not. diff --git a/test/plugins/cmd-returned-notify.plugin.bats b/test/plugins/cmd-returned-notify.plugin.bats index a849dca8f8..28a3666d67 100644 --- a/test/plugins/cmd-returned-notify.plugin.bats +++ b/test/plugins/cmd-returned-notify.plugin.bats @@ -10,7 +10,8 @@ function local_setup_file() { @test "plugins cmd-returned-notify: notify after elapsed time" { NOTIFY_IF_COMMAND_RETURNS_AFTER=0 - COMMAND_DURATION_START_SECONDS="${EPOCHREALTIME:-$SECONDS}" + COMMAND_DURATION_START_SECONDS="$(_shell_duration_en)" + export COMMAND_DURATION_START_SECONDS NOTIFY_IF_COMMAND_RETURNS_AFTER sleep 1 run precmd_return_notification assert_success @@ -19,7 +20,8 @@ function local_setup_file() { @test "plugins cmd-returned-notify: do not notify before elapsed time" { NOTIFY_IF_COMMAND_RETURNS_AFTER=10 - COMMAND_DURATION_START_SECONDS="${EPOCHREALTIME:-$SECONDS}" + COMMAND_DURATION_START_SECONDS="$(_shell_duration_en)" + export COMMAND_DURATION_START_SECONDS NOTIFY_IF_COMMAND_RETURNS_AFTER sleep 1 run precmd_return_notification assert_success @@ -35,7 +37,7 @@ function local_setup_file() { @test "lib command_duration: preexec set COMMAND_DURATION_START_SECONDS" { COMMAND_DURATION_START_SECONDS= assert_equal "${COMMAND_DURATION_START_SECONDS}" "" - NOW="${EPOCHREALTIME:-$SECONDS}" + NOW="$(_shell_duration_en)" _command_duration_pre_exec # We need to make sure to account for nanoseconds... assert_equal "${COMMAND_DURATION_START_SECONDS%.*}" "${NOW%.*}" diff --git a/test/test_helper.bash b/test/test_helper.bash index 9728801681..58daeeef19 100644 --- a/test/test_helper.bash +++ b/test/test_helper.bash @@ -41,7 +41,7 @@ function common_setup_file() { BASH_IT="${BATS_FILE_TMPDIR//\/\///}/.bash_it" # This 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. - git --git-dir="${MAIN_BASH_IT_GITDIR?}" worktree add -d "${BASH_IT}" + git --git-dir="${MAIN_BASH_IT_GITDIR?}" worktree add --detach "${BASH_IT}" load "${BASH_IT?}/vendor/github.com/erichs/composure/composure.sh" # support 'plumbing' metadata diff --git a/themes/agnoster/agnoster.theme.bash b/themes/agnoster/agnoster.theme.bash index 20c184f382..d5bac5ca69 100644 --- a/themes/agnoster/agnoster.theme.bash +++ b/themes/agnoster/agnoster.theme.bash @@ -182,7 +182,7 @@ prompt_segment() { # declare -p codes if [[ $CURRENT_BG != NONE && $1 != "$CURRENT_BG" ]]; then - declare -a intermediate=("$(fg_color $CURRENT_BG)" "$(bg_color "$1")") + declare -a intermediate=("$(fg_color "$CURRENT_BG")" "$(bg_color "$1")") debug "pre prompt " "$(ansi intermediate[@])" PR="$PR $(ansi intermediate[@])$SEGMENT_SEPARATOR" debug "post prompt " "$(ansi codes[@])" diff --git a/themes/barbuk/barbuk.theme.bash b/themes/barbuk/barbuk.theme.bash index b614d148c1..6e6eb88aaf 100644 --- a/themes/barbuk/barbuk.theme.bash +++ b/themes/barbuk/barbuk.theme.bash @@ -1,8 +1,11 @@ # shellcheck shell=bash # shellcheck disable=SC2034 # Expected behavior for themes. -# shellcheck disable=SC2154 #TODO: fix these all. + +# Prompt defaut configuration +BARBUK_PROMPT=${BARBUK_PROMPT:="git-uptream-remote-logo ssh path scm python_venv ruby node terraform cloud duration exit"} # Theme custom glyphs +# SCM SCM_GIT_CHAR_GITLAB=${BARBUK_GITLAB_CHAR:=' '} SCM_GIT_CHAR_BITBUCKET=${BARBUK_BITBUCKET_CHAR:=' '} SCM_GIT_CHAR_GITHUB=${BARBUK_GITHUB_CHAR:=' '} @@ -10,13 +13,20 @@ 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 EXIT_CODE_ICON=${BARBUK_EXIT_CODE_ICON:=' '} +# Programming and tools PYTHON_VENV_CHAR=${BARBUK_PYTHON_VENV_CHAR:=' '} -COMMAND_DURATION_ICON=${BARBUK_COMMAND_DURATION_ICON:-"$bold_blue  "} +RUBY_CHAR=${BARBUK_RUBY_CHAR:=' '} +NODE_CHAR=${BARBUK_NODE_CHAR:=' '} +TERRAFORM_CHAR=${BARBUK_TERRAFORM_CHAR:="❲t❳ "} +# Cloud +AWS_PROFILE_CHAR=${BARBUK_AWS_PROFILE_CHAR:=" aws "} +SCALEWAY_PROFILE_CHAR=${BARBUK_SCALEWAY_PROFILE_CHAR:=" scw "} +GCLOUD_CHAR=${BARBUK_GCLOUD_CHAR:=" google "} # Command duration COMMAND_DURATION_MIN_SECONDS=${COMMAND_DURATION_MIN_SECONDS:-1} -COMMAND_DURATION_COLOR="$normal" # Ssh user and hostname display SSH_INFO=${BARBUK_SSH_INFO:=true} @@ -24,24 +34,32 @@ 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}✓" +SCM_THEME_PROMPT_DIRTY=" ${bold_red?}✗" +SCM_THEME_PROMPT_CLEAN=" ${bold_green?}✓" SCM_THEME_PROMPT_PREFIX="|" -SCM_THEME_PROMPT_SUFFIX="${green}| " -SCM_GIT_BEHIND_CHAR="${bold_red}↓${normal}" -SCM_GIT_AHEAD_CHAR="${bold_green}↑${normal}" +SCM_THEME_PROMPT_SUFFIX="${green?}| " +SCM_GIT_BEHIND_CHAR="${bold_red?}↓${normal?}" +SCM_GIT_AHEAD_CHAR="${bold_green?}↑${normal?}" SCM_GIT_UNTRACKED_CHAR="⌀" -SCM_GIT_UNSTAGED_CHAR="${bold_yellow}•${normal}" -SCM_GIT_STAGED_CHAR="${bold_green}+${normal}" -GIT_THEME_PROMPT_DIRTY=" ${bold_red}✗" -GIT_THEME_PROMPT_CLEAN=" ${bold_green}✓" -GIT_THEME_PROMPT_PREFIX="${cyan}" -GIT_THEME_PROMPT_SUFFIX="${cyan}" -SCM_THEME_BRANCH_TRACK_PREFIX="${normal} ⤏ ${cyan}" +SCM_GIT_UNSTAGED_CHAR="${bold_yellow?}•${normal?}" +SCM_GIT_STAGED_CHAR="${bold_green?}+${normal?}" +GIT_THEME_PROMPT_DIRTY=" ${bold_red?}✗" +GIT_THEME_PROMPT_CLEAN=" ${bold_green?}✓" +GIT_THEME_PROMPT_PREFIX="${cyan?}" +GIT_THEME_PROMPT_SUFFIX="${cyan?}" +SCM_THEME_BRANCH_TRACK_PREFIX="${normal?} ⤏ ${cyan?}" SCM_THEME_CURRENT_USER_PREFFIX='  ' SCM_GIT_SHOW_CURRENT_USER=false - -function _git-uptream-remote-logo { +NVM_THEME_PROMPT_PREFIX='' +NVM_THEME_PROMPT_SUFFIX='' +RVM_THEME_PROMPT_PREFIX='' +RVM_THEME_PROMPT_SUFFIX='' +RBENV_THEME_PROMPT_PREFIX=' ' +RBENV_THEME_PROMPT_SUFFIX='' +RBFU_THEME_PROMPT_PREFIX='' +RBFU_THEME_PROMPT_SUFFIX='' + +function __git-uptream-remote-logo_prompt() { [[ "$(_git-upstream)" == "" ]] && SCM_GIT_CHAR="$SCM_GIT_CHAR_DEFAULT" local remote remote_domain @@ -57,36 +75,72 @@ function _git-uptream-remote-logo { bitbucket) SCM_GIT_CHAR="$SCM_GIT_CHAR_BITBUCKET" ;; *) SCM_GIT_CHAR="$SCM_GIT_CHAR_DEFAULT" ;; esac + + echo "${purple?}$(scm_char)" } -function git_prompt_info { +function git_prompt_info() { git_prompt_vars - echo -e " on $SCM_GIT_CHAR_ICON_BRANCH $SCM_PREFIX$SCM_BRANCH$SCM_STATE$SCM_GIT_AHEAD$SCM_GIT_BEHIND$SCM_GIT_STASH$SCM_SUFFIX" + echo -e "on $SCM_GIT_CHAR_ICON_BRANCH $SCM_PREFIX$SCM_BRANCH$SCM_STATE$SCM_GIT_AHEAD$SCM_GIT_BEHIND$SCM_GIT_STASH$SCM_SUFFIX " } -function _exit-code { - if [[ "$1" -ne 0 ]]; then - exit_code=" ${purple}${EXIT_CODE_ICON}${yellow}${exit_code}${bold_orange}" +function __exit_prompt() { + if [[ "$exit_code" -ne 0 ]]; then + echo "${purple?}${EXIT_CODE_ICON}${yellow?}${exit_code}${bold_orange?} " else - exit_code="${bold_green}" + echo "${bold_green}" fi } -function _prompt { - local exit_code="$?" wrap_char=' ' dir_color=$green ssh_info='' python_venv='' host command_duration= +function __aws_profile_prompt() { + if [[ -n "${AWS_PROFILE}" ]]; then + echo -n "${bold_purple?}${AWS_PROFILE_CHAR}${normal?}${AWS_PROFILE} " + fi +} - command_duration=$(_command_duration) +function __scaleway_profile_prompt() { + if [[ -n "${SCW_PROFILE}" ]]; then + echo -n "${bold_purple?}${SCALEWAY_PROFILE_CHAR}${normal?}${SCW_PROFILE} " + fi +} + +function __gcloud_prompt() { + local active_gcloud_account="" - _exit-code exit_code - _git-uptream-remote-logo + active_gcloud_account="$(active_gcloud_account_prompt)" + [[ -n "${active_gcloud_account}" ]] && echo "${bold_purple?}${GCLOUD_CHAR}${normal?}${active_gcloud_account} " +} - history -a +function __cloud_prompt() { + __aws_profile_prompt + __scaleway_profile_prompt + __gcloud_prompt +} - # Detect root shell - if [ "$(whoami)" = root ]; then - dir_color=$red +function __terraform_prompt() { + local terraform_workspace="" + + if [ -d .terraform ]; then + terraform_workspace="$(terraform_workspace_prompt)" + [[ -n "${terraform_workspace}" ]] && echo "${bold_purple?}${TERRAFORM_CHAR}${normal?}${terraform_workspace} " fi +} + +function __node_prompt() { + local node_version="" + + node_version="$(node_version_prompt)" + [[ -n "${node_version}" ]] && echo "${bold_purple?}${NODE_CHAR}${normal?}${node_version} " +} +function __ruby_prompt() { + local ruby_version="" + + ruby_version="$(ruby_version_prompt)" + [[ -n "${ruby_version}" ]] && echo "${bold_purple?}${RUBY_CHAR}${normal?}${ruby_version} " +} + +function __ssh_prompt() { # Detect ssh if [[ -n "${SSH_CONNECTION}" ]] && [ "$SSH_INFO" = true ]; then if [ "$HOST_INFO" = long ]; then @@ -94,19 +148,56 @@ function _prompt { else host="\h" fi - ssh_info="${bold_blue}\u${bold_orange}@${cyan}$host ${bold_orange}in" + echo "${bold_blue?}\u${bold_orange?}@${cyan?}$host ${bold_orange?}in " fi +} +function __python_venv_prompt() { # Detect python venv if [[ -n "${CONDA_DEFAULT_ENV}" ]]; then - python_venv="$PYTHON_VENV_CHAR${CONDA_DEFAULT_ENV} " + echo "${bold_purple?}$PYTHON_VENV_CHAR${normal?}${CONDA_DEFAULT_ENV} " elif [[ -n "${VIRTUAL_ENV}" ]]; then - python_venv="$PYTHON_VENV_CHAR$(basename "${VIRTUAL_ENV}") " + echo "${bold_purple?}$PYTHON_VENV_CHAR${normal?}$(basename "${VIRTUAL_ENV}") " + fi +} + +function __path_prompt() { + local dir_color=${green?} + # Detect root shell + if [ "$(whoami)" = root ]; then + dir_color=${red?} + fi + + echo "${dir_color}\w${normal} " +} + +function __scm_prompt() { + scm_prompt_info +} + +function __duration_prompt() { + [[ -n "$command_duration" ]] && echo "${command_duration} " +} + +function __prompt-command() { + exit_code="$?" + command_duration=$(_command_duration) + local wrap_char + + # Generate prompt + PS1="\n " + for segment in $BARBUK_PROMPT; do + local info + info="$(__"${segment}"_prompt)" + [[ -n "${info}" ]] && PS1+="${info}" + done + + # Cut prompt when it's too long + if [[ ${#PS1} -gt $((COLUMNS * 2)) ]]; then + wrap_char="\n" fi - PS1="\\n${ssh_info} ${purple}$(scm_char)${python_venv}${dir_color}\\w${normal}$(scm_prompt_info)${command_duration}${exit_code}" - [[ ${#PS1} -gt $((COLUMNS * 2)) ]] && wrap_char="\\n" PS1="${PS1}${wrap_char}❯${normal} " } -safe_append_prompt_command _prompt +safe_append_prompt_command __prompt-command diff --git a/themes/base.theme.bash b/themes/base.theme.bash index 92a56e5ec0..d78baa6adf 100644 --- a/themes/base.theme.bash +++ b/themes/base.theme.bash @@ -74,6 +74,9 @@ SCM_NONE_CHAR='○' NVM_THEME_PROMPT_PREFIX=' |' NVM_THEME_PROMPT_SUFFIX='|' +NODE_THEME_PROMPT_PREFIX=' |' +NODE_THEME_PROMPT_SUFFIX='|' + RVM_THEME_PROMPT_PREFIX=' |' RVM_THEME_PROMPT_SUFFIX='|' @@ -399,8 +402,24 @@ function nvm_version_prompt() { fi } +function node_native_version_prompt() { + local node + if _command_exists node; then + node=$(node --version 2> /dev/null) + echo -ne "${NODE_THEME_PROMPT_PREFIX-}${node}${NODE_THEME_PROMPT_SUFFIX-}" + fi +} + function node_version_prompt() { - nvm_version_prompt + NODE_VERSION_STRATEGY="${NODE_VERSION_STRATEGY:-nvm}" + + _log_debug "node: using version strategy '$NODE_VERSION_STRATEGY'" + + if [ "$NODE_VERSION_STRATEGY" == "nvm" ]; then + nvm_version_prompt + elif [ "$NODE_VERSION_STRATEGY" == "node" ]; then + node_native_version_prompt + fi } function rvm_version_prompt() { diff --git a/themes/bira/bira.theme.bash b/themes/bira/bira.theme.bash index f30d8d5d00..cba4e425b8 100644 --- a/themes/bira/bira.theme.bash +++ b/themes/bira/bira.theme.bash @@ -6,6 +6,8 @@ SCM_THEME_PROMPT_SUFFIX="›${reset_color?}" VIRTUALENV_THEME_PROMPT_PREFIX=" ${cyan?}‹" VIRTUALENV_THEME_PROMPT_SUFFIX="›${reset_color?}" +CONDAENV_THEME_PROMPT_PREFIX=" ${cyan?}‹" +CONDAENV_THEME_PROMPT_SUFFIX="›${reset_color?}" bold="\[\e[1m\]" @@ -18,7 +20,7 @@ fi function prompt_command() { local current_dir=" ${bold_blue?}\w${normal?}${reset_color?}" local virtualenv_prompt scm_prompt_info - virtualenv_prompt="$(virtualenv_prompt)" + virtualenv_prompt="${virtualenv_prompt:-$(condaenv_prompt)}" scm_prompt_info="$(scm_prompt_info)" PS1="╭─${user_host?}${current_dir}${virtualenv_prompt}${scm_prompt_info}\n╰─${bold?}\\$ ${normal?}" } diff --git a/themes/brainy/brainy.theme.bash b/themes/brainy/brainy.theme.bash index e1c3617531..b93c768f56 100644 --- a/themes/brainy/brainy.theme.bash +++ b/themes/brainy/brainy.theme.bash @@ -168,7 +168,7 @@ ___brainy_prompt_battery() { box="[|]" ac_adapter_connected && charging="+" ac_adapter_disconnected && charging="-" - info+=$charging + info+="$charging" [ "$info" == "100+" ] && info="AC" printf "%s|%s|%s|%s" "${color}" "${info}" "${bold_white}" "${box}" } diff --git a/themes/clean/clean.theme.bash b/themes/clean/clean.theme.bash index 0082d671a0..47a436b34d 100644 --- a/themes/clean/clean.theme.bash +++ b/themes/clean/clean.theme.bash @@ -1,19 +1,24 @@ +# shellcheck shell=bash +# shellcheck disable=SC2034 # Expected behavior for themes. + # git theming -SCM_THEME_PROMPT_PREFIX="${bold_blue}(${yellow}" -SCM_THEME_PROMPT_SUFFIX="${bold_blue})${reset_color} " +SCM_THEME_PROMPT_PREFIX="${bold_blue?}(${yellow?}" +SCM_THEME_PROMPT_SUFFIX="${bold_blue?})${reset_color?} " SCM_THEME_PROMPT_CLEAN="" -SCM_THEME_PROMPT_DIRTY="${bold_red}✗" - +SCM_THEME_PROMPT_DIRTY="${bold_red?}✗" # LS colors, made with http://geoff.greer.fm/lscolors/ export LSCOLORS="Gxfxcxdxbxegedabagacad" export LS_COLORS='no=00:fi=00:di=01;34:ln=00;36:pi=40;33:so=01;35:do=01;35:bd=40;33;01:cd=40;33;01:or=41;33;01:ex=00;32:*.cmd=00;32:*.exe=01;32:*.com=01;32:*.bat=01;32:*.btm=01;32:*.dll=01;32:*.tar=00;31:*.tbz=00;31:*.tgz=00;31:*.rpm=00;31:*.deb=00;31:*.arj=00;31:*.taz=00;31:*.lzh=00;31:*.lzma=00;31:*.zip=00;31:*.zoo=00;31:*.z=00;31:*.Z=00;31:*.gz=00;31:*.bz2=00;31:*.tb2=00;31:*.tz2=00;31:*.tbz2=00;31:*.avi=01;35:*.bmp=01;35:*.fli=01;35:*.gif=01;35:*.jpg=01;35:*.jpeg=01;35:*.mng=01;35:*.mov=01;35:*.mpg=01;35:*.pcx=01;35:*.pbm=01;35:*.pgm=01;35:*.png=01;35:*.ppm=01;35:*.tga=01;35:*.tif=01;35:*.xbm=01;35:*.xpm=01;35:*.dl=01;35:*.gl=01;35:*.wmv=01;35:*.aiff=00;32:*.au=00;32:*.mid=00;32:*.mp3=00;32:*.ogg=00;32:*.voc=00;32:*.wav=00;32:' function prompt_command() { + if [ "$(whoami)" = root ]; then + no_color=${red?} + else + no_color=${white?} + fi - if [ "$(whoami)" = root ]; then no_color=$red; else no_color=$white; fi - - PS1="${no_color}\u${reset_color}:${blue}\W/${reset_color} $(scm_prompt_info)${normal}$ " + PS1="${no_color}\u${reset_color}:${blue?}\W/${reset_color} $(scm_prompt_info)${normal?}$ " } safe_append_prompt_command prompt_command diff --git a/themes/elixr/elixr.theme.bash b/themes/elixr/elixr.theme.bash index 266abbad43..d266fae89d 100644 --- a/themes/elixr/elixr.theme.bash +++ b/themes/elixr/elixr.theme.bash @@ -1,15 +1,16 @@ -#!/usr/bin/env bash +# shellcheck shell=bash +# shellcheck disable=SC2034 # Expected behavior for themes. -SCM_THEME_PROMPT_DIRTY=" ${red}✗" -SCM_THEME_PROMPT_CLEAN=" ${bold_green}✓" -SCM_THEME_PROMPT_PREFIX=" ${green}| " -SCM_THEME_PROMPT_SUFFIX="${green} |" +SCM_THEME_PROMPT_DIRTY=" ${red?}✗" +SCM_THEME_PROMPT_CLEAN=" ${bold_green?}✓" +SCM_THEME_PROMPT_PREFIX=" ${green?}| " +SCM_THEME_PROMPT_SUFFIX="${green?} |" SCM_NONE_CHAR='◐ ' SCM_GIT_SHOW_MINIMAL_INFO=true -GIT_THEME_PROMPT_DIRTY=" ${red}✗" -GIT_THEME_PROMPT_CLEAN=" ${bold_green}✓" -GIT_THEME_PROMPT_PREFIX=" ${green}|" -GIT_THEME_PROMPT_SUFFIX="${green}|" +GIT_THEME_PROMPT_DIRTY=" ${red?}✗" +GIT_THEME_PROMPT_CLEAN=" ${bold_green?}✓" +GIT_THEME_PROMPT_PREFIX=" ${green?}|" +GIT_THEME_PROMPT_SUFFIX="${green?}|" RVM_THEME_PROMPT_PREFIX="|" RVM_THEME_PROMPT_SUFFIX=" d|" @@ -17,7 +18,7 @@ RVM_THEME_PROMPT_SUFFIX=" d|" BOLD="\[\e[1m\]" function prompt_command() { - PS1="\n${bold_cyan}$(scm_prompt_char_info)$(virtualenv_prompt) ${bold_cyan}\w :${reset_color}${normal}${BOLD} " + PS1="\n${bold_cyan?}$(scm_prompt_char_info)$(virtualenv_prompt) ${bold_cyan}\w :${reset_color?}${normal?}${BOLD} " } safe_append_prompt_command prompt_command diff --git a/themes/inretio/inretio.theme.bash b/themes/inretio/inretio.theme.bash new file mode 100644 index 0000000000..1db6c6d1f4 --- /dev/null +++ b/themes/inretio/inretio.theme.bash @@ -0,0 +1,100 @@ +# shellcheck shell=bash +# shellcheck disable=SC2034 # Expected behavior for themes. + +# Inretio theme for Bash-it +# Contact: bashit@inretio.eu + +# Inspired by existing themes: +# - metal +# - bobby + +# virtualenv prompts +VIRTUALENV_CHAR=" ⓔ" +VIRTUALENV_THEME_PROMPT_PREFIX="" +VIRTUALENV_THEME_PROMPT_SUFFIX="" + +# SCM prompts +SCM_NONE_CHAR="" +SCM_GIT_CHAR="[±] " +SCM_GIT_BEHIND_CHAR="${red?}↓${normal?}" +SCM_GIT_AHEAD_CHAR="${bold_green?}↑${normal?}" +SCM_GIT_UNTRACKED_CHAR="⌀" +SCM_GIT_UNSTAGED_CHAR="${bold_yellow?}•${normal?}" +SCM_GIT_STAGED_CHAR="${bold_green?}+${normal?}" + +SCM_THEME_PROMPT_DIRTY="" +SCM_THEME_PROMPT_CLEAN="" +SCM_THEME_PROMPT_PREFIX="" +SCM_THEME_PROMPT_SUFFIX="" + +# Git status prompts +GIT_THEME_PROMPT_DIRTY=" ${red?}✗${normal?}" +GIT_THEME_PROMPT_CLEAN=" ${bold_green?}✓${normal?}" +GIT_THEME_PROMPT_PREFIX="" +GIT_THEME_PROMPT_SUFFIX="" + +# ICONS ======================================================================= + +icon_start="┌──" +icon_user=" 🐧 " +icon_host=" 💻 " +icon_directory=" 📂 " +icon_branch="🌵" +icon_end="└> " + +# extra spaces ensure legiblity in prompt + +# FUNCTIONS =================================================================== + +# Display virtual environment info +function _virtualenv_prompt { + VIRTUALENV_DETAILS="" + VIRTUALENV_CHAR="" + + # $VIRTUAL_ENV is set and is non-zero length + if [[ -n "$VIRTUAL_ENV" ]]; then + # Check if Python 3 exists + if command -v python3 > /dev/null 2>&1; then + VIRTUALENV_DETAILS="$("$VIRTUAL_ENV/bin/python" --version | sed 's,Python ,,') on [$(basename "$VIRTUAL_ENV")]" + VIRTUALENV_CHAR=" 🐍" + else + VIRTUALENV_DETAILS="[$(basename "$VIRTUAL_ENV")]" + VIRTUALENV_CHAR=" ⓔ" + fi + fi + + echo "$VIRTUALENV_CHAR $VIRTUALENV_DETAILS" +} + +# Rename tab +function tabname { + printf "\e]1;%s\a" "$1" +} + +# Rename window +function winname { + printf "\e]2;%s\a" "$1" +} + +_theme_clock() { + printf '[%s]' "$(clock_prompt)" + + if [ "${THEME_SHOW_CLOCK_CHAR}" == "true" ]; then + printf '%s' "$(clock_char) " + fi +} +THEME_SHOW_CLOCK_CHAR=${THEME_SHOW_CLOCK_CHAR:-"false"} +THEME_CLOCK_CHAR_COLOR=${THEME_CLOCK_CHAR_COLOR:-"$red"} +THEME_CLOCK_COLOR=${THEME_CLOCK_COLOR:-"$normal"} +THEME_CLOCK_FORMAT=${THEME_CLOCK_FORMAT:-"%Y-%m-%d %H:%M:%S"} + +# PROMPT OUTPUT =============================================================== + +# Displays the current prompt +function prompt_command() { + PS1="\n${icon_start}$(_theme_clock)${icon_user}${bold_green?}\u${normal}${icon_host}${bold_cyan?}\h${normal}${green?}$(_virtualenv_prompt)${normal}${icon_directory}${bold_purple?}\W${normal}\$([[ -n \$(git branch 2> /dev/null) ]] && echo \" on ${icon_branch} $(scm_prompt_info) \")${white?}${normal}\n${icon_end}" + PS2="${icon_end}" +} + +# Runs prompt (this bypasses bash_it $PROMPT setting) +safe_append_prompt_command prompt_command diff --git a/themes/lambda/lambda.theme.bash b/themes/lambda/lambda.theme.bash new file mode 100644 index 0000000000..59f82a4a81 --- /dev/null +++ b/themes/lambda/lambda.theme.bash @@ -0,0 +1,35 @@ +# shellcheck shell=bash +# shellcheck disable=SC1090,SC2034 + +function set_prompt { + local user_color="\[\033[1;31m\]" # bold red for username + local at_color="\[\033[1;37m\]" # bold white for @ symbol + local host_color="\[\033[1;31m\]" # bold red for hostname + local in_color="\[\033[1;37m\]" # bold white for "in" + local dir_color="\[\033[1;35m\]" # bold purple for current working directory + local git_color="\[\033[1;36m\]" # bold cyan for Git information + local time_color="\[\033[1;32m\]" # bold green for time taken + local reset_color="\[\033[0m\]" # reset color + local prompt_symbol_color="\[\033[1;31m\]" # bold red for the prompt symbol + + local end_time time_taken + end_time=$(date +%s%3N) # current time in milliseconds + # shellcheck disable=SC2154 + time_taken=$((end_time - start_time)) # time in milliseconds + + PS1="${user_color}╭─\\u" # username + PS1+="${at_color}@${host_color}\\h" # @ symbol and hostname + PS1+="${in_color} in" # "in" between hostname and current directory + PS1+="${dir_color} \\w" # current working directory + + # Git information (status symbol) + PS1+=" ${git_color}$(__git_ps1 "[%s]")${reset_color}" + + if [ $time_taken -gt 0 ]; then + PS1+=" ${time_color}took ${time_taken}ms" # time taken in milliseconds + fi + + PS1+="\n${prompt_symbol_color}╰─λ${reset_color} " # red color for the prompt symbol, reset color after +} + +PROMPT_COMMAND='start_time=$(date +%s%3N); set_prompt' diff --git a/themes/liquidprompt/liquidprompt.theme.bash b/themes/liquidprompt/liquidprompt.theme.bash index 60e64210c4..17458fd5f1 100644 --- a/themes/liquidprompt/liquidprompt.theme.bash +++ b/themes/liquidprompt/liquidprompt.theme.bash @@ -21,7 +21,7 @@ export LP_BATTERY_THRESHOLD=${LP_BATTERY_THRESHOLD:-75} export LP_LOAD_THRESHOLD=${LP_LOAD_THRESHOLD:-60} export LP_TEMP_THRESHOLD=${LP_TEMP_THRESHOLD:-80} - +unset _lp_legacy _lp_escape __lp_escape source "$targetdir/liquidprompt" prompt() { true; } export PS2=" ┃ " @@ -29,22 +29,37 @@ export LP_PS1_PREFIX="┌─" export LP_PS1_POSTFIX="\n└▪ " export LP_ENABLE_RUNTIME=0 +_lp_legacy() +{ + type -t _lp_escape &> /dev/null +} + +_lp_legacy && __lp_escape() +{ + ret="$(_lp_escape "$@")" +} + _lp_git_branch() { (( LP_ENABLE_GIT )) || return \git rev-parse --is-inside-work-tree >/dev/null 2>&1 || return - local branch + local commit branch ret + + commit="$(\git rev-parse --short -q HEAD 2>/dev/null)" + # Recent versions of Git support the --short option for symbolic-ref, but # not 1.7.9 (Ubuntu 12.04) if branch="$(\git symbolic-ref -q HEAD)"; then - _lp_escape "$(\git rev-parse --short=5 -q HEAD 2>/dev/null):${branch#refs/heads/}" + __lp_escape "$commit:${branch#refs/heads/}" + lp_vcs_branch="$ret" else # In detached head state, use commit instead # No escape needed - \git rev-parse --short -q HEAD 2>/dev/null + lp_vcs_branch="$commit" fi + _lp_legacy && echo $lp_vcs_branch || return 0 } _lp_time() { diff --git a/themes/oh-my-posh/oh-my-posh.theme.bash b/themes/oh-my-posh/oh-my-posh.theme.bash new file mode 100644 index 0000000000..430c8acb4c --- /dev/null +++ b/themes/oh-my-posh/oh-my-posh.theme.bash @@ -0,0 +1,8 @@ +# shellcheck shell=bash + +if _command_exists oh-my-posh; then + export POSH_THEME=${POSH_THEME:-https://raw.githubusercontent.com/JanDeDobbeleer/oh-my-posh/v$(oh-my-posh --version)/themes/jandedobbeleer.omp.json} + eval "$(oh-my-posh init bash --config "${POSH_THEME}")" +else + _log_warning "The oh-my-posh binary was not found on your PATH. Falling back to your existing PS1, please see the docs for more info." +fi diff --git a/themes/parrot/parrot.theme.bash b/themes/parrot/parrot.theme.bash index a0d259dd62..251eb942f7 100644 --- a/themes/parrot/parrot.theme.bash +++ b/themes/parrot/parrot.theme.bash @@ -2,7 +2,7 @@ # 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() { diff --git a/themes/powerline-multiline/powerline-multiline.base.bash b/themes/powerline-multiline/powerline-multiline.base.bash index f752bd7516..0269c58c39 100644 --- a/themes/powerline-multiline/powerline-multiline.base.bash +++ b/themes/powerline-multiline/powerline-multiline.base.bash @@ -35,7 +35,7 @@ function __powerline_right_segment { (( padding += 1 )) fi - RIGHT_PROMPT+="$(set_color - ${params[1]})${pad_before_segment}${params[0]}${normal}" + RIGHT_PROMPT+="$(set_color "${POWERLINE_PROMPT_FOREGROUND_COLOR}" ${params[1]})${pad_before_segment}${params[0]}${normal}" (( padding += ${#pad_before_segment} )) (( padding += ${#params[0]} )) diff --git a/themes/powerline-multiline/powerline-multiline.theme.bash b/themes/powerline-multiline/powerline-multiline.theme.bash index 48a1243e03..2bca81c146 100644 --- a/themes/powerline-multiline/powerline-multiline.theme.bash +++ b/themes/powerline-multiline/powerline-multiline.theme.bash @@ -18,6 +18,8 @@ POWERLINE_COMPACT_BEFOR_FIRST_SEGMENT=${POWERLINE_COMPACT_BEFORE_FIRST_SEGMENT:= POWERLINE_COMPACT_AFTER_LAST_SEGMENT=${POWERLINE_COMPACT_AFTER_LAST_SEGMENT:=${POWERLINE_COMPACT}} POWERLINE_COMPACT_PROMPT=${POWERLINE_COMPACT_PROMPT:=${POWERLINE_COMPACT}} +POWERLINE_PROMPT_FOREGROUND_COLOR=${POWERLINE_PROMPT_FOREGROUND_COLOR:=-} + USER_INFO_SSH_CHAR=${POWERLINE_USER_INFO_SSH_CHAR:=" "} USER_INFO_THEME_PROMPT_COLOR=${POWERLINE_USER_INFO_COLOR:=32} USER_INFO_THEME_PROMPT_COLOR_SUDO=${POWERLINE_USER_INFO_COLOR_SUDO:=202} @@ -39,6 +41,8 @@ SCM_THEME_PROMPT_COLOR=${SCM_THEME_PROMPT_CLEAN_COLOR} NVM_THEME_PROMPT_PREFIX="" NVM_THEME_PROMPT_SUFFIX="" +NODE_THEME_PROMPT_PREFIX="" +NODE_THEME_PROMPT_SUFFIX="" NODE_CHAR=${POWERLINE_NODE_CHAR:="❲n❳ "} NODE_THEME_PROMPT_COLOR=${POWERLINE_NODE_COLOR:=22} diff --git a/themes/powerline-naked/powerline-naked.theme.bash b/themes/powerline-naked/powerline-naked.theme.bash index 2fb4137ef0..934a315079 100644 --- a/themes/powerline-naked/powerline-naked.theme.bash +++ b/themes/powerline-naked/powerline-naked.theme.bash @@ -13,6 +13,8 @@ POWERLINE_COMPACT_BEFOR_FIRST_SEGMENT=${POWERLINE_COMPACT_BEFORE_FIRST_SEGMENT:= POWERLINE_COMPACT_AFTER_LAST_SEGMENT=${POWERLINE_COMPACT_AFTER_LAST_SEGMENT:=${POWERLINE_COMPACT}} POWERLINE_COMPACT_PROMPT=${POWERLINE_COMPACT_PROMPT:=${POWERLINE_COMPACT}} +POWERLINE_PROMPT_FOREGROUND_COLOR=${POWERLINE_PROMPT_FOREGROUND_COLOR:=-} + USER_INFO_SSH_CHAR=${POWERLINE_USER_INFO_SSH_CHAR:=" "} USER_INFO_THEME_PROMPT_COLOR=${POWERLINE_USER_INFO_COLOR:=240} USER_INFO_THEME_PROMPT_COLOR_SUDO=${POWERLINE_USER_INFO_COLOR_SUDO:=202} @@ -34,6 +36,8 @@ SCM_THEME_PROMPT_COLOR=${SCM_THEME_PROMPT_CLEAN_COLOR} NVM_THEME_PROMPT_PREFIX="" NVM_THEME_PROMPT_SUFFIX="" +NODE_THEME_PROMPT_PREFIX="" +NODE_THEME_PROMPT_SUFFIX="" NODE_CHAR=${POWERLINE_NODE_CHAR:="❲n❳ "} NODE_THEME_PROMPT_COLOR=${POWERLINE_NODE_COLOR:=22} diff --git a/themes/powerline-plain/powerline-plain.theme.bash b/themes/powerline-plain/powerline-plain.theme.bash index 6ff68e8fae..675715287d 100644 --- a/themes/powerline-plain/powerline-plain.theme.bash +++ b/themes/powerline-plain/powerline-plain.theme.bash @@ -14,6 +14,8 @@ POWERLINE_COMPACT_AFTER_LAST_SEGMENT=${POWERLINE_COMPACT_AFTER_LAST_SEGMENT:=${P POWERLINE_COMPACT_PROMPT=${POWERLINE_COMPACT_PROMPT:=${POWERLINE_COMPACT}} POWERLINE_PROMPT_AFTER=${POWERLINE_PROMPT_AFTER:-""} +POWERLINE_PROMPT_FOREGROUND_COLOR=${POWERLINE_PROMPT_FOREGROUND_COLOR:=-} + PYTHON_VENV_CHAR=${POWERLINE_PYTHON_VENV_CHAR:="ⓔ "} CONDA_PYTHON_VENV_CHAR=${POWERLINE_CONDA_PYTHON_VENV_CHAR:="ⓔ "} PYTHON_VENV_THEME_PROMPT_COLOR=${POWERLINE_PYTHON_VENV_COLOR:=35} @@ -31,6 +33,8 @@ SCM_THEME_PROMPT_COLOR=${SCM_THEME_PROMPT_CLEAN_COLOR} NVM_THEME_PROMPT_PREFIX="" NVM_THEME_PROMPT_SUFFIX="" +NODE_THEME_PROMPT_PREFIX="" +NODE_THEME_PROMPT_SUFFIX="" NODE_CHAR=${POWERLINE_NODE_CHAR:="❲n❳ "} NODE_THEME_PROMPT_COLOR=${POWERLINE_NODE_COLOR:=22} diff --git a/themes/powerline/powerline.base.bash b/themes/powerline/powerline.base.bash index 84469e877f..e7ae8ede7f 100644 --- a/themes/powerline/powerline.base.bash +++ b/themes/powerline/powerline.base.bash @@ -1,6 +1,7 @@ # shellcheck shell=bash # shellcheck disable=SC2034 # Expected behavior for themes. +#To set color for foreground and background function set_color() { local fg='' bg='' if [[ "${1:-}" != "-" ]]; then @@ -8,43 +9,41 @@ function set_color() { fi if [[ "${2:-}" != "-" ]]; then bg="48;5;${2}" - [[ -n "${fg}" ]] && bg=";${bg}" + if [[ -n "${fg}" ]]; then + bg=";${bg}" + fi fi - echo -e "\[\033[${fg}${bg}m\]" + printf '\[\\e[%s%sm\]' "${fg}" "${bg}" } +#Customising User Info Segment function __powerline_user_info_prompt() { - local user_info="" - local color=${USER_INFO_THEME_PROMPT_COLOR} - - if [[ "${THEME_CHECK_SUDO}" = true ]]; then - sudo -vn 1> /dev/null 2>&1 && color=${USER_INFO_THEME_PROMPT_COLOR_SUDO} - fi + local user_info='\u' + local color=${USER_INFO_THEME_PROMPT_COLOR-${POWERLINE_USER_INFO_COLOR-"32"}} - case "${POWERLINE_PROMPT_USER_INFO_MODE}" in - "sudo") - if [[ "${color}" = "${USER_INFO_THEME_PROMPT_COLOR_SUDO}" ]]; then + if [[ "${THEME_CHECK_SUDO:-false}" == true ]]; then + if sudo -vn 2> /dev/null; then + color=${USER_INFO_THEME_PROMPT_COLOR_SUDO-${POWERLINE_USER_INFO_COLOR_SUDO-"202"}} + if [[ "${POWERLINE_PROMPT_USER_INFO_MODE:-}" == "sudo" ]]; then user_info="!" fi - ;; - *) - local user=${SHORT_USER:-${USER}} - if [[ -n "${SSH_CLIENT}" ]] || [[ -n "${SSH_CONNECTION}" ]]; then - user_info="${USER_INFO_SSH_CHAR}${user}" - else - user_info="${user}" - fi - ;; - esac - [[ -n "${user_info}" ]] && echo "${user_info}|${color}" + fi + fi + + if [[ -n "${SSH_CLIENT:-}" || -n "${SSH_CONNECTION:-}" ]]; then + user_info="${USER_INFO_SSH_CHAR-${POWERLINE_USER_INFO_SSH_CHAR-"⌁"}}${user_info}" + fi + printf '%s|%s' "${user_info}" "${color}" } function __powerline_terraform_prompt() { local terraform_workspace="" - if [ -d .terraform ]; then + if [[ -d .terraform ]]; then terraform_workspace="$(terraform_workspace_prompt)" - [[ -n "${terraform_workspace}" ]] && echo "${TERRAFORM_CHAR}${terraform_workspace}|${TERRAFORM_THEME_PROMPT_COLOR}" + if [[ -n "${terraform_workspace}" ]]; then + printf '%s%s|%s' "${TERRAFORM_CHAR-${POWERLINE_TERRAFORM_CHAR-"❲t❳"}}" "${terraform_workspace}" "${TERRAFORM_THEME_PROMPT_COLOR-${POWERLINE_TERRAFORM_COLOR-"161"}}" + fi fi } @@ -52,18 +51,23 @@ function __powerline_gcloud_prompt() { local active_gcloud_account="" active_gcloud_account="$(active_gcloud_account_prompt)" - [[ -n "${active_gcloud_account}" ]] && echo "${GCLOUD_CHAR}${active_gcloud_account}|${GCLOUD_THEME_PROMPT_COLOR}" + if [[ -n "${active_gcloud_account}" ]]; then + printf '%s%s|%s' "${GCLOUD_CHAR-${POWERLINE_GCLOUD_CHAR-"❲G❳"}}" "${active_gcloud_account}" "${GCLOUD_THEME_PROMPT_COLOR-${POWERLINE_GCLOUD_COLOR-"161"}}" + fi } function __powerline_node_prompt() { local node_version="" node_version="$(node_version_prompt)" - [[ -n "${node_version}" ]] && echo "${NODE_CHAR}${node_version}|${NODE_THEME_PROMPT_COLOR}" + if [[ -n "${node_version}" ]]; then + printf '%s%s|%s' "${NODE_CHAR-${POWERLINE_NODE_CHAR-="❲n❳"}}" "${node_version}" "${NODE_THEME_PROMPT_COLOR-${POWERLINE_NODE_COLOR-"22"}}" + fi } +#Customising Ruby Prompt function __powerline_ruby_prompt() { - local ruby_version="" + local ruby_version if _command_exists rvm; then ruby_version="$(rvm_version_prompt)" @@ -71,7 +75,9 @@ function __powerline_ruby_prompt() { ruby_version=$(rbenv_version_prompt) fi - [[ -n "${ruby_version}" ]] && echo "${RUBY_CHAR}${ruby_version}|${RUBY_THEME_PROMPT_COLOR}" + if [[ -n "${ruby_version:-}" ]]; then + printf '%s%s|%s' "${RUBY_CHAR-${POWERLINE_RUBY_CHAR-"💎"}}" "${ruby_version}" "${RUBY_THEME_PROMPT_COLOR-${POWERLINE_RUBY_COLOR-"161"}}" + fi } function __powerline_k8s_context_prompt() { @@ -81,7 +87,9 @@ function __powerline_k8s_context_prompt() { kubernetes_context="$(k8s_context_prompt)" fi - [[ -n "${kubernetes_context}" ]] && echo "${KUBERNETES_CONTEXT_THEME_CHAR}${kubernetes_context}|${KUBERNETES_CONTEXT_THEME_PROMPT_COLOR}" + if [[ -n "${kubernetes_context}" ]]; then + printf '%s%s|%s' "${KUBERNETES_CONTEXT_THEME_CHAR-${POWERLINE_KUBERNETES_CONTEXT_CHAR-"⎈"}}" "${kubernetes_context}" "${KUBERNETES_CONTEXT_THEME_PROMPT_COLOR-${POWERLINE_KUBERNETES_CONTEXT_COLOR-"26"}}" + fi } function __powerline_k8s_namespace_prompt() { @@ -91,65 +99,73 @@ function __powerline_k8s_namespace_prompt() { kubernetes_namespace="$(k8s_namespace_prompt)" fi - [[ -n "${kubernetes_namespace}" ]] && echo "${KUBERNETES_NAMESPACE_THEME_CHAR}${kubernetes_namespace}|${KUBERNETES_NAMESPACE_THEME_PROMPT_COLOR}" + if [[ -n "${kubernetes_namespace}" ]]; then + printf '%s%s|%s' "${KUBERNETES_NAMESPACE_THEME_CHAR-${POWERLINE_KUBERNETES_NAMESPACE_CHAR-"⎈"}}" "${kubernetes_namespace}" "${KUBERNETES_NAMESPACE_THEME_PROMPT_COLOR-${POWERLINE_KUBERNETES_NAMESPACE_COLOR-"60"}}" + fi } +#Customising Python (venv) Prompt function __powerline_python_venv_prompt() { local python_venv="" if [[ -n "${CONDA_DEFAULT_ENV:-}" ]]; then python_venv="${CONDA_DEFAULT_ENV}" - PYTHON_VENV_CHAR=${CONDA_PYTHON_VENV_CHAR} + local PYTHON_VENV_CHAR=${CONDA_PYTHON_VENV_CHAR-${POWERLINE_CONDA_PYTHON_VENV_CHAR-"ⓔ"}} elif [[ -n "${VIRTUAL_ENV:-}" ]]; then python_venv="${VIRTUAL_ENV##*/}" fi - [[ -n "${python_venv}" ]] && echo "${PYTHON_VENV_CHAR}${python_venv}|${PYTHON_VENV_THEME_PROMPT_COLOR}" + if [[ -n "${python_venv}" ]]; then + printf '%s%s|%s' "${PYTHON_VENV_CHAR-${POWERLINE_PYTHON_VENV_CHAR-"ⓔ"}}" "${python_venv}" "${PYTHON_VENV_THEME_PROMPT_COLOR-${POWERLINE_PYTHON_VENV_COLOR-"35"}}" + fi } +#Customising SCM(GIT) Prompt function __powerline_scm_prompt() { local color="" local scm_prompt="" scm_prompt_vars - if [[ "${SCM_NONE_CHAR}" != "${SCM_CHAR}" ]]; then - if [[ "${SCM_DIRTY}" -eq 3 ]]; then - color=${SCM_THEME_PROMPT_STAGED_COLOR} - elif [[ "${SCM_DIRTY}" -eq 2 ]]; then - color=${SCM_THEME_PROMPT_UNSTAGED_COLOR} - elif [[ "${SCM_DIRTY}" -eq 1 ]]; then - color=${SCM_THEME_PROMPT_DIRTY_COLOR} + if [[ "${SCM_NONE_CHAR?}" != "${SCM_CHAR?}" ]]; then + if [[ "${SCM_DIRTY?}" -eq 3 ]]; then + color=${SCM_THEME_PROMPT_STAGED_COLOR-${POWERLINE_SCM_STAGED_COLOR-"30"}} + elif [[ "${SCM_DIRTY?}" -eq 2 ]]; then + color=${SCM_THEME_PROMPT_UNSTAGED_COLOR-${POWERLINE_SCM_UNSTAGED_COLOR-"92"}} + elif [[ "${SCM_DIRTY?}" -eq 1 ]]; then + color=${SCM_THEME_PROMPT_DIRTY_COLOR-${POWERLINE_SCM_DIRTY_COLOR-"88"}} + elif [[ "${SCM_DIRTY?}" -eq 0 ]]; then + color=${SCM_THEME_PROMPT_CLEAN_COLOR-${POWERLINE_SCM_CLEAN_COLOR-"25"}} else - color=${SCM_THEME_PROMPT_CLEAN_COLOR} + color=${SCM_THEME_PROMPT_COLOR-${POWERLINE_SCM_CLEAN_COLOR-"25"}} fi - if [[ "${SCM_GIT_CHAR}" == "${SCM_CHAR}" ]]; then - scm_prompt+="${SCM_CHAR}${SCM_BRANCH}${SCM_STATE}" - elif [[ "${SCM_P4_CHAR}" == "${SCM_CHAR}" ]]; then - scm_prompt+="${SCM_CHAR}${SCM_BRANCH}${SCM_STATE}" - elif [[ "${SCM_HG_CHAR}" == "${SCM_CHAR}" ]]; then - scm_prompt+="${SCM_CHAR}${SCM_BRANCH}${SCM_STATE}" - elif [[ "${SCM_SVN_CHAR}" == "${SCM_CHAR}" ]]; then - scm_prompt+="${SCM_CHAR}${SCM_BRANCH}${SCM_STATE}" + if [[ "${SCM_GIT_CHAR?}" == "${SCM_CHAR?}" ]]; then + scm_prompt+="${SCM_CHAR}${SCM_BRANCH?}${SCM_STATE?}" + elif [[ "${SCM_P4_CHAR?}" == "${SCM_CHAR}" ]]; then + scm_prompt+="${SCM_CHAR}${SCM_BRANCH?}${SCM_STATE?}" + elif [[ "${SCM_HG_CHAR?}" == "${SCM_CHAR}" ]]; then + scm_prompt+="${SCM_CHAR}${SCM_BRANCH?}${SCM_STATE?}" + elif [[ "${SCM_SVN_CHAR?}" == "${SCM_CHAR}" ]]; then + scm_prompt+="${SCM_CHAR}${SCM_BRANCH?}${SCM_STATE?}" fi - echo "${scm_prompt?}|${color}" + printf '%s|%s' "${scm_prompt}" "${color}" fi } function __powerline_cwd_prompt() { - echo "\w|${CWD_THEME_PROMPT_COLOR}" + printf '%s|%s' "\w" "${CWD_THEME_PROMPT_COLOR-"240"}" } function __powerline_hostname_prompt() { - echo "${SHORT_HOSTNAME:-$(hostname -s)}|${HOST_THEME_PROMPT_COLOR}" + printf '%s|%s' "\h" "${HOST_THEME_PROMPT_COLOR-"0"}" } function __powerline_wd_prompt() { - echo "\W|${CWD_THEME_PROMPT_COLOR}" + printf '%s|%s' "\W" "${CWD_THEME_PROMPT_COLOR-"240"}" } function __powerline_clock_prompt() { - echo "$(date +"${THEME_CLOCK_FORMAT}")|${CLOCK_THEME_PROMPT_COLOR}" + printf '%s|%s' "\D{${THEME_CLOCK_FORMAT-"%H:%M:%S"}}" "${CLOCK_THEME_PROMPT_COLOR-"240"}" } function __powerline_battery_prompt() { @@ -160,149 +176,159 @@ function __powerline_battery_prompt() { true else if [[ "$((10#${battery_status}))" -le 5 ]]; then - color="${BATTERY_STATUS_THEME_PROMPT_CRITICAL_COLOR}" + color="${BATTERY_STATUS_THEME_PROMPT_CRITICAL_COLOR-"160"}" elif [[ "$((10#${battery_status}))" -le 25 ]]; then - color="${BATTERY_STATUS_THEME_PROMPT_LOW_COLOR}" + color="${BATTERY_STATUS_THEME_PROMPT_LOW_COLOR-"208"}" else - color="${BATTERY_STATUS_THEME_PROMPT_GOOD_COLOR}" + color="${BATTERY_STATUS_THEME_PROMPT_GOOD_COLOR-"70"}" + fi + if ac_adapter_connected; then + battery_status="${BATTERY_AC_CHAR-"+"}${battery_status}" fi - ac_adapter_connected && battery_status="${BATTERY_AC_CHAR}${battery_status}" - echo "${battery_status}%|${color}" + printf '%s|%s' "${battery_status}%" "${color}" fi } function __powerline_in_vim_prompt() { - if [[ -n "$VIMRUNTIME" ]]; then - echo "${IN_VIM_THEME_PROMPT_TEXT}|${IN_VIM_THEME_PROMPT_COLOR}" + if [[ -n "${VIMRUNTIME:-}" ]]; then + printf '%s|%s' "${IN_VIM_THEME_PROMPT_TEXT-"vim"}" "${IN_VIM_THEME_PROMPT_COLOR-"245"}" fi } function __powerline_aws_profile_prompt() { - if [[ -n "${AWS_PROFILE}" ]]; then - echo "${AWS_PROFILE_CHAR}${AWS_PROFILE}|${AWS_PROFILE_PROMPT_COLOR}" + if [[ -n "${AWS_PROFILE:-}" ]]; then + printf '%s%s|%s' "${AWS_PROFILE_CHAR-${POWERLINE_AWS_PROFILE_CHAR-"❲aws❳"}}" "${AWS_PROFILE}" "${AWS_PROFILE_PROMPT_COLOR-${POWERLINE_AWS_PROFILE_COLOR-"208"}}" fi } function __powerline_in_toolbox_prompt() { - if [ -f /run/.containerenv ] && [ -f /run/.toolboxenv ]; then - echo "${IN_TOOLBOX_THEME_PROMPT_TEXT}|${IN_TOOLBOX_THEME_PROMPT_COLOR}" + if [[ -f /run/.containerenv && -f /run/.toolboxenv ]]; then + printf '%s|%s' "${IN_TOOLBOX_THEME_PROMPT_TEXT-"⬢"}" "${IN_TOOLBOX_THEME_PROMPT_COLOR-"125"}" fi } function __powerline_shlvl_prompt() { if [[ "${SHLVL}" -gt 1 ]]; then - local prompt="${SHLVL_THEME_PROMPT_CHAR}" + local prompt="${SHLVL_THEME_PROMPT_CHAR-"§"}" local level=$((SHLVL - 1)) - echo "${prompt}${level}|${SHLVL_THEME_PROMPT_COLOR}" + printf '%s|%s' "${prompt}${level}" "${SHLVL_THEME_PROMPT_COLOR-${HOST_THEME_PROMPT_COLOR-"0"}}" fi } function __powerline_dirstack_prompt() { if [[ "${#DIRSTACK[@]}" -gt 1 ]]; then local depth=$((${#DIRSTACK[@]} - 1)) - local prompt="${DIRSTACK_THEME_PROMPT_CHAR}" + local prompt="${DIRSTACK_THEME_PROMPT_CHAR-${POWERLINE_DIRSTACK_CHAR-"←"}}" if [[ "${depth}" -ge 2 ]]; then prompt+="${depth}" fi - echo "${prompt}|${DIRSTACK_THEME_PROMPT_COLOR}" + printf '%s|%s' "${prompt}" "${DIRSTACK_THEME_PROMPT_COLOR-${POWERLINE_DIRSTACK_COLOR-${CWD_THEME_PROMPT_COLOR-${POWERLINE_CWD_COLOR-"240"}}}}" fi } function __powerline_history_number_prompt() { - echo "${HISTORY_NUMBER_THEME_PROMPT_CHAR}\!|${HISTORY_NUMBER_THEME_PROMPT_COLOR}" + printf '%s%s|%s' "${HISTORY_NUMBER_THEME_PROMPT_CHAR-${POWERLINE_HISTORY_NUMBER_CHAR-"#"}}" '\!' "${HISTORY_NUMBER_THEME_PROMPT_COLOR-${POWERLINE_HISTORY_NUMBER_COLOR-"0"}}" } function __powerline_command_number_prompt() { - echo "${COMMAND_NUMBER_THEME_PROMPT_CHAR}\#|${COMMAND_NUMBER_THEME_PROMPT_COLOR}" + printf '%s%s|%s' "${COMMAND_NUMBER_THEME_PROMPT_CHAR-${POWERLINE_COMMAND_NUMBER_CHAR-"#"}}" '\#' "${COMMAND_NUMBER_THEME_PROMPT_COLOR-${POWERLINE_COMMAND_NUMBER_COLOR-"0"}}" } function __powerline_duration_prompt() { local duration duration=$(_command_duration) - [[ -n "$duration" ]] && echo "${duration}|${COMMAND_DURATION_PROMPT_COLOR}" + if [[ -n "$duration" ]]; then + printf '%s|%s' "${duration}" "${COMMAND_DURATION_PROMPT_COLOR?}" + fi } function __powerline_left_segment() { - local params + local -a params IFS="|" read -ra params <<< "${1}" local pad_before_segment=" " - if [[ "${SEGMENTS_AT_LEFT}" -eq 0 ]]; then - if [[ "${POWERLINE_COMPACT_BEFORE_FIRST_SEGMENT}" -ne 0 ]]; then + #for seperator character + if [[ "${SEGMENTS_AT_LEFT?}" -eq 0 ]]; then + if [[ "${POWERLINE_COMPACT_BEFORE_FIRST_SEGMENT:-${POWERLINE_COMPACT:-0}}" -ne 0 ]]; then pad_before_segment="" fi else - if [[ "${POWERLINE_COMPACT_AFTER_SEPARATOR}" -ne 0 ]]; then + if [[ "${POWERLINE_COMPACT_AFTER_SEPARATOR:-${POWERLINE_COMPACT:-0}}" -ne 0 ]]; then pad_before_segment="" fi # Since the previous segment wasn't the last segment, add padding, if needed # - if [[ "${POWERLINE_COMPACT_BEFORE_SEPARATOR}" -eq 0 ]]; then - LEFT_PROMPT+="$(set_color - "${LAST_SEGMENT_COLOR}") ${normal?}" + if [[ "${POWERLINE_COMPACT_BEFORE_SEPARATOR:-${POWERLINE_COMPACT:-0}}" -eq 0 ]]; then + LEFT_PROMPT+="$(set_color - "${LAST_SEGMENT_COLOR?}") ${normal?}" fi - if [[ "${LAST_SEGMENT_COLOR}" -eq "${params[1]}" ]]; then - LEFT_PROMPT+="$(set_color - "${LAST_SEGMENT_COLOR}")${POWERLINE_LEFT_SEPARATOR_SOFT}${normal?}" + if [[ "${LAST_SEGMENT_COLOR?}" -eq "${params[1]:-}" ]]; then + LEFT_PROMPT+="$(set_color - "${LAST_SEGMENT_COLOR?}")${POWERLINE_LEFT_SEPARATOR_SOFT- }${normal?}" else - LEFT_PROMPT+="$(set_color "${LAST_SEGMENT_COLOR}" "${params[1]}")${POWERLINE_LEFT_SEPARATOR}${normal?}" + LEFT_PROMPT+="$(set_color "${LAST_SEGMENT_COLOR?}" "${params[1]:-}")${POWERLINE_LEFT_SEPARATOR- }${normal?}" fi fi - LEFT_PROMPT+="$(set_color - "${params[1]}")${pad_before_segment}${params[0]}${normal}" - LAST_SEGMENT_COLOR=${params[1]} + #change here to cahnge fg color + LEFT_PROMPT+="$(set_color - "${params[1]:-}")${pad_before_segment}${params[0]}${normal?}" + #seperator char color == current bg + LAST_SEGMENT_COLOR="${params[1]:-}" ((SEGMENTS_AT_LEFT += 1)) } function __powerline_left_last_segment_padding() { - LEFT_PROMPT+="$(set_color - "${LAST_SEGMENT_COLOR}") ${normal?}" + LEFT_PROMPT+="$(set_color - "${LAST_SEGMENT_COLOR?}") ${normal?}" } function __powerline_last_status_prompt() { - [[ "$1" -ne 0 ]] && echo "${1}|${LAST_STATUS_THEME_PROMPT_COLOR}" + if [[ "${1?}" -ne 0 ]]; then + printf '%s|%s' "${1}" "${LAST_STATUS_THEME_PROMPT_COLOR-"52"}" + fi } function __powerline_prompt_command() { local last_status="$?" ## always the first - local separator_char="${POWERLINE_PROMPT_CHAR}" info prompt_color + local beginning_of_line='\[\e[G\]' + local info prompt_color segment prompt - LEFT_PROMPT="" - SEGMENTS_AT_LEFT=0 - LAST_SEGMENT_COLOR="" + local LEFT_PROMPT="" + local SEGMENTS_AT_LEFT=0 + local LAST_SEGMENT_COLOR="" _save-and-reload-history "${HISTORY_AUTOSAVE:-0}" - if [[ -n "${POWERLINE_PROMPT_DISTRO_LOGO}" ]]; then - LEFT_PROMPT+="$(set_color "${PROMPT_DISTRO_LOGO_COLOR}" "${PROMPT_DISTRO_LOGO_COLORBG}")${PROMPT_DISTRO_LOGO}$(set_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 - -)" fi ## left prompt ## - for segment in $POWERLINE_PROMPT; do - info="$(__powerline_"${segment}"_prompt)" - [[ -n "${info}" ]] && __powerline_left_segment "${info}" + # shellcheck disable=SC2068 # intended behavior + for segment in ${POWERLINE_PROMPT[@]-"user_info" "scm" "python_venv" "ruby" "node" "cwd"}; do + info="$("__powerline_${segment}_prompt")" + if [[ -n "${info}" ]]; then + __powerline_left_segment "${info}" + fi done - [[ "${last_status}" -ne 0 ]] && __powerline_left_segment "$(__powerline_last_status_prompt "${last_status}")" + if [[ "${last_status}" -ne 0 ]]; then + __powerline_left_segment "$(__powerline_last_status_prompt "${last_status}")" + fi - if [[ -n "${LEFT_PROMPT}" ]] && [[ "${POWERLINE_COMPACT_AFTER_LAST_SEGMENT:-}" -eq 0 ]]; then + if [[ -n "${LEFT_PROMPT:-}" && "${POWERLINE_COMPACT_AFTER_LAST_SEGMENT:-${POWERLINE_COMPACT:-0}}" -eq 0 ]]; then __powerline_left_last_segment_padding fi # By default we try to match the prompt to the adjacent segment's background color, # but when part of the prompt exists within that segment, we instead match the foreground color. - prompt_color="$(set_color "${LAST_SEGMENT_COLOR}" -)" - if [[ -n "${LEFT_PROMPT}" ]] && [[ -n "${POWERLINE_LEFT_LAST_SEGMENT_PROMPT_CHAR}" ]]; then - LEFT_PROMPT+="$(set_color - "${LAST_SEGMENT_COLOR}")${POWERLINE_LEFT_LAST_SEGMENT_PROMPT_CHAR}" + prompt_color="$(set_color "${LAST_SEGMENT_COLOR?}" -)" + if [[ -n "${LEFT_PROMPT:-}" && -n "${POWERLINE_LEFT_LAST_SEGMENT_END_CHAR:-}" ]]; then + LEFT_PROMPT+="$(set_color - "${LAST_SEGMENT_COLOR?}")${POWERLINE_LEFT_LAST_SEGMENT_END_CHAR}" prompt_color="${normal?}" fi - [[ -n "${LEFT_PROMPT}" ]] && LEFT_PROMPT+="${prompt_color}${separator_char}${normal?}" - if [[ "${POWERLINE_COMPACT_PROMPT:-}" -eq 0 ]]; then - LEFT_PROMPT+=" " + prompt="${prompt_color}${PROMPT_CHAR-${POWERLINE_PROMPT_CHAR-\\$}}${normal?}" + if [[ "${POWERLINE_COMPACT_PROMPT:-${POWERLINE_COMPACT:-0}}" -eq 0 ]]; then + prompt+=" " fi - PS1="${LEFT_PROMPT}" - - ## cleanup ## - unset LAST_SEGMENT_COLOR \ - LEFT_PROMPT \ - SEGMENTS_AT_LEFT + PS1="${beginning_of_line}${normal?}${LEFT_PROMPT}${prompt}" } diff --git a/themes/powerline/powerline.theme.bash b/themes/powerline/powerline.theme.bash index 49b397aa1d..d65429045d 100644 --- a/themes/powerline/powerline.theme.bash +++ b/themes/powerline/powerline.theme.bash @@ -1,20 +1,21 @@ # shellcheck shell=bash # shellcheck disable=SC2034 # Expected behavior for themes. - -# shellcheck source=../../themes/powerline/powerline.base.bash -. "$BASH_IT/themes/powerline/powerline.base.bash" +# shellcheck source-path=SCRIPTDIR/../powerline +source "${BASH_IT?}/themes/powerline/powerline.base.bash" PROMPT_CHAR=${POWERLINE_PROMPT_CHAR:=""} -POWERLINE_LEFT_SEPARATOR=${POWERLINE_LEFT_SEPARATOR:=""} -POWERLINE_LEFT_SEPARATOR_SOFT=${POWERLINE_LEFT_SEPARATOR_SOFT:=""} -POWERLINE_LEFT_LAST_SEGMENT_PROMPT_CHAR=${POWERLINE_LEFT_LAST_SEGMENT_PROMPT_CHAR:=""} +: "${POWERLINE_LEFT_SEPARATOR:=""}" +: "${POWERLINE_LEFT_SEPARATOR_SOFT:=""}" +: "${POWERLINE_LEFT_LAST_SEGMENT_END_CHAR:=""}" + +: "${POWERLINE_COMPACT:=0}" +: "${POWERLINE_COMPACT_BEFORE_SEPARATOR:=${POWERLINE_COMPACT}}" +: "${POWERLINE_COMPACT_AFTER_SEPARATOR:=${POWERLINE_COMPACT}}" +: "${POWERLINE_COMPACT_BEFORE_FIRST_SEGMENT:=${POWERLINE_COMPACT}}" +: "${POWERLINE_COMPACT_AFTER_LAST_SEGMENT:=${POWERLINE_COMPACT}}" +: "${POWERLINE_COMPACT_PROMPT:=${POWERLINE_COMPACT}}" -POWERLINE_COMPACT=${POWERLINE_COMPACT:=0} -POWERLINE_COMPACT_BEFORE_SEPARATOR=${POWERLINE_COMPACT_BEFORE_SEPARATOR:=${POWERLINE_COMPACT}} -POWERLINE_COMPACT_AFTER_SEPARATOR=${POWERLINE_COMPACT_AFTER_SEPARATOR:=${POWERLINE_COMPACT}} -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_FOREGROUND_COLOR=${POWERLINE_PROMPT_FOREGROUND_COLOR:=-} USER_INFO_SSH_CHAR=${POWERLINE_USER_INFO_SSH_CHAR:=" "} USER_INFO_THEME_PROMPT_COLOR=${POWERLINE_USER_INFO_COLOR:=32} @@ -37,6 +38,8 @@ SCM_THEME_PROMPT_COLOR=${SCM_THEME_PROMPT_CLEAN_COLOR} NVM_THEME_PROMPT_PREFIX="" NVM_THEME_PROMPT_SUFFIX="" +NODE_THEME_PROMPT_PREFIX="" +NODE_THEME_PROMPT_SUFFIX="" NODE_CHAR=${POWERLINE_NODE_CHAR:="❲n❳ "} NODE_THEME_PROMPT_COLOR=${POWERLINE_NODE_COLOR:=22} @@ -65,12 +68,12 @@ LAST_STATUS_THEME_PROMPT_COLOR=${POWERLINE_LAST_STATUS_COLOR:=52} CLOCK_THEME_PROMPT_COLOR=${POWERLINE_CLOCK_COLOR:=240} -BATTERY_AC_CHAR=${BATTERY_AC_CHAR:="⚡"} +: "${BATTERY_AC_CHAR:="⚡"}" BATTERY_STATUS_THEME_PROMPT_GOOD_COLOR=${POWERLINE_BATTERY_GOOD_COLOR:=70} BATTERY_STATUS_THEME_PROMPT_LOW_COLOR=${POWERLINE_BATTERY_LOW_COLOR:=208} BATTERY_STATUS_THEME_PROMPT_CRITICAL_COLOR=${POWERLINE_BATTERY_CRITICAL_COLOR:=160} -THEME_CLOCK_FORMAT=${THEME_CLOCK_FORMAT:="%H:%M:%S"} +: "${THEME_CLOCK_FORMAT:="%H:%M:%S"}" IN_VIM_THEME_PROMPT_COLOR=${POWERLINE_IN_VIM_COLOR:=245} IN_VIM_THEME_PROMPT_TEXT=${POWERLINE_IN_VIM_TEXT:="vim"} @@ -97,6 +100,6 @@ GCLOUD_CHAR=${POWERLINE_GCLOUD_CHAR:="❲G❳ "} COMMAND_DURATION_PROMPT_COLOR=${POWERLINE_COMMAND_DURATION_COLOR:=129} -POWERLINE_PROMPT=${POWERLINE_PROMPT:="user_info scm python_venv ruby node cwd"} +: "${POWERLINE_PROMPT:="user_info scm python_venv ruby node cwd"}" safe_append_prompt_command __powerline_prompt_command diff --git a/themes/rjorgenson/rjorgenson.theme.bash b/themes/rjorgenson/rjorgenson.theme.bash index 71d29e7866..6e73c4a28c 100644 --- a/themes/rjorgenson/rjorgenson.theme.bash +++ b/themes/rjorgenson/rjorgenson.theme.bash @@ -1,3 +1,5 @@ +# shellcheck shell=bash + # port of zork theme # set colors for use throughout the prompt @@ -50,7 +52,7 @@ function is_integer() { # helper function for todo-txt-count todo_txt_count() { if `hash todo.sh 2>&-`; then # is todo.sh installed - count=`todo.sh ls | egrep "TODO: [0-9]+ of ([0-9]+) tasks shown" | awk '{ print $4 }'` + count=`todo.sh ls | grep -E "TODO: [0-9]+ of ([0-9]+) tasks shown" | awk '{ print $4 }'` if is_integer $count; then # did we get a sane answer back echo "${BRACKET_COLOR}[${STRING_COLOR}T:$count${BRACKET_COLOR}]$normal" fi diff --git a/vendor/github.com/dsifford/yarn-completion/yarn b/vendor/github.com/dsifford/yarn-completion/yarn new file mode 100644 index 0000000000..ff78e47137 --- /dev/null +++ b/vendor/github.com/dsifford/yarn-completion/yarn @@ -0,0 +1,1208 @@ +# shellcheck shell=bash disable=2207 +# vim: set fdm=syntax fdl=0: +# +# Version: 0.17.0 +# Yarn Version: 1.22.11 +# +# bash completion for Yarn (https://github.com/yarnpkg/yarn) +# +# To enable on-demand completion loading, copy this file to one of the following locations: +# - $BASH_COMPLETION_USER_DIR/completions/yarn +# or +# - $XDG_DATA_HOME/bash-completion/completions/yarn +# or +# - ~/.local/share/bash-completion/completions/yarn +# + +### +# Parses and extracts data from package.json files. +# +# Usage: +# __yarn_get_package_fields [-g] [-t FIELDTYPE] +# +# Options: +# -g Parse global package.json file, if available +# -t FIELDTYPE The field type being parsed (array|boolean|number|object|string) [default: object] +# +# Notes: +# If FIELDTYPE is object, then the object keys are returned. +# If FIELDTYPE is array, boolean, number, or string, then the field values are returned. +# must be a first-level field in the json file. +## +__yarn_get_package_fields() { + declare cwd=$PWD field_type=object field_key opt package_dot_json OPTIND OPTARG + + while [[ -n $cwd ]]; do + if [[ -f "$cwd/package.json" ]]; then + package_dot_json="$cwd/package.json" + break + fi + cwd="${cwd%/*}" + done + + while getopts ":gt:" opt; do + case $opt in + g) + if [[ -f $HOME/.config/yarn/global/package.json ]]; then + package_dot_json="$HOME/.config/yarn/global/package.json" + elif [[ -f $HOME/.local/share/yarn/global/package.json ]]; then + package_dot_json="$HOME/.local/share/yarn/global/package.json" + elif [[ -f $HOME/.yarn/global/package.json ]]; then + package_dot_json="$HOME/.yarn/global/package.json" + else + package_dot_json="" + fi + ;; + t) + case "$OPTARG" in + array | boolean | number | object | string) + field_type="$OPTARG" + ;; + esac + ;; + *) ;; + + esac + done + shift $((OPTIND - 1)) + + field_key='"'$1'"' + + [[ ! -f $package_dot_json || ! $field_key ]] && return + + case "$field_type" in + object) + sed -n '/'"$field_key"':[[:space:]]*{/,/^[[:space:]]*}/{ + # exclude start and end patterns + //!{ + # extract the text between the first pair of double quotes + s/^[[:space:]]*"\([^"]*\).*/\1/p + } + }' "$package_dot_json" + ;; + array) + sed -n '/'"$field_key"':[[:space:]]*\[/,/^[[:space:]]*]/{ + # exclude start and end patterns + //!{ + # extract the text between the first pair of double quotes + s/^[[:space:]]*"\([^"]*\).*/\1/p + } + }' "$package_dot_json" + ;; + boolean | number) + sed -n 's/[[:space:]]*'"$field_key"':[[:space:]]*\([a-z0-9]*\)/\1/p' "$package_dot_json" + ;; + string) + sed -n 's/[[:space:]]*'"$field_key"':[[:space:]]*"\(.*\)".*/\1/p' "$package_dot_json" + ;; + esac +} + +### +# Count all command arguments starting at a given depth, excluding flags and +# flag arguments. +# +# Usage: +# __yarn_count_args [-d INT] +# +# Options: +# -d INT The start depth to begin counting [default: 0] +# +# Globals: +# *args +# cword +## +__yarn_count_args() { + args=0 + declare -i counter=0 depth=0 + declare arg_flag_pattern opt OPTIND + arg_flag_pattern="@($(tr ' ' '|' <<< "${arg_flags[*]}"))" + + while getopts ":d:" opt; do + case $opt in + d) + depth=$OPTARG + ;; + *) ;; + esac + done + shift $((OPTIND - 1)) + + while ((counter < cword)); do + case ${words[counter]} in + -* | =) ;; + *) + # shellcheck disable=SC2053 + if [[ ${words[counter - 1]} != $arg_flag_pattern ]]; then + if ((depth-- <= 0)); then + ((args++)) + fi + fi + ;; + esac + ((counter++)) + done +} + +### +# Retrieves the command or subcommand at a given depth, or the last occurring +# command or subcommand before the cursor location if no depth is given, or if +# depth exceeds cursor location. +# +# Usage: +# __yarn_get_command [-d INT] +# +# Options: +# -d INT Depth of command to retrieve. +# +# Globals: +# *cmd +# commands +# cword +# subcommands +# words +## +__yarn_get_command() { + declare -i counter=0 cmd_depth=0 OPTIND + declare cmdlist word opt + + while getopts ":d:" opt; do + case $opt in + d) + cmd_depth="$OPTARG" + ;; + *) ;; + esac + done + shift $((OPTIND - 1)) + + cmdlist="@($(tr ' ' '|' <<< "${commands[*]} ${subcommands[*]}"))" + cmd=yarn + + while ((counter < cword)); do + word="${words[counter]}" + case "$word" in + $cmdlist) + cmd="$word" + ((--cmd_depth == 0)) && break + ;; + esac + ((counter++)) + done +} + +### +# Global fallback completion generator if all else fails. +# +# Usage: +# __yarn_fallback +# +# Globals: +# cur +## +__yarn_fallback() { + case "$cur" in + -*) + COMPREPLY=($(compgen -W "$(__yarn_flags)" -- "$cur")) + ;; + *) + COMPREPLY=($(compgen -o plusdirs -f -- "$cur")) + ;; + esac +} + +### +# Process and merge local and global flags after removing the flags that +# have already been used. +# +# Usage: +# __yarn_flags +# +# Globals: +# flags +# global_flags +# words +## +__yarn_flags() { + declare word + declare -a existing_flags=() + + for word in "${words[@]}"; do + case "$word" in + -*) + existing_flags+=("$word") + ;; + esac + done + + LC_ALL=C comm -23 \ + <(echo "${flags[@]}" "${global_flags[@]}" | tr ' ' '\n' | LC_ALL=C sort -u) \ + <(echo "${existing_flags[@]}" | tr ' ' '\n' | LC_ALL=C sort -u) +} + +### +# Handles completions for flags that require, or optionally take, arguments. +# +# Usage: +# __yarn_flag_args +# +# Globals: +# cur +# prev +## +__yarn_flag_args() { + declare {arg,bool,dir,file,int,special}_flag_pattern + arg_flag_pattern="@($(tr ' ' '|' <<< "${arg_flags[*]}"))" + + # shellcheck disable=SC2053 + if [[ $prev != $arg_flag_pattern ]]; then + return 1 + fi + + bool_flag_pattern="@($(tr ' ' '|' <<< "${bool_arg_flags[*]}"))" + dir_flag_pattern="@($(tr ' ' '|' <<< "${dir_arg_flags[*]}"))" + file_flag_pattern="@($(tr ' ' '|' <<< "${file_arg_flags[*]}"))" + int_flag_pattern="@($(tr ' ' '|' <<< "${int_arg_flags[*]}"))" + special_flag_pattern="@($(tr ' ' '|' <<< "${special_arg_flags[*]}"))" + + case "$prev" in + $bool_flag_pattern) + COMPREPLY=($(compgen -W 'true false' -- "$cur")) + ;; + $dir_flag_pattern) + compopt -o dirnames + ;; + $file_flag_pattern) + compopt -o default -o filenames + ;; + $int_flag_pattern) + compopt -o nospace + COMPREPLY=($(compgen -W '{0..9}' -- "$cur")) + ;; + $special_flag_pattern) + case "$prev" in + --access) + COMPREPLY=($(compgen -W 'public restricted' -- "$cur")) + ;; + --groups) + COMPREPLY=($(compgen -W 'dependencies devDependencies optionalDependencies' -- "$cur")) + ;; + --level) + COMPREPLY=($(compgen -W 'info low moderate high critical' -- "$cur")) + ;; + --network-timeout) + compopt -o nospace + COMPREPLY=($(compgen -W '{1000..10000..1000}' -- "$cur")) + ;; + esac + ;; + esac + return 0 +} + +_yarn_add() { + ((depth++)) + flags=( + --audit -A + --dev -D + --exact -E + --optional -O + --peer -P + --tilde -T + --ignore-workspace-root-check -W + ) + return 1 +} + +_yarn_audit() { + ((depth++)) + flags=( + --groups + --level + --summary + ) + return 1 +} + +_yarn_autoclean() { + ((depth++)) + flags=( + --force -F + --init -I + ) + return 1 +} + +_yarn_cache() { + ((depth++)) + declare cmd + flags=( + --pattern + ) + subcommands=( + clean + dir + list + ) + __yarn_get_command + + case "$cmd" in + cache) + case "$cur" in + -*) + return 1 + ;; + *) + COMPREPLY=($(compgen -W "${subcommands[*]}" -- "$cur")) + return 0 + ;; + esac + ;; + *) + return 1 + ;; + esac +} + +_yarn_check() { + ((depth++)) + flags=( + --integrity + --verify-tree + ) + return 1 +} + +_yarn_config() { + ((depth++)) + declare cmd + declare subcommands=( + delete + get + list + set + ) + declare known_keys=( + ignore-optional + ignore-platform + ignore-scripts + init-author-email + init-author-name + init-author-url + init-license + init-version + no-progress + prefix + registry + save-prefix + user-agent + version-git-message + version-git-sign + version-git-tag + version-tag-prefix + ) + __yarn_get_command + + case "$cmd" in + get | delete) + case "$cur" in + -*) ;; + *) + if [[ $prev == @(get|delete) ]]; then + COMPREPLY=($(compgen -W "${known_keys[*]}" -- "$cur")) + return 0 + fi + ;; + esac + ;; + set) + case "$cur" in + -*) + flags=( + --global + ) + ;; + *) + if [[ $prev == set ]]; then + COMPREPLY=($(compgen -W "${known_keys[*]}" -- "$cur")) + return 0 + fi + ;; + esac + ;; + config) + case "$cur" in + -*) ;; + *) + COMPREPLY=($(compgen -W "${subcommands[*]}" -- "$cur")) + return 0 + ;; + esac + ;; + esac + return 1 +} + +_yarn_create() { + ((depth++)) + declare -i args + case "$cur" in + -*) ;; + *) + __yarn_count_args -d $depth + ((args == 0)) && return 0 + ;; + esac + return 1 +} + +_yarn_generate_lock_entry() { + ((depth++)) + flags=( + --resolved + --use-manifest + ) + return 1 +} + +_yarn_global() { + ((depth++)) + declare cmd cmdlist + flags=( + --latest + --prefix + ) + subcommands=( + add + bin + list + remove + upgrade + upgrade-interactive + ) + cmdlist="@($(tr ' ' '|' <<< "${subcommands[*]}"))" + + __yarn_get_command -d 3 + + case "$cur" in + -*) ;; + *) + case "$cmd" in + $cmdlist) + "_yarn_${cmd//-/_}" 2> /dev/null + return $? + ;; + global) + COMPREPLY=($(compgen -W "${subcommands[*]}" -- "$cur")) + return 0 + ;; + esac + ;; + esac + + return 1 +} + +_yarn_help() { + ((depth++)) + declare -i args + case "$cur" in + -*) ;; + *) + __yarn_count_args -d $depth + if ((args == 0)); then + COMPREPLY=($(compgen -W "${commands[*]}" -- "$cur")) + return 0 + fi + ;; + esac + return 1 +} + +_yarn_info() { + ((depth++)) + flags=( + --json + ) + declare standard_fields=( + author + bin + bugs + contributors + dependencies + description + devDependencies + dist-tags + engines + files + homepage + keywords + license + main + maintainers + name + optionalDependencies + peerDependencies + repository + version + versions + ) + + declare -i args + __yarn_count_args -d $depth + + case "$cur" in + -*) ;; + *) + case "$args" in + 0) + COMPREPLY=( + $(compgen -W " + $(__yarn_get_package_fields dependencies) + $(__yarn_get_package_fields devDependencies) + " -- "$cur") + ) + return 0 + ;; + 1) + COMPREPLY=($(compgen -W "${standard_fields[*]}" -- "$cur")) + return 0 + ;; + esac + ;; + esac + return 1 +} + +_yarn_init() { + ((depth++)) + flags=( + --yes -y + --private -p + --install -i + ) + return 1 +} + +_yarn_install() { + ((depth++)) + flags=( + --audit -A + ) + return 1 +} + +_yarn_licenses() { + ((depth++)) + declare cmd + subcommands=( + list + generate-disclaimer + ) + case "$cur" in + -*) ;; + *) + __yarn_get_command + case "$cmd" in + licenses) + COMPREPLY=($(compgen -W "${subcommands[*]}" -- "$cur")) + return 0 + ;; + esac + ;; + esac + return 1 +} + +_yarn_list() { + ((depth++)) + flags=( + --depth + --pattern + ) + return 1 +} + +_yarn_node() { + ((depth++)) + flags=( + --into + ) + return 1 +} + +_yarn_outdated() { + ((depth++)) + case "$cur" in + -*) ;; + *) + COMPREPLY=( + $(compgen -W " + $(__yarn_get_package_fields dependencies) + $(__yarn_get_package_fields devDependencies) + " -- "$cur") + ) + return 0 + ;; + esac + return 1 +} + +_yarn_owner() { + ((depth++)) + declare cmd + subcommands=( + add + list + remove + ) + __yarn_get_command + if [[ $cmd == owner ]]; then + case "$cur" in + -*) ;; + *) + COMPREPLY=($(compgen -W "${subcommands[*]}" -- "$cur")) + return 0 + ;; + esac + fi + return 1 +} + +_yarn_pack() { + ((depth++)) + flags=( + --filename -f + ) + return 1 +} + +_yarn_policies() { + ((depth++)) + declare standard_policies=( + latest + nightly + rc + ) + + declare -i args + __yarn_count_args -d $depth + + case "$cur" in + -*) ;; + *) + case "$args" in + 0) + COMPREPLY=($(compgen -W "${standard_policies[*]}" -- "$cur")) + return 0 + ;; + esac + ;; + esac + return 1 +} + +_yarn_publish() { + ((depth++)) + flags=( + --access + --major + --message + --minor + --new-version + --no-commit-hooks + --no-git-tag-version + --patch + --preid + --premajor + --preminor + --prepatch + --prerelease + --tag + ) + return 1 +} + +_yarn_remove() { + ((depth++)) + declare cmd dependencies devDependencies + flags=( + --ignore-workspace-root-check -W + ) + __yarn_get_command -d 1 + case "$cmd" in + global) + dependencies=$(__yarn_get_package_fields -g dependencies) + devDependencies='' + ;; + remove) + dependencies=$(__yarn_get_package_fields dependencies) + devDependencies=$(__yarn_get_package_fields devDependencies) + ;; + *) + return 1 + ;; + esac + case "$cur" in + -*) ;; + *) + COMPREPLY=($(compgen -W "$dependencies $devDependencies" -- "$cur")) + return 0 + ;; + esac + return 1 +} + +_yarn_run() { + ((depth++)) + declare cmd + subcommands=( + env + $(__yarn_get_package_fields scripts) + ) + __yarn_get_command + if [[ $cmd == run ]]; then + case "$cur" in + -*) ;; + *) + COMPREPLY=($(compgen -W "${subcommands[*]}" -- "$cur")) + return 0 + ;; + esac + fi + return 1 +} + +_yarn_tag() { + ((depth++)) + declare cmd + subcommands=( + add + list + remove + ) + __yarn_get_command + case "$cmd" in + tag) + case "$cur" in + -*) ;; + *) + COMPREPLY=($(compgen -W "${subcommands[*]}" -- "$cur")) + return 0 + ;; + esac + ;; + esac + return 1 +} + +_yarn_team() { + ((depth++)) + declare cmd + subcommands=( + add + create + destroy + list + remove + ) + __yarn_get_command + case "$cmd" in + team) + case "$cur" in + -*) ;; + *) + COMPREPLY=($(compgen -W "${subcommands[*]}" -- "$cur")) + return 0 + ;; + esac + ;; + esac + return 1 +} + +_yarn_unplug() { + ((depth++)) + flags=( + --clear + --clear-all + ) + case "$cur" in + -*) ;; + *) + COMPREPLY=( + $(compgen -W " + $(__yarn_get_package_fields dependencies) + $(__yarn_get_package_fields devDependencies) + " -- "$cur") + ) + return 0 + ;; + + esac + return 1 +} + +_yarn_upgrade() { + ((depth++)) + declare cmd dependencies devDependencies + flags=( + --audit -A + --caret -C + --exact -E + --latest -L + --pattern -P + --scope -S + --tilde -T + ) + __yarn_get_command -d 1 + case "$cmd" in + global) + dependencies=$(__yarn_get_package_fields -g dependencies) + devDependencies='' + ;; + upgrade) + dependencies=$(__yarn_get_package_fields dependencies) + devDependencies=$(__yarn_get_package_fields devDependencies) + ;; + *) + return 1 + ;; + esac + case "$cur" in + -*) ;; + *) + COMPREPLY=($(compgen -W "$dependencies $devDependencies" -- "$cur")) + return 0 + ;; + esac + return 1 +} + +_yarn_upgrade_interactive() { + ((depth++)) + flags=( + --caret -C + --exact -E + --latest + --scope -S + --tilde -T + ) + return 1 +} + +_yarn_version() { + ((depth++)) + flags=( + --major + --message + --minor + --new-version + --no-commit-hooks + --no-git-tag-version + --patch + --preid + --premajor + --preminor + --prepatch + --prerelease + ) + return 1 +} + +_yarn_workspace() { + ((depth++)) + declare -i args + declare workspaces_info + + case "$cur" in + -*) ;; + *) + __yarn_count_args + case "$args" in + [0-2]) + workspaces_info=$(yarn workspaces info -s 2> /dev/null) + if [[ -n $workspaces_info ]]; then + mapfile -t < <( + sed -n 's/^ \{2\}"\([^"]*\)": {$/\1/p' <<< "$workspaces_info" + ) + COMPREPLY=($(compgen -W "${MAPFILE[*]}" -- "$cur")) + fi + return 0 + ;; + 3) + COMPREPLY=($(compgen -W "${commands[*]}" -- "$cur")) + return 0 + ;; + *) + declare cmd + workspaces_info=$(yarn workspaces info -s 2> /dev/null) + + if [[ -n $workspaces_info ]]; then + PWD=$( + sed -n '/^ \{2\}"'"${COMP_WORDS[2]}"'": {$/,/^ \{2\}},\{0,1\}$/{ + s/^ \{4\}"location": "\([^"]*\)",$/\1/p + }' <<< "$workspaces_info" + ) + fi + + __yarn_get_command -d 3 + "_yarn_${cmd//-/_}" 2> /dev/null + return $? + ;; + esac + ;; + esac + return 1 +} + +_yarn_workspaces() { + ((depth++)) + declare cmd + subcommands=( + info + run + ) + __yarn_get_command -d 4 + case "$cmd" in + workspaces) + case "$cur" in + -*) ;; + *) + COMPREPLY=($(compgen -W "${subcommands[*]}" -- "$cur")) + return 0 + ;; + esac + ;; + info) + return 0 + ;; + run) + __yarn_run + return 0 + ;; + esac + return 1 +} + +_yarn_why() { + ((depth++)) + case "$cur" in + -*) ;; + ./*) + compopt -o filenames + ;; + *) + declare modules + modules=$(yarn list --depth 0 | sed -n 's/.* \([a-zA-Z0-9@].*\)@.*/\1/p') || return 1 + COMPREPLY=($(compgen -W "$modules" -- "$cur")) + return 0 + ;; + esac + return 1 +} + +_yarn_yarn() { + ((depth++)) + case "$cur" in + -*) ;; + *) + COMPREPLY=($(compgen -W "${commands[*]}" -- "$cur")) + return 0 + ;; + esac + return 1 +} + +_yarn() { + # shellcheck disable=SC2064 + trap " + PWD=$PWD + $(shopt -p extglob) + set +o pipefail + " RETURN + + shopt -s extglob + set -o pipefail + + declare cur cmd prev + declare -a words + declare -i cword counter=1 depth=1 + declare -ar commands=( + access + add + audit + autoclean + bin + cache + check + config + create + exec + generate-lock-entry + global + help + import + info + init + install + licenses + link + list + login + logout + node + outdated + owner + pack + policies + publish + remove + run + tag + team + unlink + unplug + upgrade + upgrade-interactive + version + versions + why + workspace + workspaces + $(__yarn_get_package_fields scripts) + ) + declare -a subcommands=() + + declare -ar bool_arg_flags=( + --emoji + --production --prod + --scripts-prepend-node-path + ) + declare -ar dir_arg_flags=( + --cache-folder + --cwd + --global-folder + --into + --link-folder + --modules-folder + --preferred-cache-folder + --prefix + ) + declare -ar file_arg_flags=( + --filename -f + --use-manifest + --use-yarnrc + ) + declare -ar int_arg_flags=( + --depth + --network-concurrency + ) + declare -ar special_arg_flags=( + --access + --groups + --level + --network-timeout + ) + declare -ar optional_arg_flags=( + --emoji + --prod + --production + --scripts-prepend-node-path + ) + declare -ar skipped_arg_flags=( + --https-proxy + --message + --mutex + --new-version + --otp + --pattern -P + --proxy + --registry + --resolved + --scope -S + --tag + ) + declare -ar arg_flags=( + "${bool_arg_flags[@]}" + "${dir_arg_flags[@]}" + "${file_arg_flags[@]}" + "${int_arg_flags[@]}" + "${special_arg_flags[@]}" + "${optional_arg_flags[@]}" + "${skipped_arg_flags[@]}" + ) + + declare -ar global_flags=( + --cache-folder + --check-files + --cwd + --disable-pnp + --emoji + --enable-pnp --pnp + --flat + --focus + --force + --frozen-lockfile + --global-folder + --har + --help -h + --https-proxy + --ignore-engines + --ignore-optional + --ignore-platform + --ignore-scripts + --json + --link-duplicates + --link-folder + --modules-folder + --mutex + --network-concurrency + --network-timeout + --no-bin-links + --no-default-rc + --no-lockfile + --non-interactive + --no-node-version-check + --no-progress + --offline + --otp + --prefer-offline + --preferred-cache-folder + --prod + --production + --proxy + --pure-lockfile + --registry + --scripts-prepend-node-path + --silent -s + --skip-integrity-check + --strict-semver + --update-checksums + --use-yarnrc + --verbose + --version -v + ) + declare -a flags=() + + COMPREPLY=() + if command -v _get_comp_words_by_ref > /dev/null; then + _get_comp_words_by_ref -n = -n @ -n : cur prev words cword + elif command -v _init_completion > /dev/null; then + _init_completion + fi + + __yarn_get_command -d 1 + + __yarn_flag_args || "_yarn_${cmd//-/_}" 2> /dev/null || __yarn_fallback + + if command -v __ltrim_colon_completions > /dev/null; then + __ltrim_colon_completions "$cur" + fi +} + +if [[ ${BASH_VERSINFO[0]} -ge 4 && ${BASH_VERSINFO[1]} -ge 4 ]]; then + complete -o nosort -F _yarn yarn +else + complete -F _yarn yarn +fi \ No newline at end of file