Enhance the prompt by calculating alignment based on the hostname and branch lengths, ensuring better visibility of git status in the terminal.
327 lines
11 KiB
Bash
327 lines
11 KiB
Bash
# Color definitions
|
|
_WHITE='\033[1;37m' # White
|
|
_NC='\033[0m' # Get the current day of the week, day of the month, and year
|
|
day_of_week=$(date "+%A")
|
|
day_of_month=$(date "+%d")
|
|
month_name=$(date "+%B")
|
|
year=$(date "+%Y")
|
|
|
|
# Determine the day suffix (th, nd, rd)
|
|
case "$day_of_month" in
|
|
1[0-9]) day_suffix="th";;
|
|
*1) day_suffix="st";;
|
|
*2) day_suffix="nd";;
|
|
*3) day_suffix="rd";;
|
|
*) day_suffix="th";;
|
|
esac
|
|
|
|
_RED='\033[0;31m' # Red
|
|
_GREEN='\033[01;32m' # Bright Green
|
|
_YELLOW='\033[0;33m' # Yellow
|
|
_BLUE='\033[1;34m' # Bright Blue
|
|
_BRIGHT_GREEN='\033[1;32m' # Bright Green (for positive)
|
|
_BRIGHT_RED='\033[1;31m' # Bright Red (for negative)
|
|
_BRIGHT_WHITE='\033[1;37m' # Bright White
|
|
_DIM_RED='\033[91m' # Bright Red (for TODO files)
|
|
|
|
export SHELL_CONFIG="$SHELL_CONFIG:.bashrc"
|
|
#
|
|
# ~/.bashrc
|
|
#
|
|
|
|
function show_date() {
|
|
# Define the dot file to store the selected adjective
|
|
dotfile="$HOME/.adjective_of_the_day"
|
|
|
|
# Check if the dot file exists and was modified since yesterday
|
|
if [[ -f "$dotfile" && $(date -d "$(stat -c %y "$dotfile")" +%s) -ge $(date -d 'yesterday' +%s) ]]; then
|
|
# If the dot file exists and was modified since yesterday
|
|
# read the stored adjective from the file
|
|
selected_adjective=$(cat "$dotfile")
|
|
else
|
|
# Define an array of adjectives with classifications
|
|
adjectives=(
|
|
"beautiful:positive"
|
|
"engaging:positive"
|
|
"majestic:positive"
|
|
"distinguished:positive"
|
|
"venerable:positive"
|
|
"formal:positive"
|
|
"elegant:positive"
|
|
"serene:positive"
|
|
"graceful:positive"
|
|
"regal:positive"
|
|
"noble:positive"
|
|
|
|
"miserable:negative"
|
|
"worthless:negative"
|
|
"depressing:negative"
|
|
"soulless:negative"
|
|
"desolate:negative"
|
|
"archaic:negative"
|
|
"grim:negative"
|
|
"dreadful:negative"
|
|
"forlorn:negative"
|
|
"wretched:negative"
|
|
|
|
"neutral:neutral"
|
|
"ordinary:neutral"
|
|
"common:neutral"
|
|
"antique:neutral"
|
|
"ceremonial:neutral"
|
|
"timeless:neutral"
|
|
"classic:neutral"
|
|
"historic:neutral"
|
|
"ancient:neutral"
|
|
)
|
|
|
|
# Select a random adjective from the array
|
|
selected_adjective="${adjectives[$RANDOM % ${#adjectives[@]}]}"
|
|
|
|
# Store the selected adjective in the dot file
|
|
echo "$selected_adjective" > "$dotfile"
|
|
fi
|
|
|
|
# Split the selected adjective into the adjective and classification parts
|
|
IFS=':' read -r adjective classification <<< "$selected_adjective"
|
|
|
|
# Get the current day of the week, day of the month, and year
|
|
day_of_week=$(date "+%A")
|
|
day_of_month=$(date "+%d")
|
|
month_name=$(date "+%B")
|
|
year=$(date "+%Y")
|
|
|
|
# Determine the day suffix (th, nd, rd)
|
|
case "$day_of_month" in
|
|
1[0-9]) day_suffix="th";;
|
|
*1) day_suffix="st";;
|
|
*2) day_suffix="nd";;
|
|
*3) day_suffix="rd";;
|
|
*) day_suffix="th";;
|
|
esac
|
|
|
|
# Determine the color based on the classification
|
|
case "$classification" in
|
|
"positive") text_color="$_BRIGHT_GREEN";;
|
|
"negative") text_color="$_BRIGHT_RED";;
|
|
*) text_color="";;
|
|
esac
|
|
|
|
# Create the full date format with colored parts and the selected adjective
|
|
full_date="Pray, be informed, on this ${text_color}${adjective}${_NC} day,\n${_BLUE}${day_of_week}${_NC} the ${_BLUE}${day_of_month}${day_suffix}${_NC} day of ${_BLUE}${month_name}${_NC}, in the year of our Lord ${_BLUE}${year}${_NC}!"
|
|
|
|
# Print the full date
|
|
echo -e "$full_date"
|
|
echo ""
|
|
}
|
|
|
|
|
|
# If not running interactively, don't do anything
|
|
[[ $- != *i* ]] && return
|
|
|
|
# ============================================================================
|
|
# SHELL CONFIGURATION
|
|
# ============================================================================
|
|
|
|
export HISTCONTROL=ignoreboth:erasedups
|
|
|
|
# Function to draw a terminal-width divider line with timestamp
|
|
function draw_prompt_divider() {
|
|
local width=${COLUMNS:-80} # Use terminal width, fallback to 80
|
|
local timestamp=$(date '+%H:%M:%S')
|
|
local prefix="$timestamp ├"
|
|
local prefix_length=${#prefix}
|
|
local line_length=$((width - prefix_length))
|
|
|
|
# Print timestamp + junction + line to fill remaining width
|
|
printf '%s' "$prefix"
|
|
printf '%.0s─' $(seq 1 $line_length)
|
|
echo
|
|
}
|
|
|
|
# Function to calculate git status alignment based on hostname and branch lengths
|
|
function calculate_git_alignment() {
|
|
# Get the raw hostname length (without color codes) - use actual prompt format
|
|
local user_host="$USER@$HOSTNAME"
|
|
local hostname_only="$HOSTNAME" # Just the hostname part after @
|
|
local hostname_length=${#hostname_only}
|
|
|
|
# Extract branch name from GITSTATUS_PROMPT if it exists
|
|
local branch_name=""
|
|
if [[ -n "$GITSTATUS_PROMPT" ]]; then
|
|
# Remove all escape sequences: \001, \002, and ANSI color codes
|
|
local cleaned_prompt=$(echo "$GITSTATUS_PROMPT" | sed -e 's/\x01//g' -e 's/\x02//g' -e 's/\x1b\[[0-9;]*m//g')
|
|
|
|
# Extract first word as branch name and trim any whitespace
|
|
branch_name=$(echo "$cleaned_prompt" | awk '{print $1}' | tr -d '[:space:]')
|
|
fi
|
|
|
|
local branch_length=${#branch_name}
|
|
|
|
# Calculate padding to align the END of branch name with END of hostname
|
|
# We want: [padding spaces] + branch_name to end at same position as hostname
|
|
# Total user@hostname length is where we want to align to
|
|
local total_user_host_length=${#user_host} # "ray@MachineOne" = 14 chars
|
|
local needed_padding=$((total_user_host_length - branch_length))
|
|
|
|
# Ensure minimum indentation of 8 spaces even if branch is very long
|
|
if [[ $needed_padding -lt 8 ]]; then
|
|
needed_padding=8
|
|
fi
|
|
|
|
# Generate the padding string
|
|
GIT_ALIGNMENT_PADDING=$(printf '%*s' $needed_padding '')
|
|
}
|
|
|
|
# Load custom gitstatus configuration
|
|
[ -f "$HOME/.config/bash/gitstatus-custom.sh" ] && . "$HOME/.config/bash/gitstatus-custom.sh"
|
|
|
|
# Set up prompt command to draw divider, update git status, and calculate alignment
|
|
PROMPT_COMMAND="draw_prompt_divider; my_gitstatus_prompt_update; calculate_git_alignment"
|
|
|
|
# Set PS1 with user@host, directory on first line, dynamically aligned git status, prompt on third line
|
|
PS1='\[\033[01;32m\]\u@\h\[\033[00m\] \[\033[1;34m\]\w\[\033[00m\]\n${GITSTATUS_PROMPT:+$GIT_ALIGNMENT_PADDING$GITSTATUS_PROMPT\n}\[\033[01;$((31+!$?))m\]\$\[\033[00m\] \[\e]0;\u@\h: \w\a\]'
|
|
|
|
# If there are multiple matches for completion, Tab should cycle through them
|
|
bind TAB:menu-complete
|
|
# Display a list of the matching files
|
|
bind "set show-all-if-ambiguous on"
|
|
# Perform partial (common) completion on the first Tab press, only start
|
|
# cycling full results on the second Tab press (from bash version 5)
|
|
bind "set menu-complete-display-prefix on"
|
|
|
|
show_date;
|
|
|
|
source ~/.profile
|
|
|
|
export NVM_DIR="$HOME/.nvm"
|
|
[ -s "$NVM_DIR/nvm.sh" ] && \. "$NVM_DIR/nvm.sh" # This loads nvm
|
|
[ -s "$NVM_DIR/bash_completion" ] && \. "$NVM_DIR/bash_completion" # This loads nvm bash_completion
|
|
|
|
# https://github.com/skywind3000/z.lua
|
|
if command -v lua ; then
|
|
eval "$(lua $HOME/.z.lua/z.lua --init bash enhanced once echo)"
|
|
fi > /dev/null
|
|
|
|
_mem_available=$(awk '/MemAvailable/ { printf "%.1f \n", $2/1024/1024 }' /proc/meminfo)
|
|
_updates_available="$(wc -l $HOME/.checkupdates | cut -d' ' -f1)"
|
|
[ -z $_updates_available ] && _updates_available="0"
|
|
|
|
echo "Remember your commands:"
|
|
echo -e " ${_WHITE}lftp cheat vimv 'flameshot gui' rclone mid3v2 zathura tesseract remmina$ v4l2 ${_NC}(webcam)"
|
|
echo ""
|
|
|
|
if [ ${_mem_available%.*} -lt 5 ] ; then
|
|
echo -ne "Memory available: ${_YELLOW}"
|
|
[ ${_mem_available%.*} -lt 3 ] && echo -ne "${_RED}"
|
|
echo -n "${_mem_available}"
|
|
echo -e "GB${_NC}"
|
|
fi
|
|
|
|
if [ $_updates_available -gt 0 ] ; then
|
|
update_color="$_BRIGHT_WHITE" # default white
|
|
if [ $_updates_available -gt 29 ] ; then
|
|
update_color="$_RED" # red
|
|
elif [ $_updates_available -gt 15 ] ; then
|
|
update_color="$_YELLOW" # yellow
|
|
fi
|
|
|
|
echo -ne "Updates available: ${update_color}${_updates_available}${_NC}"
|
|
echo -ne " [ update with: ${update_color}update${_NC} ]"
|
|
echo ""
|
|
fi
|
|
|
|
_orphans_available="$(pacman -Qdtq 2>/dev/null | wc -l)"
|
|
if [ $_orphans_available -gt 0 ] ; then
|
|
echo -ne "Orphaned packages: $_BRIGHT_WHITE"
|
|
|
|
orphan_color="$_BRIGHT_WHITE"
|
|
if [ $_orphans_available -gt 9 ] ; then
|
|
orphan_color="$_RED"
|
|
elif [ $_orphans_available -gt 4 ] ; then
|
|
orphan_color="$_YELLOW"
|
|
fi
|
|
|
|
echo -ne "${orphan_color}${_orphans_available}${_NC}"
|
|
echo -ne " [ remove with: ${orphan_color}sudo pacman -Rns \$(pacman -Qdtq)${_NC} ]"
|
|
echo ""
|
|
fi
|
|
|
|
|
|
echo ""
|
|
echo -e "Remember \"${_BLUE}TODO.md${_NC}\" and \"${_BLUE}autonote.md${_NC}\" files have content automatically displayed."
|
|
echo -e "Edit these with ${_BLUE}et${_NC} and ${_BLUE}ea${_NC}"
|
|
echo ""
|
|
|
|
. "$HOME/.config/bash/cheat.bash"
|
|
|
|
if command -v checkupdates ; then
|
|
(checkupdates > "$HOME/.checkupdates") & disown
|
|
fi > /dev/null
|
|
|
|
. "$HOME/.cargo/env"
|
|
|
|
alias backup='sudo borgmatic create --verbosity 1 --files'
|
|
|
|
# Function to check for TODO.md and echo its contents
|
|
function check_todo() {
|
|
if [ -f "TODO.md" ]; then
|
|
echo
|
|
echo -e "${_DIM_RED}TODO.md${_NC}"
|
|
echo "---------------------------"
|
|
mdcat TODO.md
|
|
echo "---------------------------"
|
|
echo
|
|
fi
|
|
}
|
|
# Function to check for .autonote.md and echo its contents
|
|
function check_autonote() {
|
|
if [ -f ".autonote.md" ]; then
|
|
echo
|
|
echo -e "${_DIM_RED}autonote.md${_NC}"
|
|
echo "---------------------------"
|
|
mdcat .autonote.md
|
|
echo "---------------------------"
|
|
echo
|
|
fi
|
|
}
|
|
# Hook to execute check_todo, check_autonote when changing directories
|
|
cd() {
|
|
builtin cd "$@"
|
|
check_todo
|
|
check_autonote
|
|
}
|
|
|
|
random-bg() {
|
|
local color='xxx'
|
|
|
|
while getopts ":mrgb" opt; do
|
|
case $opt in
|
|
m) muted=true ;;
|
|
r) color="ffxx" ;;
|
|
g) color="xffx" ;;
|
|
b) color="xxff" ;;
|
|
*) echo "Invalid option: -$OPTARG" >&2
|
|
return 1 ;;
|
|
esac
|
|
done
|
|
|
|
if [ "$muted" = true ]; then
|
|
# FIXME sometimes gives 7 digit value
|
|
# note value of 30 works
|
|
hue_range=360 # Restricted hue range (0-360 degrees)
|
|
hue=$((RANDOM % $hue_range))
|
|
saturation_range="50-80" # Adjust as needed
|
|
saturation=$((RANDOM % ($saturation_range + 1) + ${saturation_range%-*}))
|
|
lightness_range="60-80" # Adjust as needed
|
|
lightness=$((RANDOM % ($lightness_range + 1) + ${lightness_range%-*}))
|
|
color=$(printf "%02x%02x%02x" "$hue" "$saturation" "$lightness")
|
|
|
|
else
|
|
# FIXME: each x is replaced with same value, need a different value for each x
|
|
color=${color//x/$(openssl rand -hex 1)}
|
|
fi
|
|
|
|
echo "#$color"
|
|
xsetroot -solid "#$color"
|
|
}
|