fish: The friendly interactive shell

Posted: November 27, 2006 in Applications

One thing which bothered me with BASH are its limited completion capabilities, even though you have bash-completion installed.

This made me switch to ZSH some years ago, which felt more right. It has completions for the most common commands and seemed to be much better suited for interactve work. Nevertheless, I never got into shell programming, although ZSH has some nifty stuff that make it really powerful.

Then three weeks ago I fell over fish because of an LWN article. It’s (the article) quite outdated, but shows many of fish’s nice features. A more actual article can be found at Linux.com.

So what makes fish that cool? Why do we need another shell? Well, because it has many features no other shell has, and because it breaks compatibility. (Why in hell does anyone want compatibility with the 25 year old Korn shell, if the only "benefit" is broken usability? Ok, maybe you’re used to it, but try fish anyway!)

Now let’s talk about fish’s features:

  1. Fish has an advanced syntax highlighting. When you type an incomplete or unknown command, it’s colored in red to indicate an error. Once it’s complete, it’s colored in green. An existing path will be underlined to show its validity. Syntax errors are highlighted in red, too. There are other attributes for e.g. different file types or regular expressions, and of course you con adjust them to fit your needs.
  2. TAB completion is an essential feature when working in the shell, and it’s a part where fish really shines. Of course it completes all commands in PATH and directories/files, but it completes the options and switches of a command, too. For example it knows that the darcs command has the subcommands add, ..., whatsnew, and it knows the switches of those subcommands. Beside completing those subcommands and switches, it displays a short description, so the user can exploit the completion mechanism to explore what a command can do. The best thing is: All those completions are fish scripts utilizing the complete command. So if there’s no completion for the foobar command, you can easily write one yourself (and submit it to the fish ML to share it with the other users).
  3. Fish uses Emacs keybindings, so an emacs user will find it very comfortable. It even has a kill ring!
  4. The command history is awesome. If you press the up and down arrows, you walk accross the command history like in BASH. But if you enter a string at the prompt first, then fish shows only commands that match the entered string. If you use M-Up/M-Down the history commands are tokenized, so you can complete arguments this way.
  5. There’s an open command which open the given file with the application chosen in the desktop environment’s MIME database.

Beside those mentioned features, fish has a lot of other nice capabilities. So here’s my advice: TRY IT and join us at #fish at irc.oftc.net.

Comments
  1. shreevatsa says:

    Hi,
    I use bash, and bash completion looks pretty good to me. I’m curious to know what zsh has that bash doesn’t… could you clarify a bit?

    As for Fish’s features:
    1. Wow, nice! Bash doesn’t have this AFAIK
    2. Bash does this too. It not only knows the top-level commands (like svn aTAB shows add and annotate), but also as many levels as desired (like mplayer -ao TAB shows only those audio output drivers that are available). Of course, the available completions can be edited in /etc/bash_completion
    3. So does bash (readline, to be precise. You can also change to vi keys instead).
    4. In Bash (again, it’s readline), one uses C-r (like Emacs’s reverse-isearch) for this. M-. only gives the *last* argument of the previous command, but I think this can be changed…
    5. It’s called run-mailcap, see, edit, compose, or print.

    Fish seems nice, let me see if it does everything bash does…

  2. Tassilo Horn says:

    I’m curious to know what zsh has that bash doesn’t… could you clarify a bit?

    Hm, good question. Bash-completion has never worked well for me, whereas ZSH’s manual told to put “compinit” into your zshrc, and everything worked out of the box.

    One thing were ZSH is still better compared to fish, is completion of paths on remote hosts. But it shouldn’t be too hard to add this feature in fish as well.

    2. Bash does this too.

    But fish also knows options (e.g. -o) and switches (e.g. –option) and shows a description. Here’s an example:

    heimdall@baldur ~/r/fish> darcs pu<TAB>
    pull (Copy and apply patches from another repository to this one)
    push (Copy and apply patches from this repository to another one)
    heimdall@baldur ~/r/fish> darcs pull –no-<TAB>
    –no-deps (Nicht automatisch Abhängigkeiten erfüllen)
    –no-set-default (Standard-Paketdepot nicht setzen)
    –no-summary (Änderungen nicht zusammenfassen)
    –no-test (Das test-Skript nicht ausführen)

    5. It’s called run-mailcap, see, edit, compose, or print.

    Hm, but the name suggests that those commands always use /etc/mailcap. Fish uses the mime database of the desktop environment you’re using (KDE/GNOME), and /etc/mailcap is used as fallback.

  3. shreevatsa says:

    Nice. I started trying fish today, actually. It’s attractive, but I don’t think I’ll switch until I have time to migrate my 400-odd lines of bash customisation (aliases, functions,shell scripts) to fish syntax :-)
    One very useful bash (POSIX) feature which I wish fish had is “type”. There is “functions” which works for most of the cases when one would want to type “type”, though.
    Another annoyance with fish is that it takes too long to do simple readline things like deleting a character or a word. Used to Emacs syntax, I hit C-d ( or M-d) and it seems to take nearly two full seconds and a repaint of the line to work (it even changes the title of the (konsole) window to “delete-or-exit…” in the meantime).
    The completion functions for some commonly used (by me) commands don’t seem to have been written yet (rsync, gcc…)

    On the whole, fish is quite friendly as claimed. Thanks for mentioning fish; I doubt I’d have heard of it otherwise :-)

  4. Tassilo Horn says:

    One very useful bash (POSIX) feature which I wish fish had is “type”. There is “functions” which works for most of the cases when one would want to type “type”, though.

    type is a builtin command in fish, according to the docs. Works for me. Maybe you use a very outdated version?

    Used to Emacs syntax, I hit C-d ( or M-d) and it seems to take nearly two full seconds and a repaint of the line to work (it even changes the title of the (konsole) window to “delete-or-exit…” in the meantime).

    Yes, indeed. These 2 commands take longer and flicker here. I consider that a bug and report it to the author, who is quite responsive. For example M-k works instantly as it should be.

    The completion functions for some commonly used (by me) commands don’t seem to have been written yet (rsync, gcc…)

    gcc works for me, but rsync is missing right now. So write it and submit it to the mailing list. Have a look at the completion scripts in /usr/share/fish/completions/ for examples and “help complete”.

Leave a comment