TL;DR; take me to the Tips already
What & Why
Fish is an awesome shell, and for me a natural bash replacement. The website sums it all up:
Why fish?
fish is a fully-equipped command line shell (like bash or zsh) that is smart and user-friendly. fish supports powerful features like syntax highlighting, autosuggestions, and tab completions that just work, with nothing to learn or configure.
If you want to make your command line more productive, more useful, and more fun, without learning a bunch of arcane syntax and configuration options, then fish might be just what you're looking for!
To me, it is an improvement over bash in at least these areas:
- Convenience
- Configurability
- Scripting Syntax
- Platform neutrality
- Proper Documentation
You can find it here
Convenience
Fish - as it comes - includes a load of thing that potentially improve productivity in the Terminal immediately. A great access to the history of commands, as well as amazing tab-completion are to be mentionied here.
Completion is turned on by default and as you type, you’ll get (greyed out here) suggestions form your history:
Of course completion does not stop here, as fish “knows” how to complete git for instance by default:
Note that you can use the tab-key to cycle through the suggestions
It also can provide further information about the completions
and to wrap this up, after running fish_update_completions, fish completes more or less anything there is a man page for !
From where i am standing, this alone makes it well worth giving it a try!
Configurability
The creators of fish have a funny approach to configurability:
Configurability is the root of all evil
Every configuration option in a program is a place where the program is too stupid to figure out for itself what the user really wants, and should be considered a failure of both the
program and the programmer who implemented it.
Nevertheless, for the most obvious things, fish comes with a nifty web-console for configuration called ‘fish_config’.
Scripting Syntax
I confess not to be a bash wizard, and i probably never will be. This is mostly because i don’t need to write scripts regularly, so it feels like a waste to wrap my head around that pesky syntax. Fish on the other hand brings an intuitive scripting language, that raises my hope of not being lost every time i’d need to script a few lines.
So even if you have never seen a fish script, you’ll be able to read this, right?
if grep fish /etc/shells
echo Found fish
else if grep bash /etc/shells
echo Found bash
else
echo Got nothing
end
or
switch (uname)
case Linux
echo Hi Tux!
case Darwin
echo Hi Hexley!
case FreeBSD NetBSD DragonFly
echo Hi Beastie!
case '*'
echo Hi, stranger!
end
That’s right, no more fi or trying to remember where to put a semicolon.
Platform neutrality
Fish comes for MacOs, Windows (Cygwin, Msys2) and Linux (11 flavours pre-packaged).
Ever tried to create a tiny script in bash, because everyone in the Team/Company should benefit from it, just to find your peers complaining about bash showing a slightly different behavior on MacOS, than on Linux? Not only is the scripting language a more intuitive than bash, it’ll run consistently. That of course leaves you with the prerequisite of convincing everyone to install fish, but you know… :)
Proper Documentation in one place
I really love the docs
9 Tips what to do with a fish
Here is, what i did after installing fish. None of these steps is required or even suggested, it is just what i did to further tweak fish in order to make it more convenient for me.
Tip 1: Do /not/ make fish the default shell
Many people assume that bash or a compatible shell is the default shell. For that reason, i did not use chsh in order to make it default. Where i start sub-shells (like when using sudo or guake), i explicitly call fish. (The su function will be discussed later, see Tip 6).
Tip 2: Use fish_config
Use ‘fish_config’ to select the prompt you like and peek into key bindings and predefined functions.
Tip 3: Add fish_update_completions to your crontab
In order to be sure to leverage the full power of tab completion
Tip 4: Use the F1 Key
F1 brings up the man page of a command, and lets you continue typing after exiting the man page. Just as it should be.
Tip 5: Install re-search
In order to be able to CTRL-R through your history, you’d probably want to install re-search:
git clone https://github.com/jbonjean/re-search.git
cd re-search ; make ; sudo cp re-search /usr/local/bin ; cp *.fish ~/.config/fish/functions
and then create ~/.config/fish/functions/fish_user_key_bindings.fish
containing
function fish_user_key_bindings
bind \cr re_search
end
That gives you incremental search in your history and binds it to CTRL-R, similar than what you are used to from bash.
Tip 6: Put globals into ~/.config/fish/config.fish
This is where to put scripts that should fire when starting fish. The contents of mine is
# disable fishy greeting
set fish_greeting
# define aliases
alias apt="sudo apt"
alias su="sudo /bin/su --shell=/usr/bin/fish "
Note, that the su alias explicitely asks for fish as the shell.
Tip 7: Tweak the Prompt
Skip this if you’re all lucky with the prompt you selected via fish_config.
I disliked the path abbreviations and wanted to have the git status on the right, so here’s what i did:
Create a file ~/.config/fish/functions/fish_prompt.fish
function fish_prompt --description 'Write out the prompt'
set -l home_escaped (echo -n $HOME | sed 's/\//\\\\\//g')
# set pwd to $PWD with the home replaced by ~
set -l pwd (echo -n $PWD | sed "s/^$home_escaped/~/" | sed 's/ /%20/g')
set -l color_bracket FAFAFA
set -l color_user BBB
set -l color_host yellow
set_color $color_bracket
printf '['
set_color $color_user
printf '%s' $USER
# Show the host only for remote sessions
if test -n "$SSH_CLIENT" -o -n "$SSH_TTY"
set_color $color_host
printf '@%s' (hostname)
end
set_color $fish_color_cwd
printf ' %s' $pwd
set_color $color_bracket
printf '] '
set_color normal
end
That gives you my fav. kind of prompt, with ~ replacing home and @HOST only shown, if it is a non-local session.
Then, create a file ~/.config/fish/functions/fish_right_prompt.fish
# fish git prompt
set __fish_git_prompt_showdirtystate 'yes'
set __fish_git_prompt_showupstream 'yes'
set __fish_git_prompt_color_branch yellow
# Status Chars
set __fish_git_prompt_char_dirtystate '!'
set __fish_git_prompt_char_upstream_ahead '>'
set __fish_git_prompt_char_upstream_behind '<'
function fish_right_prompt -d "Write out the right prompt"
printf '%s ' (__fish_git_prompt)
end
that will give you the git status on the right, like:
i am sure, you can figure out, what the symbols mean :)
Tip 8: Install Oh-My-Fish and z
curl -L https://get.oh-my.fish | fish
omf install z
I am sure, there are many gems to be discovered in the OMF repository, but i really want to point to z.
z gives you a tiny function, that lets you cd without navigating through a directory tree using your history, even if (and this is the important part) you partly know the target directory’s name.
Some example:
Tip 9: Browse the OMF repo
While all a matter of taste, i like things like sudope as well. If you found another must-have plugin, let me know…