Fish (shell) fun: event handlers

[Tweet]

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
  end
end

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
end

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.