branch: elpa/inf-clojure commit 80cefbb6c10d641d8e0faa745a31275deff38ab6 Author: dan sutton <d...@dpsutton.com> Commit: Bozhidar Batsov <bozhidar.bat...@gmail.com>
API to update repl-features --- README.md | 48 +++++++++++++++++++++++++++++++++++------------ inf-clojure.el | 35 +++++++++++++++++++++++++++++----- test/inf-clojure-tests.el | 10 ++++++++++ 3 files changed, 76 insertions(+), 17 deletions(-) diff --git a/README.md b/README.md index f1aac4b..bb3b1d6 100644 --- a/README.md +++ b/README.md @@ -243,22 +243,46 @@ configurable. You can see all the configuration options available using the command `M-x customize-group RET inf-clojure`. +The supported repl-features are in an alist called +`inc-clojure-repl-features` and it has the following shape: + +```emacs-lisp +'((cljs . ((doc . "(cljs.repl/doc %s)") + (source . "(cljs.repl/source %s)") + (arglists . "(try (->> '%s cljs.core/resolve cljs.core/meta :arglists) (catch :default _ nil))") + (apropos . "(cljs.repl/apropos \"%s\")") + (ns-vars . "(cljs.repl/dir %s)") + (set-ns . "(in-ns '%s)") + (macroexpand . "(cljs.core/macroexpand '%s)") + (macroexpand-1 . "(cljs.core/macroexpand-1 '%s)")))) +``` + +If you want to add a new repl type, just `(add-to-list +'inf-clojure-repl-features (cons new-repl-type '((doc +. "(myrepl/doc-command %s") ...)))` + +If you want to update a specific form there is a function +`inf-clojure-update-repl-feature` which can be used like so: + +```emacs-lisp +(inf-clojure-update-feature 'clojure 'completion "(complete.core/completions \"%s\")") +``` + #### REPL Type -An `inf-clojure` REPL can be of different types: Clojure, ClojureScript, Lumo -and Planck are all potentially valid options. +An `inf-clojure` REPL can be of different types: Clojure, +ClojureScript, Lumo and Planck are all potentially valid options. -At the moment, the default Clojure REPL, the Lumo REPL, the Planck REPL and the -Joker REPL are supported (standard ClojureScript is lacking mostly because some -features require to access the compiler state, -[cljs-tooling](https://github.com/clojure-emacs/cljs-tooling) is a good -candidate for enabling support). +At the moment, the default Clojure REPL, the Lumo REPL, the Planck +REPL and the Joker REPL are supported. -What does it mean that a REPL type is supported - well it means that `inf-clojure` -would use the proper code internally to power commands like definition lookup and friends. -Those differ from REPL to REPL and can't be implemented in a REPL-independent way. At -boot type `inf-clojure` tries to detect the type of the REPL that was started and uses -this type to dispatch the proper code for the respective REPL type. +What does it mean that a REPL type is supported - well it means that +`inf-clojure` would use the proper code internally to power commands +like definition lookup and friends. Those differ from REPL to REPL +and can't be implemented in a REPL-independent way. At startup +`inf-clojure` tries to detect the type of the REPL that was started +and uses this type to dispatch the proper code for the respective REPL +type. By default `inf-clojure` would start a standard Clojure REPL using `lein` or `boot` but you can easily change this. To boot some other REPL just use the diff --git a/inf-clojure.el b/inf-clojure.el index 008c6a1..e9cb89f 100644 --- a/inf-clojure.el +++ b/inf-clojure.el @@ -146,15 +146,40 @@ (macroexpand . "(clojure.core/macroexpand '%s)") (macroexpand-1 . "(clojure.core/macroexpand-1 '%s)"))))) +(defun inf-clojure--get-feature (repl-type feature no-error) + "Get FEATURE for REPL-TYPE from repl-features. +If no-error is truthy don't error if feature is not present." + (let ((feature-form (alist-get feature (alist-get repl-type inf-clojure-repl-features)))) + (cond (feature-form feature-form) + (no-error nil) + (t (error "%s not configured for %s" feature repl-type))))) + (defun inf-clojure-get-feature (proc feature &optional no-error) "Get FEATURE based on repl type for PROC." (let* ((repl-type (or (with-current-buffer (process-buffer proc) inf-clojure-repl-type) - (error "Repl type is not known"))) - (feature-form (alist-get feature (alist-get repl-type inf-clojure-repl-features)))) - (cond (feature-form feature-form) - (no-error nil) - (t (error "%s not configured for %s" feature repl-type))))) + (error "Repl type is not known")))) + (inf-clojure--get-feature repl-type feature no-error))) + +(defun inf-clojure--update-feature (repl-type feature form) + "Return a copy of the datastructure containing the repl features. +Given a REPL-TYPE ('clojure, 'lumo, ...) and a FEATURE ('doc, +'apropos, ...) and a FORM this will return a new datastructure +that can be set as `inf-clojure-repl-features'." + (let ((original (alist-get repl-type inf-clojure-repl-features))) + (if original + (cons (cons repl-type (cons (cons feature form) (assoc-delete-all feature original))) + (assoc-delete-all repl-type inf-clojure-repl-features)) + (error "Attempted to update %s form of unknown repl type %s" + (symbol-name feature) + (symbol-name repl-type))))) + +(defun inf-clojure-update-feature (repl-type feature form) + "Mutate the repl features to the new FORM. +Given a REPL-TYPE ('clojure, 'lumo, ...) and a FEATURE ('doc, +'apropos, ...) and a FORM this will set +`inf-clojure-repl-features' with these new values." + (setq inf-clojure-repl-features (inf-clojure--update-feature repl-type feature form))) (defun inf-clojure-proc (&optional no-error) "Return the current inferior Clojure process. diff --git a/test/inf-clojure-tests.el b/test/inf-clojure-tests.el index 09b224e..bf49c30 100644 --- a/test/inf-clojure-tests.el +++ b/test/inf-clojure-tests.el @@ -139,4 +139,14 @@ (it "returns empty string when the command is empty" (expect (inf-clojure--sanitize-command " ") :to-equal ""))) +(describe "inf-clojure--update-feature" + (it "updates new forms correctly" + (let ((inf-clojure-repl-features (inf-clojure--update-feature 'cljs 'doc "new doc"))) + (expect (inf-clojure--get-feature 'cljs 'doc nil) + :to-equal "new doc"))) + (describe "if the repl type is unknown" + (it "signals an error" + (expect (inf-clojure--update-feature 'not-found 'doc "new doc") + :to-throw)))) + ;;; inf-clojure-tests.el ends here