Skip to content

Instantly share code, notes, and snippets.

@andyearnshaw
Created May 3, 2013 08:39
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save andyearnshaw/5507968 to your computer and use it in GitHub Desktop.
Save andyearnshaw/5507968 to your computer and use it in GitHub Desktop.
Powerline-style PS1 written in pure Bash. Requires the Powerline-patched fonts. Why not just use Powerline, you ask? Well, I was using it on my NAS and it takes around 1500ms for the prompt to appear when the system is idle, but when doing something like compiling, it can take 5-15 seconds.
#!/bin/bash
soft_sep='';
hard_sep='';
reset='\[\033[0m\]';
txt='\[\033[38;5;252m\]';
txt_prf='\[\033[38;5;252m\]';
user_bg='\[\033[48;5;31m\]';
root_bg='\[\033[48;5;31m\]';
host_colour='\[\033[48;5;166m\033[38;5;221m\]';
host_sepc='\[\033[38;5;166m\]';
user_colour='\[\033[1;48;5;31m\]'$txt;
user_sepc='\[\033[48;5;240m\033[38;5;31m\]';
root_colour='\[\033[1;48;5;52m\]'$txt;
root_sepc='\[\033[48;5;240m\033[38;5;52m\]';
bold='\[\033[1m\]';
git_clean_colour='\[\033[48;5;23m\]';
git_clean_sepc='\[\033[38;5;23m\]';
git_needs_commit_colour='\[\033[48;5;52m\]';
git_needs_commit_sepc='\[\033[38;5;52m\]';
path_colour='\[\033[0m\]'$user_sepc$txt;
cdir_sep=$reset'\[\033[38;5;240m\]';
pwd_sepc='\[\033[38;5;240m\]';
if [ $(id -u) == 0 ]; then
user_bg=$root_bg;
user_colour=$root_colour;
user_sepc=$root_sepc;
fi
function __generate_ps1 {
local prompt='';
if [ "$SSH_CONNECTION" ]; then
prompt+=$host_colour'  \h '$host_sepc$user_bg$hard_sep;
fi
prompt+=$user_colour' \u '"$user_sepc$hard_sep $path_colour";
local git=$(git rev-parse --show-toplevel 2> /dev/null);
local parts;
local pwd=$(pwd);
local path=${pwd/$HOME/\~};
local git_colour=$git_clean_colour;
local git_sepc=$git_clean_sepc;
if [ $path == "/" ] || [ $path == "~" ]; then
prompt+="$bold$path $reset$pwd_sepc$hard_sep$reset";
export PS1=$prompt' ';
return 0;
fi
if [[ "$git" ]]; then
echo `git status` | grep "nothing to commit" > /dev/null 2>&1;
if [[ "$?" != "0" ]]; then
git_colour=$git_needs_commit_colour;
git_sepc=$git_needs_commit_sepc;
fi
if [[ $git == '.' ]]; then
path='';
IFS='/' read -a parts <<< "${pwd/$HOME/\~}";
else
path=${pwd/$git};
IFS='/' read -a parts <<< "${git/$HOME/\~}";
fi
local prnt=${parts[${#parts[@]}-2]};
if [[ "$prnt" == "~" ]]; then
prompt+="~ $soft_sep ";
elif [[ "$prnt" ]]; then
prompt+="… $soft_sep ";
fi
local branch=$(git rev-parse --abbrev-ref HEAD 2> /dev/null);
prompt+="${parts[${#parts[@]}-1]} $git_colour$pwd_sepc$hard_sep$txt";
prompt+="  $bold${branch/HEAD/master} $reset$git_colour";
fi
IFS='/' read -a parts <<< "$path";
if [[ "$path" != '' ]]; then
if [[ "$git" == '' ]]; then
if [[ "${parts[2]}" ]] && [[ "${parts[3]}" ]]; then
prompt+="… $soft_sep ";
elif [[ "${parts[2]}" ]] && ( [[ "$path" == /* ]] || [[ "$path" == ~* ]] ); then
prompt+="${path:0:1} $soft_sep ";
elif [[ "$path" == /* ]]; then
prompt+="/ $soft_sep ";
fi
else
prompt+="$soft_sep ";
fi
[[ ${parts[${#parts[@]}-2]} ]] && prompt+="${parts[${#parts[@]}-2]} $soft_sep ";
prompt+=$bold${parts[${#parts[@]}-1]}' ';
fi
if [[ $git ]]; then
prompt+=$reset$git_sepc$hard_sep$reset;
else
prompt+=$reset$pwd_sepc$hard_sep$reset;
fi
prompt+=$reset' ';
export PS1=$prompt;
}
export -f __generate_ps1
export PROMPT_COMMAND='__generate_ps1';
@andyearnshaw
Copy link
Author

I'm not really a bash scriptwriter (if you couldn't tell), so there might be some ways of refactoring the code to be a little better. If so, let me know, I'm happy to learn.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment