Fuzzy search through files in Visual Studio Code

Fuzzy search in Visual Studio Code

In Visual Studio Code, it’s easy to search over all the files in the currently opened folder. But you can make searching over the files more ergonomic and easier to use.

In some ways, I’m going to copy the behavior of the command :RG from Vim plugin junegunn/fzf.vim.

First, I’ll list what I’m after, and then I’ll show you how you can add it to Visual Studio Code.

What I’m after

This is the Find in files in Visual Studio Code:

Find in files in Visual Studio Code

I want to improve on it in several ways.

Fuzzy search

I want to avoid writing complicated regular expressions. I prefer not to write out the full names.

If I’m looking for the function getSelectedAddressFormValues, I should be able to find it with the search term getseladd.

With default Find in files, you better make sure you know your regular expressions because you’re going to need them.

One input field, no need for mouse, shortcuts, or toggles

With Find in files, you have multiple input fields and extra toggles which you need to keep checking and toggling either with a mouse or complicated shortcuts.

I want to have one input field where the search term affects almost everything. See how fzf does it.

Do you want to use the exact match? 'wild
Do you want to use an inverse match? !wild

Everything is part of the search term.

Limiting the files included in the search should be easier

With Find in files, there are at least two ways to limit what files are included in your search, but neither of them is ergonomic:

  • Write out the exact path of the folder, e.g., ./packages/my-package/web-app, to a separate field.
  • Select a folder in the folder list and then run the Find in folder command.

Why do I need to write out the whole path? Why do I have to be precise?
You can use glob syntax. But even then, you have to think about where to put it and how to write it.

Limiting the included files shouldn’t be complicated.

I want to enter the folder/file name right inside the same input field as the search term. And it should support fuzzy matching.

Example

You want to find the word wild inside the folder web-app. The full relative path to the folder web-app is ./packages/web-app.

This is the search term I would like to use:

web-app wild

Or even this should work:

weba wild # fuzzy matching

Complete search history

With Find in files, you can go through previous searches, but Visual Studio Code doesn’t remember the toggles and files to include field.

I want to have access to the same searches I did before, with the toggles and other fields as part of it.

Solution

We’ll create a custom shell command rgf for fuzzy searching. After we select the result, it will open the file in Visual Studio Code on the correct line.

Then we’ll make this command runnable from Visual Studio Code.

This is how the workflow will look like:

Fuzzy searching in Visual Studio Code

Prerequisites

I’ve tested the solution with this setup:

  • Unix system, tested on macOS, I haven’t tested it on Windows, but it could possibly work with some modifications.
  • fzf >= 0.30.0
  • ripgrep >= 13.0.0
  • bat >= 0.20.0
  • Visual Studio Code >= 1.66.2
  • Extension Command Runner
  • Visual Studio Code is runnable from the command line with command code – https://code.visualstudio.com/docs/setup/mac#_launching-from-the-command-line
  • bash >= 5.1.16

Recommended settings for installed software

Save this environment variable. Probably to $HOME/.bashrc, but it depends on your shell and your setup:

# Load search history from the specified file and update the file on completion.
# When enabled, CTRL-N and CTRL-P are remapped to the next history and previous history. User CTRL-H and CTRL-J or arrow keys to select the next and previous result.
export FZF_DEFAULT_OPTS="--history=$HOME/.fzf-history"

Install the script for fuzzy searching

Copy the following script to your clipboard:

#!/usr/bin/env bash

##
# Interactive search.
#
[[ -n $1 ]] && cd "$1" # go to provided folder or noop

export FZF_DEFAULT_COMMAND="rg --column --line-number --no-heading --color=always -- ''"
selected=$(
  fzf \
    --ansi \
    --delimiter : \
    --bind "f12:execute-silent:(code -g $PWD/{1..3})" \
    --preview-window 'up,60%,border-bottom,+{2}+3/3,~3' \
    --preview 'bat -f --highlight-line={2} {1}' | cut -d":" -f1,2,3
)

[[ -n $selected ]] && code -g "$PWD"/"$selected"

Run this in your shell. Don’t try to copy and paste these; otherwise you’ll overwrite the script you have in your clipboard, and it won’t work:

pbpaste > ~/bin/rgf # I have ~/bin in my $PATH. It can differ for you, so change the location accordingly.
chmod +x ~/bin/rgf

It will save the copied script to ~/bin/rgf and make it executable, so we can run it in our shell.

The script combines fzf, rg, bat and code to fuzzy search through your code and to open the result in Visual Studio Code. I’ve written the script based on Using fzf as interactive Ripgrep launcher. If you want a bit more info about what else you can do, check it out.

The main difference is that my script behaves more as the :RG command in junegunn/fzf.vim. Meaning, it uses fzf fuzzy searching right away. It doesn’t pre-filter the results with ripgrep. The script uses ripgrep only to list all lines in the project, with path, filename, and line number.

You can run the new rgf command everywhere, but let’s make it easier to use from Visual Studio Code.

Install fuzzy search command to Visual Studio Code

Add this to your Visual Studio Code settings.json:

"command-runner.commands": {
    "rgf": "rgf; exit"
}

Make sure you don’t have something similar in your settings. In that case, extend it.

After doing this, you can:

  • Press cmd + shift + P.
  • Run Run Command.
  • Select rgf.
  • Now you can fuzzy search. Press enter to open the search result and close the window. Or press F12. This will not close the window, and you can continue with your search.

Add fuzzy search shortcut

Add this to your Visual Studio Code keybindings.json:

{
  "key": "cmd+k .",
  "command": "command-runner.run",
  "args": { "command": "rgf" }
}

After doing this, you can:

  • Press cmd + k, . to start fuzzy searching.
  • Again, press enter to open the search result and close the search window. Or press F12. This will not close the window. Instead, it will open the search result, and you can continue with your search. This way you can open multiple files.

New workflow

After you’ve done all this, this is what you’ll get:

Fuzzy searching in Visual Studio Code