After some years of using the great one and only zsh
shell, I have accumulated a few plugins in my
configuration. My plugin manager of choice has been
antibody which is written in Go and
consists of a single binary. It does everything I want and stays mostly out of
my way, but the setup involves downloading or compiling a binary and placing it
somewhere in your $PATH
.
This is fine if you have only one device with your shell configured, but if you want to manage and deploy your dotfiles automatically, it introduces unnecessary complexity and extra work.
I manage all my dotfiles with ansible, setting up antibody with all of it's
plugins is defined in a dedicated ansible
role. When
deploying the dotfiles to a new machine, this role has often been the one to
cause problems and involve manual fixing. I tried various approaches, the last
one being to run the install_antibody.sh
script that I put in the repository
of my ansible role.
What I really want, is to have as little moving parts as possible for my shell setup. It should just work™ and just involve starting the ansible playbook, me getting a coffee and coming back to a fully configured shell the way I have it setup on all my other devices.
Enter Znap
A few days ago I saw an announcement on reddit about a new plugin manager, written in pure zsh code and decided to give it a try.
Znap is roughly 4 kilobytes of source code that does everything you could ask for from a plugin manager and nothing that you don't ask for.
The installation consists of cloning the repository and sourcing it from your
.zshrc
. Plugins are simply cloned from via some handy aliases it provides.
Here is the repository for those not knowing how google works.
Installing Znap
Create a folder to hold all your plugins and znap itself ~/.zsh-plugins
is
suggested, but you can use anything you want. In it clone the managers
repository.
That's it. Now just source the manager at the top of your .zshrc
so it is
loaded before any of the functions provided by it are used and restart your
shell.
# ~/.zshrc
Installing Plugins
To install a plugin you could manually clone it to your newly created
~/.zsh-plugins
folder, but znap provides a function to do it for you that
places it in the correct directory.
I currently use the following plugins
- zsh-users/zsh-completions
- zsh-users/zsh-syntax-highlighting
- mafredri/zsh-async
- rupa/z
- sindresorhus/pure
- ael-code/zsh-colored-man-pages
- momo-lab/zsh-abbrev-alias
- Aloxaf/fzf-tab
From on-my-zsh and prezto I only want to include certain parts and not the complete plugin eco-system
- robbyrussell/oh-my-zsh
- lib/completion
- sorin-ionescu/prezto
- modules/utility
- modules/completion
- modules/environment
- modules/terminal
- modules/editor
- modules/history
- modules/directory
- modules/syntax-highlighting
- modules/zsh-history-substring-search
All of them can be installed with a single command (of course you could also run multiple commands to split it up)
Znap will download all plugins to the .zsh-plugins
directory. At this point
you only have to source the folders of each plugin you want to use from your
~/.zshrc
. For me this looks like this:
# From Oh-my-ZSH
# From Prezto
fpath+=( )
# Pure prompt
fpath+=
&&
Final Words
That's all! Everything worked out of the box with the above configuration. My shell looks and behaves exactly like it did before, with the difference of being extremly portable and probably working on any system that has zsh installed.
I will update my ansible role for zsh to use znap, which should be only a matter
of using the git
module and
copying my ~/.zshrc
file like I did before. No compiling, no dependencies and
hopefully no more broken shells.
Thanks to Marlon Richert, the author of znap, leave him a star on GitHub!