From 9af04142e9751fa2c4dd7f35bfd2b2f0eda2a626 Mon Sep 17 00:00:00 2001 From: Michael Griffiths Date: Fri, 7 Aug 2015 13:28:37 +0100 Subject: [PATCH 1/2] Add support for `refresh-clear` middleware op --- CHANGELOG.md | 1 + README.md | 3 +-- cider-interaction.el | 19 ++++++++++++++----- 3 files changed, 16 insertions(+), 7 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 14f2a70b4..d1a25a3af 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -25,6 +25,7 @@ * [#1219](https://github.com/clojure-emacs/cider/pull/1219): The output of `cider-refresh` is now sent to a dedicated `*cider-refresh-log*` buffer. * [#1219](https://github.com/clojure-emacs/cider/pull/1219): New custom variables `cider-refresh-before-fn` and `cider-refresh-after-fn`. * [#1220](https://github.com/clojure-emacs/cider/issues/1220): Treat keywords as symbols in lookup commands like `cider-find-var`. +* [#1241](https://github.com/clojure-emacs/cider/pull/1241): Passing a double prefix argument to `cider-refresh` will now clear the state of the namespace tracker used by the refresh middleware. This is useful for recovering from errors that a normal reload would not otherwise recover from, but may cause stale code in any deleted files to not be completely unloaded. ### Changes diff --git a/README.md b/README.md index 4a775059a..2402c5c00 100644 --- a/README.md +++ b/README.md @@ -820,8 +820,7 @@ Keyboard shortcut | Description C-c M-o | Clear the entire REPL buffer, leaving only a prompt. Useful if you're running the REPL buffer in a side by side buffer. C-c C-k | Load (eval) the current buffer. C-c C-l | Load (eval) a Clojure file. -C-c C-x | Reload all modified files on the classpath. -C-u C-c C-x | Reload all files on the classpath. +C-c C-x | Reload all modified files on the classpath. If invoked with a prefix argument, reload all files on the classpath. If invoked with a double prefix argument, clear the state of the namespace tracker before reloading. C-c C-d d | Display doc string for the symbol at point. If invoked with a prefix argument, or no symbol is found at point, prompt for a symbol. C-c C-d j | Display JavaDoc (in your default browser) for the symbol at point. If invoked with a prefix argument, or no symbol is found at point, prompt for a symbol. C-c M-i | Inspect expression. Will act on expression at point if present. diff --git a/cider-interaction.el b/cider-interaction.el index 01f3014aa..6336de7e9 100644 --- a/cider-interaction.el +++ b/cider-interaction.el @@ -2086,13 +2086,22 @@ opposite of what that option dictates." (defun cider-refresh (&optional arg) "Reload modified and unloaded namespaces on the classpath. -With a non-nil prefix ARG, reload all namespaces on the classpath -unconditionally." - (interactive "P") +With a single prefix argument ARG, reload all namespaces on the classpath +unconditionally. + +With a double prefix argument ARG, clear the state of the namespace tracker +before reloading. This is useful for recovering from some classes of +error (for example, those caused by circular dependencies) that a normal +reload would not otherwise recover from. The trade-off of clearing is that +stale code from any deleted files may not be completely unloaded." + (interactive "p") (cider-ensure-op-supported "refresh") (let ((log-buffer (cider-popup-buffer-display (or (get-buffer cider-refresh-log-buffer) - (cider-make-popup-buffer cider-refresh-log-buffer))))) - (nrepl-send-request (append (list "op" (if arg "refresh-all" "refresh") + (cider-make-popup-buffer cider-refresh-log-buffer)))) + (clear? (>= arg 16)) + (refresh-all? (>= arg 4))) + (when clear? (nrepl-send-request-sync (list "op" "refresh-clear"))) + (nrepl-send-request (append (list "op" (if refresh-all? "refresh-all" "refresh") "print-length" cider-stacktrace-print-length "print-level" cider-stacktrace-print-level) (when cider-refresh-before-fn (list "before" cider-refresh-before-fn)) From dbe7b4eb737abdc0cb0247fa31a795bc0affa35f Mon Sep 17 00:00:00 2001 From: Michael Griffiths Date: Fri, 7 Aug 2015 13:37:05 +0100 Subject: [PATCH 2/2] Add some notes on tools.namespace to the reloading documentation --- README.md | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/README.md b/README.md index 2402c5c00..aae2119a9 100644 --- a/README.md +++ b/README.md @@ -472,6 +472,26 @@ passed or failed: ### Code reloading +* `cider-refresh` wraps + [clojure.tools.namespace](https://github.com/clojure/tools.namespace), and as + such the same + [benefits](https://github.com/clojure/tools.namespace#reloading-code-motivation) + and + [caveats](https://github.com/clojure/tools.namespace#reloading-code-preparing-your-application) + regarding writing reloadable code also apply. + +* Calling `cider-refresh` will cause all modified Clojure files on the classpath + to be reloaded. You can also provide a single prefix argument to reload all + Clojure files on the classpath unconditionally, or a double prefix argument to + first clear the state of the namespace tracker before reloading. + +* The above three operations are analogous to + [`clojure.tools.namespace.repl/refresh`](http://clojure.github.io/tools.namespace/#clojure.tools.namespace.repl/refresh), + [`clojure.tools.namespace.repl/refresh-all`](http://clojure.github.io/tools.namespace/#clojure.tools.namespace.repl/refresh-all) + and + [`clojure.tools.namespace.repl/clear`](http://clojure.github.io/tools.namespace/#clojure.tools.namespace.repl/clear) + (followed by a normal refresh), respectively. + * You can define Clojure functions to be called before reloading, and after a successful reload, when using `cider-refresh`: