Adding Indent Queries
+Helix uses tree-sitter to correctly indent new lines. This requires
+a tree-sitter grammar and an indent.scm
query file placed in
+runtime/queries/{language}/indents.scm
. The indentation for a line
+is calculated by traversing the syntax tree from the lowest node at the
+beginning of the new line. Each of these nodes contributes to the total
+indent when it is captured by the query (in what way depends on the name
+of the capture).
Note that it matters where these added indents begin. For example, +multiple indent level increases that start on the same line only increase +the total indent level by 1.
+Scopes
+Added indents don't always apply to the whole node. For example, in most +cases when a node should be indented, we actually only want everything +except for its first line to be indented. For this, there are several +scopes (more scopes may be added in the future if required):
+-
+
-
+
+all
: +This scope applies to the whole captured node. This is only different from +tail
when the captured node is the first node on its line.
+ -
+
+tail
: +This scope applies to everything except for the first line of the +captured node.
+
Every capture type has a default scope which should do the right thing
+in most situations. When a different scope is required, this can be
+changed by using a #set!
declaration anywhere in the pattern:
(assignment_expression
+ right: (_) @indent
+ (#set! "scope" "all"))
+
+Capture Types
+-
+
-
+
+@indent
(default scopetail
): +Increase the indent level by 1. Multiple occurences in the same line +don't stack. If there is at least one@indent
and one@outdent
+capture on the same line, the indent level isn't changed at all.
+ -
+
+@outdent
(default scopeall
): +Decrease the indent level by 1. The same rules as for@indent
apply.
+
Predicates
+In some cases, an S-expression cannot express exactly what pattern should be matched.
+For that, tree-sitter allows for predicates to appear anywhere within a pattern,
+similar to how #set!
declarations work:
(some_kind
+ (child_kind) @indent
+ (#predicate? arg1 arg2 ...)
+)
+
+The number of arguments depends on the predicate that's used.
+Each argument is either a capture (@name
) or a string ("some string"
).
+The following predicates are supported by tree-sitter:
-
+
-
+
+#eq?
/#not-eq?
: +The first argument (a capture) must/must not be equal to the second argument +(a capture or a string).
+ -
+
+#match?
/#not-match?
: +The first argument (a capture) must/must not match the regex given in the +second argument (a string).
+
Additionally, we support some custom predicates for indent queries:
+-
+
-
+
+#not-kind-eq?
: +The kind of the first argument (a capture) must not be equal to the second +argument (a string).
+ -
+
+#same-line?
/#not-same-line?
: +The captures given by the 2 arguments must/must not start on the same line.
+