# Using FZF to Improve Productivity

--

By Akash Khan

Consider the following problem.

Given an array of strings find all strings that match a given pattern. For example consider the input array to be `['apple', 'ball', 'cat', 'doll']` and the pattern to be `al`.
Looking at the array we can see that `ball` is the only string that matches the pattern exactly and it's not very difficult to implement an algorithm to detect this. However a much more interesting version of the problem is when we remove the restriction that the characters in the pattern should appear together. In the above example it would mean that our algorithm would need to output `['apple' , 'ball']`.
This is known as fuzzy matching. It is part of a larger group of problems known as Approximate String Matching

FZF is a commandline fuzzy finder which solves the above problem . It reads the list from `STDIN` and writes the result to `STDOUT`. What makes it special though is that it is extremely fast and extensible. Combined with Unix pipelines we can create some very useful functions.

# Setting up and basic usage

Check out the github page for installation instructions. It’s available for every major platform and can be setup very easily. Once done you should have the `fzf` executable added.
Using `fzf` is very easy. All the commands I will be talking about follow the same structure .

1. First you have the input command which generates the input list .
2. Second you pass this list to the `fzf` executable using `|` operator and `fzf` will generate the UI for pattern matching.
3. Once the user inputs the pattern `fzf` will pass the results to `STDOUT` and we can use the `|` operator again to use these results.

In general

`command 1 {options} | command 2 ... | fzf {options} | command n | command n+1 ...`

For example

Since fzf is built to be extensible, it works very well with other unix commands and by composing different commands we can create powerful interfaces. I have listed a few which I’ve been using below:

• Navigating directories ( Replacing `cd` )
`sh function fd() {   local dir dir=\$(find \${1:-.} -path ‘*/\.*’ -prune \ -o -type d -print 2> /dev/null | fzf +m) && cd “\$dir” }function fdr() {  local declare dirs=()  ## Recursively fetch parent directories  get_parent_dirs() {    if [[ -d "\${1}" ]]; then dirs+=("\$1"); else return; fi    if [[ "\${1}" == '/' ]]; then      for _dir in "\${dirs[@]}"; do echo \$_dir; done    else      get_parent_dirs \$(dirname "\$1")    fi  }  local DIR=\$(get_parent_dirs \$(realpath "\$PWD") | fzf +m)  cd "\$DIR"}`
• Killing processes
`fkill() {  local pid  pid=\$(ps -ef | sed 1d | fzf -m | awk '{print \$2}')  if [ "x\$pid" != "x" ]  then    echo \$pid | xargs kill -9  fi}`
• Searching git commits
`function gitlog() {  ## git log -> fzf -> extract commit SHA -> git show  git log --graph --color=always \      --format="%C(auto)%h%d %s %C(black)%C(bold)%cr" "\$@" |  fzf --ansi --no-sort --reverse --tiebreak=index --toggle-sort=\` \      --bind "ctrl-m:execute:                echo '{}' | grep -o '[a-f0-9]\{7\}' | head -1 |                xargs -I % sh -c 'git show --color=always % | less -R'"}`

If you are a Vim/Neovim user like me, you would be glad to know that FZF also comes with a built-in integration for Vim which can be used to navigate through your code base!

# Conclusion

The above scripts are just a small subset of the things we can do with `fzf`. By composing different commands, we can create very powerful interfaces which can help save time. The FZF Wiki page contains some very good documentation and examples for getting started.