1; The following code originates mostly from
2; https://github.com/elixir-lang/tree-sitter-elixir, with minor edits to
3; align the captures with helix. The following should be considered
4; Copyright 2021 The Elixir Team
5;
6; Licensed under the Apache License, Version 2.0 (the "License");
7; you may not use this file except in compliance with the License.
8; You may obtain a copy of the License at
9;
10;    https://www.apache.org/licenses/LICENSE-2.0
11;
12; Unless required by applicable law or agreed to in writing, software
13; distributed under the License is distributed on an "AS IS" BASIS,
14; WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15; See the License for the specific language governing permissions and
16; limitations under the License.
17
18; Reserved keywords
19
20["when" "and" "or" "not" "in" "not in" "fn" "do" "end" "catch" "rescue" "after" "else"] @keyword
21
22; Operators
23
24; * doc string
25(unary_operator
26  operator: "@" @comment.block.documentation
27  operand: (call
28    target: (identifier) @comment.block.documentation.__attribute__
29    (arguments
30      [
31        (string) @comment.block.documentation
32        (charlist) @comment.block.documentation
33        (sigil
34          quoted_start: _ @comment.block.documentation
35          quoted_end: _ @comment.block.documentation) @comment.block.documentation
36        (boolean) @comment.block.documentation
37      ]))
38  (#match? @comment.block.documentation.__attribute__ "^(moduledoc|typedoc|doc)$"))
39
40; * module attribute
41(unary_operator
42  operator: "@" @variable.property
43  operand: [
44    (identifier) @variable.property
45    (call
46      target: (identifier) @variable.property)
47    (boolean) @variable.property
48    (nil) @variable.property
49  ])
50
51; * capture operator
52(unary_operator
53  operator: "&"
54  operand: [
55    (integer) @operator
56    (binary_operator
57      left: [
58        (call target: (dot left: (_) right: (identifier) @function))
59        (identifier) @function
60      ] operator: "/" right: (integer) @operator)
61  ])
62
63(operator_identifier) @operator
64
65(unary_operator
66  operator: _ @operator)
67
68(binary_operator
69  operator: _ @operator)
70
71(dot
72  operator: _ @operator)
73
74(stab_clause
75  operator: _ @operator)
76
77; Literals
78
79(nil) @constant.builtin
80
81(boolean) @constant.builtin.boolean
82
83[
84  (integer)
85  (float)
86] @number
87
88(alias) @type
89
90(call
91  target: (dot
92    left: (atom) @type))
93
94(char) @constant.character
95
96; Quoted content
97
98(interpolation "#{" @punctuation.special "}" @punctuation.special) @embedded
99
100(escape_sequence) @escape
101
102[
103  (atom)
104  (quoted_atom)
105  (keyword)
106  (quoted_keyword)
107] @string.special.symbol
108
109[
110  (string)
111  (charlist)
112] @string
113
114; Note that we explicitly target sigil quoted start/end, so they are not overridden by delimiters
115
116(sigil
117  (sigil_name) @__name__
118  quoted_start: _ @string
119  quoted_end: _ @string
120  (#match? @__name__ "^[sS]$")) @string
121
122(sigil
123  (sigil_name) @__name__
124  quoted_start: _ @string.regexp
125  quoted_end: _ @string.regexp
126  (#match? @__name__ "^[rR]$")) @string.regexp
127
128(sigil
129  (sigil_name) @__name__
130  quoted_start: _ @string.special
131  quoted_end: _ @string.special) @string.special
132
133; Calls
134
135; * definition keyword
136(call
137  target: (identifier) @keyword
138  (#match? @keyword "^(def|defdelegate|defexception|defguard|defguardp|defimpl|defmacro|defmacrop|defmodule|defn|defnp|defoverridable|defp|defprotocol|defstruct)$"))
139
140; * kernel or special forms keyword
141(call
142  target: (identifier) @keyword
143  (#match? @keyword "^(alias|case|cond|else|for|if|import|quote|raise|receive|require|reraise|super|throw|try|unless|unquote|unquote_splicing|use|with)$"))
144
145; * function call
146(call
147  target: [
148    ; local
149    (identifier) @function
150    ; remote
151    (dot
152      right: (identifier) @function)
153  ])
154
155; * just identifier in function definition
156(call
157  target: (identifier) @keyword
158  (arguments
159    [
160      (identifier) @function
161      (binary_operator
162        left: (identifier) @function
163        operator: "when")
164    ])
165  (#match? @keyword "^(def|defdelegate|defguard|defguardp|defmacro|defmacrop|defn|defnp|defp)$"))
166
167; * pipe into identifier (definition)
168(call
169  target: (identifier) @keyword
170  (arguments
171    (binary_operator
172      operator: "|>"
173      right: (identifier) @variable))
174  (#match? @keyword "^(def|defdelegate|defguard|defguardp|defmacro|defmacrop|defn|defnp|defp)$"))
175
176; * pipe into identifier (function call)
177(binary_operator
178  operator: "|>"
179  right: (identifier) @function)
180
181; Identifiers
182
183; * special
184(
185  (identifier) @constant.builtin
186  (#match? @constant.builtin "^(__MODULE__|__DIR__|__ENV__|__CALLER__|__STACKTRACE__)$")
187)
188
189; * unused
190(
191  (identifier) @comment
192  (#match? @comment "^_")
193)
194
195; * regular
196(identifier) @variable
197
198; Comment
199
200(comment) @comment
201
202; Punctuation
203
204[
205 "%"
206] @punctuation
207
208[
209 ","
210 ";"
211] @punctuation.delimiter
212
213[
214  "("
215  ")"
216  "["
217  "]"
218  "{"
219  "}"
220  "<<"
221  ">>"
222] @punctuation.bracket
223
224(ERROR) @warning
225