Skip to content

Commit f2d0601

Browse files
committed
Speedup align-forms by introducing indentation rules caching
1 parent f036ed1 commit f2d0601

1 file changed

Lines changed: 32 additions & 8 deletions

File tree

clojure-ts-mode.el

Lines changed: 32 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1151,6 +1151,10 @@ Includes a dispatch value when applicable (defmethods)."
11511151
"Return non-nil if NODE represents a protocol or interface definition."
11521152
(clojure-ts--definition-node-match-p clojure-ts--interface-type-regexp node))
11531153

1154+
(defun clojure-ts--value-type-node-p (node)
1155+
"Return non-nil if field name of the NODE is value."
1156+
(string= (treesit-node-field-name node) "value"))
1157+
11541158
(defvar clojure-ts--imenu-settings
11551159
`(("Namespace" "list_lit" clojure-ts--ns-node-p)
11561160
("Function" "list_lit" clojure-ts--function-node-p
@@ -1440,17 +1444,34 @@ If NS is defined, then the fully qualified symbol is passed to
14401444
(seq-sort (lambda (spec1 _spec2)
14411445
(equal (car spec1) :block)))))))))
14421446

1443-
(defun clojure-ts--find-semantic-rules-for-node (node)
1444-
"Return a list of semantic rules for NODE."
1445-
(let* ((first-child (clojure-ts--node-child-skip-metadata node 0))
1446-
(symbol-name (clojure-ts--named-node-text first-child))
1447-
(symbol-namespace (clojure-ts--node-namespace-text first-child)))
1447+
(defvar clojure-ts--dynamic-indent-for-symbol-cache
1448+
(make-hash-table :test 'equal))
1449+
1450+
(defvar clojure-ts--dynamic-indent-for-symbol-cache-p nil
1451+
"If set to nil, do not use cache for dynamic indentation rules.")
1452+
1453+
(defun clojure-ts--find-semantic-rules-for-symbol (node)
1454+
"Return a list of semantic rules for symbol NODE.
1455+
1456+
If rules are not found return :not-found symbol."
1457+
(let ((symbol-name (clojure-ts--named-node-text node))
1458+
(symbol-namespace (clojure-ts--node-namespace-text node)))
14481459
(or (clojure-ts--dynamic-indent-for-symbol symbol-name symbol-namespace)
14491460
(alist-get symbol-name
14501461
clojure-ts--semantic-indent-rules-cache
14511462
nil
14521463
nil
1453-
#'equal))))
1464+
#'equal)
1465+
:not-found)))
1466+
1467+
(defun clojure-ts--find-semantic-rules-for-node (node)
1468+
"Return a list of semantic rules for NODE."
1469+
(let* ((first-child (clojure-ts--first-value-child node))
1470+
(symbol-full-name (treesit-node-text first-child)))
1471+
(if clojure-ts--dynamic-indent-for-symbol-cache-p
1472+
(with-memoization (gethash symbol-full-name clojure-ts--dynamic-indent-for-symbol-cache)
1473+
(clojure-ts--find-semantic-rules-for-symbol first-child))
1474+
(clojure-ts--find-semantic-rules-for-symbol first-child))))
14541475

14551476
(defun clojure-ts--find-semantic-rule (node parent current-depth)
14561477
"Return a suitable indentation rule for NODE, considering the CURRENT-DEPTH.
@@ -1462,7 +1483,8 @@ increasing the CURRENT-DEPTH. If a rule is not found upon reaching the
14621483
root of the syntax tree, it returns nil. A rule is considered a match
14631484
only if the CURRENT-DEPTH matches the rule's required depth."
14641485
(let* ((idx (- (treesit-node-index node) 2)))
1465-
(if-let* ((rule-set (clojure-ts--find-semantic-rules-for-node parent)))
1486+
(if-let* ((rule-set (clojure-ts--find-semantic-rules-for-node parent))
1487+
((not (equal rule-set :not-found))))
14661488
(if (zerop current-depth)
14671489
(let ((rule (car rule-set)))
14681490
(if (equal (car rule) :block)
@@ -1917,9 +1939,11 @@ between BEG and END."
19171939
(end (clojure-ts--end-of-defun-pos)))
19181940
(list start end))))))
19191941
(setq end (copy-marker end))
1942+
(clrhash clojure-ts--dynamic-indent-for-symbol-cache)
19201943
(let* ((sexps-to-align (clojure-ts--get-nodes-to-align beg (marker-position end)))
19211944
;; We have to disable it here to avoid endless recursion.
1922-
(clojure-ts-align-forms-automatically nil))
1945+
(clojure-ts-align-forms-automatically nil)
1946+
(clojure-ts--dynamic-indent-for-symbol-cache-p t))
19231947
(save-excursion
19241948
(indent-region beg (marker-position end))
19251949
(dolist (sexp sexps-to-align)

0 commit comments

Comments
 (0)