I use fzf in this very way and could have written this article if I weren’t lazy lol. However, I can add two other use cases:
1. I use i3wm at home (haven’t yet made the jump into Sway/Wayland), and don’t want to change my screen resolution by opening an app, clicking with my mouse, and then waiting. So I use fzf for quick resolution changes using xrandr:
2. At work I switch between multiple Kubernetes contexts during the day. To make the switch fast without typing a sentence, I will use this helper function:
I found this to be better than tab-completion because with tab completion I only get the name of the context, and not the cluster/user/namespace fields that make it easier to select the right one.
Use the above at your own risk, as they are fast hack-ups and could be far more clear (my sed skills are prone to error and overly verbose).
I would highly recommend looking at something like kubectx [0] to manage switching between kubernetes contexts! I've been using this for a while now and have it aliased to kx. It supports tab completion, as well as fzf integration if you have it installed [1]. There's also kubens in there which does the same for namespaces!
Just a heads up that the quotes used in the kc function appear to be "smart quotes" and will likely throw an error if copied verbatim into your shell config
Those are very creative use cases for fzf, I had never considered doing something like that.
My usage of it probably counts as quite basic. That said, I use it constantly. I just love the feeling of real time interaction it gives - it is well and truly part of my muscle memory now.
I use the vim plugin too, which is also brilliant and makes navigating larger projects very quick and easy. I use these two extra bindings all the time:
Yeah, the ability to fake a "show all references to this identifier" via integrated ':Rg' is the greatest feature of FZF I've encountered yet, and makes for a passable substitute of one language-server must-haves.
Hey, sorry that I didn't really try to explain the bindings. Climb_stealth said it all really but here are some extra bits.
The first one is a normal mode binding (the n in nnoremap). yiw copies the word you are currently on (without surrounding spaces), and then <C-r>" pastes that into the :Rg command. The :Rg command is part of the fzf vim plugin and it is a wrapper around ripgrep (see the link from climb_stealth), which gives you fuzzy search over the results of a ripgrep search.
It's basically just how you paste the contents of registers into commands.
The second one is almost exactly the same except that it is a visual mode mapping (the v in vnoremap). If you highlight something with visual mode, then use that command, it will search for the highlighted text using ripgrep.
<C-Space> is just the key chord that the command is bound to. It is a pretty arbitrary personal choice, I find it a very quick and easy chord combination but you can put whatever you want in there. For example, <C-S> would activate the command when you pressed the chord 'control + s'.
There is quite a good list of keys that are unused by vim here:
'yiw' is yank inner word. It basically copies the current word from wherever you are in that word. The pure yank 'y' I presume would just work if you already have something highlighted. It looks like these shortcuts take the current word or current selection and pass it to Rg [0] to be searched for.
I don't have the plugin but it sounds super useful and I'm going to give them a try.
Junegunn, the fzf author, makes great vim plugins too. Both the user experience and the developer experience (the code of these plugins) feel just right.
Fzf is better integrated in vim than in emacs. So I use dmenu on X/wofi on wayland instead, which are basically GUI fzf replacement.
Both fzf and dmenu are "selector menu" utilities, in turn, for terminal and X, but for dmenu, fuzzy search is not its main thing. It has a fuzzy patch though...
I love fzf and tend to use it whenever repeatitive, non-static behavior is in play.
Replacing Ctrl-R with fzf is the most basic and most useful usage.
Basically every git command involving history, branches etc have fzf wrappers in my setup.
My latest, least common usage is having built a wrapper around KeepassX and keepassx-cli to access my secrets from the CLI with fzf to fuzzy search entries. Saves me a lot of time every day.
I mostly use it to open files in vim [0]. The good thing about these aliases is that they keep the command in the shell history. So you open a file with the alias and it will leave a full 'vim path-to-file' in the history.
# Open any file under current dir
vf() {
files="$(fzf --query="$1" --multi --select-1 --exit-0)"
if test -n "$files"; then
echo "${EDITOR:-vim} \"$files\""
print -s "${EDITOR:-vim} \"$files\""
${EDITOR:-vim} "$files"
fi
}
# Open from current modified files in git repository
vfc() {
files="$(git ls-files -m | fzf --multi --select-1 --exit-0)"
if test -n "$files"; then
echo "${EDITOR:-vim} \"$files\""
print -s "${EDITOR:-vim} \"$files\""
${EDITOR:-vim} "$files"
fi
}
I also have a "create feature branch from JIRA issue" (it was in the list of ideas in this post I wrote for the engineering blog at work [1] about autocompleting EC2 instances, although I was already using it). The JIRA API is a bit too slow for fast response, so what I do is populate a text file via a cron job that requests from the API regularly, and use the text in the file for the completion.
Forgot to add that at some point I had a similar autocompleter to the one in the blog above, that would connect to N chosen machines (using the _multiple_ fzf setting), pane them in a tmux session automatically and thus allow you to send the same command to all of them. I only used it twice, but was kind of fun to write.
If anyone is interested in a rust version (probably the main benefit being you can use it as a rust library) there is a similar tool called skim[1]
It's actively developed and seems to have a non-overlapping set of features with fzf other than the basics (they both have features the other doesn't, and skim copies most of the core ui from fzf)
Last I heard, skim's fuzzy search was not "as good as" fzf (I don't know in what measure?)...
And there were talks of how skim could not utilize concurrency as efficiently as fzf and that has something to do with how Rust handles concurrency and how Go does it...
These were just the result of me skimming (ha!) over internet posts so I'd be curious if anyone could elaborate on them...
When I tried skim the list didn't update as "smoothly" as fzf, in response to changing input. No language bias here! (I personally use Rust but not Go) I'd be interested to know more.
1. I use i3wm at home (haven’t yet made the jump into Sway/Wayland), and don’t want to change my screen resolution by opening an app, clicking with my mouse, and then waiting. So I use fzf for quick resolution changes using xrandr:
2. At work I switch between multiple Kubernetes contexts during the day. To make the switch fast without typing a sentence, I will use this helper function: I found this to be better than tab-completion because with tab completion I only get the name of the context, and not the cluster/user/namespace fields that make it easier to select the right one.Use the above at your own risk, as they are fast hack-ups and could be far more clear (my sed skills are prone to error and overly verbose).
—Edited for HN formatting
[0]: https://github.com/ahmetb/kubectx
[1]: https://github.com/ahmetb/kubectx#interactive-mode
Link to Rofi: https://github.com/davatorium/rofi
Examples of how I use rofi:https://adityam.github.io/linux-blog/post/rofi-selectors/
My usage of it probably counts as quite basic. That said, I use it constantly. I just love the feeling of real time interaction it gives - it is well and truly part of my muscle memory now.
I use the vim plugin too, which is also brilliant and makes navigating larger projects very quick and easy. I use these two extra bindings all the time:
They're very simple, but when combined with the ability to add search items to the quickfix list it makes for a pretty powerful workflow.The first one in particular gives a great approximation of symbol search that 'just works' anywhere.
The first one is a normal mode binding (the n in nnoremap). yiw copies the word you are currently on (without surrounding spaces), and then <C-r>" pastes that into the :Rg command. The :Rg command is part of the fzf vim plugin and it is a wrapper around ripgrep (see the link from climb_stealth), which gives you fuzzy search over the results of a ripgrep search.
There is more detail on the <C-r>" command here:
https://vim.fandom.com/wiki/Paste_registers_in_search_or_col....
It's basically just how you paste the contents of registers into commands.
The second one is almost exactly the same except that it is a visual mode mapping (the v in vnoremap). If you highlight something with visual mode, then use that command, it will search for the highlighted text using ripgrep.
<C-Space> is just the key chord that the command is bound to. It is a pretty arbitrary personal choice, I find it a very quick and easy chord combination but you can put whatever you want in there. For example, <C-S> would activate the command when you pressed the chord 'control + s'.
There is quite a good list of keys that are unused by vim here:
https://vim.fandom.com/wiki/Unused_keys
You can pick whatever you want but I prefer not to override any of the default bindings.
Hope that helps!
I don't have the plugin but it sounds super useful and I'm going to give them a try.
[0] Rg being ripgrep, see https://github.com/BurntSushi/ripgrep
Fzf is better integrated in vim than in emacs. So I use dmenu on X/wofi on wayland instead, which are basically GUI fzf replacement.
Replacing Ctrl-R with fzf is the most basic and most useful usage.
Basically every git command involving history, branches etc have fzf wrappers in my setup.
My latest, least common usage is having built a wrapper around KeepassX and keepassx-cli to access my secrets from the CLI with fzf to fuzzy search entries. Saves me a lot of time every day.
Thanks junegunn for theamazimg tool!
The esc-c command is so freaking useful.
(I use this and it works great.)
It's actively developed and seems to have a non-overlapping set of features with fzf other than the basics (they both have features the other doesn't, and skim copies most of the core ui from fzf)
[1] https://github.com/lotabout/skim
And there were talks of how skim could not utilize concurrency as efficiently as fzf and that has something to do with how Rust handles concurrency and how Go does it...
These were just the result of me skimming (ha!) over internet posts so I'd be curious if anyone could elaborate on them...