Two years ago I was feeling some pain. I was trying to find a particular helper method in one of our applications, and full-text search across an entire project was not easy to do, by default. I was using TextMate at the time, which has a full-project search feature, but unless you took the time to actually configure your project just right, it would search everything (log files, Rails, etc) and that was painful. Furthermore, I was at the command-line a lot, and it wasn’t very fun to have to switch back to TextMate just to search the project.

What I typically did was just issue a suitably arcane Unix command via the command-line:

grep "def some_helper_function" app/helpers/*.rb

That’s not too bad, really, though it gets tedious when you do it often. What’s worse is when you want to find everywhere in your project that you reference that method:

find app lib -name '*.rb' \
  -o -name '*.rhtml' \
  -o -name '*.rjs' \
  -o -name '*.rxml' | \
  xargs grep some_helper_function

That’s where the pain begins to feel crippling.

So, about that time I created a utility script, called (unimaginatively) “find”, which essentially was a thin wrapper around find+xargs+grep. Instead of the above, it let me simply say:

script/find some_helper_function

However, I could scope the search, too, for narrower (and thus faster) searches:

script/find helper "def some_helper_function"

It turned out to be so handy that we’ve since copied it to nearly all of our projects. For two years I’ve relied on this script, to the point that when I started a new (personal) project this last week, I really felt the lack.

So I got permission from David to release it as a Rails plugin. I rewrote it a bit so it doesn’t rely on find, xargs, or grep (so it can be used on more than just Unix platforms), added some simple documentation, and posted it on GitHub.

Behold: the ProjectSearch plugin for Rails.

And if you happen to be a fellow Vimmer, you might find this vim script handy, which uses script/find to search in your project:

function! RailsScriptSearch(args)
  let l:savegrepprg = &grepprg
  let l:savegrepformat = &grepformat

  try
    set grepprg=script/find
    set grepformat=%f:%l:%m

    execute "grep " . a:args
  finally
    execute "set grepformat=" . l:savegrepformat
    execute "set grepprg=" . l:savegrepprg
  endtry
endfunction

" search with explicitly provided arguments
command! -n=? Rgrep :call RailsScriptSearch('<args>')

" search for the word under the cursor
map <leader>rg :silent call RailsScriptSearch(expand("<cword>"))<CR>:cc<CR>

" search for the method definition of the word under the cursor
map <leader>rd :silent call RailsScriptSearch(expand("'def .*<cword>'"))<CR>:cc<CR>

Enjoy!