I like Zsh. It’s a powerful, efficient shell. It’s better than Bash by just about every metric (better performance, more features, better sh compatibility). I really have no idea why people keep using Bash.
Anyway, I put together a little piece of zshrc
to show my current status in right-hand prompt – a prompt that’s shown right-aligned in the shell. Zsh has a couple of features that make this really easy.
First the prompt_subst
options instructs the shell to do variable substitution when evaluating prompts. So if you were to set your prompt to '$PWD> '
then your prompt would contain your current directory. Of course you wouldn’t do it that way, %~
does that much more nicely, but that takes us to Zsh’s second feature, ridiculously powerful variable substitution and expansion. In my prompt I just use the simple $(shell-command)
substitution, but there’s a full complement of file-io, string manipulation and more to be had.
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
setopt prompt_subst | |
autoload colors zsh/terminfo | |
colors | |
function __git_prompt { | |
local DIRTY="%{$fg[yellow]%}" | |
local CLEAN="%{$fg[green]%}" | |
local UNMERGED="%{$fg[red]%}" | |
local RESET="%{$terminfo[sgr0]%}" | |
git rev-parse –git-dir >& /dev/null | |
if [[ $? == 0 ]] | |
then | |
echo -n "[" | |
if [[ `git ls-files -u >& /dev/null` == '' ]] | |
then | |
git diff –quiet >& /dev/null | |
if [[ $? == 1 ]] | |
then | |
echo -n $DIRTY | |
else | |
git diff –cached –quiet >& /dev/null | |
if [[ $? == 1 ]] | |
then | |
echo -n $DIRTY | |
else | |
echo -n $CLEAN | |
fi | |
fi | |
else | |
echo -n $UNMERGED | |
fi | |
echo -n `git branch | grep '* ' | sed 's/..//'` | |
echo -n $RESET | |
echo -n "]" | |
fi | |
} | |
export RPS1='$(__git_prompt)' |
This is fantastic; my zsh only shows my current git branch in yellow on the right-hand side, too. I may have to add this to my rc… thanks!
Neat! I probably ought to get up on this, but I fear my prompt is already too complicated: PS1=’$?] \u@\h:\w \$ ‘ (And FWIW, I keep using bash because it’s installed absolutely everywhere by default. Except debian machines, which uses dash (it’s like they want everyone to run off to Ubuntu).)
Beautiful code and snazzy idea!
For those who don’t know, sh conditional/loop syntax was originally designed to test the exit code of programs. (All most people seem to do these days is use “[” or “[[“.) So in the case where zero/non-zero is what matters, not “it has to be 1” as in Ian’s code above, try this:
if false ; then
echo “I won’t be shown”
fi
For longer commands, it looks neater if you put the “then”, “do”, etc. on the next line, as Ian did.
Nice job Gio, unfortunately it’s a bit too slow to give the prompt back on a kernel-size git repository 😉