[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[nongnu] elpa/cider 7bcdabca29 1/4: Support nbb as native cljs repl
From: |
ELPA Syncer |
Subject: |
[nongnu] elpa/cider 7bcdabca29 1/4: Support nbb as native cljs repl |
Date: |
Fri, 16 Dec 2022 02:58:34 -0500 (EST) |
branch: elpa/cider
commit 7bcdabca29eabb50418469495573c3ba49e76990
Author: ikappaki <ikappaki@users.noreply.github.com>
Commit: Bozhidar Batsov <bozhidar@batsov.dev>
Support nbb as native cljs repl
If no repl init form is given, logic assumes it is repl is cljs from
the start.
---
cider.el | 123 ++++++++++++++++++++++++++++------------
test/cider-tests.el | 43 ++++++++++++++
test/utils/nrepl-tests-utils.el | 17 ++++++
3 files changed, 146 insertions(+), 37 deletions(-)
diff --git a/cider.el b/cider.el
index dc44e1cfca..f944f8bcf9 100644
--- a/cider.el
+++ b/cider.el
@@ -230,6 +230,27 @@ By default we favor the project-specific shadow-cljs over
the system-wide."
:safe #'stringp
:package-version '(cider . "1.2.0"))
+(defcustom cider-nbb-command
+ "nbb"
+ "The command used to execute nbb."
+ :type 'string
+ :safe #'stringp
+ :package-version '(cider . "1.2.0"))
+
+(defcustom cider-nbb-global-options
+ nil
+ "Command line options used to execute nbb."
+ :type 'string
+ :safe #'stringp
+ :package-version '(cider . "1.2.0"))
+
+(defcustom cider-nbb-parameters
+ "nrepl-server"
+ "Params passed to nbb to start an nREPL server via `cider-jack-in'."
+ :type 'string
+ :safe #'stringp
+ :package-version '(cider . "1.2.0"))
+
(defcustom cider-jack-in-default (if (executable-find "clojure") 'clojure-cli
'lein)
"The default tool to use when doing `cider-jack-in' outside a project.
This value will only be consulted when no identifying file types, i.e.
@@ -243,7 +264,8 @@ to Leiningen."
(const clojure-cli)
(const shadow-cljs)
(const gradle)
- (const babashka))
+ (const babashka)
+ (const nbb))
:safe #'symbolp
:package-version '(cider . "0.9.0"))
@@ -262,6 +284,7 @@ command when there is no ambiguity."
(const shadow-cljs)
(const gradle)
(const babashka)
+ (const nbb)
(const :tag "Always ask" nil))
:safe #'symbolp
:package-version '(cider . "0.13.0"))
@@ -337,6 +360,7 @@ Sub-match 1 must be the project path.")
('babashka cider-babashka-command)
('shadow-cljs cider-shadow-cljs-command)
('gradle cider-gradle-command)
+ ('nbb cider-nbb-command)
(_ (user-error "Unsupported project type `%S'" project-type))))
(defun cider-jack-in-resolve-command (project-type)
@@ -357,6 +381,7 @@ Throws an error if PROJECT-TYPE is unknown."
;; relative path like "./gradlew" use locate file instead of checking
;; the exec-path
('gradle (cider--resolve-project-command cider-gradle-command))
+ ('nbb (cider--resolve-command cider-nbb-command))
(_ (user-error "Unsupported project type `%S'" project-type))))
(defun cider-jack-in-global-options (project-type)
@@ -368,6 +393,7 @@ Throws an error if PROJECT-TYPE is unknown."
('babashka cider-babashka-global-options)
('shadow-cljs cider-shadow-cljs-global-options)
('gradle cider-gradle-global-options)
+ ('nbb cider-nbb-global-options)
(_ (user-error "Unsupported project type `%S'" project-type))))
(defun cider-jack-in-params (project-type)
@@ -383,6 +409,7 @@ Throws an error if PROJECT-TYPE is unknown."
('babashka cider-babashka-parameters)
('shadow-cljs cider-shadow-cljs-parameters)
('gradle cider-gradle-parameters)
+ ('nbb cider-nbb-parameters)
(_ (user-error "Unsupported project type `%S'" project-type))))
@@ -766,6 +793,10 @@ dependencies."
(cider-add-clojure-dependencies-maybe
cider-jack-in-dependencies)
(cider-jack-in-normalized-nrepl-middlewares)))
+ ('nbb (concat
+ global-opts
+ (unless (seq-empty-p global-opts) " ")
+ params))
(_ (error "Unsupported project type `%S'" project-type))))
@@ -993,21 +1024,26 @@ The supplied string will be wrapped in a do form if
needed."
(def config (edn/read-string (slurp (io/file \"build.edn\"))))
(apply cider.piggieback/cljs-repl (krell.repl/repl-env) (mapcat identity
config))"
cider-check-krell-requirements)
+ ;; native cljs repl, no form required.
+ (nbb)
(custom cider-custom-cljs-repl-init-form nil))
"A list of supported ClojureScript REPLs.
-For each one we have its name, the form we need to evaluate in a Clojure
-REPL to start the ClojureScript REPL and functions to verify their
requirements.
+For each one we have its name, and then, if the repl is not a native
+ClojureScript REPL, the form we need to evaluate in a Clojure REPL to
+switch to the ClojureScript REPL and functions to verify their
+requirements.
-The form should be either a string or a function producing a string.")
+The form, if any, should be either a string or a function producing a
+string.")
-(defun cider-register-cljs-repl-type (type init-form &optional requirements-fn)
+(defun cider-register-cljs-repl-type (type &optional init-form requirements-fn)
"Register a new ClojureScript REPL type.
Types are defined by the following:
- TYPE - symbol identifier that will be used to refer to the REPL type
-- INIT-FORM - string or function (symbol) producing string
+- INIT-FORM - (optional) string or function (symbol) producing string
- REQUIREMENTS-FN - function to check whether the REPL can be started.
This param is optional.
@@ -1015,8 +1051,8 @@ All this function does is modifying
`cider-cljs-repl-types'.
It's intended to be used in your Emacs config."
(unless (symbolp type)
(user-error "The REPL type must be a symbol"))
- (unless (or (stringp init-form) (symbolp init-form))
- (user-error "The init form must be a string or a symbol referring to a
function"))
+ (unless (or (null init-form) (stringp init-form) (symbolp init-form))
+ (user-error "The init form must be a string or a symbol referring to a
function or nil"))
(unless (or (null requirements-fn) (symbolp requirements-fn))
(user-error "The requirements-fn must be a symbol referring to a
function"))
(add-to-list 'cider-cljs-repl-types (list type init-form requirements-fn)))
@@ -1036,6 +1072,7 @@ you're working on."
(const :tag "Shadow" shadow)
(const :tag "Shadow w/o Server" shadow-select)
(const :tag "Krell" krell)
+ (const :tag "Nbb" nbb)
(const :tag "Custom" custom))
:safe #'symbolp
:package-version '(cider . "0.17.0"))
@@ -1054,15 +1091,16 @@ DEFAULT is the default ClojureScript REPL to offer in
completion."
(or default (car
cider--select-cljs-repl-history))))))
(defun cider-cljs-repl-form (repl-type)
- "Get the cljs REPL form for REPL-TYPE."
- (if-let* ((repl-form (cadr (seq-find
- (lambda (entry)
- (eq (car entry) repl-type))
- cider-cljs-repl-types))))
- ;; repl-form can be either a string or a function producing a string
- (if (symbolp repl-form)
- (funcall repl-form)
- repl-form)
+ "Get the cljs REPL form for REPL-TYPE, if any."
+ (if-let* ((repl-type-info (seq-find
+ (lambda (entry)
+ (eq (car entry) repl-type))
+ cider-cljs-repl-types)))
+ (when-let ((repl-form (cadr repl-type-info)))
+ ;; repl-form can be either a string or a function producing a string
+ (if (symbolp repl-form)
+ (funcall repl-form)
+ repl-form))
(user-error "No ClojureScript REPL type %s found. Please make sure that
`cider-cljs-repl-types' has an entry for it" repl-type)))
(defun cider-verify-cljs-repl-requirements (&optional repl-type)
@@ -1258,7 +1296,6 @@ server buffer, in which case a new session for that
server is created."
(cider--update-cljs-type)
(cider--update-cljs-init-function)
(plist-put :session-name ses-name)
- (plist-put :repl-type 'cljs)
(plist-put :cider-repl-cljs-upgrade-pending t)))))
;;;###autoload
@@ -1293,7 +1330,6 @@ parameters regardless of their supplied or default
values."
(cider--update-cljs-type)
(cider--update-cljs-init-function)
(plist-put :session-name nil)
- (plist-put :repl-type 'cljs)
(plist-put :cider-repl-cljs-upgrade-pending t))))
;;;###autoload
@@ -1466,27 +1502,39 @@ non-nil, don't start if ClojureScript requirements are
not met."
(plist-put :port (cdr endpoint)))))))
(defun cider--update-cljs-init-function (params)
- "Update PARAMS :repl-init-function for cljs connections."
+ "Update repl type and any init PARAMS for cljs connections.
+
+The updated params are:
+
+:cljs-type 'cljs if it is a cljs REPL, or 'pending-cljs when the init form
+is required to be sent to the REPL to switch over to cljs.
+
+:repl-init-form The form that can switch the REPL over to cljs.
+
+:repl-init-function The fn that switches the REPL over to cljs."
(with-current-buffer (or (plist-get params :--context-buffer)
(current-buffer))
(let* ((cljs-type (plist-get params :cljs-repl-type))
(repl-init-form (cider-cljs-repl-form cljs-type)))
- (thread-first
- params
- (plist-put :repl-init-function
- (lambda ()
- (cider--check-cljs cljs-type)
- ;; FIXME: ideally this should be done in the state handler
- (setq-local cider-cljs-repl-type cljs-type)
- (cider-nrepl-send-request
- (list "op" "eval"
- "ns" (cider-current-ns)
- "code" repl-init-form)
- (cider-repl-handler (current-buffer)))
- (when (and (buffer-live-p nrepl-server-buffer)
- cider-offer-to-open-cljs-app-in-browser)
- (cider--offer-to-open-app-in-browser
nrepl-server-buffer))))
- (plist-put :repl-init-form repl-init-form)))))
+ (if (null repl-init-form)
+ (plist-put params :repl-type 'cljs)
+ (thread-first
+ params
+ (plist-put :repl-init-function
+ (lambda ()
+ (cider--check-cljs cljs-type)
+ ;; FIXME: ideally this should be done in the state
handler
+ (setq-local cider-cljs-repl-type cljs-type)
+ (cider-nrepl-send-request
+ (list "op" "eval"
+ "ns" (cider-current-ns)
+ "code" repl-init-form)
+ (cider-repl-handler (current-buffer)))
+ (when (and (buffer-live-p nrepl-server-buffer)
+ cider-offer-to-open-cljs-app-in-browser)
+ (cider--offer-to-open-app-in-browser
nrepl-server-buffer))))
+ (plist-put :repl-init-form repl-init-form)
+ (plist-put :repl-type 'pending-cljs))))))
(defun cider--check-existing-session (params)
"Ask for confirmation if a session with similar PARAMS already exists.
@@ -1666,7 +1714,8 @@ PROJECT-DIR defaults to current project."
(babashka . "bb.edn")
(shadow-cljs . "shadow-cljs.edn")
(gradle . "build.gradle")
- (gradle . "build.gradle.kts"))))
+ (gradle . "build.gradle.kts")
+ (nbb . "package.json"))))
(delq nil
(mapcar (lambda (candidate)
(when (file-exists-p (cdr candidate))
diff --git a/test/cider-tests.el b/test/cider-tests.el
index 231ee49e5a..c9693ad584 100644
--- a/test/cider-tests.el
+++ b/test/cider-tests.el
@@ -579,6 +579,49 @@
(expect (cider--resolve-project-command "command")
:to-equal (shell-quote-argument "/bin/command"))))
+(describe "cider-connect-sibling-cljs"
+ :var (-cider-cljs-repl-types bu-cider-shadow-default-options)
+ (before-all
+ (setq -cider-cljs-repl-types cider-cljs-repl-types
+ -cider-shadow-default-options cider-shadow-default-options))
+ (after-each
+ (setq cider-cljs-repl-types -cider-cljs-repl-types
+ cider-shadow-default-options -cider-shadow-default-options))
+
+ (describe "sets nrepl client local vars correctly"
+ (it "for nbb project"
+ (let* ((server-process (nrepl-start-mock-server-process))
+ (server-buffer (process-buffer server-process))
+ (client-buffer (cider-connect-sibling-cljs '(:cljs-repl-type
nbb) server-buffer)))
+ (expect (buffer-local-value 'cider-repl-type client-buffer)
:to-equal 'cljs)
+ (expect (buffer-local-value 'cider-repl-init-function
client-buffer) :to-be nil)
+ (delete-process (get-buffer-process client-buffer))))
+ (it "for shadow project"
+ (setq cider-shadow-default-options "a-shadow-alias")
+ (let* ((server-process (nrepl-start-mock-server-process))
+ (server-buffer (process-buffer server-process))
+ (client-buffer (cider-connect-sibling-cljs '(:cljs-repl-type
shadow) server-buffer)))
+ (expect (buffer-local-value 'cider-repl-type client-buffer)
:to-equal 'pending-cljs)
+ (expect (buffer-local-value 'cider-repl-init-function
client-buffer) :not :to-be nil)
+ (delete-process (get-buffer-process client-buffer))))
+ (it "for a custom cljs REPL type project"
+ (cider-register-cljs-repl-type 'native-cljs)
+ (let* ((server-process (nrepl-start-mock-server-process))
+ (server-buffer (process-buffer server-process))
+ (client-buffer (cider-connect-sibling-cljs '(:cljs-repl-type
native-cljs)
+ server-buffer)))
+ (expect (buffer-local-value 'cider-repl-type client-buffer)
:to-equal 'cljs)
+ (delete-process (get-buffer-process client-buffer))))
+ (it "for a custom REPL type project that needs to switch to cljs"
+ (cider-register-cljs-repl-type 'not-cljs-initially
"(form-to-switch-to-cljs-repl)")
+ (let* ((server-process (nrepl-start-mock-server-process))
+ (server-buffer (process-buffer server-process))
+ (client-buffer (cider-connect-sibling-cljs '(:cljs-repl-type
not-cljs-initially)
+ server-buffer)))
+ (expect (buffer-local-value 'cider-repl-type client-buffer)
:to-equal 'pending-cljs)
+ (expect (buffer-local-value 'cider-repl-init-function
client-buffer) :not :to-be nil)
+ (delete-process (get-buffer-process client-buffer))))))
+
(provide 'cider-tests)
;;; cider-tests.el ends here
diff --git a/test/utils/nrepl-tests-utils.el b/test/utils/nrepl-tests-utils.el
index e7a4a17164..549476d2df 100644
--- a/test/utils/nrepl-tests-utils.el
+++ b/test/utils/nrepl-tests-utils.el
@@ -25,6 +25,8 @@
;;; Code:
+(require 'nrepl-client)
+
(defmacro nrepl-tests-log/init! (enable? name log-filename &optional clean?)
"Create a NAME/log! elisp function to log messages to LOG-FILENAME,
taking the same arguments as `message'. Messages are appended to
@@ -97,5 +99,20 @@ calling process."
;; invoke mock server
" -l test/nrepl-server-mock.el -f nrepl-server-mock-start"))
+(defun nrepl-start-mock-server-process ()
+ "Start and return the mock nrepl server process."
+ (let* ((up? nil)
+ (server-process (nrepl-start-server-process
+ default-directory
+ (nrepl-server-mock-invocation-string)
+ (lambda (server-buffer)
+ (setq up? t))))
+ server-buffer (process-buffer server-process))
+ ;; server has reported its endpoint
+ (nrepl-tests-sleep-until 2 up?)
+ server-process))
(provide 'nrepl-tests-utils)
+
+;;; nrepl-tests-utils.el ends here
+