Skip to content

Commit 9b3f846

Browse files
authored
[Fix #3834] Extend cider-repls to filter out REPLs that don't support needed operations
1 parent 5e818d3 commit 9b3f846

File tree

6 files changed

+55
-31
lines changed

6 files changed

+55
-31
lines changed

CHANGELOG.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,13 +11,15 @@
1111
- Bump the injected `piggieback` to [0.6.1](https://github.com/nrepl/piggieback/blob/master/CHANGES.md#061-2025-12-31).
1212
- Bump the injected `cider-nrepl` to [0.58.0](https://github.com/clojure-emacs/cider-nrepl/blob/master/CHANGELOG.md#0580-2025-10-16).
1313
- * [cider-nrepl#951](https://github.com/clojure-emacs/cider-nrepl/pull/951): Debug: correctly process #dbg tag during load-file.
14+
- [#3834](https://github.com/clojure-emacs/cider/issues/3834): Change cider-ns-refresh to always use Clojure REPL.
1415

1516
### Bugs fixed
1617

1718
- [#3832](https://github.com/clojure-emacs/cider/issues/3832): Fix nrepl--eval-request sending duplicate info.
1819
- [#3837](https://github.com/clojure-emacs/cider/issues/3837): Fix broken stacktrace response when C-c C-p throws an exception.
1920
- [orchard#353](https://github.com/clojure-emacs/orchard/pull/353): Stacktrace: flag Clojure functions as duplicate.
2021
- [orchard#355](https://github.com/clojure-emacs/orchard/pull/355): Java: resolve source files for non-base JDK classes.
22+
- [#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.
2123

2224
## 1.19.0 (2025-07-10)
2325

cider-client.el

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -175,10 +175,10 @@ Skip check if repl is active if SKIP-ENSURE is non nil."
175175
nil
176176
'ensure)))))
177177

178-
(defun cider-ensure-op-supported (op)
179-
"Check for support of middleware op OP.
178+
(defun cider-ensure-op-supported (op &optional connection)
179+
"Check for support of middleware op OP for CONNECTION.
180180
Signal an error if it is not supported."
181-
(unless (cider-nrepl-op-supported-p op)
181+
(unless (cider-nrepl-op-supported-p op connection)
182182
(user-error "`%s' requires the nREPL op \"%s\" (provided by cider-nrepl)" this-command op)))
183183

184184
(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."
623623
(user-error "Invalid regexp: %s" (nrepl-dict-get response "error-msg"))
624624
(nrepl-dict-get response "apropos-matches"))))
625625

626-
(defun cider-sync-request:classpath ()
627-
"Return a list of classpath entries."
628-
(cider-ensure-op-supported "classpath")
626+
(defun cider-sync-request:classpath (&optional connection)
627+
"Return a list of classpath entries for CONNECTION."
628+
(cider-ensure-op-supported "classpath" connection)
629629
(thread-first
630630
'("op" "classpath")
631-
(cider-nrepl-send-sync-request)
631+
(cider-nrepl-send-sync-request connection)
632632
(nrepl-dict-get "classpath")))
633633

634634
(defun cider--get-abs-path (path project)
@@ -652,11 +652,11 @@ resolve those to absolute paths."
652652
(project (clojure-project-dir)))
653653
(mapcar (lambda (path) (cider--get-abs-path path project)) classpath))))
654654

655-
(defun cider-classpath-entries ()
656-
"Return a list of classpath entries."
655+
(defun cider-classpath-entries (&optional connection)
656+
"Return a list of classpath entries for CONNECTION."
657657
(seq-map #'expand-file-name ; normalize filenames for e.g. Windows
658-
(if (cider-nrepl-op-supported-p "classpath")
659-
(cider-sync-request:classpath)
658+
(if (cider-nrepl-op-supported-p "classpath" connection)
659+
(cider-sync-request:classpath connection)
660660
(cider-fallback-eval:classpath))))
661661

662662
(defun cider-sync-request:completion (prefix)

cider-connection.el

Lines changed: 17 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1015,11 +1015,12 @@ Returns a list of the form ((session1 host1) (session2 host2) ...)."
10151015
sessions
10161016
:initial-value '()))
10171017

1018-
(defun cider-repls (&optional type ensure)
1018+
(defun cider-repls (&optional type ensure required-ops)
10191019
"Return cider REPLs of TYPE from the current session.
10201020
If TYPE is nil or multi, return all REPLs. If TYPE is a list of types,
10211021
return only REPLs of type contained in the list. If ENSURE is non-nil,
1022-
throw an error if no linked session exists."
1022+
throw an error if no linked session exists. If REQUIRED-OPS is non-nil,
1023+
filters out all the REPLs that do not support the designated ops."
10231024
(let ((type (cond
10241025
((listp type)
10251026
(mapcar #'cider-maybe-intern type))
@@ -1045,16 +1046,20 @@ throw an error if no linked session exists."
10451046
(or (seq-filter (lambda (b)
10461047
(unless
10471048
(cider-cljs-pending-p b)
1048-
(cider--match-repl-type type b)))
1049+
(and (cider--match-repl-type type b)
1050+
(seq-every-p (lambda (op)
1051+
(nrepl-op-supported-p op b))
1052+
required-ops))))
10491053
repls)
10501054
(when ensure
10511055
(cider--no-repls-user-error type)))))
10521056

10531057
(defun cider-map-repls (which function)
10541058
"Call FUNCTION once for each appropriate REPL as indicated by WHICH.
10551059
The function is called with one argument, the REPL buffer. The appropriate
1056-
connections are found by inspecting the current buffer. WHICH is one of
1057-
the following keywords:
1060+
connections are found by inspecting the current buffer. WHICH is either one of
1061+
the following keywords or a list starting with one of them followed by names of
1062+
operations that the REPL is expected to support:
10581063
:auto - Act on the connections whose type matches the current buffer. In
10591064
`cljc' files, mapping happens over both types of REPLs.
10601065
:clj (:cljs) - Map over clj (cljs)) REPLs only.
@@ -1064,22 +1069,24 @@ the following keywords:
10641069
Error is signaled if no REPL buffers of specified type exist in current
10651070
session."
10661071
(declare (indent 1))
1067-
(let ((cur-type (cider-repl-type-for-buffer)))
1068-
(cl-case which
1072+
(let ((cur-type (cider-repl-type-for-buffer))
1073+
(which-key (or (car-safe which) which))
1074+
(required-ops (cdr-safe which)))
1075+
(cl-case which-key
10691076
(:clj-strict (when (eq cur-type 'cljs)
10701077
(user-error "Clojure-only operation requested in a ClojureScript buffer")))
10711078
(:cljs-strict (when (eq cur-type 'clj)
10721079
(user-error "ClojureScript-only operation requested in a Clojure buffer"))))
1073-
(let* ((type (cl-case which
1080+
(let* ((type (cl-case which-key
10741081
((:clj :clj-strict) 'clj)
10751082
((:cljs :cljs-strict) 'cljs)
10761083
(:auto (if (eq cur-type 'multi)
10771084
'(clj cljs)
10781085
cur-type))))
1079-
(ensure (cl-case which
1086+
(ensure (cl-case which-key
10801087
(:auto nil)
10811088
(t 'ensure)))
1082-
(repls (cider-repls type ensure)))
1089+
(repls (cider-repls type ensure required-ops)))
10831090
(mapcar function repls))))
10841091

10851092
;; REPLs double as connections in CIDER, so it's useful to be able to refer to

cider-ns.el

Lines changed: 5 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -219,13 +219,13 @@ presenting the error message as an overlay."
219219
error)
220220
(cider-ns--present-error error))))
221221

222-
(defun cider-ns-refresh--save-modified-buffers ()
223-
"Ensure any relevant modified buffers are saved before refreshing.
222+
(defun cider-ns-refresh--save-modified-buffers (&optional connection)
223+
"Ensure any relevant modified buffers for CONNECTION are saved before refreshing.
224224
Its behavior is controlled by `cider-ns-save-files-on-refresh' and
225225
`cider-ns-save-files-on-refresh-modes'."
226226
(when cider-ns-save-files-on-refresh
227227
(let ((dirs (seq-filter #'file-directory-p
228-
(cider-classpath-entries))))
228+
(cider-classpath-entries connection))))
229229
(save-some-buffers
230230
(not (eq cider-ns-save-files-on-refresh 'prompt))
231231
(lambda ()
@@ -297,14 +297,12 @@ refresh functions (defined in `cider-ns-refresh-before-fn' and
297297
`cider-ns-refresh-after-fn') from being invoked."
298298
(interactive "p")
299299
(cider-ensure-connected)
300-
(cider-ensure-op-supported "refresh")
301-
(cider-ensure-op-supported "cider.clj-reload/reload")
302-
(cider-ns-refresh--save-modified-buffers)
303300
(let ((clear? (member mode '(clear 16)))
304301
(all? (member mode '(refresh-all 4)))
305302
(inhibit-refresh-fns (member mode '(inhibit-fns -1))))
306-
(cider-map-repls :clj
303+
(cider-map-repls '(:clj "refresh" "cider.clj-reload/reload")
307304
(lambda (conn)
305+
(cider-ns-refresh--save-modified-buffers conn)
308306
;; Inside the lambda, so the buffer is not created if we error out.
309307
(let ((log-buffer (or (get-buffer cider-ns-refresh-log-buffer)
310308
(cider-make-popup-buffer cider-ns-refresh-log-buffer))))

cider-tracing.el

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -72,10 +72,9 @@ opposite of what that option dictates."
7272
"Toggle ns tracing.
7373
Defaults to the current ns. With prefix arg QUERY, prompts for a ns."
7474
(interactive "P")
75-
(cider-map-repls :clj-strict
75+
(cider-map-repls '(:clj-strict "toggle-trace-ns")
7676
(lambda (conn)
7777
(with-current-buffer conn
78-
(cider-ensure-op-supported "toggle-trace-ns")
7978
(let ((ns (if query
8079
(completing-read "Toggle trace for ns: "
8180
(cider-sync-request:ns-list))

test/cider-connection-tests.el

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -398,7 +398,25 @@
398398
(append cider-connection-capabilities '(cljs))))
399399

400400
(expect (cider-repls) :to-equal (list a b))
401-
(sesman-unregister 'CIDER session)))))))
401+
(sesman-unregister 'CIDER session))))))
402+
403+
(describe "when required-ops is not nil"
404+
:var (nrepl-ops)
405+
(it "only returns the repls that support the given ops"
406+
(let ((proj-dir (expand-file-name "/tmp/proj-dir")))
407+
(let ((default-directory proj-dir))
408+
(with-repl-buffer ses-name 'clj b1
409+
(setq nrepl-ops (nrepl-dict "refresh" 't))
410+
(with-repl-buffer ses-name 'clj b2
411+
(with-repl-buffer ses-name 'cljs b3
412+
(expect (cider-repls nil nil '("refresh")) :to-equal (list b1))))))))
413+
(it "raises a user error when ensure is not nil and no repl that supports the ops exist"
414+
(let ((proj-dir (expand-file-name "/tmp/proj-dir")))
415+
(let ((default-directory proj-dir))
416+
(with-repl-buffer ses-name 'clj b1
417+
(with-repl-buffer ses-name 'cljs b2
418+
(expect (cider-repls nil 't '("refresh")) :to-throw 'user-error))))))))
419+
402420

403421
(describe "cider--connection-info"
404422
(before-each

0 commit comments

Comments
 (0)