├── .gitignore ├── Symbols.JSON-tmPreferences ├── snippets ├── type.sublime-snippet ├── comment.sublime-snippet ├── mod.sublime-snippet ├── try.sublime-snippet ├── inlineComment.sublime-snippet ├── let.sublime-snippet ├── docblock.sublime-snippet └── switch.sublime-snippet ├── Comment.JSON-tmPreferences ├── Symbols.tmPreferences ├── Comment.tmPreferences ├── LICENSE.txt ├── README.md ├── bucklescript.sublime-syntax ├── Reason.JSON-tmLanguage └── Reason.tmLanguage /.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | -------------------------------------------------------------------------------- /Symbols.JSON-tmPreferences: -------------------------------------------------------------------------------- 1 | { "name": "Symbols", 2 | "scope": "meta.initialization.reason", 3 | "settings": {"showInSymbolList": 1}, 4 | "uuid": "d3270dd1-4ccd-428e-8dda-d3d20ee9fc7e" 5 | } -------------------------------------------------------------------------------- /snippets/type.sublime-snippet: -------------------------------------------------------------------------------- 1 | 2 | 5 | type 6 | source.reason 7 | 8 | -------------------------------------------------------------------------------- /snippets/comment.sublime-snippet: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | source.reason 7 | cmt 8 | // Comment 9 | 10 | -------------------------------------------------------------------------------- /snippets/mod.sublime-snippet: -------------------------------------------------------------------------------- 1 | 2 | 7 | mod 8 | source.reason 9 | 10 | -------------------------------------------------------------------------------- /snippets/try.sublime-snippet: -------------------------------------------------------------------------------- 1 | 2 | ${3:expression} 5 | } 6 | ]]> 7 | try 8 | source.reason 9 | 10 | -------------------------------------------------------------------------------- /snippets/inlineComment.sublime-snippet: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | source.reason 6 | ic 7 | /* inline Comment */ 8 | 9 | 10 | -------------------------------------------------------------------------------- /snippets/let.sublime-snippet: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | source.reason 8 | lt 9 | let x = …; 10 | 11 | -------------------------------------------------------------------------------- /snippets/docblock.sublime-snippet: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 7 | 8 | source.reason 9 | docb 10 | /** Docblock */ 11 | 12 | -------------------------------------------------------------------------------- /snippets/switch.sublime-snippet: -------------------------------------------------------------------------------- 1 | 2 | ${3:expression} 5 | ${4:| ${5:option2} => ${6:expression}} 6 | } 7 | ]]> 8 | switch 9 | source.reason 10 | 11 | -------------------------------------------------------------------------------- /Comment.JSON-tmPreferences: -------------------------------------------------------------------------------- 1 | { "name": "Comments", 2 | "scope": "source.reason", 3 | "settings": { 4 | "shellVariables": [{"name": "TM_COMMENT_START_2", "value": "// "}, 5 | {"name": "TM_COMMENT_DISABLE_INDENT", "value": "no"} 6 | ] 7 | }, 8 | "uuid": "e36d2f49-c7b0-42fe-b902-a0ed36a258ca" 9 | } 10 | -------------------------------------------------------------------------------- /Symbols.tmPreferences: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | name 6 | Symbols 7 | scope 8 | meta.initialization.reason 9 | settings 10 | 11 | showInSymbolList 12 | 1 13 | 14 | uuid 15 | d3270dd1-4ccd-428e-8dda-d3d20ee9fc7e 16 | 17 | 18 | -------------------------------------------------------------------------------- /Comment.tmPreferences: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | name 6 | Comments 7 | scope 8 | source.reason 9 | settings 10 | 11 | shellVariables 12 | 13 | 14 | name 15 | TM_COMMENT_START_2 16 | value 17 | // 18 | 19 | 20 | name 21 | TM_COMMENT_DISABLE_INDENT 22 | value 23 | no 24 | 25 | 26 | 27 | uuid 28 | e36d2f49-c7b0-42fe-b902-a0ed36a258ca 29 | 30 | 31 | -------------------------------------------------------------------------------- /LICENSE.txt: -------------------------------------------------------------------------------- 1 | Permission is hereby granted, free of charge, to any person obtaining a copy 2 | of this software and associated documentation files (the "Software"), to deal 3 | in the Software without restriction, including without limitation the rights 4 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 5 | copies of the Software, and to permit persons to whom the Software is 6 | furnished to do so, subject to the following conditions: 7 | 8 | The above copyright notice and this permission notice shall be included in 9 | all copies or substantial portions of the Software. 10 | 11 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 12 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 13 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 14 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 15 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 16 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 17 | THE SOFTWARE. -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Sublime Text package for [Reason](https://github.com/facebook/reason) 2 | 3 | To have the complete Sublime Text Reason experience, there are two plugins to install: this one, and [language-server](https://github.com/jaredly/reason-language-server). 4 | 5 | This one provides syntax highlight, snippets for Reason and allows related features to recognize the Reason syntax. 6 | 7 | Language-server provides all the others (autocompletion, type hint, jump-to-definition, etc.). 8 | 9 | ## This Plugin's Installation 10 | 11 | The plugin's [published on Package Control](https://packagecontrol.io/packages/Reason). 12 | 13 | - Go to Command Palette (`cmd-shift-p`) -> Package Control: Install Package. 14 | - Choose "Reason". 15 | 16 | ## Language Server Installation 17 | 18 | See https://github.com/jaredly/reason-language-server#sublime-text for language-server installation and configuration. 19 | 20 | If you're doing native development, instead of reason-language-server, you can try [ocaml-language-server](https://github.com/freebroccolo/ocaml-language-server#installation-1). 21 | 22 | ### Bonus Language Server Configuration 23 | 24 | In addition to the installation & configuration above, you might want to set some extra keyboard shortcuts. 25 | 26 | - Go to Command Palette (`cmd-shift-p`) -> Preferences: Key Bindings 27 | - Add the following to your configuration: 28 | 29 | ```json 30 | [ 31 | // ...whatevever config you had before 32 | { 33 | "keys": ["super+alt+enter"], 34 | "command": "lsp_symbol_definition", 35 | "context": [ 36 | { 37 | "key": "selector", 38 | "operator": "equal", 39 | "operand": ["source.reason"] 40 | } 41 | ] 42 | }, 43 | { 44 | "keys": ["super+shift+c"], 45 | "command": "lsp_format_document", 46 | "context": [ 47 | { 48 | "key": "selector", 49 | "operator": "equal", 50 | "operand": ["source.reason"] 51 | } 52 | ] 53 | } 54 | ] 55 | ``` 56 | 57 | `super` means `command` on macOS, so you can do e.g. `cmd-shift-c` to format your Reason files. 58 | 59 | [Here](https://github.com/tomv564/LSP/blob/master/Menus/Context.sublime-menu) are all the `command`s you can assign shortcuts to. 60 | 61 | # Develop This Package 62 | 63 | Thanks for the help! 64 | 65 | To test this package locally, do `Preferences: Browse Packages` and symlink this repo into `Packages/User`. Disable the existing Reason package, if any. 66 | 67 | Install [PackageDev](https://github.com/SublimeText/PackageDev), change whichever JSON file in the repo, then call `PackageDev: Convert ...` from the command palette and convert the file into the corresponding XML files. 68 | -------------------------------------------------------------------------------- /bucklescript.sublime-syntax: -------------------------------------------------------------------------------- 1 | %YAML 1.2 2 | --- 3 | name: BuckleScript 4 | file_extensions: [res, resi] 5 | scope: source.bucklescript 6 | 7 | variables: 8 | # copied over from reason-highlightjs 9 | # TODO: \"foo" ident 10 | RE_IDENT: '[a-z_][0-9a-zA-Z_]*' 11 | RE_ATTRIBUTE: '[A-Za-z_][A-Za-z0-9_\.]*' 12 | RE_MODULE_IDENT: '[A-Z_][0-9a-zA-Z_]*' 13 | 14 | # slightly different than reason-highlightjs 15 | RE_KEYWORDS: 16 | \b(and|as|assert|begin|class|constraint|done|downto|exception|external|fun|functor|inherit|lazy|let|pub|mutable|new|nonrec|object|of|or|pri|rec|then|to|val|virtual|try|catch|finally|do|else|for|if|switch|while|import|library|export|module|in|raise|private)\b 17 | RE_LITERAL: \b(true|false)\b 18 | 19 | contexts: 20 | 21 | commentLine: 22 | - match: //.* 23 | # TODO: append with file scope 24 | scope: comment.line 25 | 26 | commentBlock: 27 | - match: /\* 28 | push: 29 | - meta_scope: comment.block 30 | - match: \*/ 31 | pop: true 32 | 33 | punctuations: 34 | - match: ~ 35 | scope: punctuation.definition.keyword 36 | - match: ; 37 | scope: punctuation.terminator 38 | - match: \. 39 | scope: punctuation.accessor 40 | - match: \, 41 | scope: punctuation.separator 42 | # covers ternary. Wrong category but whatever 43 | - match: '\?|:' 44 | scope: punctuation.separator 45 | - match: \|(?!\|) 46 | scope: punctuation.separator 47 | - match: \{ 48 | scope: punctuation.section.braces.begin 49 | - match: \} 50 | scope: punctuation.section.braces.end 51 | - match: \( 52 | scope: punctuation.section.parens.begin 53 | - match: \) 54 | scope: punctuation.section.parens.end 55 | 56 | storage: 57 | - match: \btype\b 58 | scope: storage.type 59 | 60 | keyword: 61 | - match: '{{RE_KEYWORDS}}' 62 | scope: keyword 63 | 64 | constant: 65 | - match: '{{RE_LITERAL}}' 66 | scope: constant.language 67 | 68 | string: 69 | - match: '"' 70 | scope: punctuation.definition.string.begin 71 | push: 72 | - meta_scope: string.quoted.double 73 | - match: \\. 74 | scope: constant.character.escape 75 | - match: '"' 76 | scope: punctuation.definition.string.end 77 | pop: true 78 | - match: '({{RE_IDENT}})?(`)' 79 | captures: 80 | 1: variable.annotation 81 | 2: punctuation.definition.string.begin 82 | push: 83 | # different than reason-highlightjs, for now 84 | - meta_scope: string.quoted.other 85 | - match: '`' 86 | scope: punctuation.definition.string.end 87 | pop: true 88 | 89 | function: 90 | - match: => 91 | # first one is apparently for backward-compat 92 | scope: storage.type.function keyword.declaration.function 93 | 94 | character: 95 | - match: '''[\x00-\x7F]''' 96 | scope: string.quoted.single 97 | 98 | number: 99 | - match: 100 | \b(0[xX][a-fA-F0-9_]+[Lln]?|0[oO][0-7_]+[Lln]?|0[bB][01_]+[Lln]?|[0-9][0-9_]*([Lln]|(\.[0-9_]+)?([eE][-+]?[0-9_]+)?)?)\b 101 | scope: constant.numeric 102 | 103 | operator: 104 | - match: 105 | '->|\|\||&&|\+\+|\*\*|\+\.|\+|-\.|-|\*\.|\*|/\.|/|\.\.\.|\.\.|\|>|===|==|\^|:=|!|>=|<=' 106 | scope: keyword.operator 107 | 108 | assignment: 109 | - match: '=' 110 | scope: keyword.operator.assignment 111 | 112 | # doesn't contain ` unlike reason-highlightjs 113 | constructor: 114 | - match: '\b[A-Z][0-9a-zA-Z_]*\b' 115 | # won't mark and highlight this for now. This often shares the same 116 | # highlighting as entity.name.namespace (our module). We don't want 117 | # variant and modules confused 118 | # scope: entity.name.union 119 | scope: variable.function variable.other 120 | - match: '(#)[a-zA-Z][0-9a-zA-Z_]*\b' 121 | captures: 122 | 1: punctuation.definition.keyword 123 | 124 | array: 125 | - match: '\[' 126 | scope: punctuation.section.brackets.begin 127 | - match: '\]' 128 | scope: punctuation.section.brackets.end 129 | 130 | list: 131 | - match: '\b(list)(\[)' 132 | captures: 133 | 1: keyword 134 | 2: punctuation.section.brackets.begin 135 | - match: '\]' 136 | scope: punctuation.section.brackets.end 137 | 138 | objectAccess: 139 | - match: '\b{{RE_IDENT}}(\[)' 140 | captures: 141 | # technically this should be punctuation.accessor. But we don't wrap 142 | # the section, so we'll just conform to list and array brackets 143 | 1: punctuation.section.brackets.begin 144 | - match: '\]' 145 | scope: punctuation.section.brackets.end 146 | 147 | attribute: 148 | - match: '@@?' 149 | scope: storage.modifier punctuation.definition.annotation 150 | push: attributeContent 151 | - match: '%%?' 152 | scope: storage.modifier punctuation.definition.annotation 153 | push: attributeContent 154 | attributeContent: 155 | - meta_scope: meta.annotation 156 | # - match: '{{RE_ATTRIBUTE}} *\(' 157 | # scope: variable.annotation 158 | # push: 159 | # - match: \) 160 | # pop: true 161 | - match: '{{RE_ATTRIBUTE}}' 162 | scope: variable.annotation 163 | pop: true 164 | 165 | jsx: 166 | - match: '<>||/>' 167 | - match: ' (Bar: Baz) => List 218 | # Bar Bar 219 | # Bar 220 | # let a = Bar 221 | # ^ bail! Now this is bailing way too late, but that's ok for now 222 | - match: '(?=\S)' 223 | pop: true 224 | 225 | moduleDeclaration: 226 | - match: '\b(module)\s+(type\s+)?(of\s+)?({{RE_MODULE_IDENT}})' 227 | captures: 228 | 1: keyword 229 | 2: keyword 230 | 3: keyword 231 | 4: entity.name.namespace 232 | push: 233 | # and then an optional type signature is matched. Hopefully this regex 234 | # doesn't accidentally match something else 235 | - match: '\s*:\s*({{RE_MODULE_IDENT}})' 236 | captures: 237 | 1: entity.name.namespace 238 | - match: '\s*:\s*(\{)' 239 | captures: 240 | 1: punctuation.section.braces.begin 241 | push: moduleInner 242 | - match: '=' 243 | set: moduleRHS 244 | - match: '(?=\S)' 245 | pop: true 246 | 247 | moduleInner: 248 | - match: \} 249 | scope: punctuation.section.braces.end 250 | pop: true 251 | - include: main 252 | 253 | main: 254 | - include: storage 255 | - include: constant 256 | # these below are basically like reason-highlightjs 257 | - include: commentLine 258 | - include: commentBlock 259 | - include: character 260 | - include: string 261 | - include: attribute 262 | - include: function 263 | - include: list 264 | - include: objectAccess 265 | - include: array 266 | - include: jsx 267 | - include: operator 268 | - include: assignment 269 | - include: number 270 | - include: openOrIncludeModule 271 | - include: moduleDeclaration 272 | - include: moduleAccess 273 | - include: constructor 274 | # this is different than reason-highlightjs too 275 | - include: keyword 276 | - include: punctuations 277 | -------------------------------------------------------------------------------- /Reason.JSON-tmLanguage: -------------------------------------------------------------------------------- 1 | { "name": "Reason", 2 | "scopeName": "source.reason", 3 | "fileTypes": ["re", "rei"], 4 | "foldingStartMarker": "^.*\\bfun\\s*(\\w+\\s*)?\\([^\\)]*\\)(\\s*\\{[^\\}]*)?\\s*$", 5 | "foldingStopMarker": "^\\s*\\}", 6 | "patterns": [ 7 | {"include": "#reason_comment_doc_block"}, 8 | {"include": "#reason_comment_block"}, 9 | {"include": "#reason_comment"}, 10 | {"include": "#reason_named_arg"}, 11 | {"include": "#reason_module"}, 12 | {"include": "#reason_lifetime"}, 13 | {"include": "#reason_self"}, 14 | {"include": "#reason_string"}, 15 | {"include": "#reason_raw_string"}, 16 | { 17 | "name": "string.quoted.single.source.reason", 18 | "match": "\\'([^\\'\\\\]|\\\\(x[0-9A-Fa-f]{2}|u\\{[0-9A-Fa-f]{1,6}\\}|.))\\'" 19 | }, 20 | {"name": "meta.function.source.reason", 21 | "match": "\\b(fun)\\s+([a-zA-Z_][a-zA-Z0-9_]?[\\w\\:,+ \\'<>?]*)\\s*(?:\\()", 22 | "captures": { 23 | "1": {"name": "keyword.source.reason"}, 24 | "2": {"name": "entity.name.function.source.reason"} 25 | } 26 | }, 27 | { 28 | "name": "meta.initialization.reason", 29 | "match": "(let|and)\\s+(module\\s+)(rec\\s+)?([[:alpha:]_][[:alnum:]_]*)\\s*(:[^=]*)?(=?)", 30 | "captures": { 31 | "1": {"name": "keyword.source.reason"}, 32 | "2": {"name": "keyword.source.reason"}, 33 | "3": {"name": "keyword.source.reason"}, 34 | "4": {"name": "variable.other.reason"}, 35 | "5": {"name": "storage.type.source.reason"}, 36 | "6": {"name": "keyword.operator.reason"} 37 | }, 38 | "comment": "This matches the 'let x = val' style of variable intitialization." 39 | }, 40 | { 41 | "name": "meta.initialization.reason", 42 | "match": "(let)\\s+(rec\\s+)?([[:alpha:]_][[:alnum:]_]*)\\s*(:[^=]*)?(=?)", 43 | "captures": { 44 | "1": {"name": "keyword.source.reason"}, 45 | "2": {"name": "keyword.source.reason"}, 46 | "4": {"name": "storage.type.source.reason"}, 47 | "5": {"name": "keyword.operator.reason"} 48 | }, 49 | "comment": "This matches the 'let x = val' style of variable intitialization." 50 | }, 51 | { 52 | "name": "meta.import.reason", 53 | "match": "(extern\\s+crate)\\s+(\\w+)", 54 | "captures": { 55 | "1": {"name": "keyword.source.reason"}, 56 | "2": {"name": "support"} 57 | } 58 | }, 59 | { 60 | "name": "meta.macro.source.reason", 61 | "match": "\\b(macro_rules!)\\s+([a-zA-Z_][a-zA-Z0-9_]*)\\s*(?:\\{)", 62 | "captures": { 63 | "1": {"name": "keyword.source.reason"}, 64 | "2": {"name": "entity.name.macro.source.reason"} 65 | } 66 | }, 67 | {"name": "keyword.source.reason", 68 | "match": "\\b(as|box|break|claim|const|continue|copy|Copy|crate|do|drop|then|else|extern|for|if|impl|in|let|and|loop|switch|fun|open|include|mod|move|mutable|Owned|priv|pub|pure|ref|return|unsafe|use|while|mod|Send|static|trait|struct|enum|exception|type|module|rec|where)\\b" 69 | }, 70 | {"name": "storage.type.source.reason", 71 | "match": "\\b(Self|m32|m64|m128|f80|f16|f128|int|uint|isize|usize|float|char|bool|u8|u16|u32|u64|f32|f64|i8|i16|i32|i64|str|Option|Either|c_float|c_double|c_void|FILE|fpos_t|DIR|dirent|c_char|c_schar|c_uchar|c_short|c_ushort|c_int|c_uint|c_long|c_ulong|size_t|ptrdiff_t|clock_t|time_t|c_longlong|c_ulonglong|intptr_t|uintptr_t|off_t|dev_t|ino_t|pid_t|mode_t|ssize_t)\\b" 72 | }, 73 | {"name": "variable.language.source.reason", 74 | "match": "\\bself\\b" 75 | }, 76 | {"name": "constant.language.source.reason", 77 | "match": "\\b(true|false|Some|None|Ok|Err)\\b" 78 | }, 79 | {"name": "support.constant.source.reason", 80 | "match": "\\b(EXIT_FAILURE|EXIT_SUCCESS|RAND_MAX|EOF|SEEK_SET|SEEK_CUR|SEEK_END|_IOFBF|_IONBF|_IOLBF|BUFSIZ|FOPEN_MAX|FILENAME_MAX|L_tmpnam|TMP_MAX|O_RDONLY|O_WRONLY|O_RDWR|O_APPEND|O_CREAT|O_EXCL|O_TRUNC|S_IFIFO|S_IFCHR|S_IFBLK|S_IFDIR|S_IFREG|S_IFMT|S_IEXEC|S_IWRITE|S_IREAD|S_IRWXU|S_IXUSR|S_IWUSR|S_IRUSR|F_OK|R_OK|W_OK|X_OK|STDIN_FILENO|STDOUT_FILENO|STDERR_FILENO)\\b" 81 | }, 82 | {"name": "comment.block.attribute.reason", 83 | "begin": "#!?\\[", 84 | "end": "\\]", 85 | "patterns": [ 86 | {"include": "#reason_string"}, 87 | {"include": "#reason_raw_string"} 88 | ] 89 | }, 90 | {"name": "constant.numeric.integer.source.reason", 91 | "match": "\\b(([0-9][0-9_]*)|([0-9][0-9_]*(usize|u8|u16|u32|u64))|([0-9][0-9_]*(isize|i8|i16|i32|i64)))\\b" 92 | }, 93 | {"name": "constant.numeric.hex.source.reason", 94 | "match": "\\b((0x[a-fA-F0-9_]+)|(0x[a-fA-F0-9_]+(usize|u8|u16|u32|u64))|(0x[a-fA-F0-9_]+(isize|i8|i16|i32|i64)))\\b" 95 | }, 96 | {"name": "constant.numeric.binary.source.reason", 97 | "match": "\\b((0b[01_]+)|(0b[01_]+(usize|u8|u16|u32|u64))|(0b[01_]+(isize|i8|i16|i32|i64)))\\b" 98 | }, 99 | {"name": "constant.numeric.float.source.reason", 100 | "match": "\\b(([0-9][0-9_]*(f32|f64|f))|([0-9][0-9_]*([eE][+-]=[0-9_]+))|([0-9][0-9_]*([eE][+-]=[0-9_]+)(f32|f64|f))|([0-9][0-9_]*\\.[0-9_]+)|([0-9][0-9_]*\\.[0-9_]+(f32|f64|f))|([0-9][0-9_]*\\.[0-9_]+%([eE][+-]=[0-9_]+))|([0-9][0-9_]*\\.[0-9_]+%([eE][+-]=[0-9_]+)(f32|f64|f)))\\b" 101 | }, 102 | {"name": "keyword.operator.reason", 103 | "match": "(=>)|(->)|[-:=*,!.+|%/&~@<>;]" 104 | }, 105 | {"name": "support.function.reason", 106 | "match": "\\b_\\b" 107 | }, 108 | {"name": "support.function.reason", 109 | "match": "\\b(\\w+)\\b(?=\\()" 110 | }, 111 | {"name": "support.macro.reason", 112 | "match": "\\b(\\w+!)(?=\\()" 113 | }, 114 | {"name": "meta.namespace-block.reason", 115 | "match": "\\b(\\w+)::" 116 | }, 117 | { 118 | "name": "meta.macro.source.reason", 119 | "match": "\\b(\\w+!)\\s*[({\\[]", 120 | "captures": { 121 | "1": { "name": "meta.preprocessor.reason" } 122 | } 123 | }, 124 | {"match": "(\\[|\\]|{|}|\\(|\\))", 125 | "name": "punctuation.definition.bracket.reason" 126 | }, 127 | { 128 | "match": "\\b(Box|Vec|StrBuf|Path|Option|Result|Reader|Writer|Stream|Seek|Buffer|IoError|IoResult|Sender|SyncSender|Receiver|Cell|RefCell|Any)\\b", 129 | "name": "support.class.std.source.reason" 130 | }, 131 | { 132 | "match": "\\b(Send|Sized|Copy|Share)\\b", 133 | "name": "support.type.kind.source.reason" 134 | }, 135 | { 136 | "match": "\\bbox\\b", 137 | "name": "storage.modifier.box.source.reason" 138 | }, 139 | { 140 | "match": "\\brec\\b", 141 | "name": "storage.modifier.rec.source.reason" 142 | }, 143 | { 144 | "match": "\\bmodule\\b", 145 | "name": "storage.modifier.module.source.reason" 146 | } 147 | ], 148 | "repository": { 149 | "reason_escaped_character": { 150 | "name": "constant.character.escape.source.reason", 151 | "match": "\\\\(x[0-9A-Fa-f]{2}|u\\{[0-9A-Fa-f]{1,6}\\}|.)" 152 | }, 153 | "reason_string": { 154 | "name": "string.quoted.double.source.reason", 155 | "begin": "\"", 156 | "end": "\"", 157 | "patterns": [ 158 | {"include": "#reason_escaped_character"} 159 | ] 160 | }, 161 | "reason_raw_string": { 162 | "name": "string.quoted.double.raw.source.reason", 163 | "begin": "r(#*)\"", 164 | "end": "\"(\\1)" 165 | }, 166 | "reason_comment_block": { 167 | "name": "comment.block.source.reason", 168 | "begin": "/\\*", 169 | "end": "\\*/", 170 | "patterns": [ 171 | {"include": "#reason_comment_block"} 172 | ] 173 | }, 174 | "reason_comment": { 175 | "name": "comment.source.reason", 176 | "begin": "//", 177 | "end": "(?=^)" 178 | }, 179 | "reason_comment_doc_block": { 180 | "name": "comment.block.documentation.source.reason", 181 | "begin": "/\\*[!\\*][^\\*]", 182 | "end": "\\*/", 183 | "patterns": [ 184 | {"include": "#reason_comment_doc_block"} 185 | ] 186 | }, 187 | "reason_module": { 188 | "match": "\\b([A-Z][a-zA-Z0-9_]*)\\b", 189 | "captures": { 190 | "1": {"name": "variable.other.reason"} 191 | } 192 | }, 193 | "reason_named_arg": { 194 | "match": "(@([a-zA-Z_][a-zA-Z0-9_]*))\\b", 195 | "captures": { 196 | "1": { "name": "storage.modifier.lifetime.source.reason" }, 197 | "2": { "name": "entity.name.lifetime.source.reason" } 198 | } 199 | }, 200 | "reason_lifetime": { 201 | "name": "storage.modifier.lifetime.source.reason", 202 | "match": "\\'([a-zA-Z_][a-zA-Z0-9_]*)(?!\\')\\b", 203 | "captures": { 204 | "1": { "name": "entity.name.lifetime.source.reason" } 205 | } 206 | }, 207 | "reason_self": { 208 | "name": "variable.language.source.reason", 209 | "match": "\\bself\\b" 210 | } 211 | }, 212 | "uuid": "4339386b-4d67-4f0e-9e78-09ecbcddf71d" 213 | } 214 | -------------------------------------------------------------------------------- /Reason.tmLanguage: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | fileTypes 6 | 7 | re 8 | rei 9 | 10 | foldingStartMarker 11 | ^.*\bfun\s*(\w+\s*)?\([^\)]*\)(\s*\{[^\}]*)?\s*$ 12 | foldingStopMarker 13 | ^\s*\} 14 | name 15 | Reason 16 | patterns 17 | 18 | 19 | include 20 | #reason_comment_doc_block 21 | 22 | 23 | include 24 | #reason_comment_block 25 | 26 | 27 | include 28 | #reason_comment 29 | 30 | 31 | include 32 | #reason_named_arg 33 | 34 | 35 | include 36 | #reason_module 37 | 38 | 39 | include 40 | #reason_lifetime 41 | 42 | 43 | include 44 | #reason_self 45 | 46 | 47 | include 48 | #reason_string 49 | 50 | 51 | include 52 | #reason_raw_string 53 | 54 | 55 | match 56 | \'([^\'\\]|\\(x[0-9A-Fa-f]{2}|u\{[0-9A-Fa-f]{1,6}\}|.))\' 57 | name 58 | string.quoted.single.source.reason 59 | 60 | 61 | captures 62 | 63 | 1 64 | 65 | name 66 | keyword.source.reason 67 | 68 | 2 69 | 70 | name 71 | entity.name.function.source.reason 72 | 73 | 74 | match 75 | \b(fun)\s+([a-zA-Z_][a-zA-Z0-9_]?[\w\:,+ \'<>?]*)\s*(?:\() 76 | name 77 | meta.function.source.reason 78 | 79 | 80 | captures 81 | 82 | 1 83 | 84 | name 85 | keyword.source.reason 86 | 87 | 2 88 | 89 | name 90 | keyword.source.reason 91 | 92 | 3 93 | 94 | name 95 | keyword.source.reason 96 | 97 | 4 98 | 99 | name 100 | variable.other.reason 101 | 102 | 5 103 | 104 | name 105 | storage.type.source.reason 106 | 107 | 6 108 | 109 | name 110 | keyword.operator.reason 111 | 112 | 113 | comment 114 | This matches the 'let x = val' style of variable intitialization. 115 | match 116 | (let|and)\s+(module\s+)(rec\s+)?([[:alpha:]_][[:alnum:]_]*)\s*(:[^=]*)?(=?) 117 | name 118 | meta.initialization.reason 119 | 120 | 121 | captures 122 | 123 | 1 124 | 125 | name 126 | keyword.source.reason 127 | 128 | 2 129 | 130 | name 131 | keyword.source.reason 132 | 133 | 4 134 | 135 | name 136 | storage.type.source.reason 137 | 138 | 5 139 | 140 | name 141 | keyword.operator.reason 142 | 143 | 144 | comment 145 | This matches the 'let x = val' style of variable intitialization. 146 | match 147 | (let)\s+(rec\s+)?([[:alpha:]_][[:alnum:]_]*)\s*(:[^=]*)?(=?) 148 | name 149 | meta.initialization.reason 150 | 151 | 152 | captures 153 | 154 | 1 155 | 156 | name 157 | keyword.source.reason 158 | 159 | 2 160 | 161 | name 162 | support 163 | 164 | 165 | match 166 | (extern\s+crate)\s+(\w+) 167 | name 168 | meta.import.reason 169 | 170 | 171 | captures 172 | 173 | 1 174 | 175 | name 176 | keyword.source.reason 177 | 178 | 2 179 | 180 | name 181 | entity.name.macro.source.reason 182 | 183 | 184 | match 185 | \b(macro_rules!)\s+([a-zA-Z_][a-zA-Z0-9_]*)\s*(?:\{) 186 | name 187 | meta.macro.source.reason 188 | 189 | 190 | match 191 | \b(as|box|break|claim|const|continue|copy|Copy|crate|do|drop|then|else|extern|for|if|impl|in|let|and|loop|switch|fun|open|include|mod|move|mutable|Owned|priv|pub|pure|ref|return|unsafe|use|while|mod|Send|static|trait|struct|enum|exception|type|module|rec|where)\b 192 | name 193 | keyword.source.reason 194 | 195 | 196 | match 197 | \b(Self|m32|m64|m128|f80|f16|f128|int|uint|isize|usize|float|char|bool|u8|u16|u32|u64|f32|f64|i8|i16|i32|i64|str|Option|Either|c_float|c_double|c_void|FILE|fpos_t|DIR|dirent|c_char|c_schar|c_uchar|c_short|c_ushort|c_int|c_uint|c_long|c_ulong|size_t|ptrdiff_t|clock_t|time_t|c_longlong|c_ulonglong|intptr_t|uintptr_t|off_t|dev_t|ino_t|pid_t|mode_t|ssize_t)\b 198 | name 199 | storage.type.source.reason 200 | 201 | 202 | match 203 | \bself\b 204 | name 205 | variable.language.source.reason 206 | 207 | 208 | match 209 | \b(true|false|Some|None|Ok|Err)\b 210 | name 211 | constant.language.source.reason 212 | 213 | 214 | match 215 | \b(EXIT_FAILURE|EXIT_SUCCESS|RAND_MAX|EOF|SEEK_SET|SEEK_CUR|SEEK_END|_IOFBF|_IONBF|_IOLBF|BUFSIZ|FOPEN_MAX|FILENAME_MAX|L_tmpnam|TMP_MAX|O_RDONLY|O_WRONLY|O_RDWR|O_APPEND|O_CREAT|O_EXCL|O_TRUNC|S_IFIFO|S_IFCHR|S_IFBLK|S_IFDIR|S_IFREG|S_IFMT|S_IEXEC|S_IWRITE|S_IREAD|S_IRWXU|S_IXUSR|S_IWUSR|S_IRUSR|F_OK|R_OK|W_OK|X_OK|STDIN_FILENO|STDOUT_FILENO|STDERR_FILENO)\b 216 | name 217 | support.constant.source.reason 218 | 219 | 220 | begin 221 | #!?\[ 222 | end 223 | \] 224 | name 225 | comment.block.attribute.reason 226 | patterns 227 | 228 | 229 | include 230 | #reason_string 231 | 232 | 233 | include 234 | #reason_raw_string 235 | 236 | 237 | 238 | 239 | match 240 | \b(([0-9][0-9_]*)|([0-9][0-9_]*(usize|u8|u16|u32|u64))|([0-9][0-9_]*(isize|i8|i16|i32|i64)))\b 241 | name 242 | constant.numeric.integer.source.reason 243 | 244 | 245 | match 246 | \b((0x[a-fA-F0-9_]+)|(0x[a-fA-F0-9_]+(usize|u8|u16|u32|u64))|(0x[a-fA-F0-9_]+(isize|i8|i16|i32|i64)))\b 247 | name 248 | constant.numeric.hex.source.reason 249 | 250 | 251 | match 252 | \b((0b[01_]+)|(0b[01_]+(usize|u8|u16|u32|u64))|(0b[01_]+(isize|i8|i16|i32|i64)))\b 253 | name 254 | constant.numeric.binary.source.reason 255 | 256 | 257 | match 258 | \b(([0-9][0-9_]*(f32|f64|f))|([0-9][0-9_]*([eE][+-]=[0-9_]+))|([0-9][0-9_]*([eE][+-]=[0-9_]+)(f32|f64|f))|([0-9][0-9_]*\.[0-9_]+)|([0-9][0-9_]*\.[0-9_]+(f32|f64|f))|([0-9][0-9_]*\.[0-9_]+%([eE][+-]=[0-9_]+))|([0-9][0-9_]*\.[0-9_]+%([eE][+-]=[0-9_]+)(f32|f64|f)))\b 259 | name 260 | constant.numeric.float.source.reason 261 | 262 | 263 | match 264 | (=>)|(->)|[-:=*,!.+|%/&~@<>;] 265 | name 266 | keyword.operator.reason 267 | 268 | 269 | match 270 | \b_\b 271 | name 272 | support.function.reason 273 | 274 | 275 | match 276 | \b(\w+)\b(?=\() 277 | name 278 | support.function.reason 279 | 280 | 281 | match 282 | \b(\w+!)(?=\() 283 | name 284 | support.macro.reason 285 | 286 | 287 | match 288 | \b(\w+):: 289 | name 290 | meta.namespace-block.reason 291 | 292 | 293 | captures 294 | 295 | 1 296 | 297 | name 298 | meta.preprocessor.reason 299 | 300 | 301 | match 302 | \b(\w+!)\s*[({\[] 303 | name 304 | meta.macro.source.reason 305 | 306 | 307 | match 308 | (\[|\]|{|}|\(|\)) 309 | name 310 | punctuation.definition.bracket.reason 311 | 312 | 313 | match 314 | \b(Box|Vec|StrBuf|Path|Option|Result|Reader|Writer|Stream|Seek|Buffer|IoError|IoResult|Sender|SyncSender|Receiver|Cell|RefCell|Any)\b 315 | name 316 | support.class.std.source.reason 317 | 318 | 319 | match 320 | \b(Send|Sized|Copy|Share)\b 321 | name 322 | support.type.kind.source.reason 323 | 324 | 325 | match 326 | \bbox\b 327 | name 328 | storage.modifier.box.source.reason 329 | 330 | 331 | match 332 | \brec\b 333 | name 334 | storage.modifier.rec.source.reason 335 | 336 | 337 | match 338 | \bmodule\b 339 | name 340 | storage.modifier.module.source.reason 341 | 342 | 343 | repository 344 | 345 | reason_comment 346 | 347 | begin 348 | // 349 | end 350 | (?=^) 351 | name 352 | comment.source.reason 353 | 354 | reason_comment_block 355 | 356 | begin 357 | /\* 358 | end 359 | \*/ 360 | name 361 | comment.block.source.reason 362 | patterns 363 | 364 | 365 | include 366 | #reason_comment_block 367 | 368 | 369 | 370 | reason_comment_doc_block 371 | 372 | begin 373 | /\*[!\*][^\*] 374 | end 375 | \*/ 376 | name 377 | comment.block.documentation.source.reason 378 | patterns 379 | 380 | 381 | include 382 | #reason_comment_doc_block 383 | 384 | 385 | 386 | reason_escaped_character 387 | 388 | match 389 | \\(x[0-9A-Fa-f]{2}|u\{[0-9A-Fa-f]{1,6}\}|.) 390 | name 391 | constant.character.escape.source.reason 392 | 393 | reason_lifetime 394 | 395 | captures 396 | 397 | 1 398 | 399 | name 400 | entity.name.lifetime.source.reason 401 | 402 | 403 | match 404 | \'([a-zA-Z_][a-zA-Z0-9_]*)(?!\')\b 405 | name 406 | storage.modifier.lifetime.source.reason 407 | 408 | reason_module 409 | 410 | captures 411 | 412 | 1 413 | 414 | name 415 | variable.other.reason 416 | 417 | 418 | match 419 | \b([A-Z][a-zA-Z0-9_]*)\b 420 | 421 | reason_named_arg 422 | 423 | captures 424 | 425 | 1 426 | 427 | name 428 | storage.modifier.lifetime.source.reason 429 | 430 | 2 431 | 432 | name 433 | entity.name.lifetime.source.reason 434 | 435 | 436 | match 437 | (@([a-zA-Z_][a-zA-Z0-9_]*))\b 438 | 439 | reason_raw_string 440 | 441 | begin 442 | r(#*)" 443 | end 444 | "(\1) 445 | name 446 | string.quoted.double.raw.source.reason 447 | 448 | reason_self 449 | 450 | match 451 | \bself\b 452 | name 453 | variable.language.source.reason 454 | 455 | reason_string 456 | 457 | begin 458 | " 459 | end 460 | " 461 | name 462 | string.quoted.double.source.reason 463 | patterns 464 | 465 | 466 | include 467 | #reason_escaped_character 468 | 469 | 470 | 471 | 472 | scopeName 473 | source.reason 474 | uuid 475 | 4339386b-4d67-4f0e-9e78-09ecbcddf71d 476 | 477 | 478 | --------------------------------------------------------------------------------