A little bit more than one year ago, I learned about the friendly interactive shell (fish) aka fish-shell and decided to give it a try. Before, I primarily used the Bourne Again Shell (bash) as my main shell. In this post, I write about my experience with fish and some nice tweaks I discovered.
To cut a long story short, I think that fish is really awesome and it helped me to increase my productivity a lot. I am not sure if I will remember to address all the cool things I like about it in this post but I’ll just start and see where I end up. In the following, I will just start with the points that come to mind first and I will outline the features that I consider cool about them.
Automatic Suggestions based on the Command History and Search in the History
When typing something, fish directly starts to provide suggestions of potential completions based on matching the current input to the command history. If a suggestion is useful, just press the right-arrow key and enter to execute it. Otherwise, if you encounter something that looks similar to something that you used before, you can search within the history for matching entries via the up- and down-arrow keys. This matching in the history, like most (or even all) matches in fish, not only matches the beginning of the entries in the history but matches arbitrary sub-strings.
Fish features pretty clever completions for many “standard” commands. This starts by providing hints and explanations when completing a partially entered commend and goes further to meaningfully completing the corresponding command line arguments.
Another nice completion feature is that the completion is not limited to matching from the start of a string, like bash, but instead it is capable to match sub-strings. I’ll use an example for illustrating this: Say the directory “foo/” contains the files “bar.txt” “bar.sh” “bar.pdf” then one can type:
“ls foo/pdf<TAB>”, which will complete to “foo/bar.pdf”.
This is not restricted to the string at the end of the file but generally matches sub-strings.
So for “bar_abc_123.txt” “bar_def_123.txt” “bar_ghi_123.txt”
“ls foo/def<TAB>” will complete to “foo/bar_def_123.txt”.
Furthermore, you can also use completion with wildcards as well: For a directory with files “123abc.txt” “456abc.xml” “789def.pdf” “123def.pdf”.
Entering: “*a<TAB>” will complete to “*abc.” and will offer the options to complete with “txt” or “xml”.
Entering: “*d<TAB>” will complete to “*def.pdf”.
History Token Search
Another cool feature is that fish lets you go through the previously entered history token-wise. I typically use this when I need to deal with long paths or complex command line arguments. I bound the functionality history-token-search-backward and history-token-search-forward to ALT-up and ALT-down respectively as I use it quite often.
Word-wise Movement and Deletion
Yet another cool feature is the ability to perform word-wise movement and deletions when entering commands. This is particularly useful when dealing with long and complex command lines. I put backward-word, forward-word, and backward-kill-word on ALT-left, ALT-right, and ALT-backspace.
History of Visited Directories
Another neat feature is that fish maintains a history of directories that you have been to and allows you to cycle through these directories. This is done via the backward-word and forward-word functionality. As long as nothing was typed yet, using backward-word and forward-word cycles through the list of visited directories.
Git Status in the Prompt
In the Arch Linux Wiki there is also a simple guide on how to enable a nicely looking prompt that shows you the current status of a git repository whenever the current path happens to be inside of a git repository: https://wiki.archlinux.org/index.php/Fish#Prompt
Colors (“Eye Candy”)
Well, you may consider this “just” “eye candy” but from my experience having nicely colored output also helped me when working with the shell. Like many of the things I discussed above, this is most likely something that you have to try on your own for some time in order to get a real idea of its benefits
For certain tasks, like writing short snippets of scripts, such as for loops etc. in the shell, be warned that fish does not follow the syntax of shells like bash or sh. It also uses a different way for handling and setting environment variables. This may look like a problem at first, however, for me all the great advantages of fish outweigh the slight overhead of getting used to this minor peculiarity by far.
I think fish is a truly great shell and that it helped me to become much much more productive. It took me some time to integrate the new capabilities into my workflow but once I got more and more used to the new features, I am really happy about having switched to fish.
In this post, I briefly describe some of the features that I think of as most valuable. All the things I posted are based on my current workflow and experience.
Please let me know, if you happen to know other cool features that I did not mention yet. I am always looking for further improving my workflow.
Last but not least, here are my, admittedly pretty simple, fish key-bindings:
~ cat .config/fish/functions/fish_user_key_bindings.fish
bind \e, 'history-token-search-backward'
bind \e. 'history-token-search-forward'
bind \eup 'history-token-search-backward'
bind \edown 'history-token-search-forward'
bind \ebackspace 'backward-kill-word'
bind \eleft 'backward-word'
bind \eright 'forward-word'