>Am I missing something?

Yes, the article misses what fzf actually is by focusing too much on the shell integrations. I hardly ever use those features, except for fzf-tab (which partially subsumes them).

Fundamentally, fzf is a well-behaved UNIX tool for choosing things. It does one thing well (choosing things), it communicates by simple text streams on stdin and stdout, and it integrates seamlessly with other text-based programs.

It's like an interactive, human-friendly version of grep that narrows down the possibilities on every keypress. You pass any newline-separated text to its stdin, and it will let you choose from among them. Whatever you choose will get written to stdout. This can be a single choice or multiple choices. You can customize the layout and even run arbitrary scripts when each option is selected (not chosen) to show a preview.

Once you recognize it, "choosing things" shows up everywhere, so fzf can accelerate any terminal-based workflow. Examples of what I use it for:

- what unit tests to run

- what git branch/commit to check out

- what process to kill

- what wifi to connect to

- what todo list items to check off

- find an emoji and put it on the clipboard

- you're leaving your laptop and you want to choose among shutdown/restart/suspend/logout/lockscreen

- what files or options to pass into an arbitrary command (using fzf-tab)

Basically anything that, if it were in a GUI, would be shown as radio buttons or checkboxes or a dropdown menu.

You can use it in scripts/aliases, or you can just write a quick fzf command inline. I use it for so many things, it's hard to even recall them. It's part of my muscle memory now. Check the wiki on the fzf github, there are all kinds of examples. e.g. here's the one I use for killing processes[2].

An example from recently where I used it "inline": I was in the middle of debugging something in a Python project. I needed to temporarily remove a bunch of packages from the virtual envirnoment, but not all of them, to narrow down where the problem was coming from. After 20 seconds of trial and error (I forgot the syntax for tail) I had:

pip uninstall $(pip list | tail -n+3 | cut -d' ' -f1 | fzf -m)

This let me multi-select from the list of installed packages and uninstall them. Go down the list, boom-boom-boom, done. Pressing enter would uninstall my choices right away. Pressing tab would first expand the $() and replace it with the stdout of the pipeline inside, so the text after the prompt would become `pip uninstall requests numpy pandas ...` or whatever I chose, without running the `pip uninstall` part until I pressed enter. I tend to do the tab-expand trick a lot with multi-selections or with dangerous commands like rm, so I can double-check the full thing first before running it.

NB: in that pip example, the "fuzzy" part wasn't even relevant. All I did was use the up- and down- arrows to navigate the list .. there were only a few dozen entries so I didn't need the fuzzy-search. In fact, in most of my scripts I actually turn off the fuzzy matching and use the --exact flag, so that it just searches for exact substrings, whitespace-separated, order ignored. I find this makes its behaviour more predictable. e.g. if I want to find a pyproject.toml file from among all my files, in --exact mode I can just type "pypro" and it will show like

~/repos/foo/pyproject.toml
~/repos/bar/pyproject.toml
~/old-stuff/scripts/pyproject.toml
...

then I type "bar" to narrow it to the one in the "bar" repository, so my query is just "pypro bar". But unlike fuzzy mode, it doesn't show entries that just happen to have "b", "a", and "r" somewhere in the string, like something named

~/repos/big-archives/pyproject.toml
^ ^^

I have to type slightly more than I would with fuzzy-mode, but the lack of bad search results more than makes up for it.

This is what I mean when I say the core of fzf is "choosing things". It's not really about fuzzy-searching, despite the name.

[1] https://github.com/lincheney/fzf-tab-completion

[2] https://github.com/junegunn/fzf/wiki/Examples#processes