Hooking Up fzf with zsh Tab Complete and Filtering Related History
We'll go over a plugin to make it easier to filter tab complete results and find commands related to a specific command.
This post expects you have fzf installed and are familiar with what it does at a basic level. Since 2018 I’ve been writing about using fzf to reverse search history, open files and preview files in case you want a primer:
Here’s 2 new things since those posts that’s fzf related, one is very related to fzf and other is not but it’s still tied into your zsh history.
# Using fzf to Power zsh’s Tab Complete
With zsh when you hit tab to complete things it will pop up its own completion
menu. This can be handy to find directories with cd
or flags for specific
commands. Basically whenever there’s a situation where you can pick more than 1
item.
For example if you open a prompt and type la -
then hit tab it’ll show you a
bunch of flags. Likewise you can type cd
and hit tab to choose from a list
of directories.
We can take that 1 step further with https://github.com/Aloxaf/fzf-tab which
uses fzf to power that complete menu. It even supports showing you a preview of
what’s in a directory when using cd
’s tab complete which comes in handy.
I’ve added it to my dotfiles in this commit. There’s not a whole lot to mention here since that commit shows how to install it and configure a few basic things. You’re probably wondering what it looks like and how it works, the demo video shows that.
# Filtering Related History
By default you can press ctrl+p/n
to cycle between previous and next items
in your history. This would be similar to hitting the up and down arrow keys.
But check this out, you can add these bindings to your .zshrc
file:
bindkey "^p" history-search-backward
bindkey "^n" history-search-forward
# Up and down arrow key support for most terminal emulators.
bindkey "^[OA" history-search-backward
bindkey "^[OB" history-search-forward
bindkey "^[[A" history-search-backward
bindkey "^[[B" history-search-forward
After sourcing in your changes you can type something like ls
and then
ctrl+p/n
or curl
and then ctrl+p/n
. In both cases or any case, you will
only be shown history related to that specific command. If you added the arrow
key binds then they will work the same.
Think of it as a more focused way to cycle through your history.
By default those key binds are mapped to different actions such as
down-line-or-history
and up-line-or-history
which don’t let you filter
results by a command (bindkey -L
shows your current binds). The mappings we
set give us the best of both worlds. Use case 1 is cycling your history and use
case 2 is doing the same for a specific command.
You might be thinking “yeah but why not just use ctrl+r
and filter that with
fzf”? Absolutely, I almost always use fzf to reverse search my history but
sometimes the above is quicker if I know there’s a few variants of a specific
command I recently ran.
Technically you can use fzf for this use case too if you prepend your searches
with ^
such as ^curl
. Now it will only show your history starting with curl
instead of other things in your history which happen to match letters of that
word.
I’ve been using fzf for 8+ years and I only started to do this recently but it’s helpful.
The video below demos what’s been covered above.
# Demo Video
Timestamps
- 0:20 – A quick demo
- 1:38 – What zsh does without fzf integration
- 2:21 – Installing the fzf-tab plugin
- 3:50 – Configuring the plugin
- 5:36 – Previewing the tmux pop out feature
- 7:59 – zsh bindings for filtered history results
- 10:18 – Going over the bindings
Are you going to be using these methods? Let me know below.