Back to posts

Binding functions to hotkeys in your ZSH terminal

Using hotkeys in your terminal is a great way to simplify your life, by getting quick access to anything you can program! In this post we'll go over how you can improve your ZSH configuration with your own, custom hotkeys.

Creating your Function

First off, you need to know what you want your hotkey to do, and put that into a function. As an example, let’s make a simple function that takes your edit buffer and reprints it, prefixed by “You typed: “.

function run-example() {
    zle -I
    print "You typed: $BUFFER"
}

First, since we want to output something to the terminal, we need to invalidate the ZLE display using zle -I. Next, we can simply call print (or any other command) with our text. Here $BUFFER contains the entire edit buffer. See also the list of all special widget parameters.

Creating a ZLE Widget

Since we cannot directly bind a function to a hotkey, we first need to create a ZLE (Zsh Line Editor) widget. This is done using the zle command, like so:

zle -N run-example{,}

Here run-example should be replaced by your function name, and this will create a widget with that same name. If you want to create a widget with a different name than your function, you can use:

zle -N widget-name function-name

Binding the Widget to a Key

Now that we have a widget, we can use that to bind it to a hotkey. This is done using the bindkey command:

bindkey '^[OP' run-example

Here run-example should be the name of your widget, and ^[OP is an escape sequence that corresponds to the F1 key. If you don’t know the escape sequence for the key you want to use, don’t worry, there’s a very simple way to figure it out. Simply press ctrl+v in a terminal window, followed by the key (or key combination), and it will print the escape sequence.

And that’s it! If you’ve done it correctly, you should now be able to press your hotkey, and see your function in action. However, you should definitely keep reading for some more useful examples.

Examples

I’ve got quite a few CLI tools centered around improving my understanding of commands, or helping me find the right arguments and flags. The two that I use the most are tldr, and my own explainshell-shell (which I use simply as “explain”). The tldr command gives you some quick start information and examples based on a command name, and explain breaks down a full command and explains each part (with information from explainshell.com). Here are some code snippets that I’m using to bind those commands to hotkeys.

explainshell

function run-explain() {
    if [ -n "$BUFFER" ]
    then
        zle -I
        explain "$BUFFER"
    fi
}
zle -N run-explain{,}
bindkey '^[OQ' run-explain # ^[OQ = F2

tldr

function run-tldr() {
    local cmd
    cmd="$(echo "$BUFFER" | head -n1 | awk '{print $1;}')"
    if [ -n "$cmd" ]
    then
        zle -I
        tldr "$cmd"
    fi
}
zle -N run-tldr{,}
bindkey '^[OR' run-tldr # ^[OR = F3

More Information

The full Zsh Line Editor documentation can be found here: https://zsh.sourceforge.io/Doc/Release/Zsh-Line-Editor.html