@@ -746,33 +746,61 @@ The possible values for this variable are
746746 ((parent-is " list_lit" ) parent 1 )
747747 ((parent-is " set_lit" ) parent 2 ))))
748748
749- (defvar clojure-ts--symbols-with-body-expressions -regexp
749+ (defvar clojure-ts--symbols-block-0 -regexp
750750 (eval-and-compile
751- (rx (or
752- ; ; Match def* symbols,
753- ; ; we also explicitly do not match symbols beginning with
754- ; ; "default" "deflate" and "defer", like cljfmt
755- (and line-start " def" )
756- ; ; Match with-* symbols
757- (and line-start " with-" )
758- ; ; Exact matches
759- (and line-start
760- (or " alt!" " alt!!" " are" " as->"
761- " binding" " bound-fn"
762- " case" " catch" " comment" " cond" " condp" " cond->" " cond->>"
763- " delay" " do" " doseq" " dotimes" " doto"
764- " extend" " extend-protocol" " extend-type"
765- " fdef" " finally" " fn" " for" " future"
766- " go" " go-loop"
767- " if" " if-let" " if-not" " if-some"
768- " let" " letfn" " locking" " loop"
769- " match" " ns" " proxy" " reify" " struct-map"
770- " testing" " thread" " try"
771- " use-fixtures"
772- " when" " when-first" " when-let" " when-not" " when-some" " while" )
773- line-end))))
751+ (rx (and line-start
752+ (or " alt!" " alt!!"
753+ " comment"
754+ " cond"
755+ " delay"
756+ " do"
757+ " finally"
758+ " future"
759+ " go"
760+ " thread"
761+ " try"
762+ " with-out-str" )
763+ line-end)))
774764 " A regex to match symbols that are functions/macros with a body argument.
775- Taken from cljfmt:
765+ Taken from cljfmt (all symbols with [[:block 0]] rule):
766+ https://github.com/weavejester/cljfmt/blob/fb26b22f569724b05c93eb2502592dfc2de898c3/cljfmt/resources/cljfmt/indents/clojure.clj" )
767+
768+ (defun clojure-ts--match-block-0-body (node parent bol )
769+ " Match NODE if it is an argument to a PARENT expression.
770+
771+ Check if the first expression in the body is not at the same line as
772+ NODE. If there is no body, check that BOL is not at the same line."
773+ (and (clojure-ts--list-node-p parent)
774+ (let* ((first-child (clojure-ts--node-child-skip-metadata parent 0 ))
775+ (body-pos (if-let* ((body (treesit-node-next-sibling first-child)))
776+ (treesit-node-start body)
777+ bol)))
778+ (and (not (clojure-ts--match-with-metadata node))
779+ (clojure-ts--symbol-matches-p
780+ clojure-ts--symbols-block-0-regexp
781+ first-child)
782+ (< (line-number-at-pos (treesit-node-start first-child))
783+ (line-number-at-pos body-pos))))))
784+
785+ (defvar clojure-ts--symbols-block-1-regexp
786+ (eval-and-compile
787+ (rx (and line-start
788+ (or " defprotocol"
789+ " binding"
790+ " case" " cond->" " cond->>"
791+ " doseq" " dotimes" " doto"
792+ " extend" " extend-protocol" " extend-type"
793+ " for"
794+ " go-loop"
795+ " if" " if-let" " if-not" " if-some"
796+ " let" " letfn" " locking" " loop"
797+ " match" " ns" " struct-map"
798+ " testing"
799+ " when" " when-first" " when-let" " when-not" " when-some" " while"
800+ " with-local-vars" " with-open" " with-precision" " with-redefs" )
801+ line-end)))
802+ " A regex to match symbols that are functions/macros with a body argument.
803+ Taken from cljfmt (all symbols with [[:block 1]] rule):
776804https://github.com/weavejester/cljfmt/blob/fb26b22f569724b05c93eb2502592dfc2de898c3/cljfmt/resources/cljfmt/indents/clojure.clj" )
777805
778806(defun clojure-ts--match-function-call-arg (node parent _bol )
@@ -787,23 +815,93 @@ https://github.com/weavejester/cljfmt/blob/fb26b22f569724b05c93eb2502592dfc2de89
787815 (clojure-ts--keyword-node-p first-child)
788816 (clojure-ts--var-node-p first-child)))))
789817
790- (defun clojure-ts--match-expression-in-body (node parent _bol )
818+ (defun clojure-ts--node-pos-match-block (node parent bol block )
819+ " Return TRUE if NODE index in the PARENT matches requested BLOCK.
820+
821+ NODE might be nil (when we insert an empty line for example), in this
822+ case we look for next available child node in the PARENT after BOL
823+ position.
824+
825+ The first node in the expression is usually an opening paren, the last
826+ node is usually a closing paren (unless some automatic parens mode is
827+ not enabled). If requested BLOCK is 1, the NODE index should be at
828+ least 3 (first node is opening paren, second node is matched symbol,
829+ third node is first argument, and the rest is body which should be
830+ indented.)"
831+ (if node
832+ (> (treesit-node-index node) (1+ block))
833+ (when-let* ((node-after-bol (treesit-node-first-child-for-pos parent bol)))
834+ (> (treesit-node-index node-after-bol) (1+ block)))))
835+
836+ (defun clojure-ts--match-block-1-body (node parent bol )
791837 " Match NODE if it is an expression used in a body argument.
792- PARENT is expected to be a list literal.
793- See `treesit-simple-indent-rules' ."
838+
839+ The NODE has to be at least second argument of the expression. This
840+ rule matches [[:block 1]] rule of cljfmt. If NODE is nil check the next
841+ found node after BOL. PARENT is expected to be a list literal. See
842+ `treesit-simple-indent-rules' ."
794843 (and
795844 (clojure-ts--list-node-p parent)
796845 (let ((first-child (clojure-ts--node-child-skip-metadata parent 0 )))
797- (and
798- (not
799- (clojure-ts--symbol-matches-p
800- ; ; Symbols starting with this are false positives
801- (rx line-start (or " default" " deflate" " defer" ))
802- first-child))
803- (not (clojure-ts--match-with-metadata node))
804- (clojure-ts--symbol-matches-p
805- clojure-ts--symbols-with-body-expressions-regexp
806- first-child)))))
846+ (and (not (clojure-ts--match-with-metadata node))
847+ (clojure-ts--symbol-matches-p
848+ clojure-ts--symbols-block-1-regexp
849+ first-child)
850+ (clojure-ts--node-pos-match-block node parent bol 1 )))))
851+
852+ (defvar clojure-ts--symbols-block-2-regexp
853+ (eval-and-compile
854+ (rx (and line-start
855+ (or " defrecord" " deftype" " are" " as->" " catch" " condp" )
856+ line-end)))
857+ " A regex to match symbols that are functions/macros with a body argument.
858+ Taken from cljfmt (all symbols with [[:block 2]] rule):
859+ https://github.com/weavejester/cljfmt/blob/fb26b22f569724b05c93eb2502592dfc2de898c3/cljfmt/resources/cljfmt/indents/clojure.clj" )
860+
861+ (defun clojure-ts--match-block-2-body (node parent bol )
862+ " Match NODE if it is an argument to a PARENT expression.
863+
864+ The NODE has to be at least third argument of the expression. This rule
865+ matches [[:block 2]] rule of cljfmt. If NODE is nil check the next
866+ found node after BOL."
867+ (and (clojure-ts--list-node-p parent)
868+ (let ((first-child (clojure-ts--node-child-skip-metadata parent 0 )))
869+ (and (not (clojure-ts--match-with-metadata node))
870+ (clojure-ts--symbol-matches-p
871+ clojure-ts--symbols-block-2-regexp
872+ first-child)
873+ (clojure-ts--node-pos-match-block node parent bol 2 )))))
874+
875+ (defvar clojure-ts--symbols-inner-0-regexp
876+ (eval-and-compile
877+ (rx (and line-start
878+ (or " bound-fn"
879+ " def"
880+ " defmacro"
881+ " defmethod"
882+ " defmulti"
883+ " defn"
884+ " defn-"
885+ " defonce"
886+ " deftest"
887+ " fdef"
888+ " fn"
889+ " reify"
890+ " use-fixtures" )
891+ line-end)))
892+ " A regex to match symbols that match [[:inner 0]] cljfmt rule." )
893+
894+ (defun clojure-ts--match-inner-0-body (node parent _bol )
895+ " Match NODE if it is an argument to a PARENT expression.
896+
897+ The NODE has to be a child of an epression that matches rule [[:inner
898+ 0]] of cljfmt."
899+ (and (clojure-ts--list-node-p parent)
900+ (let ((first-child (clojure-ts--node-child-skip-metadata parent 0 )))
901+ (and (not (clojure-ts--match-with-metadata node))
902+ (clojure-ts--symbol-matches-p
903+ clojure-ts--symbols-inner-0-regexp
904+ first-child)))))
807905
808906(defun clojure-ts--match-method-body (_node parent _bol )
809907 " Matches a `NODE' in the body of a `PARENT' method implementation.
@@ -885,7 +983,10 @@ forms like deftype, defrecord, reify, proxy, etc."
885983 (clojure-ts--match-docstring parent 0 )
886984 ; ; https://guide.clojure.style/#body-indentation
887985 (clojure-ts--match-method-body parent 2 )
888- (clojure-ts--match-expression-in-body parent 2 )
986+ (clojure-ts--match-block-0-body parent 2 )
987+ (clojure-ts--match-block-1-body parent 2 )
988+ (clojure-ts--match-block-2-body parent 2 )
989+ (clojure-ts--match-inner-0-body parent 2 )
889990 ; ; https://guide.clojure.style/#threading-macros-alignment
890991 (clojure-ts--match-threading-macro-arg prev-sibling 0 )
891992 ; ; https://guide.clojure.style/#vertically-align-fn-args
0 commit comments