Skip to content

Commit 8766a70

Browse files
Add jack-in support for ClojureCLR
1 parent 8a4405c commit 8766a70

File tree

4 files changed

+74
-17
lines changed

4 files changed

+74
-17
lines changed

CHANGELOG.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@
44

55
### New features
66

7+
- [#3839](https://github.com/clojure-emacs/cider/pull/3839): Add jack-in support for ClojureCLR.
8+
79
### Changes
810

911
### Bugs fixed

cider.el

Lines changed: 59 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -298,6 +298,26 @@ By default we favor the project-specific shadow-cljs over the system-wide."
298298
:safe #'stringp
299299
:package-version '(cider . "1.14.0"))
300300

301+
(defcustom cider-clr-command
302+
"cljr"
303+
"The command used to execute ClojureCLR."
304+
:type 'string
305+
:safe #'stringp
306+
:package-version '(cider . "1.20.0"))
307+
308+
(defcustom cider-clr-parameters
309+
"-X clojure.tools.nrepl/start-server!"
310+
"Params passed to ClojureCLR to start an nREPL server via `cider-jack-in'."
311+
:type 'string
312+
:safe #'stringp
313+
:package-version '(cider . "1.20.0"))
314+
315+
(defcustom cider-clr-nrepl-version "v0.1.2-alpha2"
316+
"The version of clr.tools.nrepl injected on jack-in with ClojureCLR."
317+
:type 'string
318+
:safe #'stringp
319+
:package-version '(cider . "1.20.0"))
320+
301321
(make-obsolete-variable 'cider-lein-global-options 'cider-lein-parameters "1.8.0")
302322
(make-obsolete-variable 'cider-boot-command nil "1.8.0")
303323
(make-obsolete-variable 'cider-boot-parameters nil "1.8.0")
@@ -325,7 +345,8 @@ to Leiningen."
325345
(const gradle)
326346
(const babashka)
327347
(const nbb)
328-
(const basilisp))
348+
(const basilisp)
349+
(const clr))
329350
:safe #'symbolp
330351
:package-version '(cider . "0.9.0"))
331352

@@ -346,6 +367,7 @@ command when there is no ambiguity."
346367
(const babashka)
347368
(const nbb)
348369
(const basilisp)
370+
(const clr)
349371
(const :tag "Always ask" nil))
350372
:safe #'symbolp
351373
:package-version '(cider . "0.13.0"))
@@ -419,7 +441,8 @@ Sub-match 1 must be the project path.")
419441
(lein (:prefix-arg 2 :cmd (:jack-in-type clj :project-type lein :edit-project-dir t)))
420442
(babashka (:prefix-arg 3 :cmd (:jack-in-type clj :project-type babashka :edit-project-dir t)))
421443
(nbb (:prefix-arg 4 :cmd (:jack-in-type cljs :project-type nbb :cljs-repl-type nbb :edit-project-dir t)))
422-
(basilisp (:prefix-arg 5 :cmd (:jack-in-type clj :project-type basilisp :edit-project-dir t))))
444+
(basilisp (:prefix-arg 5 :cmd (:jack-in-type clj :project-type basilisp :edit-project-dir t)))
445+
(clr (:prefix-arg 6 :cmd (:jack-in-type clj :project-type clr :edit-project-dir t))))
423446
"The list of project tools that are supported by the universal jack in command.
424447
425448
Each item in the list consists of the tool name and its plist options.
@@ -451,6 +474,7 @@ The plist supports the following keys
451474
('gradle cider-gradle-command)
452475
('nbb cider-nbb-command)
453476
('basilisp cider-basilisp-command)
477+
('clr cider-clr-command)
454478
(_ (user-error "Unsupported project type `%S'" project-type))))
455479

456480
(defcustom cider-enrich-classpath nil
@@ -482,6 +506,7 @@ Throws an error if PROJECT-TYPE is unknown."
482506
;; the exec-path
483507
('gradle (cider--resolve-project-command cider-gradle-command))
484508
('basilisp (cider--resolve-command cider-basilisp-command))
509+
('clr (cider--resolve-command cider-clr-command))
485510
(_ (user-error "Unsupported project type `%S'" project-type))))
486511

487512
(defun cider-jack-in-global-options (project-type)
@@ -494,6 +519,7 @@ Throws an error if PROJECT-TYPE is unknown."
494519
('gradle cider-gradle-global-options)
495520
('nbb cider-nbb-global-options)
496521
('basilisp nil)
522+
('clr nil)
497523
(_ (user-error "Unsupported project type `%S'" project-type))))
498524

499525
(defun cider-jack-in-params (project-type)
@@ -510,6 +536,7 @@ Throws an error if PROJECT-TYPE is unknown."
510536
('gradle cider-gradle-parameters)
511537
('nbb cider-nbb-parameters)
512538
('basilisp cider-basilisp-parameters)
539+
('clr cider-clr-parameters)
513540
(_ (user-error "Unsupported project type `%S'" project-type))))
514541

515542

@@ -856,6 +883,30 @@ Does so by concatenating GLOBAL-OPTS, DEPENDENCIES finally PARAMS."
856883
" "
857884
params)))
858885

886+
(defun cider-clr-jack-in-dependencies (params dependencies &optional command)
887+
"Create ClojureCLR clr.core.cli jack-in dependencies.
888+
Does so by concatenating DEPENDENCIES, and PARAMS into a
889+
suitable `cljr` invocation and quoting, also accounting for COMMAND if
890+
provided."
891+
(let* ((all-deps (thread-last dependencies
892+
(cider--dedupe-deps)
893+
(seq-map (lambda (dep)
894+
(if (listp (cadr dep))
895+
(format "%s {%s}"
896+
(car dep)
897+
(seq-reduce
898+
(lambda (acc v)
899+
(concat acc (format " :%s \"%s\" " (car v) (cdr v))))
900+
(cadr dep)
901+
""))
902+
(format "%s {:git/tag \"%s\"}" (car dep) (cadr dep)))))))
903+
(deps (format "{:deps {%s}}"
904+
(string-join all-deps " ")))
905+
(deps-quoted (cider--shell-quote-argument deps command)))
906+
(format "-Sdeps %s %s"
907+
deps-quoted
908+
(if params (format " %s" params) ""))))
909+
859910
(defun cider-add-clojure-dependencies-maybe (dependencies)
860911
"Return DEPENDENCIES with an added Clojure dependency if requested.
861912
See also `cider-jack-in-auto-inject-clojure'."
@@ -915,6 +966,10 @@ dependencies."
915966
(unless (seq-empty-p global-opts) " ")
916967
params))
917968
('basilisp params)
969+
('clr (cider-clr-jack-in-dependencies
970+
params
971+
`(("io.github.clojure/clr.tools.nrepl" ,cider-clr-nrepl-version))
972+
command))
918973
(_ (error "Unsupported project type `%S'" project-type))))
919974

920975

@@ -2031,7 +2086,8 @@ PROJECT-DIR defaults to current project."
20312086
(gradle . "build.gradle")
20322087
(gradle . "build.gradle.kts")
20332088
(nbb . "nbb.edn")
2034-
(basilisp . "basilisp.edn"))))
2089+
(basilisp . "basilisp.edn")
2090+
(clr . "deps-clr.edn"))))
20352091
(delq nil
20362092
(mapcar (lambda (candidate)
20372093
(when (file-exists-p (cdr candidate))

doc/modules/ROOT/pages/caveats.adoc

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -60,13 +60,12 @@ from your Emacs config.
6060

6161
== ClojureCLR Support
6262

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

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

7170
Those issues are not insurmountable, but are beyond the scope of our current roadmap.
7271
If someone would like to tackle them, we'd be happy to provide assistance.

doc/modules/ROOT/pages/platforms/clojureclr.adoc

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -2,27 +2,27 @@
22

33
== Current Status
44

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

8-
- https://github.com/clojure/clr.tools.nrepl[clr.tools.nrepl]: A direct (but incomplete) port of the reference Clojure nREPL server.
7+
- 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]).
8+
- 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
9+
ultimately better integrate with CIDER once CIDER's middleware (cider-nrepl) is also adapted/ported.
910
- https://github.com/arcadia-unity/Arcadia/blob/master/Editor/NRepl.cs[Arcadia's nREPL]: A basic, but working nREPL implementation in C#.
1011

11-
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
12-
more sophisticated project and ideally we should get it over to the finish line.
12+
An alternative to CIDER & a nREPL server is inf-clojure with ClojureCLR's stock socket REPL server.
1313

1414
== Usage
1515

1616
NOTE: Contributions welcome!
1717

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

2122
== Plans
2223

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

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

0 commit comments

Comments
 (0)