1
0
Fork
You've already forked sigil-nrepl
0
Network REPL server for Sigil.
  • Scheme 100%
Find a file
David Wilson 7b4f1c3a03
Some checks failed
ci/woodpecker/push/woodpecker Pipeline failed
Remove superseded item1 abort prototype notes
The abort/interrupt op is now implemented via the sliced-eval task machinery
(commit 2edb78d); the prototype patch/notes are no longer a resume point.
2026年07月10日 09:25:22 +03:00
src/sigil Drain streamed :out/:err frames in the nREPL client 2026年07月10日 09:16:28 +03:00
test Add interrupt/abort and incremental output streaming 2026年07月10日 09:12:14 +03:00
.gitignore Extract sigil-nrepl from sigil monorepo 2026年04月25日 04:40:42 +03:00
.woodpecker.yml Bump CI pin to sigil v0.14.3 2026年04月26日 20:18:26 +03:00
dev-redirects.sgl Extract sigil-nrepl from sigil monorepo 2026年04月25日 04:40:42 +03:00
manifest.scm Extract sigil-nrepl from sigil monorepo 2026年04月25日 04:40:42 +03:00
package.sgl Bump sigil-nrepl to 0.17 toolchain 2026年07月10日 08:41:42 +03:00
README.md Document interrupt/abort and output-streaming ops in README 2026年07月10日 09:17:09 +03:00
sigil.lock Bump sigil-nrepl to 0.17 toolchain 2026年07月10日 08:41:42 +03:00

sigil-nrepl

Network REPL server for Sigil — provides a JSON-RPC-style nREPL endpoint that editors and live-development tools connect to. Built on (sigil repl) for prompt rendering and command parsing, and on (sigil socket) for transport.

Long-running Sigil apps (live-crafter, cinder-cantata, game servers, etc.) embed an nREPL server so the developer can evaluate code, switch modules, inspect state, and iterate on running code without restarting the process.

Modules

Module Purpose
(sigil nrepl) nREPL server: connection handling, session state, op dispatch (eval/doc/...)
(sigil nrepl client) nREPL client: connect, send requests, named-connection registry

Wire protocol

Messages are length-prefixed S-expressions:

<length:u32-be><sexp>

Request format: (request :id <string> :op <symbol> [:module <string>] [...params])

Response format: (response :id <string> :status <symbol> [...results])

Ops supported: eval, abort (alias interrupt), complete, doc, describe, macroexpand, switch-module, modules, plus the debug-protocol ops (debug-policy, debug-state, debug-frames, debug-restarts, debug-quit).

Interrupt / abort

Expression evals run cooperatively — one preemptive-yield slice per nrepl-process-pending — so a CPU-bound eval (e.g. (let loop () (loop))) does not freeze the host's loop. Interrupt one from a second connection:

(request :id <abort-id> :op abort :target-id <eval-request-id>)

The abort responder gets :status ok :aborted <eval-request-id>; the interrupted eval receives :status error :code "interrupted"; the session survives and evaluates normally afterward. (A single top-level form that mixes a top-level define with a long loop runs on the immediate, non-abortable path — define at top level, then run, as separate requests.)

Output streaming

Output written during an eval is streamed back incrementally as it happens, before the final response, carrying the original eval request id:

(response :id <eval-id> :status out :out <string>) ; stdout
(response :id <eval-id> :status err :err <string>) ; stderr

followed by the normal terminal (response :id <eval-id> :status ok :value ...). The bundled (sigil nrepl client) transparently drains these frames and returns the terminal response from nrepl-eval.

Embedding an nREPL server

(import (sigil nrepl))
(define server (nrepl-start port: 7888))
;; In your app's main loop, drain pending requests:
(nrepl-process-pending server)
;; On shutdown:
(nrepl-stop server)

Connecting from a client

(import (sigil nrepl client))
(define conn (nrepl-connect "127.0.0.1" 7888))
(nrepl-eval conn "(+ 1 2)") ; => ((status . ok) (value . "3"))
(nrepl-switch-module conn "(my app)")
(nrepl-disconnect conn)

Build and test

sigil deps install
sigil build
sigil test --report

Local development against an unreleased sigil monorepo or against a local sigil-repl checkout:

sigil build --redirects ./dev-redirects.sgl

License

BSD-3-Clause. See LICENSE in the sigil monorepo for the canonical copy.