Jake McCrary

My favorite clj-refactor features

If you write Clojure using Emacs you should check out clj-refactor. It is working better than ever and makes developing Clojure more enjoyable.

I don’t use all the features in clj-refactor. There are a lot of features I haven’t had the need to use and many I just can’t remember. Below are the features I use consistently.

Favorite Features

My favorite feature of clj-refactor is the magic requires. This feature lets you type a prefix (such as (str/)) and have the namespace automatically added to your ns form (in this example [clojure.string :as str]). It is awesome. You can also add your own prefix mappings.

My other most frequently used refactorings are introduce let, expand let, and move to let. These three are very complementary and are a quick way if introducing named locals.

Add missing libspec is a recent discovery of mine. Have you ever paired with a developer who uses Intellij with Cursive and been a bit jealous of the auto-requiring? I have. This refactoring lets you do that. Type whatever symbol you want and clj-refactor tries to resolve it and then require the containing namespace with correct prefix. Recently I broke a massive namespace into a few smaller ones and this refactoring saved me a ton of time.

I used to use move form when trying to reorganize namespaces but now I pretty much just cut and paste and use add missing libspec to fix the requires. I want to use move form but I haven’t had a ton of success with it. Add missing libspec plus cut and paste is a few more steps but my success rate has been much higher.

Sort ns does exactly what it says, it sorts your ns form. Once you get used to keeping your ns forms sorted you won’t go back.

Extract function is another refactoring I recently stumbled upon. I’ve used it a few times since then and when it works it is pretty awesome. I’ve had unexpected behavior a couple of times but it was unclear if that was my fault or it not handling macros well. If you’re extracting a function you might as well give it a shot.

The final feature is the automatic insertion of namespace declarations when you create a new Clojure file. I nearly forgot to highlight this feature because it requires no action on my side and it is amazing. If I never have to type a namespace symbol again I’ll be happy.

Customization

Below is my entire clj-refactor setup from my Emacs init.el. It doesn’t take much to get it to a state I like.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
(require 'clj-refactor)

;; Add custom magic requires.
(dolist (mapping '(("maps" . "outpace.util.maps")
                   ("seqs" . "outpace.util.seqs")
                   ("times" . "outpace.util.times")
                   ("repl" . "outpace.util.repl")
                   ("time" . "clj-time.core")
                   ("string" . "clojure.string")))
  (add-to-list 'cljr-magic-require-namespaces mapping t))

(setq cljr-favor-prefix-notation nil)

(add-hook 'clojure-mode-hook (lambda ()
                               (clj-refactor-mode 1)
                               (yas/minor-mode 1)
                               (cljr-add-keybindings-with-prefix "C-c C-x")))

If you use Emacs and write Clojure you should check out clj-refactor. There are enough features that consistently work and help keep you in the flow that it is worth using.

Looking forward to the next article? Never miss a post by subscribing using e-mail or RSS. The e-mail newsletter goes out periodically (at most once a month) and includes reviews of books I've been reading and links to stuff I've found interesting.

Comments