Making Tools

Clojure is a Lisp and those are relatively easy to parse. So maybe we can put together something useful together with relatively low effort?

Over last few years I’ve been experimenting with writing simple development tools that rely on a Clojure parser. There are a number of them available (e.g. Edamame) The parser I’m using I’ve written myself as an exercise to learn Nim. It evolved from a library for reading EDN config files into something that can’t decide whether it wants to be a Clojure or EDN parser (more on that some other time). Once it was feature complete enough to parse the codebase at my job, I could actually start implementing something useful on top of it.

todeftool - a utility to navigate a re-frame project

Goal: give me a way to search & navigate to any re-frame events, subs, effects or coeffects.

We use ClojureScript & re-frame at work. Finding what re-frame events are defined and then quickly opening the right file in the editor became a series of steps: grep, select function name, find where that name is defined (which may not be the same place as the re-frame event/sub/etc definition). This is especially annoying when exploring the codebase. Let’s say you want to find all events having to do something with sending messages (we have to rely on a naming convention here, but in practice it works fine).

Below are the counts of different re-frame definitions in the main app.

Type Count
Events 637
Subs 382
FX 69
CoFX 14

Apart from being able to parse random files, we need to be able to know about Clojure namespaces and how to go from a symbol to its definition. After completing this bit (reframe-tool) I wanted a simple UI (though, I’d like to ultimately feed data to helm in Emacs). I decided on Tcl/Tk, because back then I’ve been reading a book about it and also I was curious how easy it to build small applications in it. While the idea of “everything is a string” is not appealing to me, I judge my limited experience with the language and toolkit positively. The UI bit is just around 200 lines, which I think is just right for what it does. It’s definitely not a “hip” technology and hasn’t been for years, yet some parts of it feel really modern.

A screenshot of todeftool window.
todeftool.tcl window

How everything works: The re-frame tool parses chosen directories and prints all the occurrences of re-frame events, subs, etc to stdout in CSV format. todeftool.tcl can run the re-frame tool by launching a process and reading its output and ultimately feeding it to different tabs in the UI. Search is just a scan and regex match over the stored items and works instantly - no background workers needed (or possible, Tcl is single threaded) for a dataset that small.

I use the tool almost every day. Though a while ago I’ve also implemented the UI part in Swift as a gentle introduction to the language and that’s what I tend to use now (it’s not on github yet).

Further

While I’ve been using the above tools for the last ~3 years, I should mention that emacs-lsp gained similar abilities fairly recently. It allows you to jump to definition of re-frame subs in Emacs (I haven’t checked other editor integration).

I wouldn’t recommend doing exactly what I did if you just want to build a codebase specific tool. Fortunately you don’t have to. There are a few Clojure parsers out there, and countless ways to create a GUI, so just pick the one you’re familiar with.