This is a short set of notes regarding zsh
on macOS and Ubuntu, motivated by the upcoming switch to zsh
as the default shell in macOS Catalina.
In case you’re in a hurry, here’s a public Gist with my current .zshrc
.
Prequisites
First off, you don’t need to install it from brew
. macOS Mojave comes with a perfectly serviceable zsh
5.3 in /bin/zsh
, but by all means feel free to use whatever version you want.
In Ubuntu 18.04 (and WSL), sudo apt-get install zsh
installs it for you, and on any system you can change your default shell in the usual way using chsh
(man chsh
for details and examples, don’t go blindly copying stuff from blog posts…).
The Zero Frills Approach
Almost every zsh
post I came across mentions oh-my-zsh
or prezto
and themeing and a bunch of pretty, colorful, but non-critical things it sets up for you.
I will have none of that, thank you.
Being a purist/stoic, I want to understand what the single most important piece of code I run inside a terminal does, and want its setup to be as minimal (and cross-platform) as possible. I’ve long kept shared versions . bashrc
in either Dropbox or OneDrive, and am doing the same for .zshrc
now as well.
Command Line Editing
Even though I´m a vim
user, I am used to having emacs
bindings for line editing:
bindkey -e
Prompt Setup
I like my PS1
to be short, concise and, above all consistent everywhere:
user@hostname:path$
I’m willing to concede on the $
(since zsh
uses %
for standard users and #
for root), but I like minimal color, and appreciate that zsh
can do it without cluttering PS1
with ANSI escape codes:
autoload -Uz colors && colors
# set a fancy prompt (non-color, unless we know we "want" color)
case "$TERM" in
xterm-color|*-256color) color_prompt=yes;;
esac
if [ "$color_prompt" = yes ]; then
PS1="%{$fg_bold[green]%}%n@%m%{%f%}:%{$fg_bold[blue]%}%~%{$reset_color%}%# "
else
PS1="%n@%m:%~%# "
fi
unset color_prompt
Terminal Titles
The prompt is nice when you’re looking at the terminal, but useless when you’re sorting through a bunch of terminal windows. So I always set the terminal title as well:
# If this is an xterm set the title to user@host:dir
case $TERM in
xterm*|rxvt*)
precmd () {print -Pn "\e]0;%n@%m:%~%#\a"}
;;
*)
;;
esac
Command Completion
When you need to use bash
autocompletion configurations, all you need to do is:
autoload -U +X bashcompinit && bashcompinit
Azure CLI
For instance, for the specific case of az
, assuming you’re using pyenv
and got argcomplete
installed like me, this is what you need to do:
# run this once
activate-global-python-argcomplete --user
# add this to .zshrc
source $HOME/.bash_completion.d/python-argcomplete.sh
eval "$(register-python-argcomplete az)"
SSH Keychain
Another essential I keep near the end of my .zshrc
in Ubuntu:
eval `keychain --agents ssh --eval id_rsa --quiet -Q`
Python and NPM
My current settings for pyenv
and npm
“global” module installations:
export PYENV_ROOT=$HOME/.pyenv
export PATH=$PYENV_ROOT/bin:$PATH
eval "$(pyenv init -)"
export GOPATH=$HOME/Library/Go
NPM_PACKAGES="${HOME}/.npm-packages"
PATH="$NPM_PACKAGES/bin:$PATH"
unset MANPATH
export MANPATH="$NPM_PACKAGES/share/man:$(manpath)"