fzf, vi-mode, and fixing delays

Half the fun of installing a new tool is fixing the issues that arise from doing so.

I recently installed fzf, which is a command-line tool for fuzzy-searching command history and files. The fzf commands are bound to keys, the main ones being ctrl-r to search history (replacing the built-in history search) and ctrl-t to search for files in the subdirectories of the current working directory. I love the tool, the only problem was that there was a very noticeable delay between pressing the key binding and the fzf action actually happening. I knew that this was not fzf's fault, because the person who told me about the tool was able to use it with no problem. I set out to fix the issue.

My first thought was that tmux was somehow causing the issue. However, I tried running fzf in a plain terminal outside of a tmux session, and still had the same problem. Continuing my search, I took a look at the fzf bash key binding script. I scrolled down to the key bindings that apply when bash is in vi mode (my mode of choice, as opposed to emacs mode). The fzf bindings both involved the escape sequence (\e) multiple times, since that key is used to enter vi-movement-mode by default. After fiddling around with the bindings, I determined that the escapes were indeed the culprit, but I did not yet know exactly why.

I figured that either tmux or bash itself was inserting a delay between pressing the escape key and the escape sequence actually being acted upon. Searching around a bit, I found an option for tmux to not wait after pressing escape. To activate it, I put the following in my .tmux.conf file: set -sg escape-time 0. Unfortunately, this did not fix the delay issue with fzf. Bash itself became the prime suspect.

Much like vim, if a key is at the start of multiple bash key bindings, bash will wait for a certain amount of time after that key is pressed for another key to be pressed, which could potentially complete a binding. If another key is not pressed within the delay time, the key press will go through normally. I checked my current bash key bindings by running bind -p | grep -F "\e". As suspected, there were many key bindings beginning with "\e", and thus causing escape to have a delay when pressed alone.

My solution to this was fairly simple. I simply picked a key binding that I wasn't currently using, ctrl-a, and mapped it to also enter vi-movement-mode. I then went back into the fzf key bindings file and changed the "\e"'s to "\C-a"'s. No more delay!