# shellcheck shell=bash # If not running interactively, don't do anything. [[ $- != *i* ]] && return # Color definitions _WHITE='\033[1;37m' # White _NC='\033[0m' # No color _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:+${SHELL_CONFIG}:}.bashrc" # # ~/.bashrc # function show_date() { local dotfile selected_adjective adjective classification local day_of_week day_of_month month_name year day_suffix text_color full_date local -a adjectives # 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 "" } # ============================================================================ # SHELL CONFIGURATION # ============================================================================ export HISTCONTROL=ignoreboth:erasedups export HISTFILE="$HOME/.histfile" export HISTSIZE=10000 export HISTFILESIZE=10000 shopt -s histappend checkwinsize # Disable terminal flow-control keys only when stdin is a terminal. [[ -t 0 ]] && stty -ixon # Optimized divider function - simple timestamp without coloring function draw_prompt_divider() { local timestamp prefix_length line_length i printf -v timestamp '%(%H:%M:%S)T' -1 # Faster than $(date) local prefix="$timestamp ├" prefix_length=${#prefix} line_length=$(( ${COLUMNS:-80} - prefix_length )) # Print timestamp, junction, then fill with box-drawing characters printf '%s' "$prefix" for ((i=0; i&2 return 127 } _error_block='██████' # Set PS1 with user@host, directory, git status, and prompt ($ color works!) PS1='\[\033[01;32m\]\u@\h\[\033[00m\] \[\033[1;34m\]\w\[\033[00m\]\n${GITSTATUS_PROMPT:+$GIT_ALIGNMENT_PADDING$GITSTATUS_PROMPT\n}$([ "$?" -eq 0 ] && echo "" || echo "\[\033[01;31m\]$_error_block\[\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 [ -r "$HOME/.config/profile/aliases.sh" ] && . "$HOME/.config/profile/aliases.sh" export NVM_DIR="$HOME/.nvm" if [[ -s "$NVM_DIR/nvm.sh" ]]; then \. "$NVM_DIR/nvm.sh" nvm use default >/dev/null [[ -s "$NVM_DIR/bash_completion" ]] && \. "$NVM_DIR/bash_completion" fi # 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) _package_status_cache="${XDG_CACHE_HOME:-$HOME/.cache}/package-status/status" _package_status_attempt="${XDG_CACHE_HOME:-$HOME/.cache}/package-status/last-attempt" _package_status_max_age=3600 _package_status_retry_delay=300 _package_status_version="" _package_status_checked_at="" _package_status_pacman_log_signature="" _updates_available="0" _orphans_available="0" if [ -r "$_package_status_cache" ]; then while IFS='=' read -r _package_status_key _package_status_value; do case "$_package_status_key" in version) _package_status_version="$_package_status_value" ;; updates) _updates_available="$_package_status_value" ;; orphans) _orphans_available="$_package_status_value" ;; checked_at) _package_status_checked_at="$_package_status_value" ;; pacman_log_signature) _package_status_pacman_log_signature="$_package_status_value" ;; esac done < "$_package_status_cache" fi _package_status_now=$(date +%s) _package_status_current_pacman_log_signature=$(stat -c '%Y:%s:%i' /var/log/pacman.log 2>/dev/null || echo '0:0:0') if ! [[ "$_package_status_version" == "1" \ && "$_updates_available" =~ ^[0-9]+$ \ && "$_orphans_available" =~ ^[0-9]+$ \ && "$_package_status_checked_at" =~ ^[0-9]+$ \ && "$_package_status_pacman_log_signature" =~ ^[0-9]+:[0-9]+:[0-9]+$ \ && $_package_status_now -ge $_package_status_checked_at \ && $((_package_status_now - _package_status_checked_at)) -le $_package_status_max_age \ && "$_package_status_pacman_log_signature" == "$_package_status_current_pacman_log_signature" ]]; then _updates_available="0" _orphans_available="0" _package_status_attempt_time=$(stat -c %Y "$_package_status_attempt" 2>/dev/null || echo 0) if ! [[ "$_package_status_attempt_time" =~ ^[0-9]+$ \ && $_package_status_now -ge $_package_status_attempt_time \ && $((_package_status_now - _package_status_attempt_time)) -lt $_package_status_retry_delay ]]; then systemctl --user start --no-block package-status-refresh.service >/dev/null 2>&1 || true fi fi unset _package_status_cache _package_status_attempt _package_status_max_age unset _package_status_retry_delay _package_status_attempt_time _package_status_version unset _package_status_checked_at _package_status_pacman_log_signature unset _package_status_now _package_status_current_pacman_log_signature unset _package_status_key _package_status_value echo "Remember commands:" printf '%b' "$_WHITE" _command_reminder printf '%b\n' "$_NC" 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 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}\" (${_BLUE}et${_NC}) and \"${_BLUE}autonote.md${_NC}\" (${_BLUE}ea${_NC}) files have content automatically displayed." echo "" [ -r "$HOME/.config/bash/cheat.bash" ] && . "$HOME/.config/bash/cheat.bash" #openai codex completion if command -v codex >/dev/null 2>&1; then eval "$(codex completion bash)" fi # 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 "---------------------------" if command -v mdcat >/dev/null 2>&1; then mdcat TODO.md; else cat TODO.md; fi 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 "---------------------------" if command -v mdcat >/dev/null 2>&1; then mdcat .autonote.md; else cat .autonote.md; fi echo "---------------------------" echo fi } # Hook to execute check_todo, check_autonote when changing directories cd() { builtin cd "$@" || return check_todo check_autonote return 0 } # opencode case ":$PATH:" in *":$HOME/.opencode/bin:"*) ;; *) export PATH="$HOME/.opencode/bin:$PATH" ;; esac #pyenv export PYENV_ROOT="$HOME/.pyenv" case ":$PATH:" in *":$PYENV_ROOT/bin:"*) ;; *) export PATH="$PYENV_ROOT/bin:$PATH" ;; esac if [[ -z ${PYENV_SHELL:-} ]] && command -v pyenv >/dev/null 2>&1; then eval "$(pyenv init -)" fi