Ksh Tricks: Keybinds and Fzf Integration

12 March 2019 ยท 2 minute read

This took way too long to figure out.

ksh93 has a keybinding mechanism, but it’s a bit obscure and there isn’t that many examples to support it. In outline:

  1. Keypresses in the editor trigger the KEYBD trap.
  2. You can check what keys triggered the trap by looking at .sh.edchar.
  3. If you get the key you want, you can run any shell script you want.
  4. And here was the tricky bit, you can replace .sh.edchar with any string.
  5. In this case, I’m passing the text on the current command line .sh.edtext to provide a hint for fzf completion.

The following code remaps Control-t to fzf completion using fd to find candidate files and Control-r to fzf history completion. The function fzf_widgit takes a look at what’s currently on the command line for a hint about whether to list all files or directories. The KEYBD_trap function looks for Control-t or Control-r and launches the appropriate functions.

function fzf_widgit {
    # Hacky, search for directories if the command line starts with cd.
    if [[ $1 =~ "^cd" ]]; then
		fd . --type d | fzf
    else
		fd . | fzf
    fi
}

function fzh_widgit {

    hist -l 1 | fzf +s --tac | sed 's/ *[0-9]*. *//'

}

function KEYBD_trap {
    if [[ ${.sh.edchar} == $'\ct' ]]; then # quote type is important. 
		.sh.edchar=$(fzf_widgit ${.sh.edtext})
    elif [[ ${.sh.edchar} == $'\cr' ]]; then
		.sh.edchar=$(fzh_widgit ${.sh.edtext})
    fi

}
trap KEYBD_trap KEYBD