Skip to content

Check servers with what Calva, Conjure and vim-fireplace send - #6

Merged
bbatsov merged 3 commits into
mainfrom
more-client-profiles
Oct 8, 2026
Merged

bbatsov merged 3 commits into
mainfrom
more-client-profiles

Conversation

@bbatsov

@bbatsov bbatsov commented Oct 8, 2026

Copy link
Copy Markdown
Contributor

Profiles for the other popular clients, each started from a recording of the client against nREPL. vim-fireplace finds the classpath with Java interop, so its checks need a new java capability; failing ClojureCLR, Basilisp or jank for it would say nothing about those servers. wire.error-terminal now leaves multi-form evals alone, as nREPL itself goes on after a form that throws, and Conjure's startup code was the first check traffic to run into that.

nREPL evaluates every form of a request, so when one of them throws, the
output and values of the ones after it come after the eval-error status:

    (/ 1 0) (println "after") 2

gets err, then ex with eval-error, then out "after\n", values nil and 2,
and done. wire.error-terminal reported that as a failure, so nREPL
itself would fail it for any request like that. The clients the rule is
there for don't run into it, as REPLy sends one form per request.

Now the rule leaves alone requests whose code is several forms, each in
brackets, like the code clients evaluate when they connect. Code in
other languages can't be told apart into forms, so for it the rule
stays as it was.
Before it can evaluate anything, vim-fireplace (without cider-nrepl)
asks the server for its classpath:

    (System/getProperty "path.separator")
    (or (System/getProperty "fake.class.path")
        (System/getProperty "java.class.path") "")
    (System/getProperty "user.dir")
    (require 'clojure.repl 'clojure.java.javadoc)

proof serve didn't know or and System/getProperty, so vim-fireplace
couldn't connect to it and its tests couldn't use it. Now the path
separator and the working directory are the real ones, the classpath is
src and other properties are nil, as Java has them when they aren't set.
CIDER was the only client with a profile, so a server could pass every
check and still break the other popular clients. Each new profile
started as a recording of the client against nREPL through proof proxy
(Conjure and vim-fireplace driven by a headless Neovim, Calva by its own
nREPL client code under node), and says what the client needs from each
reply, with links to the code that needs it:

- Calva evaluates *ns* without a session, clones a session and asks for
  describe, and it sends only the ops it finds there. It then evaluates
  its startup code, and before code from a source file, the file's ns
  form.
- Conjure asks for describe and ls-sessions, clones a session when there
  are none and evaluates code of its own in it (one form to find out the
  kind of Clojure, then its preamble). Before code from a source buffer
  it evaluates an ns form for the buffer's namespace, and its print
  options are a dict even when they're empty.
- vim-fireplace finds the classpath by evaluating Java interop without
  a session, and reads the first three values, which it tells apart by
  the ns that comes with each one (the new values step option). Then it
  clones a session, and asks for the value of the user's code to be
  streamed with an integer.

vim-fireplace can't connect without Java interop, so its checks need a
new java capability, which the profiles of nREPL and Babashka declare.
The preset matrix test now runs each server with its own capabilities,
so its columns have the same skips as the real ones.

The fake server splits code into forms the way wire.error-terminal does,
so vim-fireplace's classpath code gets four values. Every server in the
matrix passes the checks that apply to it.
@bbatsov
bbatsov merged commit 49d33d9 into main Oct 8, 2026
4 checks passed
@bbatsov
bbatsov deleted the more-client-profiles branch October 8, 2026 08:46
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant