The ClojureScript implementation of Piggieback's nREPL middleware.
Loaded lazily by cider.piggieback, and only when ClojureScript is on the
classpath. All of Piggieback's coupling to the ClojureScript compiler
internals (cljs.repl, cljs.analyzer, cljs.env, cljs.closure,
cljs.tagged-literals) lives here, so the public cider.piggieback namespace
carries no hard dependency on ClojureScript.
The session-state dynamic vars and two pure helpers (forwarding-writer,
UnknownTaggedLiteral) live in cider.piggieback, referred to here as pb.
The ClojureScript implementation of Piggieback's nREPL middleware. Loaded lazily by `cider.piggieback`, and only when ClojureScript is on the classpath. All of Piggieback's coupling to the ClojureScript compiler internals (`cljs.repl`, `cljs.analyzer`, `cljs.env`, `cljs.closure`, `cljs.tagged-literals`) lives here, so the public `cider.piggieback` namespace carries no hard dependency on ClojureScript. The session-state dynamic vars and two pure helpers (`forwarding-writer`, `UnknownTaggedLiteral`) live in `cider.piggieback`, referred to here as `pb`.
(analyzer-env ns-sym)An empty analyzer environment scoped to ns-sym.
An empty analyzer environment scoped to `ns-sym`.
(build-opts repl-opts options)Initialise the repl options the way cljs.repl/repl* would internally. We
evaluate outside of that loop, so we have to do this ourselves.
Initialise the repl options the way `cljs.repl/repl*` would internally. We evaluate outside of that loop, so we have to do this ourselves.
(cljs-repl repl-env & {:as options})Starts a ClojureScript REPL over top an nREPL session. Accepts all options usually accepted by e.g. cljs.repl/repl.
Starts a ClojureScript REPL over top an nREPL session. Accepts all options usually accepted by e.g. cljs.repl/repl.
(current-ns)The current ClojureScript namespace (a symbol).
The current ClojureScript namespace (a symbol).
The default :caught handler (cljs.repl/repl-caught).
The default `:caught` handler (`cljs.repl/repl-caught`).
(default-compiler-env opts)A fresh ClojureScript compiler environment for opts.
A fresh ClojureScript compiler environment for `opts`.
(delegating-repl-env repl-env)Wrap repl-env in a delegating env with a no-op -tear-down.
Wrap `repl-env` in a delegating env with a no-op `-tear-down`.
(describe-cljs {:keys [session]})A describe-fn (see nREPL's wrap-describe) that contributes Piggieback's
per-session ClojureScript status to the describe response's :aux map.
Lets tooling detect whether the session is currently evaluating ClojureScript (and against which repl-env), instead of having to infer it out of band.
A describe-fn (see nREPL's `wrap-describe`) that contributes Piggieback's per-session ClojureScript status to the `describe` response's `:aux` map. Lets tooling detect whether the session is currently evaluating ClojureScript (and against which repl-env), instead of having to infer it out of band.
(ensure-close-teardown! session)Augment the session's :close metadata (once) so that closing the session
also tears down any active ClojureScript repl-env.
nREPL's session middleware handles the close op itself and never delegates
it to Piggieback, so we can't intercept it as an op. Instead we compose our
teardown into the :close fn that nrepl.middleware.session/close-session
invokes. Without this, closing a session (or a client exiting) without first
sending :cljs/quit leaks the JavaScript runtime, e.g. a Node subprocess.
Augment the session's `:close` metadata (once) so that closing the session also tears down any active ClojureScript repl-env. nREPL's session middleware handles the `close` op itself and never delegates it to Piggieback, so we can't intercept it as an op. Instead we compose our teardown into the `:close` fn that `nrepl.middleware.session/close-session` invokes. Without this, closing a session (or a client exiting) without first sending `:cljs/quit` leaks the JavaScript runtime, e.g. a Node subprocess.
(eval-bindings compiler-env repl-env opts)Binding map for evaluating in repl-env, with opts the repl options (see
build-opts).
We evaluate outside of cljs.repl/repl*'s loop, so this recreates the
bindings repl* establishes around it, relative to the current warnings and
warning handlers as repl* does. Without them repl options are silently
ignored (e.g. :warnings, issue #154 for *repl-opts*), and an analyzer var
that code set!s has no thread binding to set (issue #95). The
cider.piggieback-repl-parity-test checks this against repl* itself.
Binding map for evaluating in `repl-env`, with `opts` the repl options (see `build-opts`). We evaluate outside of `cljs.repl/repl*`'s loop, so this recreates the bindings `repl*` establishes around it, relative to the current warnings and warning handlers as `repl*` does. Without them repl options are silently ignored (e.g. `:warnings`, issue #154 for `*repl-opts*`), and an analyzer var that code `set!`s has no thread binding to set (issue #95). The `cider.piggieback-repl-parity-test` checks this against `repl*` itself.
(eval-form repl-env env form file opts print-fn)Evaluate a single ClojureScript form in repl-env/env. opts are the
repl options; print-fn is the name of nREPL's requested print function, used
to pick a result-wrapping strategy.
Evaluate a single ClojureScript `form` in `repl-env`/`env`. `opts` are the repl options; `print-fn` is the name of nREPL's requested print function, used to pick a result-wrapping strategy.
(load-source repl-env source filename)Load ClojureScript source (a string of one or more forms) as if it were the
file at filename, evaluating each form in repl-env.
Unlike cljs.repl/load-file, this loads the source handed to it rather than
reading the file from disk, so unsaved editor buffers load correctly. As
cljs.repl/load-file does, it starts the file with the unchecked flags off,
and restores the current analyzer namespace, and any analyzer settings the
file set!s (e.g. *warn-on-infer*), afterwards.
Must run under eval-bindings, as load-stream takes the repl options from
cljs.repl/*repl-opts* (issue #154).
Load ClojureScript `source` (a string of one or more forms) as if it were the file at `filename`, evaluating each form in `repl-env`. Unlike `cljs.repl/load-file`, this loads the source handed to it rather than reading the file from disk, so unsaved editor buffers load correctly. As `cljs.repl/load-file` does, it starts the file with the unchecked flags off, and restores the current analyzer namespace, and any analyzer settings the file `set!`s (e.g. `*warn-on-infer*`), afterwards. Must run under `eval-bindings`, as `load-stream` takes the repl options from `cljs.repl/*repl-opts*` (issue #154).
The ClojureScript analyzer's current-namespace var. Exposed so the handlers
can use it as a key in binding maps and in the session atom without naming a
compiler internal directly.
The ClojureScript analyzer's current-namespace var. Exposed so the handlers can use it as a key in `binding` maps and in the session atom without naming a compiler internal directly.
(read-bindings)Binding map for reading ClojureScript in the current namespace. Mirrors the
bindings cljs.repl/repl* establishes around reading, which the
cider.piggieback-repl-parity-test checks.
Binding map for reading ClojureScript in the current namespace. Mirrors the bindings `cljs.repl/repl*` establishes around reading, which the `cider.piggieback-repl-parity-test` checks.
(read-form form-str)Read a single ClojureScript form from form-str, with the cljs data readers
and the current namespace's alias map in place. Returns nil for blank input.
Read a single ClojureScript form from `form-str`, with the cljs data readers and the current namespace's alias map in place. Returns nil for blank input.
(repl-options repl-env)The repl-env's own repl options (cljs.repl/-repl-options).
The repl-env's own repl options (`cljs.repl/-repl-options`).
(set-current-ns! ns-sym)Set the current ClojureScript namespace. Must run on a thread where
ns-var is bound.
Set the current ClojureScript namespace. Must run on a thread where `ns-var` is bound.
(setup-repl repl-env compiler-env options init-ns code)Drive cljs.repl/repl* through a single setup form (the cljs.user
namespace require), starting from analyzer namespace init-ns.
This is the one place we drive the full repl* loop rather than evaluating
forms ourselves; everything else goes through eval-form. The setup form
always switches into cljs.user, and the compiler env is the one we passed in,
so the caller can read both back directly after this returns - no callback or
:print side-channel needed.
Drive `cljs.repl/repl*` through a single setup form (the `cljs.user` namespace require), starting from analyzer namespace `init-ns`. This is the one place we drive the full `repl*` loop rather than evaluating forms ourselves; everything else goes through `eval-form`. The setup form always switches into `cljs.user`, and the compiler env is the one we passed in, so the caller can read both back directly after this returns - no callback or `:print` side-channel needed.
(special-fns repl-options)The REPL special functions, merging the cljs defaults with any provided by the repl options.
The REPL special functions, merging the cljs defaults with any provided by the repl options.
(tear-down! repl-env)Tear down the (unwrapped) repl env.
Tear down the (unwrapped) repl env.
cljdoc builds & hosts documentation for Clojure/Script libraries
| Ctrl+k | Jump to recent docs |
| ← | Move to previous article |
| → | Move to next article |
| Ctrl+/ | Jump to the search field |