@@ -1003,13 +1003,10 @@ If there is no namespace, returns nil."
10031003(defun clojure-ts--node-child-skip-metadata (node n )
10041004 " Return the Nth child of NODE like `treesit-node-child' , sans metadata.
10051005Skip the optional metadata node at pos 0 if present."
1006- (let ((first-child (treesit-node-child node 0 t )))
1007- (treesit-node-child
1008- node
1009- (if (clojure-ts--metadata-node-p first-child)
1010- (1+ n)
1011- n)
1012- t )))
1006+ (let ((value-nodes (thread-last (treesit-node-children node t )
1007+ (seq-filter (lambda (child )
1008+ (string= (treesit-node-field-name child) " value" ))))))
1009+ (seq-elt value-nodes n)))
10131010
10141011(defun clojure-ts--first-value-child (node )
10151012 " Return the first value child of the given NODE.
@@ -1439,17 +1436,34 @@ If NS is defined, then the fully qualified symbol is passed to
14391436 (seq-sort (lambda (spec1 _spec2 )
14401437 (equal (car spec1) :block )))))))))
14411438
1442- (defun clojure-ts--find-semantic-rules-for-node (node )
1443- " Return a list of semantic rules for NODE."
1444- (let* ((first-child (clojure-ts--node-child-skip-metadata node 0 ))
1445- (symbol-name (clojure-ts--named-node-text first-child))
1446- (symbol-namespace (clojure-ts--node-namespace-text first-child)))
1439+ (defvar clojure-ts--dynamic-indent-for-symbol-cache
1440+ (make-hash-table :test 'equal ))
1441+
1442+ (defvar clojure-ts--dynamic-indent-for-symbol-cache-p nil
1443+ " If set to nil, do not use cache for dynamic indentation rules." )
1444+
1445+ (defun clojure-ts--find-semantic-rules-for-symbol (node )
1446+ " Return a list of semantic rules for symbol NODE.
1447+
1448+ If rules are not found return :not-found symbol."
1449+ (let ((symbol-name (clojure-ts--named-node-text node))
1450+ (symbol-namespace (clojure-ts--node-namespace-text node)))
14471451 (or (clojure-ts--dynamic-indent-for-symbol symbol-name symbol-namespace)
14481452 (alist-get symbol-name
14491453 clojure-ts--semantic-indent-rules-cache
14501454 nil
14511455 nil
1452- #'equal ))))
1456+ #'equal )
1457+ :not-found )))
1458+
1459+ (defun clojure-ts--find-semantic-rules-for-node (node )
1460+ " Return a list of semantic rules for NODE."
1461+ (let* ((first-child (clojure-ts--node-child-skip-metadata node 0 ))
1462+ (symbol-full-name (treesit-node-text first-child)))
1463+ (if clojure-ts--dynamic-indent-for-symbol-cache-p
1464+ (with-memoization (gethash symbol-full-name clojure-ts--dynamic-indent-for-symbol-cache)
1465+ (clojure-ts--find-semantic-rules-for-symbol first-child))
1466+ (clojure-ts--find-semantic-rules-for-symbol first-child))))
14531467
14541468(defun clojure-ts--find-semantic-rule (node parent current-depth )
14551469 " Return a suitable indentation rule for NODE, considering the CURRENT-DEPTH.
@@ -1461,7 +1475,8 @@ increasing the CURRENT-DEPTH. If a rule is not found upon reaching the
14611475root of the syntax tree, it returns nil. A rule is considered a match
14621476only if the CURRENT-DEPTH matches the rule's required depth."
14631477 (let* ((idx (- (treesit-node-index node) 2 )))
1464- (if-let* ((rule-set (clojure-ts--find-semantic-rules-for-node parent)))
1478+ (if-let* ((rule-set (clojure-ts--find-semantic-rules-for-node parent))
1479+ ((not (equal rule-set :not-found ))))
14651480 (if (zerop current-depth)
14661481 (let ((rule (car rule-set)))
14671482 (if (equal (car rule) :block )
@@ -1916,9 +1931,11 @@ between BEG and END."
19161931 (end (clojure-ts--end-of-defun-pos)))
19171932 (list start end))))))
19181933 (setq end (copy-marker end))
1934+ (clrhash clojure-ts--dynamic-indent-for-symbol-cache)
19191935 (let* ((sexps-to-align (clojure-ts--get-nodes-to-align beg (marker-position end)))
19201936 ; ; We have to disable it here to avoid endless recursion.
1921- (clojure-ts-align-forms-automatically nil ))
1937+ (clojure-ts-align-forms-automatically nil )
1938+ (clojure-ts--dynamic-indent-for-symbol-cache-p t ))
19221939 (save-excursion
19231940 (indent-region beg (marker-position end))
19241941 (dolist (sexp sexps-to-align)
@@ -2570,6 +2587,28 @@ before DELIM-OPEN."
25702587 (goto-char pos))
25712588 (user-error " Must be invoked inside a list" )))
25722589
2590+ (defun clojure-ts--toggle-ignore-next-sexp (&optional n )
2591+ " Insert or delete N `#_' ignore macros at the current point.
2592+
2593+ Point must be directly before a sexp or the #_ characters. When acting
2594+ on a top level form, insert #_ on a new line preceding the form to
2595+ prevent indentation changes."
2596+
2597+ (dotimes (_ (or n 1 )) (insert-before-markers " #_" )))
2598+
2599+ (defun clojure-ts-toggle-ignore (&optional n )
2600+ " Toggle the #_ ignore reader form for the sexp at point.
2601+
2602+ With the numeric argument, toggle N number of #_ forms at the same point.
2603+
2604+ e.g. with N = 2:
2605+ |a b c => #_#_a b c"
2606+ (interactive " p" )
2607+ (let ((sexp (treesit-thing-at-point 'sexp 'nested )))
2608+ (goto-char (treesit-node-start sexp))
2609+ (clojure-ts--toggle-ignore-next-sexp n)
2610+ ))
2611+
25732612(defvar clojure-ts-refactor-map
25742613 (let ((map (make-sparse-keymap )))
25752614 (keymap-set map " C-t" #'clojure-ts-thread )
0 commit comments