@@ -404,9 +404,9 @@ with the markdown_inline grammar."
404404 ; ; `clojure.core' .
405405 :feature 'builtin
406406 :language 'clojure
407- `(((list_lit meta: _ :? :anchor (sym_lit !namespace name: (sym_name) @font-lock-keyword-face))
407+ `(((list_lit meta: _ :* :anchor (sym_lit !namespace name: (sym_name) @font-lock-keyword-face))
408408 (:match , clojure-ts--builtin-symbol-regexp @font-lock-keyword-face))
409- ((list_lit meta: _ :? :anchor
409+ ((list_lit meta: _ :* :anchor
410410 (sym_lit namespace: ((sym_ns) @ns
411411 (:equal " clojure.core" @ns))
412412 name: (sym_name) @font-lock-keyword-face))
@@ -608,6 +608,12 @@ This does not include the NODE's namespace."
608608 (let ((first-child (treesit-node-child node 0 t )))
609609 (treesit-node-child node (if (clojure-ts--metadata-node-p first-child) (1+ n) n) t )))
610610
611+ (defun clojure-ts--node-with-metadata-parent (node )
612+ " Return parent for NODE only if NODE has metadata, otherwise returns nil."
613+ (when-let* ((prev-sibling (treesit-node-prev-sibling node))
614+ ((clojure-ts--metadata-node-p prev-sibling)))
615+ (treesit-node-parent (treesit-node-parent node))))
616+
611617(defun clojure-ts--symbol-matches-p (symbol-regexp node )
612618 " Return non-nil if NODE is a symbol that matches SYMBOL-REGEXP."
613619 (and (clojure-ts--symbol-node-p node)
@@ -977,18 +983,54 @@ forms like deftype, defrecord, reify, proxy, etc."
977983 (and prev-sibling
978984 (clojure-ts--metadata-node-p prev-sibling))))
979985
986+ (defun clojure-ts--anchor-parent-skip-metadata (_node parent _bol )
987+ " Anchor function that returns position of PARENT start for NODE.
988+
989+ If PARENT has optional metadata we skip it and return starting position
990+ of the first child's opening paren.
991+
992+ NOTE: This anchor is used to fix indentation issue for forms with type
993+ hints."
994+ (let ((first-child (treesit-node-child parent 0 t )))
995+ (if (clojure-ts--metadata-node-p first-child)
996+ ; ; We don't need named node here
997+ (treesit-node-start (treesit-node-child parent 1 ))
998+ (treesit-node-start parent))))
999+
1000+ (defun clojure-ts--match-collection-item-with-metadata (node-type )
1001+ " Returns a matcher for a collection item with metadata by NODE-TYPE.
1002+
1003+ The returned matcher accepts NODE, PARENT and BOL and returns true only
1004+ if NODE has metadata and its parent has type NODE-TYPE."
1005+ (lambda (node _parent _bol )
1006+ (string-equal node-type
1007+ (treesit-node-type
1008+ (clojure-ts--node-with-metadata-parent node)))))
1009+
9801010(defun clojure-ts--semantic-indent-rules ()
9811011 " Return a list of indentation rules for `treesit-simple-indent-rules' ."
9821012 `((clojure
9831013 ((parent-is " source" ) parent-bol 0 )
9841014 (clojure-ts--match-docstring parent 0 )
9851015 ; ; https://guide.clojure.style/#body-indentation
9861016 (clojure-ts--match-method-body parent 2 )
987- (clojure-ts--match-form-body parent 2 )
1017+ (clojure-ts--match-form-body clojure-ts--anchor- parent-skip-metadata 2 )
9881018 ; ; https://guide.clojure.style/#threading-macros-alignment
9891019 (clojure-ts--match-threading-macro-arg prev-sibling 0 )
9901020 ; ; https://guide.clojure.style/#vertically-align-fn-args
9911021 (clojure-ts--match-function-call-arg (nth-sibling 2 nil ) 0 )
1022+ ; ; Collections items with metadata.
1023+ ; ;
1024+ ; ; This should be before `clojure-ts--match-with-metadata' , otherwise they
1025+ ; ; will never be matched.
1026+ (,(clojure-ts--match-collection-item-with-metadata " vec_lit" ) grand-parent 1 )
1027+ (,(clojure-ts--match-collection-item-with-metadata " map_lit" ) grand-parent 1 )
1028+ (,(clojure-ts--match-collection-item-with-metadata " set_lit" ) grand-parent 2 )
1029+ ; ;
1030+ ; ; If we enable this rule for lists, it will break many things.
1031+ ; ; (,(clojure-ts--match-collection-item-with-metadata "list_lit") grand-parent 1)
1032+ ; ;
1033+ ; ; All other forms with metadata.
9921034 (clojure-ts--match-with-metadata parent 0 )
9931035 ; ; Literal Sequences
9941036 ((parent-is " list_lit" ) parent 1 ) ; ; https://guide.clojure.style/#one-space-indent
0 commit comments