├── .github └── workflows │ └── main.yml ├── .gitignore ├── .vscode ├── launch.json └── tasks.json ├── .vscodeignore ├── CHANGELOG.md ├── LICENSE.txt ├── README.md ├── gulpfile.js ├── images └── icon.png ├── language-configuration.json ├── package-lock.json ├── package.json ├── syntaxes ├── rust.tmLanguage.json └── rust.tmLanguage.yml └── test ├── test.rs └── test_line_comment.rs /.github/workflows/main.yml: -------------------------------------------------------------------------------- 1 | name: CI 2 | on: 3 | push: 4 | branches: [main, dev] 5 | pull_request: 6 | branches: [main, dev] 7 | jobs: 8 | test: 9 | runs-on: ubuntu-latest 10 | steps: 11 | - uses: actions/checkout@v2 12 | - name: run Textmate scope tests 13 | # use the same version of vscode-tmgrammar-test as in package.lock.json 14 | run: npx vscode-tmgrammar-test@0.1.1 "./test/**/*.rs" --compact --grammar ./syntaxes/rust.tmLanguage.json 15 | build: 16 | runs-on: ubuntu-latest 17 | steps: 18 | - uses: actions/checkout@v2 19 | - name: package extension 20 | run: npx vsce package 21 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | *.afdesign 2 | *.vsix 3 | refs/ 4 | node_modules 5 | -------------------------------------------------------------------------------- /.vscode/launch.json: -------------------------------------------------------------------------------- 1 | // A launch configuration that launches the extension inside a new window 2 | // Use IntelliSense to learn about possible attributes. 3 | // Hover to view descriptions of existing attributes. 4 | // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 5 | { 6 | "version": "0.2.0", 7 | "configurations": [ 8 | { 9 | "name": "Extension", 10 | "type": "extensionHost", 11 | "request": "launch", 12 | "runtimeExecutable": "${execPath}", 13 | "args": [ 14 | "--extensionDevelopmentPath=${workspaceFolder}" 15 | ] 16 | } 17 | ] 18 | } -------------------------------------------------------------------------------- /.vscode/tasks.json: -------------------------------------------------------------------------------- 1 | { 2 | "version": "2.0.0", 3 | "tasks": [ 4 | { 5 | "label": "Gulp watch: YAML -> JSON", 6 | "type": "gulp", 7 | "task": "watch-yaml", 8 | "runOptions": { 9 | "runOn": "folderOpen" 10 | }, 11 | "problemMatcher": [], 12 | "group": { 13 | "kind": "build", 14 | "isDefault": true 15 | }, 16 | "presentation": { 17 | "clear": false, 18 | "echo": true, 19 | "focus": false, 20 | "panel": "shared", 21 | "reveal": "silent", 22 | "showReuseMessage": true 23 | } 24 | }, 25 | { 26 | "label": "Test TM scopes", 27 | "type": "npm", 28 | "script": "test", 29 | "detail": "npm run test-TM-scope", 30 | "group": { 31 | "kind": "test", 32 | "isDefault": true 33 | }, 34 | "presentation": { 35 | "clear": true, 36 | "echo": true, 37 | "focus": false, 38 | "panel": "shared", 39 | "reveal": "always", 40 | "showReuseMessage": true 41 | }, 42 | "problemMatcher": { 43 | "fileLocation": [ 44 | "relative", 45 | "${workspaceFolder}" 46 | ], 47 | "pattern": [ 48 | { 49 | "regexp": "^(ERROR)\\s([^:]+):(\\d+):(\\d+):(\\d+)\\s(.*)$", 50 | "severity": 1, 51 | "file": 2, 52 | "line": 3, 53 | "column": 4, 54 | "endColumn": 5, 55 | "message": 6 56 | } 57 | ] 58 | } 59 | } 60 | ] 61 | } 62 | -------------------------------------------------------------------------------- /.vscodeignore: -------------------------------------------------------------------------------- 1 | .gitignore 2 | .vscode-test/** 3 | .vscode/** 4 | rust.tmLanguage.yaml 5 | vsc-extension-quickstart.md 6 | -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # Change Log 2 | 3 | Notable changes to the Rust Syntax extension will be documented in this file. 4 | 5 | ## **[0.5.0]:** 2021-06-09 6 | 7 | - allow granular targeting of `storage.type` scopes by adding `keyword` scopes (thanks to @a5hk) 8 | 9 | ## **[0.4.0]:** 2020-11-10 10 | 11 | - add a stub for future scope tests 12 | - add dev dependencies and a CI workflow for contributors 13 | 14 | ## **[0.3.0]:** 2020-11-08 15 | 16 | - more conventional keyword scopes (thanks: @cynecx) 17 | - many interval patch fixes (ranges, angle brackets, operator precedence, turbofish, comments, raw strings) 18 | 19 | ## **[0.2.0]:** 2020-10-10 20 | 21 | - move non-control keywords into `storage` and `keyword.other` 22 | - bundle macro bangs into macro scopes 23 | - unique scope for `macro_rules` 24 | 25 | ## **[0.1.2]:** 2020-10-03 26 | 27 | - change to a single meta scope inside string interpolations 28 | 29 | ## **[0.1.0]:** 2020-09-26 30 | 31 | - Initial release 32 | -------------------------------------------------------------------------------- /LICENSE.txt: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2020 Dustin Pomerleau 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Rust Syntax 2 | 3 | This extension provides a TextMate grammar for Rust. This grammar is 4 | used for VS Code's built-in Rust syntax highlighting 5 | ([source](https://github.com/microsoft/vscode/blob/main/extensions/rust/syntaxes/rust.tmLanguage.json)). 6 | 7 | Issues and PRs should be submitted here, and [VS Code syncs this repo regularly](https://github.com/microsoft/vscode/pull/194758#issuecomment-1748526176). 8 | 9 | The semantic highlighting provided by [Rust 10 | Analyzer](https://marketplace.visualstudio.com/items?itemName=matklad.rust-analyzer) 11 | is more precise than this grammar. For example, semantic highlighting can easily 12 | distinguish enums, structs, and traits. 13 | 14 | For best results, install Rust Analyzer to benefit from both. 15 | 16 | Rust Syntax is compatible with Rust Analyzer, but the scopes provided 17 | by this extension will not be visible while semantic highlighting is 18 | enabled. If for some reason you would like to disable semantic 19 | highlighting, you can do this in your `settings.json`: 20 | 21 | ```json 22 | "[rust]": { 23 | "editor.semanticHighlighting.enabled": false 24 | } 25 | ``` 26 | 27 | ## Compatibility 28 | 29 | Not all themes are specifically optimized for Rust. 30 | We have tried to provide sensible default scopes that will work with most themes. 31 | If you want to modify the colors in a particular theme, you can do so in your `settings.json`: 32 | 33 | ```json 34 | "editor.tokenColorCustomizations": { 35 | "[Theme Name]": { 36 | "textMateRules": [ 37 | { 38 | "scope": "variable.other.rust", 39 | "settings": { 40 | "foreground": "#ffff00" 41 | } 42 | } 43 | ] 44 | } 45 | } 46 | ``` 47 | 48 | The VS Code command `Developer: Inspect Editor Tokens and Scopes` will show you the scope stack at the current cursor position. 49 | 50 | ## Contributing 51 | 52 | The grammar is maintained as YAML, using tasks to generate JSON on save (please don't edit the JSON grammar directly). 53 | 54 | ```sh 55 | npm install 56 | 57 | # Watch for changes of YAML files and regenerate JSON 58 | npm start 59 | 60 | # Run tests 61 | npm test 62 | ``` 63 | 64 | If you are using VS Code, you can use the `Tasks: Run Build Task` command from the command palette to run the gulp task. And you can use the `Tasks: Run Test Task` command to run the tests. 65 | -------------------------------------------------------------------------------- /gulpfile.js: -------------------------------------------------------------------------------- 1 | var gulp = require('gulp') 2 | var yaml = require('gulp-yaml') 3 | 4 | gulp.task('yaml', function(cb) { 5 | gulp 6 | .src('./syntaxes/*.yml') 7 | .pipe(yaml({ safe: false, space: 4 })) 8 | .pipe( 9 | gulp.dest(function (f) { 10 | return f.base 11 | }) 12 | ) 13 | cb() 14 | }) 15 | 16 | gulp.task( 17 | 'watch-yaml', 18 | gulp.series('yaml', function(cb) { 19 | gulp.watch('./syntaxes/*.yml', gulp.series('yaml')) 20 | cb() 21 | }) 22 | ) 23 | -------------------------------------------------------------------------------- /images/icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dustypomerleau/rust-syntax/0c24ff211d8a239f8b96d4c646d607a8bf645f78/images/icon.png -------------------------------------------------------------------------------- /language-configuration.json: -------------------------------------------------------------------------------- 1 | { 2 | "comments": { 3 | // symbol used for single line comment. Remove this entry if your language does not support line comments 4 | "lineComment": "//", 5 | // symbols used for start and end a block comment. Remove this entry if your language does not support block comments 6 | "blockComment": [ "/*", "*/" ] 7 | }, 8 | // symbols used as brackets 9 | "brackets": [ 10 | ["{", "}"], 11 | ["[", "]"], 12 | ["(", ")"] 13 | ], 14 | // symbols that are auto closed when typing 15 | "autoClosingPairs": [ 16 | ["{", "}"], 17 | ["[", "]"], 18 | ["(", ")"], 19 | ["\"", "\""], 20 | ["'", "'"] 21 | ], 22 | // symbols that can be used to surround a selection 23 | "surroundingPairs": [ 24 | ["{", "}"], 25 | ["[", "]"], 26 | ["(", ")"], 27 | ["\"", "\""], 28 | ["'", "'"] 29 | ] 30 | } -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "rust-syntax", 3 | "displayName": "Rust Syntax", 4 | "version": "0.6.1", 5 | "description": "Improved Rust syntax highlighting", 6 | "publisher": "dustypomerleau", 7 | "homepage": "https://github.com/dustypomerleau/rust-syntax", 8 | "author": { 9 | "name": "dustypomerleau" 10 | }, 11 | "scripts": { 12 | "start": "npx gulp watch-yaml", 13 | "test": "npm run test-TM-scope", 14 | "test-TM-scope": "npx vscode-tmgrammar-test \"./test/**/test*.rs\" --compact --grammar ./syntaxes/rust.tmLanguage.json" 15 | }, 16 | "repository": { 17 | "type": "git", 18 | "url": "https://github.com/dustypomerleau/rust-syntax" 19 | }, 20 | "bugs": { 21 | "url": "https://github.com/dustypomerleau/rust-syntax/issues" 22 | }, 23 | "license": "Please see LICENSE.txt", 24 | "galleryBanner": { 25 | "color": "#292d3e", 26 | "theme": "dark" 27 | }, 28 | "icon": "images/icon.png", 29 | "categories": [ 30 | "Programming Languages" 31 | ], 32 | "keywords": [ 33 | "rust", 34 | "language", 35 | "syntax", 36 | "grammar", 37 | "highlighting" 38 | ], 39 | "contributes": { 40 | "grammars": [ 41 | { 42 | "language": "rust", 43 | "scopeName": "source.rust", 44 | "path": "./syntaxes/rust.tmLanguage.json" 45 | } 46 | ] 47 | }, 48 | "devDependencies": { 49 | "gulp": "^5.0.0", 50 | "gulp-yaml": "^2.0.4", 51 | "js-yaml": "^4.1.0", 52 | "vsce": "^2.9.2", 53 | "vscode-tmgrammar-test": "^0.1.1" 54 | }, 55 | "engines": { 56 | "vscode": "^1.44.0" 57 | } 58 | } 59 | -------------------------------------------------------------------------------- /syntaxes/rust.tmLanguage.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "https://raw.githubusercontent.com/martinring/tmlanguage/master/tmlanguage.json", 3 | "name": "Rust", 4 | "fileTypes": [ 5 | "rs" 6 | ], 7 | "scopeName": "source.rust", 8 | "patterns": [ 9 | { 10 | "comment": "boxed slice literal", 11 | "begin": "(<)(\\[)", 12 | "beginCaptures": { 13 | "1": { 14 | "name": "punctuation.brackets.angle.rust" 15 | }, 16 | "2": { 17 | "name": "punctuation.brackets.square.rust" 18 | } 19 | }, 20 | "end": ">", 21 | "endCaptures": { 22 | "0": { 23 | "name": "punctuation.brackets.angle.rust" 24 | } 25 | }, 26 | "patterns": [ 27 | { 28 | "include": "#block-comments" 29 | }, 30 | { 31 | "include": "#comments" 32 | }, 33 | { 34 | "include": "#gtypes" 35 | }, 36 | { 37 | "include": "#lvariables" 38 | }, 39 | { 40 | "include": "#lifetimes" 41 | }, 42 | { 43 | "include": "#punctuation" 44 | }, 45 | { 46 | "include": "#types" 47 | } 48 | ] 49 | }, 50 | { 51 | "comment": "macro type metavariables", 52 | "name": "meta.macro.metavariable.type.rust", 53 | "match": "(\\$)((crate)|([A-Z]\\w*))(\\s*(:)\\s*(block|expr(?:_2021)?|ident|item|lifetime|literal|meta|pat(?:_param)?|path|stmt|tt|ty|vis)\\b)?", 54 | "captures": { 55 | "1": { 56 | "name": "keyword.operator.macro.dollar.rust" 57 | }, 58 | "3": { 59 | "name": "keyword.other.crate.rust" 60 | }, 61 | "4": { 62 | "name": "entity.name.type.metavariable.rust" 63 | }, 64 | "6": { 65 | "name": "keyword.operator.key-value.rust" 66 | }, 67 | "7": { 68 | "name": "variable.other.metavariable.specifier.rust" 69 | } 70 | }, 71 | "patterns": [ 72 | { 73 | "include": "#keywords" 74 | } 75 | ] 76 | }, 77 | { 78 | "comment": "macro metavariables", 79 | "name": "meta.macro.metavariable.rust", 80 | "match": "(\\$)([a-z]\\w*)(\\s*(:)\\s*(block|expr(?:_2021)?|ident|item|lifetime|literal|meta|pat(?:_param)?|path|stmt|tt|ty|vis)\\b)?", 81 | "captures": { 82 | "1": { 83 | "name": "keyword.operator.macro.dollar.rust" 84 | }, 85 | "2": { 86 | "name": "variable.other.metavariable.name.rust" 87 | }, 88 | "4": { 89 | "name": "keyword.operator.key-value.rust" 90 | }, 91 | "5": { 92 | "name": "variable.other.metavariable.specifier.rust" 93 | } 94 | }, 95 | "patterns": [ 96 | { 97 | "include": "#keywords" 98 | } 99 | ] 100 | }, 101 | { 102 | "comment": "macro rules", 103 | "name": "meta.macro.rules.rust", 104 | "match": "\\b(macro_rules!)\\s+(([a-z0-9_]+)|([A-Z][a-z0-9_]*))\\s+(\\{)", 105 | "captures": { 106 | "1": { 107 | "name": "entity.name.function.macro.rules.rust" 108 | }, 109 | "3": { 110 | "name": "entity.name.function.macro.rust" 111 | }, 112 | "4": { 113 | "name": "entity.name.type.macro.rust" 114 | }, 115 | "5": { 116 | "name": "punctuation.brackets.curly.rust" 117 | } 118 | } 119 | }, 120 | { 121 | "comment": "modules", 122 | "match": "(mod)\\s+((?:r#(?!crate|[Ss]elf|super))?[a-z][A-Za-z0-9_]*)", 123 | "captures": { 124 | "1": { 125 | "name": "storage.type.rust" 126 | }, 127 | "2": { 128 | "name": "entity.name.module.rust" 129 | } 130 | } 131 | }, 132 | { 133 | "comment": "external crate imports", 134 | "name": "meta.import.rust", 135 | "begin": "\\b(extern)\\s+(crate)", 136 | "beginCaptures": { 137 | "1": { 138 | "name": "storage.type.rust" 139 | }, 140 | "2": { 141 | "name": "keyword.other.crate.rust" 142 | } 143 | }, 144 | "end": ";", 145 | "endCaptures": { 146 | "0": { 147 | "name": "punctuation.semi.rust" 148 | } 149 | }, 150 | "patterns": [ 151 | { 152 | "include": "#block-comments" 153 | }, 154 | { 155 | "include": "#comments" 156 | }, 157 | { 158 | "include": "#keywords" 159 | }, 160 | { 161 | "include": "#punctuation" 162 | } 163 | ] 164 | }, 165 | { 166 | "comment": "use statements", 167 | "name": "meta.use.rust", 168 | "begin": "\\b(use)\\s", 169 | "beginCaptures": { 170 | "1": { 171 | "name": "keyword.other.rust" 172 | } 173 | }, 174 | "end": ";", 175 | "endCaptures": { 176 | "0": { 177 | "name": "punctuation.semi.rust" 178 | } 179 | }, 180 | "patterns": [ 181 | { 182 | "include": "#block-comments" 183 | }, 184 | { 185 | "include": "#comments" 186 | }, 187 | { 188 | "include": "#keywords" 189 | }, 190 | { 191 | "include": "#namespaces" 192 | }, 193 | { 194 | "include": "#punctuation" 195 | }, 196 | { 197 | "include": "#types" 198 | }, 199 | { 200 | "include": "#lvariables" 201 | } 202 | ] 203 | }, 204 | { 205 | "include": "#block-comments" 206 | }, 207 | { 208 | "include": "#comments" 209 | }, 210 | { 211 | "include": "#attributes" 212 | }, 213 | { 214 | "include": "#lvariables" 215 | }, 216 | { 217 | "include": "#constants" 218 | }, 219 | { 220 | "include": "#gtypes" 221 | }, 222 | { 223 | "include": "#functions" 224 | }, 225 | { 226 | "include": "#types" 227 | }, 228 | { 229 | "include": "#keywords" 230 | }, 231 | { 232 | "include": "#lifetimes" 233 | }, 234 | { 235 | "include": "#macros" 236 | }, 237 | { 238 | "include": "#namespaces" 239 | }, 240 | { 241 | "include": "#punctuation" 242 | }, 243 | { 244 | "include": "#strings" 245 | }, 246 | { 247 | "include": "#variables" 248 | } 249 | ], 250 | "repository": { 251 | "comments": { 252 | "patterns": [ 253 | { 254 | "comment": "documentation comments", 255 | "name": "comment.line.documentation.rust", 256 | "match": "(///).*$", 257 | "captures": { 258 | "1": { 259 | "name": "punctuation.definition.comment.rust" 260 | } 261 | } 262 | }, 263 | { 264 | "comment": "line comments", 265 | "name": "comment.line.double-slash.rust", 266 | "match": "(//).*$", 267 | "captures": { 268 | "1": { 269 | "name": "punctuation.definition.comment.rust" 270 | } 271 | } 272 | } 273 | ] 274 | }, 275 | "block-comments": { 276 | "patterns": [ 277 | { 278 | "comment": "empty block comments", 279 | "name": "comment.block.rust", 280 | "match": "/\\*\\*/" 281 | }, 282 | { 283 | "comment": "block documentation comments", 284 | "name": "comment.block.documentation.rust", 285 | "begin": "/\\*\\*", 286 | "end": "\\*/", 287 | "patterns": [ 288 | { 289 | "include": "#block-comments" 290 | } 291 | ] 292 | }, 293 | { 294 | "comment": "block comments", 295 | "name": "comment.block.rust", 296 | "begin": "/\\*(?!\\*)", 297 | "end": "\\*/", 298 | "patterns": [ 299 | { 300 | "include": "#block-comments" 301 | } 302 | ] 303 | } 304 | ] 305 | }, 306 | "constants": { 307 | "patterns": [ 308 | { 309 | "comment": "ALL CAPS constants", 310 | "name": "constant.other.caps.rust", 311 | "match": "\\b[A-Z]{2}[A-Z0-9_]*\\b" 312 | }, 313 | { 314 | "comment": "constant declarations", 315 | "match": "\\b(const)\\s+([A-Z][A-Za-z0-9_]*)\\b", 316 | "captures": { 317 | "1": { 318 | "name": "storage.type.rust" 319 | }, 320 | "2": { 321 | "name": "constant.other.caps.rust" 322 | } 323 | } 324 | }, 325 | { 326 | "comment": "decimal integers and floats", 327 | "name": "constant.numeric.decimal.rust", 328 | "match": "\\b\\d[\\d_]*(\\.?)[\\d_]*(?:(E|e)([+-]?)([\\d_]+))?(f32|f64|i128|i16|i32|i64|i8|isize|u128|u16|u32|u64|u8|usize)?\\b", 329 | "captures": { 330 | "1": { 331 | "name": "punctuation.separator.dot.decimal.rust" 332 | }, 333 | "2": { 334 | "name": "keyword.operator.exponent.rust" 335 | }, 336 | "3": { 337 | "name": "keyword.operator.exponent.sign.rust" 338 | }, 339 | "4": { 340 | "name": "constant.numeric.decimal.exponent.mantissa.rust" 341 | }, 342 | "5": { 343 | "name": "entity.name.type.numeric.rust" 344 | } 345 | } 346 | }, 347 | { 348 | "comment": "hexadecimal integers", 349 | "name": "constant.numeric.hex.rust", 350 | "match": "\\b0x[\\da-fA-F_]+(i128|i16|i32|i64|i8|isize|u128|u16|u32|u64|u8|usize)?\\b", 351 | "captures": { 352 | "1": { 353 | "name": "entity.name.type.numeric.rust" 354 | } 355 | } 356 | }, 357 | { 358 | "comment": "octal integers", 359 | "name": "constant.numeric.oct.rust", 360 | "match": "\\b0o[0-7_]+(i128|i16|i32|i64|i8|isize|u128|u16|u32|u64|u8|usize)?\\b", 361 | "captures": { 362 | "1": { 363 | "name": "entity.name.type.numeric.rust" 364 | } 365 | } 366 | }, 367 | { 368 | "comment": "binary integers", 369 | "name": "constant.numeric.bin.rust", 370 | "match": "\\b0b[01_]+(i128|i16|i32|i64|i8|isize|u128|u16|u32|u64|u8|usize)?\\b", 371 | "captures": { 372 | "1": { 373 | "name": "entity.name.type.numeric.rust" 374 | } 375 | } 376 | }, 377 | { 378 | "comment": "booleans", 379 | "name": "constant.language.bool.rust", 380 | "match": "\\b(true|false)\\b" 381 | } 382 | ] 383 | }, 384 | "escapes": { 385 | "comment": "escapes: ASCII, byte, Unicode, quote, regex", 386 | "name": "constant.character.escape.rust", 387 | "match": "(\\\\)(?:(?:(x[0-7][\\da-fA-F])|(u(\\{)[\\da-fA-F]{4,6}(\\}))|.))", 388 | "captures": { 389 | "1": { 390 | "name": "constant.character.escape.backslash.rust" 391 | }, 392 | "2": { 393 | "name": "constant.character.escape.bit.rust" 394 | }, 395 | "3": { 396 | "name": "constant.character.escape.unicode.rust" 397 | }, 398 | "4": { 399 | "name": "constant.character.escape.unicode.punctuation.rust" 400 | }, 401 | "5": { 402 | "name": "constant.character.escape.unicode.punctuation.rust" 403 | } 404 | } 405 | }, 406 | "attributes": { 407 | "comment": "attributes", 408 | "name": "meta.attribute.rust", 409 | "begin": "(#)(\\!?)(\\[)", 410 | "beginCaptures": { 411 | "1": { 412 | "name": "punctuation.definition.attribute.rust" 413 | }, 414 | "3": { 415 | "name": "punctuation.brackets.attribute.rust" 416 | } 417 | }, 418 | "end": "\\]", 419 | "endCaptures": { 420 | "0": { 421 | "name": "punctuation.brackets.attribute.rust" 422 | } 423 | }, 424 | "patterns": [ 425 | { 426 | "include": "#block-comments" 427 | }, 428 | { 429 | "include": "#comments" 430 | }, 431 | { 432 | "include": "#keywords" 433 | }, 434 | { 435 | "include": "#lifetimes" 436 | }, 437 | { 438 | "include": "#punctuation" 439 | }, 440 | { 441 | "include": "#strings" 442 | }, 443 | { 444 | "include": "#gtypes" 445 | }, 446 | { 447 | "include": "#types" 448 | } 449 | ] 450 | }, 451 | "functions": { 452 | "patterns": [ 453 | { 454 | "comment": "pub as a function", 455 | "match": "\\b(pub)(\\()", 456 | "captures": { 457 | "1": { 458 | "name": "keyword.other.rust" 459 | }, 460 | "2": { 461 | "name": "punctuation.brackets.round.rust" 462 | } 463 | } 464 | }, 465 | { 466 | "comment": "function definition", 467 | "name": "meta.function.definition.rust", 468 | "begin": "\\b(fn)\\s+((?:r#(?!crate|[Ss]elf|super))?[A-Za-z0-9_]+)((\\()|(<))", 469 | "beginCaptures": { 470 | "1": { 471 | "name": "keyword.other.fn.rust" 472 | }, 473 | "2": { 474 | "name": "entity.name.function.rust" 475 | }, 476 | "4": { 477 | "name": "punctuation.brackets.round.rust" 478 | }, 479 | "5": { 480 | "name": "punctuation.brackets.angle.rust" 481 | } 482 | }, 483 | "end": "(\\{)|(;)", 484 | "endCaptures": { 485 | "1": { 486 | "name": "punctuation.brackets.curly.rust" 487 | }, 488 | "2": { 489 | "name": "punctuation.semi.rust" 490 | } 491 | }, 492 | "patterns": [ 493 | { 494 | "include": "#block-comments" 495 | }, 496 | { 497 | "include": "#comments" 498 | }, 499 | { 500 | "include": "#keywords" 501 | }, 502 | { 503 | "include": "#lvariables" 504 | }, 505 | { 506 | "include": "#constants" 507 | }, 508 | { 509 | "include": "#gtypes" 510 | }, 511 | { 512 | "include": "#functions" 513 | }, 514 | { 515 | "include": "#lifetimes" 516 | }, 517 | { 518 | "include": "#macros" 519 | }, 520 | { 521 | "include": "#namespaces" 522 | }, 523 | { 524 | "include": "#punctuation" 525 | }, 526 | { 527 | "include": "#strings" 528 | }, 529 | { 530 | "include": "#types" 531 | }, 532 | { 533 | "include": "#variables" 534 | } 535 | ] 536 | }, 537 | { 538 | "comment": "function/method calls, chaining", 539 | "name": "meta.function.call.rust", 540 | "begin": "((?:r#(?!crate|[Ss]elf|super))?[A-Za-z0-9_]+)(\\()", 541 | "beginCaptures": { 542 | "1": { 543 | "name": "entity.name.function.rust" 544 | }, 545 | "2": { 546 | "name": "punctuation.brackets.round.rust" 547 | } 548 | }, 549 | "end": "\\)", 550 | "endCaptures": { 551 | "0": { 552 | "name": "punctuation.brackets.round.rust" 553 | } 554 | }, 555 | "patterns": [ 556 | { 557 | "include": "#block-comments" 558 | }, 559 | { 560 | "include": "#comments" 561 | }, 562 | { 563 | "include": "#attributes" 564 | }, 565 | { 566 | "include": "#keywords" 567 | }, 568 | { 569 | "include": "#lvariables" 570 | }, 571 | { 572 | "include": "#constants" 573 | }, 574 | { 575 | "include": "#gtypes" 576 | }, 577 | { 578 | "include": "#functions" 579 | }, 580 | { 581 | "include": "#lifetimes" 582 | }, 583 | { 584 | "include": "#macros" 585 | }, 586 | { 587 | "include": "#namespaces" 588 | }, 589 | { 590 | "include": "#punctuation" 591 | }, 592 | { 593 | "include": "#strings" 594 | }, 595 | { 596 | "include": "#types" 597 | }, 598 | { 599 | "include": "#variables" 600 | } 601 | ] 602 | }, 603 | { 604 | "comment": "function/method calls with turbofish", 605 | "name": "meta.function.call.rust", 606 | "begin": "((?:r#(?!crate|[Ss]elf|super))?[A-Za-z0-9_]+)(?=::<.*>\\()", 607 | "beginCaptures": { 608 | "1": { 609 | "name": "entity.name.function.rust" 610 | } 611 | }, 612 | "end": "\\)", 613 | "endCaptures": { 614 | "0": { 615 | "name": "punctuation.brackets.round.rust" 616 | } 617 | }, 618 | "patterns": [ 619 | { 620 | "include": "#block-comments" 621 | }, 622 | { 623 | "include": "#comments" 624 | }, 625 | { 626 | "include": "#attributes" 627 | }, 628 | { 629 | "include": "#keywords" 630 | }, 631 | { 632 | "include": "#lvariables" 633 | }, 634 | { 635 | "include": "#constants" 636 | }, 637 | { 638 | "include": "#gtypes" 639 | }, 640 | { 641 | "include": "#functions" 642 | }, 643 | { 644 | "include": "#lifetimes" 645 | }, 646 | { 647 | "include": "#macros" 648 | }, 649 | { 650 | "include": "#namespaces" 651 | }, 652 | { 653 | "include": "#punctuation" 654 | }, 655 | { 656 | "include": "#strings" 657 | }, 658 | { 659 | "include": "#types" 660 | }, 661 | { 662 | "include": "#variables" 663 | } 664 | ] 665 | } 666 | ] 667 | }, 668 | "keywords": { 669 | "patterns": [ 670 | { 671 | "comment": "control flow keywords", 672 | "name": "keyword.control.rust", 673 | "match": "\\b(await|break|continue|do|else|for|if|loop|match|return|try|while|yield)\\b" 674 | }, 675 | { 676 | "comment": "storage keywords", 677 | "name": "keyword.other.rust storage.type.rust", 678 | "match": "\\b(extern|let|macro|mod)\\b" 679 | }, 680 | { 681 | "comment": "const keyword", 682 | "name": "storage.modifier.rust", 683 | "match": "\\b(const)\\b" 684 | }, 685 | { 686 | "comment": "type keyword", 687 | "name": "keyword.declaration.type.rust storage.type.rust", 688 | "match": "\\b(type)\\b" 689 | }, 690 | { 691 | "comment": "enum keyword", 692 | "name": "keyword.declaration.enum.rust storage.type.rust", 693 | "match": "\\b(enum)\\b" 694 | }, 695 | { 696 | "comment": "trait keyword", 697 | "name": "keyword.declaration.trait.rust storage.type.rust", 698 | "match": "\\b(trait)\\b" 699 | }, 700 | { 701 | "comment": "struct keyword", 702 | "name": "keyword.declaration.struct.rust storage.type.rust", 703 | "match": "\\b(struct)\\b" 704 | }, 705 | { 706 | "comment": "storage modifiers", 707 | "name": "storage.modifier.rust", 708 | "match": "\\b(abstract|static)\\b" 709 | }, 710 | { 711 | "comment": "other keywords", 712 | "name": "keyword.other.rust", 713 | "match": "\\b(as|async|become|box|dyn|move|final|gen|impl|in|override|priv|pub|ref|typeof|union|unsafe|unsized|use|virtual|where)\\b" 714 | }, 715 | { 716 | "comment": "fn", 717 | "name": "keyword.other.fn.rust", 718 | "match": "\\bfn\\b" 719 | }, 720 | { 721 | "comment": "crate", 722 | "name": "keyword.other.crate.rust", 723 | "match": "\\bcrate\\b" 724 | }, 725 | { 726 | "comment": "mut", 727 | "name": "storage.modifier.mut.rust", 728 | "match": "\\bmut\\b" 729 | }, 730 | { 731 | "comment": "logical operators", 732 | "name": "keyword.operator.logical.rust", 733 | "match": "(\\^|\\||\\|\\||&&|<<|>>|!)(?!=)" 734 | }, 735 | { 736 | "comment": "logical AND, borrow references", 737 | "name": "keyword.operator.borrow.and.rust", 738 | "match": "&(?![&=])" 739 | }, 740 | { 741 | "comment": "assignment operators", 742 | "name": "keyword.operator.assignment.rust", 743 | "match": "(\\+=|-=|\\*=|/=|%=|\\^=|&=|\\|=|<<=|>>=)" 744 | }, 745 | { 746 | "comment": "single equal", 747 | "name": "keyword.operator.assignment.equal.rust", 748 | "match": "(?])=(?!=|>)" 749 | }, 750 | { 751 | "comment": "comparison operators", 752 | "name": "keyword.operator.comparison.rust", 753 | "match": "(=(=)?(?!>)|!=|<=|(?=)" 754 | }, 755 | { 756 | "comment": "math operators", 757 | "name": "keyword.operator.math.rust", 758 | "match": "(([+%]|(\\*(?!\\w)))(?!=))|(-(?!>))|(/(?!/))" 759 | }, 760 | { 761 | "comment": "less than, greater than (special case)", 762 | "match": "(?:\\b|(?:(\\))|(\\])|(\\})))[ \\t]+([<>])[ \\t]+(?:\\b|(?:(\\()|(\\[)|(\\{)))", 763 | "captures": { 764 | "1": { 765 | "name": "punctuation.brackets.round.rust" 766 | }, 767 | "2": { 768 | "name": "punctuation.brackets.square.rust" 769 | }, 770 | "3": { 771 | "name": "punctuation.brackets.curly.rust" 772 | }, 773 | "4": { 774 | "name": "keyword.operator.comparison.rust" 775 | }, 776 | "5": { 777 | "name": "punctuation.brackets.round.rust" 778 | }, 779 | "6": { 780 | "name": "punctuation.brackets.square.rust" 781 | }, 782 | "7": { 783 | "name": "punctuation.brackets.curly.rust" 784 | } 785 | } 786 | }, 787 | { 788 | "comment": "namespace operator", 789 | "name": "keyword.operator.namespace.rust", 790 | "match": "::" 791 | }, 792 | { 793 | "comment": "dereference asterisk", 794 | "match": "(\\*)(?=\\w+)", 795 | "captures": { 796 | "1": { 797 | "name": "keyword.operator.dereference.rust" 798 | } 799 | } 800 | }, 801 | { 802 | "comment": "subpattern binding", 803 | "name": "keyword.operator.subpattern.rust", 804 | "match": "@" 805 | }, 806 | { 807 | "comment": "dot access", 808 | "name": "keyword.operator.access.dot.rust", 809 | "match": "\\.(?!\\.)" 810 | }, 811 | { 812 | "comment": "ranges, range patterns", 813 | "name": "keyword.operator.range.rust", 814 | "match": "\\.{2}(=|\\.)?" 815 | }, 816 | { 817 | "comment": "colon", 818 | "name": "keyword.operator.key-value.rust", 819 | "match": ":(?!:)" 820 | }, 821 | { 822 | "comment": "dashrocket, skinny arrow", 823 | "name": "keyword.operator.arrow.skinny.rust", 824 | "match": "->|<-" 825 | }, 826 | { 827 | "comment": "hashrocket, fat arrow", 828 | "name": "keyword.operator.arrow.fat.rust", 829 | "match": "=>" 830 | }, 831 | { 832 | "comment": "dollar macros", 833 | "name": "keyword.operator.macro.dollar.rust", 834 | "match": "\\$" 835 | }, 836 | { 837 | "comment": "question mark operator, questionably sized, macro kleene matcher", 838 | "name": "keyword.operator.question.rust", 839 | "match": "\\?" 840 | } 841 | ] 842 | }, 843 | "interpolations": { 844 | "comment": "curly brace interpolations", 845 | "name": "meta.interpolation.rust", 846 | "match": "({)[^\"{}]*(})", 847 | "captures": { 848 | "1": { 849 | "name": "punctuation.definition.interpolation.rust" 850 | }, 851 | "2": { 852 | "name": "punctuation.definition.interpolation.rust" 853 | } 854 | } 855 | }, 856 | "lifetimes": { 857 | "patterns": [ 858 | { 859 | "comment": "named lifetime parameters", 860 | "match": "(['])([a-zA-Z_][0-9a-zA-Z_]*)(?!['])\\b", 861 | "captures": { 862 | "1": { 863 | "name": "punctuation.definition.lifetime.rust" 864 | }, 865 | "2": { 866 | "name": "entity.name.type.lifetime.rust" 867 | } 868 | } 869 | }, 870 | { 871 | "comment": "borrowing references to named lifetimes", 872 | "match": "(\\&)(['])([a-zA-Z_][0-9a-zA-Z_]*)(?!['])\\b", 873 | "captures": { 874 | "1": { 875 | "name": "keyword.operator.borrow.rust" 876 | }, 877 | "2": { 878 | "name": "punctuation.definition.lifetime.rust" 879 | }, 880 | "3": { 881 | "name": "entity.name.type.lifetime.rust" 882 | } 883 | } 884 | } 885 | ] 886 | }, 887 | "macros": { 888 | "patterns": [ 889 | { 890 | "comment": "macros", 891 | "name": "meta.macro.rust", 892 | "match": "(([a-z_][A-Za-z0-9_]*!)|([A-Z_][A-Za-z0-9_]*!))", 893 | "captures": { 894 | "2": { 895 | "name": "entity.name.function.macro.rust" 896 | }, 897 | "3": { 898 | "name": "entity.name.type.macro.rust" 899 | } 900 | } 901 | } 902 | ] 903 | }, 904 | "namespaces": { 905 | "patterns": [ 906 | { 907 | "comment": "namespace (non-type, non-function path segment)", 908 | "match": "(?", 943 | "endCaptures": { 944 | "0": { 945 | "name": "punctuation.brackets.angle.rust" 946 | } 947 | }, 948 | "patterns": [ 949 | { 950 | "include": "#block-comments" 951 | }, 952 | { 953 | "include": "#comments" 954 | }, 955 | { 956 | "include": "#keywords" 957 | }, 958 | { 959 | "include": "#lvariables" 960 | }, 961 | { 962 | "include": "#lifetimes" 963 | }, 964 | { 965 | "include": "#punctuation" 966 | }, 967 | { 968 | "include": "#types" 969 | }, 970 | { 971 | "include": "#variables" 972 | } 973 | ] 974 | }, 975 | { 976 | "comment": "primitive types", 977 | "name": "entity.name.type.primitive.rust", 978 | "match": "\\b(bool|char|str)\\b" 979 | }, 980 | { 981 | "comment": "trait declarations", 982 | "match": "\\b(trait)\\s+(_?[A-Z][A-Za-z0-9_]*)\\b", 983 | "captures": { 984 | "1": { 985 | "name": "keyword.declaration.trait.rust storage.type.rust" 986 | }, 987 | "2": { 988 | "name": "entity.name.type.trait.rust" 989 | } 990 | } 991 | }, 992 | { 993 | "comment": "struct declarations", 994 | "match": "\\b(struct)\\s+(_?[A-Z][A-Za-z0-9_]*)\\b", 995 | "captures": { 996 | "1": { 997 | "name": "keyword.declaration.struct.rust storage.type.rust" 998 | }, 999 | "2": { 1000 | "name": "entity.name.type.struct.rust" 1001 | } 1002 | } 1003 | }, 1004 | { 1005 | "comment": "enum declarations", 1006 | "match": "\\b(enum)\\s+(_?[A-Z][A-Za-z0-9_]*)\\b", 1007 | "captures": { 1008 | "1": { 1009 | "name": "keyword.declaration.enum.rust storage.type.rust" 1010 | }, 1011 | "2": { 1012 | "name": "entity.name.type.enum.rust" 1013 | } 1014 | } 1015 | }, 1016 | { 1017 | "comment": "type declarations", 1018 | "match": "\\b(type)\\s+(_?[A-Z][A-Za-z0-9_]*)\\b", 1019 | "captures": { 1020 | "1": { 1021 | "name": "keyword.declaration.type.rust storage.type.rust" 1022 | }, 1023 | "2": { 1024 | "name": "entity.name.type.declaration.rust" 1025 | } 1026 | } 1027 | }, 1028 | { 1029 | "comment": "types", 1030 | "name": "entity.name.type.rust", 1031 | "match": "\\b_?[A-Z][A-Za-z0-9_]*\\b(?!!)" 1032 | } 1033 | ] 1034 | }, 1035 | "gtypes": { 1036 | "patterns": [ 1037 | { 1038 | "comment": "option types", 1039 | "name": "entity.name.type.option.rust", 1040 | "match": "\\b(Some|None)\\b" 1041 | }, 1042 | { 1043 | "comment": "result types", 1044 | "name": "entity.name.type.result.rust", 1045 | "match": "\\b(Ok|Err)\\b" 1046 | } 1047 | ] 1048 | }, 1049 | "punctuation": { 1050 | "patterns": [ 1051 | { 1052 | "comment": "comma", 1053 | "name": "punctuation.comma.rust", 1054 | "match": "," 1055 | }, 1056 | { 1057 | "comment": "curly braces", 1058 | "name": "punctuation.brackets.curly.rust", 1059 | "match": "[{}]" 1060 | }, 1061 | { 1062 | "comment": "parentheses, round brackets", 1063 | "name": "punctuation.brackets.round.rust", 1064 | "match": "[()]" 1065 | }, 1066 | { 1067 | "comment": "semicolon", 1068 | "name": "punctuation.semi.rust", 1069 | "match": ";" 1070 | }, 1071 | { 1072 | "comment": "square brackets", 1073 | "name": "punctuation.brackets.square.rust", 1074 | "match": "[\\[\\]]" 1075 | }, 1076 | { 1077 | "comment": "angle brackets", 1078 | "name": "punctuation.brackets.angle.rust", 1079 | "match": "(?]" 1080 | } 1081 | ] 1082 | }, 1083 | "strings": { 1084 | "patterns": [ 1085 | { 1086 | "comment": "double-quoted strings and byte strings", 1087 | "name": "string.quoted.double.rust", 1088 | "begin": "(b?)(\")", 1089 | "beginCaptures": { 1090 | "1": { 1091 | "name": "string.quoted.byte.raw.rust" 1092 | }, 1093 | "2": { 1094 | "name": "punctuation.definition.string.rust" 1095 | } 1096 | }, 1097 | "end": "\"", 1098 | "endCaptures": { 1099 | "0": { 1100 | "name": "punctuation.definition.string.rust" 1101 | } 1102 | }, 1103 | "patterns": [ 1104 | { 1105 | "include": "#escapes" 1106 | }, 1107 | { 1108 | "include": "#interpolations" 1109 | } 1110 | ] 1111 | }, 1112 | { 1113 | "comment": "double-quoted raw strings and raw byte strings", 1114 | "name": "string.quoted.double.rust", 1115 | "begin": "(b?r)(#*)(\")", 1116 | "beginCaptures": { 1117 | "1": { 1118 | "name": "string.quoted.byte.raw.rust" 1119 | }, 1120 | "2": { 1121 | "name": "punctuation.definition.string.raw.rust" 1122 | }, 1123 | "3": { 1124 | "name": "punctuation.definition.string.rust" 1125 | } 1126 | }, 1127 | "end": "(\")(\\2)", 1128 | "endCaptures": { 1129 | "1": { 1130 | "name": "punctuation.definition.string.rust" 1131 | }, 1132 | "2": { 1133 | "name": "punctuation.definition.string.raw.rust" 1134 | } 1135 | } 1136 | }, 1137 | { 1138 | "comment": "characters and bytes", 1139 | "name": "string.quoted.single.char.rust", 1140 | "begin": "(b)?(')", 1141 | "beginCaptures": { 1142 | "1": { 1143 | "name": "string.quoted.byte.raw.rust" 1144 | }, 1145 | "2": { 1146 | "name": "punctuation.definition.char.rust" 1147 | } 1148 | }, 1149 | "end": "'", 1150 | "endCaptures": { 1151 | "0": { 1152 | "name": "punctuation.definition.char.rust" 1153 | } 1154 | }, 1155 | "patterns": [ 1156 | { 1157 | "include": "#escapes" 1158 | } 1159 | ] 1160 | } 1161 | ] 1162 | }, 1163 | "lvariables": { 1164 | "patterns": [ 1165 | { 1166 | "comment": "self", 1167 | "name": "variable.language.self.rust", 1168 | "match": "\\b[Ss]elf\\b" 1169 | }, 1170 | { 1171 | "comment": "super", 1172 | "name": "variable.language.super.rust", 1173 | "match": "\\bsuper\\b" 1174 | } 1175 | ] 1176 | }, 1177 | "variables": { 1178 | "patterns": [ 1179 | { 1180 | "comment": "variables", 1181 | "name": "variable.other.rust", 1182 | "match": "\\b(?' 18 | endCaptures: 19 | 0: 20 | name: punctuation.brackets.angle.rust 21 | patterns: 22 | - include: '#block-comments' 23 | - include: '#comments' 24 | - include: '#gtypes' 25 | - include: '#lvariables' 26 | - include: '#lifetimes' 27 | - include: '#punctuation' 28 | - include: '#types' 29 | - 30 | comment: macro type metavariables 31 | name: meta.macro.metavariable.type.rust 32 | match: (\$)((crate)|([A-Z]\w*))(\s*(:)\s*(block|expr(?:_2021)?|ident|item|lifetime|literal|meta|pat(?:_param)?|path|stmt|tt|ty|vis)\b)? 33 | captures: 34 | 1: 35 | name: keyword.operator.macro.dollar.rust 36 | 3: 37 | name: keyword.other.crate.rust 38 | 4: 39 | name: entity.name.type.metavariable.rust 40 | 6: 41 | name: keyword.operator.key-value.rust 42 | 7: 43 | name: variable.other.metavariable.specifier.rust 44 | patterns: 45 | - include: '#keywords' 46 | - 47 | comment: macro metavariables 48 | name: meta.macro.metavariable.rust 49 | match: (\$)([a-z]\w*)(\s*(:)\s*(block|expr(?:_2021)?|ident|item|lifetime|literal|meta|pat(?:_param)?|path|stmt|tt|ty|vis)\b)? 50 | captures: 51 | 1: 52 | name: keyword.operator.macro.dollar.rust 53 | 2: 54 | name: variable.other.metavariable.name.rust 55 | 4: 56 | name: keyword.operator.key-value.rust 57 | 5: 58 | name: variable.other.metavariable.specifier.rust 59 | patterns: 60 | - include: '#keywords' 61 | - 62 | comment: macro rules 63 | name: meta.macro.rules.rust 64 | match: \b(macro_rules!)\s+(([a-z0-9_]+)|([A-Z][a-z0-9_]*))\s+(\{) 65 | captures: 66 | 1: 67 | name: entity.name.function.macro.rules.rust 68 | 3: 69 | name: entity.name.function.macro.rust 70 | 4: 71 | name: entity.name.type.macro.rust 72 | 5: 73 | name: punctuation.brackets.curly.rust 74 | - 75 | comment: modules 76 | match: (mod)\s+((?:r#(?!crate|[Ss]elf|super))?[a-z][A-Za-z0-9_]*) 77 | captures: 78 | 1: 79 | name: storage.type.rust 80 | 2: 81 | name: entity.name.module.rust 82 | - 83 | comment: external crate imports 84 | name: meta.import.rust 85 | begin: \b(extern)\s+(crate) 86 | beginCaptures: 87 | 1: 88 | name: storage.type.rust 89 | 2: 90 | name: keyword.other.crate.rust 91 | end: ; 92 | endCaptures: 93 | 0: 94 | name: punctuation.semi.rust 95 | patterns: 96 | - include: '#block-comments' 97 | - include: '#comments' 98 | - include: '#keywords' 99 | - include: '#punctuation' 100 | - 101 | comment: use statements 102 | name: meta.use.rust 103 | begin: \b(use)\s 104 | beginCaptures: 105 | 1: 106 | name: keyword.other.rust 107 | end: ; 108 | endCaptures: 109 | 0: 110 | name: punctuation.semi.rust 111 | patterns: 112 | - include: '#block-comments' 113 | - include: '#comments' 114 | - include: '#keywords' 115 | - include: '#namespaces' 116 | - include: '#punctuation' 117 | - include: '#types' 118 | - include: '#lvariables' 119 | - include: '#block-comments' 120 | - include: '#comments' 121 | - include: '#attributes' 122 | - include: '#lvariables' 123 | - include: '#constants' 124 | - include: '#gtypes' 125 | - include: '#functions' 126 | - include: '#types' 127 | - include: '#keywords' 128 | - include: '#lifetimes' 129 | - include: '#macros' 130 | - include: '#namespaces' 131 | - include: '#punctuation' 132 | - include: '#strings' 133 | - include: '#variables' 134 | repository: 135 | comments: 136 | patterns: 137 | - 138 | comment: documentation comments 139 | name: comment.line.documentation.rust 140 | match: (///).*$ 141 | captures: 142 | 1: 143 | name: punctuation.definition.comment.rust 144 | - 145 | comment: line comments 146 | name: comment.line.double-slash.rust 147 | match: "(//).*$" 148 | captures: 149 | 1: 150 | name: punctuation.definition.comment.rust 151 | block-comments: 152 | patterns: 153 | - 154 | comment: empty block comments 155 | name: comment.block.rust 156 | match: /\*\*/ 157 | - 158 | comment: block documentation comments 159 | name: comment.block.documentation.rust 160 | begin: /\*\* 161 | end: \*/ 162 | patterns: 163 | - include: '#block-comments' 164 | - 165 | comment: block comments 166 | name: comment.block.rust 167 | begin: /\*(?!\*) 168 | end: \*/ 169 | patterns: 170 | - include: '#block-comments' 171 | constants: 172 | patterns: 173 | - 174 | comment: ALL CAPS constants 175 | name: constant.other.caps.rust 176 | match: \b[A-Z]{2}[A-Z0-9_]*\b 177 | - 178 | comment: constant declarations 179 | match: \b(const)\s+([A-Z][A-Za-z0-9_]*)\b 180 | captures: 181 | 1: 182 | name: storage.type.rust 183 | 2: 184 | name: constant.other.caps.rust 185 | - 186 | comment: decimal integers and floats 187 | name: constant.numeric.decimal.rust 188 | match: \b\d[\d_]*(\.?)[\d_]*(?:(E|e)([+-]?)([\d_]+))?(f32|f64|i128|i16|i32|i64|i8|isize|u128|u16|u32|u64|u8|usize)?\b 189 | captures: 190 | 1: 191 | name: punctuation.separator.dot.decimal.rust 192 | 2: 193 | name: keyword.operator.exponent.rust 194 | 3: 195 | name: keyword.operator.exponent.sign.rust 196 | 4: 197 | name: constant.numeric.decimal.exponent.mantissa.rust 198 | 5: 199 | name: entity.name.type.numeric.rust 200 | - 201 | comment: hexadecimal integers 202 | name: constant.numeric.hex.rust 203 | match: \b0x[\da-fA-F_]+(i128|i16|i32|i64|i8|isize|u128|u16|u32|u64|u8|usize)?\b 204 | captures: 205 | 1: 206 | name: entity.name.type.numeric.rust 207 | - 208 | comment: octal integers 209 | name: constant.numeric.oct.rust 210 | match: \b0o[0-7_]+(i128|i16|i32|i64|i8|isize|u128|u16|u32|u64|u8|usize)?\b 211 | captures: 212 | 1: 213 | name: entity.name.type.numeric.rust 214 | - 215 | comment: binary integers 216 | name: constant.numeric.bin.rust 217 | match: \b0b[01_]+(i128|i16|i32|i64|i8|isize|u128|u16|u32|u64|u8|usize)?\b 218 | captures: 219 | 1: 220 | name: entity.name.type.numeric.rust 221 | - 222 | comment: booleans 223 | name: constant.language.bool.rust 224 | match: \b(true|false)\b 225 | escapes: 226 | comment: 'escapes: ASCII, byte, Unicode, quote, regex' 227 | name: constant.character.escape.rust 228 | match: (\\)(?:(?:(x[0-7][\da-fA-F])|(u(\{)[\da-fA-F]{4,6}(\}))|.)) 229 | captures: 230 | 1: 231 | name: constant.character.escape.backslash.rust 232 | 2: 233 | name: constant.character.escape.bit.rust 234 | 3: 235 | name: constant.character.escape.unicode.rust 236 | 4: 237 | name: constant.character.escape.unicode.punctuation.rust 238 | 5: 239 | name: constant.character.escape.unicode.punctuation.rust 240 | attributes: 241 | comment: attributes 242 | name: meta.attribute.rust 243 | begin: '(#)(\!?)(\[)' 244 | beginCaptures: 245 | 1: 246 | name: punctuation.definition.attribute.rust 247 | 3: 248 | name: punctuation.brackets.attribute.rust 249 | end: '\]' 250 | endCaptures: 251 | 0: 252 | name: punctuation.brackets.attribute.rust 253 | patterns: 254 | - include: '#block-comments' 255 | - include: '#comments' 256 | - include: '#keywords' 257 | - include: '#lifetimes' 258 | - include: '#punctuation' 259 | - include: '#strings' 260 | - include: '#gtypes' 261 | - include: '#types' 262 | functions: 263 | patterns: 264 | - 265 | comment: pub as a function 266 | match: \b(pub)(\() 267 | captures: 268 | 1: 269 | name: keyword.other.rust 270 | 2: 271 | name: punctuation.brackets.round.rust 272 | - 273 | comment: function definition 274 | name: meta.function.definition.rust 275 | begin: \b(fn)\s+((?:r#(?!crate|[Ss]elf|super))?[A-Za-z0-9_]+)((\()|(<)) 276 | beginCaptures: 277 | 1: 278 | name: keyword.other.fn.rust 279 | 2: 280 | name: entity.name.function.rust 281 | 4: 282 | name: punctuation.brackets.round.rust 283 | 5: 284 | name: punctuation.brackets.angle.rust 285 | end: (\{)|(;) 286 | endCaptures: 287 | 1: 288 | name: punctuation.brackets.curly.rust 289 | 2: 290 | name: punctuation.semi.rust 291 | patterns: 292 | - include: '#block-comments' 293 | - include: '#comments' 294 | - include: '#keywords' 295 | - include: '#lvariables' 296 | - include: '#constants' 297 | - include: '#gtypes' 298 | - include: '#functions' 299 | - include: '#lifetimes' 300 | - include: '#macros' 301 | - include: '#namespaces' 302 | - include: '#punctuation' 303 | - include: '#strings' 304 | - include: '#types' 305 | - include: '#variables' 306 | - 307 | # todo: capitalized functions in most cases represent enum members or tuple structs 308 | # separate these out and color them accordingly 309 | # this has to be done without breaking struct scoping when the struct keyword is used: 310 | # struct MyStruct() 311 | # this currently highlights correctly, even with parens 312 | comment: function/method calls, chaining 313 | name: meta.function.call.rust 314 | begin: ((?:r#(?!crate|[Ss]elf|super))?[A-Za-z0-9_]+)(\() 315 | beginCaptures: 316 | 1: 317 | name: entity.name.function.rust 318 | 2: 319 | name: punctuation.brackets.round.rust 320 | end: \) 321 | endCaptures: 322 | 0: 323 | name: punctuation.brackets.round.rust 324 | patterns: 325 | - include: '#block-comments' 326 | - include: '#comments' 327 | - include: "#attributes" 328 | - include: '#keywords' 329 | - include: '#lvariables' 330 | - include: '#constants' 331 | - include: '#gtypes' 332 | - include: '#functions' 333 | - include: '#lifetimes' 334 | - include: '#macros' 335 | - include: '#namespaces' 336 | - include: '#punctuation' 337 | - include: '#strings' 338 | - include: '#types' 339 | - include: '#variables' 340 | - 341 | comment: function/method calls with turbofish 342 | name: meta.function.call.rust 343 | begin: ((?:r#(?!crate|[Ss]elf|super))?[A-Za-z0-9_]+)(?=::<.*>\() 344 | beginCaptures: 345 | 1: 346 | name: entity.name.function.rust 347 | end: \) 348 | endCaptures: 349 | 0: 350 | name: punctuation.brackets.round.rust 351 | patterns: 352 | - include: '#block-comments' 353 | - include: '#comments' 354 | - include: "#attributes" 355 | - include: '#keywords' 356 | - include: '#lvariables' 357 | - include: '#constants' 358 | - include: '#gtypes' 359 | - include: '#functions' 360 | - include: '#lifetimes' 361 | - include: '#macros' 362 | - include: '#namespaces' 363 | - include: '#punctuation' 364 | - include: '#strings' 365 | - include: '#types' 366 | - include: '#variables' 367 | keywords: 368 | patterns: 369 | - 370 | comment: control flow keywords 371 | name: keyword.control.rust 372 | match: \b(await|break|continue|do|else|for|if|loop|match|return|try|while|yield)\b 373 | - 374 | comment: storage keywords 375 | name: keyword.other.rust storage.type.rust 376 | match: \b(extern|let|macro|mod)\b 377 | - 378 | comment: const keyword 379 | name: storage.modifier.rust 380 | match: \b(const)\b 381 | - 382 | comment: type keyword 383 | name: keyword.declaration.type.rust storage.type.rust 384 | match: \b(type)\b 385 | - 386 | comment: enum keyword 387 | name: keyword.declaration.enum.rust storage.type.rust 388 | match: \b(enum)\b 389 | - 390 | comment: trait keyword 391 | name: keyword.declaration.trait.rust storage.type.rust 392 | match: \b(trait)\b 393 | - 394 | comment: struct keyword 395 | name: keyword.declaration.struct.rust storage.type.rust 396 | match: \b(struct)\b 397 | - 398 | comment: storage modifiers 399 | name: storage.modifier.rust 400 | match: \b(abstract|static)\b 401 | - 402 | comment: other keywords 403 | name: keyword.other.rust 404 | match: \b(as|async|become|box|dyn|move|final|gen|impl|in|override|priv|pub|ref|typeof|union|unsafe|unsized|use|virtual|where)\b 405 | - 406 | comment: fn 407 | name: keyword.other.fn.rust 408 | match: \bfn\b 409 | - 410 | comment: crate 411 | name: keyword.other.crate.rust 412 | match: \bcrate\b 413 | - 414 | comment: mut 415 | name: storage.modifier.mut.rust 416 | match: \bmut\b 417 | - 418 | comment: logical operators 419 | name: keyword.operator.logical.rust 420 | match: (\^|\||\|\||&&|<<|>>|!)(?!=) 421 | - 422 | comment: logical AND, borrow references 423 | name: keyword.operator.borrow.and.rust 424 | match: '&(?![&=])' 425 | - 426 | comment: assignment operators 427 | name: keyword.operator.assignment.rust 428 | match: (\+=|-=|\*=|/=|%=|\^=|&=|\|=|<<=|>>=) 429 | - 430 | comment: single equal 431 | name: keyword.operator.assignment.equal.rust 432 | match: '(?])=(?!=|>)' 433 | - 434 | comment: comparison operators 435 | name: keyword.operator.comparison.rust 436 | match: (=(=)?(?!>)|!=|<=|(?=) 437 | - 438 | comment: math operators 439 | name: keyword.operator.math.rust 440 | match: '(([+%]|(\*(?!\w)))(?!=))|(-(?!>))|(/(?!/))' 441 | - 442 | comment: less than, greater than (special case) 443 | match: (?:\b|(?:(\))|(\])|(\})))[ \t]+([<>])[ \t]+(?:\b|(?:(\()|(\[)|(\{))) 444 | captures: 445 | 1: 446 | name: punctuation.brackets.round.rust 447 | 2: 448 | name: punctuation.brackets.square.rust 449 | 3: 450 | name: punctuation.brackets.curly.rust 451 | 4: 452 | name: keyword.operator.comparison.rust 453 | 5: 454 | name: punctuation.brackets.round.rust 455 | 6: 456 | name: punctuation.brackets.square.rust 457 | 7: 458 | name: punctuation.brackets.curly.rust 459 | - 460 | comment: namespace operator 461 | name: keyword.operator.namespace.rust 462 | match: '::' 463 | - 464 | comment: dereference asterisk 465 | match: (\*)(?=\w+) 466 | captures: 467 | 1: 468 | name: keyword.operator.dereference.rust 469 | - 470 | comment: subpattern binding 471 | name: keyword.operator.subpattern.rust 472 | match: '@' 473 | - 474 | comment: dot access 475 | name: keyword.operator.access.dot.rust 476 | match: \.(?!\.) 477 | - 478 | comment: ranges, range patterns 479 | name: keyword.operator.range.rust 480 | match: \.{2}(=|\.)? 481 | - 482 | comment: colon 483 | name: keyword.operator.key-value.rust 484 | match: ':(?!:)' 485 | - 486 | comment: dashrocket, skinny arrow 487 | name: keyword.operator.arrow.skinny.rust 488 | match: ->|<- 489 | - 490 | comment: hashrocket, fat arrow 491 | name: keyword.operator.arrow.fat.rust 492 | match: => 493 | - 494 | comment: dollar macros 495 | name: keyword.operator.macro.dollar.rust 496 | match: \$ 497 | - 498 | comment: question mark operator, questionably sized, macro kleene matcher 499 | name: keyword.operator.question.rust 500 | match: \? 501 | interpolations: 502 | comment: curly brace interpolations 503 | name: meta.interpolation.rust 504 | match: '({)[^"{}]*(})' 505 | captures: 506 | 1: 507 | name: punctuation.definition.interpolation.rust 508 | 2: 509 | name: punctuation.definition.interpolation.rust 510 | lifetimes: 511 | patterns: 512 | - 513 | comment: named lifetime parameters 514 | match: (['])([a-zA-Z_][0-9a-zA-Z_]*)(?!['])\b 515 | captures: 516 | 1: 517 | name: punctuation.definition.lifetime.rust 518 | 2: 519 | name: entity.name.type.lifetime.rust 520 | - 521 | comment: borrowing references to named lifetimes 522 | match: (\&)(['])([a-zA-Z_][0-9a-zA-Z_]*)(?!['])\b 523 | captures: 524 | 1: 525 | name: keyword.operator.borrow.rust 526 | 2: 527 | name: punctuation.definition.lifetime.rust 528 | 3: 529 | name: entity.name.type.lifetime.rust 530 | macros: 531 | patterns: 532 | - 533 | comment: macros 534 | name: meta.macro.rust 535 | match: (([a-z_][A-Za-z0-9_]*!)|([A-Z_][A-Za-z0-9_]*!)) 536 | captures: 537 | 2: 538 | name: entity.name.function.macro.rust 539 | 3: 540 | name: entity.name.type.macro.rust 541 | namespaces: 542 | patterns: 543 | - 544 | comment: namespace (non-type, non-function path segment) 545 | match: (?' 568 | endCaptures: 569 | 0: 570 | name: punctuation.brackets.angle.rust 571 | patterns: 572 | - include: '#block-comments' 573 | - include: '#comments' 574 | - include: '#keywords' 575 | - include: '#lvariables' 576 | - include: '#lifetimes' 577 | - include: '#punctuation' 578 | - include: '#types' 579 | - include: '#variables' 580 | - 581 | comment: primitive types 582 | name: entity.name.type.primitive.rust 583 | match: \b(bool|char|str)\b 584 | - 585 | comment: trait declarations 586 | match: \b(trait)\s+(_?[A-Z][A-Za-z0-9_]*)\b 587 | captures: 588 | 1: 589 | name: keyword.declaration.trait.rust storage.type.rust 590 | 2: 591 | name: entity.name.type.trait.rust 592 | # todo: add a specific case for struct fields so they can have different scope than variables - make sure not to catch namespaces 593 | - 594 | comment: struct declarations 595 | match: \b(struct)\s+(_?[A-Z][A-Za-z0-9_]*)\b 596 | captures: 597 | 1: 598 | name: keyword.declaration.struct.rust storage.type.rust 599 | 2: 600 | name: entity.name.type.struct.rust 601 | - 602 | comment: enum declarations 603 | match: \b(enum)\s+(_?[A-Z][A-Za-z0-9_]*)\b 604 | captures: 605 | 1: 606 | name: keyword.declaration.enum.rust storage.type.rust 607 | 2: 608 | name: entity.name.type.enum.rust 609 | - 610 | comment: type declarations 611 | match: \b(type)\s+(_?[A-Z][A-Za-z0-9_]*)\b 612 | captures: 613 | 1: 614 | name: keyword.declaration.type.rust storage.type.rust 615 | 2: 616 | name: entity.name.type.declaration.rust 617 | - 618 | comment: types 619 | name: entity.name.type.rust 620 | match: '\b_?[A-Z][A-Za-z0-9_]*\b(?!!)' 621 | gtypes: 622 | patterns: 623 | - 624 | comment: option types 625 | name: entity.name.type.option.rust 626 | match: \b(Some|None)\b 627 | - 628 | comment: result types 629 | name: entity.name.type.result.rust 630 | match: \b(Ok|Err)\b 631 | punctuation: 632 | patterns: 633 | - 634 | comment: comma 635 | name: punctuation.comma.rust 636 | match: ',' 637 | - 638 | comment: curly braces 639 | name: punctuation.brackets.curly.rust 640 | match: '[{}]' 641 | - 642 | comment: parentheses, round brackets 643 | name: punctuation.brackets.round.rust 644 | match: '[()]' 645 | - 646 | comment: semicolon 647 | name: punctuation.semi.rust 648 | match: ; 649 | - 650 | comment: square brackets 651 | name: punctuation.brackets.square.rust 652 | match: '[\[\]]' 653 | - 654 | comment: angle brackets 655 | name: punctuation.brackets.angle.rust 656 | match: '(?]' 657 | strings: 658 | patterns: 659 | - 660 | comment: double-quoted strings and byte strings 661 | name: string.quoted.double.rust 662 | begin: '(b?)(")' 663 | beginCaptures: 664 | 1: 665 | name: string.quoted.byte.raw.rust 666 | 2: 667 | name: punctuation.definition.string.rust 668 | end: '"' 669 | endCaptures: 670 | 0: 671 | name: punctuation.definition.string.rust 672 | patterns: 673 | - include: '#escapes' 674 | - include: '#interpolations' 675 | - 676 | comment: double-quoted raw strings and raw byte strings 677 | name: string.quoted.double.rust 678 | begin: '(b?r)(#*)(")' 679 | beginCaptures: 680 | 1: 681 | name: string.quoted.byte.raw.rust 682 | 2: 683 | name: punctuation.definition.string.raw.rust 684 | 3: 685 | name: punctuation.definition.string.rust 686 | end: '(")(\2)' 687 | endCaptures: 688 | 1: 689 | name: punctuation.definition.string.rust 690 | 2: 691 | name: punctuation.definition.string.raw.rust 692 | - 693 | comment: characters and bytes 694 | name: string.quoted.single.char.rust 695 | begin: "(b)?(')" 696 | beginCaptures: 697 | 1: 698 | name: string.quoted.byte.raw.rust 699 | 2: 700 | name: punctuation.definition.char.rust 701 | end: "'" 702 | endCaptures: 703 | 0: 704 | name: punctuation.definition.char.rust 705 | patterns: 706 | - include: '#escapes' 707 | lvariables: 708 | patterns: 709 | - 710 | comment: self 711 | name: variable.language.self.rust 712 | match: \b[Ss]elf\b 713 | - 714 | comment: super 715 | name: variable.language.super.rust 716 | match: \bsuper\b 717 | variables: 718 | patterns: 719 | # In order to capture variables ending ranges, but not struct field access, we match a preceding dot, only if it's preceded by at least one other dot. 720 | # The double negation states that the pattern "must not be preceded by a dot that is not preceded by a dot." 721 | # Attempting to match on (\.{2,})? won't work, because then struct field access can match after the dot. 722 | - 723 | comment: variables 724 | name: variable.other.rust 725 | match: \b(? {}; 53 | // ^^^^^^^ ^^^^^^^^^ meta.macro.metavariable.rust 54 | // ^^^^^^^^ ^^^^^^^^^ meta.macro.metavariable.type.rust 55 | // ^ ^ ^ ^ keyword.operator.macro.dollar.rust 56 | // ^^^ ^^^ variable.other.metavariable.name.rust 57 | // ^^^^ ^^^^ entity.name.type.metavariable.rust 58 | // ^ ^ ^ ^ keyword.operator.key-value.rust 59 | // ^^ ^^ ^^ ^^ variable.other.metavariable.specifier.rust 60 | ($var:pat_param $Var:pat_param) => {}; 61 | // ^^^^^^^^^^^^^^ meta.macro.metavariable.rust 62 | // ^^^^^^^^^^^^^^ meta.macro.metavariable.type.rust 63 | // ^ ^ keyword.operator.macro.dollar.rust 64 | // ^^^ variable.other.metavariable.name.rust 65 | // ^^^ entity.name.type.metavariable.rust 66 | // ^ ^ keyword.operator.key-value.rust 67 | // ^^^^^^^^^ ^^^^^^^^^ variable.other.metavariable.specifier.rust 68 | ($var: expr_2021 $Var: expr_2021) => {}; 69 | // ^^^^^^^^^^^^^^^ meta.macro.metavariable.rust 70 | // ^^^^^^^^^^^^^^^ meta.macro.metavariable.type.rust 71 | // ^ ^ keyword.operator.macro.dollar.rust 72 | // ^^^ variable.other.metavariable.name.rust 73 | // ^^^ entity.name.type.metavariable.rust 74 | // ^ ^ keyword.operator.key-value.rust 75 | // ^^^^^^^^^ ^^^^^^^^^ variable.other.metavariable.specifier.rust 76 | () => { $var $Type $crate }; 77 | // ^^^^ meta.macro.metavariable.rust 78 | // ^^^^^ ^^^^^^ meta.macro.metavariable.type.rust 79 | // ^ ^ ^ - meta.macro.metavariable.rust meta.macro.metavariable.type.rust 80 | // ^ ^ ^ keyword.operator.macro.dollar.rust 81 | // ^^^ variable.other.metavariable.name.rust 82 | // ^^^^ entity.name.type.metavariable.rust 83 | // ^^^^^ keyword.other.crate.rust 84 | () => { $var: not_a_specifier }; 85 | // ^^^^ meta.macro.metavariable.rust 86 | // ^ keyword.operator.macro.dollar.rust 87 | // ^^^ variable.other.metavariable.name.rust 88 | // ^^^^^^^^^^^^^^^^^ - meta.macro.metavariable.rust 89 | } -------------------------------------------------------------------------------- /test/test_line_comment.rs: -------------------------------------------------------------------------------- 1 | // SYNTAX TEST "source.rust" "Textmate grammar scope tests for line comment" 2 | 3 | // This file is a placeholder stub that will gradually be expanded to unit test all scopes. 4 | // Instructions for writing Textmate grammar tests can be found at: 5 | // https://github.com/PanAeon/vscode-tmgrammar-test/blob/master/README.md 6 | 7 | // some comment content 8 | // ^^ punctuation.definition.comment.rust 9 | // ^^^^^^^^^^^^^^^^^^^^^^^ comment.line.double-slash.rust 10 | // ^^^^^^^^^^^^^^^^^^^^^^^ source.rust 11 | // <---- source.rust 12 | 13 | /// some comment content 14 | // ^^^ punctuation.definition.comment.rust 15 | // ^^^^^^^^^^^^^^^^^^^^^^^^ comment.line.documentation.rust 16 | // ^^^^^^^^^^^^^^^^^^^^^^^^ source.rust 17 | // <---- source.rust 18 | 19 | 20 | --------------------------------------------------------------------------------