Skip to content
Snippets Groups Projects
Commit 2508d631 authored by Bob Mottram's avatar Bob Mottram
Browse files

Add powerline

parent d55f12d7
No related branches found
No related tags found
No related merge requests found
#!/usr/bin/env bash
# Based on https://github.com/undu/bash-powerline
__powerline() {
# User config variables,
# it's recommended to override those variables through .bashrc or similar
#
# Use powerline mode
# readonly POWERLINE_FONT=''
#
# Always show user in the prompt
# readonly SHOW_USER=''
#
# Never show a default user
# readonly DEFAULT_USER='user'
# Default background and foreground ANSI colours
readonly DEFAULT_BG=0
readonly DEFAULT_FG=7
# Max length of full path
readonly MAX_PATH_LENGTH=30
# Unicode symbols
if [ -z "${POWERLINE_FONT+x}" ]; then
readonly GIT_BRANCH_SYMBOL='⑂'
else
readonly GIT_BRANCH_SYMBOL=''
fi
readonly GIT_BRANCH_CHANGED_SYMBOL='Δ'
readonly GIT_NEED_PUSH_SYMBOL='↑'
readonly GIT_NEED_PULL_SYMBOL='↓'
# Powerline symbols
readonly BLOCK_START=''
# ANSI Colours
readonly BLACK=0
readonly RED=1
readonly GREEN=2
readonly YELLOW=3
readonly BLUE=4
readonly MAGENTA=5
readonly CYAN=6
readonly WHITE=7
readonly BLACK_BRIGHT=8
readonly RED_BRIGHT=9
readonly GREEN_BRIGHT=10
readonly YELLOW_BRIGHT=11
readonly BLUE_BRIGHT=12
readonly MAGENTA_BRIGHT=13
readonly CYAN_BRIGHT=14
readonly WHITE_BRIGHT=15
# Font effects
readonly DIM="\[$(tput dim)\]"
readonly REVERSE="\[$(tput rev)\]"
readonly RESET="\[$(tput sgr0)\]"
readonly BOLD="\[$(tput bold)\]"
# Generate terminal colour codes
# $1 is an int (a colour) and $2 must be 'fg' or 'bg'
__colour() {
case "$2" in
'fg'*)
echo "\[$(tput setaf "$1")\]"
;;
'bg'*)
echo "\[$(tput setab "$1")\]"
;;
*)
echo "\[$(tput setab "$1")\]"
;;
esac
}
# Generate a single-coloured block for the prompt
__prompt_block() {
local bg; local fg
if [ ! -z "${1+x}" ]; then
bg=$1
else
if [ ! -z "$last_bg" ]; then
bg=$last_bg
else
bg=$DEFAULT_BG
fi
fi
if [ ! -z "${2+x}" ]; then
fg=$2
else
fg=$DEFAULT_FG
fi
local block
# Need to generate a separator if the background changes
if [[ ! -z "$last_bg" && "$bg" != "$last_bg" && ! -z "${POWERLINE_FONT+x}" ]]; then
block+="$(__colour "$bg" 'bg')"
block+="$(__colour "$last_bg" 'fg')"
block+="$BLOCK_START $RESET"
block+="$(__colour "$bg" 'bg')"
block+="$(__colour "$fg" 'fg')"
else
block+="$(__colour "$bg" 'bg')"
block+="$(__colour "$fg" 'fg')"
block+=" "
fi
if [ ! -z "${3+x}" ]; then
block+="$3 $RESET"
fi
last_bg=$bg
__block_text="$block"
}
function __end_block() {
__block_text=''
if [ ! -z "$last_bg" ]; then
if [ ! -z "${POWERLINE_FONT+x}" ]; then
__block_text+="$(__colour $DEFAULT_BG 'bg')"
__block_text+="$(__colour "$last_bg" 'fg')"
__block_text+="$BLOCK_START$RESET"
__block_text+="$(__colour $DEFAULT_BG 'bg')"
__block_text+="$(__colour "$DEFAULT_FG" 'fg')"
else
__block_text+="$(__colour $DEFAULT_BG 'bg')"
__block_text+="$(__colour "$DEFAULT_FG" 'fg')"
fi
fi
__block_text+=' '
}
### Prompt components
__git_block() {
if ! command -V git > /dev/null; then
# git not found
__block_text=''
return
fi
# force git output in English to make our work easier
local git_eng="env LANG=C git"
# check if pwd is under git
if ! git rev-parse --is-inside-git-dir > /dev/null 2> /dev/null; then
# not in a git repo, bail out
__block_text=''
return
fi
# get current branch name or short SHA1 hash for detached head
local branch; local ref_symbol
branch="$($git_eng symbolic-ref --short HEAD 2>/dev/null)"
# shellcheck disable=SC2181
if [ $? != 0 ]; then
branch="$($git_eng describe --tags --always 2>/dev/null)"
ref_symbol='➦'
else
ref_symbol=$GIT_BRANCH_SYMBOL
fi
# In pcmode (and only pcmode) the contents of
# $gitstring are subject to expansion by the shell.
# Avoid putting the raw ref name in the prompt to
# protect the user from arbitrary code execution via
# specially crafted ref names (e.g., a ref named
# '$(IFS=_;cmd=sudo_rm_-rf_/;$cmd)' would execute
# 'sudo rm -rf /' when the prompt is drawn). Instead,
# put the ref name in a new global variable (in the
# __git_ps1_* namespace to avoid colliding with the
# user's environment) and reference that variable from
# PS1.
# note that the $ is escaped -- the variable will be
# expanded later (when it's time to draw the prompt)
if shopt -q promptvars; then
export __git_ps1_block="$branch"
ref="$ref_symbol \${__git_ps1_block}"
else
ref="$ref_symbol $branch"
fi
local marks
# check if HEAD is dirty
if [ -n "$($git_eng status --porcelain 2>/dev/null)" ]; then
dirty='y'
marks+=" $GIT_BRANCH_CHANGED_SYMBOL"
fi
# how many commits local branch is ahead/behind of remote?
local stat; local aheadN; local behindN
stat="$($git_eng status --porcelain --branch 2>/dev/null | grep '^##' | grep -o '\[.\+\]$')"
aheadN="$(echo "$stat" | grep -o 'ahead [[:digit:]]\+' | grep -o '[[:digit:]]\+')"
behindN="$(echo "$stat" | grep -o 'behind [[:digit:]]\+' | grep -o '[[:digit:]]\+')"
[ -n "$aheadN" ] && marks+=" $GIT_NEED_PUSH_SYMBOL$aheadN"
[ -n "$behindN" ] && marks+=" $GIT_NEED_PULL_SYMBOL$behindN"
local bg; local fg
fg=$BLACK
if [ -z "$dirty" ]; then
bg=$GREEN
else
bg=$YELLOW
fi
__prompt_block $bg $fg "$ref$marks"
}
__virtualenv_block() {
# Copied from Python virtualenv's activate.sh script.
# https://github.com/pypa/virtualenv/blob/a9b4e673559a5beb24bac1a8fb81446dd84ec6ed/virtualenv_embedded/activate.sh#L62
# License: MIT
if [ -n "$VIRTUAL_ENV" ]; then
local venv
# In pcmode (and only pcmode) the contents of
# $gitstring are subject to expansion by the shell.
# Avoid putting the raw ref name in the prompt to
# protect the user from arbitrary code execution via
# specially crafted ref names (e.g., a ref named
# '$(IFS=_;cmd=sudo_rm_-rf_/;$cmd)' would execute
# 'sudo rm -rf /' when the prompt is drawn). Instead,
# put the ref name in a new global variable (in the
# __git_ps1_* namespace to avoid colliding with the
# user's environment) and reference that variable from
# PS1.
# note that the $ is escaped -- the variable will be
# expanded later (when it's time to draw the prompt)
if shopt -q promptvars; then
export __venv_ps1_block
__venv_ps1_block=$(basename "$VIRTUAL_ENV")
venv="$ref_symbol \${__venv_ps1_block}"
else
venv="$(basename "$VIRTUAL_ENV")"
fi
__prompt_block $WHITE $BLACK "$venv"
else
__block_text=''
fi
}
__pwd_block() {
# Use ~ to represent $HOME prefix
local pwd; pwd=$(pwd | sed -e "s|^$HOME|~|")
# shellcheck disable=SC1001,SC2088
if [[ ( $pwd = ~\/*\/* || $pwd = \/*\/*/* ) && ${#pwd} -gt $MAX_PATH_LENGTH ]]; then
local IFS='/'
read -ra split <<< "$pwd"
if [[ $pwd = ~* ]]; then
pwd="~/${split[1]}/.../${split[*]:(-2):1}/${split[*]:(-1)}"
else
pwd="/${split[1]}/.../${split[*]:(-2):1}/${split[*]:(-1)}"
fi
fi
__prompt_block $BLACK_BRIGHT $WHITE_BRIGHT "$pwd"
}
# superuser or not, here I go!
__user_block() {
# Colours to use
local fg=$WHITE_BRIGHT
local bg=$BLUE
if [[ ! -z "$SSH_CLIENT" ]]; then
local show_host="y"
bg=$CYAN
fi
if [ -z "$(id -u "$USER")" ]; then
bg=$RED
fi
# shellcheck disable=SC2153
if [[ ! -z "${SHOW_USER+x}" || ( ! -z "${DEFAULT_USER+x}" && "$DEFAULT_USER" != "$(whoami)" ) ]]; then
local show_user="y"
fi
local text
if [ ! -z ${show_user+x} ]; then
text+="$BOLD$(whoami)"
fi
if [ ! -z ${show_host+x} ]; then
if [ ! -z "${text+x}" ]; then
text+="@"
fi
text+="\h"
fi
if [ ! -z ${text+x} ]; then
__prompt_block $bg $fg $text
fi
}
__status_block() {
local text
if [ "$exit_code" != 0 ]; then
__prompt_block $BLACK $RED '✘'
text+=$__block_text
fi
if [ "$(id -u "$USER")" == 0 ]; then
__prompt_block $BLACK $YELLOW '⚡'
text+=$__block_text
fi
if [ "$(jobs -l | wc -l)" != 0 ]; then
__prompt_block $BLACK $CYAN '⚙'
text+=$__block_text
fi
if [ ! -z "$text" ]; then
__block_text=$text
else
__block_text=''
fi
}
# Build the prompt
prompt() {
# I don't like bash; execute first to capture correct status code
local exit_code=$?
# shellcheck disable=SC2091
$(history -a ; history -n)
last_bg=''
PS1=''
__status_block
PS1+=$__block_text
__virtualenv_block
PS1+=$__block_text
__user_block
PS1+=$__block_text
__pwd_block
PS1+=$__block_text
__git_block
PS1+=$__block_text
__end_block
PS1+=$__block_text
}
PROMPT_COMMAND=prompt
}
__powerline
unset __powerline
......@@ -627,6 +627,28 @@ function setup_firewall {
firewall_block_bad_ip_ranges
}
function setup_powerline {
if [ -d ~/${PROJECT_NAME}/src/${PROJECT_NAME}-powerline ]; then
cp ~/${PROJECT_NAME}/src/${PROJECT_NAME}-powerline ~/.powerline.bash
cp ~/${PROJECT_NAME}/src/${PROJECT_NAME}-powerline /etc/skel/.powerline.bash
else
if [ -d /home/${MY_USERNAME}/${PROJECT_NAME}/src/${PROJECT_NAME}-powerline ]; then
cp /home/${MY_USERNAME}/${PROJECT_NAME}/src/${PROJECT_NAME}-powerline ~/.powerline.bash
cp /home/${MY_USERNAME}/${PROJECT_NAME}/src/${PROJECT_NAME}-powerline /etc/skel/.powerline.bash
fi
fi
if ! grep -q "powerline" ~/.bashrc; then
if [ -f ~/.powerline.bash ]; then
echo 'source ~/.powerline.bash' >> ~/.bashrc
fi
fi
if ! grep -q "powerline" /etc/skel/.bashrc; then
if [ -f /etc/skel/.powerline.bash ]; then
echo 'source ~/.powerline.bash' >> /etc/skel/.bashrc
fi
fi
}
function setup_utils {
read_config_param "PROJECT_REPO"
write_config_param "PROJECT_REPO" "$PROJECT_REPO"
......@@ -828,6 +850,9 @@ function setup_utils {
function_check create_usb_canary
create_usb_canary
function_check setup_powerline
setup_powerline
}
function setup_email {
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment