Fish (shell) fun: event handlers

In my last post on the Fish shell, I brazenly stated that “because of the way that Fish handles the prompt function, there’s no easy way to hook it without modifying the original theme files.” That was 100% incorrect, as I figured out the next day.

Fish has the ability to specify that any function act as an event handler. You can attach to the event fish_prompt to have the function run right before the prompt displays. So my revised function in my init file is:

function __should_na --on-event fish_prompt
  set -l cmd (history --max=1|awk '{print $1;}')
  set -l cds cd z j popd g
  if contains $cmd $cds
    test -s (basename $PWD)".taskpaper" && ~/scripts/fish/na

Now I no longer need to edit the theme files directly at all, which is much more how I’d prefer things to be. As an alternative to fish_prompt, you can also attach to variables changing, which means you can use PWD to run the function any time the working directory changes. That would look like:

function __should_na --on-variable PWD

Also, any function can use the emit command to add its own hook. The example from the docs is nice and succinct:

function event_test --on-event test_event
    echo event test: $argv

emit test_event something

This is one area where the Fish documentation seems lacking: there’s no list of available hooks nor (that I can find) any way to retrieve a list of emitted events in the shell. It’s been trial and error for me thus far. Hopefully someone will correct me if I’m wrong here. Update, someone (evanrelf) did correct me in the comments: you can find a list of all named events using function -h.

Ok, so that’s an extended correction to my last post, but it’s a cool enough aspect of Fish that it seemed worth covering on its own.

Brett Terpstra

Brett is a writer and developer living in Minnesota, USA. You can follow him as ttscoff on Twitter, GitHub, and Mastodon. Keep up with this blog by subscribing in your favorite news reader.

This content is supported by readers like you.