Tweaking fish shell

Example Custom Fish Shell Prompt

Example custom fish shell prompt.

Very early this cold morning I had a sudden urge to improve and customise my shell. A few weeks ago I discovered fish shell but didn’t get around to using it much, so maybe my subconscious decided to wake me up so I can get it done. You win again, brain.

Configuration Synchronisation

As soon as possible, with any new piece of software that needs configuring, it either goes on Git or Google Drive. The latter is currently my preference since it’s automatic. Maybe worth looking at SparkleShare for the future.

Following simple sequence of commands will automatically synchronise the fish config within Google Drive, as long as it’s running:

The Prompt

Color Scheme

Blue colour scheme in iTerm

This is one of the most looked at part of the screen for development and system administration when dealing with the command line. I want it to look good, be informative and only show information when I need it.

Most of the following prompt sections will only display when something important needs to be shown. For example, when the last return code isn’t 0, or if the current load average is too high.

These commands are constructed for OS X Mountain Lion, which might not work with other *nixes, so keep that in mind if you’re using the code as inspiration on other platforms.

Colours

For colours, I picked some blues for foreground text, and then found a colour scheme called Tomorrow Night Blue that had a nice contrasting background colour. I haven’t decided if I rather have a blue or black background yet, so the screenshots you see below alternate between the two.

Current Time

Fish Time

A basic prompt with the current time.

This one is straightforward even though it looks like a mess. Just use the date command with the ANSI colour codes. $c2 for the numbers and $c0 for the colons. The %H, %M and %S to grab the latest hour, minute and second.

 

Execution Time and Alerts

Time taken shown in prompt

Time taken shown in prompt.

I’ve been meaning to do this for a while. In the past I’ve done this manually, and failed to do it automatically, and with fish shell, I’ve discovered it is possible without too much hackery. The code tracks the last time a command executed vs the current time, and if it takes too long (10 seconds in this case), display the seconds taken in the prompt.

Growl Notification

Growl notification showing seconds taken and the return code.

On top of that, if the warning is triggered, it also creates a growl notification. I do this because when waiting for a long running task, I generally switch away to another window (because it’s like watching paint dry). When switching away, there’s no decent way of knowing when the task ends, and I can be wasting precious minutes if I’m not continuously checking on the task.

Edit: Thanks to David Adam for pointing out the undocumented variable called $CMD_DURATION which is only set if a command takes longer than a second.

Current Branch and Status for Git

Git Branch and Dirty Count

Current Git branch and dirty count.

The things I tend to check when working with a Git repository is the current branch and the status of all the files. I mashed these two together in the prompt: the current branch name, and the number of “dirty” files. Dirty in this instance is every entry in the git status command, which includes modified, new, and untracked files that aren’t ignored.

Edit: Woops. Thanks to @leunicorn1 for pointing out that I’m missing the git_branch function:

Python virtualenv

Virtualenv

Current virtualenv env shown.

It’s good practice to create a new virtualenv for each new Python project. Grabbing a virtualenv fish script called virtualfish lets me run commands like vf create hello_world and vf activate hello_world. With the prompt, it just reads the $VIRTUAL_ENV environment variable and displays it when it’s set.

Edit: Thanks to the author, Adam Brenecki for pointing out it’s “activate”, and not “use”.

Load Average

Load Average

Load average warning.

Another warning to display is the 1 minute load average when it gets too high. Useful when you’re worried about power usage, or just keeping your system lean. I had to multiple the load average fraction by 100 so that the test -gt could work, since it only deals with integers.

Disk Usage

Disk Usage

Disk usage warning.

During a large data processing task in my day job, the SSD fills up pretty quickly. It is good to know when this is close to happening, rather than continuously monitoring du, Finder’s status bar, or wait for the dreaded low disk space dialog. The code looks at the output from du on the root device and extracts the percentage, but only shows the value if it’s more than 80% full.

Vi Mode

There currently is no vi mode in fish shell, which was almost a deal breaker until I tried this vi-mode.fish module. Amazingly enough it shells out to Python to do some of the work, but is very responsive until you spam the navigation keys, e.g. lots of pressing w, b, w, b, etc. in quick succession. Fortunately I don’t do this normally, so don’t get to see this effect unless I try!

Conclusion and Future

If you want to steal the whole thing, there’s a gist of it, but I have to warn you, I probably won’t be updating it and it currently has a few bugs. Feel free to fork it and use it as your own, but leave a comment if you do!

There’s lots of work that still needs to be done with this prompt. I want to convert to fish shell on other systems, so I’ll need to add the host name and user to the prompt. An idea is to colour the host name depending on the importance of the system, e.g. orange for production, yellow for a staging server, etc. Similarly, making the username become obvious all the times when switching to root or another user.

If you have any suggestions, please let me know.

One thought on “Tweaking fish shell

  1. slehar

    Very nice! Thanks!

    My only comment: Why not use the fishy-looking prompt?

    function fish_prompt
    set_color $fish_color_cwd
    echo -n ‘~> ‘
    end

Comments are closed.