Created
July 30, 2025 14:17
-
-
Save davivc/8570198e1aae1844ef6d531e9a1fcf3e to your computer and use it in GitHub Desktop.
Improved colored git terminal
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
# Complex Git prompt with Powerline fonts, enhanced colors, status indicators, and virtual environment support | |
force_color_prompt=yes | |
color_prompt=yes | |
# Powerline symbols (install fonts-powerline package first) | |
# Replace the powerline symbols section with these unicode alternatives: | |
POWERLINE_BRANCH="πΏ" # or use "git:" | |
POWERLINE_SEPARATOR="βΆ" # or use ">" | |
POWERLINE_RIGHT_SEPARATOR="β" | |
POWERLINE_LOCK="π" | |
POWERLINE_AHEAD="β¬" | |
POWERLINE_BEHIND="β¬" | |
POWERLINE_DIVERGED="β‘" | |
# Enhanced git branch function with detailed status indicators | |
parse_git_branch() { | |
local branch | |
local status | |
local color | |
local symbols="" | |
# Get branch name | |
branch=$(git branch 2> /dev/null | sed -e '/^[^*]/d' -e 's/* \(.*\)/\1/') | |
if [ -n "$branch" ]; then | |
# Get git status | |
status=$(git status --porcelain 2> /dev/null) | |
# Check for different types of changes and add symbols | |
if [ -n "$status" ]; then | |
echo "$status" | grep -q "^M" && symbols="${symbols}β" # Modified files | |
echo "$status" | grep -q "^A" && symbols="${symbols}+" # Added files | |
echo "$status" | grep -q "^D" && symbols="${symbols}β" # Deleted files | |
echo "$status" | grep -q "^R" && symbols="${symbols}β" # Renamed files | |
echo "$status" | grep -q "^??" && symbols="${symbols}?" # Untracked files | |
echo "$status" | grep -q "^UU" && symbols="${symbols}!" # Merge conflicts | |
# Determine color based on staging status | |
if git diff --cached --quiet 2> /dev/null; then | |
# Only unstaged changes - bright yellow | |
color="1;33" | |
else | |
# Has staged changes - bright green | |
color="1;32" | |
fi | |
else | |
# Clean working directory - bright cyan | |
color="1;36" | |
fi | |
# Check if we're ahead/behind remote | |
local remote_status="" | |
if git rev-parse --abbrev-ref @{upstream} >/dev/null 2>&1; then | |
local ahead=$(git rev-list --count @{upstream}..HEAD 2>/dev/null) | |
local behind=$(git rev-list --count HEAD..@{upstream} 2>/dev/null) | |
if [ "$ahead" -gt 0 ] && [ "$behind" -gt 0 ]; then | |
remote_status="${POWERLINE_DIVERGED}${ahead}/${behind}" | |
elif [ "$ahead" -gt 0 ]; then | |
remote_status="${POWERLINE_AHEAD}${ahead}" | |
elif [ "$behind" -gt 0 ]; then | |
remote_status="${POWERLINE_BEHIND}${behind}" | |
fi | |
fi | |
# Combine all status info | |
local full_status="" | |
if [ -n "$symbols" ]; then | |
full_status+=" ${symbols}" | |
fi | |
if [ -n "$remote_status" ]; then | |
full_status+=" ${remote_status}" | |
fi | |
if [ -n "$full_status" ]; then | |
echo -e "\033[${color}m${POWERLINE_BRANCH} ${branch}${full_status}\033[0m" | |
else | |
echo -e "\033[${color}m${POWERLINE_BRANCH} ${branch}\033[0m" | |
fi | |
fi | |
} | |
# Alternative simpler git function (you can switch between them) | |
parse_git_branch_simple() { | |
local branch=$(git branch 2> /dev/null | sed -e '/^[^*]/d' -e 's/* \(.*\)/\1/') | |
if [ -n "$branch" ]; then | |
if git diff-index --quiet HEAD -- 2>/dev/null; then | |
# Clean - bright cyan | |
echo -e "\033[1;36m${POWERLINE_BRANCH}${branch}\033[0m" | |
else | |
# Dirty - bright yellow | |
echo -e "\033[1;33m${POWERLINE_BRANCH}${branch}\033[0m" | |
fi | |
fi | |
} | |
# Enhanced virtual environment display | |
parse_venv() { | |
local venv_display="" | |
if [ -n "$VIRTUAL_ENV" ]; then | |
local venv_name=$(basename "$VIRTUAL_ENV") | |
local venv_path=$(dirname "$VIRTUAL_ENV") | |
# Different colors and formats for different venv types | |
if [[ "$venv_name" == ".venv" ]]; then | |
# Standard .venv - bright magenta with project name | |
local project_name=$(basename "$venv_path") | |
venv_display="\033[1;35m(.venv:${project_name})\033[0m" | |
elif [[ "$venv_name" == "venv" ]]; then | |
# Standard venv - bright magenta | |
venv_display="\033[1;35m(venv)\033[0m" | |
elif [[ "$VIRTUAL_ENV" == *"conda"* ]] || [[ -n "$CONDA_DEFAULT_ENV" ]]; then | |
# Conda environment - bright green | |
local conda_env="${CONDA_DEFAULT_ENV:-$venv_name}" | |
venv_display="\033[1;32m(π conda:${conda_env})\033[0m" | |
else | |
# Named venv - bright blue | |
venv_display="\033[1;34m(π ${venv_name})\033[0m" | |
fi | |
elif [ -n "$CONDA_DEFAULT_ENV" ] && [ "$CONDA_DEFAULT_ENV" != "base" ]; then | |
# Conda environment without VIRTUAL_ENV | |
venv_display="\033[1;32m(π conda:${CONDA_DEFAULT_ENV})\033[0m" | |
fi | |
if [ -n "$venv_display" ]; then | |
echo -e "$venv_display" | |
fi | |
} | |
# Python version display (shows current Python version) | |
parse_python() { | |
if command -v python &> /dev/null; then | |
local py_version=$(python --version 2>/dev/null | cut -d' ' -f2 | cut -d'.' -f1,2) | |
if [ -n "$py_version" ]; then | |
echo -e "\033[0;90m[py:${py_version}]\033[0m" | |
fi | |
fi | |
} | |
# Node.js version display (since you have nvm) | |
parse_node() { | |
if command -v node &> /dev/null; then | |
local node_version=$(node --version 2>/dev/null | sed 's/v//' | cut -d'.' -f1,2) | |
if [ -n "$node_version" ] && [ "$node_version" != "system" ]; then | |
echo -e "\033[0;90m[node:${node_version}]\033[0m" | |
fi | |
fi | |
} | |
# Git stash indicator | |
parse_git_stash() { | |
if git rev-parse --is-inside-work-tree >/dev/null 2>&1; then | |
local stash_count=$(git stash list 2>/dev/null | wc -l) | |
if [ "$stash_count" -gt 0 ]; then | |
echo -e "\033[0;90m[stash:${stash_count}]\033[0m" | |
fi | |
fi | |
} | |
# Choose which git function to use (complex or simple) | |
GIT_FUNCTION="parse_git_branch" # Change to "parse_git_branch_simple" for simpler version | |
# Disable default venv prompt (we handle it ourselves) | |
export VIRTUAL_ENV_DISABLE_PROMPT=1 | |
# Optional components (comment out what you don't want) | |
SHOW_PYTHON_VERSION=true | |
SHOW_NODE_VERSION=true # Set to true if you want Node version | |
SHOW_GIT_STASH=true | |
if [ "$color_prompt" = yes ]; then | |
# Build the prompt dynamically | |
prompt_parts=() | |
# Virtual environment | |
prompt_parts+=('$(parse_venv)') | |
# User@host:path | |
prompt_parts+=('\[\e[1;32m\]\u@\h\[\e[0m\]βΆ\[\e[1;34m\]\w\[\e[0m\]') | |
# Git branch with status | |
prompt_parts+=('$('"$GIT_FUNCTION"')') | |
# Optional components | |
[ "$SHOW_PYTHON_VERSION" = true ] && prompt_parts+=('$(parse_python)') | |
[ "$SHOW_NODE_VERSION" = true ] && prompt_parts+=('$(parse_node)') | |
[ "$SHOW_GIT_STASH" = true ] && prompt_parts+=('$(parse_git_stash)') | |
# Final prompt symbol | |
prompt_parts+=('\[\e[1;37m\]β―\[\e[0m\] ') | |
# Join all parts with spaces | |
#PS1=$(IFS=' '; echo "${prompt_parts[*]}") | |
PS1="" | |
for part in "${prompt_parts[@]}"; do | |
PS1+="${part}" | |
done | |
else | |
PS1='$(parse_venv)\u@\h:\w$('"$GIT_FUNCTION"')\$ ' | |
fi | |
unset color_prompt force_color_prompt |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment