Sometime ago, I did a post on how I work with Atom to develop Clojure and ClojureScript projects. It is in Portuguese, so I’m gonna re-visit the subject and also update with my current workflow.

There are two packages that I have to install to work with Clojure: lisp-paredit and chlorine. Without lisp-paredit, when I start a newline, the indentation gets all sorts of problematic. I use it on “strict mode” and use the tools to slurp/barf forward only. As for chlorine, it is needed to have autocomplete, evaluation, show documentation, goto var definition and so on. Last, I use also parinfer so I can remove whole lines of text and parinfer will infer the correct closing of parenthesis for me (most of the time at least).

Now, how exactly do I work with Clojure? When you use lein or boot, you’ll get a nREPL port. This is not the port you use with Chlorine, so I need a bit more of work. I can’t just start a REPL with lein repl or clj, I need to inform the tool to open a socket-repl server. The JVM option needed is: '-Dclojure.server.myrepl={:port,5555,:accept,clojure.core.server/repl}'. So, the commands below are what I use with lein or clj:

JAVA_OPTS='-Dclojure.server.myrepl={:port,5555,:accept,clojure.core.server/repl}' lein repl

or

clj -J'-Dclojure.server.myrepl={:port,5555,:accept,clojure.core.server/repl}'

This will open a REPL at port 5555 (or I can change the port if necessary). Then, it’s time to fire up the Atom’s command palette and select “Connect Clojure Socket REPL”, put 5555 on the port, and connect. Then, I’ll use “Refresh Namespaces” or “Load file” command to load my latest version of code into the REPL, and start working.

Now, most of my projects are in ClojureScript, and I find easier to work with Shadow-CLJS, so for now, Chlorine only supports Shadow-CLJS. When I start any compiling process with npx shadow-cljs watch <target>, Chlorine will already detect the port to connect, so no other operations needed. Then, I’ll run “Connect Embedded” and it’ll connect to ClojureScript. Please toggle “Enable experimental features” on Chlorine too – it makes the whole ClojureScript experience WAY better.

While working with ClojureScript, there’s no need for “refresh” or anything: all the time I save some file, shadow-cljs will automatically refresh the code. The catch is that I need to have a Javascript connected all the time – it means that I have to keep the browser on the ClojureScript page opened, or the current node.js code running. Also, I rely a lot on a correct refreshable code, so I tend to work really hard as to be able to save code and automatically have my workflow refreshed (that’s one of the reasons sometimes I have things like {:callback #(@some-function)} on my code: if I always deref a var inside an anonymous function it’ll always get the latest version on the callback, but obviously I remove these on production builds).

Additional tools

To get the most of Chlorine and Clojure, I add some libraries to my tools. If I’m using lein (most of the time I’m working with Clojure I’ll be using it), I’ll add on my profiles.clj file some libraries: compliment, orchard, and tools.namespace. For now, Chlorine only uses compliment and tools.namespace, but I’m doing some tests with Orchard and I think it’ll be the next library to be implemented. Lein, by default, allows you to “inject” additional libraries on your classpath without expliciting adding then to your project by adding then on a file on your home folder, subfolder .lein. So, on Linux, the full path would be ~/.lein/profiles.clj. The format of the file is:

{:user {:dependencies [[compliment &quot;0.4.0-SNAPSHOT&quot;]
                       [org.clojure/tools.namespace &quot;0.2.11&quot;]
                       [cider/orchard &quot;0.5.1&quot;]]}}

This will add support for “full refresh” on Clojure, and for better autocomplete both for Clojure and ClojureScript. In the future, it will also add better support for Clojure documentation, goto var definition, and other issues.

Now, if I’m not working with lein, I’ll probably be working on shadow-cljs for ClojureScript. In this case, I can add on the shadow-cljs.edn of the project I’m working with the compliment dependency, as it’ll only be used on the development (and will never be added on production builds).

I also like to work with Prismatic Schema on my projects. So, for Chlorine to work even better with Prismatic, I add an additional command that can be found on the Chlorine repository on github.

There are people that use REBL with Clojure and Chlorine, with great results. Unfortunately, I still haven’t tried REBL on production-grade code, but it’s a good combination too. As I like vim bindings, I’m also using vim-mode-plus in Atom, so I don’t need “key combinations” (for example, most of my keybindings are “space” then some letter, pressed one after the other, no “CTRL+ALT+something”) and I think this reduces stress over my hands.

Also, I don’t use any tools to colorize parenthesis because I’m color blind ¯\_(ツ)_/¯.