@@ -1003,9 +1003,9 @@ 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 ((value-nodes (seq -filter ( lambda ( child )
1007- ( string= (treesit-node-field-name child) " value" ))
1008- (treesit-node-children node t ) )))
1006+ (let ((value-nodes (treesit -filter- child node
1007+ # 'clojure-ts-- value-type-node-p
1008+ t )))
10091009 (seq-elt value-nodes n)))
10101010
10111011(defun clojure-ts--first-value-child (node )
@@ -1147,6 +1147,10 @@ Includes a dispatch value when applicable (defmethods)."
11471147 " Return non-nil if NODE represents a protocol or interface definition."
11481148 (clojure-ts--definition-node-match-p clojure-ts--interface-type-regexp node))
11491149
1150+ (defun clojure-ts--value-type-node-p (node )
1151+ " Return non-nil if field name of the NODE is value."
1152+ (string= (treesit-node-field-name node) " value" ))
1153+
11501154(defvar clojure-ts--imenu-settings
11511155 `((" Namespace" " list_lit" clojure-ts--ns-node-p)
11521156 (" Function" " list_lit" clojure-ts--function-node-p
@@ -1435,17 +1439,34 @@ If NS is defined, then the fully qualified symbol is passed to
14351439 (seq-sort (lambda (spec1 _spec2 )
14361440 (equal (car spec1) :block )))))))))
14371441
1438- (defun clojure-ts--find-semantic-rules-for-node (node )
1439- " Return a list of semantic rules for NODE."
1440- (let* ((first-child (clojure-ts--node-child-skip-metadata node 0 ))
1441- (symbol-name (clojure-ts--named-node-text first-child))
1442- (symbol-namespace (clojure-ts--node-namespace-text first-child)))
1442+ (defvar clojure-ts--dynamic-indent-for-symbol-cache
1443+ (make-hash-table :test 'equal ))
1444+
1445+ (defvar clojure-ts--dynamic-indent-for-symbol-cache-p nil
1446+ " If set to nil, do not use cache for dynamic indentation rules." )
1447+
1448+ (defun clojure-ts--find-semantic-rules-for-symbol (node )
1449+ " Return a list of semantic rules for symbol NODE.
1450+
1451+ If rules are not found return :not-found symbol."
1452+ (let ((symbol-name (clojure-ts--named-node-text node))
1453+ (symbol-namespace (clojure-ts--node-namespace-text node)))
14431454 (or (clojure-ts--dynamic-indent-for-symbol symbol-name symbol-namespace)
14441455 (alist-get symbol-name
14451456 clojure-ts--semantic-indent-rules-cache
14461457 nil
14471458 nil
1448- #'equal ))))
1459+ #'equal )
1460+ :not-found )))
1461+
1462+ (defun clojure-ts--find-semantic-rules-for-node (node )
1463+ " Return a list of semantic rules for NODE."
1464+ (let* ((first-child (clojure-ts--first-value-child node))
1465+ (symbol-full-name (treesit-node-text first-child)))
1466+ (if clojure-ts--dynamic-indent-for-symbol-cache-p
1467+ (with-memoization (gethash symbol-full-name clojure-ts--dynamic-indent-for-symbol-cache)
1468+ (clojure-ts--find-semantic-rules-for-symbol first-child))
1469+ (clojure-ts--find-semantic-rules-for-symbol first-child))))
14491470
14501471(defun clojure-ts--find-semantic-rule (node parent current-depth )
14511472 " Return a suitable indentation rule for NODE, considering the CURRENT-DEPTH.
@@ -1457,7 +1478,8 @@ increasing the CURRENT-DEPTH. If a rule is not found upon reaching the
14571478root of the syntax tree, it returns nil. A rule is considered a match
14581479only if the CURRENT-DEPTH matches the rule's required depth."
14591480 (let* ((idx (- (treesit-node-index node) 2 )))
1460- (if-let* ((rule-set (clojure-ts--find-semantic-rules-for-node parent)))
1481+ (if-let* ((rule-set (clojure-ts--find-semantic-rules-for-node parent))
1482+ ((not (equal rule-set :not-found ))))
14611483 (if (zerop current-depth)
14621484 (let ((rule (car rule-set)))
14631485 (if (equal (car rule) :block )
@@ -1912,9 +1934,11 @@ between BEG and END."
19121934 (end (clojure-ts--end-of-defun-pos)))
19131935 (list start end))))))
19141936 (setq end (copy-marker end))
1937+ (clrhash clojure-ts--dynamic-indent-for-symbol-cache)
19151938 (let* ((sexps-to-align (clojure-ts--get-nodes-to-align beg (marker-position end)))
19161939 ; ; We have to disable it here to avoid endless recursion.
1917- (clojure-ts-align-forms-automatically nil ))
1940+ (clojure-ts-align-forms-automatically nil )
1941+ (clojure-ts--dynamic-indent-for-symbol-cache-p t ))
19181942 (save-excursion
19191943 (indent-region beg (marker-position end))
19201944 (dolist (sexp sexps-to-align)
@@ -2566,6 +2590,28 @@ before DELIM-OPEN."
25662590 (goto-char pos))
25672591 (user-error " Must be invoked inside a list" )))
25682592
2593+ (defun clojure-ts--toggle-ignore-next-sexp (&optional n )
2594+ " Insert or delete N `#_' ignore macros at the current point.
2595+
2596+ Point must be directly before a sexp or the #_ characters. When acting
2597+ on a top level form, insert #_ on a new line preceding the form to
2598+ prevent indentation changes."
2599+
2600+ (dotimes (_ (or n 1 )) (insert-before-markers " #_" )))
2601+
2602+ (defun clojure-ts-toggle-ignore (&optional n )
2603+ " Toggle the #_ ignore reader form for the sexp at point.
2604+
2605+ With the numeric argument, toggle N number of #_ forms at the same point.
2606+
2607+ e.g. with N = 2:
2608+ |a b c => #_#_a b c"
2609+ (interactive " p" )
2610+ (let ((sexp (treesit-thing-at-point 'sexp 'nested )))
2611+ (goto-char (treesit-node-start sexp))
2612+ (clojure-ts--toggle-ignore-next-sexp n)
2613+ ))
2614+
25692615(defvar clojure-ts-refactor-map
25702616 (let ((map (make-sparse-keymap )))
25712617 (keymap-set map " C-t" #'clojure-ts-thread )
0 commit comments