Add powerline
This commit is contained in:
parent
d55f12d79b
commit
2508d63134
|
@ -0,0 +1,357 @@
|
|||
#!/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 {
|
||||
|
|
Loading…
Reference in New Issue