Searching for Silver Bullets

Jon Kinney

Searching across a project's codebase for keywords is a pretty standard requirement when starting something new. Recently I inherited a very large Rails app with 238 models and 348 controllers. That is to say nothing of the number of view and JavaScript files as well as service objects, presenters, etc. It was pretty clear that I was going to have to find a way to explore certain parts of the code by looking for what I was working on that day in isolation.

Lots of editors have this capability built in including: RubyMine, Sublime Text, Atom, and Textmate, but at Headway we use console Vim inside of Tmux for the majority of our development, and project-wide search isn't provided out of the box. This led me to try several different "grep like" tools over the years, including just plain grep. However, with thousands of files to search through, I needed speed. For many years I was happily served by a tool called Ack, which bills itself as a much faster grep replacement. But even with all the improvements over vanilla grep that Ack made, it was still too slow for my needs. Enter The Silver Searcher, or "Ag" as it's known.

Ag starts out claiming that "it is an order of magnitude faster than ack". A bold statement to be sure, but I can say with certainty that it is indeed worth the upgrade.

Installing Ag

To install Ag, use homebrew: brew install the_silver_searcher. For other platforms, see the readme.

Configuring Ag To Ignore Directories

Without any configuration, Ag will search through all the files in a directory except for those matched by ignore patterns specified in the project's .gitignore or .hgignore or .agignore files. You can also create a ~/.agignore file at the root of your home directory for global use.

Ignoring some directories in a Rails app like /public/system and /coverage that aren't typically found in the .gitignore, can have a dramatic impact on the speed at which results are returned from Ag. Without a tuned .agignore, in the project I mentioned earlier, Ag would take 15 seconds to return results. With a tuned .agignore file though, I was able to get results back in under a second! Ack or grep were unusable and just locked up my machine.

The .agignore pattern is really straightforward. You simply list the folders or files you want to ignore by name like so:

/cache/
/HTML_DEMOS/
/log/
/db/migrate/
/public/demos/
/public/system/
/public/images/
/public/html/
/production_data/
/cookbooks/
/vim_sessions/
/coverage/
/tmp/
/compiled/
/gems/
/.idea/
*.idea
tags
.zenflow-log
/app/assets/fonts
/app/assets/html
/app/assets/images

Performing Advanced Searches

One of the tasks that I needed to perform involved deleting a whole workflow from the app. This meant that while I wanted to delete code that included text like "news" I didn't want to include text like "newsignword". In order to find only items that stopped after the four characters "news" I needed to use a negative lookahead regex.

Ag uses Perl-Compatible Regular Expression (PCRE) syntax, which I wasn't overly familiar with, so here are a few sites that I used to help test my regex:

I ended up with this:

news(?!ignword|tyle)

This would search for the string "news" but omit results that would include "ignword" or "tyle" immediately following "news". So while all the "news" hits showed up, I was able to filter out tens of hits for "newsignword" and "newStyle".

Wrap up

Next time you need to get up to speed quickly on a new codebase, give Ag a shot! Coupled with other tools like ctags, and rails.vim, Vim is a great IDE for Ruby on Rails development! Also, check out the cool things happening in the neovim space!


SIGN UP FOR OUR NEWSLETTER

The Weekly Manifest

Receive the latest design, development, and startup articles to stay updated!

Close

Inquiry Sent!

Thanks so much for your interest in working with us, and for your time to fill out the form. We're passionate about what we do and would love the opportunity to create a successful solution for you.

Expect to hear back from us within the next 3 business days.

Work With Us

We can take on any type of project, but we don’t work with everyone. We only partner with clients that align with our business values, honestly benefit from our expertise, and embrace the systems we build in.

Fill out the form below to start a conversation see if you’re the right fit for us.

What type of project would you like to partner with us on?