Broot content search

4 minute read Published: 2020-07-26

An example of an efficient search workflow based on broot, a general purpose file manager.

Here's how broot looks when launched on my big code directory with br -s ~/dev (300k files, 22GB):

br-s

I want to look for examples of Option<Option (an option of an option in Rust).

The command for such filtering is c/Option<Option (c/ then the searched string).

Broot lists the matching files in real time, in a tree view helping you get a clear overview, and with a relevant extract in green.

matches

In practice you rarely bother typing the whole searched string, you type just as much as is needed to discriminate what you're looking for.

If I want to know more about a given file, I hit ctrl (after that, I can close it with ctrl) :

matches

Broot now shows me the matching lines in the chosen file.

It's now clear this match is just the blog post I'm typing... not very interesting.

So I hit the tab key to navigate to other matched files. The preview is automatically updated:

matches

The tree lets me see those options of options occur in BurntSushi's regex crate and it's quite obvious (when you've done some Rust) that iterations are the reason of such type.

Another ctrl lets me focus the preview panel and then I navigate among matched lines using and :

matches

Hitting ctrl again dives in the file on the selected line so that I can see the context.

unfiltered

(it confirms the Iterator hypothesis)

I can go back to the list of matched lines with ctrl.

And if I want to open the file in the editor, I type :e (or a space and a e).

The command which is executed on enter is previewed in the status line at the bottom:

matches

and I hit enter to go to my favorite text editor on the relevant line:

nvim

When I quit vim, I'm back to broot.

Composing patterns

It's possible to compose patterns using | (or), & (and), ! (not), and parenthesis.

The most common case is when you want to search on content but only on some kinds of files.

For example, let's see how not to have the md file listed when searching for Option<Option.

To see files whose name ends in "md", this regular expression can be typed in broot: /md$/.

To not see them, you use !/md$/, that is you take the files which don't match the pattern.

To see files matching both patterns, we combine the patterns with &. The composite pattern is thus !/md$/&c/Option</Option.

This pattern is equivalent: c/Option<Option/&!/md$/ but is a little slower as we first look into all files before filtering on their name (the difference speed doesn't usually matter on a SSD).

composite

Another example (quite common for me) is searching for the projects in which I use some crate. I simply look at the occurences of the crate names in Cargo.toml files

As matching files are displayed as fast as I type, I just filter Cargo.toml files with carto:

carto

and I complete the pattern to filter on the files containing the name of the crate:

carto-lazy

To go further, you may want to skim the documentation on patterns)

How fast was it ?

Quite fast. In fact with my SSD there's practically no delay in such a workflow. In my tests on big directories full of git repositories, broot is much faster than grep, ripgrep, ag, etc.

(that was on my machine and in no way a serious benchmark, so let's just remember it's "fast enough")