Trying Fish Shell
Posted on June 10, 2020
I have been using zsh
as my shell for almost 15 years. I spent ages
configuring it in the beginning and for the most part I have been happy with
my setup. Lately, I saw multiple suggestions for
zsh-autosuggestions, which
has a tag-line “Fish-like autosuggestions for zsh”. Imitation is the best form
of flattery. So, I thought of giving fish a shot.
I did not have high hopes with fish, simply because I am so very used to zsh and fish is an opinionated shell which breaks POSIX compatibility. After spending a day configuring it and spending another day using it, I have been pleasantly surprised.
For the most part, the default behavior of fish was similar to my zsh setup. It was relatively simple to port all my aliases and customized shell functions from zsh to fish. And for the most part, I was productive right away in fish.
I like the directory dependent auto-suggestions and like the fact that it can parse man pages for tab completion options. As an example, I use hugo to generate this blog. Hugo comes with a completion plugin for bash but not for zsh. I had a written a bare bones zsh-completion plugin for hugo for the 2 or 3 options that I commonly use. Fish is able to suggest tab completion options by parsing the man page.
But there are two pain points.
The first is the ability to ignore suffixes in tab completion. For example, I had the following in my .zshrc [inserted manual line break for readability]:
# Vim: do not offer completion of temporary files of tex
zstyle ':completion::*:(nvim|vim):*' file-patterns '*~*.(aux|dvi|log|thm|idx|pdf
|rel|out|tuo|tui|tuc|tmp|mpo|mpb|mpd|1|keep|pgf|fls|gz|fdb_latexmk)' '*'
So, when I press vim <Tab>
, the autocomplete does not suggest filenames with
the above extensions. I use the same pattern for many programs. In my quick
scan of the auto-complete plugins distributed with fish, I could not find a
similar pattern. I ended up replicating this functionality with (again,
inserted line break for readability):
# Do not offer completion of tmp files
complete -c nvim -x -a "(
fd --full-path --type file --max-results=20 (commandline -ct)
-E '*.{aux,bbl,blg,dvi,fdb_latexmk,gz,fls,idx,log,pdf,pgf,out,tmp,tuc,thm}'
)"
This is not functionally equivalent and I am forking out to an external
problem rather than builtin completion. But fd
is relatively fast, and I do
not notice any perceptible difference in speed. Plus, it has the advantage
that I get suggestions from nested sub-directories, which I find useful.
The other trouble is that fish does not support history substitution (!$
,
etc.). This is explicitly mentioned in the
FAQ.
Fish recommends using Up Arraw
and editing the recalled line or using Alt+Up Arrow
or Alt+.
to recall the arguments of the previous command, start from
the last.
This breaks a lot of my muscle memory. For example, when generating a new blog post, I use
$ hugo new post/title-of-the-post.md
$ nvim content/!$
Using Alt+.
after content/
does not work.1
In spite of these two annoyances, I like the rest of the shell. I like the
fact that I can type funced name
to see how each function is defined, and
tweak it if I wish. So, I am going to use fish for a while and see how it
goes.
-
Though, in this situation, I can use my fancy new
fd
based completion to simply donvim title<Tab>
to complete the filename. I could also usenvim title<Ctrl+T>
to invokefzf
based completion (but that doesn’t ignore exteions). ↩︎
This entry was posted in CLI and tagged fish, zsh, shell.