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