Comparing Clojure IDEs — Emacs/Cider vs IDEA/Cursive

IntelliJ/Cursive and Emacs/Cider editors side by side in a family portrait.

Introduction

Recently I edited a blog post in which I interviewed Metosinians regarding their favorite Clojure editors. It was quite interesting to see that there is a diverse group of editors in use. In that blog post, I told myself that I have configured my Emacs/Cider setup to be as close to IDEA/Cursive regarding look-and-feel. Someone in Reddit asked about this and I got an idea that I look at my latest Cursive and Dygma related configurations and check if there is some need for fine-tuning regarding my Emacs setup to make both Cursive and Emacs as similar regarding their look-and-feel as possible — and write a new blog post about this experience. There are a couple of earlier blog posts in which I have touched this topic a bit:

Versions and Repository

I experimented with Cursive and Emacs editors using my latest World Statistics exercise — you can find e.g. the deps.edn (e.g. emacs profile) and Justfile (e.g. commands backend-debug-reveal-kari-port for starting the repl for Cursive, and backend-debug-kari-emacs for starting the repl for Emacs). If you are interested in reading about the World Statistics exercise itself, I have another blog post about that: World Statistics Exercise - I just updated the above mentioned deps.edn and Justfile files for this new blog post.

Emacs and Cider

Emacs is an old editor — the first versions were created in the 1970’s, the GNU Emacs development started in the 1980’s. I started using Emacs back in my studies at the Helsinki University of Technology in the 1990’s — and have been using Emacs ever since. I really like Emacs, though I’m not by any standard an Emacs or eLisp guru. Emacs is implemented using Lisp (Emacs Lisp) which makes it a nice editor for writing Lisp code, e.g. Clojure. Having said that I must emphasize that Emacs is a general-purpose editor, not specifically meant for Lisp programming — you can find a so-called Emacs major mode basically for any programming language. The best way to describe Emacs is that it is an extensible, customizable editor — you can customize it any way you like using the eLisp language. And since eLisp is a Lisp you can add new editing commands while editing. There are also a lot of Emacs packages someone has written for you using the eLisp language — the best way to extend Emacs is first to search a melpa package, and if you can’t find one that suits your needs, only then write one for yourself.

IntelliJ and Cursive

IntelliJ IDEA just turned 20 years old, but I haven’t been using IDEA that long. I have been programming with Java and Python for some 20 years, but I started programming Java / Python with Emacs (with Java and Python major modes), and a few years after that started using Eclipse for Java (and continued using Emacs for Python). I used Eclipse quite a few years but at some point, I started using IntelliJ IDEA for both Java and Python programming — kind of nice to use the same editor with the same look-and-feel for both programming languages, and I have stuck with IntelliJ IDEA ever since, though I still use Emacs for various other programming / editing tasks. (Lately, I have also started using Visual Studio Code, but that’s another story.)

What Is a Clojure REPL?

The REPL is the secret weapon of the Lisp world — a way to interact with the Lisp program under development. Other programmers might say that their favorite language also has a “repl” — it’s nothing compared to a real Lisp REPL — you really need a homoiconic language to implement a real powerful REPL, and Lisp (and Clojure) is a homoiconic language.

Starting the REPLs for the Editors

For Clojure newbies I explain that there are a couple of ways to use the REPL — either start the repl as part of your IDE, or start an external REPL and connect to it from your editor — I’m using this second way.

