1 package c
2
3 import (
4 . "github.com/alecthomas/chroma"
5 "github.com/alecthomas/chroma/lexers/internal"
6 )
7
8
9 var Crystal = internal.Register(MustNewLazyLexer(
10 &Config{
11 Name: "Crystal",
12 Aliases: []string{"cr", "crystal"},
13 Filenames: []string{"*.cr"},
14 MimeTypes: []string{"text/x-crystal"},
15 DotAll: true,
16 },
17 crystalRules,
18 ))
19
20 func crystalRules() Rules {
21 return Rules{
22 "root": {
23 {`#.*?$`, CommentSingle, nil},
24 {Words(``, `\b`, `abstract`, `asm`, `as`, `begin`, `break`, `case`, `do`, `else`, `elsif`, `end`, `ensure`, `extend`, `ifdef`, `if`, `include`, `instance_sizeof`, `next`, `of`, `pointerof`, `private`, `protected`, `rescue`, `return`, `require`, `sizeof`, `super`, `then`, `typeof`, `unless`, `until`, `when`, `while`, `with`, `yield`), Keyword, nil},
25 {Words(``, `\b`, `true`, `false`, `nil`), KeywordConstant, nil},
26 {`(module|lib)(\s+)([a-zA-Z_]\w*(?:::[a-zA-Z_]\w*)*)`, ByGroups(Keyword, Text, NameNamespace), nil},
27 {`(def|fun|macro)(\s+)((?:[a-zA-Z_]\w*::)*)`, ByGroups(Keyword, Text, NameNamespace), Push("funcname")},
28 {"def(?=[*%&^`~+-/\\[<>=])", Keyword, Push("funcname")},
29 {`(class|struct|union|type|alias|enum)(\s+)((?:[a-zA-Z_]\w*::)*)`, ByGroups(Keyword, Text, NameNamespace), Push("classname")},
30 {`(self|out|uninitialized)\b|(is_a|responds_to)\?`, KeywordPseudo, nil},
31 {Words(``, `\b`, `debugger`, `record`, `pp`, `assert_responds_to`, `spawn`, `parallel`, `getter`, `setter`, `property`, `delegate`, `def_hash`, `def_equals`, `def_equals_and_hash`, `forward_missing_to`), NameBuiltinPseudo, nil},
32 {`getter[!?]|property[!?]|__(DIR|FILE|LINE)__\b`, NameBuiltinPseudo, nil},
33 {Words(`(?<!\.)`, `\b`, `Object`, `Value`, `Struct`, `Reference`, `Proc`, `Class`, `Nil`, `Symbol`, `Enum`, `Void`, `Bool`, `Number`, `Int`, `Int8`, `Int16`, `Int32`, `Int64`, `UInt8`, `UInt16`, `UInt32`, `UInt64`, `Float`, `Float32`, `Float64`, `Char`, `String`, `Pointer`, `Slice`, `Range`, `Exception`, `Regex`, `Mutex`, `StaticArray`, `Array`, `Hash`, `Set`, `Tuple`, `Deque`, `Box`, `Process`, `File`, `Dir`, `Time`, `Channel`, `Concurrent`, `Scheduler`, `abort`, `at_exit`, `caller`, `delay`, `exit`, `fork`, `future`, `get_stack_top`, `gets`, `lazy`, `loop`, `main`, `p`, `print`, `printf`, `puts`, `raise`, `rand`, `read_line`, `sleep`, `sprintf`, `system`, `with_color`), NameBuiltin, nil},
34 {"(?<!\\w)(<<-?)([\"`\\']?)([a-zA-Z_]\\w*)(\\2)(.*?\\n)", StringHeredoc, nil},
35 {`(<<-?)("|\')()(\2)(.*?\n)`, StringHeredoc, nil},
36 {`__END__`, CommentPreproc, Push("end-part")},
37 {`(?:^|(?<=[=<>~!:])|(?<=(?:\s|;)when\s)|(?<=(?:\s|;)or\s)|(?<=(?:\s|;)and\s)|(?<=\.index\s)|(?<=\.scan\s)|(?<=\.sub\s)|(?<=\.sub!\s)|(?<=\.gsub\s)|(?<=\.gsub!\s)|(?<=\.match\s)|(?<=(?:\s|;)if\s)|(?<=(?:\s|;)elsif\s)|(?<=^when\s)|(?<=^index\s)|(?<=^scan\s)|(?<=^sub\s)|(?<=^gsub\s)|(?<=^sub!\s)|(?<=^gsub!\s)|(?<=^match\s)|(?<=^if\s)|(?<=^elsif\s))(\s*)(/)`, ByGroups(Text, LiteralStringRegex), Push("multiline-regex")},
38 {`(?<=\(|,|\[)/`, LiteralStringRegex, Push("multiline-regex")},
39 {`(\s+)(/)(?![\s=])`, ByGroups(Text, LiteralStringRegex), Push("multiline-regex")},
40 {`(0o[0-7]+(?:_[0-7]+)*(?:_?[iu][0-9]+)?)\b(\s*)([/?])?`, ByGroups(LiteralNumberOct, Text, Operator), nil},
41 {`(0x[0-9A-Fa-f]+(?:_[0-9A-Fa-f]+)*(?:_?[iu][0-9]+)?)\b(\s*)([/?])?`, ByGroups(LiteralNumberHex, Text, Operator), nil},
42 {`(0b[01]+(?:_[01]+)*(?:_?[iu][0-9]+)?)\b(\s*)([/?])?`, ByGroups(LiteralNumberBin, Text, Operator), nil},
43 {`((?:0(?![0-9])|[1-9][\d_]*)(?:\.\d[\d_]*)(?:e[+-]?[0-9]+)?(?:_?f[0-9]+)?)(\s*)([/?])?`, ByGroups(LiteralNumberFloat, Text, Operator), nil},
44 {`((?:0(?![0-9])|[1-9][\d_]*)(?:\.\d[\d_]*)?(?:e[+-]?[0-9]+)(?:_?f[0-9]+)?)(\s*)([/?])?`, ByGroups(LiteralNumberFloat, Text, Operator), nil},
45 {`((?:0(?![0-9])|[1-9][\d_]*)(?:\.\d[\d_]*)?(?:e[+-]?[0-9]+)?(?:_?f[0-9]+))(\s*)([/?])?`, ByGroups(LiteralNumberFloat, Text, Operator), nil},
46 {`(0\b|[1-9][\d]*(?:_\d+)*(?:_?[iu][0-9]+)?)\b(\s*)([/?])?`, ByGroups(LiteralNumberInteger, Text, Operator), nil},
47 {`@@[a-zA-Z_]\w*`, NameVariableClass, nil},
48 {`@[a-zA-Z_]\w*`, NameVariableInstance, nil},
49 {`\$\w+`, NameVariableGlobal, nil},
50 {"\\$[!@&`\\'+~=/\\\\,;.<>_*$?:\"^-]", NameVariableGlobal, nil},
51 {`\$-[0adFiIlpvw]`, NameVariableGlobal, nil},
52 {`::`, Operator, nil},
53 Include("strings"),
54 {`\?(\\[MC]-)*(\\([\\befnrtv#"\']|x[a-fA-F0-9]{1,2}|[0-7]{1,3})|\S)(?!\w)`, LiteralStringChar, nil},
55 {`[A-Z][A-Z_]+\b`, NameConstant, nil},
56 {`\{%`, LiteralStringInterpol, Push("in-macro-control")},
57 {`\{\{`, LiteralStringInterpol, Push("in-macro-expr")},
58 {`(@\[)(\s*)([A-Z]\w*)`, ByGroups(Operator, Text, NameDecorator), Push("in-attr")},
59 {Words(`(\.|::)`, ``, `!=`, `!~`, `!`, `%`, `&&`, `&`, `**`, `*`, `+`, `-`, `/`, `<=>`, `<<`, `<=`, `<`, `===`, `==`, `=~`, `=`, `>=`, `>>`, `>`, `[]=`, `[]?`, `[]`, `^`, `||`, `|`, `~`), ByGroups(Operator, NameOperator), nil},
60 {"(\\.|::)([a-zA-Z_]\\w*[!?]?|[*%&^`~+\\-/\\[<>=])", ByGroups(Operator, Name), nil},
61 {`[a-zA-Z_]\w*(?:[!?](?!=))?`, Name, nil},
62 {`(\[|\]\??|\*\*|<=>?|>=|<<?|>>?|=~|===|!~|&&?|\|\||\.{1,3})`, Operator, nil},
63 {`[-+/*%=<>&!^|~]=?`, Operator, nil},
64 {`[(){};,/?:\\]`, Punctuation, nil},
65 {`\s+`, Text, nil},
66 },
67 "funcname": {
68 {"(?:([a-zA-Z_]\\w*)(\\.))?([a-zA-Z_]\\w*[!?]?|\\*\\*?|[-+]@?|[/%&|^`~]|\\[\\]=?|<<|>>|<=?>|>=?|===?)", ByGroups(NameClass, Operator, NameFunction), Pop(1)},
69 Default(Pop(1)),
70 },
71 "classname": {
72 {`[A-Z_]\w*`, NameClass, nil},
73 {`(\()(\s*)([A-Z_]\w*)(\s*)(\))`, ByGroups(Punctuation, Text, NameClass, Text, Punctuation), nil},
74 Default(Pop(1)),
75 },
76 "in-intp": {
77 {`\{`, LiteralStringInterpol, Push()},
78 {`\}`, LiteralStringInterpol, Pop(1)},
79 Include("root"),
80 },
81 "string-intp": {
82 {`#\{`, LiteralStringInterpol, Push("in-intp")},
83 },
84 "string-escaped": {
85 {`\\([\\befnstv#"\']|x[a-fA-F0-9]{1,2}|[0-7]{1,3})`, LiteralStringEscape, nil},
86 },
87 "string-intp-escaped": {
88 Include("string-intp"),
89 Include("string-escaped"),
90 },
91 "interpolated-regex": {
92 Include("string-intp"),
93 {`[\\#]`, LiteralStringRegex, nil},
94 {`[^\\#]+`, LiteralStringRegex, nil},
95 },
96 "interpolated-string": {
97 Include("string-intp"),
98 {`[\\#]`, LiteralStringOther, nil},
99 {`[^\\#]+`, LiteralStringOther, nil},
100 },
101 "multiline-regex": {
102 Include("string-intp"),
103 {`\\\\`, LiteralStringRegex, nil},
104 {`\\/`, LiteralStringRegex, nil},
105 {`[\\#]`, LiteralStringRegex, nil},
106 {`[^\\/#]+`, LiteralStringRegex, nil},
107 {`/[imsx]*`, LiteralStringRegex, Pop(1)},
108 },
109 "end-part": {
110 {`.+`, CommentPreproc, Pop(1)},
111 },
112 "in-macro-control": {
113 {`\{%`, LiteralStringInterpol, Push()},
114 {`%\}`, LiteralStringInterpol, Pop(1)},
115 {`for\b|in\b`, Keyword, nil},
116 Include("root"),
117 },
118 "in-macro-expr": {
119 {`\{\{`, LiteralStringInterpol, Push()},
120 {`\}\}`, LiteralStringInterpol, Pop(1)},
121 Include("root"),
122 },
123 "in-attr": {
124 {`\[`, Operator, Push()},
125 {`\]`, Operator, Pop(1)},
126 Include("root"),
127 },
128 "strings": {
129 {`\:@{0,2}[a-zA-Z_]\w*[!?]?`, LiteralStringSymbol, nil},
130 {Words(`\:@{0,2}`, ``, `!=`, `!~`, `!`, `%`, `&&`, `&`, `**`, `*`, `+`, `-`, `/`, `<=>`, `<<`, `<=`, `<`, `===`, `==`, `=~`, `=`, `>=`, `>>`, `>`, `[]=`, `[]?`, `[]`, `^`, `||`, `|`, `~`), LiteralStringSymbol, nil},
131 {`:'(\\\\|\\'|[^'])*'`, LiteralStringSymbol, nil},
132 {`'(\\\\|\\'|[^']|\\[^'\\]+)'`, LiteralStringChar, nil},
133 {`:"`, LiteralStringSymbol, Push("simple-sym")},
134 {`([a-zA-Z_]\w*)(:)(?!:)`, ByGroups(LiteralStringSymbol, Punctuation), nil},
135 {`"`, LiteralStringDouble, Push("simple-string")},
136 {"(?<!\\.)`", LiteralStringBacktick, Push("simple-backtick")},
137 {`%\{`, LiteralStringOther, Push("cb-intp-string")},
138 {`%[wi]\{`, LiteralStringOther, Push("cb-string")},
139 {`%r\{`, LiteralStringRegex, Push("cb-regex")},
140 {`%\[`, LiteralStringOther, Push("sb-intp-string")},
141 {`%[wi]\[`, LiteralStringOther, Push("sb-string")},
142 {`%r\[`, LiteralStringRegex, Push("sb-regex")},
143 {`%\(`, LiteralStringOther, Push("pa-intp-string")},
144 {`%[wi]\(`, LiteralStringOther, Push("pa-string")},
145 {`%r\(`, LiteralStringRegex, Push("pa-regex")},
146 {`%<`, LiteralStringOther, Push("ab-intp-string")},
147 {`%[wi]<`, LiteralStringOther, Push("ab-string")},
148 {`%r<`, LiteralStringRegex, Push("ab-regex")},
149 {`(%r([\W_]))((?:\\\2|(?!\2).)*)(\2[imsx]*)`, String, nil},
150 {`(%[wi]([\W_]))((?:\\\2|(?!\2).)*)(\2)`, String, nil},
151 {`(?<=[-+/*%=<>&!^|~,(])(\s*)(%([\t ])(?:(?:\\\3|(?!\3).)*)\3)`, ByGroups(Text, LiteralStringOther, None), nil},
152 {`^(\s*)(%([\t ])(?:(?:\\\3|(?!\3).)*)\3)`, ByGroups(Text, LiteralStringOther, None), nil},
153 {`(%([\[{(<]))((?:\\\2|(?!\2).)*)(\2)`, String, nil},
154 },
155 "simple-string": {
156 Include("string-intp-escaped"),
157 {`[^\\"#]+`, LiteralStringDouble, nil},
158 {`[\\#]`, LiteralStringDouble, nil},
159 {`"`, LiteralStringDouble, Pop(1)},
160 },
161 "simple-sym": {
162 Include("string-escaped"),
163 {`[^\\"#]+`, LiteralStringSymbol, nil},
164 {`[\\#]`, LiteralStringSymbol, nil},
165 {`"`, LiteralStringSymbol, Pop(1)},
166 },
167 "simple-backtick": {
168 Include("string-intp-escaped"),
169 {"[^\\\\`#]+", LiteralStringBacktick, nil},
170 {`[\\#]`, LiteralStringBacktick, nil},
171 {"`", LiteralStringBacktick, Pop(1)},
172 },
173 "cb-intp-string": {
174 {`\\[\{]`, LiteralStringOther, nil},
175 {`\{`, LiteralStringOther, Push()},
176 {`\}`, LiteralStringOther, Pop(1)},
177 Include("string-intp-escaped"),
178 {`[\\#{}]`, LiteralStringOther, nil},
179 {`[^\\#{}]+`, LiteralStringOther, nil},
180 },
181 "cb-string": {
182 {`\\[\\{}]`, LiteralStringOther, nil},
183 {`\{`, LiteralStringOther, Push()},
184 {`\}`, LiteralStringOther, Pop(1)},
185 {`[\\#{}]`, LiteralStringOther, nil},
186 {`[^\\#{}]+`, LiteralStringOther, nil},
187 },
188 "cb-regex": {
189 {`\\[\\{}]`, LiteralStringRegex, nil},
190 {`\{`, LiteralStringRegex, Push()},
191 {`\}[imsx]*`, LiteralStringRegex, Pop(1)},
192 Include("string-intp"),
193 {`[\\#{}]`, LiteralStringRegex, nil},
194 {`[^\\#{}]+`, LiteralStringRegex, nil},
195 },
196 "sb-intp-string": {
197 {`\\[\[]`, LiteralStringOther, nil},
198 {`\[`, LiteralStringOther, Push()},
199 {`\]`, LiteralStringOther, Pop(1)},
200 Include("string-intp-escaped"),
201 {`[\\#\[\]]`, LiteralStringOther, nil},
202 {`[^\\#\[\]]+`, LiteralStringOther, nil},
203 },
204 "sb-string": {
205 {`\\[\\\[\]]`, LiteralStringOther, nil},
206 {`\[`, LiteralStringOther, Push()},
207 {`\]`, LiteralStringOther, Pop(1)},
208 {`[\\#\[\]]`, LiteralStringOther, nil},
209 {`[^\\#\[\]]+`, LiteralStringOther, nil},
210 },
211 "sb-regex": {
212 {`\\[\\\[\]]`, LiteralStringRegex, nil},
213 {`\[`, LiteralStringRegex, Push()},
214 {`\][imsx]*`, LiteralStringRegex, Pop(1)},
215 Include("string-intp"),
216 {`[\\#\[\]]`, LiteralStringRegex, nil},
217 {`[^\\#\[\]]+`, LiteralStringRegex, nil},
218 },
219 "pa-intp-string": {
220 {`\\[\(]`, LiteralStringOther, nil},
221 {`\(`, LiteralStringOther, Push()},
222 {`\)`, LiteralStringOther, Pop(1)},
223 Include("string-intp-escaped"),
224 {`[\\#()]`, LiteralStringOther, nil},
225 {`[^\\#()]+`, LiteralStringOther, nil},
226 },
227 "pa-string": {
228 {`\\[\\()]`, LiteralStringOther, nil},
229 {`\(`, LiteralStringOther, Push()},
230 {`\)`, LiteralStringOther, Pop(1)},
231 {`[\\#()]`, LiteralStringOther, nil},
232 {`[^\\#()]+`, LiteralStringOther, nil},
233 },
234 "pa-regex": {
235 {`\\[\\()]`, LiteralStringRegex, nil},
236 {`\(`, LiteralStringRegex, Push()},
237 {`\)[imsx]*`, LiteralStringRegex, Pop(1)},
238 Include("string-intp"),
239 {`[\\#()]`, LiteralStringRegex, nil},
240 {`[^\\#()]+`, LiteralStringRegex, nil},
241 },
242 "ab-intp-string": {
243 {`\\[<]`, LiteralStringOther, nil},
244 {`<`, LiteralStringOther, Push()},
245 {`>`, LiteralStringOther, Pop(1)},
246 Include("string-intp-escaped"),
247 {`[\\#<>]`, LiteralStringOther, nil},
248 {`[^\\#<>]+`, LiteralStringOther, nil},
249 },
250 "ab-string": {
251 {`\\[\\<>]`, LiteralStringOther, nil},
252 {`<`, LiteralStringOther, Push()},
253 {`>`, LiteralStringOther, Pop(1)},
254 {`[\\#<>]`, LiteralStringOther, nil},
255 {`[^\\#<>]+`, LiteralStringOther, nil},
256 },
257 "ab-regex": {
258 {`\\[\\<>]`, LiteralStringRegex, nil},
259 {`<`, LiteralStringRegex, Push()},
260 {`>[imsx]*`, LiteralStringRegex, Pop(1)},
261 Include("string-intp"),
262 {`[\\#<>]`, LiteralStringRegex, nil},
263 {`[^\\#<>]+`, LiteralStringRegex, nil},
264 },
265 }
266 }
267
View as plain text