Skip to content

Commit ff43bb1

Browse files
raxod502bbatsov
authored andcommitted
Allow predicates in plugin and middleware lists
See clojure-emacs/clj-refactor.el#392 (comment)
1 parent 57d99d3 commit ff43bb1

File tree

3 files changed

+117
-9
lines changed

3 files changed

+117
-9
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
* [#2241](https://github.com/clojure-emacs/cider/pull/2241): Make `cider-test-ediff` diff eval'ed values.
2020
* Add support for shadow-cljs to `cider-jack-in`.
2121
* [#2244](https://github.com/clojure-emacs/cider/issues/2244): Display the REPL type in the modeline.
22+
* [#2238](https://github.com/clojure-emacs/cider/pull/2238): Allow specifying predicates for entries in `cider-jack-in-lein-plugins` and `cider-jack-in-nrepl-middlewares`.
2223

2324
### Bugs Fixed
2425

cider.el

Lines changed: 60 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -157,8 +157,10 @@ version from the CIDER package or library.")
157157
:package-version '(cider . "0.17.0"))
158158

159159
(defcustom cider-clojure-cli-parameters
160-
"-e '(require (quote cider-nrepl.main)) (cider-nrepl.main/init [\"cider.nrepl/cider-middleware\"])'"
161-
"Params passed to clojure to start an nREPL server via `cider-jack-in'."
160+
"-e '(require (quote cider-nrepl.main)) (cider-nrepl.main/init %s)'"
161+
"Params passed to clojure to start an nREPL server via `cider-jack-in'.
162+
This is evaluated using `format', with the first argument being the Clojure
163+
vector of middleware variables as a string."
162164
:type 'string
163165
:group 'cider
164166
:safe #'stringp
@@ -346,7 +348,14 @@ Throws an error if PROJECT-TYPE is unknown. Known types are
346348
(pcase project-type
347349
("lein" cider-lein-parameters)
348350
("boot" cider-boot-parameters)
349-
("clojure-cli" cider-clojure-cli-parameters)
351+
("clojure-cli" (format cider-clojure-cli-parameters
352+
(concat
353+
"["
354+
(mapconcat
355+
(apply-partially #'format "\"%s\"")
356+
(cider-jack-in-normalized-nrepl-middlewares)
357+
", ")
358+
"]")))
350359
("shadow-cljs" cider-shadow-cljs-parameters)
351360
("gradle" cider-gradle-parameters)
352361
(_ (user-error "Unsupported project type `%s'" project-type))))
@@ -385,17 +394,60 @@ specifying the artifact ID, and the second element the version number."
385394
(string :tag "Version"))))
386395

387396
(defvar cider-jack-in-lein-plugins nil
388-
"List of Leiningen plugins where elements are lists of artifact name and version.")
397+
"List of Leiningen plugins to be injected at jack-in.
398+
Each element is a list of artifact name and version, followed optionally by
399+
keyword arguments. The only keyword argument currently accepted is
400+
`:predicate', which should be given a function that takes the list (name,
401+
version, and keyword arguments) and returns non-nil to indicate that the
402+
plugin should actually be injected. (This is useful primarily for packages
403+
that extend CIDER, not for users. For example, a refactoring package might
404+
want to inject some middleware only when within a project context.)")
389405
(put 'cider-jack-in-lein-plugins 'risky-local-variable t)
390406
(cider-add-to-alist 'cider-jack-in-lein-plugins
391407
"cider/cider-nrepl" (upcase cider-version))
392408

409+
(defun cider-jack-in-normalized-lein-plugins ()
410+
"Return a normalized list of Leiningen plugins to be injected.
411+
See `cider-jack-in-lein-plugins' for the format, except that the list
412+
returned by this function does not include keyword arguments."
413+
(thread-last cider-jack-in-lein-plugins
414+
(seq-filter
415+
(lambda (spec)
416+
(if-let* ((pred (plist-get (seq-drop spec 2) :predicate)))
417+
(funcall pred spec)
418+
t)))
419+
(mapcar
420+
(lambda (spec)
421+
(seq-take spec 2)))))
422+
393423
(defvar cider-jack-in-nrepl-middlewares nil
394424
"List of Clojure variable names.
395-
Each of these Clojure variables should hold a vector of nREPL middlewares.")
425+
Each of these Clojure variables should hold a vector of nREPL middlewares.
426+
Instead of a string, an element can be a list containing a string followed
427+
by optional keyword arguments. The only keyword argument currently
428+
accepted is `:predicate', which should be given a function that takes the
429+
list (string and keyword arguments) and returns non-nil to indicate that
430+
the middlewares should actually be injected.")
396431
(put 'cider-jack-in-nrepl-middlewares 'risky-local-variable t)
397432
(add-to-list 'cider-jack-in-nrepl-middlewares "cider.nrepl/cider-middleware")
398433

434+
(defun cider-jack-in-normalized-nrepl-middlewares ()
435+
"Return a normalized list of middleware variable names.
436+
See `cider-jack-in-nrepl-middlewares' for the format, except that the list
437+
returned by this function only contains strings."
438+
(thread-last cider-jack-in-nrepl-middlewares
439+
(seq-filter
440+
(lambda (spec)
441+
(or (not (listp spec))
442+
(if-let* ((pred (plist-get (cdr spec) :predicate)))
443+
(funcall pred spec)
444+
t))))
445+
(mapcar
446+
(lambda (spec)
447+
(if (listp spec)
448+
(car spec)
449+
spec)))))
450+
399451
(defun cider--list-as-boot-artifact (list)
400452
"Return a boot artifact string described by the elements of LIST.
401453
LIST should have the form (ARTIFACT-NAME ARTIFACT-VERSION). The returned
@@ -523,14 +575,14 @@ dependencies."
523575
(cider-add-clojure-dependencies-maybe
524576
cider-jack-in-dependencies)
525577
cider-jack-in-dependencies-exclusions
526-
cider-jack-in-lein-plugins))
578+
(cider-jack-in-normalized-lein-plugins)))
527579
("boot" (cider-boot-jack-in-dependencies
528580
global-opts
529581
params
530582
(cider-add-clojure-dependencies-maybe
531583
cider-jack-in-dependencies)
532-
cider-jack-in-lein-plugins
533-
cider-jack-in-nrepl-middlewares))
584+
(cider-jack-in-normalized-lein-plugins)
585+
(cider-jack-in-normalized-nrepl-middlewares)))
534586
("clojure-cli" (cider-clojure-cli-jack-in-dependencies
535587
global-opts
536588
params

test/cider-tests.el

Lines changed: 56 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -134,7 +134,62 @@
134134
:to-equal "-C -o -i \"(require 'cider.tasks)\" -d org.clojure/tools.nrepl\\:0.2.12 -d cider/cider-nrepl\\:0.11.0 cider.tasks/add-middleware -m cider.nrepl/cider-middleware repl -s wait"))
135135
(it "can concat in a gradle project"
136136
(expect (cider-inject-jack-in-dependencies "-m" "--no-daemon clojureRepl" "gradle")
137-
:to-equal "-m --no-daemon clojureRepl"))))
137+
:to-equal "-m --no-daemon clojureRepl")))
138+
139+
(describe "when there are predicates"
140+
:var (plugins-predicate middlewares-predicate)
141+
142+
(before-each
143+
(fset 'plugins-predicate (lambda (&rest _) t))
144+
(fset 'middlewares-predicate (lambda (&rest _) t))
145+
(setq-local cider-jack-in-lein-plugins '(("refactor-nrepl" "2.0.0" :predicate plugins-predicate) ("cider/cider-nrepl" "0.11.0")))
146+
(setq-local cider-jack-in-nrepl-middlewares '(("refactor-nrepl.middleware/wrap-refactor" :predicate middlewares-predicate) "cider.nrepl/cider-middleware" ("another/middleware"))))
147+
(it "includes plugins whose predicates return true"
148+
(expect (cider-jack-in-normalized-lein-plugins)
149+
:to-equal '(("refactor-nrepl" "2.0.0") ("cider/cider-nrepl" "0.11.0"))))
150+
(it "includes middlewares whose predicates return true"
151+
(expect (cider-jack-in-normalized-nrepl-middlewares)
152+
:to-equal '("refactor-nrepl.middleware/wrap-refactor" "cider.nrepl/cider-middleware" "another/middleware")))
153+
(it "ignores plugins whose predicates return false"
154+
(spy-on 'plugins-predicate :and-return-value nil)
155+
(expect (cider-jack-in-normalized-lein-plugins)
156+
:to-equal '(("cider/cider-nrepl" "0.11.0"))))
157+
(it "ignores plugins whose predicates return false"
158+
(spy-on 'middlewares-predicate :and-return-value nil)
159+
(expect (cider-jack-in-normalized-nrepl-middlewares)
160+
:to-equal '("cider.nrepl/cider-middleware" "another/middleware")))
161+
(it "calls plugin predicates with the whole list entry"
162+
(spy-on 'plugins-predicate)
163+
(cider-jack-in-normalized-lein-plugins)
164+
(expect 'plugins-predicate
165+
:to-have-been-called-with '("refactor-nrepl" "2.0.0" :predicate plugins-predicate)))
166+
(it "calls middleware predicates with the whole list entry"
167+
(spy-on 'middlewares-predicate)
168+
(cider-jack-in-normalized-nrepl-middlewares)
169+
(expect 'middlewares-predicate
170+
:to-have-been-called-with '("refactor-nrepl.middleware/wrap-refactor" :predicate middlewares-predicate)))
171+
(it "only calls plugin predicates for their own entries"
172+
(spy-on 'plugins-predicate)
173+
(cider-jack-in-normalized-lein-plugins)
174+
(expect 'plugins-predicate :to-have-been-called-times 1))
175+
(it "only calls middleware predicates for their own entries"
176+
(spy-on 'middlewares-predicate)
177+
(cider-jack-in-normalized-nrepl-middlewares)
178+
(expect 'middlewares-predicate :to-have-been-called-times 1)))
179+
180+
(describe "when the middleware and plugin lists have been normalized"
181+
(before-each
182+
(spy-on 'cider-jack-in-normalized-nrepl-middlewares
183+
:and-return-value '("refactor-nrepl.middleware/wrap-refactor" "cider.nrepl/cider-middleware"))
184+
(spy-on 'cider-jack-in-normalized-lein-plugins
185+
:and-return-value '(("refactor-nrepl" "2.0.0") ("cider/cider-nrepl" "0.11.0")))
186+
(setq-local cider-jack-in-dependencies-exclusions '()))
187+
(it "uses them in a lein project"
188+
(expect (cider-inject-jack-in-dependencies "" "repl :headless" "lein")
189+
:to-equal "update-in :dependencies conj \\[org.clojure/tools.nrepl\\ \\\"0.2.12\\\"\\] -- update-in :plugins conj \\[refactor-nrepl\\ \\\"2.0.0\\\"\\] -- update-in :plugins conj \\[cider/cider-nrepl\\ \\\"0.11.0\\\"\\] -- repl :headless"))
190+
(it "uses them in a boot project"
191+
(expect (cider-inject-jack-in-dependencies "" "repl -s wait" "boot")
192+
:to-equal "-i \"(require 'cider.tasks)\" -d org.clojure/tools.nrepl\\:0.2.12 -d refactor-nrepl\\:2.0.0 -d cider/cider-nrepl\\:0.11.0 cider.tasks/add-middleware -m refactor-nrepl.middleware/wrap-refactor -m cider.nrepl/cider-middleware repl -s wait"))))
138193

139194
(describe "cider-jack-in-auto-inject-clojure"
140195
(it "injects `cider-minimum-clojure-version' when `cider-jack-in-auto-inject-clojure' is set to minimal"

0 commit comments

Comments
 (0)