Posts

  • Modernizing CIDER's Completion

    CIDER’s code completion has quietly gotten quite good over the years, and I don’t think it gets enough credit. It’s all built on Emacs’s standard completion-at-point, so it works with whatever completion UI you prefer - the built-in one, Corfu, company - without any special setup. Under the hood compliment does the heavy lifting for Clojure (and clj-suitable for ClojureScript), which means smart, backend-driven matching: mai completes to map-indexed, cji to clojure.java.io, and an unimported BiFun to java.util.function.BiFunction. The candidates come back ranked by the backend and are context-aware - it knows when you’re inside a -> or completing a deftype field.

    Lately I’ve been giving the Emacs side of things some attention, to bring it in line with the modern completion stack so many of us now use - Vertico, Corfu, Consult, Marginalia and friends. Two changes are worth calling out.

    The first is about the symbol prompts. A number of CIDER commands ask you for a Clojure symbol when there’s nothing at point - cider-doc, cider-find-var and the like. Historically those prompts used the older completion machinery, so your completing-read UI didn’t kick in and you were left with TAB and a *Completions* buffer. There’s now cider-use-completing-read-for-symbol (off by default for now); turn it on and those prompts go through completing-read over a collection that queries the running REPL lazily as you type. Vertico, Ivy, Helm - whatever you drive completing-read with - just works, and the candidates carry their type and namespace.

    The second is smaller, but I like it a lot: annotations now line up in a proper column instead of trailing raggedly after each candidate.

    CIDER completion annotations

    This comes from an affixation-function, the richer successor to the old annotation-function, so every frontend that understands it - the built-in *Completions*, Corfu, Vertico - renders the aligned version. company keeps showing its own trailing annotations, same as before.

    Both changes are in the latest CIDER MELPA build and will ship in the next stable release. As always, I’d love to hear how they work out for you.

    That’s all I have for you today. Keep hacking!

    P.S. If you use Embark, I wrote up a fun way to act on Clojure symbols with it - documentation, jump-to-definition, inspect and so on - over on Emacs Redux.

  • Making CIDER More Discoverable

    This series about the notable changes in CIDER 2.0 continues with the change you’ll bump into first, whatever your workflow: the transient menus, and the broader push to make CIDER’s functionality discoverable.

    The problem: CIDER is huge

    CIDER has well over 300 interactive commands. I’ll admit something I’ve said before: there are features in CIDER that even I forget exist, and I wrote half of them. For users, historically, the options for finding functionality were:

    • memorize cryptic key chords (C-c C-w i, anyone?)
    • grep the (very long) manual
    • read the source
    • stumble on a feature by accident three years in and feel robbed

    That’s not great for a tool whose whole pitch is making you more productive. The Emacs answer to this problem was demonstrated years ago by Magit: transient menus, which turn every prefix into a self-documenting popup. It took us embarrassingly long to follow suit, but CIDER 2.0 finally does.

    Transient everywhere

    Every command group in CIDER now opens a transient menu: cider-eval-menu at C-c C-v, cider-doc-menu at C-c C-d, and likewise for test, namespace, macroexpand, profile, trace and references. A top-level cider-menu ties them all together, and even the debugger (? mid-session) and the inspector (m) got menus of their own. Jack-in and connect live in cider-start-menu at C-c C-x.

    Here’s the evaluation menu, which is a good illustration of the problem the menus solve - I doubt many people knew all of this was hiding behind C-c C-v:

    The CIDER evaluation transient menu, listing every evaluation command

    One design constraint was non-negotiable: your muscle memory is safe. These menus replace bare prefix keymaps, so every existing keybinding works exactly as before, at full speed - C-c C-v e still evaluates instantly, menu or no menu. And if you’d rather not see the menus at all unless you actually hesitate mid-chord, set transient-show-popup to a short delay and they’ll appear only in that moment of doubt - which is precisely when you need them.

    Transient also gave us something the old keymaps never could: arguments. Menus now carry flags for the things that vary per invocation - pick a pretty-printer with --print-fn=, set test selectors with --include=/--exclude= and reuse them across runs, toggle cider-ns-refresh’s modes explicitly, pass Clojure CLI aliases at jack-in time. All those “this command behaves differently with a prefix argument” paragraphs in the manual are becoming visible checkboxes instead.

    The test menu shows this nicely - set the selectors once and every run below them picks them up:

    The CIDER test transient menu with its include and exclude selector arguments

    Discovery beyond menus

    The menus are the headline, but the discoverability push in the 2.0 cycle went wider:

    • A new keybindings reference page collects every binding in one place, and the printable refcard was brought back up to date.
    • The REPL’s shouty welcome banner is gone, replaced by a one-line hint; the getting-started material now lives in a summonable reference card (C-c C-h, or the ,refcard REPL shortcut) - available when you want it, invisible when you don’t.
    • CIDER now warns (once per session) when you use a deprecated keybinding, so bindings can actually be retired someday without silently breaking people. M-x cider-list-deprecated-keybindings shows what’s on the way out.
    • The 1.22 cycle’s big audit already made the mode menus expose dozens of commands that were technically present but practically invisible; 2.0 builds on that foundation.
    • Even cider-doctor is discoverability of a sort - it surfaces the problems in your setup that you’d otherwise discover one confusing bug report at a time.

    The philosophy

    If I had to compress the 2.0 discoverability work into one sentence: the features were always there; now the tool tells you about them. Documentation is where knowledge goes to be forgotten - the only reliable place to teach a user about a feature is inside the workflow itself, at the moment of hesitation. Transient menus are exactly that, and Magit proved the pattern scales to enormous command sets.

    If some menu feels wrong - a missing command, a flag that should exist, a grouping that doesn’t match how you think - please file an issue. This part of CIDER is young and very much open to feedback.

    The keybindings docs have the full picture. Keep hacking!

  • clj-suitable 0.8.0: Closing the Gap with Compliment

    You had me at js/.

    – Jerry Maguire, on ClojureScript interop completion

    clj-suitable 0.8.0 is out! If the name doesn’t ring a bell, that’s rather the point - clj-suitable is the small library that quietly powers ClojureScript code completion in CIDER, Calva, and pretty much anything else that talks to a cljs REPL over nREPL. Think of it as the ClojureScript counterpart to what compliment1 does for Clojure. For years it lagged well behind its Clojure sibling, and this release is my attempt to finally close that gap - to make cljs completion, if you’ll forgive me, a touch more suitable.

    This is also a direct follow-up to the Piggieback work I wrote about a couple of weeks ago. Once I had the cljs REPL plumbing back in decent shape, fixing up the completion story sitting on top of it was the obvious next move.2

    1. The completion library, spelled with an i. Not the nice thing 

    2. One thing invariably leads to another with this stuff. You set out to fix 

    Read More
  • Sayid 0.8

    Sayid 0.8 is out! It’s the third release since I brought Sayid back from the dead a couple of weeks ago, and it has a clear theme: making the tool easy to pick up. The revival releases were mostly about the engine - bounding the recording, consolidating the API, getting the data out. This one is about the experience. If you’ve ever bounced off Sayid because you couldn’t figure out what to press, or what it was trying to tell you, 0.8 is for you.

    Read More
  • Projectile 3.2

    Projectile 3.2 is out!1 That’s the third Projectile release this month, and by now you probably see the pattern - a whole lot of nothing for a couple of years, then everything at once. Where 3.0 was the big cleanup and 3.1 the pile of long-standing feature requests, 3.2 is a focused release with one clear theme: search and replace. Plus one bonus feature I’ve wanted for ages, but more on that below.

    1. Technically it’s been out since July 12th, and there’s already a 3.2.1 

    Read More

Subscribe via RSS | View Older Posts