What it does…

As said, fzf is my go to for great shell search and tui’s. Basically add a fuzzy search to everyting you can imagine. But this is not what I want to write about, today I want to show another usecase of fzf in combination with my fish shell.

I start using fzf as a SSH config tui. It allows me to type ssh + space and the basically type any hostname or alias from within my .ssh/config to autocomplete and search using up down. See the recording:


As you see it easy matches the yyy demo entries in my ssh config, 5 of 85 entries (yeah need to tidy up) got found, even I typed far to many yyyyyy the fuzzy search kick in. As soon as I press RETURN key it select it and present me with the correct ssh command ssh yyy1234demo6 which match the host entry in my .ssh/config:

Host yyy1234demo6
     Hostname yyy1234demo6.myserver.demo
     User root

How-to Configure

As mentioned, I use fish Shell. This btw. can also be run easily on Linux and MacOS. It allow you very easy to create custom functions which are a drop in call for certain events / functions in your shell. In this case the function triggers whenever i type ssh*.

To create a function in fish you just drop in a file to .config/fish/functions/ here we go:

# .config/fish/functions/ssh.fish
# Parse SSH config into aligned columns: Alias, HostName, User, Port
# Header is emitted as the first row so column -t aligns it with the data.
# Port 22 is omitted (default, adds noise).
function __ssh_config_hosts
    awk '
        BEGIN { printf "ALIAS\tHOSTNAME\tUSER\tPORT\n" }
        /^Host / {
            if ($2 ~ /[*?]/) { host = ""; next }
            if (host) printf "%s\t%s\t%s\t%s\n", host, (hn ? hn : ""), (user ? user : ""), (port && port != "22" ? port : "")
            host = $2; hn = ""; user = ""; port = ""
        }
        { k = tolower($1)
          if (k == "hostname") hn   = $2
          if (k == "user")     user = $2
          if (k == "port")     port = $2
        }
        END { if (host) printf "%s\t%s\t%s\t%s\n", host, (hn ? hn : ""), (user ? user : ""), (port && port != "22" ? port : "") }
    ' ~/.ssh/config | column -t -s (printf '\t')
end

# Tab completion handler: FZF for ssh/kssh/sshp, normal completion for everything else
function __fzf_complete_ssh
    set -l cmd (commandline -opc)
    set -l token (commandline -ct)

    if test (count $cmd) -ge 1 && contains -- $cmd[1] ssh kssh sshp
        set -l host (__ssh_config_hosts \
            | fzf --height 40% --reverse --query=$token --select-1 --exit-0 \
                  --header-lines=1 \
            | awk '{print $1}')
        if test -n "$host"
            commandline -t -- $host
            commandline -f repaint
        end
        return
    end

    commandline -f complete
end

# Tab triggers FZF for ssh, normal completion for everything else
bind \t __fzf_complete_ssh
# Ctrl+S as an alternative trigger anywhere on the line
bind \cs __fzf_complete_ssh