Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
Zsh spanning bar prompt with “balanced” sides.
# Spanning bar prompt with “balanced” sides.
#
# Author: Micah Elliott http://MicahElliott.com
# License: WTFPL http://sam.zoy.org/wtfpl/
#
# Term-width spanning ideas and much code from Phil!
# http://aperiodic.net/phil/prompt/
#
# Some VCS ideas from Krynr.
# http://kriener.org/articles/2009/06/04/zsh-prompt-magic
#
# Combined, extended, and submitted by Micah Elliott.
#
# Drop this file (prompt_balance_setup) into a dir on your fpath and
# type: prompt -«tab»
#
# Not yet doing anything proper when git is in rebase mode.
#
# Other useful glyphs: ☻ ♡ ≠ ▶ → ★ ↑
prompt_balance_help() {
cat <<EOH
See key indicators when you need them, with apposite emphasis.
Supports changing the highlight line colors.
% prompt balance [<color-or-number>]
where the color will be a bold version of:
black blue cyan green gray magenta red white yellow
## Features
* kinda pretty :)
* automatically show/hide status indicators (VCS, jobs, errors)
* color-tweakable highlight bar color
* use of 7 pleasant non-bold colors (use color names or numbers)
* spanning bar to mark your place in long scroll of shell output
* show the executing foreground command in titlebar
* some fancy unicode chars for status
* somewhat minimalist, excluding pty, uname, etc
* should look okay on dark or light bg console
You might do best with an xterm. Try ‘xfontsel’ and choose a font that
supports iso10646 and record in ‘~/.Xdefaults-$(hostname)’.
## Philosophy
* The right side often goes unnoticed, so don’t put very important things
over there.
* Use characters that are by default copy-able (colons are bad).
* Important things should stand out, so error exits should jump at you.
* The VCS indicators should match the VCS’s output.
I chose red to for ‘changed’ since it’s most critical to get committed.
Blue up-down arrows mean changesets need to be pulled/pushed.
* A simple clock on left is kind of important to easily see a start- and
end-time of a command you forgot to time. RPROMPT won’t work for this.
* Each ‘box’ is self-contained and has a different color. The most
relevant is the one next to where you start typing so it should have key
status indicators.
Git can be made to use (subjectively) better colors with:
% git config --global color.status.«tab» <color>
EOH
}
precmd() {
vcs_info 'prompt'
# ${${vcs_info_msg_1_%%.}/$HOME/~}
local promptsize=${#${(%):---(%n@%m)---()--}}
local pwdsize=${#${(%):-%~}}
# Can’t actually calculate this since color codes add to char count.
# So using 16 as magic number by rough count. But screw it anyway;
# won’t use this.
local vcssize=$(( ${#${vcs_info_msg_1_%%.}/$HOME/\~} - 16 ))
local totalsize=$((promptsize + pwdsize))
#local totalsize=$((promptsize + pwdsize + vcssize))
#local totalsize=$((promptsize + vcssize))
local TERMWIDTH
(( TERMWIDTH = COLUMNS - 1 ))
# Truncate the path if it's too long.
PR_FILLBAR=""
PR_PWDLEN=""
if [[ "$totalsize" -gt $TERMWIDTH ]]; then
((PR_PWDLEN = TERMWIDTH - promptsize))
else
PR_FILLBAR="\${(l.(($TERMWIDTH - ($totalsize)))..${PR_HBAR}.)}"
fi
# RVM status, colorized.
# Only showing version and gemset; may add others (esp ‘p’) as I use more.
# Showing everything makes prompt too long.
# rvm-prompt command is tweakable with arg(s): [ivpragus]
# (see ~/.rvm/bin/rvm-prompt)
##local rvm=$(rvm-prompt v g)
##[[ -n $rvm ]] && PR_RVM=" %F{yell}r$rvm" || PR_RVM=""
# Maybe faster way but convoluted/unreliable.
#[[ $rvm_ruby_string == "system" || -z $rvm_ruby_string ]] && PR_RVM="" || PR_RVM=" ($rvm_ruby_string)"
# VirtualEnv status.
# YAY, there is a way to stop VE from adulterating your prompt!
# Put this in your Zsh startup config.
# export VIRTUAL_ENV_DISABLE_PROMPT=1
if [[ -n $VIRTUAL_ENV ]]; then
# Fastest possible way to get python version.
pythonv=$(python -V 2>&1 |awk '{print $2}')
PR_VE=" %F{yell}p$pythonv@${VIRTUAL_ENV:t}"
else
PR_VE=""
fi
# Each i3 window resize clears tabs setting.
# Causes extra newline on each prompt.
#tabs 16
}
preexec() {
# Show the running command in titlebar.
# Useful any time some command is running in foreground, especially
# for things like REPLs.
# Test with `somecmd; sleep 3` to see somecmd in bar.
# $1 is as typed; $2 is alias-expanded.
# I don't actually know what the \e]0 or \a (bell??) escapes do, but
# they seem required.
# BUG: But this makes % act screwy, as in:
# print '%2B'
##print -Pn $'%{\e]0;$1 ($2) | %~\a%}'
}
prompt_balance_setup() {
setopt extended_glob
setopt prompt_subst
autoload -Uz vcs_info
# See if we can use colors.
autoload colors zsh/terminfo
if [[ "$terminfo[colors]" -ge 8 ]]; then
colors
fi
for color in RED GREEN YELLOW BLUE MAGENTA CYAN WHITE; do
eval PR_$color='%{$terminfo[bold]$fg[${(L)color}]%}'
done
# HACK: Turning bold off here redundantly since not sure why
# completion munges color for terminal without.
PR_NO_COLOUR="%{$terminfo[sgr0]%}%b"
### See if we can use extended characters to look nicer.
PR_SET_CHARSET="%{$terminfo[enacs]%}"
PR_SHIFT_IN="%{$terminfo[smacs]%}"
PR_SHIFT_OUT="%{$terminfo[rmacs]%}"
# These are not simply extended ascii; won't render in places like asciiio.
typeset -A altchar
set -A altchar ${(s..)terminfo[acsc]}
#PR_HBAR=${altchar[q]:--}
#PR_ULCORNER=${altchar[l]:--}
#PR_LLCORNER=${altchar[m]:--}
#PR_LRCORNER=${altchar[j]:--}
#PR_URCORNER=${altchar[k]:--}
PR_HBAR=''
PR_ULCORNER=$''
PR_LLCORNER=$''
PR_URCORNER=$''
PR_LRCORNER=$''
### VCS settings.
zstyle ':vcs_info:*:prompt:*' enable git
# check-for-changes can be really slow; disable if working with big repos.
zstyle ':vcs_info:*:prompt:*' check-for-changes true
# Set up strings to be used below.
zstyle ':vcs_info:*:prompt:*' stagedstr " ↕↕"
zstyle ':vcs_info:*:prompt:*' unstagedstr " ±±"
# These affect ‘formats’ and ‘actionformats’. See zshcontrib.
# %s - vcs in use
# %b - branchname
# %a - action (e.g. rebase-i)
# %i - revision number
# %c - stangedstr (see style below)
# %u - unstagedstr (see style below)
# %R - repo path
# %r - base dir of repo
# %S - subdir in repo
# %m - misc info
# Note that to use prompt formatting codes like %u (stop underline) you
# need to double up the %s (if conflicting, but good idea anyway!).
# Very important to terminate these with unsetters like %%f and %%u to turn
# off codes, lest you muck up your completion coloring.
zstyle ':vcs_info:*:prompt:*' actionformats " %b%u%c(%a%)//" "%R/%S"
zstyle ':vcs_info:*:prompt:*' formats " %%F{cyan}%b%%F{red}%u%%f%%F{blue}%c%%f" "%R/%S"
# For when no vcs found.
zstyle ':vcs_info:*:prompt:*' nvcsformats "" "%~"
### Titlebar text.
PR_TITLEBAR=$'%{\e]0;%(!.-=*[ROOT]*=- | .)%n@%m:%~ | ${COLUMNS}x${LINES} | ${TERM} | ${ZSH_NAME}\a%}'
# Generalized colors.
PR_C1=${1:-'black'}
#echo "Set color to ‘$PR_C1’"
#PR_C1=black
PR_LINES=%B%F{$PR_C1}
BO="%B%F{$PR_C1}[%f%b"
BC="%B%F{$PR_C1}]%f%b"
# Finally, the prompt.
# This thing is a little out of control. I’d like to just remove the
# extended character SHIFTing business, but would be more work than to
# just leave them alone.
PROMPT='$PR_SET_CHARSET${(e)PR_TITLEBAR}\
$PR_LINES$PR_SHIFT_IN$PR_ULCORNER%b%F{blue}«$PR_SHIFT_OUT$BO\
%b%F{blue}%$PR_PWDLEN<...<%~%<<\
%B%F{whit}$BC$PR_SHIFT_IN%F{blue}»$PR_LINES$PR_HBAR${(e)PR_FILLBAR}%b%F{gree}«$PR_SHIFT_OUT$BO\
%F{gree}%(!.%SROOT%s.%n)%F{gree}@%m\
%F{whit}$BC%F{gree}$PR_SHIFT_IN»$PR_LINES$PR_URCORNER$PR_SHIFT_OUT\
$PR_LINES$PR_SHIFT_IN$PR_LLCORNER%b%F{whit}«$PR_SHIFT_OUT$BO\
%(?.%F{gree}✓0 .%F{whit}%K{red}✗%?%k )\
%1(j.%b%K{blue}j%j%b%F{whit}%k .)\
%F{whit}%D{%H:%M}%b$PR_RVM$PR_VE$vcs_info_msg_0_ \
%(!.%F{red}.%F{whit})%#%F{whit}$BC$PR_SHIFT_IN%b%F{whit}»$PR_SHIFT_OUT\
$PR_LINES$PR_SHIFT_IN$PR_HBAR$PR_SHIFT_OUT\
$PR_NO_COLOUR%f%b '
RPROMPT=' $PR_LINES$PR_SHIFT_IN$PR_HBAR%b%F{mage}«$PR_SHIFT_OUT\
$BO%F{mage}%D{%a,%b%d}%b%F{mage}$BC$PR_SHIFT_IN%b%F{mage}»$PR_LINES$PR_LRCORNER$PR_SHIFT_OUT$PR_NO_COLOUR%f%b'
PS2='$PR_LINES$PR_SHIFT_IN$PR_HBAR$PR_SHIFT_OUT\
$PR_SHIFT_IN%b%F{whit}«$PR_SHIFT_OUT$BO\
%b%F{whit}%_%F{whit}$BC$PR_SHIFT_IN%b%F{whit}»$PR_SHIFT_OUT\
$PR_LINES$PR_SHIFT_IN$PR_HBAR$PR_SHIFT_OUT$PR_NO_COLOUR%f%b '
}
prompt_balance_setup "$@"
# vim:set filetype=zsh:
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment