Last active
February 2, 2022 21:20
-
-
Save clux/864a4168712b9c28515a27de77f7c503 to your computer and use it in GitHub Desktop.
git-prompt-powerline-style
This file contains 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 | |
export TERM=xterm-256color | |
show_cwd() { | |
local dir_limit="3" | |
local truncation="⋯" | |
local first_char | |
local part_count=0 | |
local formatted_cwd="" | |
local dir_sep=" " | |
local tilde="~" | |
local cwd="${PWD/#$HOME/$tilde}" | |
# get first char of the path, i.e. tilde or slash | |
first_char=${cwd::1} | |
# remove leading tilde | |
cwd="${cwd#\~}" | |
while [[ "$cwd" == */* && "$cwd" != "/" ]]; do | |
# pop off last part of cwd | |
local part="${cwd##*/}" | |
cwd="${cwd%/*}" | |
formatted_cwd="$dir_sep$part$formatted_cwd" | |
part_count=$((part_count+1)) | |
[[ $part_count -eq $dir_limit ]] && first_char="$truncation" && break | |
done | |
echo -e "$first_char$formatted_cwd" | |
} | |
show_git_differences() { | |
[[ $(git rev-parse --is-inside-work-tree 2>/dev/null) == true ]] || return 1 | |
local unmerged=0 modified=0 has_untracked=0 added=0 is_clean="" | |
# shellcheck disable=SC2046 | |
set -- $(git rev-list --left-right --count "@{upstream}...HEAD" 2>/dev/null) | |
local behind_count=$1 | |
local ahead_count=$2 | |
# Added (A), Copied (C), Deleted (D), Modified (M), Renamed (R), changed (T), Unmerged (U), Unknown (X), Broken (B) | |
while read -r line; do | |
case "$line" in | |
M*) modified=$(( modified + 1 )) ;; | |
U*) unmerged=$(( unmerged + 1 )) ;; | |
esac | |
done < <(git diff --name-status) | |
while read -r line; do | |
case "$line" in | |
*) added=$(( added + 1 )) ;; | |
esac | |
done < <(git diff --name-status --cached) | |
if [ -n "$(git ls-files --others --exclude-standard)" ]; then | |
has_untracked=1 | |
fi | |
local -r stashed=$(( $(git rev-parse --verify refs/stash 2> /dev/null | wc -l) )); | |
if [ $(( unmerged + modified + has_untracked + added )) -eq 0 ]; then | |
is_clean=1 | |
fi | |
local s="" | |
# We always print at least one of these due to definition of is_clean | |
# Thus `s` always begins with a leading space | |
[[ $ahead_count -gt 0 ]] && s+=" ↑$ahead_count" | |
[[ $behind_count -gt 0 ]] && s+=" ↓$behind_count" | |
[[ $modified -gt 0 ]] && s+=" +$modified" | |
[[ $unmerged -gt 0 ]] && s+=" ✗$unmerged" | |
[[ $added -gt 0 ]] && s+=" ●" #$added | |
[[ $has_untracked -gt 0 ]] && s+=" …" | |
[[ $stashed -gt 0 ]] && s+=" ⚑" #$stashed | |
[[ $is_clean -gt 0 ]] && s+=" ✔" | |
# remove leading space | |
echo -e "$s" | sed 's/\s//' | |
} | |
prompt_git() { | |
local branchName='' | |
local s='' | |
# Check if the current directory is in a Git repository. | |
if git rev-parse --is-inside-work-tree &>/dev/null; then | |
s=$(show_git_differences) | |
# Get the short symbolic ref. | |
# If HEAD isn’t a symbolic ref, get the short SHA for the latest commit | |
# Otherwise, just give up. | |
branchName="$(git symbolic-ref --quiet --short HEAD 2> /dev/null || \ | |
git rev-parse --short HEAD 2> /dev/null || \ | |
echo '(unknown)')" | |
echo -e " ${vcstxt}${branchName} ${s}" | |
fi | |
} | |
prompt_lal() { | |
local branchName='' | |
local res | |
if res=$(lal env 2> /dev/null); then | |
echo -e " (${yellow}${res}${maintxt})" | |
fi | |
} | |
set_prompt() { | |
local -r rc=$? # Must save this | |
tput sgr0 # reset colors | |
# Solarized colors, taken from http://git.io/solarized-colors. | |
#local -r bold="\[$(tput bold)\]" | |
local -r reset="\[$(tput sgr0)\]" | |
#local -r black="\[$(tput setaf 0)\]" | |
#local -r blue="\[$(tput setaf 33)\]" | |
local -r cyan="\[$(tput setaf 38)\]" | |
#local -r green="\[$(tput setaf 64)\]" | |
#local -r orange="\[$(tput setaf 166)\]" | |
local -r purple="\[$(tput setaf 125)\]" | |
local -r red="\[$(tput setaf 124)\]" | |
#local -r violet="\[$(tput setaf 61)\]" | |
local -r white="\[$(tput setaf 15)\]" | |
local -r yellow="\[$(tput setaf 136)\]" | |
# Short indication for when your inline shell script is incomplete | |
PS2="${yellow}⚡${reset} " | |
# color info | |
# - bg color is the background color for each of the up to three chunks | |
# - txt colors are the colors used inside the chunks | |
# - fg color is only used to replace background colors between chunks | |
# - separator takes last bg color as new fg color for one character only | |
# - reset only used at the end for partially transparent end separator | |
# First (optional) chunk with return code (if != 0) | |
local -r has_warn=$(( rc )) | |
local -r warnbg="\[$(tput setab 9)\]" # red-ish | |
local -r warnfg="\[$(tput setaf 9)\]" | |
local -r warntxt="${white}" | |
# Second (optional) chunk with hostname (when connected via ssh) | |
local -r has_host="${SSH_TTY}" | |
local -r hostbg="\[$(tput setab 235)\]" # light-grey | |
local -r hostfg="\[$(tput setaf 235)\]" | |
local -r hosttxt="${white}" | |
# Third (main mandatory) chunk with cwd and (optionally) git status | |
local -r mainbg="\[$(tput setab 232)\]" # dark-grey | |
local -r mainfg="\[$(tput setaf 232)\]" | |
local -r maintxt="${white}" | |
local -r vcstxt="${cyan}" | |
# Return code when non-zero | |
PS1="${mainbg}" # initialize bg for warn and no host blocks | |
if [[ $has_warn -gt 0 ]]; then | |
PS1+="${warnbg}${warntxt} ${rc} ${warnfg}" | |
if [[ -n $has_host ]]; then # shade for hostname block if on ssh | |
PS1+="${hostbg}" | |
else | |
PS1+="${mainbg}" | |
fi | |
fi | |
# Show the hostname when connected via SSH | |
if [[ -n $has_host ]]; then | |
PS1+="${hostbg}${hosttxt} ${HOSTNAME} ${hostfg}" | |
PS1+="${mainbg}" | |
fi | |
# Show CWD | |
PS1+="${maintxt} " | |
# Prepend (root) if root | |
if [ $EUID -eq 0 ]; then | |
"(${red}root${maintxt}) " | |
fi | |
PS1+="$(show_cwd)" | |
if [ -n "${VIRTUAL_ENV}" ]; then | |
# Append (pyv) if in venv | |
PS1+=" (${purple}pyv${maintxt})" | |
elif [ -d .lal ]; then | |
# Append lal environment if inside a lal repo | |
PS1+="$(prompt_lal)" | |
fi | |
# Show git status | |
PS1+="${mainbg}" | |
PS1+="$(prompt_git) " # git repository (fast and detailed) | |
# Make last separator half-transparent | |
PS1+="${reset}${mainfg}${reset} " | |
} | |
PROMPT_COMMAND='set_prompt' |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Added lal integration to it today.