My long weekend project is (arguably) useful enough to share, so I've published it. It's called
hgrep, and it uses
ghc-exactprint and regular expressions to search Haskell source code from the command line. You can grab it on Hackage or Github.
For navigational search, I tend to lean pretty heavily on
ag. This has all sorts of ramifications - for example, I always format my code such that a declaration
foo can be found by searching for
"^foo ::". When a colleague uses a different style, I'm totally hosed. I'll save you from additional anecdotes; rest assured that string search is not great for huge piles of source code.
We don't need a GHC session to do navigational search across Haskell files. The syntax is really rich and complicated. All we need is an AST!
My project this long weekend,
hgrep, aims to replace
ag in my workflow. Instead of bluntly searching the strings,
ghc-exactprint to parse Haskell source code. Your query is run against that source tree, and the results are printed with surrounding context from the originating file, with optional syntax highlighting.
This means we can explicitly search for definitions, imports, or usage sites.
hgrep is kinda embarrassingly simple: you give it a string and some files, it finds Haskell definitions that precisely match the string. If the terminal supports ANSI escape codes, it runs it through HsColour on the way out. It looks a bit like this:
It's not all that pretty, but it works:
This means it replaces
ag FooBar and
ag "foo ::" for me, which is a pleasant first step. The second step requires a little bit of thought.
I've already been reaching for it all day at work, so I suspect it's useful enough to release as-is. Nevertheless, I plan to make it a lot more useful with filters and regular expressions over the weekend, so stay tuned!
Syntactic search is not necessarily an improvement over fast string-search tools like
rg! There are a number of pros and cons.
Arguably, the current feature set of
hgrep could be implemented with a handful of regular expressions. It wouldn't be as precise, nor would it print as much useful context, but it'd be faster and "good enough."
Here are a few things I'd like to achieve over the next little while:
hgrep foo .shorthand)
Before I do serious work on a fancy set of queries, I'd like to hear from potential users. What would you like to see in a general-purpose tool for Haskell syntactic search?
I'd like to hear about the kind of navigational search you do when working in large Haskell codebases. Please get in touch if you regularly get stuck in the maelstrom of Hoogle and text search. Your feedback will help me figure out how this tool should ultimately function.
This codebase is still pretty small, so it's perfect for newcomers to Haskell or to open source in general. If you're looking for a project to hack on, I've done my best to identify a bunch of low-hanging fruit. All of these should be achievable in an hour or an evening.
If you're interested in diving into one of those issues, I'm willing to provide plenty of help and support! Get in touch.