branch: elpa/cider
commit 9b3f84645b1e81e9fe7981aab48d5c46424b512a
Author: Vilppu Saarinen <[email protected]>
Commit: GitHub <[email protected]>

    [Fix #3834] Extend cider-repls to filter out REPLs that don't support 
needed operations
---
 CHANGELOG.md                   |  2 ++
 cider-client.el                | 22 +++++++++++-----------
 cider-connection.el            | 27 +++++++++++++++++----------
 cider-ns.el                    | 12 +++++-------
 cider-tracing.el               |  3 +--
 test/cider-connection-tests.el | 20 +++++++++++++++++++-
 6 files changed, 55 insertions(+), 31 deletions(-)

diff --git a/CHANGELOG.md b/CHANGELOG.md
index 23bc338c0f3..c9cb86d4133 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -11,6 +11,7 @@
 - Bump the injected `piggieback` to 
[0.6.1](https://github.com/nrepl/piggieback/blob/master/CHANGES.md#061-2025-12-31).
 - Bump the injected `cider-nrepl` to 
[0.58.0](https://github.com/clojure-emacs/cider-nrepl/blob/master/CHANGELOG.md#0580-2025-10-16).
   - * 
[cider-nrepl#951](https://github.com/clojure-emacs/cider-nrepl/pull/951): 
Debug: correctly process #dbg tag during load-file.
+- [#3834](https://github.com/clojure-emacs/cider/issues/3834): Change 
cider-ns-refresh to always use Clojure REPL.
 
 ### Bugs fixed
 
@@ -18,6 +19,7 @@
 - [#3837](https://github.com/clojure-emacs/cider/issues/3837): Fix broken 
stacktrace response when C-c C-p throws an exception.
 - [orchard#353](https://github.com/clojure-emacs/orchard/pull/353): 
Stacktrace: flag Clojure functions as duplicate.
 - [orchard#355](https://github.com/clojure-emacs/orchard/pull/355): Java: 
resolve source files for non-base JDK classes.
+- [#3834](https://github.com/clojure-emacs/cider/issues/3834): Fix 
cider-ns-refresh throwing an error when a clojure REPL exists, but 
cider-current-repl does not support the required operations.
 
 ## 1.19.0 (2025-07-10)
 
diff --git a/cider-client.el b/cider-client.el
index 97bd02a4d31..7771b42d2f0 100644
--- a/cider-client.el
+++ b/cider-client.el
@@ -175,10 +175,10 @@ Skip check if repl is active if SKIP-ENSURE is non nil."
                                                               nil
                                                             'ensure)))))
 
-(defun cider-ensure-op-supported (op)
-  "Check for support of middleware op OP.
+(defun cider-ensure-op-supported (op &optional connection)
+  "Check for support of middleware op OP for CONNECTION.
 Signal an error if it is not supported."
-  (unless (cider-nrepl-op-supported-p op)
+  (unless (cider-nrepl-op-supported-p op connection)
     (user-error "`%s' requires the nREPL op \"%s\" (provided by cider-nrepl)" 
this-command op)))
 
 (defun cider-nrepl-send-request (request callback &optional connection tooling)
@@ -623,12 +623,12 @@ Optional arguments include SEARCH-NS, DOCS-P, PRIVATES-P, 
CASE-SENSITIVE-P."
         (user-error "Invalid regexp: %s" (nrepl-dict-get response "error-msg"))
       (nrepl-dict-get response "apropos-matches"))))
 
-(defun cider-sync-request:classpath ()
-  "Return a list of classpath entries."
-  (cider-ensure-op-supported "classpath")
+(defun cider-sync-request:classpath (&optional connection)
+  "Return a list of classpath entries for CONNECTION."
+  (cider-ensure-op-supported "classpath" connection)
   (thread-first
     '("op" "classpath")
-    (cider-nrepl-send-sync-request)
+    (cider-nrepl-send-sync-request connection)
     (nrepl-dict-get "classpath")))
 
 (defun cider--get-abs-path (path project)
@@ -652,11 +652,11 @@ resolve those to absolute paths."
           (project (clojure-project-dir)))
       (mapcar (lambda (path) (cider--get-abs-path path project)) classpath))))
 
-(defun cider-classpath-entries ()
-  "Return a list of classpath entries."
+(defun cider-classpath-entries (&optional connection)
+  "Return a list of classpath entries for CONNECTION."
   (seq-map #'expand-file-name ; normalize filenames for e.g. Windows
-           (if (cider-nrepl-op-supported-p "classpath")
-               (cider-sync-request:classpath)
+           (if (cider-nrepl-op-supported-p "classpath" connection)
+               (cider-sync-request:classpath connection)
              (cider-fallback-eval:classpath))))
 
 (defun cider-sync-request:completion (prefix)
diff --git a/cider-connection.el b/cider-connection.el
index f4181330e96..6d96043df34 100644
--- a/cider-connection.el
+++ b/cider-connection.el
@@ -1015,11 +1015,12 @@ Returns a list of the form ((session1 host1) (session2 
host2) ...)."
              sessions
              :initial-value '()))
 
-(defun cider-repls (&optional type ensure)
+(defun cider-repls (&optional type ensure required-ops)
   "Return cider REPLs of TYPE from the current session.
 If TYPE is nil or multi, return all REPLs.  If TYPE is a list of types,
 return only REPLs of type contained in the list.  If ENSURE is non-nil,
-throw an error if no linked session exists."
+throw an error if no linked session exists.  If REQUIRED-OPS is non-nil,
+filters out all the REPLs that do not support the designated ops."
   (let ((type (cond
                ((listp type)
                 (mapcar #'cider-maybe-intern type))
@@ -1045,7 +1046,10 @@ throw an error if no linked session exists."
     (or (seq-filter (lambda (b)
                       (unless
                           (cider-cljs-pending-p b)
-                        (cider--match-repl-type type b)))
+                        (and (cider--match-repl-type type b)
+                             (seq-every-p (lambda (op)
+                                            (nrepl-op-supported-p op b))
+                                          required-ops))))
                     repls)
         (when ensure
           (cider--no-repls-user-error type)))))
@@ -1053,8 +1057,9 @@ throw an error if no linked session exists."
 (defun cider-map-repls (which function)
   "Call FUNCTION once for each appropriate REPL as indicated by WHICH.
 The function is called with one argument, the REPL buffer.  The appropriate
-connections are found by inspecting the current buffer.  WHICH is one of
-the following keywords:
+connections are found by inspecting the current buffer.  WHICH is either one of
+the following keywords or a list starting with one of them followed by names of
+operations that the REPL is expected to support:
  :auto - Act on the connections whose type matches the current buffer.  In
      `cljc' files, mapping happens over both types of REPLs.
  :clj (:cljs) - Map over clj (cljs)) REPLs only.
@@ -1064,22 +1069,24 @@ the following keywords:
 Error is signaled if no REPL buffers of specified type exist in current
 session."
   (declare (indent 1))
-  (let ((cur-type (cider-repl-type-for-buffer)))
-    (cl-case which
+  (let ((cur-type (cider-repl-type-for-buffer))
+        (which-key (or (car-safe which) which))
+        (required-ops (cdr-safe which)))
+    (cl-case which-key
       (:clj-strict (when (eq cur-type 'cljs)
                      (user-error "Clojure-only operation requested in a 
ClojureScript buffer")))
       (:cljs-strict (when (eq cur-type 'clj)
                       (user-error "ClojureScript-only operation requested in a 
Clojure buffer"))))
-    (let* ((type (cl-case which
+    (let* ((type (cl-case which-key
                    ((:clj :clj-strict) 'clj)
                    ((:cljs :cljs-strict) 'cljs)
                    (:auto (if (eq cur-type 'multi)
                               '(clj cljs)
                             cur-type))))
-           (ensure (cl-case which
+           (ensure (cl-case which-key
                      (:auto nil)
                      (t 'ensure)))
-           (repls (cider-repls type ensure)))
+           (repls (cider-repls type ensure required-ops)))
       (mapcar function repls))))
 
 ;; REPLs double as connections in CIDER, so it's useful to be able to refer to
diff --git a/cider-ns.el b/cider-ns.el
index 1f56c209987..e99e6a01493 100644
--- a/cider-ns.el
+++ b/cider-ns.el
@@ -219,13 +219,13 @@ presenting the error message as an overlay."
                error)
       (cider-ns--present-error error))))
 
-(defun cider-ns-refresh--save-modified-buffers ()
-  "Ensure any relevant modified buffers are saved before refreshing.
+(defun cider-ns-refresh--save-modified-buffers (&optional connection)
+  "Ensure any relevant modified buffers for CONNECTION are saved before 
refreshing.
 Its behavior is controlled by `cider-ns-save-files-on-refresh' and
 `cider-ns-save-files-on-refresh-modes'."
   (when cider-ns-save-files-on-refresh
     (let ((dirs (seq-filter #'file-directory-p
-                            (cider-classpath-entries))))
+                            (cider-classpath-entries connection))))
       (save-some-buffers
        (not (eq cider-ns-save-files-on-refresh 'prompt))
        (lambda ()
@@ -297,14 +297,12 @@ refresh functions (defined in 
`cider-ns-refresh-before-fn' and
 `cider-ns-refresh-after-fn') from being invoked."
   (interactive "p")
   (cider-ensure-connected)
-  (cider-ensure-op-supported "refresh")
-  (cider-ensure-op-supported "cider.clj-reload/reload")
-  (cider-ns-refresh--save-modified-buffers)
   (let ((clear? (member mode '(clear 16)))
         (all? (member mode '(refresh-all 4)))
         (inhibit-refresh-fns (member mode '(inhibit-fns -1))))
-    (cider-map-repls :clj
+    (cider-map-repls '(:clj "refresh" "cider.clj-reload/reload")
       (lambda (conn)
+        (cider-ns-refresh--save-modified-buffers conn)
         ;; Inside the lambda, so the buffer is not created if we error out.
         (let ((log-buffer (or (get-buffer cider-ns-refresh-log-buffer)
                               (cider-make-popup-buffer 
cider-ns-refresh-log-buffer))))
diff --git a/cider-tracing.el b/cider-tracing.el
index bccaea4077e..3efe0a7cf24 100644
--- a/cider-tracing.el
+++ b/cider-tracing.el
@@ -72,10 +72,9 @@ opposite of what that option dictates."
   "Toggle ns tracing.
 Defaults to the current ns.  With prefix arg QUERY, prompts for a ns."
   (interactive "P")
-  (cider-map-repls :clj-strict
+  (cider-map-repls '(:clj-strict  "toggle-trace-ns")
     (lambda (conn)
       (with-current-buffer conn
-        (cider-ensure-op-supported "toggle-trace-ns")
         (let ((ns (if query
                       (completing-read "Toggle trace for ns: "
                                        (cider-sync-request:ns-list))
diff --git a/test/cider-connection-tests.el b/test/cider-connection-tests.el
index 60a6765e2df..2fc7a0c98a2 100644
--- a/test/cider-connection-tests.el
+++ b/test/cider-connection-tests.el
@@ -398,7 +398,25 @@
                    (append cider-connection-capabilities '(cljs))))
 
            (expect (cider-repls) :to-equal (list a b))
-           (sesman-unregister 'CIDER session)))))))
+           (sesman-unregister 'CIDER session))))))
+
+  (describe "when required-ops is not nil"
+    :var (nrepl-ops)
+    (it "only returns the repls that support the given ops"
+      (let ((proj-dir (expand-file-name "/tmp/proj-dir")))
+        (let ((default-directory proj-dir))
+          (with-repl-buffer ses-name 'clj b1
+            (setq nrepl-ops (nrepl-dict "refresh" 't))
+            (with-repl-buffer ses-name 'clj b2
+              (with-repl-buffer ses-name 'cljs b3
+                (expect (cider-repls nil nil '("refresh")) :to-equal (list 
b1))))))))
+    (it "raises a user error when ensure is not nil and no repl that supports 
the ops exist"
+      (let ((proj-dir (expand-file-name "/tmp/proj-dir")))
+        (let ((default-directory proj-dir))
+          (with-repl-buffer ses-name 'clj b1
+            (with-repl-buffer ses-name 'cljs b2
+              (expect (cider-repls nil 't '("refresh")) :to-throw 
'user-error))))))))
+
 
 (describe "cider--connection-info"
   (before-each

Reply via email to