Skip to content
Open
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
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
- `cider-read-and-eval` (`:`)
- `cider-eval-defun-to-comment` (`;`)
- `cider-pprint-eval-last-sexp-to-repl` (`f j e`)
- [#3839](https://github.com/clojure-emacs/cider/pull/3839): Add jack-in support for ClojureCLR.

### Bugs fixed

Expand Down
1 change: 1 addition & 0 deletions doc/modules/ROOT/pages/basics/up_and_running.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -182,6 +182,7 @@ The following Clojure build tools are supported so far
- kbd:[M-3 C-c C-x j u] jack-in using babashka.
- kbd:[M-4 C-c C-x j u] jack-in using nbb.
- kbd:[M-5 C-c C-x j u] jack-in using basilisp.
- kbd:[M-6 C-c C-x j u] jack-in using ClojureCLR.

Here is an example of how to bind kbd:[F12] for quickly bringing up a
babashka REPL:
Expand Down
10 changes: 4 additions & 6 deletions doc/modules/ROOT/pages/caveats.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -60,13 +60,11 @@ from your Emacs config.

== ClojureCLR Support

CIDER currently has very basic support for ClojureCLR (via Arcadia's nREPL server). The reasons for this are the following:
CIDER currently has very basic support for ClojureCLR (via either a port of Babashka's nREPL server or Arcadia's nREPL server). The reasons for this are the following:

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we can remove mentions of Arcadia, as the project has been dead for a few years now. Less is more.


* nREPL itself runs only on the JVM (because it leverages Java APIs
internally). There's an
https://github.com/clojure/clr.tools.nrepl[nREPL port for ClojureCLR], but
it's not actively maintained and it doesn't behave like the Clojure nREPL.
* `cider-nrepl` uses a lot of Java code internally itself.
* The https://github.com/clojure/clr.tools.nrepl/tree/master/partial-nrepl-nrepl-port[nrepl/nrepl port to ClojureCLR] is not yet working

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Both those items will be quite easy to tackle today with the help of AI agents (as the outcome is fairly well specified, so it'd be mostly a matter of time and tokens), but I'm not sure if anyone has interest in filling in the blanks there.

Perhaps we should remove this server as well, so we won't confuse users?

I'm also thinking we should probably suggest neat as a good alternative of CIDER for ClojureCLR, as it's simpler and makes no assumptions about the runtime.

* `cider-nrepl` uses a lot of Java code internally itself and would need to be adapted/ported like any
other clojure library adapted/ported to ClojureCLR.

Those issues are not insurmountable, but are beyond the scope of our current roadmap.
If someone would like to tackle them, we'd be happy to provide assistance.
Expand Down
16 changes: 8 additions & 8 deletions doc/modules/ROOT/pages/platforms/clojureclr.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -2,27 +2,27 @@

== Current Status

ClojureCLR on CIDER is not great due to the lack of a fully-functional nREPL
server for ClojureCLR. There are currently two options:
You will get basic CIDER functionality with ClojureCLR. Three nREPL server options:

- https://github.com/clojure/clr.tools.nrepl[clr.tools.nrepl]: A direct (but incomplete) port of the reference Clojure nREPL server.
- https://github.com/clojure/clr.tools.nrepl[clr.tools.nrepl]: At present port of babashka's nREPL server (https://github.com/babashka/babashka.nrepl[babashka.nrepl]).
- https://github.com/clojure/clr.tools.nrepl/tree/master/partial-nrepl-nrepl-port[port of nrepl/nrepl]: A non-working, work-in-progress port of nrepl/nrepl, which may
ultimately better integrate with CIDER once CIDER's middleware (cider-nrepl) is also adapted/ported.
- https://github.com/arcadia-unity/Arcadia/blob/master/Editor/NRepl.cs[Arcadia's nREPL]: A basic, but working nREPL implementation in C#.

If you need to use CIDER with ClojureCLR today Arcadia's nREPL is your only usable option. That being said - `clr.tools.nrepl` is a much
more sophisticated project and ideally we should get it over to the finish line.
An alternative to CIDER & a nREPL server is inf-clojure with ClojureCLR's stock socket REPL server.

== Usage

NOTE: Contributions welcome!

As `cider-jack-in` doesn't support ClojureCLR projects out-of-the-box currently, you'll need to start an nREPL server externally and
connect to it with `cider-connect`.
`cider-jack-in-universal` will jack into a clr.tools.nrepl server as long as a `deps-clr.edn` file
exists in the project directory, otherwise you may call `cider-jack-in-universal` with prefix
argument 6, by either `M-6` or `C-u 6` followed by `M-x cider-jack-in-universal`.

== Plans

In an ideal world we'll achieve the following objectives:

- out-of-the-box ClojureCLR support with `cider-jack-in`
- feature parity between Clojure's nREPL implementation and `clr.tools.nrepl` (the project can use some help)
- adapting `cider-nrepl` for ClojureCLR (some of its codebase is JVM-specific)

Expand Down
61 changes: 61 additions & 0 deletions lisp/cider-jack-in.el
Original file line number Diff line number Diff line change
Expand Up @@ -207,6 +207,30 @@ By default we favor the project-specific shadow-cljs over the system-wide."
:safe #'stringp
:package-version '(cider . "1.14.0"))

(defcustom cider-clojure-clr-cli-command
"cljr"
"The command used to execute ClojureCLR."
:type 'string
:group 'cider
:safe #'stringp
:package-version '(cider . "1.21.0"))

(defcustom cider-clojure-clr-cli-parameters
"-X clojure.tools.nrepl/start-server!"
"Params passed to ClojureCLR to start an nREPL server via `cider-jack-in'."
:type 'string
:group 'cider
:safe #'stringp
:package-version '(cider . "1.21.0"))

;; Clojure git deps require :git/sha even when :git/tag is set, just do full SHA
(defcustom cider-clojure-clr-cli-nrepl-sha "a6bf822a5f72ec613f703eaf95420758591f2437"
"The version of clr.tools.nrepl injected on jack-in with ClojureCLR."
:type 'string
:group 'cider
:safe #'stringp
:package-version '(cider . "1.21.0"))


;;; Jack-in defaults and toggles

Expand Down Expand Up @@ -623,6 +647,30 @@ Does so by concatenating PARAMS and DEPENDENCIES."
" "
params)))

(defun cider-clojure-clr-cli-jack-in-dependencies (params dependencies &optional command)
"Create ClojureCLR clr.core.cli jack-in dependencies.
Does so by concatenating DEPENDENCIES, and PARAMS into a
suitable `cljr` invocation and quoting, also accounting for COMMAND if
provided."
(let* ((all-deps (thread-last dependencies
(cider--dedupe-deps)
(seq-map (lambda (dep)
(if (listp (cadr dep))
(format "%s {%s}"
(car dep)
(seq-reduce
(lambda (acc v)
(concat acc (format " :%s \"%s\" " (car v) (cdr v))))
(cadr dep)
""))
(format "%s {:git/sha \"%s\"}" (car dep) (cadr dep)))))))
(deps (format "{:deps {%s}}"
(string-join all-deps " ")))
(deps-quoted (cider--shell-quote-argument deps command)))
(format "-Sdeps %s %s"
deps-quoted
(if params (format " %s" params) ""))))

(defun cider-add-clojure-dependencies-maybe (dependencies)
"Return DEPENDENCIES with an added Clojure dependency if requested.
See also `cider-jack-in-auto-inject-clojure'."
Expand Down Expand Up @@ -682,6 +730,12 @@ COMMAND is the resolved jack-in command, used to handle PowerShell quoting."
(cider-add-clojure-dependencies-maybe cider-jack-in-dependencies)
(cider-jack-in-normalized-nrepl-middlewares)))

(defun cider--clojure-clr-cli-inject-deps (params _project-type _command)
"Inject CIDER deps into PARAMS for a ClojureCLR CLI project."
(cider-clojure-clr-cli-jack-in-dependencies
params
`(("io.github.clojure/clr.tools.nrepl" ,cider-clojure-clr-cli-nrepl-sha))))

(defun cider-inject-jack-in-dependencies (params project-type &optional command)
"Return PARAMS with injected REPL dependencies for PROJECT-TYPE.
Looks up the tool's :inject-fn in `cider-jack-in-tools' and calls it with
Expand Down Expand Up @@ -849,6 +903,13 @@ Throws an error if PROJECT-TYPE is unknown."
:project-files '("basilisp.edn")
:universal-prefix-arg 5)

(cider-register-jack-in-tool 'clojure-clr-cli
:command-var 'cider-clojure-clr-cli-command
:params-var 'cider-clojure-clr-cli-parameters
:project-files '("deps-clr.edn")
:inject-fn #'cider--clojure-clr-cli-inject-deps
:universal-prefix-arg 6)


;;; ClojureScript jack-in helpers

Expand Down
Loading