summaryrefslogtreecommitdiff
path: root/runtime/queries/rust/indents.scm
blob: af2e05e3b4e1917e879ec46faee1013b9cc3a82c (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
[
  (use_list)
  (block)
  (match_block)
  (arguments)
  (parameters)
  (declaration_list)
  (field_declaration_list)
  (field_initializer_list)
  (struct_pattern)
  (tuple_pattern)
  (unit_expression)
  (enum_variant_list)
  (call_expression)
  (binary_expression)
  (field_expression)
  (await_expression)
  (tuple_expression)
  (array_expression)
  (where_clause)
  (type_cast_expression)

  (token_tree)
  (macro_definition)
  (token_tree_pattern)
  (token_repetition)
] @indent

[
  "}"
  "]"
  ")"
] @outdent

; Indent the right side of assignments.
; The #not-same-line? predicate is required to prevent an extra indent for e.g.
; an else-clause where the previous if-clause starts on the same line as the assignment.
(assignment_expression
  .
  (_) @expr-start
  right: (_) @indent
  (#not-same-line? @indent @expr-start)
  (#set! "scope" "all")
)
(compound_assignment_expr
  .
  (_) @expr-start
  right: (_) @indent
  (#not-same-line? @indent @expr-start)
  (#set! "scope" "all")
)
(let_declaration
  "let" @expr-start
  value: (_) @indent
  alternative: (_)? @indent
  (#not-same-line? @indent @expr-start)
  (#set! "scope" "all")
)
(let_condition
  .
  (_) @expr-start
  value: (_) @indent
  (#not-same-line? @indent @expr-start)
  (#set! "scope" "all")
)
(if_expression
  .
  (_) @expr-start
  condition: (_) @indent
  (#not-same-line? @indent @expr-start)
  (#set! "scope" "all")
)
(static_item
  .
  (_) @expr-start
  value: (_) @indent
  (#not-same-line? @indent @expr-start)
  (#set! "scope" "all")
)
(field_pattern
  .
  (_) @expr-start
  pattern: (_) @indent
  (#not-same-line? @indent @expr-start)
  (#set! "scope" "all")
)
; Indent type aliases that span multiple lines, similar to
; regular assignment expressions
(type_item
  .
  (_) @expr-start
  type: (_) @indent
  (#not-same-line? @indent @expr-start)
  (#set! "scope" "all")
)

; Some field expressions where the left part is a multiline expression are not
; indented by cargo fmt.
; Because this multiline expression might be nested in an arbitrary number of
; field expressions, this can only be matched using a Regex.
(field_expression
  value: (_) @val
  "." @outdent
  ; Check whether the first line ends with `(`, `{` or `[` (up to whitespace).
  (#match? @val "(\\A[^\\n\\r]+(\\(|\\{|\\[)[\\t ]*(\\n|\\r))")
)
; Same as above, but with an additional `call_expression`. This is required since otherwise
; the arguments of the function call won't be outdented.
(call_expression
  function: (field_expression
    value: (_) @val
    "." @outdent
    (#match? @val "(\\A[^\\n\\r]+(\\(|\\{|\\[)[\\t ]*(\\n|\\r))")
  )
  arguments: (_) @outdent
)


; Indent if guards in patterns.
; Since the tree-sitter grammar doesn't create a node for the if expression,
; it's not possible to do this correctly in all cases. Indenting the tail of the
; whole pattern whenever it contains an `if` only fails if the `if` appears after
; the second line of the pattern (which should only rarely be the case)
(match_pattern
  .
  (_) @expr-start
  "if" @pattern-guard
  (#not-same-line? @expr-start @pattern-guard)
) @indent

; Align closure parameters if they span more than one line
(closure_parameters
  "|"
  .
  (_) @anchor
  (_) @expr-end
  .
  (#not-same-line? @anchor @expr-end)
) @align

(for_expression
  "in" @in
  .
  (_) @indent
  (#not-same-line? @in @indent)
  (#set! "scope" "all")
)