I’ve used Fish shell for the past few years now and find it pretty useful.1 I was originally convinced by Julia Evans’ The fish shell is awesome. Lately, she has the follow up Reasons I still love the fish shell. These are both worth reading - and just generally her posts. She’s a very, very good explainer at plenty of concepts that are hard.

The tl;dr from these articles is that Fish has good multiline support for pasting, good tab completion, good auto suggestions, and decent command history (she reports 256000).

I actually have a few more to add on to that - mostly rehashing the Fish documentation page, but with asciinema recordings of the commands.2

I think of learning how to use the Fish shell interactively as becoming faster at doing routine things within my job and also regular work. These are often annoying things to do. I don’t really have a scientific argument to make here about any relative speedups. I mostly use Fish because I find it more comfortable. It also saves me time because there’s a pre-existing “way to do things”. There are a lot of decisions to be made in engineering, but the minute specifics of how I interact with my shell is not one of them yet.

Here’s some classics:

tab and shift-tab

Here I demonstrate just how nice the tab interface is for the Fish shell. Notice that after having started the -, Fish “knows” to complete commands and prints them to tab through them with brief explanations of each command. From what I understand, Fish starts by parsing the man pages of each command and maintains a database it looks up from.

arrow keys

In Fish, you can use the arrow keys to move around the shell. This is identical to most terminals that I know of, and, perhaps a very good thing. Additionally, you can use alt or shift alongside an arrow key to move by words or words (without considering punctuation) respectively.

You can also use the right arrow key to accept a suggestion just as you can with tab. If a command is outlined, simply pressing the right arrow (or Ctrl+e as we will see shortly) is enough to materialize it.

As you can see, first I start typing clang, then hit the right arrow to materialize it. After that, I use just the arrow keys to move back and forth. Using alt allows me to move by word, and using shift right after allows me to skip punctuation. If you’re clever, you might notice that alt considers the -- in --help to be its own word, whereas shift does not.

more pieces of navigation

If you’ve ever used vanilla Emacs, you will know that Emacs has a somewhat strange approach to keybindings. It’s not that vi (or vim or nvim) is necessarily intuitive, but the whole notion of moving around while holding Ctrl is kind of hilarious to me. For example, left or right are ctrl+b and ctrl+f respectively.

Why, you say?

Ah, yeah, not the slightest idea.

I assume it seemed reasonable to someone? I’m not even sure why you wouldn’t just co-opt the vim style hjkl or even jkl; to at least keep your fingers in the same place during typing.

Anyways, fish loves Emacs style bindings so much that you can use all the classic ones.

There are only a few I think are worth talking about though, because they can be rather handy, namely ctrl-a (which goes to the front of the line) and ctrl-e (which, surprise, goes to the end of the line).

There are also oddballs, like ctrl-t to transpose characters, alt-t to transpose words, alt-c to capitalize the latest word, alt-u to make the latest word all caps. (ALL CAPS when you spell the man name.)

I personally just re-type things, but maybe you’ll find use in it.

command history

Recently, I’ve embraced not typing the same stuff over and over. I like history (which just dumps the latest command history into less - or presumably whatever pager you’ve chosen). If you use Emacs bindings, then ctrl-r is especially good.

Essentially, it let search through the history of your past commands with a decent fuzzy search. If you want to get a sample of what you’ve written, pressing ctrl-r while inside the search takes you to older records, whereas ctrl-s takes you to newer ones.

less is more

less is a pager, which is a tool written for before the days of scrollable terminals. Essentially, it lets you use arrow keys or vim like bindings to look over a file or the output of a command. (Really just any stream of text.) You might balk at this given your fancy scrollable terminal, but consider the downside of the scrollable terminal: if you are like me, the outputs of your last commands are still in your “scrollback”, which can get you confused if you think they might be the output of your code after your latest compile & run sequence.

alt-p lets you append &| to a command, which lets you take both the standard output and standard error of a command and read it without worrying about mixing it up with the last output.

tough commands

When your command gets too long you can use alt-e to open it in whatever you have declared as EDITOR or VISUAL. As a side note, you should certainly set these in whatever shell you’ve decided to choose.

the duds

I could not, for the life of me, get alt-w to work quickly. Conceptually, you are supposed to It took probably 10 seconds, which is much slower than virtually everything else in my terminal emulator seems to operate at. I also suspect that just using man is a faster approach to getting the same conclusion.

  1. I’m not actually terribly old - both in the cosmic sense and in the computing sense. In fact, I personally have only spanned 5 prime ministers, which is my favourite measure of time. As a result, I don’t have a lot of the historical context for why someone might choose shells like tcsh or bash. I’m sensitive to the concept that I might be doing a Chesterton’s Fence with this one, but I’m open to hearing alternative opinions. My e-mail address is on the front page of this blog after all.

  2. I’m mostly focused on interactive usage here, which is most of what I use my shell for. After reading the piece of poetry that is j3s’s write posix shell, I was to some extent convinced that using the most rock solid and well-specified.