Skip to content

Commit 80cefbb

Browse files
dpsuttonbbatsov
authored andcommitted
API to update repl-features
1 parent e33a546 commit 80cefbb

File tree

3 files changed

+76
-17
lines changed

3 files changed

+76
-17
lines changed

README.md

Lines changed: 36 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -243,22 +243,46 @@ configurable.
243243
You can see all the configuration options available using the command
244244
`M-x customize-group RET inf-clojure`.
245245

246+
The supported repl-features are in an alist called
247+
`inc-clojure-repl-features` and it has the following shape:
248+
249+
```emacs-lisp
250+
'((cljs . ((doc . "(cljs.repl/doc %s)")
251+
(source . "(cljs.repl/source %s)")
252+
(arglists . "(try (->> '%s cljs.core/resolve cljs.core/meta :arglists) (catch :default _ nil))")
253+
(apropos . "(cljs.repl/apropos \"%s\")")
254+
(ns-vars . "(cljs.repl/dir %s)")
255+
(set-ns . "(in-ns '%s)")
256+
(macroexpand . "(cljs.core/macroexpand '%s)")
257+
(macroexpand-1 . "(cljs.core/macroexpand-1 '%s)"))))
258+
```
259+
260+
If you want to add a new repl type, just `(add-to-list
261+
'inf-clojure-repl-features (cons new-repl-type '((doc
262+
. "(myrepl/doc-command %s") ...)))`
263+
264+
If you want to update a specific form there is a function
265+
`inf-clojure-update-repl-feature` which can be used like so:
266+
267+
```emacs-lisp
268+
(inf-clojure-update-feature 'clojure 'completion "(complete.core/completions \"%s\")")
269+
```
270+
246271
#### REPL Type
247272

248-
An `inf-clojure` REPL can be of different types: Clojure, ClojureScript, Lumo
249-
and Planck are all potentially valid options.
273+
An `inf-clojure` REPL can be of different types: Clojure,
274+
ClojureScript, Lumo and Planck are all potentially valid options.
250275

251-
At the moment, the default Clojure REPL, the Lumo REPL, the Planck REPL and the
252-
Joker REPL are supported (standard ClojureScript is lacking mostly because some
253-
features require to access the compiler state,
254-
[cljs-tooling](https://github.com/clojure-emacs/cljs-tooling) is a good
255-
candidate for enabling support).
276+
At the moment, the default Clojure REPL, the Lumo REPL, the Planck
277+
REPL and the Joker REPL are supported.
256278

257-
What does it mean that a REPL type is supported - well it means that `inf-clojure`
258-
would use the proper code internally to power commands like definition lookup and friends.
259-
Those differ from REPL to REPL and can't be implemented in a REPL-independent way. At
260-
boot type `inf-clojure` tries to detect the type of the REPL that was started and uses
261-
this type to dispatch the proper code for the respective REPL type.
279+
What does it mean that a REPL type is supported - well it means that
280+
`inf-clojure` would use the proper code internally to power commands
281+
like definition lookup and friends. Those differ from REPL to REPL
282+
and can't be implemented in a REPL-independent way. At startup
283+
`inf-clojure` tries to detect the type of the REPL that was started
284+
and uses this type to dispatch the proper code for the respective REPL
285+
type.
262286

263287
By default `inf-clojure` would start a standard Clojure REPL using
264288
`lein` or `boot` but you can easily change this. To boot some other REPL just use the

inf-clojure.el

Lines changed: 30 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -146,15 +146,40 @@
146146
(macroexpand . "(clojure.core/macroexpand '%s)")
147147
(macroexpand-1 . "(clojure.core/macroexpand-1 '%s)")))))
148148

149+
(defun inf-clojure--get-feature (repl-type feature no-error)
150+
"Get FEATURE for REPL-TYPE from repl-features.
151+
If no-error is truthy don't error if feature is not present."
152+
(let ((feature-form (alist-get feature (alist-get repl-type inf-clojure-repl-features))))
153+
(cond (feature-form feature-form)
154+
(no-error nil)
155+
(t (error "%s not configured for %s" feature repl-type)))))
156+
149157
(defun inf-clojure-get-feature (proc feature &optional no-error)
150158
"Get FEATURE based on repl type for PROC."
151159
(let* ((repl-type (or (with-current-buffer (process-buffer proc)
152160
inf-clojure-repl-type)
153-
(error "Repl type is not known")))
154-
(feature-form (alist-get feature (alist-get repl-type inf-clojure-repl-features))))
155-
(cond (feature-form feature-form)
156-
(no-error nil)
157-
(t (error "%s not configured for %s" feature repl-type)))))
161+
(error "Repl type is not known"))))
162+
(inf-clojure--get-feature repl-type feature no-error)))
163+
164+
(defun inf-clojure--update-feature (repl-type feature form)
165+
"Return a copy of the datastructure containing the repl features.
166+
Given a REPL-TYPE ('clojure, 'lumo, ...) and a FEATURE ('doc,
167+
'apropos, ...) and a FORM this will return a new datastructure
168+
that can be set as `inf-clojure-repl-features'."
169+
(let ((original (alist-get repl-type inf-clojure-repl-features)))
170+
(if original
171+
(cons (cons repl-type (cons (cons feature form) (assoc-delete-all feature original)))
172+
(assoc-delete-all repl-type inf-clojure-repl-features))
173+
(error "Attempted to update %s form of unknown repl type %s"
174+
(symbol-name feature)
175+
(symbol-name repl-type)))))
176+
177+
(defun inf-clojure-update-feature (repl-type feature form)
178+
"Mutate the repl features to the new FORM.
179+
Given a REPL-TYPE ('clojure, 'lumo, ...) and a FEATURE ('doc,
180+
'apropos, ...) and a FORM this will set
181+
`inf-clojure-repl-features' with these new values."
182+
(setq inf-clojure-repl-features (inf-clojure--update-feature repl-type feature form)))
158183

159184
(defun inf-clojure-proc (&optional no-error)
160185
"Return the current inferior Clojure process.

test/inf-clojure-tests.el

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -139,4 +139,14 @@
139139
(it "returns empty string when the command is empty"
140140
(expect (inf-clojure--sanitize-command " ") :to-equal "")))
141141

142+
(describe "inf-clojure--update-feature"
143+
(it "updates new forms correctly"
144+
(let ((inf-clojure-repl-features (inf-clojure--update-feature 'cljs 'doc "new doc")))
145+
(expect (inf-clojure--get-feature 'cljs 'doc nil)
146+
:to-equal "new doc")))
147+
(describe "if the repl type is unknown"
148+
(it "signals an error"
149+
(expect (inf-clojure--update-feature 'not-found 'doc "new doc")
150+
:to-throw))))
151+
142152
;;; inf-clojure-tests.el ends here

0 commit comments

Comments
 (0)