2 minutes
Fish shell via Homebrew on macOS
How to install and configure fish shell on macOS via homebrew.
This is mostly for my future self to reference, but just in case anyone else finds it useful, here is how I setup fish shell on macOS.
brew install fish
- Add
/usr/local/bin/fish
to/etc/shells
chsh -s /usr/local/bin/fish
- [Recommended] Create config directories and files:
- Create
mkdir -p ~/.config/fish
andtouch ~/.config/fish/config.fish
. This config file will be used for other optional installs such as Starship, below. - Create
mkdir -p ~/config/fish/conf.d
. Any files placed in this directory will automatically be sourced by fish on startup. I have my abbreviations (abbr) and oh-my-fish files here.
- Create
- Remove intro to fish message:
set fish_greeting
- [Optional] Enable vi keybinds
fish_vi_key_bindings
- [Recommended] Install oh-my-fish
- [Optional] Install git plugin
omf install https://github.com/jhillyerd/plugin-git
- [Optional] Install fasd plugin
omf install fasd
- [Optional] Install osx plugin
omf install osx
- [Optional] Install tab plugin
omf install tab
- [Optional] Install git plugin
- [Recommended] Install Starship prompt
Likes:
- text-replacement style aliases (abbr)
- rich autocomplete via man page parsing
- It’s something new and different. I’ve used (in order): csh, tcsh, bash, zsh. Those all feel like the same family. Fish feels like something totally different. A little less UNIX-y and a little more… python-y?
Dislikes:
- Terminal.app spawns bash shells on every command for some unknown reason. Use iTerm2 instead. I’ll eventually have to solve this one. I prefer the built-in apps unless there is a very large feature gap to third party solutions. (iTerm2 arguably is exactly that)
- Fish is not POSIX compliant; this was known before installing. It is just something to be aware of. Use
/bin/sh
for most scripts anyway. - Does not support escaping commands. I have a few commands that I like more modern, feature-rich versions of (cat –> bat, top –> htop, vim –> nvim) but there are times where you want the plain old version executed. In zsh, I can escape the command by prepending backslash:
\cat .zshrc
. Fish won’t recognize that syntax so I have to edit my abbreviation replacement.
Follow-Up 1
- All terminals (not just Terminal.app) were spawning zombie bash shells (on macOS) and sh (on Pop! OS)
- Tracking down the cullprit: omf plugin for fasd. Removing it fixed the per-command-zombie process!
Follow-Up 2
- Dotfiles - I like to maintain all my settings in a dotfiles repository for easy deployment and versioning. Fish and Oh-My-Fish are no exceptions. All of the fish settings are in
~/.config/fish
and omf reside in~/.config/omf
. Make sure those are versioned for easy deployment. - I’ve added the following omf plugins:
❯ omf list
Plugins
bang-bang fzf.fish git-flow osx xcode
fish-spec git omf tab