By Erik Larson | August 20, 2020
Getting started with zsh
I just recently made the switch from bash to zsh. I started trying zsh after updating my mac to Catalina and getting this message:
The default interactive shell is now zsh.
To update your account to use zsh, please run `chsh -s /bin/zsh`.
For more details, please visit https://support.apple.com/kb/HT208050.
I had pretty much only used bash to that point. I started slowly with zsh, not changing the default right away as I wasn’t quite ready to give up on bash just yet. I didn’t know much about zsh or how it differed from bash, so I started with the Moving to zsh blog series on Scripting OS X. If you are new to zsh that is a great place to start. After reading the post on Customizing the zsh Prompt, I wanted to try it out. I made a very simple .zshrc
, copying over alias
statements from my bash setup, and creating a custom prompt:
PROMPT='%(?.%F{green}√.%F{red}?%?)%f %B%F{blue}%3~%f%b %# '
If the previous shell command returned an error, the error number is displayed in red at the front of the prompt. Handy! Otherwise, a green checkmark is displayed. Next is the current path, showing at most 3 levels. Pretty simple, but an upgrade over the bash prompt I was using.
I would jump into zsh occasionally, but still not quite ready to change the default. Then I saw the release announcement for Kali Linux 2020.3. Wow! I had seen some interesting themes using Oh My Zsh, but this layout really caputured my attention. I really loved the idea of having the informational part of the prompt on another line from the typed command. The release announcement mentioned that Kali would be switching its default shell to zsh also. Now I was convinced, time to switch.
A quick chsh -s /bin/zsh
and I was running.
I installed Kali Linux 2020.3 as a VM using Parallels and quickly grabbed that .zshrc
file. It worked! I now have syntax highlighting, path completions, changing directories with just the path (no cd
needed), autocompletions, command result on the right side and a 2-line prompt. Excellent!
But can we make it a little better? Of course!
Customizing zsh
You can try out my .zshrc
There is some GNU and Debian-specific configuration in the Kali Linux .zshrc
, so removing that makes the file quite a bit simpler.
Adding git info
With a 2-line prompt, there is plenty of room for extra info. Let’s add git information to the first line. To enable version control information, the vcs_info
function is used. Autoload it and include it in the existing precmd()
function.
autoload -Uz vcs_info
precmd() {
...
vcs_info
}
zstyle ':vcs_info:git:*' formats
formats the git info string. It is only displayed if the current directory is in a git repo.
zstyle ':vcs_info:*' check-for-changes true
zstyle ':vcs_info:*' unstagedstr '!'
zstyle ':vcs_info:*' stagedstr '+'
zstyle ':vcs_info:git:*' formats $'\Ue0a0''[%b]%u%c%m'
$'\Ue0a0'
is the unicode for the branch-looking character (more on this later)%b
is the current branch name%u
displaysunstagedstr
if there are unstaged changes (not added)%c
displaysstagedstr
if there are staged changes (added but not committed)%m
displays a string for untracked files in the repo
The %u
and %c
formats need check-for-changes
enabled. To detect untracked files, we need a bit more code
zstyle ':vcs_info:git*+set-message:*' hooks git-untracked
+vi-git-untracked(){
if [[ $(git rev-parse --is-inside-work-tree 2> /dev/null) == 'true' ]] && \
git status --porcelain | grep '??' &> /dev/null ; then
hook_com[staged]+='T'
fi
}
To add the string generated by formats
to the prompt, put ${vcs_info_msg_0_)
in the PROMPT
definition just before the \n
. I’ve broken out each piece of the prompt here to highlight each part indvidually.
PROMPT_USER_MACHINE='%F{green}┌──(%B%F{blue}%n%m%b%F{green})-'
PROMPT_PATH='[%B%F{reset}%(6~.%-1~/…/%4~.%5~)%b%F{green}]'
PROMPT_GIT='%F{011}${vcs_info_msg_0_}'
PROMPT_LINE2=$'\n%F{green}└─%B%F{blue}$%b%F{reset} '
PROMPT='$PROMPT_USER_MACHINE''$PROMPT_PATH''$PROMPT_GIT''$PROMPT_LINE2'
Now we’ve added the git info in a bright yellow to the prompt!
Color
The color commands for macos are a little different than GNU. Use the -G
option to add color to ls
. The --color=auto
option still works with grep
.
alias ls="ls -GF"
alias ll="ls -lGF"
alias la="ls -aGF"
alias l="ls -GF"
alias lla="ls -alGF"
alias grep='grep --color=auto'
alias fgrep='fgrep --color=auto'
alias egrep='egrep --color=auto'
Custom Alias and Commands
I use lots of alias
commands as shortcuts to do things like configure JLink
for a specific microcontroller. I didn’t want to include those here, so that the .zshrc
stays somewhat generic. To use this .zshrc
file unmodified, but still add your own alias
or other setup, create a .alias
file in the home directory, and it will be run, if it exists.
if [ -f ~/.alias ]; then
. ~/.alias
fi
Install
Install the zsh-syntax-highlighting, zsh-autosuggestions and menlo powerline font packages using Homebrew. I use the menlo font with the Ocean profile in Terminal, so this will install the powerline version of that font.
brew install zsh-syntax-highlighting zsh-autosuggestions homebrew/cask-fonts/font-menlo-for-powerline
The powerline fonts include special characters like the branch character we are using in the prompt. There are several other powerline fonts available in Homebrew.
brew search powerline
brew cask install font-<name>-for-powerline
Backup the existing .zshrc
and symlink the .zshrc file from my Github repo to your home directory.
Watch Star Fork Issue Download
git clone https://github.com/statropy/zsh-macos.git
mv ~/.zshrc ~/.zshrc.orig
ln -s ./zsh-macos/.zshrc ~/.zshrc
To add your own alias or other commands without having to edit .zshrc
, create a .alias
file in the home directory. The .zshrc
file will load it if it exists. You can copy alias
commands directly from your .bashrc
and they will work.
In the Terminal Preferences for the selected Profile, change the font to Menlo for Powerline
(or another installed powerline font). Open a new Terminal tab with that Profile.