Switching to fish shell

Over the years, I’ve primarily used bash with occassional forays into zsh (and oh-my-zsh). zsh never seemed significantly better than bash, and it introduced enough friction in writing and running scripts that I’d inevitably switch back to trusty bash after a few months.

I’ve played around with fish in the past, but I never took the time to make an honest go at it. This time I’ve decided to spend some time to learn the shell, port my bash customizations, and see if fish will become my permanent choice.

First steps

Installing on archlinux is fairly straight forward, as the package is simply called fish. Then I ran chsh -s /usr/bin/fish to set fish as my default shell upon login.

Fish configuration location

Fish helpfully stores its primary configuration at $XDG_CONFIG_HOME/fish/config.fish, which is already a welcome change from putting random dot files in your home directory. Also, by default, fish looks for function files in $XDG_CONFIG_HOME/fish/functions/<function>.fish.

Setting vi mode

Setting vi mode in fish involvings invoking a built-in function.

# ~/.config/fish/config.fish

fish_vi_key_bindings

Auto-starting xorg

The next challenge is porting over my .bash_profile. Mine doesn’t do much except set an env var then start xorg, since I don’t use a display manager:

# ~/.bash_profile
[[ -f ~/.bashrc ]] && . ~/.bashrc

if [[ ! $DISPLAY && $XDG_VTNR -eq 1 ]]; then
  export QT_AUTO_SCREEN_SCALE_FACTOR=0
  exec startx
fi

Wanting to use functions, I did this:

# ~/.config/fish/config.fish
start_xserver
# ~/.config/fish/functions/start_xserver.fish
function start_xserver
    if test -z $DISPLAY && $XDG_VTNR -eq 1
        setenv QT_AUTO_SCREEN_SCALE_FACTOR 0
        exec startx
    end
end

fzf

fzf was a bit of a game changer for me after switching to fish. CTRL-R history search becomes fuzzy and so I can type the first half of a command followed by some other random bit of the command and have it selected properly.

# yay -S fzf
# curl -sL https://git.io/fisher | source && fisher install jorgebucaran/fisher
# fisher install jethrokuan/fzf 

I used https://github.com/jethrokuan/fzf instead of the more popular https://github.com/PatrickF1/fzf.fish since the former didn’t have any additional dependencies on fd and bat.

Intellij / Goland

I had to set the Settings -> Terminal -> Application Settings -> Shell Path:

/usr/bin/env XDG_CONFIG_HOME=/home/victor/.config /usr/bin/fish

This got fish running properly in the IntelliJ built-in terminal.

Update in March 2021

It’s been over 6 months since I’ve installed fish and I haven’t gone back to bash, so I suppose it’s been a successful switch.

I still sometimes switch back to bash to run some one-line loops because of muscle memory of bash syntax instead of learning the fish equivalent. I also find the fish vi mode somewhat inconsistent compared to bash’s vi emulation.

However, aside from that, I find fish to be very fast and configurable.