A warm, fuzzy, file-finding feeling

[Tweet : ADN : nvALT]

I write a lot of scripts. I often want to edit and tweak those scripts. I sometimes forget exactly where a script is in my path, though, so I end up using “subl $(which scriptname)” to do it (yes, I have an alias for that). I didn’t know I needed a smarter, faster way until I built this, but now I’m quite enamored with it.

The idea started as a bash function that ran a series of searches in a sequence designed to find the file I most likely wanted to edit. That worked well, and looked like this:

It required you to get at least part of the string right, though. How annoying.

So I was playing around with fuzzy string matching (again), and found a smart little Ruby gem called Fuzzy File Finder. It’s essentially TextMate/Quicksilver style matching for a directory tree, allowing you to use queries that aren’t contiguous but are in left to right sequence and ranking the results. If you haven’t used this kind of searching before, think of it as typing your initials to match your whole name. Typing “brmc” would match “Black Rebel Motorcycle Club,” but so would “bblmccb.”

I built it into a proof-of-concept script that turned out to be really useful. It’s already become second nature for me after just a couple of days. The script is designed to quickly find a text/source file I want to edit within a group of my standard script directories, but it could easily be modified to handle an array of file searching tasks. The algorithm for Fuzzy Finder itself is portable to more than just filenames, too1. More on that another time.

This script has Fuzzy File Finder built in, so there are no dependencies and it should run on any stock Ruby install. To run it, save the Gist to a folder in your path as editscript and make it executable (chmod a+x editscript).

See the comments at the top of the script for a description, and run editscript -h for options. There are a couple of items to configure at below the top documentation and before the script. It comes set up to search in “~/scripts”, “~/bin” and “/usr/local/bin”, but you can adjust as needed. It searches recursively, so don’t set a root folder as a search directory or you’ll be in for a long wait. Also set up the command for your preferred editor (mvim, vim, mate, subl, etc.) in that section.

editscript: locate a text file by name using fuzzy string matching
Usage: editscript [$options] 'search terms'

Options:
    -s, --show                       Show results without executing
    -n, --no-menu                    No menu interaction. Executes the highest ranked result or, with '-s', returns a plain list of results
    -a, --show-all                   Show all results, otherwise limited to top 10
    --scores                     	 Show match scoring with results
    -c, --command COMMAND            Run an arbitrary command instead of the defined editor
    -d, --debug                      Verbose debugging
    -h, --help                       help

By default it returns up to 10 of the most likely matches for your query as a numbered menu for you to select from. You can tell it to skip the menu and just open the top match with -n. You can also have it return a raw list of matches for use in other scripts using -s. You can prevent truncation of the list to the top 10 items and return all matches using -a.

For verbose debugging use -d (though there are very few messages… one, I think) and use --scores to include the match rankings in the output (both -s and default menu output). You can also run a command in place of the default editor with the -c option.

The script is a Gist on Github. I hope you find it as handy as I have.

  1. I frequently use amatch for text searching, but I wanted to play with some options.

Ryan Irelan has produced a series of shell trick videos based on BrettTerpstra.com posts. Readers can get 10% off using the coupon code TERPSTRA.