Set up fish, the user-friendly interactive shell
Fish (Friendly Interactive SHell) is a Unix shell designed to be user-friendly and interactive. It features syntax highlighting, autosuggestions, and a built-in help system, among other features. Fish aims to be more intuitive and easier to use than traditional Unix shells like Bash, while still providing powerful scripting capabilities. Modern macOS computers ship with zsh as the default shell, you can check out Why I Switched from zsh to fish but the main reasons are the speed, simplicity, autosuggestions and vim mode that the fish shell offers.
Installing fish
Fish does not come pre-installed on macOS, you have to install it with Homebrew by running the following command in the terminal.
If you’re not familiar with Homebrew, check out Managing macOS packages with Homebrew.
Making fish your default shell
Now that the fish shell is installed, you have to manually change the default shell by completing the following steps.
First, you will need to get the path to the fish shell executable. If you’re unfamiliar with how executables in the terminal work, I recommend checking out What is the terminal?. Run the following which
command.
The command will output something similar to /opt/homebrew/bin/fish
. Copy the value from your terminal and add it to the /etc/shells
file. You’ll want to edit the file using the sudo
command, since this is an system-level file that lists valid login shells for user accounts. Here is how to update it using vi
.
Enter your user password to open the file then add the fish shell’s path as an new line in the file and save it.
If you’re unfamiliar with vi
, I recommend running vimtutor
in your terminal which will guide you through the basics of how to edit text from inside the terminal.
Now that you’ve added fish as a valid login shell for macOS, you can run the chsh
(change shell) command to change the default login shell.
Copy the command below and run all three commands at once to quickly change your default shell to fish.
You may be prompted, again, to enter your user password and when the command is completed your login shell is now switched to fish. In order for your changes to take effect, you’ll need to log out and log back in to your user account. I recommend you restart your computer for good measure. When you log back in fish will be your default shell, congrats!
Configuring fish
Fish configuration is written in its own scripting language. The entry point for configuring the fish shell is the config.fish
file which can be created with the following command.
This command first creates the ~/.config/fish
directory with the -p
option, which creates any parent directories that do not exist. Then it creates the config.fish
file inside the ~/.config/fish
directory using the touch
command. Note: all of fish’s configuration files are stored in ~/.config/fish
more of which will explore later.
Configure homebrew
I highly recommend you Manage macOS packages with Homebrew. Add the following eval code to your config file to configure homebrew with the fish shell.
Note: Evaluating a command in the shell is typically done with $(cmd)
but fish uses (/cmd)
instead, dropping in the $
. Some developers I’ve talked have chosen not to use fish because of the subtle syntax differences from more traditional shells, but I think it’s worth it.
Add directories to PATH
In fish, the fish_add_path
function is used to add directories to the PATH
environment variable. Adding directories to your system’s PATH
environment variable allows you to run programs located in those directories from anywhere on your system without specifying the full path. By doing so, you extend the list of directories that the shell searches for executables, making it more convenient to run programs and execute commands.
To add support for Homebrew executables to the fish shell, add the following lines to your ~/.config.fish
file.
I recommend creating a ~/.config/bin
directory to store any custom scripts you make come up to improve your workflow or automate tasks.
Setting environment variables
In the Fish shell, the set
command is used to create and modify shell variables. Shell variables are used to store values that can be referenced and reused throughout a shell session or script. Here are some common variables that are helpful.
The -U
flag is used with the set
command to create or modify a universal variable. Universal variables are similar to regular variables, but they have a global scope and can be accessed from any shell session or script.
The fish_greeting
variable is used to customize the greeting message that is displayed when a new shell session is started. By default, the greeting message includes the Fish version number and a welcome message. Since I am constantly spinning up new shells in my development workflow, I prefer to disable the fish greeting by setting it with not value.
The fish_vi_key_bindings
variable allows you to hit escape while writing a command in fish to switch to a vi-mode to easily manipulate your command before running it. Just like vi, you can hit i
to get back to insert mode.
There are many other variables you can set to customize your shell, check out the fish documentation for more information.
The next most common variable to change is the default editor for your shell. This is set with the EDITOR
variable.
Note the -x
flag is used with the set
command to export a variable as an environment variable. When a variable is exported, it becomes available to child processes and can be accessed by programs and utilities that use environment variables. This is helpful as you extend your development environment with other tools that can generate sub processes
Abbreviations
One of my favorite features of fish is the ability to create abbreviations. This works similar to a shell aliasm but the main difference is the abbreviation will expand when ran.
You can create abbreviations with the abbr
command in your config.fish
file. Let’s add a few helpful ones for homebrew.
You’ll have to source your config.fish
file for the change to be reflected in your shell.
Now, you type bs<space>
and you’ll see the prompt quickly expand to brew search
to allow you to create commands quickly using a simple mnemonic-style abbreviations. Abbreviations speed up my dev workflow significantly and are one of my favorite features of the fish shell.
Plugins
There is a large community of plugins for the fish shell. I recommend using fisher to manage them.
A great starter plugin for fish is sponge, which cleans your fish history from typos automatically. It can be installed with the fisher command.
You’ll notice two things.
- A
~/.config/fish/fish_plugins
file was created and added sponge as a plugin. This is how fisher manages plugins. - A
~/.config/fish/functions
directory was created and multiple_sponge_*.fish
files were added to it. This is the plugin code which fish will automatically read to extend the shell. This folder will contain more files as you add more plugins, you can even create your own!
Summary
The fish shell is a simple, fast, and intuitive shell alternative for macOS. In this post we installed fish, set it as your default user shell, configured homebrew, added a directory to your path, customized some of fish’s options, create abbreviations, and installed your first plugin.
Sign-Up for New Posts
Stay in the loop and get the latest blog posts about dotfiles sent to your inbox.
Or use the