Skip to content

Instantly share code, notes, and snippets.

@rizquuula
Created July 10, 2025 02:36
Show Gist options
  • Save rizquuula/9858cec94e160b374fa3045d165faf42 to your computer and use it in GitHub Desktop.
Save rizquuula/9858cec94e160b374fa3045d165faf42 to your computer and use it in GitHub Desktop.
bashrc theme, useful, beautiful
#!/bin/bash
# Enhanced Git branch and status information
parse_git_info() {
git rev-parse --is-inside-work-tree &>/dev/null || return
local branch dirty staged untracked ahead behind
local git_status=""
# Get branch name or commit hash
branch=$(git symbolic-ref --short HEAD 2>/dev/null || git describe --tags --exact-match 2>/dev/null || git rev-parse --short HEAD 2>/dev/null)
# Get detailed status
local status_output=$(git status --porcelain 2>/dev/null)
dirty=$(echo "$status_output" | grep -c "^ M\|^AM\|^MM\|^ T")
staged=$(echo "$status_output" | grep -c "^M\|^A\|^D\|^R\|^C")
untracked=$(echo "$status_output" | grep -c "^??")
# Get ahead/behind information
local upstream=$(git rev-parse --abbrev-ref @{upstream} 2>/dev/null)
if [[ -n "$upstream" ]]; then
local ahead_behind=$(git rev-list --left-right --count HEAD...@{upstream} 2>/dev/null)
ahead=$(echo "$ahead_behind" | cut -f1)
behind=$(echo "$ahead_behind" | cut -f2)
fi
# Build status string
git_status=" [$branch"
# Add status indicators
[[ $staged -gt 0 ]] && git_status+=" ●$staged"
[[ $dirty -gt 0 ]] && git_status+=" ✚$dirty"
[[ $untracked -gt 0 ]] && git_status+=" ?$untracked"
# Add ahead/behind indicators
[[ $ahead -gt 0 ]] && git_status+=" ↑$ahead"
[[ $behind -gt 0 ]] && git_status+=" ↓$behind"
# Add clean indicator if no changes
if [[ $staged -eq 0 && $dirty -eq 0 && $untracked -eq 0 ]]; then
git_status+=" ✓"
fi
git_status+="]"
echo "$git_status"
}
# Get current Python virtual environment
get_python_env() {
if [[ -n "$VIRTUAL_ENV" ]]; then
echo " ($(basename "$VIRTUAL_ENV"))"
elif [[ -n "$CONDA_DEFAULT_ENV" ]]; then
echo " (conda:$CONDA_DEFAULT_ENV)"
fi
}
# Get current Node.js version if in a Node project
get_node_info() {
if [[ -f "package.json" ]] && command -v node &>/dev/null; then
echo " ⬢$(node -v)"
fi
}
# Get current directory size for large directories
get_dir_info() {
local file_count=$(find . -maxdepth 1 -type f | wc -l 2>/dev/null)
local dir_count=$(find . -maxdepth 1 -type d | wc -l 2>/dev/null)
((dir_count--)) # Subtract current directory
if [[ $file_count -gt 50 || $dir_count -gt 20 ]]; then
echo " ($file_count files, $dir_count dirs)"
fi
}
# Get load average on systems that support it
get_load_average() {
if [[ -f /proc/loadavg ]]; then
local load=$(cut -d' ' -f1 /proc/loadavg)
local cores=$(nproc 2>/dev/null || echo 1)
local load_percent=$(echo "scale=0; $load * 100 / $cores" | bc -l 2>/dev/null)
if [[ $load_percent -gt 80 ]]; then
echo " ⚠️${load_percent}%"
elif [[ $load_percent -gt 50 ]]; then
echo " ⚡${load_percent}%"
fi
fi
}
# Enhanced precmd function
precmd() {
export LAST_EXIT="$?"
# Update terminal title with current directory
echo -ne "\033]0;$(basename "$(pwd)") - $(whoami)@$(hostname)\007"
# Log command history with timestamp (optional)
if [[ -n "$PROMPT_COMMAND_HISTORY" ]]; then
history -a
fi
}
# Set the prompt command
PROMPT_COMMAND=precmd
# Detect color support
if [[ -z "$color_prompt" ]]; then
if [[ -t 1 ]] && [[ $(tput colors 2>/dev/null) -ge 8 ]]; then
color_prompt=yes
else
color_prompt=no
fi
fi
# Color definitions for better organization
if [[ "$color_prompt" = yes ]]; then
# Color codes
RESET='\[\033[0m\]'
BOLD='\[\033[1m\]'
# Standard colors
BLACK='\[\033[0;30m\]'
RED='\[\033[0;31m\]'
GREEN='\[\033[0;32m\]'
YELLOW='\[\033[0;33m\]'
BLUE='\[\033[0;34m\]'
PURPLE='\[\033[0;35m\]'
CYAN='\[\033[0;36m\]'
WHITE='\[\033[0;37m\]'
# Bold colors
BOLD_BLACK='\[\033[1;30m\]'
BOLD_RED='\[\033[1;31m\]'
BOLD_GREEN='\[\033[1;32m\]'
BOLD_YELLOW='\[\033[1;33m\]'
BOLD_BLUE='\[\033[1;34m\]'
BOLD_PURPLE='\[\033[1;35m\]'
BOLD_CYAN='\[\033[1;36m\]'
BOLD_WHITE='\[\033[1;37m\]'
# Background colors
BG_RED='\[\033[0;41m\]'
BG_GREEN='\[\033[0;42m\]'
# Build the colored prompt
PS1='\n' # Start with newline for clean separation
# Top line: timestamp, user@host, system info
PS1+="${BOLD_WHITE}┌─[${BOLD_CYAN}\t${BOLD_WHITE}]" # timestamp
PS1+="─[${GREEN}\u${BOLD_WHITE}@${GREEN}\h${BOLD_WHITE}]" # user@host
PS1+="${PURPLE}\$(get_load_average)${BOLD_WHITE}" # load average
PS1+='\n'
# Middle line: directory, git info, environment info
PS1+="${BOLD_WHITE}├─[${BLUE}\w${BOLD_WHITE}]" # working directory
PS1+="${PURPLE}\$(parse_git_info)" # git information
PS1+="${YELLOW}\$(get_python_env)" # Python environment
PS1+="${CYAN}\$(get_node_info)" # Node.js info
PS1+="${WHITE}\$(get_dir_info)" # directory info
PS1+='\n'
# Bottom line: exit status and prompt
PS1+="${BOLD_WHITE}└─\$(if [ \"\$LAST_EXIT\" = 0 ]; then echo \"${BG_GREEN}${BOLD_WHITE} ✓ ${RESET}${BOLD_GREEN}\"; else echo \"${BG_RED}${BOLD_WHITE} ✘ \$LAST_EXIT ${RESET}${BOLD_RED}\"; fi)${RESET}${BOLD_WHITE}▶${RESET} "
else
# Non-color prompt (fallback)
PS1='\n'
PS1+='┌─[\t]─[\u@\h]$(get_load_average)\n'
PS1+='├─[\w]$(parse_git_info)$(get_python_env)$(get_node_info)$(get_dir_info)\n'
PS1+='└─$(if [ "$LAST_EXIT" = 0 ]; then echo "✓"; else echo "✘ $LAST_EXIT"; fi)▶ '
fi
# Optional: Enable command timing
if [[ -n "$PROMPT_ENABLE_TIMING" ]]; then
trap 'timer_start=${timer_start:-$SECONDS}' DEBUG
get_command_time() {
if [[ -n "$timer_start" ]]; then
local timer_end=$SECONDS
local elapsed=$((timer_end - timer_start))
unset timer_start
if [[ $elapsed -gt 10 ]]; then
echo " (${elapsed}s)"
fi
fi
}
# Add timing to prompt
if [[ "$color_prompt" = yes ]]; then
PS1="${PS1%▶*}${YELLOW}\$(get_command_time)${RESET}${BOLD_WHITE}▶${RESET} "
else
PS1="${PS1%▶*}\$(get_command_time)▶ "
fi
fi
# Export the prompt
export PS1
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment