Skip to content

Commit 34998fb

Browse files
committed
[Fix #478] Cache the result of clojure-find-ns to optimize its performance
1 parent 9b9bd5f commit 34998fb

File tree

2 files changed

+52
-14
lines changed

2 files changed

+52
-14
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
* Indent `fdef` (clojure.spec) like a `def`.
88
* The results of `clojure-project-dir` are cached by default to optimize performance.
99
* Add `shadow-cljs.edn` to the default list of build tool files.
10+
* [#478](https://github.com/clojure-emacs/clojure-mode/issues/478): Cache the result of `clojure-find-ns` to optimize performance.
1011

1112
## 5.7.0 (2018-04-29)
1213

clojure-mode.el

Lines changed: 51 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1796,23 +1796,60 @@ content) are considered part of the preceding sexp."
17961796
(zero-or-one (any ":'")) ;; (in-ns 'foo) or (ns+ :user)
17971797
(group (one-or-more (not (any "()\"" whitespace))) symbol-end)))
17981798

1799+
(defcustom clojure-cache-ns t
1800+
"Whether to cache the results of `clojure-find-ns'.
1801+
1802+
Note that this won't work well in buffers with multiple namespace
1803+
declarations (which rarely occur in practice) and you'll
1804+
have to invalidate this manually after changing the ns for
1805+
a buffer."
1806+
:type 'boolean
1807+
:safe #'booleanp
1808+
:package-version '(clojure-mode . "5.8.0"))
1809+
1810+
(defvar-local clojure-cached-ns nil
1811+
"A buffer ns cache used to speed up ns-related operations.")
1812+
17991813
(defun clojure-find-ns ()
18001814
"Return the namespace of the current Clojure buffer.
18011815
Return the namespace closest to point and above it. If there are
1802-
no namespaces above point, return the first one in the buffer."
1803-
(save-excursion
1804-
(save-restriction
1805-
(widen)
1806-
1807-
;; Move to top-level to avoid searching from inside ns
1808-
(ignore-errors (while t (up-list nil t t)))
1809-
1810-
;; The closest ns form above point.
1811-
(when (or (re-search-backward clojure-namespace-name-regex nil t)
1812-
;; Or any form at all.
1813-
(and (goto-char (point-min))
1814-
(re-search-forward clojure-namespace-name-regex nil t)))
1815-
(match-string-no-properties 4)))))
1816+
no namespaces above point, return the first one in the buffer.
1817+
1818+
The results will be cached if `clojure-cache-ns' is set to t."
1819+
(if (and clojure-cache-ns clojure-cached-ns)
1820+
clojure-cached-ns
1821+
(let ((ns (save-excursion
1822+
(save-restriction
1823+
(widen)
1824+
1825+
;; Move to top-level to avoid searching from inside ns
1826+
(ignore-errors (while t (up-list nil t t)))
1827+
1828+
;; The closest ns form above point.
1829+
(when (or (re-search-backward clojure-namespace-name-regex nil t)
1830+
;; Or any form at all.
1831+
(and (goto-char (point-min))
1832+
(re-search-forward clojure-namespace-name-regex nil t)))
1833+
(match-string-no-properties 4))))))
1834+
(setq clojure-cached-ns ns)
1835+
ns)))
1836+
1837+
(defun clojure-show-cache ()
1838+
"Display cached values if present.
1839+
Useful for debugging."
1840+
(interactive)
1841+
(message "Cached Project: %s, Cached Namespace: %s" clojure-cached-project-dir clojure-cached-ns))
1842+
1843+
(defun clojure-clear-cache ()
1844+
"Clear all buffer-local cached values.
1845+
1846+
Normally you'd need to do this very infrequently - e.g.
1847+
after renaming the root folder of project or after
1848+
renaming a namespace."
1849+
(interactive)
1850+
(setq clojure-cached-project-dir nil
1851+
clojure-cached-ns nil)
1852+
(message "Buffer-local clojure-mode cache cleared"))
18161853

18171854
(defconst clojure-def-type-and-name-regex
18181855
(concat "(\\(?:\\(?:\\sw\\|\\s_\\)+/\\)?"

0 commit comments

Comments
 (0)