diff --git a/CHANGELOG.md b/CHANGELOG.md index 4792e29ff..a0cad9b5d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -17,6 +17,8 @@ - [#3251](https://github.com/clojure-emacs/cider/pull/3251): Disable undo in `*cider-stacktrace*` buffers. - Consecutive overlays will not be spuriously deleted. - [#3260](https://github.com/clojure-emacs/cider/pull/3260): Scroll REPL buffer in other frame. +- [#3061](https://github.com/clojure-emacs/cider/issues/3061): Allow + connect-clj for plain cljs repls (nbb etc). ## 1.5.0 (2022-08-24) diff --git a/cider-connection.el b/cider-connection.el index dace07129..7b5fa4f76 100644 --- a/cider-connection.el +++ b/cider-connection.el @@ -343,6 +343,14 @@ buffer." (when cider-auto-mode (cider-enable-on-existing-clojure-buffers)) + (setf cider-connection-capabilities + (append + (pcase (cider-runtime) + ('clojure '(clojure jvm-compilation-errors)) + ('babashka '(babashka jvm-compilation-errors)) + (_ '())) + (when (cider-clojurescript-present-p) '(cljs)))) + (run-hooks 'cider-connected-hook))))) (defun cider--disconnected-handler () @@ -437,6 +445,22 @@ about this buffer (like variable `cider-repl-type')." (plist-get nrepl-endpoint :host) (plist-get nrepl-endpoint :port)))))) +(defun cider-clojurescript-present-p () + "Return non nil when ClojureScript is present." + (nrepl-dict-get (cider-sync-tooling-eval "cljs.core/inc") "value")) + +(defvar-local cider-connection-capabilities '() + "A list of some of the capabilites of this connection buffer. +Aka what assumptions we make about the runtime. Aka stuff we needed to make explicit +in order for nbb to work. +This is more genaral than `cider-nrepl-op-supported-p' and `cider-library-present-p'. +But does not need to replace them.") + +(defun cider-connection-has-capability-p (capability) + "Return non nil when the cider connection has CAPABILITY." + (with-current-buffer (cider-current-repl) + (member capability cider-connection-capabilities))) + ;;; Connection Management Commands @@ -885,7 +909,13 @@ no linked session or there is no REPL of TYPE within the current session." (cond ((null buffer-repl-type) nil) ((or (null type) (eq type 'multi) (eq type 'any)) t) ((listp type) (member buffer-repl-type type)) - (t (string= type buffer-repl-type))))) + (t + (or (string= type buffer-repl-type) + (let ((capabilities + (buffer-local-value 'cider-connection-capabilities buffer))) + (cond ((listp type) + (cl-some (lambda (it) (member it capabilities)) type)) + (t (member type capabilities))))))))) (defun cider--get-host-from-session (session) "Returns the host associated with SESSION." diff --git a/cider-eval.el b/cider-eval.el index 6e1fd4440..a7c4aecbc 100644 --- a/cider-eval.el +++ b/cider-eval.el @@ -462,6 +462,13 @@ Uses the value of the `out' slot in RESPONSE." (cider-nrepl-sync-request:eval "(clojure.stacktrace/print-cause-trace *e)"))) +(defun cider-default-err-eval-print-handler () + "Display the last exception without middleware support. +When clojure.stracktrace is not present." + (cider--handle-err-eval-response + (cider-nrepl-sync-request:eval + "(println (ex-data *e))"))) + (defun cider--render-stacktrace-causes (causes &optional error-types) "If CAUSES is non-nil, render its contents into a new error buffer. Optional argument ERROR-TYPES contains a list which should determine the @@ -498,9 +505,10 @@ into a new error buffer." (defun cider-default-err-handler () "This function determines how the error buffer is shown. It delegates the actual error content to the eval or op handler." - (if (cider-nrepl-op-supported-p "stacktrace") - (cider-default-err-op-handler) - (cider-default-err-eval-handler))) + (cond ((cider-nrepl-op-supported-p "stacktrace") (cider-default-err-op-handler)) + ((cider-library-present-p "clojure.stacktrace") (cider-default-err-eval-handler)) + (t (cider-default-err-eval-print-handler)))) + ;; The format of the error messages emitted by Clojure's compiler changed in ;; Clojure 1.10. That's why we're trying to match error messages to both the @@ -739,7 +747,9 @@ when `cider-auto-inspect-after-eval' is non-nil." (cider-emit-interactive-eval-output out)) (lambda (_buffer err) (cider-emit-interactive-eval-err-output err) - (unless cider-show-error-buffer + (when (or (not cider-show-error-buffer) + (not (cider-connection-has-capability-p 'jvm-compilation-errors))) + ;; Display errors as temporary overlays (let ((cider-result-use-clojure-font-lock nil)) (cider--display-interactive-eval-result diff --git a/cider-overlays.el b/cider-overlays.el index 3c56e8060..614388a07 100644 --- a/cider-overlays.el +++ b/cider-overlays.el @@ -303,6 +303,7 @@ focused." (let* ((font-value (if cider-result-use-clojure-font-lock (cider-font-lock-as-clojure value) value)) + (font-value (string-trim-right font-value)) (used-overlay (when (and point cider-use-overlays) (cider--make-result-overlay font-value :where point diff --git a/cider-repl.el b/cider-repl.el index eff5f99ba..80f47ec04 100644 --- a/cider-repl.el +++ b/cider-repl.el @@ -153,7 +153,8 @@ you'd like to use the default Emacs behavior use (make-obsolete-variable 'cider-repl-print-level 'cider-print-options "0.21") (defvar cider-repl-require-repl-utils-code - '((clj . "(clojure.core/apply clojure.core/require clojure.main/repl-requires)") + '((clj . "(when-let [requires (resolve 'clojure.main/repl-requires)] + (clojure.core/apply clojure.core/require @requires))") (cljs . "(require '[cljs.repl :refer [apropos dir doc find-doc print-doc pst source]])"))) (defcustom cider-repl-init-code (list (cdr (assoc 'clj cider-repl-require-repl-utils-code))) diff --git a/cider.el b/cider.el index b79c89a0a..c931a2178 100644 --- a/cider.el +++ b/cider.el @@ -780,7 +780,7 @@ Generally you should not disable this unless you run into some faulty check." (defun cider-verify-clojurescript-is-present () "Check whether ClojureScript is present." - (unless (cider-library-present-p "cljs.core") + (unless (cider-clojurescript-present-p) (user-error "ClojureScript is not available. See https://docs.cider.mx/cider/basics/clojurescript for details"))) (defun cider-verify-piggieback-is-present () diff --git a/test/cider-connection-tests.el b/test/cider-connection-tests.el index 1ff79dd52..a096d0a03 100644 --- a/test/cider-connection-tests.el +++ b/test/cider-connection-tests.el @@ -370,6 +370,26 @@ (expect (cider-repls) :to-equal (list a b)) (kill-buffer b) (expect (cider-repls) :to-equal (list a)) + (sesman-unregister 'CIDER session)))))) + + (describe "cljs capability" + (it "Upgraded clj repl counts as cljs" + (let ((default-directory (expand-file-name "/tmp/some-dir"))) + (cider-test-with-buffers + (a b) + (let ((session (list "some-session" a b))) + (with-current-buffer a + (setq cider-repl-type 'clj)) + (with-current-buffer b + (setq cider-repl-type 'cljs)) + (sesman-register 'CIDER session) + (expect (cider-repls 'cljs) :to-equal (list b)) + + (with-current-buffer a + (setf cider-connection-capabilities + (append cider-connection-capabilities '(cljs)))) + + (expect (cider-repls) :to-equal (list a b)) (sesman-unregister 'CIDER session))))))) (describe "cider--connection-info"