I read people who mention using emacs to develop Clojure but without using Cider. Now, I love Cider, but the updates are killing me. Be that as it may, how is it even possible to have a REPL-driven workflow in emacs without cider?
Good question. I know inf-clojure has some adherents. I think GitHub - volrath/spiral: Emacs Clojure IDE based on UNREPL is mostly experimental?
How so, are you seeing breakage or new bugs?
And are you installing from melpa-stable? Or the more frothy melpa?
I use Straight, so often I am getting them from the git repo directly. I did this with Cider, just pulling the latest.
I just fired up one of my primary projects, for which I am trying for a soon deploying, and cider wouldn’t start at all because of some missing compatibility code. Even trying to run the evaluate the source code gave similar errors about missing things. Eventually I restarted my computer – which is not a cheap thing as it loses browser settings, emacs registers, etc – and now it is working again. This worked this particular time, and then I had to resolve nrepl-version mismatch warnings. It wasn’t necessarily awful this time, but the trouble is that I lose time on errors like these every few months.
It sounds like you should switch to using only stable releases from melpa-stable, then.
I highly recommend setting up your editor to avoid automatic CIDER updates, or limiting them to melpa-stable.
Great advice. I will be extra careful with this in the future. My latest issue with another primary project is detailed here: Cider error: cider-get-ns-name: Wrong number of arguments | Tech.ToryAnderson.com . tldr: I upgraded cider, then upgraded nrepl, then downgraded cider, then removed CLJ-refactor. It was all broken until I was reminded that I need to upgrade my clojure-mode version, which I had forgotten existed. Then it all worked – 4 package actions later.
It was this sort of fragility that was the final nail in the coffin for using Emacs for me. I’d used it on and off since the 17.x days a long time ago, but when I was using it for Clojure I could never find a stable configuration that I liked enough for day-to-day use for any length of time… I tried a lot of people’s curated Emacs setups (including Prelude) and just found I was wasting so much time on the “care’n’feeding” that Emacs/CIDER seemed to need
So I tried a lot of other editors and went back and forth between them and Emacs for years, and finally settled on Atom (with Chlorine – so no nREPL/CIDER stuff), then VS Code (with Clover – so no nREPL/CIDER stuff either – but finally I switched to Calva, which meant nREPL/CIDER again… but it seems to be a lot more stable in that context).
I’ve been using Doom (and before that Spacemacs), and haven’t really had any issues with Cider, that I can remember. Probably using the latest HEAD directly is not the best strategy, unless you’re working on Cider itself.
I don’t think think Emacs and CIDER need “care’n’feeding”. I’ve been using CIDER for more than 8 years now (I think?). I think I’ve seen things break twice — I don’t even remember the first time, but the last one was recently with changes in how formatting is handled that affected me. I can deal with breakage once every 4 years.
I think the key is to use melpa-stable, rather than bleeding-edge setups.
I love CIDER and respect the work of the maintainers. Nevertheless, the fact that we’re all saying “yeah, the default way you install packages will occasionally break your IDE; here’s the workaround” is actually rather bad.
It’s a broken stair: lots and lots of Clojure devs who are new to emacs fall down this hole at least once. After all, the installation instructions barely mention melpa-stable, and encourage people to track the master branch. It’s unfortunate that we booby-trap Clojure-in-Emacs for newcomers in this way. I wish the docs were changed something like this closed PR.
At the very least, it’s worth noting the cultural distance between Clojure’s “stability is our top priority; breaking changes are the devil’s work” and CIDER’s “from time to time you might run into some…epic mistakes”.
Just to clarify, that is not at all what I said. In fact, I said quite the opposite — if you stick to the stable repository (MELPA-stable), you will be fine. But it seems the documentation says something different — I thought the “default way” is to use the stable releases.
I have an article on Vanilla ClojureScript and has a section on live-reloading code without any additional tooling (no cider, no figwheel, no shadow-cljs). Reloading code in vanilla JVM Clojure is a similar story. If you know how to change NS and recompile a form, you can pretty much do anything REPL-driven without additional tooling, as long as you are willing to type in the REPL directly.
I sometimes fallback this workflow when needed, but I still prefer my Emacs and cider workflow
I don’t use CIDER
My setup is based on Monroe GitHub - sanel/monroe: Clojure nREPL client for Emacs and a couple of REPL helper functions that I wrote. I’ve been working like this for good 3 or 4 years now.
My Clojure.el: https://github.com/lukaszkorecki/command-center/blob/master/settings/lk/clojure.el
My REPL helpers: GitHub - lukaszkorecki/rumble: Clojure REPL helpers
Also, LSP via Eglot for the usual stuff (navigation, renaming etc)
I don’t feel that there is as complete an alternative to CIDER for Repl based development with Emacs.
GitHub - clojure-emacs/inf-clojure: Basic interaction with a Clojure subprocess states it provides a basic repl interaction and can be a good approach if many of the CIDER features are not required
GitHub - sanel/monroe: Clojure nREPL client for Emacs describes itself as an nRepl client for Emacs and states it is not trying to be an alternative to CIDER. Again this could be a viable approach if needs are relatively simple or if other tools are used in conjunction with Emacs.
If you wish to have a large number of Repl and Clojure IDE features from an Emacs package, then CIDER is the most appropriate option.
Tools such as Clojure LSP, Portal and flowstorm have overlap with some of the features that CIDER provides as well as their own features. So inf-clojure or monroe could be coupled with these tools to provide a more comparable experience to using CIDER with Emacs.
I’ve rarely had an issue with Cider for Clojure development over the last decade, despite how many changes there have been with the tools used to start and manage a repl and the impact of introducing Clojure LSP (which has significant overlap with Cider and clj-refactor).
I’ve predominantly use Spacemacs community config which installs Cider from MELPA (builds from GitHub default branch every few hours), so I can choose when I wish to update the package and get the latest features. The same applies to using straight package manager. Both of these approaches can also pin particular commits to avoid potential update issues.
And that is a significant point, I can choose when I wish to update the package (same applies to straight). I do so only when there is value to updating and when I have time to read the changelog and manage any minor challenges that may occur.
If a package is updated every day, then there is far greater potential to experience issues (all maintainers are human after all and issues can happen)
Given I use over 300 Emacs packages, then I take a pragmatic approach to updates. I am also amazed at how few issues I do experience with package updates overall.
I have found the Cider maintainers are very responsive to issues on either the Clojurians slack channel or when specific issues are raised via GitHub.
Any issues that have arisen can be quickly managed by either a package rollback or pinning a version of the package. Although in my experience the maintainers of packages usually fix an issue the same day they are informed about them.
https://practical.li/blog/posts/pin-emacs-package-to-manage-issues/
If there is documentation missing then raising an issue would be an effective approach or even contributing a pull request. This would benefit the Clojure community.
There have been recent changes that enhance the capability of Cider, especially around Java interop which may increase memory requirements, although these seem to be behind variables switched off by default.
Without specific issues being highlighted and reproducible, then improvements for any Clojure tooling is more challenging to resolve
No software is perfect and all editor extensions have their quirks. People will use the set of quirks they are happiest living with balance with the benefits a particular editor & extension provides.
Cider still remains the most popular tool for Clojure according to the yearly Clojure survey, although there is very good Clojure support for a wide range of editors.
I’m curious what features do you use? Not trying to convince you or anything - I just want to know what I’m missing by not using CIDER
I feel like LSP + REPL + scratch buffer are pretty much all I need, although I started using Portal more and more and it’s incredibly useful.
In general Cider provided much of the core features of LSP, Portal and flowstorm long before these tools arrived, especially when considering CIDER as Clojure-mode, cider, clj-refactor packages combined.
However, as Portal, Clojure LSP and Flowstorm mature, there can be advantages using them over the cider features (which also continue to be enhanced).
I’ve cover much of my Emacs Clojure workflow in Practicalli Spacemacs
Predominant use is not unique to cider:
- to start or more often connect to a repl process
- provide inline results when evaluating code via source code buffers
There is a rich set of evaluation options, although I mostly use:
- top-level and nested forms (and many many variations available)
- evaluation to comments, pretty print results, macro-expand
- interrupting evaluation
Managing the repl connection & repl state
- undefining vars, especially when renaming unit tests
- refresh & restart the repl process (maintain a clean repl state)
- browse repl process running / connected to (for multiple projects or full-stack projects)
Cider test runner is very convenient and I can also use that with Kaocha. I do tend to also run a command line Kaocha test watcher in the background, especially during a code refactor or major rewrite.
Cider also helps navigate stack traces when there are errors, with options to hide parts of the stack trace to make them easier to digest
The Cider data inspector is a very powerful and efficient way of exploring large or deeply nested data sets returned from code evaluation. Updating each time I evaluation
Cider-debug is also an invaluable tool. I don’t need it very often, but when loop recur or other iterative code returns unexpected results, having a built-in step debugger is very useful and convenient. I also find cider-debug a useful learning and demonstration tool, showing how an involved expression works step by step
Not part of Cider, but I’ve used Smartparents to great effect over the years, although as I learned vim-style multi-modal edition, much of the structural editing and text wrangling can be done by speaking vim (Emacs Evil)
As I became more confident and experienced with Clojure, some Cider features are used less often and I have narrowed my use of commands over the years.
I’ve also been using Neovim quite a lot over the last year and whilst Conjure is a wonderful piece of software to use it does not provide additional Clojure features like cider-inspect or cider-debug (and Conjure doesn’t really need to provide this - although there is some interesting work around DAP). This provided the incentive to spent more time appreciating Portal, which has a surprisingly amount of features I’m only recently figuring out how to make use of. Portal has become my defacto REPL history for all evaluations, logs API test results, data visualization, etc.
Adapting to Clojure LSP has also been a journey, although this feels an easier fit with Neovim & Conjure as there is much less overlap than with Clojure LSP & Cider. I only use a small amount of the LSP features with Cider, a little more with Neovim & Conjure.
Using different editors has helped me adopt a common set of tools and workflow regardless of editor, some of which is captured in Practicalli REPL Reloaded
So In summary, I do feel that in terms of Emacs packages, Cider is far more comprehensive than any other Emacs package. There are different ways to achieve similar workflows and tool support regardless of editor, each with there own benefits and constraints.
There are still many changes ahead with CIDER and Emacs, I watch clojure-ts-mode with great interest (as treesitter was one of the motivating factors to use Neovim and has been very successful so far)
Hope this helps
Got it - looks like I’m not personally missing out on much then, at least based on what I’m working on now - I don’t have a need for multiple REPL sessions (which Monroe doesn’t support).
Thank you for the elaborate answer, as always
How did you come to this solution? You must have had a background in related tech? I can’t imagine a newby arriving at this solution. Nice, though!