Aaron Kelly's Blog

FZF

I discovered this program recently, and it’s so good I had to write a post about it

keybinds

The install script adds:

In my zsh shell these weren’t enabled by default, maybe one day I’ll figure out how to enable them.

Killer features

These options are what make fzf great for me

--preview
Opens a preview pane to view the output of the command. The preview pane also supports ANSI colours, so you can use any program that takes full advantage of this (syntax highlighting...)

--multi (-m)
Allows you to select multiple results with `TAB`. Pressing `ENTER` will echo the results back you to your terminal, or optionally, can be passed to a program.

Useful fzf queries

NOTE: more programming-specific queries are in A REPL for shell commands

Note: most of the below queries will by default have the --multi (-m) option enabled.

find and run program (e.g. midi player)

Here you go, a midi player which can easily search through 1000’s of files

fzf --multi --preview 'timidity {}'

find in file (put this in API if it looks useful):

#!/bin/bash

grep --line-buffered --color=never -r "" * | fzf

# with ag - respects .agignore and .gitignore
ag --nobreak --nonumbers --noheading . | fzf

# using ripgrep combined with preview
# find-in-file - usage: fif <searchTerm>
fif() {
  if [ ! "$#" -gt 0 ]; then echo "Need a string to search for!"; return 1; fi
  rg --files-with-matches --no-messages "$1" | fzf --preview "highlight -O ansi -l {} 2> /dev/null | rg --colors 'match:bg:yellow' --ignore-case --pretty --context 10 '$1' || rg --ignore-case --pretty --context 10 '$1' {}"
}

Find file by name and display contents

Find a file by name and display its contents in the preview pane:

fzf --preview 'find . -type f -name {q} | head -100 {}'

Search for file contents (using grep/ripgrep)

The contents of the file will be dispalyed in the search results:

grep --line-buffered --color=never --ignore-case --recursive "" | fzf

Generate a list, mark rows, perform action

This is useful for tasks such as:

Searching bash history, execute command

A good replacement for bash’s history search CTRL+R is the built-in history search that comes with fzf:

You can also create your own!:

history | fzf -m | cut -c 8- | bash

Searching for installed applications and upgrading them

In this example, the results are processed using cut and then saved to a variable:

~ RST=$(apt list --installed | eval "fzf ${FZF_DEFAULT_OPTS} -m --header='search'" | cut -d '/' -f 1)
~ echo $RST
asciinema
baobab

Instead of saving to a variable, you could immediately pass those results to a program:

~ sudo apt install --only-upgrade $(apt list --installed | eval "fzf ${FZF_DEFAULT_OPTS} -m --header='search'" | cut -d '/' -f 1)

WARNING: apt does not have a stable CLI interface. Use with caution in scripts.

Reading package lists... Done
Building dependency tree       
Reading state information... Done
asciinema is already the newest version (2.0.2-1).
baobab is already the newest version (3.30.0-2).
0 upgraded, 0 newly installed, 0 to remove and 7 not upgraded

Instant search (WIKIs, search engines..)

Very handy when you want to get instant results! This uses w3m --dump to format the html page into plain text.

DuckDuckGo:

 : | fzf --multi --preview 'w3m -dump https://duckduckgo.com/\?q\={q}' --preview-window=up:70

Wikipedia - the exact title must match for the article to be found:

: | fzf --multi --preview 'w3m -dump https://en.wikipedia.org/wiki/{q}' --preview-window=up:70

Dark Souls 3 wiki - I remove the first n lines because it’s all boilerplate HTML:

: | fzf --multi --preview 'w3m -dump https://darksouls3.wiki.fextralife.com/{q} | tail -n +344' --preview-window=up:70

Resources

https://github.com/junegunn/fzf#preview-window

Or even better:

man fzf

see also

[[rga (ripgrep-all)]]

A REPL for shell commands

Tools I use daily