Simple Emacs configuration for Clojure development
Tags: emacs, clojure, ide
Published: 2020-03-03 13:37:23

I suppose that most programmers have, together with their preferred IDE (such as [Intellij IDEA](https://www.jetbrains.com/idea/), [Eclipse](https://www.eclipse.org/eclipseide/) and [Visual Studio](https://visualstudio.microsoft.com/)), a lighter code editor for smaller coding tasks. I remember using [Notepad++](https://notepad-plus-plus.org/downloads/), changing to [Sublime Text](https://www.sublimetext.com/) at some point, than more recently to [Visual Studio Code](https://code.visualstudio.com/). My current "light" editor of choice is [Emacs](https://www.gnu.org/s/emacs/).

The main reason for choosing Emacs is that I wanted a great coding experience when developing in [Clojure](https://clojure.org/). I tried to use Intellij IDEA with [Cursive](https://cursive-ide.com/) but even though I am familiar with the IDE (I use it daily to write Java and Kotlin code), it doesn't feel right with Clojure, a heavy weight tool with a slim language... So I resorted to simpler code editors, but never found a setup that was appealing.

I don't think we can say that Emacs is "light" or "simple". It can be a beast... I tried many times to learn it but the learning curve can be discouraging. Only recently I read a post where the author gave a suggestion that is helping me learn Emacs step by step: [`M-x`](https://www.gnu.org/software/emacs/manual/html_node/emacs/M_002dx.html) is your friend. :-) Learn a few basic keybindings and start using the editor, use `M-x` for actions you don't know the binding. With time you'll memorize bindings for actions that you repeteadly use.

That tip took care of the anxiety I had when using Emacs without knowing my way around it! Time to setup my Clojure development environment and start writing some serious code! Or not... Emacs is a black hole of packages, options, ways of organizing your configuration.

To simplify things I used the configuration suggested on the book [Clojure for the Brave and True](https://www.braveclojure.com/basic-emacs/) and tried [Spacemacs](https://www.spacemacs.org/) with the [Clojure layer](https://www.spacemacs.org/layers/+lang/clojure/README.html). The problem is that I am the kind of guy that wants to know **why** things work the way they work, I wanted to be able to replicate parts of these setups and understand them.

After a lot of trials, errors and frustrations I finally came up with a initial setup that I am happy with! I think it is good enough for my taste and a small starting point for further customization, and that is why I decided to share it. [Check out this gist](https://gist.github.com/matheusemm/d3b216a0369c3af6f4d83549276bacb1/5706bf75f52e3d37d521d3b6eaddeafbf091bd2c)!

A quick overview of what this configuration does:
1. Adds [Melpa](https://melpa.org/) as an additional packages source.
1. Sets [Dank Mono](https://dank.sh/) as default font. Change the `:family` attribute to your preferred font.
1. Installs [zenburn theme](https://github.com/bbatsov/zenburn-emacs), super nice.
1. Installs [undo-tree](http://www.dr-qubit.org/undo-tree.html), a package that gives visual clues of your changes history. Reading the docs I discovered that Emacs has a very powerful redo/undo system and undo-tree makes full use of it.
1. Installs [ivy](https://github.com/abo-abo/swiper), a completion system. I opted for ivy because it is cider and other packages recommend it.
1. Installs [smex](https://github.com/nonsequitur/smex), a package that improves the use of `M-x`.
1. Installs [projectile](https://github.com/bbatsov/projectile) to help navigate between files in a project.
1. Installs [magit](https://magit.vc/) for Git interaction. You'll be able to do a lot with only two keybindings!
1. Installs [exec-path-from-shell](https://github.com/purcell/exec-path-from-shell), that is used to set Emacs path from your shell's path (I use it because my current OS is MacOS, I think it is not required for Windows).
1. Installs [flycheck](https://www.flycheck.org/) and [flycheck-clj-kondo](https://github.com/borkdude/flycheck-clj-kondo). Flycheck-clj-kondo is a nice linting and analysis tool for Clojure, highly recommended.
1. Installs [company-mode](https://company-mode.github.io/), a package that is used for code completion.
1. Installs [clojure-mode](https://github.com/clojure-emacs/clojure-mode), [cider](https://github.com/clojure-emacs/cider) and [clj-refactor](https://github.com/clojure-emacs/clj-refactor.el), the main packages for Clojure development.
1. Installs [which-key](https://github.com/justbur/emacs-which-key). This makes using `M-x` much easier because it presents "next keys" options based on a prefix keybinding. E.g. You press `C-c` and it shows further keys that can complete the keybinding. Super nice!
1. Performs other simple configurations (under `editing`, `ui` and `misc`). These came mainly from the Clojure from the Brave and True setup.

I recommend that you take some time and read at least a bit of each package's documentation. You'll better understand not only the configuration file but the **capabilities** that each tool provide. Let me know if this configuration is useful for you and if you have any suggestions on how to improve it.

Godspeed.

<small>Cover photo by [Ussama Azam](https://unsplash.com/@ussamaazam?utm_source=unsplash&utm_medium=referral&utm_content=creditCopyText) on [Unsplash](https://unsplash.com/@ussamaazam?utm_source=unsplash&utm_medium=referral&utm_content=creditCopyText).</small>