diff options
Diffstat (limited to 'files/old-config/synth-shell/synth-shell-prompt.sh')
-rw-r--r-- | files/old-config/synth-shell/synth-shell-prompt.sh | 996 |
1 files changed, 996 insertions, 0 deletions
diff --git a/files/old-config/synth-shell/synth-shell-prompt.sh b/files/old-config/synth-shell/synth-shell-prompt.sh new file mode 100644 index 0000000..10481a1 --- /dev/null +++ b/files/old-config/synth-shell/synth-shell-prompt.sh @@ -0,0 +1,996 @@ +#!/bin/bash + +## +## +## ======================= +## WARNING!! +## DO NOT EDIT THIS FILE!! +## ======================= +## +## This file was generated by an installation script. +## It might be overwritten without warning at any time +## and you will lose all your changes. +## +## Visit for instructions and more information: +## https://github.com/andresgongora/synth-shell/ +## +## + + + +#!/bin/bash +## +-----------------------------------+-----------------------------------+ +## | | +## | Copyright (c) 2019-2020, Andres Gongora <mail@andresgongora.com>. | +## | | +## | This program is free software: you can redistribute it and/or modify | +## | it under the terms of the GNU General Public License as published by | +## | the Free Software Foundation, either version 3 of the License, or | +## | (at your option) any later version. | +## | | +## | This program is distributed in the hope that it will be useful, | +## | but WITHOUT ANY WARRANTY; without even the implied warranty of | +## | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | +## | GNU General Public License for more details. | +## | | +## | You should have received a copy of the GNU General Public License | +## | along with this program. If not, see <http://www.gnu.org/licenses/>. | +## | | +## +-----------------------------------------------------------------------+ +## +## DESCRIPTION +## =========== +## +## Script to colorize terminal text. +## It works in either of two ways, either by providing the formatting +## sequences that should be added to the text, or by directly wrapping +## the text with the desired control sequences +## +## +## +## +## +## USAGE +## ===== +## +## Formating a text directly: +## FORMATTED_TEXT=$(formatText "Hi!" -c red -b 13 -e bold) +## echo -e "$FORMATTED_TEXT" +## +## Getting the control sequences: +## FORMAT=$(getFormatCode -c blue -b yellow -e bold -e blink) +## NONE=$(getFormatCode -e none) +## echo -e $FORMAT"Hello"$NONE +## +## Options (More than one code may be specified) +## -c color name or 256bit code for font face +## -b background color name or 256bit code +## -e effect name (e.g. bold, blink, etc.) +## +## +## +## +## +## BASH TEXT FORMATING +## =================== +## +## Colors and text formatting can be achieved by preceding the text +## with an escape sequence. An escape sequence starts with an <ESC> +## character (commonly \e[), followed by one or more formatting codes +## (its possible) to apply more that one color/effect at a time), +## and finished by a lower case m. For example, the formatting code 1 +## tells the terminal to print the text bold face. This is acchieved as: +## \e[1m Hello World! +## +## But if nothing else is specified, then eveything that may be printed +## after 'Hello world!' will be bold face as well. The code 0 is thus +## meant to remove all formating from the text and return to normal: +## \e[1m Hello World! \e[0m +## +## It's also possible to paint the text in color (codes 30 to 37 and +## codes 90 to 97), or its background (codes 40 to 47 and 100 to 107). +## Red has code 31: +## \e[31m Hello World! \e[0m +## +## More than one code can be applied at a time. Codes are separated by +## semicolons. For example, code 31 paints the text in red. Thus, +## the following would print in red bold face: +## \e[1;31m Hello World! \e[0m +## +## Some formatting sequences are, in fact, comprised of two codes +## that must go together. For example, the code 38;5; tells the terminal +## that the next code (after the semicolon) should be interpreted as +## a 256 bit formatting color. So, for example, the code 82 is a light +## green. We can paint the text using this code as follows, plus bold +## face as follows - but notice that not all terminal support 256 colors:## +## \e[1;38;5;82m Hello World! \e[0m +## +## For a detailed list of all codes, this site has an excellent guide: +## https://misc.flogisoft.com/bash/tip_colors_and_formatting +## +## +## +## +## +## TODO: When requesting an 8 bit colorcode, detect if terminal supports +## 256 bits, and return appropriate code instead +## +## TODO: Improve this description/manual text +## +## TODO: Currently, if only one parameter is passed, its treated as a +## color. Addsupport to also detect whether its an effect code. +## Now: getFormatCode blue == getFormatCode -c blue +## Add: getFormatCode bold == getFormatCode -e bold +## +## TODO: Clean up this script. Prevent functions like "get8bitCode()" +## to be accessible from outside. These are only a "helper" function +## that should only be available to this script +## +##============================================================================== +## CODE PARSERS +##============================================================================== +##------------------------------------------------------------------------------ +## +get8bitCode() +{ + CODE=$1 + case $CODE in + default) + echo 9 + ;; + none) + echo 9 + ;; + black) + echo 0 + ;; + red) + echo 1 + ;; + green) + echo 2 + ;; + yellow) + echo 3 + ;; + blue) + echo 4 + ;; + magenta|purple|pink) + echo 5 + ;; + cyan) + echo 6 + ;; + light-gray) + echo 7 + ;; + dark-gray) + echo 60 + ;; + light-red) + echo 61 + ;; + light-green) + echo 62 + ;; + light-yellow) + echo 63 + ;; + light-blue) + echo 64 + ;; + light-magenta|light-purple) + echo 65 + ;; + light-cyan) + echo 66 + ;; + white) + echo 67 + ;; + *) + echo 0 + esac +} +##------------------------------------------------------------------------------ +## +getColorCode() +{ + COLOR=$1 + ## Check if color is a 256-color code + if [ $COLOR -eq $COLOR ] 2> /dev/null; then + if [ $COLOR -gt 0 -a $COLOR -lt 256 ]; then + echo "38;5;$COLOR" + else + echo 0 + fi + ## Or if color key-workd + else + BITCODE=$(get8bitCode $COLOR) + COLORCODE=$(($BITCODE + 30)) + echo $COLORCODE + fi +} +##------------------------------------------------------------------------------ +## +getBackgroundCode() +{ + COLOR=$1 + ## Check if color is a 256-color code + if [ $COLOR -eq $COLOR ] 2> /dev/null; then + if [ $COLOR -gt 0 -a $COLOR -lt 256 ]; then + echo "48;5;$COLOR" + else + echo 0 + fi + ## Or if color key-workd + else + BITCODE=$(get8bitCode $COLOR) + COLORCODE=$(($BITCODE + 40)) + echo $COLORCODE + fi +} +##------------------------------------------------------------------------------ +## +getEffectCode() +{ + EFFECT=$1 + NONE=0 + case $EFFECT in + none) + echo $NONE + ;; + default) + echo $NONE + ;; + bold) + echo 1 + ;; + bright) + echo 1 + ;; + dim) + echo 2 + ;; + underline) + echo 4 + ;; + blink) + echo 5 + ;; + reverse) + echo 7 + ;; + hidden) + echo 8 + ;; + strikeout) + echo 9 + ;; + *) + echo $NONE + esac +} +##------------------------------------------------------------------------------ +## +getFormattingSequence() +{ + START='\e[0;' + MIDLE=$1 + END='m' + echo -n "$START$MIDLE$END" +} +##============================================================================== +## AUX +##============================================================================== +applyCodeToText() +{ + local RESET=$(getFormattingSequence $(getEffectCode none)) + TEXT=$1 + CODE=$2 + echo -n "$CODE$TEXT$RESET" +} +##============================================================================== +## MAIN FUNCTIONS +##============================================================================== +##------------------------------------------------------------------------------ +## +getFormatCode() +{ + local RESET=$(getFormattingSequence $(getEffectCode none)) + ## NO ARGUMENT PROVIDED + if [ "$#" -eq 0 ]; then + echo -n "$RESET" + ## 1 ARGUMENT -> ASSUME TEXT COLOR + elif [ "$#" -eq 1 ]; then + TEXT_COLOR=$(getFormattingSequence $(getColorCode $1)) + echo -n "$TEXT_COLOR" + ## ARGUMENTS PROVIDED + else + FORMAT="" + while [ "$1" != "" ]; do + ## PROCESS ARGUMENTS + TYPE=$1 + ARGUMENT=$2 + case $TYPE in + -c) + CODE=$(getColorCode $ARGUMENT) + ;; + -b) + CODE=$(getBackgroundCode $ARGUMENT) + ;; + -e) + CODE=$(getEffectCode $ARGUMENT) + ;; + *) + CODE="" + esac + ## ADD CODE SEPARATOR IF NEEDED + if [ "$FORMAT" != "" ]; then + FORMAT="$FORMAT;" + fi + ## APPEND CODE + FORMAT="$FORMAT$CODE" + # Remove arguments from stack + shift + shift + done + ## APPLY FORMAT TO TEXT + FORMAT_CODE=$(getFormattingSequence $FORMAT) + echo -n "${FORMAT_CODE}" + fi +} +##------------------------------------------------------------------------------ +## +formatText() +{ + local RESET=$(getFormattingSequence $(getEffectCode none)) + ## NO ARGUMENT PROVIDED + if [ "$#" -eq 0 ]; then + echo -n "${RESET}" + ## ONLY A STRING PROVIDED -> Append reset sequence + elif [ "$#" -eq 1 ]; then + TEXT=$1 + echo -n "${TEXT}${RESET}" + ## ARGUMENTS PROVIDED + else + TEXT=$1 + FORMAT_CODE=$(getFormatCode "${@:2}") + applyCodeToText "$TEXT" "$FORMAT_CODE" + fi +} +##------------------------------------------------------------------------------ +## +removeColorCodes() +{ + printf "$1" | sed 's/\x1b\[[0-9;]*m//g' +} +##============================================================================== +## DEBUG +##============================================================================== +#formatText "$@" +#FORMATTED_TEXT=$(formatText "HELLO WORLD!!" -c red -b 13 -e bold -e blink -e strikeout) +#echo -e "$FORMATTED_TEXT" +#FORMAT=$(getFormatCode -c blue -b yellow) +#NONE=$(getFormatCode -e none) +#echo -e $FORMAT"Hello"$NONE +#!/bin/bash +## +-----------------------------------+-----------------------------------+ +## | | +## | Copyright (c) 2019-2023, Andres Gongora <mail@andresgongora.com>. | +## | | +## | This program is free software: you can redistribute it and/or modify | +## | it under the terms of the GNU General Public License as published by | +## | the Free Software Foundation, either version 3 of the License, or | +## | (at your option) any later version. | +## | | +## | This program is distributed in the hope that it will be useful, | +## | but WITHOUT ANY WARRANTY; without even the implied warranty of | +## | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | +## | GNU General Public License for more details. | +## | | +## | You should have received a copy of the GNU General Public License | +## | along with this program. If not, see <http://www.gnu.org/licenses/>. | +## | | +## +-----------------------------------------------------------------------+ +## +## DESCRIPTION +## +## This script takes a path name and shortens it. +## - home is replaced by ~ +## - last folder in apth is never truncated +## +## +## REFERENCES +## +## Original source: WOLFMAN'S color bash promt +## https://wiki.chakralinux.org/index.php?title=Color_Bash_Prompt#Wolfman.27s +## +##============================================================================== +## FUNCTIONS +##============================================================================== +##------------------------------------------------------------------------------ +## +shortenPath() +{ + ## GET PARAMETERS + local path=$1 + local max_length=$2 + local default_max_length=25 + local trunc_symbol=${3:-"…"} + ## CHECK PARAMETERS AND INIT + if [ -z "$path" ]; then + echo "" + exit + elif [ -z "$max_length" ]; then + local max_length=$default_max_length + fi + ## CLEANUP PATH + ## Replace HOME with ~ for the current user, similar to sed. + local path=${path/#$HOME/\~} + ## GET PRINT LENGHT + ## - Get curred directory (last folder in path) to get its length (num characters). + ## - Determine the actual max length we will use to truncate, choosing between either + ## $max_length, set by the usert, or the length of the current dir, + ## depending on which is greater. This ensures that even if we set a + ## relatively low $max_length value, the name of the current dir will not + ## be truncated. Store in $print_length + local dir=${path##*/} + local dir_length=${#dir} + local path_length=${#path} + local print_length=$(( ( max_length < dir_length ) ? dir_length : max_length )) # + ## TRUNCATE PATH TO + ## - If $path_length > $print_lenght + ## - Truncate the path to max_length + ## - Clean off path fragments before first '/' (included) + ## - Check if the bit we have removed would have landed at home + ## - If at home, prepend '~' to the clean path + ## - Else, prepend the "trunc_symbol" to the clean path + if [ $path_length -gt $print_length ]; then + local offset=$(( $path_length - $print_length )) + local truncated_path=${path:$offset} + local clean_path="/${truncated_path#*/}" + local removed_path=${path%%"$clean_path"} + if [ "$removed_path" == "~" ]; then + local short_path="~${clean_path}" + else + local short_path=${trunc_symbol}${clean_path} + fi + else + local short_path=$path + fi + ## RETURN FINAL PATH + echo $short_path +} +##============================================================================== +## DEBUG +##============================================================================== +#PATH1="/home/andy/my/imaginary/file/path" +#echo "$PATH1" +#echo "50: $(shortenPath "$PATH1" 50)" +#echo "25: $(shortenPath "$PATH1" 25)" +#echo "24: $(shortenPath "$PATH1" 24)" +#echo "23: $(shortenPath "$PATH1" 23)" +#echo "22: $(shortenPath "$PATH1" 22)" +#echo "10: $(shortenPath "$PATH1" 10)" +##============================================================================== +## COLORS +## +## Control the color and format scheme of the bash prompt. +## The prompt is divided into segments, listed below starting from the left: +## - USER: shows the user's name. +## - HOST: shows the host's name. +## - PWD: shows the current directory. +## - GIT: if inside a git repository, shows the name of current branch. +## - PYENV: if inside a Python Virtual environment. +## - TF: if inside a Terraform Workspace. +## - CLOCK: shows current time in H:M format. +## - INPUT: actual bash input. +## +## Valid color options: +## - white black light-gray dark-gray +## red green yellow blue cyan purple +## light-red light-green light-yellow light-blue light-cyan light-purple +## - Values in the range [0-255] for 256 bit colors. To check all number-color +## pairs for your terminal, you may run the following snippet by HaleTom: +## curl -s https://gist.githubusercontent.com/HaleTom/89ffe32783f89f403bba96bd7bcd1263/raw/ | bash +## or search something like "bash 256 color codes" on the internet. +## +##============================================================================== +##============================================================================== +## MAIN FORMAT +##============================================================================== +format="USER HOST PWD GIT PYENV TF KUBE" +separator_char='\uE0B0' # Separation character, '\uE0B0'=triangle +separator_padding_left='' # Add char or string to the left of the separator +separator_padding_right='' # Add char or string to the right of the separator +segment_padding=' ' # Add char or string around segment text +enable_vertical_padding=true # Add extra new line over prompt +enable_command_on_new_line=false # Add new line between prompt and command +##============================================================================== +## USER +##============================================================================== +font_color_user="white" +background_user="blue" +texteffect_user="bold" +##============================================================================== +## HOST +##============================================================================== +font_color_host="white" +background_host="light-blue" +texteffect_host="bold" +##============================================================================== +## PWD (working dir) +##============================================================================== +font_color_pwd="dark-gray" +background_pwd="white" +texteffect_pwd="bold" +max_pwd_char="25" +pwd_trunc_symbol="…" +##============================================================================== +## GIT +##============================================================================== +font_color_git="light-gray" +background_git="dark-gray" +texteffect_git="bold" +git_symbol_synced='' +git_symbol_unpushed=' ▲' +git_symbol_unpulled=' ▼' +git_symbol_unpushedunpulled=' ◆' +git_symbol_dirty=' ◔' +git_symbol_dirty_unpushed=' ◔ △' +git_symbol_dirty_unpulled=' ◔ ▽' +git_symbol_dirty_unpushedunpulled=' ◔ ◇' +git_symbol_stash='🗎' +git_update_period_minutes=15 # Use -1 to disable automatic updates +##============================================================================== +## PYENV +##============================================================================== +font_color_pyenv="white" +background_pyenv="blue" +texteffect_pyenv="bold" +##============================================================================== +## KUBERNETES +##============================================================================== +font_color_kube="white" +background_kube="purple" +texteffect_kube="bold" +##============================================================================== +## TERRAFORM WORKSPACE +##============================================================================== +font_color_tf="purple" +background_tf="light-purple" +texteffect_tf="bold" +##============================================================================== +## CLOCK +##============================================================================== +font_color_clock="white" +background_clock="light-blue" +texteffect_clock="bold" +clock_format="%H:%M" +##============================================================================== +## INPUT (user typed command) +##============================================================================== +font_color_input="45" +background_input="none" +texteffect_input="bold" +#!/bin/bash +## +-----------------------------------+-----------------------------------+ +## | | +## | Copyright (c) 2018-2023, Andres Gongora <mail@andresgongora.com>. | +## | | +## | This program is free software: you can redistribute it and/or modify | +## | it under the terms of the GNU General Public License as published by | +## | the Free Software Foundation, either version 3 of the License, or | +## | (at your option) any later version. | +## | | +## | This program is distributed in the hope that it will be useful, | +## | but WITHOUT ANY WARRANTY; without even the implied warranty of | +## | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | +## | GNU General Public License for more details. | +## | | +## | You should have received a copy of the GNU General Public License | +## | along with this program. If not, see <http://www.gnu.org/licenses/>. | +## | | +## +-----------------------------------------------------------------------+ +## +## DESCRIPTION +## +## This script updates your "PS1" environment variable to display colors. +## Additionally, it also shortens the name of your current path to a +## maximum 25 characters, which is quite useful when working in deeply +## nested folders. +## +## +## +## REFFERENCES +## +## * http://tldp.org/HOWTO/Bash-Prompt-HOWTO/index.html +## +## +##============================================================================== +## EXTERNAL DEPENDENCIES +##============================================================================== +[ "$(type -t include)" != 'function' ]&&{ include(){ { [ -z "$_IR" ]&&_IR="$PWD"&&cd "$(dirname "${BASH_SOURCE[0]}")"&&include "$1"&&cd "$_IR"&&unset _IR;}||{ local d="$PWD"&&cd "$(dirname "$PWD/$1")"&&. "$(basename "$1")"&&cd "$d";}||{ echo "Include failed $PWD->$1"&&exit 1;};};} +synth_shell_prompt() +{ +##============================================================================== +## FUNCTIONS +##============================================================================== +##------------------------------------------------------------------------------ +## +## Returns current git branch for current directory, if (and only if) +## the current directory is part of a git repository, and git is installed. +## +## In addition, it adds a symbol to indicate the state of the repository. +## By default, these symbols and their meaning are (set globally): +## +## UPSTREAM NO CHANGE DIRTY +## up to date SSP_GIT_SYNCED SSP_GIT_DIRTY +## ahead SSP_GIT_AHEAD SSP_GIT_DIRTY_AHEAD +## behind SSP_GIT_BEHIND SSP_GIT_DIRTY_BEHIND +## diverged SSP_GIT_DIVERGED SSP_GIT_DIRTY_DIVERGED +## +## Returns an empty string otherwise. +## +## Inspired by twolfson's sexy-bash-prompt: +## https://github.com/twolfson/sexy-bash-prompt +## +getGitBranch() +{ + if ( which git > /dev/null 2>&1 ); then + ## CHECK IF IN A GIT REPOSITORY, OTHERWISE SKIP + local branch=$(git branch 2> /dev/null |\ + sed -n '/^[^*]/d;s/*\s*\(.*\)/\1/p') + if [[ -n "$branch" ]]; then + ## UPDATE LOCAL GIT BRANCH (i.e., fetch) + ## This will talk to the remote repository to get the latest + ## updates. Because doing so for every terminal prompt can + ## (and will) be slow, the script will do so only if its globaly + ## enabled and only periodically in the background. + if [ "$SSP_GIT_UPDATE_PERIOD_MINUTES" -ge 0 ]; then + ## Find .git + local d="$PWD" + local max_lvls=25 + while [ ! -e "./.git" -a $max_lvls -gt 0 ]; do + cd .. # Go up 1 level + max_lvls=$((max_lvls - 1)) + done + local dot_git="${PWD}/.git" + cd "$d" + ## Check if submodule + if [ -f "$dot_git" ]; then + local dot_git=$(cat $dot_git | grep 'gitdir' | sed 's/gitdir:\ //g') + fi + ## Get timestamp + if [ -d "$dot_git" -a -e "${dot_git}/FETCH_HEAD" ]; then + local git_last_update=$(stat -c "%Y" "${dot_git}/FETCH_HEAD") + fi + ## Update if it's time to do so + if [ ! -z $git_last_update ]; then + local current_timestamp=$(date +%s) + local elapsed_minutes=$(((current_timestamp-git_last_update)/60)) + if [ "$elapsed_minutes" -ge "$SSP_GIT_UPDATE_PERIOD_MINUTES" ]; then + git fetch --recurse-submodules > /dev/null 2>&1 & + fi + fi + fi + ## GET GIT STATUS + ## This information contains whether the current branch is + ## ahead, behind or diverged (ahead & behind), as well as + ## whether any file has been modified locally (is dirty). + ## --porcelain: script friendly output. + ## -b: show branch tracking info. + ## -u no: do not list untracked/dirty files + ## From the first line we get whether we are synced, and if + ## there are more lines, then we know it is dirty. + ## NOTE: this requires that you fetch your repository, + ## otherwise your information is outdated. + local is_dirty=false &&\ + [[ -n "$(git status --porcelain)" ]] &&\ + is_dirty=true + local is_ahead=false &&\ + [[ "$(git status --porcelain -u no -b)" == *"ahead"* ]] &&\ + is_ahead=true + local is_behind=false &&\ + [[ "$(git status --porcelain -u no -b)" == *"behind"* ]] &&\ + is_behind=true + ## SELECT SYMBOL + if $is_dirty && $is_ahead && $is_behind; then + local symbol=$SSP_GIT_DIRTY_DIVERGED + elif $is_dirty && $is_ahead; then + local symbol=$SSP_GIT_DIRTY_AHEAD + elif $is_dirty && $is_behind; then + local symbol=$SSP_GIT_DIRTY_BEHIND + elif $is_dirty; then + local symbol=$SSP_GIT_DIRTY + elif $is_ahead && $is_behind; then + local symbol=$SSP_GIT_DIVERGED + elif $is_ahead; then + local symbol=$SSP_GIT_AHEAD + elif $is_behind; then + local symbol=$SSP_GIT_BEHIND + else + local symbol=$SSP_GIT_SYNCED + fi + ## GET TAG (if any) + [[ -n "$(git tag --points-at HEAD)" ]] && local readonly tag=" $(git tag --points-at HEAD)" || local readonly tag="" + ## CHECK IF REPOSITORY HAS STASHED CODE + local git_stash="" + local readonly stashed_elements=$(git stash list 2> /dev/null | wc -l) + if [ "$stashed_elements" -gt 0 ]; then + git_stash=" ${stashed_elements}${SSP_GIT_STASH}" + fi + ## RETURN STRING + echo "${branch}$symbol${git_stash}${tag}" + fi + fi + ## DEFAULT + echo "" +} +##------------------------------------------------------------------------------ +## +## +getTerraform() +{ + ## Check if we are in a terraform directory + if [ -d .terraform ]; then + ## Check if the terraform binary is in the path + if ( which terraform > /dev/null 2>&1 ); then + ## Get the terraform workspace + local tf="$(terraform workspace show 2> /dev/null | tr -d '\n')" + echo "$tf" + fi + fi +} +##------------------------------------------------------------------------------ +## +## +getPyenv() +{ + ## Conda environment + if [ -n "$CONDA_DEFAULT_ENV" ]; then + echo "$CONDA_DEFAULT_ENV" + ## Python virtual environment + elif [ -n "${VIRTUAL_ENV:-}" ]; then + local regex='PS1=\"\((.*?)\)\s\$\{PS1' + local pyenv=$(cat $VIRTUAL_ENV/bin/activate | perl -n -e"/$regex/ && print \$1" 2> /dev/null) + if [ -z "${pyenv}" ]; then + local pyenv=$(basename ${VIRTUAL_ENV}) + fi + echo "$pyenv" + fi +} +##------------------------------------------------------------------------------ +## +## +getKube() +{ + type kubectl &>/dev/null && \ + type yq &>/dev/null && \ + echo -n "$(kubectl config view | yq '.contexts[].context.cluster |select(.contexts[].name == .current-context)' | head -n 1)" +} +##------------------------------------------------------------------------------ +## +## Print each word of the propmpt, i.e., a small text acompanied by the +## separator character and formated with colors and background. +## +printSegment() +{ + ## GET PARAMETERS + local text=$1 + local font_color=$2 + local background_color=$3 + local next_background_color=$4 # needed for the separator, it participates in this and the next text segment + local font_effect=$5 + ## COMPUTE COLOR FORMAT CODES + local no_color="\[$(getFormatCode -e reset)\]" + local text_format="\[$(getFormatCode -c $font_color -b $background_color -e $font_effect)\]" + local separator_format="\[$(getFormatCode -c $background_color -b $next_background_color)\]" + ## GENERATE TEXT + printf "${text_format}${segment_padding}${text}${segment_padding}${separator_padding_left}${separator_format}${separator_char}${separator_padding_right}${no_color}" +} +##------------------------------------------------------------------------------ +## +## +get_colors_for_element() +{ + case $1 in + "USER") echo "${SSP_COLORS_USER[@]}" ;; + "HOST") echo "${SSP_COLORS_HOST[@]}" ;; + "PWD") echo "${SSP_COLORS_PWD[@]}" ;; + "GIT") echo "${SSP_COLORS_GIT[@]}" ;; + "PYENV") echo "${SSP_COLORS_PYENV[@]}";; + "KUBE") echo "${SSP_COLORS_KUBE[@]}";; + "TF") echo "${SSP_COLORS_TF[@]}" ;; + "CLOCK") echo "${SSP_COLORS_CLOCK[@]}";; + "INPUT") echo "${SSP_COLORS_INPUT[@]}";; + *) + esac +} +##------------------------------------------------------------------------------ +## +## +combine_elements() +{ + local first=$1 + local second=$2 + local colors_first=($(get_colors_for_element $first)) + local colors_second=($(get_colors_for_element $second)) + case $first in + "USER") local text="$user" ;; + "HOST") local text="$host" ;; + "PWD") local text="$path" ;; + "GIT") local text="$git_branch" ;; + "PYENV") local text="$pyenv" ;; + "KUBE") local text="$kube" ;; + "TF") local text="$tf" ;; + "CLOCK") local text="$clock" ;; + "INPUT") local text="" ;; + *) local text="" ;; + esac + local text_color=${colors_first[0]} + local bg_color=${colors_first[1]} + local next_bg_color=${colors_second[1]} + local text_effect=${colors_first[2]} + printSegment "$text" "$text_color" "$bg_color" "$next_bg_color" "$text_effect" +} +##============================================================================== +## HOOK +##============================================================================== +prompt_command_hook() +{ + ## GET PARAMETERS + ## This might be a bit redundant, but it makes it easier to maintain + local elements=(${SSP_ELEMENTS[@]}) + local user=$USER + local host=$HOSTNAME + local path="$(shortenPath "$PWD" $SSP_MAX_PWD_CHAR $SSP_PWD_TRUNC_SYMBOL)" # bash-tools::shortenPath + local git_branch="$(getGitBranch)" + local pyenv="$(getPyenv)" + local kube="$(getKube)" + local tf="$(getTerraform)" + local clock="$(date +"${SSP_CLOCK_FORMAT}")" + ## ADAPT DYNAMICALLY ELEMENTS TO BE SHOWN + ## Check if elements such as GIT and the Python environment should be + ## shown and adapt the variables as needed. This usually implies removing + ## the appropriate field from the "elements" array if the user set them + if [ -z "$git_branch" ]; then + elements=( ${elements[@]/"GIT"} ) # Remove GIT from elements to be shown + fi + if [ -z "$pyenv" ]; then + elements=( ${elements[@]/"PYENV"} ) # Remove PYENV from elements to be shown + fi + if [ -z "$tf" ]; then + elements=( ${elements[@]/"TF"} ) # Remove TF from elements to be shown + fi + if [ -z "$kube" ]; then + elements=( ${elements[@]/"KUBE"} ) # Remove KUBE from elements to be shown + fi + ## WINDOW TITLE + ## Prevent messed up terminal-window titles, must be set in the PS1 variable + case $TERM in + xterm*|rxvt*) + SSP_PWD="$path" + local titlebar="\[\033]0;\${USER}@\${HOSTNAME}: \${SSP_PWD}\007\]" + ;; + *) + local titlebar="" + ;; + esac + ## CONSTRUCT PROMPT ITERATIVELY + ## Iterate through all elements to be shown and combine them. Stop once only + ## 1 element is left, which should be the "INPUT" element; then apply the + ## INPUT formatting. + ## Notice that this reuses the PS1 variables over and over again, and appends + ## all extra formatting elements to the end of it. + PS1="${titlebar}${SSP_VERTICAL_PADDING}${SSP_NEW_LINE_LINK_TOP}" + while [ "${#elements[@]}" -gt 1 ]; do + local current=${elements[0]} + local next=${elements[1]} + local elements=("${elements[@]:1}") #remove the 1st element + PS1="$PS1$(combine_elements $current $next)" + done + local input_colors=($(get_colors_for_element ${elements[0]})) + local input_color=${input_colors[0]} + local input_bg=${input_colors[1]} + local input_effect=${input_colors[2]} + local input_format="\[$(getFormatCode -c $input_color -b $input_bg -e $input_effect)\]" + local command_start_symbol="${input_format}${SSP_BASH_SYMBOL}" + ## the prompt is then the prompt we build above, the separation between prompt and command and in + ## the case of a new line inbetween, the corresponding link and $ symbol to start the command. + PS1="${PS1}${SSP_PROMPT_COMM_SEP}${SSP_NEW_LINE_LINK_BOTTOM}${command_start_symbol} $input_format" + ## Once this point is reached, PS1 is formatted and set. The terminal session + ## will then use that variable to prompt the user :) +} +##============================================================================== +## MAIN +##============================================================================== + ## LOAD USER CONFIGURATION + local user_config_file="$HOME/.config/synth-shell/synth-shell-prompt.config" + local root_config_file="/etc/synth-shell/synth-shell-prompt.root.config" + local sys_config_file="/etc/synth-shell/synth-shell-prompt.config" + if [ -f $user_config_file ]; then + source $user_config_file + elif [ -f $root_config_file -a "$USER" == "root" ]; then + source $root_config_file + elif [ -f $sys_config_file ]; then + source $sys_config_file + fi + ## PADDING + if $enable_vertical_padding; then + local vertical_padding="\n" + else + local vertical_padding="" + fi + ## NEW LINE + if $enable_command_on_new_line; then + local new_line_link_top="╭" + local new_line_link_bottom="╰" + local prompt_command_separation="\n" + local bash_symbol="\$" + else + local new_line_link_top="" + local new_line_link_top="" + local prompt_command_separation="" + local bash_symbol="" + fi + ## CONFIG FOR "prompt_command_hook()" + SSP_ELEMENTS=($format "INPUT") # Append INPUT to elements that have to be shown + SSP_COLORS_USER=($font_color_user $background_user $texteffect_user) + SSP_COLORS_HOST=($font_color_host $background_host $texteffect_host) + SSP_COLORS_PWD=($font_color_pwd $background_pwd $texteffect_pwd) + SSP_COLORS_GIT=($font_color_git $background_git $texteffect_git) + SSP_COLORS_PYENV=($font_color_pyenv $background_pyenv $texteffect_pyenv) + SSP_COLORS_KUBE=($font_color_kube $background_kube $texteffect_kube) + SSP_COLORS_TF=($font_color_tf $background_tf $texteffect_tf) + SSP_COLORS_CLOCK=($font_color_clock $background_clock $texteffect_clock) + SSP_COLORS_INPUT=($font_color_input $background_input $texteffect_input) + SSP_VERTICAL_PADDING=$vertical_padding + SSP_NEW_LINE_LINK_TOP=$new_line_link_top + SSP_NEW_LINE_LINK_BOTTOM=$new_line_link_bottom + SSP_PROMPT_COMM_SEP=$prompt_command_separation + SSP_BASH_SYMBOL=$bash_symbol + SSP_MAX_PWD_CHAR=${max_pwd_char:-25} + SSP_PWD_TRUNC_SYMBOL=${pwd_trunc_symbol:-"..."} + SSP_GIT_SYNCED=$git_symbol_synced + SSP_GIT_AHEAD=$git_symbol_unpushed + SSP_GIT_BEHIND=$git_symbol_unpulled + SSP_GIT_DIVERGED=$git_symbol_unpushedunpulled + SSP_GIT_DIRTY=$git_symbol_dirty + SSP_GIT_DIRTY_AHEAD=$git_symbol_dirty_unpushed + SSP_GIT_DIRTY_BEHIND=$git_symbol_dirty_unpulled + SSP_GIT_DIRTY_DIVERGED=$git_symbol_dirty_unpushedunpulled + SSP_GIT_STASH=$git_symbol_stash + SSP_GIT_UPDATE_PERIOD_MINUTES=$git_update_period_minutes + SSP_CLOCK_FORMAT=${clock_format:-"%H:%M"} + ## For terminal line coloring, leaving the rest standard + none="$(tput sgr0)" + trap 'echo -ne "${none}"' DEBUG + ## ADD HOOK TO UPDATE PS1 AFTER EACH COMMAND + ## Bash provides an environment variable called PROMPT_COMMAND. + ## The contents of this variable are executed as a regular Bash command + ## just before Bash displays a prompt. + ## We want it to call our own command to truncate PWD and store it in NEW_PWD + PROMPT_COMMAND=prompt_command_hook +} # synth_shell_prompt() +##------------------------------------------------------------------------------ +## +## CALL SCRIPT FUNCTION +## - CHECK IF SCRIPT IS _NOT_ BEING SOURCED +## - CHECK IF COLOR SUPPORTED +## - Check if compliant with Ecma-48 (ISO/IEC-6429) +## - Call script +## - Unset script +## If not running interactively, don't do anything +if [ -n "$( echo $- | grep i )" ]; then + if [ "${BASH_SOURCE[0]}" == "${0}" ]; then + echo -e "Do not run this script, it will do nothing.\nPlease source it instead by running:\n" + echo -e "\t. ${BASH_SOURCE[0]}\n" + elif [ -x /usr/bin/tput ] && tput setaf 1 >&/dev/null; then + synth_shell_prompt + fi + unset synth_shell_prompt + unset include +fi |