zsh Prompt Template
I noticed a lot of people online had prompts that looked like this:
These require the terminal to use a font that contains glyphs for certain private unicode
code points. I used the Meslo font, and installed the MesloLGMDZNerdFontMono-Bold.ttf
and MesloLGMDZNerdFontMono-Regular.ttf
variants, and set Terminal.app to use them.
The prompt is made up of a combination of foreground and background color choice, and special (private) Unicode characters:
Code | Character | Description |
---|---|---|
U+E0B0 | | Right arrow |
U+E0B4 | | Right rounded end cap |
U+E0B6 | | Left rounded end cap |
These probably won’t show up correctly until I fix up this site’s fonts.
For each segment pair, choose background and foreground colors. Call these <b1>
and <f1>
and <b2>
and <f2>
. There is also the window background color <bw>
. Take special note, for my preferred white background, I had to use xterm color code 231 for <wb>
. As far as I know, these are three-digit values taken from the xterm-256 color table. There may be other ways so specify the exact color you want.
Useing the above example as a guide, here are the zsh
prompt fragments for each element:
Eleemnt | Fragment |
---|---|
Opening round cap | %F{<b1>}%K{<wb>}$'\UE0B6'%k%f |
First segment text | %F{<f1>}%K{<b1>}<text here>%k%f |
First segment arrow without gap | %F{<f1>}%K{<b2>}$'\UE0B0'%k%f |
First segment arrow with gap | %F{<f1>}%K{<wb>}$'\UE0B0'%k%f%F{<wb>}%K{<b2>}$'\UE0B0'%k%f |
Second segment text | %F{<f2>}%K{<b2>}<text here>%k%f |
Closing round cap | %F{<b2>}%K{<wb>}$'\UE0B4'%k%f |
The arrow gap is made up of two arrow glyphs with judicious color application.
You can also paste the unicode character directly into the prompt string instead of using the zsh unicode escape sequence (e.g. $'\UE0B0'
), but this may be harder to work with if your editor doesn’t display the unicode code points properly.
Issues & Improvements
I’m currently using a prompt like this:
PS1='%B%*%b %(?.%F{green}√.%F{red}?%?)%f %F{114}%K{231}%k%f%K{114}%B %2~/ %b%k%F{114}%K{183}%k%f%K{183}$(__git_ps1 " (%s)")%k%F{183}%K{231}%k%f %# '
It gives me the time, result of last command, pwd, and current git branch. But it gets messy when there’s no current git branch, as it draws the right arrow and end cap with an empty segment:
I think some functions could make this all easier to manage, and if they’re allowed to maintain some state across calls, might be kind of elegant. Maybe I’ll get around to implementing them some day:
Function | Description |
---|---|
initSeg(windowBackground) | Initializes the state and sets the window background color |
segment(text, bg, fg, gap) | On first call, renders the open end cap and text. On subsequent calls, renders the arrow and text. If gap is true, adds a gap. If text is empty, renders nothing but remembers the last-used colors. |
endSeg | Renders the end cap and resets state. |
Oh My *
There are at least a couple of zsh
add-ons that make this stuff easier (e.g. oh-my-posh), but I didn’t want to add a bunch of black-box cruft to my setup. It took me a while to figure out how these prompt bars were being created. There’s likely room for improvement, but this is as much time as I want to spend on it right now.