Skip to content

Commit 24b9891

Browse files
Allow connecting to nbb via connect-clj (clojure-emacs#3061) (clojure-emacs#3272)
This is for nbb, scittle, joyride. Better support for "pain" repls, support "cljs" without setup. We want to: 1. connect with a plain nREPL client 2. make any assumptions explicit about the nREPL server/runtime 3. connect cljs buffers with those plain repls 1. Check for cider middleware being present, before using it (already being done) 2. Check for cider-library-present-p, before relying on anything in the runtime. 3. Make assumptions about the runtime explicit My suggestion is to solve these problems is `cider-connection-capabilities`. Currently, there was an implicit assumption about the compilation error format. Changes to `cider-repls`: Now returns cljs, if the repl capabilities include 'cljs. This way we can make a "plain" clj client, upgrade on connect with cljs capability and have it be connected in cljs buffers. This is more a concession / workaround the current repl-type setup. Here's the slack discussion that lead to this PR: https://clojurians.slack.com/archives/C04CAKAGADU
1 parent 5064287 commit 24b9891

File tree

9 files changed

+108
-7
lines changed

9 files changed

+108
-7
lines changed

CHANGELOG.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,8 @@
1717
- [#3251](https://github.com/clojure-emacs/cider/pull/3251): Disable undo in `*cider-stacktrace*` buffers.
1818
- Consecutive overlays will not be spuriously deleted.
1919
- [#3260](https://github.com/clojure-emacs/cider/pull/3260): Scroll REPL buffer in other frame.
20+
- [#3061](https://github.com/clojure-emacs/cider/issues/3061): Allow
21+
connect-clj for plain cljs repls (nbb etc).
2022

2123
## 1.5.0 (2022-08-24)
2224

cider-connection.el

Lines changed: 33 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -343,6 +343,19 @@ buffer."
343343
(when cider-auto-mode
344344
(cider-enable-on-existing-clojure-buffers))
345345

346+
(setf cider-connection-capabilities
347+
(append
348+
(pcase (cider-runtime)
349+
('clojure '(clojure jvm-compilation-errors))
350+
('babashka '(babashka jvm-compilation-errors))
351+
(_ '()))
352+
(when
353+
;; see `cider-sync-tooling-eval', but it is defined on a higher layer
354+
(nrepl-dict-get
355+
(nrepl-sync-request:eval "cljs.core/demunge" (current-buffer) nil 'tooling)
356+
"value")
357+
'(cljs))))
358+
346359
(run-hooks 'cider-connected-hook)))))
347360

348361
(defun cider--disconnected-handler ()
@@ -437,6 +450,19 @@ about this buffer (like variable `cider-repl-type')."
437450
(plist-get nrepl-endpoint :host)
438451
(plist-get nrepl-endpoint :port))))))
439452

453+
(defvar-local cider-connection-capabilities '()
454+
"A list of some of the capabilites of this connection buffer.
455+
Aka what assumptions we make about the runtime.
456+
This is more general than
457+
`cider-nrepl-op-supported-p' and `cider-library-present-p'.
458+
But does not need to replace them.")
459+
460+
(defun cider-connection-has-capability-p (capability :optional connection-buffer)
461+
"Return non nil when the cider connection has CAPABILITY.
462+
By default it assumes the connection buffer is current."
463+
(with-current-buffer (or connection-buffer (current-buffer))
464+
(member capability cider-connection-capabilities)))
465+
440466

441467
;;; Connection Management Commands
442468

@@ -885,7 +911,13 @@ no linked session or there is no REPL of TYPE within the current session."
885911
(cond ((null buffer-repl-type) nil)
886912
((or (null type) (eq type 'multi) (eq type 'any)) t)
887913
((listp type) (member buffer-repl-type type))
888-
(t (string= type buffer-repl-type)))))
914+
(t
915+
(or (string= type buffer-repl-type)
916+
(let ((capabilities
917+
(buffer-local-value 'cider-connection-capabilities buffer)))
918+
(cond ((listp type)
919+
(cl-some (lambda (it) (member it capabilities)) type))
920+
(t (member type capabilities)))))))))
889921

890922
(defun cider--get-host-from-session (session)
891923
"Returns the host associated with SESSION."

cider-eval.el

Lines changed: 15 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -462,6 +462,13 @@ Uses the value of the `out' slot in RESPONSE."
462462
(cider-nrepl-sync-request:eval
463463
"(clojure.stacktrace/print-cause-trace *e)")))
464464

465+
(defun cider-default-err-eval-print-handler ()
466+
"Display the last exception without middleware support.
467+
When clojure.stracktrace is not present."
468+
(cider--handle-err-eval-response
469+
(cider-nrepl-sync-request:eval
470+
"(println (ex-data *e))")))
471+
465472
(defun cider--render-stacktrace-causes (causes &optional error-types)
466473
"If CAUSES is non-nil, render its contents into a new error buffer.
467474
Optional argument ERROR-TYPES contains a list which should determine the
@@ -498,9 +505,10 @@ into a new error buffer."
498505
(defun cider-default-err-handler ()
499506
"This function determines how the error buffer is shown.
500507
It delegates the actual error content to the eval or op handler."
501-
(if (cider-nrepl-op-supported-p "stacktrace")
502-
(cider-default-err-op-handler)
503-
(cider-default-err-eval-handler)))
508+
(cond ((cider-nrepl-op-supported-p "stacktrace") (cider-default-err-op-handler))
509+
((cider-library-present-p "clojure.stacktrace") (cider-default-err-eval-handler))
510+
(t (cider-default-err-eval-print-handler))))
511+
504512

505513
;; The format of the error messages emitted by Clojure's compiler changed in
506514
;; Clojure 1.10. That's why we're trying to match error messages to both the
@@ -739,7 +747,10 @@ when `cider-auto-inspect-after-eval' is non-nil."
739747
(cider-emit-interactive-eval-output out))
740748
(lambda (_buffer err)
741749
(cider-emit-interactive-eval-err-output err)
742-
(unless cider-show-error-buffer
750+
751+
(when (or (not cider-show-error-buffer)
752+
(not (cider-connection-has-capability-p 'jvm-compilation-errors)))
753+
743754
;; Display errors as temporary overlays
744755
(let ((cider-result-use-clojure-font-lock nil))
745756
(cider--display-interactive-eval-result

cider-overlays.el

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -303,6 +303,7 @@ focused."
303303
(let* ((font-value (if cider-result-use-clojure-font-lock
304304
(cider-font-lock-as-clojure value)
305305
value))
306+
(font-value (string-trim-right font-value))
306307
(used-overlay (when (and point cider-use-overlays)
307308
(cider--make-result-overlay font-value
308309
:where point

cider-repl.el

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -153,7 +153,8 @@ you'd like to use the default Emacs behavior use
153153
(make-obsolete-variable 'cider-repl-print-level 'cider-print-options "0.21")
154154

155155
(defvar cider-repl-require-repl-utils-code
156-
'((clj . "(clojure.core/apply clojure.core/require clojure.main/repl-requires)")
156+
'((clj . "(when-let [requires (resolve 'clojure.main/repl-requires)]
157+
(clojure.core/apply clojure.core/require @requires))")
157158
(cljs . "(require '[cljs.repl :refer [apropos dir doc find-doc print-doc pst source]])")))
158159

159160
(defcustom cider-repl-init-code (list (cdr (assoc 'clj cider-repl-require-repl-utils-code)))

cider.el

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -778,9 +778,13 @@ Generally you should not disable this unless you run into some faulty check."
778778
:safe #'booleanp
779779
:package-version '(cider . "0.17.0"))
780780

781+
(defun cider-clojurescript-present-p ()
782+
"Return non nil when ClojureScript is present."
783+
(nrepl-dict-get (cider-sync-tooling-eval "cljs.core/demunge") "value"))
784+
781785
(defun cider-verify-clojurescript-is-present ()
782786
"Check whether ClojureScript is present."
783-
(unless (cider-library-present-p "cljs.core")
787+
(unless (cider-clojurescript-present-p)
784788
(user-error "ClojureScript is not available. See https://docs.cider.mx/cider/basics/clojurescript for details")))
785789

786790
(defun cider-verify-piggieback-is-present ()

doc/modules/ROOT/nav.adoc

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
* Alternative Platforms
1414
** xref:platforms/overview.adoc[Overview]
1515
** xref:platforms/babashka.adoc[Babashka]
16+
** xref:platforms/scittle_and_friends.adoc[Scittle and Friends]
1617
* Using CIDER
1718
** xref:usage/interactive_programming.adoc[Interactive Programming]
1819
** xref:usage/cider_mode.adoc[Using cider-mode]
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
= Scittle, Nbb, Joyride, and future plain repls
2+
3+
The default cider (clj-repl) should be capable of connecting to any
4+
nrepl server that provides minimal functionality.
5+
6+
As such, all of these work:
7+
https://github.com/babashka/nbb[nbb],
8+
https://github.com/babashka/scittle[scittle], https://github.com/BetterThanTomorrow/joyride[joyride]
9+
10+
First start an nrepl server (the project's Readme usually has a section
11+
on starting a nrepl server).
12+
13+
You can use
14+
15+
kbd:[M-x `cider-connect-clj` <RET>]
16+
17+
to connect to any plain Clojure(Script) nrepl server.
18+
19+
Features:
20+
21+
* Eval, load file etc.
22+
* Errors as overlays. (The default cider error buffer is not implemented currently).
23+
* Other nrepl features the server provides; This might be rather minimal.
24+
25+
Nbb, Scittle and Joyride all have quite cool completions already.
26+
27+
== Note
28+
29+
For nbb you can alternatively connect via cljs, see xref:platform/nbb.adoc[Nbb]

test/cider-connection-tests.el

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -370,6 +370,26 @@
370370
(expect (cider-repls) :to-equal (list a b))
371371
(kill-buffer b)
372372
(expect (cider-repls) :to-equal (list a))
373+
(sesman-unregister 'CIDER session))))))
374+
375+
(describe "cljs capability"
376+
(it "Upgraded clj repl counts as cljs"
377+
(let ((default-directory (expand-file-name "/tmp/some-dir")))
378+
(cider-test-with-buffers
379+
(a b)
380+
(let ((session (list "some-session" a b)))
381+
(with-current-buffer a
382+
(setq cider-repl-type 'clj))
383+
(with-current-buffer b
384+
(setq cider-repl-type 'cljs))
385+
(sesman-register 'CIDER session)
386+
(expect (cider-repls 'cljs) :to-equal (list b))
387+
388+
(with-current-buffer a
389+
(setf cider-connection-capabilities
390+
(append cider-connection-capabilities '(cljs))))
391+
392+
(expect (cider-repls) :to-equal (list a b))
373393
(sesman-unregister 'CIDER session)))))))
374394

375395
(describe "cider--connection-info"

0 commit comments

Comments
 (0)