Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions PLAN.md
Original file line number Diff line number Diff line change
Expand Up @@ -108,7 +108,7 @@ Runtime deps: `org.clojure/clojure`, `nrepl/nrepl`, `org.jline/jline` 4.x. That'
- Gotcha: a subscription switches orchard from printing to sending events for the whole server, so while one's open, `neorepl eval` and every other client get no printed traces. The REPL subscribes only once something's traced, and unsubscribes when it ends. A client that goes away without unsubscribing leaves the server sending events to nobody until a traced call finds the connection gone, which drops the subscription since cider-nrepl 0.62.2, losing that one call's trace.
- Reloading what changed (2026-11-03, cider-nrepl 0.64.0, with clj-reload 1.0.0). `cider.clj-reload/reload` runs in the session it names, after what's running there, and answers with `:progress` lines, "Reloading N namespaces..." and then "Reloaded N namespaces in M ms" or " failed to load NS" with the error's first line, then `ok`, or `error` with the analyzed causes as `:error` and what `repl-caught` prints on `:err`, and `done`. It reloads the namespaces whose files changed and the ones that require them, in dependency order, leaves alone the ones nothing loaded, and keeps what `defonce` defined, through a failed reload too, which keeps the namespace that failed for the next one. In a ClojureScript session it answers `done` and `clojure-only`, with a word on `:err`.
- Gotcha: cider-nrepl loads a middleware's namespace the first time its op comes, and clj-reload notes the files' times when it loads, so on a server that's never reloaded, the first reload only starts noting what changes, and takes about half a second. A file changed before then doesn't get reloaded. neorepl sends that first reload in the background as soon as a server it starts with cider-nrepl is up, so `eval --reload` there sees everything since. On other servers, the first `--reload` or `,autoreload` is where it starts. cider-nrepl starting clj-reload with the server would do away with it.
- Gotcha: clj-reload makes the namespaces it reloads anew, and a session in one goes on in the old one, where a function just added to the file doesn't resolve. Unlike tools.namespace's `refresh`, it doesn't put the session back, so neorepl does, after a reload that reloaded something, evaluating `in-ns` there in a way that leaves `*1`, `*2` and `*3` as they were. babashka resolves names through the namespace's name, so it doesn't go stale there.
- Gotcha: clj-reload makes the namespaces it reloads anew, and a session in one goes on in the old one, where a function just added to the file doesn't resolve. Unlike `clojure.tools.namespace.repl/refresh`, it doesn't put the session back, and neither does cider-nrepl's `refresh` op, which calls tools.namespace's `track-reload` itself, so neorepl does, after a reload that reloaded something, evaluating `in-ns` there in a way that leaves `*1`, `*2` and `*3` as they were. babashka resolves names through the namespace's name, so it doesn't go stale there. [cider-nrepl#1078](https://github.com/clojure-emacs/cider-nrepl/pull/1078) does it in cider-nrepl after both reloads, for the session that asks for one, and once a release with it is the oldest one supported, neorepl's can go.
- Gotcha: the same goes for the aliases and refers of the namespaces a reload leaves alone, like the REPL's own, with clj-reload and with cider-nrepl's `refresh`, whose tools.namespace also makes namespaces anew with `remove-ns` (2026-11-06, cider-nrepl 0.64.0 and clj-reload 1.0.0, whose README says so). They stay on the old namespace and its vars, so a function added to the file since doesn't resolve through the alias, and requiring the namespace with the same alias again fails with "Alias o already exists". Calling a function that was there before works, since compiled code finds vars by their names. So after a reload that reloaded something, neorepl has every alias and refer that's on a namespace that's gone point at the one by that name now, and its var by that name, a few milliseconds with cider-nrepl's namespaces loaded. What has nothing new to point at stays as it was, since an `:as-alias` keeps working for keywords, and another client's reload can be halfway through. It goes by the var's own namespace and name, since potemkin's `import-vars` copies another var's `:ns` and `:name` into its metadata. Only Clojure servers have these reloads, so it's Clojure only. [cider-nrepl#1077](https://github.com/clojure-emacs/cider-nrepl/pull/1077) does it in cider-nrepl after both reloads, for every client, and once a release with it is the oldest one supported, neorepl's can go.
- Output from other threads (2026-11-03, nREPL 1.8.0, with piggieback 0.8.0 too, bb 1.13.227 and 1.13.229, and shadow-cljs 3.5.7, which brings nREPL 1.3.1 and can't). `forward-system-output` swaps in `System/out` and `System/err`, and root bindings of `*out*` and `*err*`, which threads no session started print to, that copy what's printed to the session that asked, as `:out` or `:err` with `:source "system"` on that request's id, after its `done`. An evaluation prints to its session's `*out*` as before, unless it writes to `System/out` itself. nREPL keeps one forwarding per session, so asking again replaces it. cider-nrepl 0.64.0's `cider/out-subscribe`, the way before it, sends nothing to a session that hasn't evaluated anything, and its `cider/out-unsubscribe` leaves the session subscribed and fails to send its answer, which carries the whole request ([cider-nrepl#1074](https://github.com/clojure-emacs/cider-nrepl/issues/1074)), so neorepl leaves it be. What comes forwarded is all the server prints, its own noise included, like the `SocketException` traces of [babashka#2227](https://github.com/babashka/babashka/issues/2227).
- Gotcha: nREPL never drops a session's forwarding, not even once the session's closed ([nrepl#513](https://github.com/nrepl/nrepl/issues/513)), so every later write goes to a connection that's gone, which fails without a word, and the request it keeps holds on to the session, with its `*1` and `*e`. So the REPL asks in a session of its own, which never evaluates anything, and closes it when it ends. And a client in the server's process gets sent what it prints, and prints it again, forever, so `forward-system-output` doesn't ask a server in neorepl's process, nor one neorepl started, whose output the REPL shows already.
Expand Down Expand Up @@ -395,7 +395,7 @@ Not covered yet: Linux (Docker wasn't running) and Windows. Neither should surpr
1. CI against real servers, see 0.5. So far the tests run on the JVM and bb against an in-process nREPL, with fakes for the cider-nrepl ops, and the real servers get checked by hand and with proof.
2. babashka. Filed: `test-var-query` going quiet for a test that throws outside an assertion, [babashka#2201](https://github.com/babashka/babashka/issues/2201), fixed after 1.13.226, and, a few at a time to keep from flooding the tracker, on 2026-10-21 and 2026-10-22: `test-var-query` by var for a namespace that isn't loaded killing the session ([#2206](https://github.com/babashka/babashka/issues/2206)), `:project?` and `:load-project-ns?` being ignored ([#2207](https://github.com/babashka/babashka/issues/2207)), test results carrying the file of the session's last `load-file` ([#2208](https://github.com/babashka/babashka/issues/2208)), `info` without `:line` or `:column`, resolving built-in files against the working directory ([#2209](https://github.com/babashka/babashka/issues/2209)), the `SocketException` from `nREPL-track-state` after every client that disconnects ([#2210](https://github.com/babashka/babashka/issues/2210)), `inspect-last-exception` ([#2211](https://github.com/babashka/babashka/issues/2211)), `org.jline.utils.Status` (mid-buffer eldoc) and `org.jline.reader.CompletingParsedLine` (for reify) ([#2218](https://github.com/babashka/babashka/issues/2218)), `jdk.net.ExtendedSocketOptions`, for `TCP_QUICKACK` ([#2219](https://github.com/babashka/babashka/issues/2219)), and `source-fn`, which resolves bb's own dependencies the first time it's asked for a built-in, cloning git deps, which is what timed out on fresh Windows runners, and keeps `nil` for good when that fails, which is what failed `source when` for the whole run on 2026-10-18 ([#2220](https://github.com/babashka/babashka/issues/2220)). All of them are fixed on bb's master, not released yet. The 1.13.227-SNAPSHOT dev build fixes each one, on macOS and on Linux in Docker, and passes neorepl's tests; with `TCP_QUICKACK` there, `eval -f` of 100 forms on Linux goes from 4.5s to 154ms. Its `inspect-last-exception`, like cider-nrepl's, inspects what `analyze-last-stacktrace` analyzed, so the stacktrace has to be asked for first. Still open, from 2026-10-22: a session whose client disconnects during an evaluation never answers again, since nREPL 1.7's session thread dies writing the reply, which nREPL 1.8 fixed ([#2227](https://github.com/babashka/babashka/issues/2227)). It's also the `nREPL-session` SocketException in the output of neorepl's tests on bb. bb's server has been a vendored nREPL 1.7 since 1.13.221, so the interrupted evaluation's exception after `done` is nREPL's, [nrepl#506](https://github.com/nrepl/nrepl/issues/506), and so are its sockets without `TCP_NODELAY`, [nrepl#507](https://github.com/nrepl/nrepl/issues/507). On 2026-10-31, what tests print going out under the session's previous message, as it did in cider-nrepl before 0.64.0 ([#2265](https://github.com/babashka/babashka/issues/2265)). On 2026-11-01, `info` knowing nothing about namespaces ([#2270](https://github.com/babashka/babashka/issues/2270)), its `lookup` being the vendored nREPL's, which nrepl#511 covers. On 2026-11-04, `print-method` and `clojure.pprint/write` not seeing `binding`s of `*print-length*` and `*print-level*`, which nREPL's printers count on ([#2274](https://github.com/babashka/babashka/issues/2274)). Still to talk over with borkdude: how `bb repl --connect` and neorepl should relate long term.
3. nREPL. Filed: `need-input` going to the connection that created the session ([nrepl#183](https://github.com/nrepl/nrepl/issues/183)), interrupting an evaluation dropping the ones queued behind it ([nrepl#503](https://github.com/nrepl/nrepl/issues/503)), an interrupt not reaching an evaluation that hasn't started, queued or just sent ([nrepl#504](https://github.com/nrepl/nrepl/issues/504)), `*file*` staying bound after an eval with a `:file` ([nrepl#505](https://github.com/nrepl/nrepl/issues/505)), and an interrupted evaluation's InterruptedException coming after its `done` ([nrepl#506](https://github.com/nrepl/nrepl/issues/506)). [#498](https://github.com/nrepl/nrepl/pull/498), the interrupted evaluation's last response going to its own connection, is merged. The 1.6 warnings about middleware a descriptor names and the stack lacks are [nrepl#424](https://github.com/nrepl/nrepl/issues/424): with piggieback on the classpath, cider-nrepl's descriptors bring eleven of them, and shadow-cljs's own one more, since it expects piggieback's middleware without listing it; one line per missing middleware, and none for `:expects`, would quiet it. On 2026-10-22: the server's sockets going without `TCP_NODELAY`, so on Linux an eval's `done` waits up to 40ms behind its value ([nrepl#507](https://github.com/nrepl/nrepl/issues/507)), which macOS doesn't show. The fix is [#508](https://github.com/nrepl/nrepl/pull/508), which takes 100 evals from nREPL's own client from 4.4s to 90ms on Linux. Until servers have it, neorepl sets `TCP_QUICKACK` before each read, on the JVM and on bb, which has `ExtendedSocketOptions` from 1.13.227. On 2026-11-01, `lookup` finding namespaces, by their name or an alias, [#511](https://github.com/nrepl/nrepl/pull/511), which also leaves `:file` out where there's none, rather than sending an empty list, as it does for a var made with `intern`. On 2026-11-03, closing a session not stopping its `forward-system-output` ([nrepl#513](https://github.com/nrepl/nrepl/issues/513)).
4. cider-nrepl and orchard. Filed: ClojureScript tests not running on shadow-cljs ([cider-nrepl#1054](https://github.com/clojure-emacs/cider-nrepl/issues/1054)), and on 2026-10-21 `test-var-query` never answering for a test whose namespace isn't loaded ([#1057](https://github.com/clojure-emacs/cider-nrepl/issues/1057)), running every test when the tests it names aren't there ([#1058](https://github.com/clojure-emacs/cider-nrepl/issues/1058)), test output going out under the session's previous message ([#1059](https://github.com/clojure-emacs/cider-nrepl/issues/1059)), ClojureScript test runs leaving the report in `*1` ([#1060](https://github.com/clojure-emacs/cider-nrepl/issues/1060)) and `cider/trace-subscribe` answering `done` before its events ([#1061](https://github.com/clojure-emacs/cider-nrepl/issues/1061)). In orchard: the namespace query's NullPointerException once a project namespace fails to load ([orchard#434](https://github.com/clojure-emacs/orchard/issues/434), #70 again), which is what hangs `test-var-query` with `:load-project-ns?`, a traced call that throws getting no exit line or event ([orchard#435](https://github.com/clojure-emacs/orchard/issues/435)), and tracing what orchard's tracing calls, like `clojure.core/map`, taking the server down ([orchard#436](https://github.com/clojure-emacs/orchard/issues/436)). On 2026-10-26, the spaces orchard puts between everything in a Javadoc's HTML and its unescaped `{@code}`, with the fix ([orchard#438](https://github.com/clojure-emacs/orchard/pull/438)). A subscription outliving its connection was fixed in 0.62.2. orchard 0.48.0 and cider-nrepl 0.64.0 fix #1054, #1057, #1058, #1059, orchard#434 and orchard#435. orchard#436 is only half fixed: tracing a function orchard's tracing calls no longer takes the server down, but orchard still traces it, since refusing takes a status in cider-nrepl that CIDER can show. Still open: #1060, and #1061, which waits until most neorepl users have a REPL that takes its subscription without waiting for `done`, from 0.5.0 on. On 2026-11-03, `cider/out-unsubscribe` not unsubscribing and failing to send its answer ([#1074](https://github.com/clojure-emacs/cider-nrepl/issues/1074)), `cider/profile-summary` failing until a profiled function gets called ([#1072](https://github.com/clojure-emacs/cider-nrepl/issues/1072)), no ops to list what's profiled or stop all of it ([#1073](https://github.com/clojure-emacs/cider-nrepl/issues/1073)), a value that can't be printed ending a tap subscription ([#1075](https://github.com/clojure-emacs/cider-nrepl/issues/1075)), tapped values kept once per subscription and after the last one ([#1076](https://github.com/clojure-emacs/cider-nrepl/issues/1076)), and in orchard, profiling maps and multimethods ([orchard#445](https://github.com/clojure-emacs/orchard/issues/445)).
4. cider-nrepl and orchard. Filed: ClojureScript tests not running on shadow-cljs ([cider-nrepl#1054](https://github.com/clojure-emacs/cider-nrepl/issues/1054)), and on 2026-10-21 `test-var-query` never answering for a test whose namespace isn't loaded ([#1057](https://github.com/clojure-emacs/cider-nrepl/issues/1057)), running every test when the tests it names aren't there ([#1058](https://github.com/clojure-emacs/cider-nrepl/issues/1058)), test output going out under the session's previous message ([#1059](https://github.com/clojure-emacs/cider-nrepl/issues/1059)), ClojureScript test runs leaving the report in `*1` ([#1060](https://github.com/clojure-emacs/cider-nrepl/issues/1060)) and `cider/trace-subscribe` answering `done` before its events ([#1061](https://github.com/clojure-emacs/cider-nrepl/issues/1061)). In orchard: the namespace query's NullPointerException once a project namespace fails to load ([orchard#434](https://github.com/clojure-emacs/orchard/issues/434), #70 again), which is what hangs `test-var-query` with `:load-project-ns?`, a traced call that throws getting no exit line or event ([orchard#435](https://github.com/clojure-emacs/orchard/issues/435)), and tracing what orchard's tracing calls, like `clojure.core/map`, taking the server down ([orchard#436](https://github.com/clojure-emacs/orchard/issues/436)). On 2026-10-26, the spaces orchard puts between everything in a Javadoc's HTML and its unescaped `{@code}`, with the fix ([orchard#438](https://github.com/clojure-emacs/orchard/pull/438)). A subscription outliving its connection was fixed in 0.62.2. orchard 0.48.0 and cider-nrepl 0.64.0 fix #1054, #1057, #1058, #1059, orchard#434 and orchard#435. orchard#436 is only half fixed: tracing a function orchard's tracing calls no longer takes the server down, but orchard still traces it, since refusing takes a status in cider-nrepl that CIDER can show. Still open: #1060, and #1061, which waits until most neorepl users have a REPL that takes its subscription without waiting for `done`, from 0.5.0 on. On 2026-11-03, `cider/out-unsubscribe` not unsubscribing and failing to send its answer ([#1074](https://github.com/clojure-emacs/cider-nrepl/issues/1074)), `cider/profile-summary` failing until a profiled function gets called ([#1072](https://github.com/clojure-emacs/cider-nrepl/issues/1072)), no ops to list what's profiled or stop all of it ([#1073](https://github.com/clojure-emacs/cider-nrepl/issues/1073)), a value that can't be printed ending a tap subscription ([#1075](https://github.com/clojure-emacs/cider-nrepl/issues/1075)), tapped values kept once per subscription and after the last one ([#1076](https://github.com/clojure-emacs/cider-nrepl/issues/1076)), and in orchard, profiling maps and multimethods ([orchard#445](https://github.com/clojure-emacs/orchard/issues/445)). After a reload, the aliases and refers left on the namespaces it removed are fixed on master by [#1077](https://github.com/clojure-emacs/cider-nrepl/pull/1077) (2026-11-06), and the session left in one by [#1078](https://github.com/clojure-emacs/cider-nrepl/pull/1078), open since 2026-11-07, neither released yet.
5. piggieback: evaluating every form of an `eval` message, the way nREPL's own eval does, and loading ClojureScript on the first `cljs-repl` rather than at startup, both open as [#162](https://github.com/nrepl/piggieback/pull/162) and [#161](https://github.com/nrepl/piggieback/pull/161), and `describe` reporting `cljs.user` after an `ns` switch ([piggieback#163](https://github.com/nrepl/piggieback/issues/163)). Its README says ClojureScript evaluations can't be interrupted, which for Node isn't the whole story, see the gotcha. In ClojureScript: interrupting the Node REPL, and two Node REPLs sharing a result queue, see the gotcha, to raise on ask.clojure.org.
6. JLine: `TAIL_TIP` hiding the incremental search's prompt ([jline3#2330](https://github.com/jline/jline3/issues/2330)), `LineDisciplineTerminal` echoing `^C` with ECHO off ([#2331](https://github.com/jline/jline3/issues/2331)) and `setTailTip(null)` throwing ([#2332](https://github.com/jline/jline3/issues/2332)). A tail tip that doesn't start with `[` loses its first word while a word without a `-` is typed, which is by design, for TailTipWidgets' argument lists; eldoc's tips for special forms start with `(`, so they lose it, and starting them with a space would keep them whole. Since 2026-11-01 eldoc goes under the input, and neorepl has no tail tips.
7. nbb. Filed on 2026-11-02: code that throws getting no `eval-error` status ([nbb#425](https://github.com/babashka/nbb/issues/425)), fixed the same day, after 1.6.214, an eval's `:ns` losing to the namespace the last eval left ([#426](https://github.com/babashka/nbb/issues/426)), `in-ns` not switching ([#427](https://github.com/babashka/nbb/issues/427)), sessions sharing the namespace, `*1` and `*e` ([#429](https://github.com/babashka/nbb/issues/429)), `load-file` taking the file's contents for its `:file` ([#430](https://github.com/babashka/nbb/issues/430)), and `info` and `eldoc` answering what they don't find with empty lists and no `no-info` or `no-eldoc` ([#431](https://github.com/babashka/nbb/issues/431)). On 2026-11-04, nREPL's own printers and a session's `*print-length*` being ignored ([#436](https://github.com/babashka/nbb/issues/436)).
Expand Down
Loading
Loading