Created
July 10, 2025 02:36
-
-
Save rizquuula/9858cec94e160b374fa3045d165faf42 to your computer and use it in GitHub Desktop.
bashrc theme, useful, beautiful
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/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