|
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521 |
- %YAML 1.2
- ---
- # http://www.sublimetext.com/docs/3/syntax.html
- name: Elixir
- comment: Textmate bundle for Elixir Programming Language.
- file_extensions:
- - ex
- - exs
- first_line_match: ^#!/.*\belixir
- scope: source.elixir
- contexts:
- main:
- - match: \b(fn)\b(?!.*->)
- captures:
- 1: keyword.control.elixir
- push:
- - match: $
- pop: true
- - include: core_syntax
- - match: \b(fn)\b(?=.*->)
- captures:
- 1: keyword.control.elixir
- push:
- - match: (?>(->)|(when)|(\)))
- captures:
- 1: keyword.operator.other.elixir
- 2: keyword.control.elixir
- 3: punctuation.section.function.elixir
- pop: true
- - include: core_syntax
- - include: core_syntax
- - match: '^(?=.*->)((?![^"'']*("|'')[^"'']*->)|(?=.*->[^"'']*("|'')[^"'']*->))((?!.*\([^\)]*->)|(?=[^\(\)]*->)|(?=\s*\(.*\).*->))((?!.*\b(fn)\b)|(?=.*->.*\bfn\b))'
- captures:
- 1: keyword.control.elixir
- push:
- - match: (?>(->)|(when)|(\)))
- captures:
- 1: keyword.operator.other.elixir
- 2: keyword.control.elixir
- 3: punctuation.section.function.elixir
- pop: true
- - include: core_syntax
- core_syntax:
- - match: ^\s*(defmodule)\b
- captures:
- 1: keyword.control.module.elixir
- push:
- - meta_scope: meta.module.elixir
- - match: \b(do)\b
- captures:
- 1: keyword.control.module.elixir
- pop: true
- - match: '\b[A-Z]\w*\b'
- scope: entity.name.class.elixir
- - match: ^\s*(defprotocol)\b
- captures:
- 1: keyword.control.protocol.elixir
- push:
- - meta_scope: meta.protocol_declaration.elixir
- - match: \b(do)\b
- captures:
- 1: keyword.control.protocol.elixir
- pop: true
- - match: '\b[A-Z]\w*\b'
- scope: entity.name.protocol.elixir
- - match: ^\s*(defimpl)\b
- captures:
- 1: keyword.control.protocol.elixir
- push:
- - meta_scope: meta.protocol_implementation.elixir
- - match: \b(do)\b
- captures:
- 1: keyword.control.protocol.elixir
- pop: true
- - match: '\b[A-Z]\w*\b'
- scope: entity.name.protocol.elixir
- - match: '^\s*(def|defmacro)\s+((?>[a-zA-Z_]\w*(?>\.|::))?(?>[a-zA-Z_]\w*(?>[?!]|=(?!>))?|===?|>[>=]?|<=>|<[<=]?|[%&`/\|]|\*\*?|=?~|[-+]@?|\[\]=?))((\()|\s*)'
- captures:
- 1: keyword.control.module.elixir
- 2: entity.name.function.public.elixir
- 4: punctuation.section.function.elixir
- push:
- - meta_scope: meta.function.public.elixir
- - match: (\bdo:)|(\bdo\b)|(?=\s+(def|defmacro)\b)
- captures:
- 1: constant.other.keywords.elixir
- 2: keyword.control.module.elixir
- pop: true
- - include: main
- - match: \s(\\\\)
- captures:
- 1: keyword.operator.other.elixir
- push:
- - match: ',|\)|$'
- pop: true
- - include: main
- - match: \b(is_atom|is_binary|is_bitstring|is_boolean|is_float|is_function|is_integer|is_list|is_map|is_nil|is_number|is_pid|is_port|is_record|is_reference|is_tuple|is_exception|abs|bit_size|byte_size|div|elem|hd|length|map_size|node|rem|round|tl|trunc|tuple_size)\b
- scope: keyword.control.elixir
- - match: '^\s*(defp|defmacrop)\s+((?>[a-zA-Z_]\w*(?>\.|::))?(?>[a-zA-Z_]\w*(?>[?!]|=(?!>))?|===?|>[>=]?|<=>|<[<=]?|[%&`/\|]|\*\*?|=?~|[-+]@?|\[\]=?))((\()|\s*)'
- captures:
- 1: keyword.control.module.elixir
- 2: entity.name.function.private.elixir
- 4: punctuation.section.function.elixir
- push:
- - meta_scope: meta.function.private.elixir
- - match: (\bdo:)|(\bdo\b)|(?=\s+(defp|defmacrop)\b)
- captures:
- 1: constant.other.keywords.elixir
- 2: keyword.control.module.elixir
- pop: true
- - include: main
- - match: \s(\\\\)
- captures:
- 1: keyword.operator.other.elixir
- push:
- - match: ',|\)|$'
- pop: true
- - include: main
- - match: \b(is_atom|is_binary|is_bitstring|is_boolean|is_float|is_function|is_integer|is_list|is_map|is_nil|is_number|is_pid|is_port|is_record|is_reference|is_tuple|is_exception|abs|bit_size|byte_size|div|elem|hd|length|map_size|node|rem|round|tl|trunc|tuple_size)\b
- scope: keyword.control.elixir
- - match: '@(module|type)?doc (~[a-z])?"""'
- comment: "@doc with heredocs is treated as documentation"
- push:
- - meta_scope: comment.documentation.heredoc
- - match: \s*"""
- pop: true
- - include: interpolated_elixir
- - include: escaped_char
- - match: '@(module|type)?doc ~[A-Z]"""'
- comment: "@doc with heredocs is treated as documentation"
- push:
- - meta_scope: comment.documentation.heredoc
- - match: \s*"""
- pop: true
- - match: "@(module|type)?doc (~[a-z])?'''"
- comment: "@doc with heredocs is treated as documentation"
- push:
- - meta_scope: comment.documentation.heredoc
- - match: \s*'''
- pop: true
- - include: interpolated_elixir
- - include: escaped_char
- - match: "@(module|type)?doc ~[A-Z]'''"
- comment: "@doc with heredocs is treated as documentation"
- push:
- - meta_scope: comment.documentation.heredoc
- - match: \s*'''
- pop: true
- - match: "@(module|type)?doc false"
- comment: "@doc false is treated as documentation"
- scope: comment.documentation.false
- - match: '@(module|type)?doc "'
- comment: "@doc with string is treated as documentation"
- push:
- - meta_scope: comment.documentation.string
- - match: '"'
- pop: true
- - include: interpolated_elixir
- - include: escaped_char
- - match: '(?<!\.)\b(do|end|case|bc|lc|for|if|cond|unless|try|receive|fn|defmodule|defp?|defprotocol|defimpl|defrecord|defstruct|defmacrop?|defdelegate|defcallback|defmacrocallback|defexception|defoverridable|exit|after|rescue|catch|else|raise|throw|import|require|alias|use|quote|unquote|super|with)\b(?![?!:])'
- scope: keyword.control.elixir
- - match: (?<!\.)\b(and|not|or|when|xor|in)\b
- comment: as above, just doesn't need a 'end' and does a logic operation
- scope: keyword.operator.elixir
- - match: '\b[A-Z]\w*\b'
- scope: entity.name.class.elixir
- - match: '\b(nil|true|false)\b(?![?!])'
- scope: constant.language.elixir
- - match: '\b(__(CALLER|ENV|MODULE|DIR)__)\b(?![?!])'
- scope: variable.language.elixir
- - match: '(@)[a-zA-Z_]\w*'
- scope: variable.other.readwrite.module.elixir
- captures:
- 1: punctuation.definition.variable.elixir
- - match: (&)\d+
- scope: variable.other.anonymous.elixir
- captures:
- 1: punctuation.definition.variable.elixir
- - match: '\^[a-z_]\w*'
- scope: variable.other.capture.elixir
- captures:
- 1: punctuation.definition.variable.elixir
- - match: '\b(0x[0-9A-Fa-f](?>_?[0-9A-Fa-f])*|\d(?>_?\d)*(\.(?![^[:space:][:digit:]])(?>_?\d)*)?([eE][-+]?\d(?>_?\d)*)?|0b[01]+|0o[0-7]+)\b'
- scope: constant.numeric.elixir
- - match: ":'"
- captures:
- 0: punctuation.definition.constant.elixir
- push:
- - meta_scope: constant.other.symbol.single-quoted.elixir
- - match: "'"
- captures:
- 0: punctuation.definition.constant.elixir
- pop: true
- - include: interpolated_elixir
- - include: escaped_char
- - match: ':"'
- captures:
- 0: punctuation.definition.constant.elixir
- push:
- - meta_scope: constant.other.symbol.double-quoted.elixir
- - match: '"'
- captures:
- 0: punctuation.definition.constant.elixir
- pop: true
- - include: interpolated_elixir
- - include: escaped_char
- - match: (?>''')
- comment: Single-quoted heredocs
- captures:
- 0: punctuation.definition.string.begin.elixir
- push:
- - meta_scope: string.quoted.single.heredoc.elixir
- - match: ^\s*'''
- captures:
- 0: punctuation.definition.string.end.elixir
- pop: true
- - include: interpolated_elixir
- - include: escaped_char
- - match: "'"
- comment: single quoted string (allows for interpolation)
- captures:
- 0: punctuation.definition.string.begin.elixir
- push:
- - meta_scope: string.quoted.single.elixir
- - match: "'"
- captures:
- 0: punctuation.definition.string.end.elixir
- pop: true
- - include: interpolated_elixir
- - include: escaped_char
- - match: (?>""")
- comment: Double-quoted heredocs
- captures:
- 0: punctuation.definition.string.begin.elixir
- push:
- - meta_scope: string.quoted.double.heredoc.elixir
- - match: ^\s*"""
- captures:
- 0: punctuation.definition.string.end.elixir
- pop: true
- - include: interpolated_elixir
- - include: escaped_char
- - match: '"'
- comment: double quoted string (allows for interpolation)
- captures:
- 0: punctuation.definition.string.begin.elixir
- push:
- - meta_scope: string.quoted.double.elixir
- - match: '"'
- captures:
- 0: punctuation.definition.string.end.elixir
- pop: true
- - include: interpolated_elixir
- - include: escaped_char
- - match: '~[a-z](?>""")'
- comment: Double-quoted heredocs sigils
- captures:
- 0: punctuation.definition.string.begin.elixir
- push:
- - meta_scope: string.quoted.double.heredoc.elixir
- - match: ^\s*"""
- captures:
- 0: punctuation.definition.string.end.elixir
- pop: true
- - include: interpolated_elixir
- - include: escaped_char
- - match: '~[a-z]\{'
- comment: sigil (allow for interpolation)
- captures:
- 0: punctuation.definition.string.begin.elixir
- push:
- - meta_scope: string.interpolated.elixir
- - match: '\}[a-z]*'
- captures:
- 0: punctuation.definition.string.end.elixir
- pop: true
- - include: interpolated_elixir
- - include: escaped_char
- - match: '~[a-z]\['
- comment: sigil (allow for interpolation)
- captures:
- 0: punctuation.definition.string.begin.elixir
- push:
- - meta_scope: string.interpolated.elixir
- - match: '\][a-z]*'
- captures:
- 0: punctuation.definition.string.end.elixir
- pop: true
- - include: interpolated_elixir
- - include: escaped_char
- - match: '~[a-z]\<'
- comment: sigil (allow for interpolation)
- captures:
- 0: punctuation.definition.string.begin.elixir
- push:
- - meta_scope: string.interpolated.elixir
- - match: '\>[a-z]*'
- captures:
- 0: punctuation.definition.string.end.elixir
- pop: true
- - include: interpolated_elixir
- - include: escaped_char
- - match: '~[a-z]\('
- comment: sigil (allow for interpolation)
- captures:
- 0: punctuation.definition.string.begin.elixir
- push:
- - meta_scope: string.interpolated.elixir
- - match: '\)[a-z]*'
- captures:
- 0: punctuation.definition.string.end.elixir
- pop: true
- - include: interpolated_elixir
- - include: escaped_char
- - match: '~[a-z]([^\w])'
- comment: sigil (allow for interpolation)
- captures:
- 0: punctuation.definition.string.begin.elixir
- push:
- - meta_scope: string.interpolated.elixir
- - match: '\1[a-z]*'
- captures:
- 0: punctuation.definition.string.end.elixir
- pop: true
- - include: interpolated_elixir
- - include: escaped_char
- - include: escaped_char
- - match: '~[A-Z](?>""")'
- comment: Double-quoted heredocs sigils
- captures:
- 0: punctuation.definition.string.begin.elixir
- push:
- - meta_scope: string.quoted.other.literal.upper.elixir
- - match: ^\s*"""
- captures:
- 0: punctuation.definition.string.end.elixir
- pop: true
- - match: '~[A-Z]\{'
- comment: sigil (without interpolation)
- captures:
- 0: punctuation.definition.string.begin.elixir
- push:
- - meta_scope: string.quoted.other.literal.upper.elixir
- - match: '\}[a-z]*'
- captures:
- 0: punctuation.definition.string.end.elixir
- pop: true
- - match: '~[A-Z]\['
- comment: sigil (without interpolation)
- captures:
- 0: punctuation.definition.string.begin.elixir
- push:
- - meta_scope: string.quoted.other.literal.upper.elixir
- - match: '\][a-z]*'
- captures:
- 0: punctuation.definition.string.end.elixir
- pop: true
- - match: '~[A-Z]\<'
- comment: sigil (without interpolation)
- captures:
- 0: punctuation.definition.string.begin.elixir
- push:
- - meta_scope: string.quoted.other.literal.upper.elixir
- - match: '\>[a-z]*'
- captures:
- 0: punctuation.definition.string.end.elixir
- pop: true
- - match: '~[A-Z]\('
- comment: sigil (without interpolation)
- captures:
- 0: punctuation.definition.string.begin.elixir
- push:
- - meta_scope: string.quoted.other.literal.upper.elixir
- - match: '\)[a-z]*'
- captures:
- 0: punctuation.definition.string.end.elixir
- pop: true
- - match: '~[A-Z]([^\w])'
- comment: sigil (without interpolation)
- captures:
- 0: punctuation.definition.string.begin.elixir
- push:
- - meta_scope: string.quoted.other.literal.upper.elixir
- - match: '\1[a-z]*'
- captures:
- 0: punctuation.definition.string.end.elixir
- pop: true
- - match: '(?<!:)(:)(?>[a-zA-Z_][\w@]*(?>[?!]|=(?![>=]))?|\<\>|===?|!==?|<<>>|<<<|>>>|~~~|::|<\-|\|>|=>|=~|=|/|\\\\|\*\*?|\.\.?\.?|>=?|<=?|&&?&?|\+\+?|\-\-?|\|\|?\|?|\!|@|\%?\{\}|%|\[\]|\^(\^\^)?)'
- comment: symbols
- scope: constant.other.symbol.elixir
- captures:
- 1: punctuation.definition.constant.elixir
- - match: '(?>[a-zA-Z_][\w@]*(?>[?!])?)(:)(?!:)'
- comment: symbols
- scope: constant.other.keywords.elixir
- captures:
- 1: punctuation.definition.constant.elixir
- - match: ^\s*(##).*$\n?
- scope: comment.line.section.elixir
- captures:
- 1: punctuation.definition.comment.elixir
- - match: '(?:^[ \t]+)?(#).*$\n?'
- scope: comment.line.number-sign.elixir
- captures:
- 1: punctuation.definition.comment.elixir
- - match: '(?<!\w)\?(\\(x[0-9A-Fa-f]{1,2}(?![0-9A-Fa-f])\b|[^xMC])|[^\s\\])'
- comment: |
- matches questionmark-letters.
-
- examples (1st alternation = hex):
- ?\x1 ?\x61
-
- examples (2rd alternation = escaped):
- ?\n ?\b
-
- examples (3rd alternation = normal):
- ?a ?A ?0
- ?* ?" ?(
- ?. ?#
-
- the negative lookbehind prevents against matching
- p(42.tainted?)
- scope: constant.numeric.elixir
- - match: \+\+|\-\-|<\|>
- scope: keyword.operator.concatenation.elixir
- - match: \|\>|<~>|<>|<<<|>>>|~>>|<<~|~>|<~|<\|>
- scope: keyword.operator.sigils_1.elixir
- - match: "&&&|&&"
- scope: keyword.operator.sigils_2.elixir
- - match: <\-|\\\\
- scope: keyword.operator.sigils_3.elixir
- - match: "===?|!==?|<=?|>=?"
- scope: keyword.operator.comparison.elixir
- - match: (\|\|\||&&&|^^^|<<<|>>>|~~~)
- scope: keyword.operator.bitwise.elixir
- - match: '(?<=[ \t])!+|\bnot\b|&&|\band\b|\|\||\bor\b|\bxor\b'
- scope: keyword.operator.logical.elixir
- - match: (\*|\+|\-|/)
- scope: keyword.operator.arithmetic.elixir
- - match: \||\+\+|\-\-|\*\*|\\\\|\<\-|\<\>|\<\<|\>\>|\:\:|\.\.|\|>|~|=>|&
- scope: keyword.operator.other.elixir
- - match: "="
- scope: keyword.operator.assignment.elixir
- - match: ":"
- scope: punctuation.separator.other.elixir
- - match: \;
- scope: punctuation.separator.statement.elixir
- - match: ","
- scope: punctuation.separator.object.elixir
- - match: \.
- scope: punctuation.separator.method.elixir
- - match: '\{|\}'
- scope: punctuation.section.scope.elixir
- - match: '\[|\]'
- scope: punctuation.section.array.elixir
- - match: \(|\)
- scope: punctuation.section.function.elixir
- escaped_char:
- - match: '\\(x[\da-fA-F]{1,2}|.)'
- scope: constant.character.escaped.elixir
- interpolated_elixir:
- - match: '#\{(\})'
- scope: source.elixir.embedded.source
- captures:
- 0: punctuation.section.embedded.elixir
- 1: source.elixir.embedded.source.empty
- - match: '#\{'
- captures:
- 0: punctuation.section.embedded.elixir
- push:
- - meta_scope: source.elixir.embedded.source
- - match: '\}'
- captures:
- 0: punctuation.section.embedded.elixir
- pop: true
- - include: nest_curly_and_self
- - include: main
- nest_curly_and_self:
- - match: '\{'
- captures:
- 0: punctuation.section.scope.elixir
- push:
- - match: '\}'
- captures:
- 0: punctuation.section.scope.elixir
- pop: true
- - include: nest_curly_and_self
- - include: main
- regex_sub:
- - include: interpolated_elixir
- - include: escaped_char
- - match: '(\{)\d+(,\d+)?(\})'
- scope: string.regexp.arbitrary-repitition.elixir
- captures:
- 1: punctuation.definition.arbitrary-repitition.elixir
- 3: punctuation.definition.arbitrary-repitition.elixir
- - match: '\[(?:\^?\])?'
- captures:
- 0: punctuation.definition.character-class.elixir
- push:
- - meta_scope: string.regexp.character-class.elixir
- - match: '\]'
- captures:
- 0: punctuation.definition.character-class.elixir
- pop: true
- - include: escaped_char
- - match: \(
- captures:
- 0: punctuation.definition.group.elixir
- push:
- - meta_scope: string.regexp.group.elixir
- - match: \)
- captures:
- 0: punctuation.definition.group.elixir
- pop: true
- - include: regex_sub
- - match: '(?<=^|\s)(#)\s[[a-zA-Z0-9,. \t?!-][^\x{00}-\x{7F}]]*$'
- 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.
- scope: comment.line.number-sign.elixir
- captures:
- 1: punctuation.definition.comment.elixir
|