Emacs is the editor for real folk, and CIDER is one sweet piece of software to program in Clojure, but some would argue that it lacks "big IDE" refactoring tools. This is partly true, but not entirely. Today I gonna show you an easy and cool way to rename all references inside a single function. This can be useful if you want to rename a local variable, or a binding introduced by let.
There are certain tools that allow you to do project-wide replacement too, but they are outside the scope of its post. You should absolutely check @bbatsov's excellent Projectile package for some leads. But let's get back to our original task.
Emacs users are not shy to borrow useful features from other editors.
Popularized in Sublime Text (probably), multiple cursors found their way to
Emacs in Magnar Sveen's multiple-cursors.el package. You can install it by
M-x package-install multiple-cursors. This package provides many
useful tricks, but again for now we only need
Bind it to some key and you are good to go.
The workflow is the following: you are editing a function, you spot a symbol
you want to rename (likely a local variable), you move the cursor to that
symbol and execute
mc/mark-all-like-this-dwim, type the changes, Enter.
Like a baws! In fact this is not specific to Clojure and can be used with any Lisp (or non-Lisp if combined with the next feature).
You'll notice how MC selected only symbols in the same defn-form, and not the outside ones. It is because this function is intelligent, but there exist also cruder tools that operate on the whole buffer. To tame those you'll need another useful mechanic called narrowing.
Narrowing in Emacs allows to focus on a particular region of the buffer like there's nothing else in that buffer. Sounds confusing? Well, it works confusing too, that's why this functionality is disabled by default, so that if you were to trigger it accidentally Emacs would ask you for confirmation. Now that you know what narrowing is you can confidently enable for future sessions.
(defun narrow-or-widen-dwim (p) "If the buffer is narrowed, it widens. Otherwise, it narrows intelligently. Intelligently means: region, subtree, or defun, whichever applies first. With prefix P, don't widen, just narrow even if buffer is already narrowed." (interactive "P") (declare (interactive-only)) (cond ((and (buffer-narrowed-p) (not p)) (widen)) ((region-active-p) (narrow-to-region (region-beginning) (region-end))) ((derived-mode-p 'org-mode) (org-narrow-to-subtree)) (t (narrow-to-defun))))
It is a Do-What-I-Mean command, so it will perform the correct action every time you call it. No need to memorize loads of functions, just bind this one to some key combination and you are set. This single function will narrow to a top-level sexp by default, narrow to region if region is active, and widen if the current text is narrowed. Just splendid.
If you know any other Emacs refactoring tricks, please share them in comments. I know there is a whole project called clj-refactor.el which I'm yet to try. But I wanted to tell about this specific feature because it is simple, seamless and composable. Enjoy your hacking!