{:paths ["resources"]
:deps {org.clojure/clojure {:mvn/version "1.10.1"}}
:aliases {
...
:backend {:extra-paths ["src/clj"]
:extra-deps {metosin/ring-http-response {:mvn/version "0.9.1"}
...
nrepl/nrepl {:mvn/version "0.8.2"}
...
;; Emacs Cider specific.
:emacs {:extra-deps {cider/cider-nrepl {:mvn/version "0.25.5"}}}}
# For Cursive
@backend-debug-reveal-kari-port:
# clj -J-Dvlaaad.reveal.prefs="{:theme :light}" -M:dev:test:common:backend:reveal:kari -m nrepl.cmdline --middleware '[com.gfredericks.debug-repl/wrap-debug-repl vlaaad.reveal.nrepl/middleware]' -p 44444 -i -C
clj -M:dev:test:common:backend:reveal:kari -m nrepl.cmdline --middleware '[com.gfredericks.debug-repl/wrap-debug-repl vlaaad.reveal.nrepl/middleware]' -p 44444 -i -C
# Start backend repl with my toolbox for Emacs.
@backend-debug-kari-emacs:
PROFILE=emacs clj -M:dev:test:common:backend:reveal:kari:emacs -m nrepl.cmdline --middleware '[com.gfredericks.debug-repl/wrap-debug-repl vlaaad.reveal.nrepl/middleware cider.nrepl/cider-middleware]' -p 55555 -i -C

Connecting to the REPLs from the Editors

In IDEA / Cursive create a Run/Debug Configuration as in the picture below:

The REPL Output in the Editors

The picture below shows the Cursive REPL output window. It is important to mention here that Clojurians do not write in the REPL. You write in the editor and send the forms for evaluation to the REPL, typically using some hotkey (more about that later). So, in the picture below I have first reset my Integrant state (using a hotkey, of course). Then I have evaluated the forms (e.g. (set! *print-length* 100)) one by one with a dedicated hotkey.

=> {:country_name "Finland", :country_code :FIN, :series-name "Hospital beds (per 1,000 people)", :series-code :SH.MED.BEDS.ZS, :year 2002, :value 7.4, :country-id 246}

Look-And-Feel — the Look

The look is basically the theme of the editor — how colors are used, font ligature, etc.

Look-And-Feel — the Feel

The Feel part is how one navigates in the editor and manipulates S-expressions. Since Clojure is a Lisp and therefore a homoiconic language all expressions are so called S-expressions — S-expressions can be constructed from other S-expressions. That’s why Lisps have a lot of parentheses — but this also makes the language really powerful (macros etc) and nice to edit. There are two major schools related to how to edit Lisp code: the older paredit style and the newer parinfer style. Using paredit you have certain commands that you use to manipulate the S-expressions, e.g. move this S-expression inside the next S-expression, etc. When using parinfer you don’t have to remember any special commands but you achieve the same results by indenting Lisp code.

Hotkeys for Slurping and Barfing

To understand my slurping and barfing hotkeys the reader needs to read my previous blog post Dygma Raise Keyboard Reflections Part 1 first. In that blog post, I explain how I have configured the CapsLock key to function as AltGr key in order to use it to get the various parentheses without twisting my right thumb. Then the reader needs to understand the two layers I have configured in my Dygma Raise. I really recommend Dygma Raise — the best keyboard I have ever used — a perfect keyboard for a programmer.

;; override the default keybindings in paredit
(eval-after-load 'paredit
'(progn
(define-key paredit-mode-map (kbd "C-M-j") nil)
(define-key paredit-mode-map (kbd "C-M-l") nil)
(define-key paredit-mode-map (kbd "C-M-j") 'paredit-backward-slurp-sexp)
(define-key paredit-mode-map (kbd "M-<right>") 'paredit-forward-slurp-sexp)
(define-key paredit-mode-map (kbd "C-M-l") 'paredit-backward-barf-sexp)
(define-key paredit-mode-map (kbd "M-<left>") 'paredit-forward-barf-sexp)
(define-key paredit-mode-map (kbd "C-<right>") 'right-word)
(define-key paredit-mode-map (kbd "C-<left>") 'left-word)
))
...
(eval-after-load 'cider
'(progn
...
(define-key cider-mode-map (kbd "M-l") 'cider-eval-last-sexp)
(define-key cider-mode-map (kbd "M-ö") 'cider-eval-defun-at-point)
(define-key cider-mode-map (kbd "M-n") 'cider-repl-set-ns)
(define-key cider-mode-map (kbd "M-m") 'cider-load-buffer)
(define-key cider-mode-map (kbd "M-{") 'cider-format-buffer)
(define-key cider-mode-map (kbd "M-å") 'cider-test-run-ns-tests)
(define-key cider-mode-map (kbd "M-ä") 'cider-test-run-test)

Conclusions

Both IDEA/Cursive and Emacs/Cider are excellent editors and Clojure integrated development environments. If you want to switch from one to another you can quite easily configure both editors to have pretty much the same look-and-feel.

I’m a Software architect and developer. Currently implementing systems on AWS / GCP / Azure / Docker / Kubernetes using Java, Python, Go and Clojure.

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store