on 89fcbb2 help sign in
bat/assets/syntaxes/Crystal.sublime-syntax
1036 lines 38 kB history raw
1%YAML 1.2
2---
3# http://www.sublimetext.com/docs/3/syntax.html
4name: Crystal
5comment: |
6 TODO: unresolved issues
8 text:
9 "p << end
10 print me!
11 end"
12 symptoms:
13 not recognized as a heredoc
14 solution:
15 there is no way to distinguish perfectly between the << operator and the start
16 of a heredoc. Currently, we require assignment to recognize a heredoc. More
17 refinement is possible.
18 • Heredocs with indented terminators (<<-) are always distinguishable, however.
19 • Nested heredocs are not really supportable at present
21 text:
22 print <<-'THERE'
23 This is single quoted.
24 The above used #{Time.now}
25 THERE
26 symtoms:
27 From Programming Ruby p306; should be a non-interpolated heredoc.
29 text:
30 "a\332a"
31 symptoms:
32 '\332' is not recognized as slash3.. which should be octal 332.
33 solution:
34 plain regexp.. should be easy.
36 text:
37 val?(a):p(b)
38 val?'a':'b'
39 symptoms:
40 ':p' is recognized as a symbol.. its 2 things ':' and 'p'.
41 :'b' has same problem.
42 solution:
43 ternary operator rule, precedence stuff, symbol rule.
44 but also consider 'a.b?(:c)' ??
45file_extensions:
46 - cr
47first_line_match: ^#!/.*\bcrystal
48scope: source.crystal
49contexts:
50 main:
51 - match: |-
52 (?x)
53 ^
54 \s*
55 (abstract)?
56 \s*
57 (class|struct|union)
58 \s+
59 (
60 (
61 [.A-Z_:\x{80}-\x{10FFFF}][.\w:\x{80}-\x{10FFFF}]*
62 (\(([,\s.a-zA-Z0-9_:\x{80}-\x{10FFFF}]+)\))?
63 (
64 \s*(<)\s*
65 [.:A-Z\x{80}-\x{10FFFF}][.:\w\x{80}-\x{10FFFF}]*
66 (\(([.a-zA-Z0-9_:]+\s,)\))?
67 )?
68 )|(
69 (<<)
70 \s*
71 [.A-Z0-9_:\x{80}-\x{10FFFF}]+
72 )
73 )
74 scope: meta.class.crystal
75 captures:
76 1: keyword.control.class.crystal
77 2: keyword.control.class.crystal
78 3: entity.name.type.class.crystal
79 5: punctuation.separator.crystal
80 6: support.class.other.type-param.crystal
81 7: entity.other.inherited-class.crystal
82 8: punctuation.separator.crystal
83 9: punctuation.separator.crystal
84 10: support.class.other.type-param.crystal
85 11: punctuation.definition.variable.crystal
86 - match: '^\s*(module)\s+(([A-Z\x{80}-\x{10FFFF}][\w\x{80}-\x{10FFFF}]*(::))?([A-Z\x{80}-\x{10FFFF}][\w\x{80}-\x{10FFFF}]*(::))?([A-Z\x{80}-\x{10FFFF}][\w\x{80}-\x{10FFFF}]*(::))*[A-Z\x{80}-\x{10FFFF}][\w\x{80}-\x{10FFFF}]*)'
87 scope: meta.module.crystal
88 captures:
89 1: keyword.control.module.crystal
90 2: entity.name.type.module.crystal
91 3: entity.other.inherited-class.module.first.crystal
92 4: punctuation.separator.inheritance.crystal
93 5: entity.other.inherited-class.module.second.crystal
94 6: punctuation.separator.inheritance.crystal
95 7: entity.other.inherited-class.module.third.crystal
96 8: punctuation.separator.inheritance.crystal
97 - match: '^\s*(lib)\s+(([A-Z]\w*(::))?([A-Z]\w*(::))?([A-Z]\w*(::))*[A-Z]\w*)'
98 scope: meta.lib.crystal
99 captures:
100 1: keyword.control.lib.crystal
101 2: entity.name.type.lib.crystal
102 3: entity.other.inherited-class.lib.first.crystal
103 4: punctuation.separator.inheritance.crystal
104 5: entity.other.inherited-class.lib.second.crystal
105 6: punctuation.separator.inheritance.crystal
106 7: entity.other.inherited-class.lib.third.crystal
107 8: punctuation.separator.inheritance.crystal
108 - match: (?<!\.)\belse(\s)+if\b
109 comment: else if is a common mistake carried over from other languages. it works if you put in a second end, but it’s never what you want.
110 scope: invalid.deprecated.crystal
111 - match: '(?<!\.)\b(BEGIN|alias|as|begin|case|select|abstract|class|END|ensure|for|fun|if|ifdef|in|lib|module|of|out|private|protected|rescue|struct|with|union|enum|macro|then|type|unless|until|while)\b(?![?!])'
112 comment: everything being a reserved word, not a value and needing a 'end' is a..
113 scope: keyword.control.primary.crystal
114 - match: '(?<!\.)\b(when|else|elsif)\b(?![?!])'
115 comment: everything being a reserved word, not a value and needing a 'end' is a..
116 scope: keyword.control.secondary.crystal
117 - match: '(?<!\.)\b(end)\b(?![?!])'
118 comment: Give the end keyword an additional scope
119 scope: keyword.control.secondary.end.crystal
120 - match: (?<!\.)\bdo\b\s*
121 comment: contextual smart pair support for block parameters
122 scope: keyword.control.start-block.crystal
123 - match: '(?<=\{)(\s+)'
124 comment: contextual smart pair support
125 scope: meta.syntax.crystal.start-block
126 - match: (?<!\.)\b(and|not|or)\b
127 comment: as above, just doesn't need a 'end' and does a logic operation
128 scope: keyword.operator.logical.crystal
129 - match: '(?<!\.)\b(alias|alias_method|break|next|pointerof|typeof|sizeof|instance_sizeof|return|super|yield|uninitialized|forall)\b(?![?!])'
130 comment: just as above but being not a logical operation
131 scope: keyword.control.pseudo-method.crystal
132 - match: '\b(nil|true|false)\b(?![?!])'
133 scope: constant.language.crystal
134 - match: '\b(__(DIR|FILE|LINE)__|self)\b(?![?!])'
135 scope: variable.language.crystal
136 - match: '\b(initialize|new|loop|include|extend|raise|getter|setter|property|class_getter|class_setter|class_property|describe|it|with|delegate|def_hash|def_equals|def_equals_and_hash|forward_missing_to|record|assert_responds_to|spawn)\b[!?]?'
137 comment: everything being a method but having a special function is a..
138 scope: keyword.control.special-method.crystal
139 - match: \b(require)\b
140 captures:
141 1: keyword.control.special-method.crystal
142 push:
143 - meta_scope: meta.require.crystal
144 - match: $|(?=#)
145 captures:
146 1: keyword.control.special-method.crystal
147 pop: true
148 - include: main
149 - match: '(@)[a-zA-Z_\x{80}-\x{10FFFF}][\w\x{80}-\x{10FFFF}]*[?!=]?'
150 scope: variable.other.readwrite.instance.crystal
151 captures:
152 1: punctuation.definition.variable.crystal
153 - match: '(@@)[a-zA-Z_\x{80}-\x{10FFFF}][\w\x{80}-\x{10FFFF}]*[?!=]?'
154 scope: variable.other.readwrite.class.crystal
155 captures:
156 1: punctuation.definition.variable.crystal
157 - match: '(\$)[a-zA-Z_]\w*'
158 scope: variable.other.readwrite.global.crystal
159 captures:
160 1: punctuation.definition.variable.crystal
161 - match: '(\$)(!|@|&|`|''|\+|\d+|~|=|/|\\|,|;|\.|<|>|_|\*|\$|\?|:|"|-[0adFiIlpv])'
162 scope: variable.other.readwrite.global.pre-defined.crystal
163 captures:
164 1: punctuation.definition.variable.crystal
165 - match: '\b(ENV)\['
166 captures:
167 1: variable.other.constant.crystal
168 push:
169 - meta_scope: meta.environment-variable.crystal
170 - match: '\]'
171 pop: true
172 - include: main
173 - match: '\b[A-Z\x{80}-\x{10FFFF}][\w\x{80}-\x{10FFFF}]*'
174 scope: support.class.crystal
175 - match: '\b[A-Z\x{80}-\x{10FFFF}][\w\x{80}-\x{10FFFF}]*\b'
176 scope: variable.other.constant.crystal
177 - match: |-
178 (?x)
179 (?=def\b) # an optimization to help Oniguruma fail fast
180 (?<=^|\s)(def)\s+ # the def keyword
181 ( (?>[a-zA-Z_\x{80}-\x{10FFFF}][\x{80}-\x{10FFFF}\w]*(?>\.|::))? # a method name prefix
182 (?>[a-zA-Z_\x{80}-\x{10FFFF}][\x{80}-\x{10FFFF}\w]*(?>[?!]|=(?!>))? # the method name
183 |===?|>[>=]?|<=>|<[<=]?|[%&`/\|]|\*\*?|=?~|[-+]@?|\[\]=?) ) # …or an operator method
184 \s*(\() # the openning parenthesis for arguments
185 comment: the method pattern comes from the symbol pattern, see there for a explaination
186 captures:
187 1: keyword.control.def.crystal
188 2: entity.name.function.crystal
189 3: punctuation.definition.parameters.crystal
190 push:
191 - meta_scope: meta.function.method.with-arguments.crystal
192 - meta_content_scope: variable.parameter.function.crystal
193 - match: \)\s*$|\)\s*:|\)\s*;
194 captures:
195 0: punctuation.definition.parameters.crystal
196 pop: true
197 - include: main
198 - match: |-
199 (?x)
200 (?=def\b) # an optimization to help Oniguruma fail fast
201 (?<=^|\s)(def)\s+ # the def keyword
202 ( (?>[a-zA-Z_\x{80}-\x{10FFFF}][\w\x{80}-\x{10FFFF}]*(?>\.|::))? # a method name prefix
203 (?>[a-zA-Z_\x{80}-\x{10FFFF}][\w\x{80}-\x{10FFFF}]*(?>[?!]|=(?!>))? # the method name
204 |===?|>[>=]?|<=>|<[<=]?|[%&`/\|]|\*\*?|=?~|[-+]@?|\[\]=?) ) # …or an operator method
205 [ \t] # the space separating the arguments
206 (?=[ \t]*[^\s#;]) # make sure arguments and not a comment follow
207 comment: same as the previous rule, but without parentheses around the arguments
208 captures:
209 1: keyword.control.def.crystal
210 2: entity.name.function.crystal
211 push:
212 - meta_scope: meta.function.method.with-arguments.crystal
213 - meta_content_scope: variable.parameter.function.crystal
214 - match: $
215 pop: true
216 - include: main
217 - match: |-
218 (?x)
219 (?=def\b) # an optimization to help Oniguruma fail fast
220 (?<=^|\s)(def)\b # the def keyword
221 ( \s+ # an optional group of whitespace followed by…
222 ( (?>[a-zA-Z_\x{80}-\x{10FFFF}][\w\x{80}-\x{10FFFF}]*(?>\.|::))? # a method name prefix
223 (?>[a-zA-Z_\x{80}-\x{10FFFF}][\w\x{80}-\x{10FFFF}]*(?>[?!]|=(?!>))? # the method name
224 |===?|>[>=]?|<=>|<[<=]?|[%&`/\|]|\*\*?|=?~|[-+]@?|\[\]=?) ) )? # …or an operator method
225 comment: the optional name is just to catch the def also without a method-name
226 scope: meta.function.method.without-arguments.crystal
227 captures:
228 1: keyword.control.def.crystal
229 3: entity.name.function.crystal
230 - match: '\b(0[xX]\h(?>_?\h)*|\d(?>_?\d)*(\.(?![^[:space:][:digit:]])(?>_?\d)*)?([eE][-+]?\d(?>_?\d)*)?|0[bB][01]+|0o[0-7]+)(_?(u8|u16|u32|u64|i8|i16|i32|i64|f32|f64))?\b'
231 scope: constant.numeric.crystal
232 - match: ":'"
233 captures:
234 0: punctuation.definition.constant.crystal
235 push:
236 - meta_scope: constant.other.symbol.single-quoted.crystal
237 - match: "'"
238 captures:
239 0: punctuation.definition.constant.crystal
240 pop: true
241 - match: '\\[''\\]'
242 scope: constant.character.escape.crystal
243 - match: ':"'
244 captures:
245 0: punctuation.definition.constant.crystal
246 push:
247 - meta_scope: constant.other.symbol.double-quoted.crystal
248 - match: '"'
249 captures:
250 0: punctuation.definition.constant.crystal
251 pop: true
252 - include: interpolated_crystal
253 - include: escaped_char
254 - match: /=
255 comment: Needs higher precidence than regular expressions.
256 scope: keyword.operator.assignment.augmented.crystal
257 - match: "'"
258 comment: single quoted string (does not allow interpolation)
259 captures:
260 0: punctuation.definition.string.begin.crystal
261 push:
262 - meta_scope: string.quoted.single.crystal
263 - match: "'"
264 captures:
265 0: punctuation.definition.string.end.crystal
266 pop: true
267 - match: \\'|\\\\
268 scope: constant.character.escape.crystal
269 - match: '"'
270 comment: double quoted string (allows for interpolation)
271 captures:
272 0: punctuation.definition.string.begin.crystal
273 push:
274 - meta_scope: string.quoted.double.crystal
275 - match: '"'
276 captures:
277 0: punctuation.definition.string.end.crystal
278 pop: true
279 - include: interpolated_crystal
280 - include: escaped_char
281 - match: "`"
282 comment: execute string (allows for interpolation)
283 captures:
284 0: punctuation.definition.string.begin.crystal
285 push:
286 - meta_scope: string.interpolated.crystal
287 - match: "`"
288 captures:
289 0: punctuation.definition.string.end.crystal
290 pop: true
291 - include: interpolated_crystal
292 - include: escaped_char
293 - match: '%x\{'
294 comment: execute string (allow for interpolation)
295 captures:
296 0: punctuation.definition.string.begin.crystal
297 push:
298 - meta_scope: string.interpolated.crystal
299 - match: '\}'
300 captures:
301 0: punctuation.definition.string.end.crystal
302 pop: true
303 - include: interpolated_crystal
304 - include: escaped_char
305 - include: nest_curly_i
306 - match: '%x\['
307 comment: execute string (allow for interpolation)
308 captures:
309 0: punctuation.definition.string.begin.crystal
310 push:
311 - meta_scope: string.interpolated.crystal
312 - match: '\]'
313 captures:
314 0: punctuation.definition.string.end.crystal
315 pop: true
316 - include: interpolated_crystal
317 - include: escaped_char
318 - include: nest_brackets_i
319 - match: '%x\<'
320 comment: execute string (allow for interpolation)
321 captures:
322 0: punctuation.definition.string.begin.crystal
323 push:
324 - meta_scope: string.interpolated.crystal
325 - match: \>
326 captures:
327 0: punctuation.definition.string.end.crystal
328 pop: true
329 - include: interpolated_crystal
330 - include: escaped_char
331 - include: nest_ltgt_i
332 - match: '%x\('
333 comment: execute string (allow for interpolation)
334 captures:
335 0: punctuation.definition.string.begin.crystal
336 push:
337 - meta_scope: string.interpolated.crystal
338 - match: \)
339 captures:
340 0: punctuation.definition.string.end.crystal
341 pop: true
342 - include: interpolated_crystal
343 - include: escaped_char
344 - include: nest_parens_i
345 - match: '%x([^\w])'
346 comment: execute string (allow for interpolation)
347 captures:
348 0: punctuation.definition.string.begin.crystal
349 push:
350 - meta_scope: string.interpolated.crystal
351 - match: \1
352 captures:
353 0: punctuation.definition.string.end.crystal
354 pop: true
355 - include: interpolated_crystal
356 - include: escaped_char
357 - match: |-
358 (?x)
359 (?:
360 ^ # beginning of line
361 | (?<= # or look-behind on:
362 [=>~(?:\[,|&;]
363 | [\s;]if\s # keywords
364 | [\s;]elsif\s
365 | [\s;]while\s
366 | [\s;]unless\s
367 | [\s;]when\s
368 | [\s;]assert_match\s
369 | [\s;]or\s # boolean opperators
370 | [\s;]and\s
371 | [\s;]not\s
372 | [\s.]index\s # methods
373 | [\s.]scan\s
374 | [\s.]sub\s
375 | [\s.]sub!\s
376 | [\s.]gsub\s
377 | [\s.]gsub!\s
378 | [\s.]match\s
379 )
380 | (?<= # or a look-behind with line anchor:
381 ^when\s # duplication necessary due to limits of regex
382 | ^if\s
383 | ^elsif\s
384 | ^while\s
385 | ^unless\s
386 )
387 )
388 \s*((/))(?![*+{}?])
389 comment: |
390 regular expressions (normal)
391 we only start a regexp if the character before it (excluding whitespace)
392 is what we think is before a regexp
393 captures:
394 1: string.regexp.classic.crystal
395 2: punctuation.definition.string.crystal
396 push:
397 - meta_content_scope: string.regexp.classic.crystal
398 - match: "((/[eimnosux]*))"
399 captures:
400 1: string.regexp.classic.crystal
401 2: punctuation.definition.string.crystal
402 pop: true
403 - include: regex_sub
404 - match: '%r\{'
405 comment: regular expressions (literal)
406 captures:
407 0: punctuation.definition.string.begin.crystal
408 push:
409 - meta_scope: string.regexp.mod-r.crystal
410 - match: '\}[eimnosux]*'
411 captures:
412 0: punctuation.definition.string.end.crystal
413 pop: true
414 - include: regex_sub
415 - include: nest_curly_r
416 - match: '%r\['
417 comment: regular expressions (literal)
418 captures:
419 0: punctuation.definition.string.begin.crystal
420 push:
421 - meta_scope: string.regexp.mod-r.crystal
422 - match: '\][eimnosux]*'
423 captures:
424 0: punctuation.definition.string.end.crystal
425 pop: true
426 - include: regex_sub
427 - include: nest_brackets_r
428 - match: '%r\('
429 comment: regular expressions (literal)
430 captures:
431 0: punctuation.definition.string.begin.crystal
432 push:
433 - meta_scope: string.regexp.mod-r.crystal
434 - match: '\)[eimnosux]*'
435 captures:
436 0: punctuation.definition.string.end.crystal
437 pop: true
438 - include: regex_sub
439 - include: nest_parens_r
440 - match: '%r\<'
441 comment: regular expressions (literal)
442 captures:
443 0: punctuation.definition.string.begin.crystal
444 push:
445 - meta_scope: string.regexp.mod-r.crystal
446 - match: '\>[eimnosux]*'
447 captures:
448 0: punctuation.definition.string.end.crystal
449 pop: true
450 - include: regex_sub
451 - include: nest_ltgt_r
452 - match: '%r([^\w])'
453 comment: regular expressions (literal)
454 captures:
455 0: punctuation.definition.string.begin.crystal
456 push:
457 - meta_scope: string.regexp.mod-r.crystal
458 - match: '\1[eimnosux]*'
459 captures:
460 0: punctuation.definition.string.end.crystal
461 pop: true
462 - include: regex_sub
463 - match: '%[QWSR]?\('
464 comment: literal capable of interpolation ()
465 captures:
466 0: punctuation.definition.string.begin.crystal
467 push:
468 - meta_scope: string.quoted.other.literal.upper.crystal
469 - match: \)
470 captures:
471 0: punctuation.definition.string.end.crystal
472 pop: true
473 - include: interpolated_crystal
474 - include: escaped_char
475 - include: nest_parens_i
476 - match: '%[QWSR]?\['
477 comment: "literal capable of interpolation []"
478 captures:
479 0: punctuation.definition.string.begin.crystal
480 push:
481 - meta_scope: string.quoted.other.literal.upper.crystal
482 - match: '\]'
483 captures:
484 0: punctuation.definition.string.end.crystal
485 pop: true
486 - include: interpolated_crystal
487 - include: escaped_char
488 - include: nest_brackets_i
489 - match: '%[QWSR]?\<'
490 comment: literal capable of interpolation <>
491 captures:
492 0: punctuation.definition.string.begin.crystal
493 push:
494 - meta_scope: string.quoted.other.literal.upper.crystal
495 - match: \>
496 captures:
497 0: punctuation.definition.string.end.crystal
498 pop: true
499 - include: interpolated_crystal
500 - include: escaped_char
501 - include: nest_ltgt_i
502 - match: '%[QWSR]?\{'
503 comment: "literal capable of interpolation -- {}"
504 captures:
505 0: punctuation.definition.string.begin.crystal
506 push:
507 - meta_scope: string.quoted.double.crystal.mod
508 - match: '\}'
509 captures:
510 0: punctuation.definition.string.end.crystal
511 pop: true
512 - include: interpolated_crystal
513 - include: escaped_char
514 - include: nest_curly_i
515 - match: '%[QWSR]([^\w])'
516 comment: literal capable of interpolation -- wildcard
517 captures:
518 0: punctuation.definition.string.begin.crystal
519 push:
520 - meta_scope: string.quoted.other.literal.upper.crystal
521 - match: \1
522 captures:
523 0: punctuation.definition.string.end.crystal
524 pop: true
525 - include: interpolated_crystal
526 - include: escaped_char
527 - match: '%[qws]\('
528 comment: literal incapable of interpolation -- ()
529 captures:
530 0: punctuation.definition.string.begin.crystal
531 push:
532 - meta_scope: string.quoted.other.literal.lower.crystal
533 - match: \)
534 captures:
535 0: punctuation.definition.string.end.crystal
536 pop: true
537 - match: \\\)|\\\\
538 scope: constant.character.escape.crystal
539 - include: nest_parens
540 - match: '%[qws]\<'
541 comment: literal incapable of interpolation -- <>
542 captures:
543 0: punctuation.definition.string.begin.crystal
544 push:
545 - meta_scope: string.quoted.other.literal.lower.crystal
546 - match: \>
547 captures:
548 0: punctuation.definition.string.end.crystal
549 pop: true
550 - match: \\\>|\\\\
551 scope: constant.character.escape.crystal
552 - include: nest_ltgt
553 - match: '%[qws]\['
554 comment: "literal incapable of interpolation -- []"
555 captures:
556 0: punctuation.definition.string.begin.crystal
557 push:
558 - meta_scope: string.quoted.other.literal.lower.crystal
559 - match: '\]'
560 captures:
561 0: punctuation.definition.string.end.crystal
562 pop: true
563 - match: '\\\]|\\\\'
564 scope: constant.character.escape.crystal
565 - include: nest_brackets
566 - match: '%[qws]\{'
567 comment: "literal incapable of interpolation -- {}"
568 captures:
569 0: punctuation.definition.string.begin.crystal
570 push:
571 - meta_scope: string.quoted.other.literal.lower.crystal
572 - match: '\}'
573 captures:
574 0: punctuation.definition.string.end.crystal
575 pop: true
576 - match: '\\\}|\\\\'
577 scope: constant.character.escape.crystal
578 - include: nest_curly
579 - match: '%[qws]([^\w])'
580 comment: literal incapable of interpolation -- wildcard
581 captures:
582 0: punctuation.definition.string.begin.crystal
583 push:
584 - meta_scope: string.quoted.other.literal.lower.crystal
585 - match: \1
586 captures:
587 0: punctuation.definition.string.end.crystal
588 pop: true
589 - match: \\.
590 comment: Cant be named because its not neccesarily an escape.
591 - match: '(?<!:)(:)(?>[a-zA-Z_\x{80}-\x{10FFFF}][\w\x{80}-\x{10FFFF}]*(?>[?!]|=(?![>=]))?|===?|>[>=]?|<[<=]?|<=>|[%&`/\|]|\*\*?|=?~|[-+]@?|\[\]=?|@@?[a-zA-Z_\x{80}-\x{10FFFF}][\w\x{80}-\x{10FFFF}]*)'
592 comment: symbols
593 scope: constant.other.symbol.crystal
594 captures:
595 1: punctuation.definition.constant.crystal
596 - match: '(?>[a-zA-Z_\x{80}-\x{10FFFF}][\w\x{80}-\x{10FFFF}]*(?>[?!])?)(:)(?!:)'
597 comment: symbols
598 scope: constant.other.symbol.crystal.19syntax
599 captures:
600 1: punctuation.definition.constant.crystal
601 - match: '(?:^[ \t]+)?(#).*$\n?'
602 scope: comment.line.number-sign.crystal
603 captures:
604 1: punctuation.definition.comment.crystal
605 - match: ^__END__\n
606 comment: __END__ marker
607 captures:
608 0: string.unquoted.program-block.crystal
609 push:
610 - meta_content_scope: text.plain
611 - match: (?=not)impossible
612 captures:
613 0: string.unquoted.program-block.crystal
614 pop: true
615 - match: (?=<?xml|<(?i:html\b)|!DOCTYPE (?i:html\b))
616 push:
617 - meta_scope: text.html.embedded.crystal
618 - match: (?=not)impossible
619 pop: true
620 - include: scope:text.html.basic
621 - match: '(?><<-("?)((?:[_\w]+_|)HTML)\b\1)'
622 comment: heredoc with embedded HTML and indented terminator
623 captures:
624 0: punctuation.definition.string.begin.crystal
625 push:
626 - meta_scope: string.unquoted.embedded.html.crystal
627 - meta_content_scope: text.html.embedded.crystal
628 - match: \s*\2$
629 captures:
630 0: punctuation.definition.string.end.crystal
631 pop: true
632 - include: heredoc
633 - include: scope:text.html.basic
634 - include: interpolated_crystal
635 - include: escaped_char
636 - match: '(?><<-("?)((?:[_\w]+_|)SQL)\b\1)'
637 comment: heredoc with embedded SQL and indented terminator
638 captures:
639 0: punctuation.definition.string.begin.crystal
640 push:
641 - meta_scope: string.unquoted.embedded.sql.crystal
642 - meta_content_scope: text.sql.embedded.crystal
643 - match: \s*\2$
644 captures:
645 0: punctuation.definition.string.end.crystal
646 pop: true
647 - include: heredoc
648 - include: scope:source.sql
649 - include: interpolated_crystal
650 - include: escaped_char
651 - match: '(?><<-("?)((?:[_\w]+_|)CSS)\b\1)'
652 comment: heredoc with embedded css and intented terminator
653 captures:
654 0: punctuation.definition.string.begin.crystal
655 push:
656 - meta_scope: string.unquoted.embedded.css.crystal
657 - meta_content_scope: text.css.embedded.crystal
658 - match: \s*\2$
659 captures:
660 0: punctuation.definition.string.end.crystal
661 pop: true
662 - include: heredoc
663 - include: scope:source.css
664 - include: interpolated_crystal
665 - include: escaped_char
666 - match: '(?><<-("?)((?:[_\w]+_|)CPP)\b\1)'
667 comment: heredoc with embedded c++ and intented terminator
668 captures:
669 0: punctuation.definition.string.begin.crystal
670 push:
671 - meta_scope: string.unquoted.embedded.cplusplus.crystal
672 - meta_content_scope: text.c++.embedded.crystal
673 - match: \s*\2$
674 captures:
675 0: punctuation.definition.string.end.crystal
676 pop: true
677 - include: heredoc
678 - include: scope:source.c++
679 - include: interpolated_crystal
680 - include: escaped_char
681 - match: '(?><<-("?)((?:[_\w]+_|)C)\b\1)'
682 comment: heredoc with embedded c++ and intented terminator
683 captures:
684 0: punctuation.definition.string.begin.crystal
685 push:
686 - meta_scope: string.unquoted.embedded.c.crystal
687 - meta_content_scope: text.c.embedded.crystal
688 - match: \s*\2$
689 captures:
690 0: punctuation.definition.string.end.crystal
691 pop: true
692 - include: heredoc
693 - include: scope:source.c
694 - include: interpolated_crystal
695 - include: escaped_char
696 - match: '(?><<-("?)((?:[_\w]+_|)(?:JS|JAVASCRIPT))\b\1)'
697 comment: heredoc with embedded javascript and intented terminator
698 captures:
699 0: punctuation.definition.string.begin.crystal
700 push:
701 - meta_scope: string.unquoted.embedded.js.crystal
702 - meta_content_scope: text.js.embedded.crystal
703 - match: \s*\2$
704 captures:
705 0: punctuation.definition.string.end.crystal
706 pop: true
707 - include: heredoc
708 - include: scope:source.js
709 - include: interpolated_crystal
710 - include: escaped_char
711 - match: '(?><<-("?)((?:[_\w]+_|)JQUERY)\b\1)'
712 comment: heredoc with embedded javascript and intented terminator
713 captures:
714 0: punctuation.definition.string.begin.crystal
715 push:
716 - meta_scope: string.unquoted.embedded.js.jquery.crystal
717 - meta_content_scope: text.js.jquery.embedded.crystal
718 - match: \s*\2$
719 captures:
720 0: punctuation.definition.string.end.crystal
721 pop: true
722 - include: heredoc
723 - include: scope:source.js.jquery
724 - include: interpolated_crystal
725 - include: escaped_char
726 - match: '(?><<-("?)((?:[_\w]+_|)(?:SH|SHELL))\b\1)'
727 comment: heredoc with embedded shell and intented terminator
728 captures:
729 0: punctuation.definition.string.begin.crystal
730 push:
731 - meta_scope: string.unquoted.embedded.shell.crystal
732 - meta_content_scope: text.shell.embedded.crystal
733 - match: \s*\2$
734 captures:
735 0: punctuation.definition.string.end.crystal
736 pop: true
737 - include: heredoc
738 - include: scope:source.shell
739 - include: interpolated_crystal
740 - include: escaped_char
741 - match: '(?><<-("?)((?:[_\w]+_|)RUBY)\b\1)'
742 comment: heredoc with embedded crystal and intented terminator
743 captures:
744 0: punctuation.definition.string.begin.crystal
745 push:
746 - meta_scope: string.unquoted.embedded.crystal.crystal
747 - meta_content_scope: text.crystal.embedded.crystal
748 - match: \s*\2$
749 captures:
750 0: punctuation.definition.string.end.crystal
751 pop: true
752 - include: heredoc
753 - include: scope:source.crystal
754 - include: interpolated_crystal
755 - include: escaped_char
756 - match: (?>\=\s*<<(\w+))
757 captures:
758 0: punctuation.definition.string.begin.crystal
759 push:
760 - meta_scope: string.unquoted.heredoc.crystal
761 - match: ^\1$
762 captures:
763 0: punctuation.definition.string.end.crystal
764 pop: true
765 - include: heredoc
766 - include: interpolated_crystal
767 - include: escaped_char
768 - match: (?><<-(\w+))
769 comment: heredoc with indented terminator
770 captures:
771 0: punctuation.definition.string.begin.crystal
772 push:
773 - meta_scope: string.unquoted.heredoc.crystal
774 - match: \s*\1$
775 captures:
776 0: punctuation.definition.string.end.crystal
777 pop: true
778 - include: heredoc
779 - include: interpolated_crystal
780 - include: escaped_char
781 - match: '(?<=\{|do|\{\s|do\s)(\|)'
782 captures:
783 1: punctuation.separator.variable.crystal
784 push:
785 - match: (\|)
786 captures:
787 1: punctuation.separator.variable.crystal
788 pop: true
789 - match: "[_a-zA-Z][_a-zA-Z0-9]*"
790 scope: variable.other.block.crystal
791 - match: ","
792 scope: punctuation.separator.variable.crystal
793 - match: "=>"
794 scope: punctuation.separator.key-value
795 - match: '<<=|%=|&=|\*=|\*\*=|\+=|\-=|\^=|\|{1,2}=|<<'
796 scope: keyword.operator.assignment.augmented.crystal
797 - match: '<=>|<(?!<|=)|>(?!<|=|>)|<=|>=|===|==|=~|!=|!~|(?<=[ \t])\?'
798 scope: keyword.operator.comparison.crystal
799 - match: '(?<=[ \t])!+|\bnot\b|&&|\band\b|\|\||\bor\b|\^'
800 scope: keyword.operator.logical.crystal
801 - match: '(\{\%|\%\}|\{\{|\}\})'
802 scope: keyword.operator.macro.crystal
803 - match: (%|&|\*\*|\*|\+|\-|/)
804 scope: keyword.operator.arithmetic.crystal
805 - match: "="
806 scope: keyword.operator.assignment.crystal
807 - match: \||~|>>
808 scope: keyword.operator.other.crystal
809 - match: ":"
810 scope: punctuation.separator.other.crystal
811 - match: \;
812 scope: punctuation.separator.statement.crystal
813 - match: ","
814 scope: punctuation.separator.object.crystal
815 - match: '\.|::'
816 scope: punctuation.separator.method.crystal
817 - match: '\{|\}'
818 scope: punctuation.section.scope.crystal
819 - match: '\[|\]'
820 scope: punctuation.section.array.crystal
821 - match: \(|\)
822 scope: punctuation.section.function.crystal
823 escaped_char:
824 - match: '\\(?:[0-7]{1,3}|x[\da-fA-F]{1,2}|.)'
825 scope: constant.character.escape.crystal
826 heredoc:
827 - match: ^<<-?\w+
828 push:
829 - match: $
830 pop: true
831 - include: main
832 interpolated_crystal:
833 - match: '#\{(\})'
834 scope: source.crystal.embedded.source
835 captures:
836 0: punctuation.section.embedded.crystal
837 1: source.crystal.embedded.source.empty
838 - match: '#\{'
839 captures:
840 0: punctuation.section.embedded.crystal
841 push:
842 - meta_scope: source.crystal.embedded.source
843 - match: '\}'
844 captures:
845 0: punctuation.section.embedded.crystal
846 pop: true
847 - include: nest_curly_and_self
848 - include: main
849 - match: '(#@)[a-zA-Z_]\w*'
850 scope: variable.other.readwrite.instance.crystal
851 captures:
852 1: punctuation.definition.variable.crystal
853 - match: '(#@@)[a-zA-Z_]\w*'
854 scope: variable.other.readwrite.class.crystal
855 captures:
856 1: punctuation.definition.variable.crystal
857 - match: '(#\$)[a-zA-Z_]\w*'
858 scope: variable.other.readwrite.global.crystal
859 captures:
860 1: punctuation.definition.variable.crystal
861 nest_brackets:
862 - match: '\['
863 captures:
864 0: punctuation.section.scope.crystal
865 push:
866 - match: '\]'
867 captures:
868 0: punctuation.section.scope.crystal
869 pop: true
870 - include: nest_brackets
871 nest_brackets_i:
872 - match: '\['
873 captures:
874 0: punctuation.section.scope.crystal
875 push:
876 - match: '\]'
877 captures:
878 0: punctuation.section.scope.crystal
879 pop: true
880 - include: interpolated_crystal
881 - include: escaped_char
882 - include: nest_brackets_i
883 nest_brackets_r:
884 - match: '\['
885 captures:
886 0: punctuation.section.scope.crystal
887 push:
888 - match: '\]'
889 captures:
890 0: punctuation.section.scope.crystal
891 pop: true
892 - include: regex_sub
893 - include: nest_brackets_r
894 nest_curly:
895 - match: '\{'
896 captures:
897 0: punctuation.section.scope.crystal
898 push:
899 - match: '\}'
900 captures:
901 0: punctuation.section.scope.crystal
902 pop: true
903 - include: nest_curly
904 nest_curly_and_self:
905 - match: '\{'
906 captures:
907 0: punctuation.section.scope.crystal
908 push:
909 - match: '\}'
910 captures:
911 0: punctuation.section.scope.crystal
912 pop: true
913 - include: nest_curly_and_self
914 - include: main
915 nest_curly_i:
916 - match: '\{'
917 captures:
918 0: punctuation.section.scope.crystal
919 push:
920 - match: '\}'
921 captures:
922 0: punctuation.section.scope.crystal
923 pop: true
924 - include: interpolated_crystal
925 - include: escaped_char
926 - include: nest_curly_i
927 nest_curly_r:
928 - match: '\{'
929 captures:
930 0: punctuation.section.scope.crystal
931 push:
932 - match: '\}'
933 captures:
934 0: punctuation.section.scope.crystal
935 pop: true
936 - include: regex_sub
937 - include: nest_curly_r
938 nest_ltgt:
939 - match: \<
940 captures:
941 0: punctuation.section.scope.crystal
942 push:
943 - match: \>
944 captures:
945 0: punctuation.section.scope.crystal
946 pop: true
947 - include: nest_ltgt
948 nest_ltgt_i:
949 - match: \<
950 captures:
951 0: punctuation.section.scope.crystal
952 push:
953 - match: \>
954 captures:
955 0: punctuation.section.scope.crystal
956 pop: true
957 - include: interpolated_crystal
958 - include: escaped_char
959 - include: nest_ltgt_i
960 nest_ltgt_r:
961 - match: \<
962 captures:
963 0: punctuation.section.scope.crystal
964 push:
965 - match: \>
966 captures:
967 0: punctuation.section.scope.crystal
968 pop: true
969 - include: regex_sub
970 - include: nest_ltgt_r
971 nest_parens:
972 - match: \(
973 captures:
974 0: punctuation.section.scope.crystal
975 push:
976 - match: \)
977 captures:
978 0: punctuation.section.scope.crystal
979 pop: true
980 - include: nest_parens
981 nest_parens_i:
982 - match: \(
983 captures:
984 0: punctuation.section.scope.crystal
985 push:
986 - match: \)
987 captures:
988 0: punctuation.section.scope.crystal
989 pop: true
990 - include: interpolated_crystal
991 - include: escaped_char
992 - include: nest_parens_i
993 nest_parens_r:
994 - match: \(
995 captures:
996 0: punctuation.section.scope.crystal
997 push:
998 - match: \)
999 captures:
1000 0: punctuation.section.scope.crystal
1001 pop: true
1002 - include: regex_sub
1003 - include: nest_parens_r
1004 regex_sub:
1005 - include: interpolated_crystal
1006 - include: escaped_char
1007 - match: '(\{)\d+(,\d+)?(\})'
1008 scope: string.regexp.arbitrary-repitition.crystal
1009 captures:
1010 1: punctuation.definition.arbitrary-repitition.crystal
1011 3: punctuation.definition.arbitrary-repitition.crystal
1012 - match: '\[(?:\^?\])?'
1013 captures:
1014 0: punctuation.definition.character-class.crystal
1015 push:
1016 - meta_scope: string.regexp.character-class.crystal
1017 - match: '\]'
1018 captures:
1019 0: punctuation.definition.character-class.crystal
1020 pop: true
1021 - include: escaped_char
1022 - match: \(
1023 captures:
1024 0: punctuation.definition.group.crystal
1025 push:
1026 - meta_scope: string.regexp.group.crystal
1027 - match: \)
1028 captures:
1029 0: punctuation.definition.group.crystal
1030 pop: true
1031 - include: regex_sub
1032 - match: '(?<=^|\s)(#)\s[[a-zA-Z0-9,. \t?!-][^\x{00}-\x{7F}]]*$'
1033 comment: We are restrictive in what we allow to go after the comment character to avoid false positives, since the availability of comments depend on regexp flags.
1034 scope: comment.line.number-sign.crystal
1035 captures:
1036 1: punctuation.definition.comment.crystal