From 993fff16058764da79324f303c5437f06af70e35 Mon Sep 17 00:00:00 2001 From: vemv Date: Wed, 9 Aug 2023 12:45:54 +0200 Subject: [PATCH 1/2] Recompute namespace info on each shadow-cljs recompilation or evaluation Fixes https://github.com/clojure-emacs/cider/issues/3393 --- CHANGELOG.md | 1 + cider-repl.el | 58 ++++++++++++++++++++++++++++++++++++++++++++++++++- 2 files changed, 58 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 41b464c04..cf4046447 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -26,6 +26,7 @@ - Fix the `xref-find-definitions` CIDER backend to return correct filenames. - Fix the `cider-xref-fn-deps` buttons to direct to the right file. +- [#3393](https://github.com/clojure-emacs/cider/issues/3393): recompute namespace info on each shadow-cljs recompilation or evaluation. ### Changes diff --git a/cider-repl.el b/cider-repl.el index 04bc1acde..93205150a 100644 --- a/cider-repl.el +++ b/cider-repl.el @@ -986,6 +986,56 @@ t, as the content-type response is (currently) an alternative to the value response. However for handlers which themselves issue subsequent nREPL ops, it may be convenient to prevent inserting a prompt.") +(defun cider--maybe-get-state-for-shadow-cljs (buffer &optional err) + "Refresh the changed namespaces metadata given BUFFER and ERR (stderr string). + +This is particularly necessary for shadow-cljs because: + +* it has a particular nREPL implementation; and +* one may have saved files (which triggers recompilation, + and therefore the need for recomputing changed namespaces) + without sending a nREPL message (this can particularly happen + if the file was edited outside Emacs)." + (with-current-buffer buffer + (when (and (eq cider-repl-type 'cljs) + (eq cider-cljs-repl-type 'shadow) + (not cider-repl-cljs-upgrade-pending) + (if err + (string-match-p "Build completed\\." err) + t)) + (when-let ((conn (cider-current-repl 'cljs))) + (when (nrepl-op-supported-p "cider/get-state" conn) + (nrepl-send-request '("op" "cider/get-state") nil conn)))))) + +(defun cider--shadow-cljs-stderr-hook (buffer err) + "Refresh the changed namespaces metadata given BUFFER and ERR." + (cider--maybe-get-state-for-shadow-cljs buffer err)) + +(defun cider--shadow-cljs-done-hook (buffer) + "Refresh the changed namespaces metadata given BUFFER." + (cider--maybe-get-state-for-shadow-cljs buffer)) + +(defcustom cider-repl-stdout-hooks nil + "Hooks to be invoked each time new stdout is received on a repl buffer. + +Good for, for instance, monitoring specific strings that may be logged, +and responding to them." + :type '(repeat function) + :package-version '(cider . "1.8.0")) + +(defcustom cider-repl-stderr-hooks (list #'cider--shadow-cljs-stderr-hook) + "Hooks to be invoked each time new stderr is received on a repl buffer. + +Good for, for instance, monitoring specific strings that may be logged, +and responding to them." + :type '(repeat function) + :package-version '(cider . "1.8.0")) + +(defcustom cider-repl-done-hooks (list #'cider--shadow-cljs-done-hook) + "Hooks to be invoked each time a given REPL interaction is complete." + :type '(repeat function) + :package-version '(cider . "1.8.0")) + (defun cider-repl-handler (buffer) "Make an nREPL evaluation handler for the REPL BUFFER." (let ((show-prompt t)) @@ -994,14 +1044,20 @@ nREPL ops, it may be convenient to prevent inserting a prompt.") (lambda (buffer value) (cider-repl-emit-result buffer value t)) (lambda (buffer out) + (dolist (f cider-repl-stdout-hooks) + (funcall f buffer out)) (cider-repl-emit-stdout buffer out)) (lambda (buffer err) + (dolist (f cider-repl-stderr-hooks) + (funcall f buffer err)) (cider-repl-emit-stderr buffer err)) (lambda (buffer) (when show-prompt (cider-repl-emit-prompt buffer)) (when cider-repl-buffer-size-limit - (cider-repl-maybe-trim-buffer buffer))) + (cider-repl-maybe-trim-buffer buffer)) + (dolist (f cider-repl-done-hooks) + (funcall f buffer))) nrepl-err-handler (lambda (buffer value content-type) (if-let* ((content-attrs (cadr content-type)) From 76feb4bbdbd556b20bf1721f31cc2d1d895bb65c Mon Sep 17 00:00:00 2001 From: vemv Date: Wed, 9 Aug 2023 19:09:47 +0200 Subject: [PATCH 2/2] Use private defvars instead of defcustoms --- cider-repl.el | 32 +++++++++----------------------- 1 file changed, 9 insertions(+), 23 deletions(-) diff --git a/cider-repl.el b/cider-repl.el index 93205150a..d70b708c3 100644 --- a/cider-repl.el +++ b/cider-repl.el @@ -1007,34 +1007,22 @@ This is particularly necessary for shadow-cljs because: (when (nrepl-op-supported-p "cider/get-state" conn) (nrepl-send-request '("op" "cider/get-state") nil conn)))))) -(defun cider--shadow-cljs-stderr-hook (buffer err) +(defun cider--shadow-cljs-handle-stderr (buffer err) "Refresh the changed namespaces metadata given BUFFER and ERR." (cider--maybe-get-state-for-shadow-cljs buffer err)) -(defun cider--shadow-cljs-done-hook (buffer) +(defun cider--shadow-cljs-handle-done (buffer) "Refresh the changed namespaces metadata given BUFFER." (cider--maybe-get-state-for-shadow-cljs buffer)) -(defcustom cider-repl-stdout-hooks nil - "Hooks to be invoked each time new stdout is received on a repl buffer. +(defvar cider--repl-stderr-functions (list #'cider--shadow-cljs-handle-stderr) + "Functions to be invoked each time new stderr is received on a repl buffer. Good for, for instance, monitoring specific strings that may be logged, -and responding to them." - :type '(repeat function) - :package-version '(cider . "1.8.0")) +and responding to them.") -(defcustom cider-repl-stderr-hooks (list #'cider--shadow-cljs-stderr-hook) - "Hooks to be invoked each time new stderr is received on a repl buffer. - -Good for, for instance, monitoring specific strings that may be logged, -and responding to them." - :type '(repeat function) - :package-version '(cider . "1.8.0")) - -(defcustom cider-repl-done-hooks (list #'cider--shadow-cljs-done-hook) - "Hooks to be invoked each time a given REPL interaction is complete." - :type '(repeat function) - :package-version '(cider . "1.8.0")) +(defvar cider--repl-done-functions (list #'cider--shadow-cljs-handle-done) + "Functions to be invoked each time a given REPL interaction is complete.") (defun cider-repl-handler (buffer) "Make an nREPL evaluation handler for the REPL BUFFER." @@ -1044,11 +1032,9 @@ and responding to them." (lambda (buffer value) (cider-repl-emit-result buffer value t)) (lambda (buffer out) - (dolist (f cider-repl-stdout-hooks) - (funcall f buffer out)) (cider-repl-emit-stdout buffer out)) (lambda (buffer err) - (dolist (f cider-repl-stderr-hooks) + (dolist (f cider--repl-stderr-functions) (funcall f buffer err)) (cider-repl-emit-stderr buffer err)) (lambda (buffer) @@ -1056,7 +1042,7 @@ and responding to them." (cider-repl-emit-prompt buffer)) (when cider-repl-buffer-size-limit (cider-repl-maybe-trim-buffer buffer)) - (dolist (f cider-repl-done-hooks) + (dolist (f cider--repl-done-functions) (funcall f buffer))) nrepl-err-handler (lambda (buffer value content-type)