Dynamic fish abbreviations — Is it possible?

Stefan Hoffmann
<pretty/code>
Published in
2 min readAug 26, 2016

On my projects with an issue tracker I always use feature branches that include the issue number. E.g. for the issue with the number “123” and title “Login Page” I would create a new feature branch named “123-login-page”. And every commit in this branch is prefixed by this issue number:

#<issue no>: <commit message>

I use the fish shell and while playing around with fish abbreviations I realized this could be automated.

For “git commit” I had already configured this abbreviation:

set fish_user_abbreviations "gcm=git commit --message"

In Fish, the abbreviations have to be stored in a variable at startup, therefore they are static. So it is not possible to simply call a function here that inserts the issue number into the expanded part.

Fish has some interesting options on the function command, that caught my attention while trying to find a way to get around this problem:

With “ — on-variable PWD” the function will run on every change of the working directory. Using this option we can build a function that replaces the abbreviation when a git repository is entered to add the issue number of the current branch:

set fish_user_abbreviations "gci=git checkout --message \"#1:"function __set_gci_abbr --on-variable PWD
# Check if we are in a git repository
if command git rev-parse --is-inside-work-tree >/dev/null 2>&1
set base_command "gci=git commit --message \"#"
set issue (git rev-parse --abbrev-ref HEAD | grep -Eo '^\d+')
set new_command $base_command$issue":"
# Replace the old command with the new one and overwrite the abbreviations
set new (string replace -r "$base_command.*:" $new_command $fish_user_abbreviations)
set fish_user_abbreviations $new
end
end

To also change the abbreviation when switching the git branch we can use the “ — on-event fish_postexec” option of the function command, which will execute the function after any command has been executed:

function __postexec --on-event fish_postexec
# was the command "git checkout"?
if command echo $argv | grep '^git checkout' >/dev/null 2>&1
__set_gci_abbr
end
end

That’s it! Now I can type “gci” (git commit issue) inside the feature branch and it will expand to:

git commit --message “#123:

This is a fishy 😉 solution to the problem at hand, nonetheless it was an interesting task that improved my knowledge of fish internals.

I’ve found a proposal on the Github page of Fish which would just fit perfectly to this usecase: add a new “ — abbreviates” option to the function command to make functions behave like abbreviations.

--

--