aboutsummaryrefslogtreecommitdiff
path: root/book/src/guides
diff options
context:
space:
mode:
authorTriton1712022-03-30 15:08:07 +0000
committerGitHub2022-03-30 15:08:07 +0000
commit58758fee610a3808dfaeafddd1b4b4242a7e42cd (patch)
tree1ca1bc05978270080693c56d6cfb3beb6dd86e1a /book/src/guides
parentc18de0e8f001041e234b2b9bb0f8fea122858ad3 (diff)
Indentation rework (#1562)
* WIP: Rework indentation system * Add ComplexNode for context-aware indentation (including a proof of concept for assignment statements in rust) * Add switch statements to Go indents.toml (fixes the second half of issue #1523) Remove commented-out code * Migrate all existing indentation queries. Add more options to ComplexNode and use them to improve C/C++ indentation. * Add comments & replace Option<Vec<_>> with Vec<_> * Add more detailed documentation for tree-sitter indentation * Improve code style in indent.rs * Use tree-sitter queries for indentation instead of TOML config. Migrate existing indent queries. * Add documentation for the new indent queries. Change xtask docgen to look for indents.scm instead of indents.toml * Improve code style in indent.rs. Fix an issue with the rust indent query. * Move indentation test sources to separate files. Add `#not-kind-eq?`, `#same-line?` and `#not-same-line` custom predicates. Improve the rust and c indent queries. * Fix indent test. Improve rust indent queries. * Move indentation tests to integration test folder. * Improve code style in indent.rs. Reuse tree-sitter cursors for indentation queries. * Migrate HCL indent query * Replace custom loading in indent tests with a designated languages.toml * Update indent query file name for --health command. * Fix single-space formatting in indent queries. * Add explanation for unwrapping. Co-authored-by: Triton171 <triton0171@gmail.com>
Diffstat (limited to 'book/src/guides')
-rw-r--r--book/src/guides/indent.md79
1 files changed, 79 insertions, 0 deletions
diff --git a/book/src/guides/indent.md b/book/src/guides/indent.md
new file mode 100644
index 00000000..235a30c4
--- /dev/null
+++ b/book/src/guides/indent.md
@@ -0,0 +1,79 @@
+# 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:
+```scm
+(assignment_expression
+ right: (_) @indent
+ (#set! "scope" "all"))
+```
+
+## Capture Types
+
+- `@indent` (default scope `tail`):
+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 scope `all`):
+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:
+```scm
+(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.