#!/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 . | ## | | ## | 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 . | ## | | ## +-----------------------------------------------------------------------+ ## ## 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 ## 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 . | ## | | ## | 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 . | ## | | ## +-----------------------------------------------------------------------+ ## ## 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 . | ## | | ## | 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 . | ## | | ## +-----------------------------------------------------------------------+ ## ## 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