From c940eca0f23c271b6ac4e125230d34dfcc57ffea Mon Sep 17 00:00:00 2001 From: vemv Date: Sun, 10 Mar 2024 20:39:31 +0100 Subject: [PATCH 1/7] `cider-ns-refresh`: accept `clear-and-inhibit` mode --- CHANGELOG.md | 2 ++ cider-ns.el | 15 +++++++++------ 2 files changed, 11 insertions(+), 6 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index d17f69c16..eb42099a8 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -15,6 +15,8 @@ - [#3626](https://github.com/clojure-emacs/cider/issues/3626): `cider-ns-refresh`: jump to the relevant file/line on errors. - [#3628](https://github.com/clojure-emacs/cider/issues/3628): `cider-ns-refresh`: summarize errors as an overlay. +- [#3628](https://github.com/clojure-emacs/cider/issues/3628): `cider-ns-refresh`: accept `clear-and-inhibit` mode. + - It often makes sense not to run the before/after functions around the `clear`ing. - Bump the injected nREPL to [1.1.1](https://github.com/nrepl/nrepl/blob/v1.1.1/CHANGELOG.md#111-2024-02-20). - Bump the injected `cider-nrepl` to [0.47.0](https://github.com/clojure-emacs/cider-nrepl/blob/v0.47.0/CHANGELOG.md#0470-2024-03-10). - Updates [Orchard](https://github.com/clojure-emacs/orchard/blob/v0.23.2/CHANGELOG.md#0232-2024-03-10). diff --git a/cider-ns.el b/cider-ns.el index 70e06d0be..9e036c670 100644 --- a/cider-ns.el +++ b/cider-ns.el @@ -286,24 +286,27 @@ Uses the configured 'refresh dirs' \(defaults to the classpath dirs). With a single prefix argument, or if MODE is `refresh-all', reload all namespaces on the classpath dirs unconditionally. -With a double prefix argument, or if MODE is `clear', clear the state of -the namespace tracker before reloading. This is useful for recovering from +With a double prefix argument, or if MODE is `clear' (or `clear-and-inhibit'), +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. -With a negative prefix argument, or if MODE is `inhibit-fns', prevent any -refresh functions (defined in `cider-ns-refresh-before-fn' and +With a negative prefix argument, +or if MODE is `inhibit-fns' (or `clear-and-inhibit'), + prevent any refresh functions (defined in `cider-ns-refresh-before-fn' and `cider-ns-refresh-after-fn') from being invoked." (interactive "p") (cider-ensure-connected) (cider-ensure-op-supported "refresh") (cider-ensure-op-supported "cider.clj-reload/reload") (cider-ns-refresh--save-modified-buffers) - (let ((clear? (member mode '(clear 16))) + (let ((clear? (member mode '(clear clear-and-inhibit 16))) (all? (member mode '(refresh-all 4))) - (inhibit-refresh-fns (member mode '(inhibit-fns -1)))) + (inhibit-refresh-fns (member mode '(inhibit-fns clear-and-inhibit -1)))) (cider-map-repls :clj (lambda (conn) ;; Inside the lambda, so the buffer is not created if we error out. From 6437d42791fe86794f2225b0097eedb83dcefed2 Mon Sep 17 00:00:00 2001 From: vemv Date: Sun, 10 Mar 2024 20:41:05 +0100 Subject: [PATCH 2/7] `cider-ns--present-error`: prefer `end-of-sexp` One has to use structural movements in order to present the overlay without errors. By using this finer-grained function, it's more likely that the overlay will show at the right place (and not too far away at the bottom). --- cider-ns.el | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cider-ns.el b/cider-ns.el index 9e036c670..924337fb3 100644 --- a/cider-ns.el +++ b/cider-ns.el @@ -153,7 +153,7 @@ presenting the error message as an overlay." (cider--display-interactive-eval-result trimmed-err 'error (save-excursion - (end-of-defun) + (end-of-sexp) (point)) 'cider-error-overlay-face))))) (cider--render-stacktrace-causes error) From a76bec6a482b25c016fa595e6e4b8f5be7ed2f01 Mon Sep 17 00:00:00 2001 From: vemv Date: Sun, 10 Mar 2024 21:15:32 +0100 Subject: [PATCH 3/7] Strengthen `cider-ns--present-error` --- cider-ns.el | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/cider-ns.el b/cider-ns.el index 924337fb3..ef16e00b0 100644 --- a/cider-ns.el +++ b/cider-ns.el @@ -137,8 +137,9 @@ presenting the error message as an overlay." ;; jars are unlikely sources of user errors, so we favor the next `cause-dict': (not (string-prefix-p "jar:" file-url)) line) - (setq buf (cider--find-buffer-for-file file-url)) - (list buf (cons line column))))) + (when-let ((found (cider--find-buffer-for-file file-url))) + (setq buf found) + (list buf (cons line column)))))) error))) (when jump-args (apply #'cider-jump-to jump-args) From 376e7b47f552bfccca5b8cf436992a58f9430581 Mon Sep 17 00:00:00 2001 From: vemv Date: Thu, 14 Mar 2024 06:37:29 +0100 Subject: [PATCH 4/7] Introduce `cider--semantic-end-of-line` --- cider-ns.el | 4 +-- cider-util.el | 22 ++++++++++++++ test/cider-util-tests.el | 65 ++++++++++++++++++++++++++++++++++++++++ 3 files changed, 88 insertions(+), 3 deletions(-) diff --git a/cider-ns.el b/cider-ns.el index ef16e00b0..5e61bfdbe 100644 --- a/cider-ns.el +++ b/cider-ns.el @@ -153,9 +153,7 @@ presenting the error message as an overlay." (trimmed-err (funcall cider-inline-error-message-function message))) (cider--display-interactive-eval-result trimmed-err 'error - (save-excursion - (end-of-sexp) - (point)) + (cider--semantic-end-of-line) 'cider-error-overlay-face))))) (cider--render-stacktrace-causes error) ;; Select the window displaying the 'culprit' buffer so that the user can immediately fix it, diff --git a/cider-util.el b/cider-util.el index 8316af962..d5a07eea0 100644 --- a/cider-util.el +++ b/cider-util.el @@ -826,6 +826,28 @@ KIND can be the symbols `ns', `var', `emph', `fn', or a face name." (t x))) menu-list)) +(defun cider--semantic-end-of-line () + "Returns POINT at the closest EOL that we can move to semantically, +i.e. using sexp-aware navigation." + (let ((continue t) + (p (point))) + (save-excursion + (while continue + (end-of-line) + (condition-case nil + (save-excursion + ;; If we can't `clojure-backward-logical-sexp', + ;; it means that we aren't in a 'semantic' position, + ;; so functions like `cider--make-result-overlay' (which use `clojure-backward-logical-sexp' internally) would fail + (clojure-backward-logical-sexp)) + (scan-error (forward-line))) + (setq p (point)) + (setq continue (and (not (eolp)) ;; we're trying to move to the end of the line + (not (eobp)) ;; abort if we reached EOF (infinite loop avoidance) + (not (equal p (point))) ;; abort if we aren't moving (infinite loop avoidance) + ))) + (point)))) + (provide 'cider-util) ;;; cider-util.el ends here diff --git a/test/cider-util-tests.el b/test/cider-util-tests.el index 9c2e612e0..069fe7862 100644 --- a/test/cider-util-tests.el +++ b/test/cider-util-tests.el @@ -392,3 +392,68 @@ and some other vars (like clojure.core/filter). (expect (cider-clojure-major-mode-p) :to-be-truthy) (expect (cider-clojurescript-major-mode-p) :not :to-be-truthy) (expect (cider-clojurec-major-mode-p) :to-be-truthy)))) + +(describe "cider--semantic-end-of-line" + (with-clojure-buffer "|(def foo) +bar +baz" + (expect (cider--semantic-end-of-line) :to-equal 10)) + + (with-clojure-buffer "(|def foo) +bar +baz" + (expect (cider--semantic-end-of-line) :to-equal 10)) + + (with-clojure-buffer "(de|f foo) +bar +baz" + (expect (cider--semantic-end-of-line) :to-equal 10)) + + (with-clojure-buffer "(def| foo) +bar +baz" + (expect (cider--semantic-end-of-line) :to-equal 10)) + + (with-clojure-buffer "(def |foo) +bar +baz" + (expect (cider--semantic-end-of-line) :to-equal 10)) + + (with-clojure-buffer "(def fo|o) +bar +baz" + (expect (cider--semantic-end-of-line) :to-equal 10)) + + (with-clojure-buffer "(def foo|) +bar +baz" + (expect (cider--semantic-end-of-line) :to-equal 10)) + + (with-clojure-buffer "(def foo)| +bar +baz" + (expect (cider--semantic-end-of-line) :to-equal 10)) + + (with-clojure-buffer "|(def + +foo) +bar +baz" + (expect (cider--semantic-end-of-line) :to-equal 5)) + + (with-clojure-buffer "(def +| +foo) +bar +baz" + (expect (cider--semantic-end-of-line) :to-equal 6)) + + (with-clojure-buffer "(def foo) +bar| +baz" + (expect (cider--semantic-end-of-line) :to-equal 14)) + + (with-clojure-buffer "(def foo) +bar +baz|" + (expect (cider--semantic-end-of-line) :to-equal 18))) From 63d5d345929f9ae34793345049f193fd01cb3aea Mon Sep 17 00:00:00 2001 From: vemv Date: Thu, 14 Mar 2024 06:43:26 +0100 Subject: [PATCH 5/7] Expand `cider-ns` user manual --- doc/modules/ROOT/pages/usage/misc_features.adoc | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/doc/modules/ROOT/pages/usage/misc_features.adoc b/doc/modules/ROOT/pages/usage/misc_features.adoc index cfa2f93ea..ab1e762bd 100644 --- a/doc/modules/ROOT/pages/usage/misc_features.adoc +++ b/doc/modules/ROOT/pages/usage/misc_features.adoc @@ -62,17 +62,24 @@ Typing kbd:[C-c M-n r] or kbd:[C-c M-n M-r] will invoke `cider-ns-refresh` and reload all modified Clojure files on the classpath. -Adding a prefix argument, kbd:[C-u C-c M-n r], will reload all +Adding a prefix argument, kbd:[C-u C-c M-n r], it will reload all the namespaces on the classpath unconditionally, regardless of their modification status. -Adding a double prefix argument, kbd:[C-u C-u M-n r], will first +Adding a double prefix argument, kbd:[C-u C-u M-n r], it will first clear the state of the namespace tracker before reloading. This is -useful for recovering from some classes of error that normal reloads +useful for recovering from some classes of errosr that normal reloads would otherwise not recover from. A good example is circular dependencies. The trade-off is that stale code from any deleted files may not be completely unloaded. +Adding a negative prefix argument will inhibit +the `cider-ns-refresh-before-fn` and `cider-ns-refresh-after-fn` functions from being run. + +Invoked with a programmatic `clear-and-inhibit` argument, +it will both clear the namespace tracker before reloading (per the previous paragraph), +and inhibit the `cider-ns-refresh-before-fn` and `cider-ns-refresh-after-fn` functions from being run. + `cider-ns-refresh` wraps https://github.com/clojure/tools.namespace[clojure.tools.namespace], and as such the same From f85f741d9ffe540645433194ea773f42349e4f70 Mon Sep 17 00:00:00 2001 From: vemv Date: Thu, 14 Mar 2024 06:49:21 +0100 Subject: [PATCH 6/7] Add `fo` to codespell.txt --- codespell.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/codespell.txt b/codespell.txt index 5158a017f..7d879ef97 100644 --- a/codespell.txt +++ b/codespell.txt @@ -1,4 +1,5 @@ edn +fo hist juxt nd From 9e7417e0a6ed5cc960de6171f3af0f9dbf0afe98 Mon Sep 17 00:00:00 2001 From: vemv Date: Thu, 14 Mar 2024 06:51:30 +0100 Subject: [PATCH 7/7] Typo --- doc/modules/ROOT/pages/usage/misc_features.adoc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/modules/ROOT/pages/usage/misc_features.adoc b/doc/modules/ROOT/pages/usage/misc_features.adoc index ab1e762bd..858e4419a 100644 --- a/doc/modules/ROOT/pages/usage/misc_features.adoc +++ b/doc/modules/ROOT/pages/usage/misc_features.adoc @@ -68,7 +68,7 @@ modification status. Adding a double prefix argument, kbd:[C-u C-u M-n r], it will first clear the state of the namespace tracker before reloading. This is -useful for recovering from some classes of errosr that normal reloads +useful for recovering from some classes of errors that normal reloads would otherwise not recover from. A good example is circular dependencies. The trade-off is that stale code from any deleted files may not be completely unloaded.