I have been eyeing to change the default shell from Zsh to Fish shell for a while now, but never made the transition because I missed a couple of power tools and configurations which didn’t work in the quite the same way on fish.
After giving fish shell configuration another go, I found that I could configure fish to match the functionality of my current zsh configuration with some new features and niceties which comes with a modern shell.
This post is about how I went about configuring fish shell for my usage patterns.
Installing and managing fish plugins
Fish shell comes with powerful autocompletion and other conveniences out of the box without the need for extensive configuration from the user. There are plugins to extend the functionality even further, and two most popular ones for fish seems to be,
Of the two
fisherman seems to be more minimalist, focusing on providing a
package manager for fish plugins. Thus after installing
fisherman you are
required to install plugins of your choosing. It also seems that the impact on
shell startup time with
fisherman is lower than with
oh-my-fish, but this is
not something I have benchmarked myself.
As of this writing, I have installed following plugins with
fisherman, but if
oh-my-fish the same plugins are available as well.
Managing plugins with fisherman
- Update plugins -
- Remove a plugin -
fisher rm <plugin name>
- If you want to get rid of
fishermanplugin manager itself -
Installing fish fzf is pretty easy -
fisher fzf. Note that for this plugin to work you should have already
fzf tool itself.
FZF is a powerful fuzzy filtering tool. Till version
2.6 fish shell had
issues with fzf, and that was the main reason I held up transitioning to fish
as I am a heavy user of fzf for filtering directories and files. With the
version I’m using now, those issues seems to be fixed and I have been able to
replicate most of the useful functions for fish shell as well.
There are couple of differences worth noting,
Fish shell does not support fuzzy glob expansion - with zsh or bash, you can press
Tabon command line after entering
> ~/Dropbox/**and fzf would give you filtering based on the path you entered before the glob
**. This does not work in the same way on fish, but you can get the same functionality by just pressing
Ctrl+Tafter entering part of the path.
Make sure that your
$FZF_DEFAULT_OPTSvariable contains options in a format which is valid for the fish shell. This is something I had to debug to fix because I had an old config option which was set for zsh, but invalid for fish shell. If you see error or warning messages when you run fzf completion commands, then it is a good idea to check this environment variable, and probably set it to a simple value in your fish config file (usually at
I have written about integrating fasd with respect to zsh integration - Using Fasd for Command Line Navigation. Fasd works in the same way with fish shell as well.
Installing fish fasd plugin is pretty easy -
fisher gretel/fasd. Please follow instructions to install
fasd for your OS.
With fzf we can make directory switching even more awesome. Default behavioiur
d command which is provided by fasd does not give ability to filter
output if there are multiple matches. We can utilise fzf to get that
behaviour with the following function.
# Function to filter through recently used directories function zd --argument-names 'name' set -l zd_command "command fasd -Rdl $name 2> /dev/null" fish -c "$zd_command" | __fzfcmd -1 -0 --no-sort -m | read -la select if test ! (count $select) -eq 0 cd "$select" end end # Set above function to even shorter j alias alias j "zd"
fish pure prompt provides popular
pure shell prompt in zsh for the fish shell. This can be installed with
fisher as follows -
One thing I tried to port from my zsh config was backgrounding and foregrounding of Vim in a terminal with the same key combination -
Ctrl+Z. After a bit of research, I found that, as of now it, is not possible to assign
Ctrl+Zfor this functionality with the fish shell.
Zsh completion is quite nice, but fish has even better completion! I quite like how fish offers completions based on history and they are most of the time the right one as well which I want to run.
Fish shell seems to start a bit faster than zsh for me, which could be due to my zsh configuration! This is not a major point, but fish shell feels a bit snappier overall.