Last active
February 19, 2022 21:49
-
-
Save existentialmutt/d27cc43cfeb6f98c1dde846e4e36c63b to your computer and use it in GitHub Desktop.
Enhancing Sublime Ruby syntax highlighting with ERB and HAML embedded in heredocs
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
%YAML 1.2 | |
--- | |
name: Ruby (Custom) | |
# TODO: unresolved issues | |
# | |
# text: | |
# "p << end | |
# print me! | |
# end" | |
# symptoms: | |
# not recognized as a heredoc | |
# solution: | |
# there is no way to distinguish perfectly between the << operator and the start | |
# of a heredoc. Currently, we require assignment to recognize a heredoc. More | |
# refinement is possible. | |
# • Heredocs with indented terminators (<<-) are always distinguishable, however. | |
# • Nested heredocs are not really supportable at present | |
# | |
# text: | |
# print <<-'THERE' | |
# This is single quoted. | |
# The above used #{Time.now} | |
# THERE | |
# symtoms: | |
# From Programming Ruby p306; should be a non-interpolated heredoc. | |
# | |
# text: | |
# "a\332a" | |
# symptoms: | |
# '\332' is not recognized as slash3.. which should be octal 332. | |
# solution: | |
# plain regexp.. should be easy. | |
# | |
# text: | |
# val?(a):p(b) | |
# val?'a':'b' | |
# symptoms: | |
# ':p' is recognized as a symbol.. its 2 things ':' and 'p'. | |
# :'b' has same problem. | |
# solution: | |
# ternary operator rule, precedence stuff, symbol rule. | |
# but also consider 'a.b?(:c)' ?? | |
file_extensions: | |
- rb | |
- Appfile | |
- Appraisals | |
- Berksfile | |
- Brewfile | |
- capfile | |
- cgi | |
- Cheffile | |
- config.ru | |
- Deliverfile | |
- Fastfile | |
- fcgi | |
- Gemfile | |
- gemspec | |
- Guardfile | |
- irbrc | |
- jbuilder | |
- Podfile | |
- podspec | |
- prawn | |
- rabl | |
- rake | |
- Rakefile | |
- Rantfile | |
- rbx | |
- rjs | |
- ruby.rail | |
- Scanfile | |
- simplecov | |
- Snapfile | |
- thor | |
- Thorfile | |
- Vagrantfile | |
first_line_match: ^#!\s*/.*\bj?ruby\b | |
scope: source.ruby.custom | |
variables: | |
identifier: '\b[[:alpha:]_][[:alnum:]_]*\b' | |
method_punctuation: '(?:[?!]|=(?![>=]))?' | |
method_name: '{{identifier}}{{method_punctuation}}' | |
path_lookahead: '(::)?({{identifier}}(\.|::))*{{identifier}}' | |
contexts: | |
main: | |
- include: expressions | |
expressions: | |
- include: class | |
- include: module | |
- include: constants | |
- include: invalid | |
- include: blocks | |
- include: keywords | |
- include: well-known-methods | |
- include: variables | |
- include: method | |
- include: strings | |
- include: comments | |
- include: data-section | |
- include: heredocs | |
- include: operators | |
- include: identifiers-accessors | |
comments: | |
# multiline comments | |
- match: ^=begin | |
scope: punctuation.definition.comment.ruby | |
push: | |
- meta_scope: comment.block.documentation.ruby | |
- match: ^=end | |
scope: punctuation.definition.comment.ruby | |
pop: true | |
- match: '(#).*$\n?' | |
scope: comment.line.number-sign.ruby | |
captures: | |
1: punctuation.definition.comment.ruby | |
class: | |
# Defining a class method | |
- match: \b(class)\b(?=\s*<) | |
scope: keyword.control.class.ruby | |
- match: '\b(class)\b' | |
scope: meta.class.ruby keyword.control.class.ruby | |
push: class-declaration | |
class-declaration: | |
- meta_content_scope: meta.class.ruby | |
- match: '(?={{path_lookahead}})' | |
set: class-name | |
# Escape if no valid match | |
- match: (?=\S) | |
pop: true | |
class-name: | |
- meta_content_scope: meta.class.ruby entity.name.class.ruby | |
- include: name-parts | |
- match: '' | |
set: class-inheritance | |
class-inheritance: | |
- meta_content_scope: meta.class.ruby | |
- match: '<' | |
scope: punctuation.separator.inheritance.ruby | |
set: | |
- meta_content_scope: meta.class.ruby | |
- match: '(?={{path_lookahead}})' | |
set: | |
- meta_content_scope: meta.class.ruby entity.other.inherited-class.ruby | |
- include: name-parts | |
- match: '' | |
pop: true | |
# Escape if no valid match | |
- match: '(?=\S)' | |
pop: true | |
# Escape if no valid match | |
- match: '(?=\S)' | |
pop: true | |
module: | |
- match: \b(module)\b | |
scope: meta.module.ruby keyword.control.module.ruby | |
push: module-declaration | |
module-declaration: | |
- meta_content_scope: meta.module.ruby | |
- match: '(?=(::)?({{identifier}}::)*{{identifier}})' | |
set: | |
- meta_content_scope: meta.module.ruby entity.name.module.ruby | |
- include: name-parts | |
- match: '' | |
pop: true | |
# Escape if no valid match | |
- match: (?=\S) | |
pop: true | |
name-parts: | |
- match: '::' | |
scope: punctuation.accessor.ruby | |
- match: '\.' | |
scope: punctuation.accessor.ruby | |
- match: '({{identifier}})(::|\.)' | |
captures: | |
1: support.other.namespace.ruby | |
2: punctuation.accessor.ruby | |
- match: '{{identifier}}' | |
invalid: | |
# 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. | |
- match: \belse\s+if\b | |
scope: invalid.deprecated.ruby | |
constants: | |
# constant definition, handles multiple definitions on a single line 'APPLE, ORANGE= 1, 2' | |
- match: '\b([[:upper:]]\w*)(?=(\s*,\s*[[:upper:]]\w*)*\s*=(?![=\>]))' | |
scope: meta.constant.ruby entity.name.constant.ruby | |
# Ruby 1.9 symbols | |
- match: '{{identifier}}[?!]?(:)(?!:)' | |
scope: constant.other.symbol.ruby | |
captures: | |
1: punctuation.definition.constant.ruby | |
push: try-regex | |
- match: '\b(nil|true|false)\b(?![?!])' | |
scope: constant.language.ruby | |
- match: '\b(__(FILE|LINE|ENCODING)__|self)\b(?![?!])' | |
scope: variable.language.ruby | |
- match: '\b(0[xX]\h(_?\h)*|\d(_?\d)*(\.(?![^[:space:][:digit:]])(_?\d)*)?([eE][-+]?\d(_?\d)*)?|0[bB][01]+)\b' | |
scope: constant.numeric.ruby | |
- match: ":'" | |
scope: punctuation.definition.constant.ruby | |
push: | |
- meta_scope: constant.other.symbol.single-quoted.ruby | |
- match: "'" | |
scope: punctuation.definition.constant.ruby | |
pop: true | |
- match: '\\[''\\]' | |
scope: constant.character.escape.ruby | |
- match: ':"' | |
scope: punctuation.definition.constant.ruby | |
push: | |
- meta_scope: constant.other.symbol.double-quoted.ruby | |
- match: '"' | |
scope: punctuation.definition.constant.ruby | |
pop: true | |
- include: interpolated-ruby | |
- include: escaped-char | |
# Unquoted symbols | |
- match: |- | |
(?x: | |
(:) | |
( | |
{{identifier}}{{method_punctuation}}| | |
===?| | |
>[>=]?| | |
<[<=]?| | |
<=>| | |
[%&`/\|]| | |
\*\*?| | |
=?~| | |
[-+]@?| | |
\[\]=?| | |
@@?{{identifier}} | |
) | |
) | |
scope: constant.other.symbol.ruby | |
captures: | |
1: punctuation.definition.constant.ruby | |
# matches questionmark-letters. | |
# | |
# examples (1st alternation = hex): | |
# ?\x1 ?\x61 | |
# | |
# examples (2nd alternation = octal): | |
# ?\0 ?\07 ?\017 | |
# | |
# examples (3rd alternation = escaped): | |
# ?\n ?\b | |
# | |
# examples (4th alternation = meta-ctrl): | |
# ?\C-a ?\M-a ?\C-\M-\C-\M-a | |
# | |
# examples (4th alternation = normal): | |
# ?a ?A ?0 | |
# ?* ?" ?( | |
# ?. ?# | |
# | |
# the negative lookbehind prevents against matching | |
# p(42.tainted?) | |
- match: '\?(\\(x\h{1,2}\b|0[0-7]{0,2}\b|[^x0MC]\b)|(\\[MC]-)+\w\b|[a-zA-Z0-9_]\b(?!\s*:)|[^a-zA-Z0-9_\s\\])' | |
scope: constant.numeric.ruby | |
blocks: | |
- match: \b(do)\b\s* | |
captures: | |
1: keyword.control.start-block.ruby | |
push: maybe-block-parameters | |
- match: \{ | |
scope: punctuation.section.scope.ruby | |
push: maybe-block-parameters | |
maybe-block-parameters: | |
- match: \| | |
scope: meta.block.parameters.ruby punctuation.definition.parameters.begin.ruby | |
set: block-parameters | |
- match: (?=\s*[^\s\|]) | |
pop: true | |
block-parameters: | |
- meta_content_scope: meta.block.parameters.ruby | |
- match: \| | |
scope: meta.block.parameters.ruby punctuation.definition.parameters.end.ruby | |
set: try-regex | |
- match: '{{identifier}}' | |
scope: variable.parameter.ruby | |
- match: ',' | |
scope: punctuation.separator.ruby | |
- match: \* | |
scope: keyword.operator.splat.ruby | |
- match: '&' | |
scope: keyword.operator.ruby | |
- match: '(?==)' | |
set: | |
- meta_content_scope: meta.block.parameters.default-value.ruby | |
- match: '=' | |
scope: keyword.operator.assignment.ruby | |
set: | |
- meta_content_scope: meta.block.parameters.default-value.ruby | |
- match: '(?=[,\|])' | |
set: block-parameters | |
- include: nest-all | |
- include: expressions | |
keywords: | |
- match: '\b(BEGIN|END)\b(?![?!])' | |
scope: keyword.control.ruby | |
- match: '\b(class|module)\b(?![?!])' | |
scope: keyword.control.ruby | |
- match: '\b(begin|end|ensure|rescue)\b(?![?!])' | |
scope: keyword.control.ruby | |
- match: '\b(case|else|ensure|for|in|then)\b(?![?!])' | |
scope: keyword.control.ruby | |
- match: '\b(elsif|if|unless|when|while|until)\b(?![?!])' | |
scope: keyword.control.ruby | |
push: after-keyword | |
- match: \b(and|not|or)\b | |
scope: keyword.operator.logical.ruby | |
push: after-keyword | |
- match: '!+|&&|\|\||\^' | |
scope: keyword.operator.logical.ruby | |
push: after-operator | |
- match: '\b(alias|alias_method|break|next|redo|retry|return|super|undef|yield)\b(?![?!])|\bdefined\?|\bblock_given\?' | |
scope: keyword.control.pseudo-method.ruby | |
operators: | |
- match: '=>' | |
scope: punctuation.separator.key-value.ruby | |
push: after-operator | |
- match: '<<=|%=|&=|\*=|\*\*=|\+=|\-=|\^=|\|{1,2}=|<<' | |
scope: keyword.operator.assignment.augmented.ruby | |
push: after-operator | |
- match: '<=>|<(?!<|=)|>(?!<|=|>)|<=|>=|===|==|=~|!=|!~' | |
scope: keyword.operator.comparison.ruby | |
push: after-operator | |
- match: (%|&|\*\*|\*|\+|\-|/) | |
scope: keyword.operator.arithmetic.ruby | |
push: after-operator | |
- match: '=' | |
scope: keyword.operator.assignment.ruby | |
push: after-operator | |
- match: \||~|>> | |
scope: keyword.operator.other.ruby | |
push: after-operator | |
- match: \? | |
scope: keyword.operator.conditional.ruby | |
push: | |
# Handle hash-key-lookalike of identifier: in ternary | |
- match: '\s*{{identifier}}(:)(?!:)' | |
captures: | |
1: keyword.operator.conditional.ruby | |
- include: after-operator | |
- match: ':(?!:)' | |
scope: keyword.operator.conditional.ruby | |
push: after-operator | |
- match: \; | |
scope: punctuation.terminator.statement.ruby | |
push: after-operator | |
- match: "," | |
scope: punctuation.separator.ruby | |
push: after-operator | |
- match: '\[' | |
scope: punctuation.section.array.ruby | |
push: after-operator | |
- match: \( | |
scope: punctuation.definition.group.begin.ruby | |
push: after-operator | |
# Opening { is handled by "block" context to try and detect parameters | |
- match: '\}' | |
scope: punctuation.section.scope.ruby | |
- match: '\]' | |
scope: punctuation.section.array.ruby | |
- match: \) | |
scope: punctuation.definition.group.end.ruby | |
- match: '\.\.\.?' | |
scope: keyword.operator.ruby | |
push: after-operator | |
identifiers-accessors: | |
# This consumes class/module access to prevent issues parsing : as part | |
# of a ternary operator | |
- match: '(::)(?={{identifier}}{{method_punctuation}})' | |
scope: punctuation.accessor.ruby | |
push: | |
- include: well-known-methods | |
- match: '{{identifier}}{{method_punctuation}}' | |
- match: '' | |
set: after-identifier | |
# This consumes attribute access so we don't need a lookbehind for . | |
- match: '(\.)(?={{identifier}}{{method_punctuation}})' | |
scope: punctuation.accessor.ruby | |
push: | |
- include: well-known-methods | |
- match: '{{identifier}}{{method_punctuation}}' | |
- match: '' | |
set: after-identifier | |
# This consumes method names ending in punctuation so we don't need a lookbehind for ?, ! or = | |
- match: '{{identifier}}{{method_punctuation}}' | |
# This consumes module/class accessor so we don't need a lookbehind for :: | |
push: after-identifier | |
- match: '::|\.' | |
scope: punctuation.accessor.ruby | |
after-identifier: | |
# Handles a : right after an identifier. In this case it can't be the | |
# beginning of a symbol, so it must be part of a ternary operator | |
- match: ':(?!:)' | |
scope: keyword.operator.conditional.ruby | |
pop: true | |
- match: '' | |
pop: true | |
variables: | |
- match: '(@)[a-zA-Z_]\w*' | |
scope: variable.other.readwrite.instance.ruby | |
captures: | |
1: punctuation.definition.variable.ruby | |
- match: '(@@)[a-zA-Z_]\w*' | |
scope: variable.other.readwrite.class.ruby | |
captures: | |
1: punctuation.definition.variable.ruby | |
- match: '(\$)[a-zA-Z_]\w*' | |
scope: variable.other.readwrite.global.ruby | |
captures: | |
1: punctuation.definition.variable.ruby | |
- match: '(\$)(!|@|&|`|''|\+|\d+|~|=|/|\\|,|;|\.|<|>|_|\*|\$|\?|:|"|-[0adFiIlpv])' | |
scope: variable.other.readwrite.global.pre-defined.ruby | |
captures: | |
1: punctuation.definition.variable.ruby | |
- match: '\b(ENV)\[' | |
captures: | |
1: variable.other.constant.ruby | |
push: | |
- meta_scope: meta.environment-variable.ruby | |
- match: '\]' | |
pop: true | |
- include: expressions | |
- match: '(::)?(\b[[:upper:]]\w*)(?=((\.|::)[[:alpha:]_]|\[))' | |
captures: | |
1: punctuation.accessor.ruby | |
2: support.class.ruby | |
- match: '\b[[:upper:]]\w*\b' | |
scope: variable.other.constant.ruby | |
well-known-methods: | |
- match: '\b(initialize|new|loop|include|extend|prepend|raise|fail|attr_reader|attr_writer|attr_accessor|attr|catch|throw|module_function|public|protected|private)\b(?![?!])' | |
scope: keyword.other.special-method.ruby | |
- match: \b(require|require_relative|gem)\b | |
captures: | |
1: keyword.other.special-method.ruby | |
push: | |
- meta_scope: meta.require.ruby | |
- match: $|(?=#) | |
captures: | |
1: keyword.other.special-method.ruby | |
pop: true | |
- include: expressions | |
# Conversion methods | |
- match: |- | |
(?x: | |
\b( | |
to_ary| | |
to_a| | |
to_c| | |
to_enum| | |
to_f| | |
to_hash| | |
to_h| | |
to_int| | |
to_io| | |
to_i| | |
to_proc| | |
to_r| | |
to_str| | |
to_sym| | |
to_s | |
)\b | |
(?![!?=]) | |
) | |
scope: support.function.builtin.ruby | |
# Methods that may be followed by a regex | |
- match: |- | |
(?x: | |
\b( | |
gsub!| | |
sub! | |
)(?=\s) | |
| | |
\b( | |
assert_match| | |
assert_no_match| | |
gsub| | |
index| | |
match| | |
scan| | |
sub | |
)\b | |
) | |
scope: support.function.builtin.ruby | |
push: try-regex | |
# Methods from the Object class not handled elsewhere, ending in punctuation | |
- match: |- | |
(?x: | |
\b( | |
eql\?| | |
instance_of\?| | |
instance_variable_defined\?| | |
is_a\?| | |
kind_of\?| | |
nil\?| | |
respond_to\?| | |
respond_to_missing\?| | |
tainted\?| | |
untrusted\? | |
) | |
) | |
scope: support.function.builtin.ruby | |
# Methods from the Object class not handled elsewhere | |
- match: |- | |
(?x: | |
\b( | |
class| | |
clone| | |
define_singleton_method| | |
display| | |
dup| | |
enum_for| | |
extend| | |
freeze| | |
frozen?| | |
hash| | |
inspect| | |
instance_variable_get| | |
instance_variable_set| | |
instance_variables| | |
itself| | |
method| | |
methods| | |
object_id| | |
private_methods| | |
protected_methods| | |
public_method| | |
public_methods| | |
public_send| | |
remove_instance_variable| | |
send| | |
singleton_class| | |
singleton_method| | |
singleton_methods| | |
taint| | |
tap| | |
trust| | |
untaint| | |
untrust | |
)\b | |
(?![!?=]) | |
) | |
scope: support.function.builtin.ruby | |
# Methods from the Kernel class not handled elsewhere, ending in punctuation | |
- match: |- | |
(?x: | |
\b( | |
autoload\?| | |
iterator\?| | |
exit! | |
) | |
) | |
scope: support.function.builtin.ruby | |
# Methods from the Kernel class not handled elsewhere | |
- match: |- | |
(?x: | |
\b( | |
Array| | |
Complex| | |
Float| | |
Hash| | |
Integer| | |
Rational| | |
String| | |
__callee__| | |
__dir__| | |
__method__| | |
abort| | |
at_exit| | |
autoload| | |
binding| | |
callcc| | |
caller| | |
caller_locations| | |
chomp| | |
chop| | |
eval| | |
exec| | |
exit| | |
fork| | |
format| | |
gets| | |
global_variables| | |
gsub| | |
lambda| | |
load| | |
local_variables| | |
open| | |
p| | |
print| | |
printf| | |
proc| | |
putc| | |
puts| | |
rand| | |
readline| | |
readlines| | |
require| | |
require_relative| | |
select| | |
set_trace_func| | |
sleep| | |
spawn| | |
sprintf| | |
srand| | |
sub| | |
syscall| | |
system| | |
test| | |
trace_var| | |
trap| | |
untrace_var| | |
warn | |
)\b | |
(?![!?=]) | |
) | |
scope: support.function.builtin.ruby | |
# Methods from the Kernel class not handled elsewhere, ending in punctuation | |
- match: |- | |
(?x: | |
\b( | |
class_variable_defined\?| | |
const_defined\?| | |
include\?| | |
instance_methods\?| | |
method_defined\?| | |
private_method_defined\?| | |
protected_method_defined\?| | |
public_method_defined\?| | |
singleton_class\? | |
) | |
) | |
scope: support.function.builtin.ruby | |
# Methods from the Module class not handled elsewhere | |
- match: |- | |
(?x: | |
\b( | |
ancestors| | |
append_features| | |
class_eval| | |
class_exec| | |
class_variable_get| | |
class_variable_set| | |
class_variables| | |
const_get| | |
const_missing| | |
const_set| | |
constants| | |
define_method| | |
extend_object| | |
extended| | |
freeze| | |
included| | |
included_modules| | |
inspect| | |
method_added| | |
method_removed| | |
method_undefined| | |
module_eval| | |
module_exec| | |
name| | |
prepend_features| | |
prepended| | |
private_class_method| | |
private_constant| | |
private_instance_methods| | |
protected_instance_methods| | |
public_class_method| | |
public_constant| | |
public_instance_method| | |
public_instance_methods| | |
refine| | |
remove_class_variable| | |
remove_const| | |
remove_method| | |
undef_method| | |
using | |
)\b | |
(?![!?=]) | |
) | |
scope: support.function.builtin.ruby | |
method: | |
- match: \b(def)\b | |
scope: meta.function.ruby keyword.control.def.ruby | |
push: | |
- meta_content_scope: meta.function.ruby | |
- match: '(self)(\.)({{identifier}}{{method_punctuation}}|===?|>[>=]?|<=>|<[<=]?|[%&`/\|]|\*\*?|=?~|[-+]@?|\[\]=?)' | |
captures: | |
1: variable.language.ruby | |
2: punctuation.accessor.ruby | |
3: entity.name.function.ruby | |
set: method-parameters-start | |
- match: '===?|>[>=]?|<=>|<[<=]?|[%&`/\|]|\*\*?|=?~|[-+]@?|\[\]=?' | |
scope: entity.name.function.ruby | |
set: method-parameters-start | |
- match: '(?:({{identifier}})(::|\.))?{{identifier}}{{method_punctuation}}' | |
scope: entity.name.function.ruby | |
captures: | |
1: support.other.namespace.ruby | |
2: punctuation.accessor.ruby | |
set: method-parameters-start | |
- match: '$' | |
pop: true | |
- match: '(?=\S)' | |
pop: true | |
method-parameters-start: | |
- meta_content_scope: meta.function.ruby | |
- match: '(?=\()' | |
set: | |
- meta_content_scope: meta.function.parameters.ruby | |
- match: '\(' | |
scope: punctuation.definition.group.begin.ruby | |
set: method-parameters | |
# No parameters | |
- match: '(?=$|;|#)' | |
pop: true | |
# No parentheses around parameters | |
- match: '(?=[[:alpha:]_*])' | |
set: method-bare-parameters | |
method-parameters: | |
- meta_content_scope: meta.function.parameters.ruby | |
- match: '\)' | |
scope: meta.function.parameters.ruby punctuation.definition.group.end.ruby | |
pop: true | |
- match: '{{identifier}}' | |
scope: variable.parameter.ruby | |
- include: comments | |
- match: ',' | |
scope: punctuation.separator.ruby | |
- match: '\*' | |
scope: keyword.operator.splat.ruby | |
- match: '&' | |
scope: keyword.operator.ruby | |
# De-structuring | |
- match: \( | |
scope: punctuation.definition.group.begin.ruby | |
push: | |
- match: \) | |
scope: punctuation.definition.group.end.ruby | |
pop: true | |
- match: '{{identifier}}' | |
scope: variable.parameter.ruby | |
- match: ',' | |
scope: punctuation.separator.ruby | |
- match: '\*' | |
scope: keyword.operator.splat.ruby | |
# Default values | |
- match: (?==) | |
set: | |
- meta_content_scope: meta.function.parameters.default-value.ruby | |
- match: '=' | |
scope: keyword.operator.assignment.ruby | |
set: | |
- meta_content_scope: meta.function.parameters.default-value.ruby | |
- match: '(?=[,\)])' | |
set: method-parameters | |
- include: nest-all | |
- include: expressions | |
# Keyword parameter (with default value support) | |
- match: (?=:) | |
set: | |
- meta_content_scope: meta.function.parameters.default-value.ruby | |
- match: ':' | |
scope: punctuation.separator.ruby | |
set: | |
- meta_content_scope: meta.function.parameters.default-value.ruby | |
- match: '(?=[,\)])' | |
set: method-parameters | |
- include: nest-all | |
- include: expressions | |
# When no parentheses are placed around the parameters | |
method-bare-parameters: | |
- meta_content_scope: meta.function.parameters.ruby | |
- match: '(?=$|;|#)' | |
pop: true | |
- match: '{{identifier}}' | |
scope: variable.parameter.ruby | |
- match: ',' | |
scope: punctuation.separator.ruby | |
- match: '\*' | |
scope: keyword.operator.splat.ruby | |
- match: '&' | |
scope: keyword.operator.ruby | |
# Default values | |
- match: (?==) | |
set: | |
- meta_content_scope: meta.function.parameters.default-value.ruby | |
- match: '=' | |
scope: punctuation.operator.assignment.ruby | |
set: | |
- meta_content_scope: meta.function.parameters.default-value.ruby | |
- match: '(?=$|[,;])' | |
set: method-bare-parameters | |
- include: nest-all | |
- include: expressions | |
# Keyword parameter (with default value support) | |
- match: (?=:) | |
set: | |
- meta_content_scope: meta.function.parameters.default-value.ruby | |
- match: ':' | |
scope: punctuation.separator.ruby | |
set: | |
- meta_content_scope: meta.function.parameters.default-value.ruby | |
- match: '(?=$|[,;])' | |
set: method-bare-parameters | |
- include: nest-all | |
- include: expressions | |
strings: | |
- include: early-strings | |
- include: regexes | |
- include: late-strings | |
early-strings: | |
# single quoted string (does not allow interpolation) | |
- match: "'" | |
scope: punctuation.definition.string.begin.ruby | |
push: | |
- meta_scope: string.quoted.single.ruby | |
- match: "'" | |
scope: punctuation.definition.string.end.ruby | |
pop: true | |
- match: \\'|\\\\ | |
scope: constant.character.escape.ruby | |
- include: string-placeholder | |
# double quoted string (allows for interpolation) | |
- match: '"' | |
scope: punctuation.definition.string.begin.ruby | |
push: | |
- meta_scope: string.quoted.double.ruby | |
- match: '"' | |
scope: punctuation.definition.string.end.ruby | |
pop: true | |
- include: interpolated-ruby | |
- include: escaped-char | |
- include: string-placeholder | |
# execute string (allows for interpolation) | |
- match: "`" | |
scope: punctuation.definition.string.begin.ruby | |
push: | |
- meta_scope: string.interpolated.ruby | |
- match: "`" | |
scope: punctuation.definition.string.end.ruby | |
pop: true | |
- include: interpolated-ruby | |
- include: escaped-char | |
# execute string (allow for interpolation) | |
- match: '%x\{' | |
scope: punctuation.definition.string.begin.ruby | |
push: | |
- meta_scope: string.interpolated.ruby | |
- match: '\}' | |
scope: punctuation.definition.string.end.ruby | |
pop: true | |
- include: interpolated-ruby | |
- include: escaped-char | |
- include: nest-curly-i | |
# execute string (allow for interpolation) | |
- match: '%x\[' | |
scope: punctuation.definition.string.begin.ruby | |
push: | |
- meta_scope: string.interpolated.ruby | |
- match: '\]' | |
scope: punctuation.definition.string.end.ruby | |
pop: true | |
- include: interpolated-ruby | |
- include: escaped-char | |
- include: nest-brackets-i | |
# execute string (allow for interpolation) | |
- match: '%x\<' | |
scope: punctuation.definition.string.begin.ruby | |
push: | |
- meta_scope: string.interpolated.ruby | |
- match: \> | |
scope: punctuation.definition.string.end.ruby | |
pop: true | |
- include: interpolated-ruby | |
- include: escaped-char | |
- include: nest-ltgt-i | |
# execute string (allow for interpolation) | |
- match: '%x\(' | |
scope: punctuation.definition.string.begin.ruby | |
push: | |
- meta_scope: string.interpolated.ruby | |
- match: \) | |
scope: punctuation.definition.string.end.ruby | |
pop: true | |
- include: interpolated-ruby | |
- include: escaped-char | |
- include: nest-parens-i | |
# execute string (allow for interpolation) | |
- match: '%x([^\w])' | |
scope: punctuation.definition.string.begin.ruby | |
push: | |
- meta_scope: string.interpolated.ruby | |
- match: \1 | |
scope: punctuation.definition.string.end.ruby | |
pop: true | |
- include: interpolated-ruby | |
- include: escaped-char | |
late-strings: | |
# literal capable of interpolation () | |
- match: '%[QWI]?\(' | |
scope: punctuation.definition.string.begin.ruby | |
push: | |
- meta_scope: string.quoted.other.literal.upper.ruby | |
- match: \) | |
scope: punctuation.definition.string.end.ruby | |
pop: true | |
- include: interpolated-ruby | |
- include: escaped-char | |
- include: nest-parens-i | |
# "literal capable of interpolation []" | |
- match: '%[QWI]?\[' | |
scope: punctuation.definition.string.begin.ruby | |
push: | |
- meta_scope: string.quoted.other.literal.upper.ruby | |
- match: '\]' | |
scope: punctuation.definition.string.end.ruby | |
pop: true | |
- include: interpolated-ruby | |
- include: escaped-char | |
- include: nest-brackets-i | |
# literal capable of interpolation <> | |
- match: '%[QWI]?\<' | |
scope: punctuation.definition.string.begin.ruby | |
push: | |
- meta_scope: string.quoted.other.literal.upper.ruby | |
- match: \> | |
scope: punctuation.definition.string.end.ruby | |
pop: true | |
- include: interpolated-ruby | |
- include: escaped-char | |
- include: nest-ltgt-i | |
# literal capable of interpolation -- {} | |
- match: '%[QWI]?\{' | |
scope: punctuation.definition.string.begin.ruby | |
push: | |
- meta_scope: string.quoted.double.ruby.mod | |
- match: '\}' | |
scope: punctuation.definition.string.end.ruby | |
pop: true | |
- include: interpolated-ruby | |
- include: escaped-char | |
- include: nest-curly-i | |
# literal capable of interpolation -- wildcard | |
- match: '%[QWI]([^\w])' | |
scope: punctuation.definition.string.begin.ruby | |
push: | |
- meta_scope: string.quoted.other.literal.upper.ruby | |
- match: \1 | |
scope: punctuation.definition.string.end.ruby | |
pop: true | |
- include: interpolated-ruby | |
- include: escaped-char | |
# literal capable of interpolation -- wildcard | |
- match: '%([^\w\s=])' | |
scope: punctuation.definition.string.begin.ruby | |
push: | |
- meta_scope: string.quoted.other.literal.other.ruby | |
- match: \1 | |
scope: punctuation.definition.string.end.ruby | |
pop: true | |
- include: interpolated-ruby | |
- include: escaped-char | |
# literal incapable of interpolation -- () | |
- match: '%[qwsi]\(' | |
scope: punctuation.definition.string.begin.ruby | |
push: | |
- meta_scope: string.quoted.other.literal.lower.ruby | |
- match: \) | |
scope: punctuation.definition.string.end.ruby | |
pop: true | |
- match: \\\)|\\\\ | |
scope: constant.character.escape.ruby | |
- include: nest-parens | |
# literal incapable of interpolation -- <> | |
- match: '%[qwsi]\<' | |
scope: punctuation.definition.string.begin.ruby | |
push: | |
- meta_scope: string.quoted.other.literal.lower.ruby | |
- match: \> | |
scope: punctuation.definition.string.end.ruby | |
pop: true | |
- match: \\\>|\\\\ | |
scope: constant.character.escape.ruby | |
- include: nest-ltgt | |
# literal incapable of interpolation -- [] | |
- match: '%[qwsi]\[' | |
scope: punctuation.definition.string.begin.ruby | |
push: | |
- meta_scope: string.quoted.other.literal.lower.ruby | |
- match: '\]' | |
scope: punctuation.definition.string.end.ruby | |
pop: true | |
- match: '\\\]|\\\\' | |
scope: constant.character.escape.ruby | |
- include: nest-brackets | |
# literal incapable of interpolation -- {} | |
- match: '%[qwsi]\{' | |
scope: punctuation.definition.string.begin.ruby | |
push: | |
- meta_scope: string.quoted.other.literal.lower.ruby | |
- match: '\}' | |
scope: punctuation.definition.string.end.ruby | |
pop: true | |
- match: '\\\}|\\\\' | |
scope: constant.character.escape.ruby | |
- include: nest-curly | |
# literal incapable of interpolation -- wildcard | |
- match: '%[qwsi]([^\w])' | |
scope: punctuation.definition.string.begin.ruby | |
push: | |
- meta_scope: string.quoted.other.literal.lower.ruby | |
- match: \1 | |
scope: punctuation.definition.string.end.ruby | |
pop: true | |
# Cant be named because its not necessarily an escape | |
- match: \\. | |
after-keyword: | |
- include: try-regex | |
after-operator: | |
- include: try-regex | |
try-regex: | |
# Generally for multiline regexes, one of the %r forms below will be used, | |
# so we bail out if we can't find a second / on the current line | |
- match: '\s*(/)(?![*+{}?])(?=.*/)' | |
captures: | |
1: string.regexp.classic.ruby punctuation.definition.string.ruby | |
push: | |
- meta_content_scope: string.regexp.classic.ruby | |
- match: "(/)([eimnosux]*)" | |
scope: string.regexp.classic.ruby | |
captures: | |
1: punctuation.definition.string.ruby | |
2: keyword.other.ruby | |
pop: true | |
- include: regex-sub | |
- match: '' | |
pop: true | |
regexes: | |
# Needs higher precedence than regular expressions. | |
- match: /= | |
scope: keyword.operator.assignment.augmented.ruby | |
- match: '(?=^\s*/)' | |
push: try-regex | |
- match: (?=/\s*[^\w\(\s@"']) | |
push: try-regex | |
# regular expressions (literal) | |
- match: '%r\{' | |
scope: punctuation.definition.string.begin.ruby | |
push: | |
- meta_scope: string.regexp.mod-r.ruby | |
- match: '\}[eimnosux]*' | |
scope: punctuation.definition.string.end.ruby | |
pop: true | |
- include: regex-sub | |
- include: nest-curly-r | |
# regular expressions (literal) | |
- match: '%r\[' | |
scope: punctuation.definition.string.begin.ruby | |
push: | |
- meta_scope: string.regexp.mod-r.ruby | |
- match: '\][eimnosux]*' | |
scope: punctuation.definition.string.end.ruby | |
pop: true | |
- include: regex-sub | |
- include: nest-brackets-r | |
# regular expressions (literal) | |
- match: '%r\(' | |
scope: punctuation.definition.string.begin.ruby | |
push: | |
- meta_scope: string.regexp.mod-r.ruby | |
- match: '\)[eimnosux]*' | |
scope: punctuation.definition.string.end.ruby | |
pop: true | |
- include: regex-sub | |
- include: nest-parens-r | |
# regular expressions (literal) | |
- match: '%r\<' | |
scope: punctuation.definition.string.begin.ruby | |
push: | |
- meta_scope: string.regexp.mod-r.ruby | |
- match: '\>[eimnosux]*' | |
scope: punctuation.definition.string.end.ruby | |
pop: true | |
- include: regex-sub | |
- include: nest-ltgt-r | |
# regular expressions (literal) | |
- match: '%r([^\w])' | |
scope: punctuation.definition.string.begin.ruby | |
push: | |
- meta_scope: string.regexp.mod-r.ruby | |
- match: '\1[eimnosux]*' | |
scope: punctuation.definition.string.end.ruby | |
pop: true | |
- include: regex-sub | |
regex-sub: | |
- include: interpolated-ruby | |
- include: escaped-char | |
- match: '(\{)\d+(,\d+)?(\})' | |
scope: string.regexp.arbitrary-repetition.ruby | |
captures: | |
1: punctuation.definition.arbitrary-repetition.ruby | |
3: punctuation.definition.arbitrary-repetition.ruby | |
- match: '\[(?:\^?\])?' | |
scope: punctuation.definition.character-class.ruby | |
push: | |
- meta_scope: string.regexp.character-class.ruby | |
- match: '\]' | |
scope: punctuation.definition.character-class.ruby | |
pop: true | |
- include: escaped-char | |
- match: \( | |
scope: punctuation.definition.group.ruby | |
push: | |
- meta_scope: string.regexp.group.ruby | |
- match: \) | |
scope: punctuation.definition.group.ruby | |
pop: true | |
- include: regex-sub | |
# 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. | |
- match: '(?:^|\s)(#)\s[[a-zA-Z0-9,. \t?!-][^\x{00}-\x{7F}]]*$' | |
scope: comment.line.number-sign.ruby | |
captures: | |
1: punctuation.definition.comment.ruby | |
nest-brackets-r: | |
- match: '\[' | |
scope: punctuation.section.scope.ruby | |
push: | |
- match: '\]' | |
scope: punctuation.section.scope.ruby | |
pop: true | |
- include: regex-sub | |
- include: nest-brackets-r | |
nest-curly-r: | |
- match: '\{' | |
scope: punctuation.section.scope.ruby | |
push: | |
- match: '\}' | |
scope: punctuation.section.scope.ruby | |
pop: true | |
- include: regex-sub | |
- include: nest-curly-r | |
nest-ltgt-r: | |
- match: \< | |
scope: punctuation.section.scope.ruby | |
push: | |
- match: \> | |
scope: punctuation.section.scope.ruby | |
pop: true | |
- include: regex-sub | |
- include: nest-ltgt-r | |
nest-parens-r: | |
- match: \( | |
scope: punctuation.section.scope.ruby | |
push: | |
- match: \) | |
scope: punctuation.section.scope.ruby | |
pop: true | |
- include: regex-sub | |
- include: nest-parens-r | |
nest-brackets: | |
- match: '\[' | |
scope: punctuation.section.scope.ruby | |
push: | |
- match: '\]' | |
scope: punctuation.section.scope.ruby | |
pop: true | |
- include: nest-brackets | |
nest-curly: | |
- match: '\{' | |
scope: punctuation.section.scope.ruby | |
push: [nest-curly-inner, maybe-block-parameters] | |
nest-curly-inner: | |
- match: '\}' | |
scope: punctuation.section.scope.ruby | |
pop: true | |
- include: nest-curly | |
nest-ltgt: | |
- match: \< | |
scope: punctuation.section.scope.ruby | |
push: | |
- match: \> | |
scope: punctuation.section.scope.ruby | |
pop: true | |
- include: nest-ltgt | |
nest-parens: | |
- match: \( | |
scope: punctuation.section.scope.ruby | |
push: | |
- match: \) | |
scope: punctuation.section.scope.ruby | |
pop: true | |
- include: nest-parens | |
string-placeholder: | |
# %[flags][width][.precision]type | |
# | |
# A format sequence consists of a percent sign, followed by optional | |
# flags, width, and precision indicators, then terminated with a field | |
# type character. | |
# | |
# Also this is used for time format in strftime. | |
- match: |- | |
(?x)% | |
([#0\- +\*]|(\d+\$))* # flags | |
(-?\d+)? # minimum field width | |
(\.(\d+)?)? # precision | |
[diouxXDOUeEfFgGaAcCsSpnvtTbByYhHmMzZ%] # conversion type | |
scope: constant.other.placeholder.ruby | |
escaped-char: | |
- match: '\\(?:[0-7]{1,3}|x[\da-fA-F]{1,2}|.)' | |
scope: constant.character.escape.ruby | |
interpolated-ruby: | |
- match: '#\{' | |
scope: punctuation.section.interpolation.begin.ruby | |
push: | |
- clear_scopes: 1 | |
- meta_scope: meta.interpolation | |
- meta_content_scope: source.ruby.embedded | |
- match: '\}' | |
scope: punctuation.section.interpolation.end.ruby | |
pop: true | |
- include: nest-curly-expressions | |
- include: expressions | |
- match: '(#@)[[:alpha:]_]\w*' | |
scope: variable.other.readwrite.instance.ruby | |
captures: | |
1: punctuation.definition.variable.ruby | |
- match: '(#@@)[[:alpha:]_]\w*' | |
scope: variable.other.readwrite.class.ruby | |
captures: | |
1: punctuation.definition.variable.ruby | |
- match: '(#\$)[[:alpha:]_]\w*' | |
scope: variable.other.readwrite.global.ruby | |
captures: | |
1: punctuation.definition.variable.ruby | |
nest-curly-expressions: | |
- match: '\{' | |
scope: punctuation.section.scope.ruby | |
push: [nest-curly-expressions-inner, maybe-block-parameters] | |
nest-curly-expressions-inner: | |
- match: '\}' | |
scope: punctuation.section.scope.ruby | |
pop: true | |
- include: nest-curly-expressions | |
- include: expressions | |
nest-all: | |
- match: '\(' | |
scope: punctuation.definition.group.begin.ruby | |
push: | |
- match: '\)' | |
scope: punctuation.definition.group.end.ruby | |
pop: true | |
- include: nest-all | |
- include: expressions | |
- match: '\{' | |
scope: punctuation.section.scope.ruby | |
push: [nest-all-inner, maybe-block-parameters] | |
- match: '\[' | |
scope: punctuation.section.array.ruby | |
push: | |
- match: '\]' | |
scope: punctuation.section.array.ruby | |
pop: true | |
- include: nest-all | |
- include: expressions | |
nest-all-inner: | |
- match: '\}' | |
scope: punctuation.section.scope.ruby | |
pop: true | |
- include: nest-all | |
- include: expressions | |
nest-brackets-i: | |
- match: '\[' | |
scope: punctuation.section.scope.ruby | |
push: | |
- match: '\]' | |
scope: punctuation.section.scope.ruby | |
pop: true | |
- include: interpolated-ruby | |
- include: escaped-char | |
- include: nest-brackets-i | |
nest-curly-i: | |
- match: '\{' | |
scope: punctuation.section.scope.ruby | |
push: [nest-curly-i-inner, maybe-block-parameters] | |
nest-curly-i-inner: | |
- match: '\}' | |
scope: punctuation.section.scope.ruby | |
pop: true | |
- include: interpolated-ruby | |
- include: escaped-char | |
- include: nest-curly-i | |
nest-ltgt-i: | |
- match: \< | |
scope: punctuation.section.scope.ruby | |
push: | |
- match: \> | |
scope: punctuation.section.scope.ruby | |
pop: true | |
- include: interpolated-ruby | |
- include: escaped-char | |
- include: nest-ltgt-i | |
nest-parens-i: | |
- match: \( | |
scope: punctuation.section.scope.ruby | |
push: | |
- match: \) | |
scope: punctuation.section.scope.ruby | |
pop: true | |
- include: interpolated-ruby | |
- include: escaped-char | |
- include: nest-parens-i | |
heredocs: | |
# heredoc with embedded HTML and indented terminator | |
- match: '(<<[-~]"?((?:[_\w]+_|)HTML)\b"?)' | |
scope: punctuation.definition.string.begin.ruby | |
push: [heredoc-html, trailing-heredoc-start] | |
# heredoc with embedded ERB and indented terminator | |
- match: '(<<[-~]"?((?:[_\w]+_|)ERB)\b"?)' | |
scope: punctuation.definition.string.begin.ruby | |
push: [heredoc-erb, trailing-heredoc-start] | |
# heredoc with embedded HAML and indented terminator | |
- match: '(<<[-~]"?((?:[_\w]+_|)HAML)\b"?)' | |
scope: punctuation.definition.string.begin.ruby | |
push: [heredoc-haml, trailing-heredoc-start] | |
# - match: '(<<[-~]"?((?:[_\w]+_|)ERB)\b"?)' | |
# embed: text.html.ruby.custom | |
# escape: ^\s*(ERB)$ | |
# escape_captures: | |
# 0: trailing-heredoc | |
# heredoc with embedded SQL and indented terminator | |
- match: '(<<[-~]"?((?:[_\w]+_|)SQL)\b"?)' | |
scope: punctuation.definition.string.begin.ruby | |
push: [heredoc-sql, trailing-heredoc-start] | |
# heredoc with embedded css and indented terminator | |
- match: '(<<[-~]"?((?:[_\w]+_|)CSS)\b"?)' | |
scope: punctuation.definition.string.begin.ruby | |
push: [heredoc-css, trailing-heredoc-start] | |
# heredoc with embedded javascript and indented terminator | |
- match: '(<<[-~]"?((?:[_\w]+_|)(?:JS|JAVASCRIPT))\b"?)' | |
scope: punctuation.definition.string.begin.ruby | |
push: [heredoc-js, trailing-heredoc-start] | |
# heredoc with embedded ruby and indented terminator | |
- match: '(<<[-~]"?((?:[_\w]+_|)RUBY)\b"?)' | |
scope: punctuation.definition.string.begin.ruby | |
push: [heredoc-ruby, trailing-heredoc-start] | |
# Escaped to prevent recursion? | |
# heredoc with embedded shell and indented terminator | |
# - match: '(<<[-~]("?)((?:[_\w]+_|)(?:SH|SHELL))\b\1)' | |
# scope: punctuation.definition.string.begin.ruby | |
# push: [heredoc-shell, trailing-heredoc-start] | |
- match: (\=)\s*(<<(\w+)) | |
captures: | |
1: keyword.operator.assignment.ruby | |
2: punctuation.definition.string.begin.ruby | |
push: [heredoc-assign, trailing-heredoc-no-embedding-start] | |
# heredoc with indented terminator | |
- match: '(<<[-~](\w+))' | |
scope: punctuation.definition.string.begin.ruby | |
push: [heredoc-plain, trailing-heredoc-no-embedding-start] | |
heredoc-html: | |
- meta_scope: string.unquoted.embedded.html.ruby | |
- meta_content_scope: text.html.embedded.ruby | |
- match: ^\s*\2$ | |
scope: punctuation.definition.string.end.ruby | |
pop: true | |
- include: scope:text.html.basic | |
- include: interpolated-ruby | |
- include: escaped-char | |
heredoc-erb: | |
- meta_scope: string.unquoted.embedded.html.ruby | |
- meta_content_scope: text.html.ruby.embedded.ruby | |
- match: ^\s*\2$ | |
scope: punctuation.definition.string.end.ruby | |
pop: true | |
- include: scope:text.html.basic | |
- include: interpolated-ruby | |
- include: escaped-char | |
- match: "<%+#" | |
scope: punctuation.definition.comment.erb | |
push: | |
- meta_scope: comment.block.erb | |
- match: "%>" | |
pop: true | |
- match: "<%+(?!>)[-=]?" | |
scope: punctuation.section.embedded.ruby | |
push: | |
- meta_scope: source.ruby.rails.embedded.html | |
- match: "-?%>" | |
scope: punctuation.section.embedded.ruby | |
pop: true | |
- match: (#).*?(?=-?%>) | |
scope: comment.line.number-sign.ruby | |
captures: | |
1: punctuation.definition.comment.ruby | |
- include: "Ruby on Rails.sublime-syntax" | |
heredoc-haml: | |
- meta_scope: string.unquoted.embedded.haml.ruby | |
- meta_content_scope: text.haml.embedded.ruby | |
- match: ^\s*HAML$ | |
scope: punctuation.definition.string.end.ruby | |
pop: true | |
- include: scope:text.haml | |
- include: interpolated-ruby | |
- include: escaped-char | |
heredoc-sql: | |
- meta_scope: string.unquoted.embedded.sql.ruby | |
- meta_content_scope: text.sql.embedded.ruby | |
- match: ^\s*\2$ | |
scope: punctuation.definition.string.end.ruby | |
pop: true | |
- include: scope:source.sql | |
- include: interpolated-ruby | |
- include: escaped-char | |
heredoc-css: | |
- meta_scope: string.unquoted.embedded.css.ruby | |
- meta_content_scope: text.css.embedded.ruby | |
- match: ^\s*\2$ | |
scope: punctuation.definition.string.end.ruby | |
pop: true | |
- include: 'scope:source.css' | |
- include: interpolated-ruby | |
- include: escaped-char | |
heredoc-js: | |
- meta_scope: string.unquoted.embedded.js.ruby | |
- meta_content_scope: text.js.embedded.ruby | |
- match: ^\s*\2$ | |
scope: punctuation.definition.string.end.ruby | |
pop: true | |
- include: 'scope:source.js' | |
- include: interpolated-ruby | |
- include: escaped-char | |
heredoc-ruby: | |
- meta_scope: string.unquoted.embedded.ruby.ruby | |
- meta_content_scope: text.ruby.embedded.ruby | |
- match: ^\s*\2$ | |
scope: punctuation.definition.string.end.ruby | |
pop: true | |
- include: interpolated-ruby | |
- include: escaped-char | |
- include: expressions | |
#heredoc-shell: | |
# - meta_scope: string.unquoted.embedded.shell.ruby | |
# - meta_content_scope: text.shell.embedded.ruby | |
# - match: ^\s*\2$ | |
# scope: punctuation.definition.string.end.ruby | |
# pop: true | |
# - include: Shell-Unix-Generic.sublime-syntax | |
# - include: interpolated-ruby | |
# - include: escaped-char | |
# This prevents clear_scopes from applying to the push token | |
trailing-heredoc-start: | |
- match: '' | |
set: trailing-heredoc | |
trailing-heredoc: | |
- clear_scopes: 2 | |
- match: '$' | |
pop: true | |
- include: expressions | |
heredoc-assign: | |
- meta_scope: string.unquoted.heredoc.ruby | |
- match: ^\s*\3$ | |
scope: punctuation.definition.string.end.ruby | |
pop: true | |
- include: interpolated-ruby | |
- include: escaped-char | |
heredoc-plain: | |
- meta_scope: string.unquoted.heredoc.ruby | |
- match: ^\s*\2$ | |
scope: punctuation.definition.string.end.ruby | |
pop: true | |
- include: interpolated-ruby | |
- include: escaped-char | |
# This prevents clear_scopes from applying to the push token | |
trailing-heredoc-no-embedding-start: | |
- match: '' | |
set: trailing-heredoc-no-embedding | |
trailing-heredoc-no-embedding: | |
- clear_scopes: 1 | |
- match: '$' | |
pop: true | |
- include: expressions | |
data-section: | |
- match: ^__END__\n | |
scope: string.unquoted.program-block.ruby | |
push: | |
- meta_content_scope: text.plain | |
- match: (?=<?xml|<(?i:html\b)|!DOCTYPE (?i:html\b)) | |
push: | |
- meta_scope: text.html.embedded.ruby | |
- include: scope:text.html.basic |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment