Last active
February 19, 2022 21:49
-
-
Save existentialmutt/d27cc43cfeb6f98c1dde846e4e36c63b to your computer and use it in GitHub Desktop.
Revisions
-
existentialmutt revised this gist
Oct 24, 2020 . 1 changed file with 19 additions and 1 deletion.There are no files selected for viewing
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 charactersOriginal file line number Diff line number Diff line change @@ -1423,9 +1423,27 @@ contexts: - 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 -
existentialmutt created this gist
Oct 23, 2020 .There are no files selected for viewing
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 charactersOriginal file line number Diff line number Diff line change @@ -0,0 +1,1536 @@ %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.ruby - include: interpolated-ruby - include: escaped-char 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