├── .github ├── no-response.yml └── workflows │ └── ci.yml ├── .gitignore ├── CONTRIBUTING.md ├── ISSUE_TEMPLATE.md ├── LICENSE.md ├── PULL_REQUEST_TEMPLATE.md ├── README.md ├── appveyor.yml ├── coffeelint.json ├── grammars ├── javascript.cson ├── jsdoc.cson ├── regular expression replacement (javascript).cson ├── regular expressions (javascript).cson ├── tree-sitter-javascript.cson ├── tree-sitter-jsdoc.cson └── tree-sitter-regex.cson ├── lib └── main.js ├── package.json ├── settings └── language-javascript.cson ├── snippets └── language-javascript.cson └── spec ├── javascript-spec.coffee ├── jsdoc-spec.coffee └── regular-expression-replacement-spec.coffee /.github/no-response.yml: -------------------------------------------------------------------------------- 1 | # Configuration for probot-no-response - https://github.com/probot/no-response 2 | 3 | # Number of days of inactivity before an issue is closed for lack of response 4 | daysUntilClose: 28 5 | 6 | # Label requiring a response 7 | responseRequiredLabel: more-information-needed 8 | 9 | # Comment to post when closing an issue for lack of response. Set to `false` to disable. 10 | closeComment: > 11 | This issue has been automatically closed because there has been no response 12 | to our request for more information from the original author. With only the 13 | information that is currently in the issue, we don't have enough information 14 | to take action. Please reach out if you have or find the answers we need so 15 | that we can investigate further. 16 | -------------------------------------------------------------------------------- /.github/workflows/ci.yml: -------------------------------------------------------------------------------- 1 | name: ci 2 | on: 3 | - pull_request 4 | - push 5 | 6 | jobs: 7 | Test: 8 | if: "!contains(github.event.head_commit.message, '[skip ci]')" 9 | runs-on: ${{ matrix.os }} 10 | strategy: 11 | fail-fast: false 12 | matrix: 13 | os: 14 | - ubuntu-latest 15 | - macos-latest 16 | - windows-latest 17 | atom_channel: 18 | - stable 19 | - nightly 20 | steps: 21 | - uses: actions/checkout@v2 22 | - name: Cache 23 | uses: actions/cache@v2 24 | with: 25 | path: | 26 | 'node_modules' 27 | 'C:/Program Files (x86)/MSBuild/Microsoft.Cpp/v4.0/v140' 28 | key: ${{ runner.os }}-${{ matrix.atom_channel }}-${{ hashFiles('package.json') }} 29 | 30 | - uses: UziTech/action-setup-atom@v1 31 | with: 32 | channel: ${{ matrix.atom_channel }} 33 | 34 | - name: Install dependencies 35 | run: apm install 36 | 37 | - name: Run tests 38 | run: apm test 39 | 40 | Skip: 41 | if: contains(github.event.head_commit.message, '[skip ci]') 42 | runs-on: ubuntu-latest 43 | steps: 44 | - name: Skip CI 🚫 45 | run: echo skip ci 46 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | package-lock.json 3 | -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | See the [Atom contributing guide](https://github.com/atom/atom/blob/master/CONTRIBUTING.md) 2 | -------------------------------------------------------------------------------- /ISSUE_TEMPLATE.md: -------------------------------------------------------------------------------- 1 | 8 | 9 | ### Prerequisites 10 | 11 | * [ ] Put an X between the brackets on this line if you have done all of the following: 12 | * Reproduced the problem in Safe Mode: http://flight-manual.atom.io/hacking-atom/sections/debugging/#using-safe-mode 13 | * Followed all applicable steps in the debugging guide: http://flight-manual.atom.io/hacking-atom/sections/debugging/ 14 | * Checked the FAQs on the message board for common solutions: https://discuss.atom.io/c/faq 15 | * Checked that your issue isn't already filed: https://github.com/issues?utf8=✓&q=is%3Aissue+user%3Aatom 16 | * Checked that there is not already an Atom package that provides the described functionality: https://atom.io/packages 17 | 18 | ### Description 19 | 20 | [Description of the issue] 21 | 22 | ### Steps to Reproduce 23 | 24 | 1. [First Step] 25 | 2. [Second Step] 26 | 3. [and so on...] 27 | 28 | **Expected behavior:** [What you expect to happen] 29 | 30 | **Actual behavior:** [What actually happens] 31 | 32 | **Reproduces how often:** [What percentage of the time does it reproduce?] 33 | 34 | ### Versions 35 | 36 | You can get this information from copy and pasting the output of `atom --version` and `apm --version` from the command line. Also, please include the OS and what version of the OS you're running. 37 | 38 | ### Additional Information 39 | 40 | Any additional information, configuration or data that might be necessary to reproduce the issue. 41 | -------------------------------------------------------------------------------- /LICENSE.md: -------------------------------------------------------------------------------- 1 | Copyright (c) 2015 GitHub Inc. 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining 4 | a copy of this software and associated documentation files (the 5 | "Software"), to deal in the Software without restriction, including 6 | without limitation the rights to use, copy, modify, merge, publish, 7 | distribute, sublicense, and/or sell copies of the Software, and to 8 | permit persons to whom the Software is furnished to do so, subject to 9 | the following conditions: 10 | 11 | The above copyright notice and this permission notice shall be 12 | included in all copies or substantial portions of the Software. 13 | 14 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 15 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 16 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 17 | NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE 18 | LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 19 | OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 20 | WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 21 | 22 | -------------------------------------------------------------------- 23 | 24 | This package was derived from a TextMate bundle located at 25 | https://github.com/textmate/javascript.tmbundle and distributed under the 26 | following license, located in `README.mdown`: 27 | 28 | Permission to copy, use, modify, sell and distribute this 29 | software is granted. This software is provided "as is" without 30 | express or implied warranty, and with no claim as to its 31 | suitability for any purpose. 32 | -------------------------------------------------------------------------------- /PULL_REQUEST_TEMPLATE.md: -------------------------------------------------------------------------------- 1 | ### Requirements 2 | 3 | * Filling out the template is required. Any pull request that does not include enough information to be reviewed in a timely manner may be closed at the maintainers' discretion. 4 | * All new code requires tests to ensure against regressions 5 | 6 | ### Description of the Change 7 | 8 | 13 | 14 | ### Alternate Designs 15 | 16 | 17 | 18 | ### Benefits 19 | 20 | 21 | 22 | ### Possible Drawbacks 23 | 24 | 25 | 26 | ### Applicable Issues 27 | 28 | 29 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ##### Atom and all repositories under Atom will be archived on December 15, 2022. Learn more in our [official announcement](https://github.blog/2022-06-08-sunsetting-atom/) 2 | # JavaScript language support in Atom 3 | 4 | ![ci](https://github.com/atom/language-javascript/workflows/ci/badge.svg) 5 | [![Dependency Status](https://david-dm.org/atom/language-javascript.svg)](https://david-dm.org/atom/language-javascript) 6 | 7 | Adds syntax highlighting and snippets for JavaScript in Atom. 8 | 9 | Originally [converted](http://flight-manual.atom.io/hacking-atom/sections/converting-from-textmate) 10 | from the [JavaScript TextMate bundle](https://github.com/textmate/javascript.tmbundle). 11 | 12 | Contributions are greatly appreciated. Please fork this repository and open a 13 | pull request to add snippets, make grammar tweaks, etc. 14 | -------------------------------------------------------------------------------- /appveyor.yml: -------------------------------------------------------------------------------- 1 | # empty appveyor 2 | build: off 3 | 4 | branches: 5 | only: 6 | - non-existing 7 | -------------------------------------------------------------------------------- /coffeelint.json: -------------------------------------------------------------------------------- 1 | { 2 | "max_line_length": { 3 | "level": "ignore" 4 | }, 5 | "no_empty_param_list": { 6 | "level": "error" 7 | }, 8 | "arrow_spacing": { 9 | "level": "error" 10 | }, 11 | "no_interpolation_in_single_quotes": { 12 | "level": "error" 13 | }, 14 | "no_debugger": { 15 | "level": "error" 16 | }, 17 | "prefer_english_operator": { 18 | "level": "error" 19 | }, 20 | "colon_assignment_spacing": { 21 | "spacing": { 22 | "left": 0, 23 | "right": 1 24 | }, 25 | "level": "error" 26 | }, 27 | "braces_spacing": { 28 | "spaces": 0, 29 | "level": "error" 30 | }, 31 | "spacing_after_comma": { 32 | "level": "error" 33 | }, 34 | "no_stand_alone_at": { 35 | "level": "error" 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /grammars/javascript.cson: -------------------------------------------------------------------------------- 1 | 'scopeName': 'source.js' 2 | 'fileTypes': [ 3 | 'js' 4 | '_js' 5 | 'cjs' 6 | 'es' 7 | 'es6' 8 | 'gs' 9 | 'htc' 10 | 'jscad' 11 | 'jscript' 12 | 'jse' 13 | 'jslib' 14 | 'jsm' 15 | 'json5' 16 | 'jspre' 17 | 'mjs' 18 | 'pac' 19 | 'pjs' 20 | 'sjs' 21 | 'snap' 22 | 'xsjs' 23 | 'xsjslib' 24 | ] 25 | 'firstLineMatch': '''(?x) 26 | # Hashbang 27 | ^\\#!.*(?:\\s|\\/|(?<=!)\\b) 28 | (?:node|iojs|JavaScript) 29 | (?:$|\\s) 30 | | 31 | # Modeline 32 | (?i: 33 | # Emacs 34 | -\\*-(?:\\s*(?=[^:;\\s]+\\s*-\\*-)|(?:.*?[;\\s]|(?<=-\\*-))mode\\s*:\\s*) 35 | (?:js|javascript) 36 | (?=[\\s;]|(?]?\\d+|m)?|\\sex)(?=:(?=\\s*set?\\s[^\\n:]+:)|:(?!\\s*set?\\s))(?:(?:\\s|\\s*:\\s*)\\w*(?:\\s*=(?:[^\\n\\\\\\s]|\\\\.)*)?)*[\\s:](?:filetype|ft|syntax)\\s*= 40 | javascript 41 | (?=\\s|:|$) 42 | ) 43 | ''' 44 | 'name': 'JavaScript' 45 | 'patterns': [ 46 | { 47 | # ES6 import 48 | 'begin': '(? [expression|{statements}] 500 | 'begin': '''(?x) 501 | (?= 502 | (? 505 | ) 506 | ''' 507 | 'end': '''(?x) 508 | (?<=})| 509 | ((?! 510 | \\s*{| 511 | \\G\\(| 512 | \\G[\\w$]+| 513 | \\s*/\\*|\\s*// 514 | )(?=\\s*\\S)) 515 | ''' 516 | 'patterns': [ 517 | { 518 | 'include': '#comments' 519 | } 520 | { 521 | 'include': '#function_body' 522 | } 523 | { 524 | 'begin': '\\G' 525 | 'end': '(?<=(=>))' 526 | 'name': 'meta.function.arrow.js' 527 | 'patterns': [ 528 | { 529 | 'include': '#arrow_function_innards' 530 | } 531 | ] 532 | } 533 | ] 534 | } 535 | { 536 | # [.]foo = ... => ... 537 | 'begin': '''(?x) 538 | (?= 539 | (\\.)?[a-zA-Z_$][\\w$]* 540 | \\s*(=)\\s* 541 | ((\\(([^\\(\\)]*)?\\))|[\\w$]+) 542 | \\s*=> 543 | ) 544 | ''' 545 | 'end': '''(?x) 546 | (?<=})| 547 | ((?! 548 | \\s*{| 549 | \\G(\\.)?[a-zA-Z_$][\\w$]*\\s*(=)\\s*\\(| 550 | \\G(\\.)?[a-zA-Z_$][\\w$]*\\s*(=)\\s*[\\w$]+| 551 | \\s*/\\*|\\s*// 552 | )(?=\\s*\\S)) 553 | ''' 554 | 'patterns': [ 555 | { 556 | 'include': '#comments' 557 | } 558 | { 559 | 'include': '#function_body' 560 | } 561 | { 562 | 'begin': '\\G' 563 | 'end': '(?<=(=>))' 564 | 'name': 'meta.function.arrow.js' 565 | 'patterns': [ 566 | { 567 | 'match': '\\G(\\.)?([a-zA-Z_$][\\w$]*)\\s*(=)' 568 | 'captures': 569 | '1': 570 | 'name': 'meta.delimiter.method.period.js' 571 | '2': 572 | 'name': 'entity.name.function.js' 573 | '3': 574 | 'name': 'keyword.operator.assignment.js' 575 | } 576 | { 577 | 'include': '#arrow_function_innards' 578 | } 579 | ] 580 | } 581 | ] 582 | } 583 | { 584 | # foo: ... => ... 585 | 'begin': '''(?x) 586 | (?= 587 | \\b[a-zA-Z_$][\\w$]* 588 | \\s*:\\s* 589 | ((\\(([^\\(\\)]*)?\\))|[\\w$]+) 590 | \\s*=> 591 | ) 592 | ''' 593 | 'end': '''(?x) 594 | (?<=})| 595 | ((?! 596 | \\s*{| 597 | \\G[\\w$]+\\s*:| 598 | \\s*/\\*|\\s*// 599 | )(?=\\s*\\S)) 600 | ''' 601 | 'patterns': [ 602 | { 603 | 'include': '#comments' 604 | } 605 | { 606 | 'include': '#function_body' 607 | } 608 | { 609 | 'begin': '\\G' 610 | 'end': '(?<=(=>))' 611 | 'name': 'meta.function.arrow.json.js' 612 | 'patterns': [ 613 | { 614 | 'match': '\\b([a-zA-Z_$][\\w$]*)\\s*(:)\\s*' 615 | 'captures': 616 | '1': 617 | 'name': 'entity.name.function.js' 618 | '2': 619 | 'name': 'keyword.operator.assignment.js' 620 | } 621 | { 622 | 'include': '#arrow_function_innards' 623 | } 624 | ] 625 | } 626 | ] 627 | } 628 | { 629 | # "foo": ... => ... 630 | 'begin': '''(?x) 631 | (?= 632 | ((\'[^\']*?\')|("[^"]*?")) 633 | \\s*:\\s* 634 | ((\\(([^\\(\\)]*)?\\))|[\\w$]+) 635 | \\s*=> 636 | ) 637 | ''' 638 | 'end': '''(?x) 639 | (?<=})| 640 | ((?! 641 | \\G((\'[^\']*?\')|("[^"]*?"))| 642 | \\s*{| 643 | \\s*/\\*|\\s*// 644 | )(?=\\s*\\S)) 645 | ''' 646 | 'patterns': [ 647 | { 648 | 'include': '#comments' 649 | } 650 | { 651 | 'include': '#function_body' 652 | } 653 | { 654 | 'begin': '\\G' 655 | 'end': '(?<=(=>))' 656 | 'name': 'meta.function.arrow.json.js' 657 | 'patterns': [ 658 | { 659 | 'match': '(?:((\')([^\']*?)(\'))|((")([^"]*?)(")))\\s*(:)' 660 | 'captures': 661 | '1': 662 | 'name': 'string.quoted.single.js' 663 | '2': 664 | 'name': 'punctuation.definition.string.begin.js' 665 | '3': 666 | 'name': 'entity.name.function.js' 667 | '4': 668 | 'name': 'punctuation.definition.string.end.js' 669 | '5': 670 | 'name': 'string.quoted.double.js' 671 | '6': 672 | 'name': 'punctuation.definition.string.begin.js' 673 | '7': 674 | 'name': 'entity.name.function.js' 675 | '8': 676 | 'name': 'punctuation.definition.string.end.js' 677 | '9': 678 | 'name': 'keyword.operator.assignment.js' 679 | } 680 | { 681 | 'include': '#arrow_function_innards' 682 | } 683 | ] 684 | } 685 | ] 686 | } 687 | { 688 | 'match': '(=>)' 689 | 'captures': 690 | '0': 691 | 'name': 'meta.function.arrow.js' 692 | '1': 693 | 'name': 'storage.type.function.arrow.js' 694 | } 695 | { 696 | 'match': '''(?x) 697 | \\b(class) 698 | (?: 699 | (?:\\s+(extends)\\s+([a-zA-Z_$][\\w$]*)) 700 | | 701 | (?: 702 | (?:\\s+([a-zA-Z_$][\\w$]*)) 703 | (?:\\s+(extends)\\s+([a-zA-Z_$][\\w$]*))? 704 | ) 705 | ) 706 | ''' 707 | 'captures': 708 | '1': 709 | 'name': 'storage.type.class.js' 710 | '2': 711 | 'name': 'storage.modifier.js' 712 | '3': 713 | 'name': 'entity.other.inherited-class.js' 714 | '4': 715 | 'name': 'entity.name.type.class.js' 716 | '5': 717 | 'name': 'storage.modifier.js' 718 | '6': 719 | 'name': 'entity.other.inherited-class.js' 720 | 'name': 'meta.class.js' 721 | } 722 | { 723 | 'match': '(new)\\s+([\\w$]+[\\w.$]*)' 724 | 'name': 'meta.class.instance.constructor.js' 725 | 'captures': 726 | '1': 727 | 'name': 'keyword.operator.new.js' 728 | '2': 729 | 'name': 'entity.name.type.instance.js' 730 | 'patterns': [ 731 | { 732 | 'match': '\\.' 733 | 'name': 'meta.delimiter.property.period.js' 734 | } 735 | ] 736 | } 737 | { 738 | # console 739 | # console.log(arg1, "arg2", [...]) 740 | 'begin': '(?)' 862 | 'captures': 863 | '0': 864 | 'name': 'punctuation.definition.comment.html.js' 865 | '2': 866 | 'name': 'punctuation.definition.comment.html.js' 867 | 'name': 'comment.block.html.js' 868 | } 869 | { 870 | 'match': '(?|&&|\\|\\|)\\s*(/)(?![/*+?])(?=.*/)' 1124 | 'beginCaptures': 1125 | '1': 1126 | 'name': 'punctuation.definition.string.begin.js' 1127 | 'end': '(/)([gimsuy]*)' 1128 | 'endCaptures': 1129 | '1': 1130 | 'name': 'punctuation.definition.string.end.js' 1131 | '2': 1132 | 'name': 'meta.flag.regexp' 1133 | 'name': 'string.regexp.js' 1134 | 'patterns': [ 1135 | { 1136 | 'include': 'source.js.regexp' 1137 | } 1138 | ] 1139 | } 1140 | { 1141 | 'begin': '\\?' 1142 | 'beginCaptures': 1143 | '0': 1144 | 'name': 'keyword.operator.ternary.js' 1145 | 'end': ':' 1146 | 'endCaptures': 1147 | '0': 1148 | 'name': 'keyword.operator.ternary.js' 1149 | 'patterns': [ 1150 | { 1151 | 'include': '#prevent_object_keys_matching' 1152 | } 1153 | { 1154 | 'include': '$self' 1155 | } 1156 | ] 1157 | } 1158 | { 1159 | 'include': '#operators' 1160 | } 1161 | { 1162 | 'include': '#method_calls' 1163 | } 1164 | { 1165 | 'include': '#function_calls' 1166 | } 1167 | { 1168 | 'include': '#numbers' 1169 | } 1170 | { 1171 | 'include': '#objects' 1172 | } 1173 | { 1174 | 'include': '#properties' 1175 | } 1176 | { 1177 | 'match': '((?>=|>>>=|\\|=' 1322 | 'name': 'keyword.operator.assignment.compound.bitwise.js' 1323 | } 1324 | { 1325 | 'match': '<<|>>>|>>' 1326 | 'name': 'keyword.operator.bitwise.shift.js' 1327 | } 1328 | { 1329 | 'match': '!==|!=|<=|>=|===|==|<|>' 1330 | 'name': 'keyword.operator.comparison.js' 1331 | } 1332 | { 1333 | 'match': '&&|!!|!|\\|\\|' 1334 | 'name': 'keyword.operator.logical.js' 1335 | } 1336 | { 1337 | 'match': '&|\\||\\^|~' 1338 | 'name': 'keyword.operator.bitwise.js' 1339 | } 1340 | { 1341 | 'match': '=|:' 1342 | 'name': 'keyword.operator.assignment.js' 1343 | } 1344 | { 1345 | 'match': '--' 1346 | 'name': 'keyword.operator.decrement.js' 1347 | } 1348 | { 1349 | 'match': '\\+\\+' 1350 | 'name': 'keyword.operator.increment.js' 1351 | } 1352 | { 1353 | 'match': '%|\\*|/|-|\\+' 1354 | 'name': 'keyword.operator.js' 1355 | } 1356 | ] 1357 | 'strings': 1358 | 'patterns': [ 1359 | { 1360 | 'begin': '\'' 1361 | 'beginCaptures': 1362 | '0': 1363 | 'name': 'punctuation.definition.string.begin.js' 1364 | 'end': '\'' 1365 | 'endCaptures': 1366 | '0': 1367 | 'name': 'punctuation.definition.string.end.js' 1368 | 'name': 'string.quoted.single.js' 1369 | 'patterns': [ 1370 | { 1371 | 'include': '#string_escapes' 1372 | } 1373 | ] 1374 | } 1375 | { 1376 | 'begin': '"' 1377 | 'beginCaptures': 1378 | '0': 1379 | 'name': 'punctuation.definition.string.begin.js' 1380 | 'end': '"' 1381 | 'endCaptures': 1382 | '0': 1383 | 'name': 'punctuation.definition.string.end.js' 1384 | 'name': 'string.quoted.double.js' 1385 | 'patterns': [ 1386 | { 1387 | 'include': '#string_escapes' 1388 | } 1389 | ] 1390 | } 1391 | { 1392 | 'begin': '((\\w+)?(html|HTML|Html))\\s*(`)' 1393 | 'beginCaptures': 1394 | '1': 1395 | 'name': 'entity.name.function.js' 1396 | '4': 1397 | 'name': 'punctuation.definition.string.begin.js' 1398 | 'end': '`' 1399 | 'endCaptures': 1400 | '0': 1401 | 'name': 'punctuation.definition.string.end.js' 1402 | 'name': 'string.quoted.template.html.js' 1403 | 'patterns': [ 1404 | { 1405 | 'include': '#string_escapes' 1406 | } 1407 | { 1408 | 'include': '#interpolated_js' 1409 | } 1410 | { 1411 | 'include': 'text.html.basic' 1412 | } 1413 | ] 1414 | } 1415 | { 1416 | 'begin': '(?<=innerHTML)\\s*(\\+?=)\\s*(?=`)' 1417 | 'beginCaptures': 1418 | '1': 1419 | 'name': 'keyword.operator.assignment.js' 1420 | 'end': '(?<=`)' 1421 | 'endCaptures': 1422 | '0': 1423 | 'name': 'punctuation.definition.string.end.js' 1424 | 'contentName': 'string.quoted.template.html.js' 1425 | 'patterns': [ 1426 | { 1427 | 'begin': '`' 1428 | 'beginCaptures': 1429 | '0': 1430 | 'name': 'punctuation.definition.string.begin.js' 1431 | 'end': '`' 1432 | 'endCaptures': 1433 | '0': 1434 | 'name': 'punctuation.definition.string.end.js' 1435 | 'patterns': [ 1436 | { 1437 | 'include': '#string_escapes' 1438 | } 1439 | { 1440 | 'include': '#interpolated_js' 1441 | } 1442 | { 1443 | 'include': 'text.html.basic' 1444 | } 1445 | ] 1446 | } 1447 | ] 1448 | } 1449 | { 1450 | 'begin': '(Relay\\.QL|gql)\\s*(`)' 1451 | 'beginCaptures': 1452 | '1': 1453 | 'name': 'entity.name.function.js' 1454 | '2': 1455 | 'name': 'punctuation.definition.string.begin.js' 1456 | 'end': '`' 1457 | 'endCaptures': 1458 | '0': 1459 | 'name': 'punctuation.definition.string.end.js' 1460 | 'name': 'string.quoted.template.graphql.js' 1461 | 'patterns': [ 1462 | { 1463 | 'include': '#string_escapes' 1464 | } 1465 | { 1466 | 'include': '#interpolated_js' 1467 | } 1468 | { 1469 | 'include': 'source.graphql' 1470 | } 1471 | ] 1472 | } 1473 | { 1474 | 'begin': '(sql|SQL|Sql)\\s*(`)' 1475 | 'beginCaptures': 1476 | '1': 1477 | 'name': 'entity.name.function.js' 1478 | '2': 1479 | 'name': 'punctuation.definition.string.begin.js' 1480 | 'end': '`' 1481 | 'endCaptures': 1482 | '0': 1483 | 'name': 'punctuation.definition.string.end.js' 1484 | 'name': 'string.quoted.template.sql.js' 1485 | 'patterns': [ 1486 | { 1487 | 'include': '#string_escapes' 1488 | } 1489 | { 1490 | 'include': '#interpolated_js' 1491 | } 1492 | { 1493 | 'include': 'source.sql' 1494 | } 1495 | ] 1496 | } 1497 | { 1498 | 'begin': '`' 1499 | 'beginCaptures': 1500 | '0': 1501 | 'name': 'punctuation.definition.string.begin.js' 1502 | 'end': '`' 1503 | 'endCaptures': 1504 | '0': 1505 | 'name': 'punctuation.definition.string.end.js' 1506 | 'name': 'string.quoted.template.js' 1507 | 'patterns': [ 1508 | { 1509 | 'include': '#string_escapes' 1510 | } 1511 | { 1512 | 'include': '#interpolated_js' 1513 | } 1514 | ] 1515 | } 1516 | ] 1517 | 'string_escapes': 1518 | 'patterns': [ 1519 | { 1520 | 'match': '\\\\u(?![A-Fa-f0-9]{4}|{[A-Fa-f0-9]+})[^\'"]*' 1521 | 'name': 'invalid.illegal.unicode-escape.js' 1522 | } 1523 | { 1524 | 'match': '\\\\u(?:[A-Fa-f0-9]{4}|({)([A-Fa-f0-9]+)(}))' 1525 | 'name': 'constant.character.escape.js' 1526 | 'captures': 1527 | '1': 1528 | 'name': 'punctuation.definition.unicode-escape.begin.bracket.curly.js' 1529 | '2': 1530 | 'patterns': [ 1531 | { 1532 | # Max codepoint: \u{10FFFF} 1533 | 'match': '[A-Fa-f\\d]{7,}|(?!10)[A-Fa-f\\d]{6}' 1534 | 'name': 'invalid.illegal.unicode-escape.js' 1535 | } 1536 | ] 1537 | '3': 1538 | 'name': 'punctuation.definition.unicode-escape.end.bracket.curly.js' 1539 | } 1540 | { 1541 | 'match': '\\\\(x[0-9A-Fa-f]{2}|[0-2][0-7]{0,2}|3[0-6][0-7]?|37[0-7]?|[4-7][0-7]?|.)' 1542 | 'name': 'constant.character.escape.js' 1543 | } 1544 | ] 1545 | 'function_params': 1546 | 'patterns': [ 1547 | { 1548 | 'begin': '\\(' 1549 | 'beginCaptures': 1550 | '0': 1551 | 'name': 'punctuation.definition.parameters.begin.bracket.round.js' 1552 | 'end': '\\)' 1553 | 'endCaptures': 1554 | '0': 1555 | 'name': 'punctuation.definition.parameters.end.bracket.round.js' 1556 | 'name': 'meta.parameters.js' 1557 | 'patterns': [ 1558 | { 1559 | 'match': '(\\.\\.\\.)([a-zA-Z_$][\\w$]*)' 1560 | 'captures': 1561 | '1': 1562 | 'name': 'keyword.operator.spread.js' 1563 | '2': 1564 | 'name': 'variable.parameter.rest.function.js' 1565 | } 1566 | { 1567 | 'include': '$self' 1568 | } 1569 | { 1570 | 'match': '[a-zA-Z_$][\\w$]*' 1571 | 'name': 'variable.parameter.function.js' 1572 | } 1573 | ] 1574 | } 1575 | ] 1576 | 'function_body': 1577 | 'patterns': [ 1578 | { 1579 | 'begin': '{' 1580 | 'beginCaptures': 1581 | '0': 1582 | 'name': 'punctuation.definition.function.body.begin.bracket.curly.js' 1583 | 'end': '}' 1584 | 'endCaptures': 1585 | '0': 1586 | 'name': 'punctuation.definition.function.body.end.bracket.curly.js' 1587 | 'patterns': [ 1588 | { 1589 | 'include': '$self' 1590 | } 1591 | ] 1592 | } 1593 | ] 1594 | 'function_innards': 1595 | 'patterns': [ 1596 | { 1597 | 'match': '(?:\\b(async)\\b\\s*)?\\b(function)\\b(?:\\s*(\\*))?' 1598 | 'captures': 1599 | '1': 1600 | 'name': 'storage.modifier.async.js' 1601 | '2': 1602 | 'name': 'storage.type.function.js' 1603 | '3': 1604 | 'name': 'storage.modifier.generator.js' 1605 | } 1606 | { 1607 | 'match': '[a-zA-Z_$][\\w$]*(?=\\s*\\()' 1608 | 'name': 'entity.name.function.js' 1609 | } 1610 | { 1611 | 'include': '#function_params' 1612 | } 1613 | { 1614 | 'include': '#comments' 1615 | } 1616 | ] 1617 | 'arrow_function_innards': 1618 | 'patterns': [ 1619 | { 1620 | 'match': '=>' 1621 | 'name': 'storage.type.function.arrow.js' 1622 | } 1623 | { 1624 | 'include': '#function_params' 1625 | } 1626 | { 1627 | 'match': '([a-zA-Z_$][\\w$]*)(?=\\s*=>)' 1628 | 'captures': 1629 | '0': 1630 | 'name': 'meta.parameters.js' 1631 | '1': 1632 | 'name': 'variable.parameter.function.js' 1633 | } 1634 | { 1635 | 'match': '(\\d[\\w$]*)' 1636 | 'captures': 1637 | '0': 1638 | 'name': 'meta.parameters.js' 1639 | '1': 1640 | 'name': 'invalid.illegal.identifier.js' 1641 | } 1642 | ] 1643 | 'arguments': 1644 | 'patterns': [ 1645 | { 1646 | 'begin': '\\(' 1647 | 'beginCaptures': 1648 | '0': 1649 | 'name': 'punctuation.definition.arguments.begin.bracket.round.js' 1650 | 'end': '\\)' 1651 | 'endCaptures': 1652 | '0': 1653 | 'name': 'punctuation.definition.arguments.end.bracket.round.js' 1654 | 'name': 'meta.arguments.js' 1655 | 'patterns': [ 1656 | { 1657 | 'include': '$self' 1658 | } 1659 | ] 1660 | } 1661 | ] 1662 | 'method_calls': 1663 | 'patterns': [ 1664 | { 1665 | # .methodCall(arg1, "arg2", [...]) 1666 | 'begin': '(\\.)\\s*([\\w$]+)\\s*(?=\\()' 1667 | 'beginCaptures': 1668 | '1': 1669 | 'name': 'meta.delimiter.method.period.js' 1670 | '2': 1671 | 'patterns': [ 1672 | { 1673 | 'match': '''(?x) 1674 | \\bon(Rowsinserted|Rowsdelete|Rowenter|Rowexit|Resize|Resizestart|Resizeend|Reset| 1675 | Readystatechange|Mouseout|Mouseover|Mousedown|Mouseup|Mousemove| 1676 | Before(cut|deactivate|unload|update|paste|print|editfocus|activate)| 1677 | Blur|Scrolltop|Submit|Select|Selectstart|Selectionchange|Hover|Help| 1678 | Change|Contextmenu|Controlselect|Cut|Cellchange|Clock|Close|Deactivate| 1679 | Datasetchanged|Datasetcomplete|Dataavailable|Drop|Drag|Dragstart|Dragover| 1680 | Dragdrop|Dragenter|Dragend|Dragleave|Dblclick|Unload|Paste|Propertychange|Error| 1681 | Errorupdate|Keydown|Keyup|Keypress|Focus|Load|Activate|Afterupdate|Afterprint|Abort)\\b 1682 | ''' 1683 | 'name': 'support.function.event-handler.js' 1684 | } 1685 | { 1686 | 'match': '''(?x) 1687 | \\b(catch|finally|then|shift|showModelessDialog|showModalDialog|showHelp|scroll|scrollX|scrollByPages| 1688 | scrollByLines|scrollY|scrollTo|stop|strike|sizeToContent|sidebar|signText|sort| 1689 | sup|sub|substr|substring|splice|split|send|set(Milliseconds|Seconds|Minutes|Hours| 1690 | Month|Year|FullYear|Date|UTC(Milliseconds|Seconds|Minutes|Hours|Month|FullYear|Date)| 1691 | Time|Hotkeys|Cursor|ZOptions|Active|Resizable|RequestHeader)|search|slice| 1692 | savePreferences|small|home|handleEvent|navigate|char|charCodeAt|charAt|concat| 1693 | contextual|confirm|compile|clear|captureEvents|call|createStyleSheet|createPopup| 1694 | createEventObject|to(GMTString|UTCString|String|Source|UpperCase|LowerCase|LocaleString)| 1695 | test|taint|taintEnabled|indexOf|italics|disableExternalCapture|dump|detachEvent|unshift| 1696 | untaint|unwatch|updateCommands|join|javaEnabled|pop|push|plugins.refresh|paddings|parse|stringify| 1697 | print|prompt|preference|enableExternalCapture|exec|execScript|valueOf|UTC|find|file| 1698 | fileModifiedDate|fileSize|fileCreatedDate|fileUpdatedDate|fixed|fontsize|fontcolor| 1699 | forward|fromCharCode|watch|link|load|lastIndexOf|anchor|attachEvent|atob|apply|alert| 1700 | abort|routeEvents|resize|resizeBy|resizeTo|recalc|returnValue|replace|reverse|reload| 1701 | releaseCapture|releaseEvents|go|get(Milliseconds|Seconds|Minutes|Hours|Month|Day|Year|FullYear| 1702 | Time|Date|TimezoneOffset|UTC(Milliseconds|Seconds|Minutes|Hours|Day|Month|FullYear|Date)| 1703 | Attention|Selection|ResponseHeader|AllResponseHeaders)|moveBy|moveBelow|moveTo| 1704 | moveToAbsolute|moveAbove|mergeAttributes|match|margins|btoa|big|bold|borderWidths|blink|back)\\b 1705 | ''' 1706 | 'name': 'support.function.js' 1707 | } 1708 | { 1709 | 'match': '''(?x) 1710 | \\b(acceptNode|add|addEventListener|addTextTrack|adoptNode|after|animate|append| 1711 | appendChild|appendData|before|blur|canPlayType|captureStream| 1712 | caretPositionFromPoint|caretRangeFromPoint|checkValidity|clear|click| 1713 | cloneContents|cloneNode|cloneRange|close|closest|collapse| 1714 | compareBoundaryPoints|compareDocumentPosition|comparePoint|contains| 1715 | convertPointFromNode|convertQuadFromNode|convertRectFromNode|createAttribute| 1716 | createAttributeNS|createCaption|createCDATASection|createComment| 1717 | createContextualFragment|createDocument|createDocumentFragment| 1718 | createDocumentType|createElement|createElementNS|createEntityReference| 1719 | createEvent|createExpression|createHTMLDocument|createNodeIterator| 1720 | createNSResolver|createProcessingInstruction|createRange|createShadowRoot| 1721 | createTBody|createTextNode|createTFoot|createTHead|createTreeWalker|delete| 1722 | deleteCaption|deleteCell|deleteContents|deleteData|deleteRow|deleteTFoot| 1723 | deleteTHead|detach|disconnect|dispatchEvent|elementFromPoint|elementsFromPoint| 1724 | enableStyleSheetsForSet|entries|evaluate|execCommand|exitFullscreen| 1725 | exitPointerLock|expand|extractContents|fastSeek|firstChild|focus|forEach|get| 1726 | getAll|getAnimations|getAttribute|getAttributeNames|getAttributeNode| 1727 | getAttributeNodeNS|getAttributeNS|getBoundingClientRect|getBoxQuads| 1728 | getClientRects|getContext|getDestinationInsertionPoints|getElementById| 1729 | getElementsByClassName|getElementsByName|getElementsByTagName| 1730 | getElementsByTagNameNS|getItem|getNamedItem|getSelection|getStartDate| 1731 | getVideoPlaybackQuality|has|hasAttribute|hasAttributeNS|hasAttributes| 1732 | hasChildNodes|hasFeature|hasFocus|importNode|initEvent|insertAdjacentElement| 1733 | insertAdjacentHTML|insertAdjacentText|insertBefore|insertCell|insertData| 1734 | insertNode|insertRow|intersectsNode|isDefaultNamespace|isEqualNode| 1735 | isPointInRange|isSameNode|item|key|keys|lastChild|load|lookupNamespaceURI| 1736 | lookupPrefix|matches|move|moveAttribute|moveAttributeNode|moveChild| 1737 | moveNamedItem|namedItem|nextNode|nextSibling|normalize|observe|open| 1738 | parentNode|pause|play|postMessage|prepend|preventDefault|previousNode| 1739 | previousSibling|probablySupportsContext|queryCommandEnabled| 1740 | queryCommandIndeterm|queryCommandState|queryCommandSupported|queryCommandValue| 1741 | querySelector|querySelectorAll|registerContentHandler|registerElement| 1742 | registerProtocolHandler|releaseCapture|releaseEvents|remove|removeAttribute| 1743 | removeAttributeNode|removeAttributeNS|removeChild|removeEventListener| 1744 | removeItem|replace|replaceChild|replaceData|replaceWith|reportValidity| 1745 | requestFullscreen|requestPointerLock|reset|scroll|scrollBy|scrollIntoView| 1746 | scrollTo|seekToNextFrame|select|selectNode|selectNodeContents|set|setAttribute| 1747 | setAttributeNode|setAttributeNodeNS|setAttributeNS|setCapture| 1748 | setCustomValidity|setEnd|setEndAfter|setEndBefore|setItem|setNamedItem| 1749 | setRangeText|setSelectionRange|setSinkId|setStart|setStartAfter|setStartBefore| 1750 | slice|splitText|stepDown|stepUp|stopImmediatePropagation|stopPropagation| 1751 | submit|substringData|supports|surroundContents|takeRecords|terminate|toBlob| 1752 | toDataURL|toggle|toString|values|write|writeln)\\b 1753 | ''' 1754 | 'name': 'support.function.dom.js' 1755 | } 1756 | { 1757 | 'match': "[a-zA-Z_$][\\w$]*" 1758 | 'name': 'entity.name.function.js' 1759 | } 1760 | { 1761 | 'match': '\\d[\\w$]*' 1762 | 'name': 'invalid.illegal.identifier.js' 1763 | } 1764 | ] 1765 | 'end': '(?<=\\))' 1766 | 'name': 'meta.method-call.js' 1767 | 'patterns': [ 1768 | { 1769 | 'include': '#arguments' 1770 | } 1771 | ] 1772 | } 1773 | ] 1774 | 'function_calls': 1775 | 'patterns': [ 1776 | { 1777 | # functionCall(arg1, "arg2", [...]) 1778 | 'begin': '([\\w$]+)\\s*(?=\\()' 1779 | 'beginCaptures': 1780 | '1': 1781 | 'patterns': [ 1782 | { 1783 | 'match': '''(?x) 1784 | \\b(isNaN|isFinite|eval|uneval|parseInt|parseFloat|decodeURI| 1785 | decodeURIComponent|encodeURI|encodeURIComponent|escape|unescape| 1786 | require|set(Interval|Timeout)|clear(Interval|Timeout))\\b 1787 | ''' 1788 | 'name': 'support.function.js' 1789 | } 1790 | { 1791 | 'match': "[a-zA-Z_$][\\w$]*" 1792 | 'name': 'entity.name.function.js' 1793 | } 1794 | { 1795 | 'match': '\\d[\\w$]*' 1796 | 'name': 'invalid.illegal.identifier.js' 1797 | } 1798 | ] 1799 | 'end': '(?<=\\))' 1800 | 'name': 'meta.function-call.js' 1801 | 'patterns': [ 1802 | { 1803 | 'include': '#arguments' 1804 | } 1805 | ] 1806 | } 1807 | ] 1808 | 'objects': 1809 | 'patterns': [ 1810 | { 1811 | # OBJ in OBJ.prop, OBJ.methodCall() 1812 | 'match': '[A-Z][A-Z0-9_$]*(?=\\s*\\.\\s*[a-zA-Z_$]\\w*)' 1813 | 'name': 'constant.other.object.js' 1814 | } 1815 | { 1816 | # obj in obj.prop, obj.methodCall() 1817 | 'match': '[a-zA-Z_$][\\w$]*(?=\\s*\\.\\s*[a-zA-Z_$]\\w*)' 1818 | 'name': 'variable.other.object.js' 1819 | } 1820 | ] 1821 | 'properties': 1822 | 'patterns': [ 1823 | { 1824 | # PROP1 in obj.PROP1.prop2, func().PROP1.prop2 1825 | 'match': '(\\.)\\s*([A-Z][A-Z0-9_$]*\\b\\$*)(?=\\s*\\.\\s*[a-zA-Z_$]\\w*)' 1826 | 'captures': 1827 | '1': 1828 | 'name': 'meta.delimiter.property.period.js' 1829 | '2': 1830 | 'name': 'constant.other.object.property.js' 1831 | } 1832 | { 1833 | # prop1 in obj.prop1.prop2, func().prop1.prop2 1834 | 'match': '(\\.)\\s*(\\$*[a-zA-Z_$][\\w$]*)(?=\\s*\\.\\s*[a-zA-Z_$]\\w*)' 1835 | 'captures': 1836 | '1': 1837 | 'name': 'meta.delimiter.property.period.js' 1838 | '2': 1839 | 'name': 'variable.other.object.property.js' 1840 | } 1841 | { 1842 | # PROP in obj.PROP, func().PROP 1843 | 'match': '(\\.)\\s*([A-Z][A-Z0-9_$]*\\b\\$*)' 1844 | 'captures': 1845 | '1': 1846 | 'name': 'meta.delimiter.property.period.js' 1847 | '2': 1848 | 'name': 'constant.other.property.js' 1849 | } 1850 | { 1851 | # prop in obj.prop, func().prop 1852 | 'match': '(\\.)\\s*(\\$*[a-zA-Z_$][\\w$]*)' 1853 | 'captures': 1854 | '1': 1855 | 'name': 'meta.delimiter.property.period.js' 1856 | '2': 1857 | 'name': 'variable.other.property.js' 1858 | } 1859 | { 1860 | # 123illegal in obj.123illegal, func().123illegal 1861 | 'match': '(\\.)\\s*([0-9][\\w$]*)' 1862 | 'captures': 1863 | '1': 1864 | 'name': 'meta.delimiter.property.period.js' 1865 | '2': 1866 | 'name': 'invalid.illegal.identifier.js' 1867 | } 1868 | ] 1869 | 'interpolated_js': 1870 | 'patterns': [ 1871 | { 1872 | 'begin': '\\${' 1873 | 'captures': 1874 | '0': 1875 | 'name': 'punctuation.section.embedded.js' 1876 | 'end': '}' 1877 | 'name': 'source.js.embedded.source' 1878 | 'patterns': [ 1879 | { 1880 | 'begin': '{' 1881 | 'beginCaptures': 1882 | '0': 1883 | 'name': 'meta.brace.curly.js' 1884 | 'end': '}' 1885 | 'endCaptures': 1886 | '0': 1887 | 'name': 'meta.brace.curly.js' 1888 | 'patterns': [ 1889 | { 1890 | 'include': '$self' 1891 | } 1892 | ] 1893 | } 1894 | { 1895 | 'include': '$self' 1896 | } 1897 | ] 1898 | } 1899 | ] 1900 | 'comments': 1901 | 'patterns': [ 1902 | { 1903 | 'captures': 1904 | '1': 1905 | 'name': 'punctuation.definition.comment.begin.js' 1906 | '2': 1907 | 'name': 'punctuation.definition.comment.end.js' 1908 | 'match': '(/\\*)(\\*/)' 1909 | 'name': 'comment.block.empty.js' 1910 | } 1911 | { 1912 | 'begin': '/\\*\\*' 1913 | 'beginCaptures': 1914 | '0': 1915 | 'name': 'punctuation.definition.comment.begin.js' 1916 | 'end': '\\*/' 1917 | 'endCaptures': 1918 | '0': 1919 | 'name': 'punctuation.definition.comment.end.js' 1920 | 'name': 'comment.block.documentation.js' 1921 | 'patterns': [ 1922 | { 1923 | 'include': 'source.jsdoc' 1924 | } 1925 | ] 1926 | } 1927 | { 1928 | 'begin': '/\\*' 1929 | 'beginCaptures': 1930 | '0': 1931 | 'name': 'punctuation.definition.comment.begin.js' 1932 | 'end': '\\*/' 1933 | 'endCaptures': 1934 | '0': 1935 | 'name': 'punctuation.definition.comment.end.js' 1936 | 'name': 'comment.block.js' 1937 | } 1938 | { 1939 | 'begin': '//' 1940 | 'beginCaptures': 1941 | '0': 1942 | 'name': 'punctuation.definition.comment.js' 1943 | 'end': '$' 1944 | 'name': 'comment.line.double-slash.js' 1945 | } 1946 | ] 1947 | 'switch_statement': 1948 | 'patterns': [ 1949 | { 1950 | # switch(expression) {...} 1951 | 'begin': '\\bswitch\\b' 1952 | 'beginCaptures': 1953 | '0': 1954 | 'name': 'keyword.control.switch.js' 1955 | 'end': '}' 1956 | 'endCaptures': 1957 | '0': 1958 | 'name': 'punctuation.definition.section.switch-block.end.bracket.curly.js' 1959 | 'name': 'meta.switch-statement.js' 1960 | 'patterns': [ 1961 | { 1962 | 'begin': '\\(' 1963 | 'beginCaptures': 1964 | '0': 1965 | 'name': 'punctuation.definition.switch-expression.begin.bracket.round.js' 1966 | 'end': '\\)' 1967 | 'endCaptures': 1968 | '0': 1969 | 'name': 'punctuation.definition.switch-expression.end.bracket.round.js' 1970 | 'patterns': [ 1971 | 'include': '$self' 1972 | ] 1973 | } 1974 | { 1975 | 'begin': '{' 1976 | 'beginCaptures': 1977 | '0': 1978 | 'name': 'punctuation.definition.section.switch-block.begin.bracket.curly.js' 1979 | 'end': '(?=})' 1980 | 'patterns': [ 1981 | { 1982 | 'begin': '\\bcase\\b' 1983 | 'beginCaptures': 1984 | '0': 1985 | 'name': 'keyword.control.case.js' 1986 | 'end': ':' 1987 | 'endCaptures': 1988 | '0': 1989 | 'name': 'punctuation.definition.section.case-statement.js' 1990 | 'patterns': [ 1991 | { 1992 | 'include': '#prevent_object_keys_matching' 1993 | } 1994 | { 1995 | 'include': '$self' 1996 | } 1997 | ] 1998 | } 1999 | { 2000 | 'match': '(?:^\\s*)?\\b(default)\\b\\s*(:)' 2001 | 'captures': 2002 | '1': 2003 | 'name': 'keyword.control.default.js' 2004 | '2': 2005 | 'name': 'punctuation.definition.section.case-statement.js' 2006 | } 2007 | { 2008 | 'include': '$self' 2009 | } 2010 | ] 2011 | } 2012 | ] 2013 | } 2014 | ] 2015 | 'prevent_object_keys_matching': 2016 | 'patterns': [ 2017 | { 2018 | # e.g. don't treat null as an object key in 2019 | # ? null : 2020 | # case null: 2021 | 'match': '(\\w+)(?=\\s*:)' 2022 | 'captures': 2023 | '1': 2024 | 'patterns': [ 2025 | 'include': '$self' 2026 | ] 2027 | } 2028 | ] 2029 | -------------------------------------------------------------------------------- /grammars/jsdoc.cson: -------------------------------------------------------------------------------- 1 | 'scopeName': 'source.jsdoc' 2 | 'name': 'JSDoc' 3 | 'patterns': [ 4 | { 5 | # @access private|protected|public 6 | 'captures': 7 | '1': 8 | 'name': 'storage.type.class.jsdoc' 9 | '2': 10 | 'name': 'punctuation.definition.block.tag.jsdoc' 11 | '3': 12 | 'name': 'constant.language.access-type.jsdoc' 13 | 'match': '''(?x) 14 | ((@)(?:access|api)) 15 | \\s+ 16 | (private|protected|public) 17 | \\b 18 | ''' 19 | } 20 | { 21 | # @author name [] 22 | 'match': '''(?x) 23 | ((@)author) 24 | \\s+ 25 | ( 26 | [^@\\s<>*/] 27 | (?:[^@<>*/]|\\*[^/])* 28 | ) 29 | (?: 30 | \\s* 31 | (<) 32 | ([^>\\s]+) 33 | (>) 34 | )? 35 | ''' 36 | 'captures': 37 | '1': 38 | 'name': 'storage.type.class.jsdoc' 39 | '2': 40 | 'name': 'punctuation.definition.block.tag.jsdoc' 41 | '3': 42 | 'name': 'entity.name.type.instance.jsdoc' 43 | '4': 44 | 'name': 'punctuation.definition.bracket.angle.begin.jsdoc' 45 | '5': 46 | 'name': 'constant.other.email.link.underline.jsdoc' 47 | '6': 48 | 'name': 'punctuation.definition.bracket.angle.end.jsdoc' 49 | } 50 | { 51 | # @borrows as 52 | 'match': '''(?x) 53 | ((@)borrows) \\s+ 54 | ((?:[^@\\s*/]|\\*[^/])+) # 55 | \\s+ (as) \\s+ # as 56 | ((?:[^@\\s*/]|\\*[^/])+) # 57 | ''' 58 | 'captures': 59 | '1': 60 | 'name': 'storage.type.class.jsdoc' 61 | '2': 62 | 'name': 'punctuation.definition.block.tag.jsdoc' 63 | '3': 64 | 'name': 'entity.name.type.instance.jsdoc' 65 | '4': 66 | 'name': 'keyword.operator.control.jsdoc' 67 | '5': 68 | 'name': 'entity.name.type.instance.jsdoc' 69 | } 70 | { 71 | # @example text(); 72 | 'name': 'meta.example.jsdoc' 73 | 'begin': '((@)example)\\s+' 74 | 'end': '(?=@|\\*/)' 75 | 'beginCaptures': 76 | '1': 77 | 'name': 'storage.type.class.jsdoc' 78 | '2': 79 | 'name': 'punctuation.definition.block.tag.jsdoc' 80 | 'patterns': [ 81 | { 82 | # Match to prevent leading asterisk being highlighted as JS 83 | 'match': '^\\s\\*\\s+' 84 | } 85 | { 86 | # Leading … before example 87 | 'begin': '\\G(<)caption(>)' 88 | 'beginCaptures': 89 | '0': 90 | 'name': 'entity.name.tag.inline.jsdoc' 91 | '1': 92 | 'name': 'punctuation.definition.bracket.angle.begin.jsdoc' 93 | '2': 94 | 'name': 'punctuation.definition.bracket.angle.end.jsdoc' 95 | 'contentName': 'constant.other.description.jsdoc' 96 | 'end': '()|(?=\\*/)' 97 | 'endCaptures': 98 | '0': 99 | 'name': 'entity.name.tag.inline.jsdoc' 100 | '1': 101 | 'name': 'punctuation.definition.bracket.angle.begin.jsdoc' 102 | '2': 103 | 'name': 'punctuation.definition.bracket.angle.end.jsdoc' 104 | } 105 | { 106 | # Highlighted JavaScript example 107 | 'match': '[^\\s@*](?:[^*]|\\*[^/])*' 108 | 'captures': 109 | '0': 110 | 'name': 'source.embedded.js' 111 | 'patterns': [ 112 | { 113 | 'include': 'source.js' 114 | } 115 | ] 116 | } 117 | ] 118 | } 119 | { 120 | # @kind type 121 | 'captures': 122 | '1': 123 | 'name': 'storage.type.class.jsdoc' 124 | '2': 125 | 'name': 'punctuation.definition.block.tag.jsdoc' 126 | '3': 127 | 'name': 'constant.language.symbol-type.jsdoc' 128 | 'match': '''(?x) 129 | ((@)kind) 130 | \\s+ 131 | (class|constant|event|external|file|function|member|mixin|module|namespace|typedef) 132 | \\b 133 | ''' 134 | } 135 | { 136 | # @see namepathOrURL 137 | 'captures': 138 | '1': 139 | 'name': 'storage.type.class.jsdoc' 140 | '2': 141 | 'name': 'punctuation.definition.block.tag.jsdoc' 142 | '3': 143 | 'name': 'variable.other.link.underline.jsdoc' 144 | '4': 145 | 'name': 'entity.name.type.instance.jsdoc' 146 | 'match': '''(?x) 147 | ((@)see) 148 | \\s+ 149 | (?: 150 | # URL 151 | ( 152 | (?=https?://) 153 | (?:[^\\s*]|\\*[^/])+ 154 | ) 155 | | 156 | # JSDoc namepath 157 | ( 158 | (?! 159 | # Avoid matching bare URIs (also acceptable as links) 160 | https?:// 161 | | 162 | # Avoid matching {@inline tags}; we match those below 163 | (?:\\[[^\\[\\]]*\\])? # Possible description [preceding]{@tag} 164 | {@(?:link|linkcode|linkplain|tutorial)\\b 165 | ) 166 | # Matched namepath 167 | (?:[^@\\s*/]|\\*[^/])+ 168 | ) 169 | ) 170 | ''' 171 | } 172 | { 173 | # @template Foo,Bar 174 | 'captures': 175 | '1': 176 | 'name': 'storage.type.class.jsdoc' 177 | '2': 178 | 'name': 'punctuation.definition.block.tag.jsdoc' 179 | '3': 180 | 'name': 'variable.other.jsdoc' 181 | 'patterns': [ 182 | { 183 | 'match': ',' 184 | 'name': 'punctuation.delimiter.object.comma.jsdoc' 185 | } 186 | ] 187 | 'match': '''(?x) 188 | ((@)template) 189 | \\s+ 190 | # One or more valid identifiers 191 | ( 192 | [A-Za-z_$] # First character: non-numeric word character 193 | [\\w$.\\[\\]]* # Rest of identifier 194 | (?: # Possible list of additional identifiers 195 | \\s* , \\s* 196 | [A-Za-z_$] 197 | [\\w$.\\[\\]]* 198 | )* 199 | ) 200 | ''' 201 | } 202 | { 203 | # Tags followed by an identifier token 204 | # - @ identifier 205 | 'captures': 206 | '1': 207 | 'name': 'storage.type.class.jsdoc' 208 | '2': 209 | 'name': 'punctuation.definition.block.tag.jsdoc' 210 | '3': 211 | 'name': 'variable.other.jsdoc' 212 | 'match': '''(?x) 213 | ( 214 | (@) 215 | (?:arg|argument|const|constant|member|namespace|param|var) 216 | ) 217 | \\s+ 218 | ( 219 | [A-Za-z_$] 220 | [\\w$.\\[\\]]* 221 | ) 222 | ''' 223 | } 224 | { 225 | # Tags followed by a type expression, then a namepath 226 | # - @ {type} namepath 227 | 'begin': '((@)typedef)\\s+(?={)' 228 | 'beginCaptures': 229 | '1': 230 | 'name': 'storage.type.class.jsdoc' 231 | '2': 232 | 'name': 'punctuation.definition.block.tag.jsdoc' 233 | 'end': '(?=\\s|\\*/|[^{}\\[\\]A-Za-z_$])' 234 | 'patterns': [ 235 | { 236 | 'include': '#type' 237 | } 238 | { 239 | 'name': 'entity.name.type.instance.jsdoc' 240 | 'match': '(?:[^@\\s*/]|\\*[^/])+' 241 | } 242 | ] 243 | } 244 | { 245 | # Tags followed by a type expression, then an identifier 246 | # - @ {type} identifier 247 | 'begin': '((@)(?:arg|argument|const|constant|member|namespace|param|prop|property|var))\\s+(?={)' 248 | 'beginCaptures': 249 | '1': 250 | 'name': 'storage.type.class.jsdoc' 251 | '2': 252 | 'name': 'punctuation.definition.block.tag.jsdoc' 253 | 'end': '(?=\\s|\\*/|[^{}\\[\\]A-Za-z_$])' 254 | 'patterns': [ 255 | { 256 | 'include': '#type' 257 | } 258 | { 259 | 'match': '([A-Za-z_$][\\w$.\\[\\]]*)' 260 | 'name': 'variable.other.jsdoc' 261 | } 262 | { 263 | # Optional value 264 | 'name': 'variable.other.jsdoc' 265 | 'match': '''(?x) 266 | (\\[)\\s* 267 | [\\w$]+ 268 | (?: 269 | (?:\\[\\])? # Foo[].bar properties within an array 270 | \\. # Foo.Bar namespaced parameter 271 | [\\w$]+ 272 | )* 273 | (?: 274 | \\s* 275 | (=) # [foo=bar] Default parameter value 276 | \\s* 277 | ( 278 | # The inner regexes are to stop the match early at */ and to not stop at escaped quotes 279 | (?> 280 | "(?:(?:\\*(?!/))|(?:\\\\(?!"))|[^*\\\\])*?" | # [foo="bar"] Double-quoted 281 | '(?:(?:\\*(?!/))|(?:\\\\(?!'))|[^*\\\\])*?' | # [foo='bar'] Single-quoted 282 | \\[ (?:(?:\\*(?!/))|[^*])*? \\] | # [foo=[1,2]] Array literal 283 | (?:(?:\\*(?!/))|\\s(?!\\s*\\])|\\[.*?(?:\\]|(?=\\*/))|[^*\\s\\[\\]])* # Everything else (sorry) 284 | )* 285 | ) 286 | )? 287 | \\s*(?:(\\])((?:[^*\\s]|\\*[^\\s/])+)?|(?=\\*/)) 288 | ''' 289 | 'captures': 290 | '1': 291 | 'name': 'punctuation.definition.optional-value.begin.bracket.square.jsdoc' 292 | '2': 293 | 'name': 'keyword.operator.assignment.jsdoc' 294 | '3': 295 | 'name': 'source.embedded.js' 296 | 'patterns': [ 297 | { 298 | 'include': '#inline-tags' 299 | } 300 | { 301 | 'include': 'source.js' 302 | } 303 | ] 304 | '4': 305 | 'name': 'punctuation.definition.optional-value.end.bracket.square.jsdoc' 306 | '5': 307 | 'name': 'invalid.illegal.syntax.jsdoc' 308 | } 309 | ] 310 | } 311 | { 312 | # Tags followed by a type expression 313 | # - @ {type} 314 | 'begin': '''(?x) 315 | ( 316 | (@) 317 | (?:define|enum|exception|export|extends|lends|implements|modifies 318 | |namespace|private|protected|returns?|suppress|this|throws|type 319 | |yields?) 320 | ) 321 | \\s+(?={) 322 | ''' 323 | 'beginCaptures': 324 | '1': 325 | 'name': 'storage.type.class.jsdoc' 326 | '2': 327 | 'name': 'punctuation.definition.block.tag.jsdoc' 328 | 'end': '(?=\\s|\\*/|[^{}\\[\\]A-Za-z_$])' 329 | 'patterns': [ 330 | { 331 | 'include': '#type' 332 | } 333 | ] 334 | } 335 | { 336 | # Tags followed by a namepath 337 | # - @ namepath 338 | 'captures': 339 | '1': 340 | 'name': 'storage.type.class.jsdoc' 341 | '2': 342 | 'name': 'punctuation.definition.block.tag.jsdoc' 343 | '3': 344 | 'name': 'entity.name.type.instance.jsdoc' 345 | 'match': '''(?x) 346 | ( 347 | (@) 348 | (?:alias|augments|callback|constructs|emits|event|fires|exports? 349 | |extends|external|function|func|host|lends|listens|interface|memberof!? 350 | |method|module|mixes|mixin|name|requires|see|this|typedef|uses) 351 | ) 352 | \\s+ 353 | ( 354 | (?: 355 | [^{}@\\s*] | \\*[^/] 356 | )+ 357 | ) 358 | ''' 359 | } 360 | { 361 | # Tags followed by a quoted arbitrary value 362 | # - @ "Quoted value" 363 | 'begin': '((@)(?:default(?:value)?|license|version))\\s+(([\'"]))' 364 | 'beginCaptures': 365 | '1': 366 | 'name': 'storage.type.class.jsdoc' 367 | '2': 368 | 'name': 'punctuation.definition.block.tag.jsdoc' 369 | '3': 370 | 'name': 'variable.other.jsdoc' 371 | '4': 372 | 'name': 'punctuation.definition.string.begin.jsdoc' 373 | 'contentName': 'variable.other.jsdoc' 374 | 'end': '(\\3)|(?=$|\\*/)' 375 | 'endCaptures': 376 | '0': 377 | 'name': 'variable.other.jsdoc' 378 | '1': 379 | 'name': 'punctuation.definition.string.end.jsdoc' 380 | } 381 | { 382 | # Tags followed by an arbitrary value 383 | # - @ value 384 | 'captures': 385 | '1': 386 | 'name': 'storage.type.class.jsdoc' 387 | '2': 388 | 'name': 'punctuation.definition.block.tag.jsdoc' 389 | '3': 390 | 'name': 'variable.other.jsdoc' 391 | 'match': '((@)(?:default(?:value)?|license|tutorial|variation|version))\\s+([^\\s*]+)' 392 | } 393 | { 394 | # Tags without arguments, or a tag without expected arguments. Because JSDoc permits 395 | # tags to be spread across lines, we should at least highlight the opening tag for 396 | # stuff like this: 397 | # 398 | # /** 399 | # * @param 400 | # * {type} 401 | # * name 402 | 'captures': 403 | '1': 404 | 'name': 'punctuation.definition.block.tag.jsdoc' 405 | 'match': '''(?x) (@) 406 | (?:abstract|access|alias|api|arg|argument|async|attribute|augments|author|beta|borrows|bubbles 407 | |callback|chainable|class|classdesc|code|config|const|constant|constructor|constructs|copyright 408 | |default|defaultvalue|define|deprecated|desc|description|dict|emits|enum|event|example|exception 409 | |exports?|extends|extension(?:_?for)?|external|externs|file|fileoverview|final|fires|for|func 410 | |function|generator|global|hideconstructor|host|ignore|implements|implicitCast|inherit[Dd]oc 411 | |inner|instance|interface|internal|kind|lends|license|listens|main|member|memberof!?|method 412 | |mixes|mixins?|modifies|module|name|namespace|noalias|nocollapse|nocompile|nosideeffects 413 | |override|overview|package|param|polymer(?:Behavior)?|preserve|private|prop|property|protected 414 | |public|read[Oo]nly|record|require[ds]|returns?|see|since|static|struct|submodule|summary 415 | |suppress|template|this|throws|todo|tutorial|type|typedef|unrestricted|uses|var|variation 416 | |version|virtual|writeOnce|yields?) 417 | \\b 418 | ''' 419 | 'name': 'storage.type.class.jsdoc' 420 | } 421 | { 422 | 'include': '#inline-tags' 423 | } 424 | ] 425 | 426 | 'repository': 427 | # Balanced brackets (square or curly) 428 | 'brackets': 429 | 'patterns': [ 430 | { 431 | 'begin': '{' 432 | 'end': '}|(?=\\*/)' 433 | 'patterns': [ 434 | { 435 | 'include': '#brackets' 436 | } 437 | ] 438 | } 439 | { 440 | 'begin': '\\[' 441 | 'end': '\\]|(?=\\*/)' 442 | 'patterns': [ 443 | { 444 | 'include': '#brackets' 445 | } 446 | ] 447 | } 448 | ] 449 | 'inline-tags': 450 | 'patterns': [ 451 | { 452 | # Description preceding {@inline tag} 453 | 'captures': 454 | '1': 455 | 'name': 'punctuation.definition.bracket.square.begin.jsdoc' 456 | '2': 457 | 'name': 'punctuation.definition.bracket.square.end.jsdoc' 458 | 'match': '(\\[)[^\\]]+(\\])(?={@(?:link|linkcode|linkplain|tutorial))' 459 | 'name': 'constant.other.description.jsdoc' 460 | } 461 | { 462 | # {@link|@tutorial …} 463 | 'begin': '({)((@)(?:link(?:code|plain)?|tutorial))\\s*' 464 | 'beginCaptures': 465 | '1': 466 | 'name': 'punctuation.definition.bracket.curly.begin.jsdoc' 467 | '2': 468 | 'name': 'storage.type.class.jsdoc' 469 | '3': 470 | 'name': 'punctuation.definition.inline.tag.jsdoc' 471 | 'end': '}|(?=\\*/)' 472 | 'endCaptures': 473 | '0': 474 | 'name': 'punctuation.definition.bracket.curly.end.jsdoc' 475 | 'name': 'entity.name.type.instance.jsdoc' 476 | 'patterns': [ 477 | { 478 | 'captures': 479 | '1': 480 | 'name': 'variable.other.link.underline.jsdoc' 481 | '2': 482 | 'name': 'punctuation.separator.pipe.jsdoc' 483 | 'match': '\\G((?=https?://)(?:[^|}\\s*]|\\*[/])+)(\\|)?' 484 | } 485 | { 486 | 'captures': 487 | '1': 488 | 'name': 'variable.other.description.jsdoc' 489 | '2': 490 | 'name': 'punctuation.separator.pipe.jsdoc' 491 | 'match': '\\G((?:[^{}@\\s|*]|\\*[^/])+)(\\|)?' 492 | } 493 | ] 494 | } 495 | ] 496 | # {type} 497 | 'type': 498 | 'patterns': [ 499 | { 500 | # {unclosed 501 | 'match': '\\G{(?:[^}*]|\\*[^/}])+$' 502 | 'name': 'invalid.illegal.type.jsdoc' 503 | } 504 | { 505 | 'begin': '\\G({)' 506 | 'beginCaptures': 507 | '0': 508 | 'name': 'entity.name.type.instance.jsdoc' 509 | '1': 510 | 'name': 'punctuation.definition.bracket.curly.begin.jsdoc' 511 | 'contentName': 'entity.name.type.instance.jsdoc' 512 | 'end': '((}))\\s*|(?=\\*/)' 513 | 'endCaptures': 514 | '1': 515 | 'name': 'entity.name.type.instance.jsdoc' 516 | '2': 517 | 'name': 'punctuation.definition.bracket.curly.end.jsdoc' 518 | 'patterns': [ 519 | { 520 | 'include': '#brackets' 521 | } 522 | ] 523 | } 524 | ] 525 | -------------------------------------------------------------------------------- /grammars/regular expression replacement (javascript).cson: -------------------------------------------------------------------------------- 1 | 'scopeName': 'source.js.regexp.replacement' 2 | 'patterns': [ 3 | { 4 | 'include': '#regexp-replacement' 5 | } 6 | ] 7 | 'repository': 8 | 'regexp-replacement': 9 | 'patterns': [ 10 | { 11 | 'match': '\\$([1-9][0-9]|[1-9]|0[1-9]|[&`\'])' 12 | 'name': 'variable.regexp.replacement' 13 | } 14 | { 15 | 'match': '\\$\\$' 16 | 'name': 'constant.character.escape.dollar.regexp.replacement' 17 | } 18 | { 19 | 'match': '\\\\[^$]' 20 | 'name': 'constant.character.escape.backslash.regexp.replacement' 21 | } 22 | ] 23 | -------------------------------------------------------------------------------- /grammars/regular expressions (javascript).cson: -------------------------------------------------------------------------------- 1 | 'scopeName': 'source.js.regexp' 2 | 'patterns': [ 3 | { 4 | 'include': '#regexp' 5 | } 6 | ] 7 | 'repository': 8 | 'regex-character-class': 9 | 'patterns': [ 10 | { 11 | 'match': '\\\\[wWsSdDtrnvf]|\\.' 12 | 'name': 'constant.character.character-class.regexp' 13 | } 14 | { 15 | 'match': '\\\\([0-7]{3}|x[0-9A-Fa-f]{2}|u[0-9A-Fa-f]{4})' 16 | 'name': 'constant.character.numeric.regexp' 17 | } 18 | { 19 | 'match': '\\\\c[A-Z]' 20 | 'name': 'constant.character.control.regexp' 21 | } 22 | { 23 | 'match': '\\\\.' 24 | 'name': 'constant.character.escape.backslash.regexp' 25 | } 26 | ] 27 | 'regexp': 28 | 'patterns': [ 29 | { 30 | 'match': '\\\\[bB]|\\^|\\$' 31 | 'name': 'keyword.control.anchor.regexp' 32 | } 33 | { 34 | 'match': '\\\\[1-9]\\d*|\\\\k<[a-zA-Z_$][\\w$]*>' 35 | 'name': 'keyword.other.back-reference.regexp' 36 | } 37 | { 38 | 'match': '[?+*]|\\{(\\d+,\\d+|\\d+,|,\\d+|\\d+)\\}\\??' 39 | 'name': 'keyword.operator.quantifier.regexp' 40 | } 41 | { 42 | 'match': '\\|' 43 | 'name': 'keyword.operator.or.regexp' 44 | } 45 | { 46 | 'begin': '(\\()(?:(\\?=)|(\\?!)|(\\?<=)|(\\?))?' 71 | 'beginCaptures': 72 | '0': 73 | 'name': 'punctuation.definition.group.regexp' 74 | 'end': '\\)' 75 | 'endCaptures': 76 | '0': 77 | 'name': 'punctuation.definition.group.regexp' 78 | 'name': 'meta.group.regexp' 79 | 'patterns': [ 80 | { 81 | 'include': '#regexp' 82 | } 83 | ] 84 | } 85 | { 86 | 'begin': '(\\[)(\\^)?' 87 | 'beginCaptures': 88 | '1': 89 | 'name': 'punctuation.definition.character-class.regexp' 90 | '2': 91 | 'name': 'keyword.operator.negation.regexp' 92 | 'end': '(\\])' 93 | 'endCaptures': 94 | '1': 95 | 'name': 'punctuation.definition.character-class.regexp' 96 | 'name': 'constant.other.character-class.set.regexp' 97 | 'patterns': [ 98 | { 99 | 'captures': 100 | '1': 101 | 'name': 'constant.character.numeric.regexp' 102 | '2': 103 | 'name': 'constant.character.control.regexp' 104 | '3': 105 | 'name': 'constant.character.escape.backslash.regexp' 106 | '4': 107 | 'name': 'constant.character.numeric.regexp' 108 | '5': 109 | 'name': 'constant.character.control.regexp' 110 | '6': 111 | 'name': 'constant.character.escape.backslash.regexp' 112 | 'match': '(?:.|(\\\\(?:[0-7]{3}|x[0-9A-Fa-f]{2}|u[0-9A-Fa-f]{4}))|(\\\\c[A-Z])|(\\\\.))\\-(?:[^\\]\\\\]|(\\\\(?:[0-7]{3}|x[0-9A-Fa-f]{2}|u[0-9A-Fa-f]{4}))|(\\\\c[A-Z])|(\\\\.))' 113 | 'name': 'constant.other.character-class.range.regexp' 114 | } 115 | { 116 | 'include': '#regex-character-class' 117 | } 118 | ] 119 | } 120 | { 121 | 'include': '#regex-character-class' 122 | } 123 | ] 124 | -------------------------------------------------------------------------------- /grammars/tree-sitter-javascript.cson: -------------------------------------------------------------------------------- 1 | name: 'JavaScript' 2 | scopeName: 'source.js' 3 | type: 'tree-sitter' 4 | parser: 'tree-sitter-javascript' 5 | 6 | fileTypes: ['js', 'jsx'] 7 | 8 | injectionRegex: '^js$|^JS$|javascript|JavaScript' 9 | 10 | firstLineRegex: [ 11 | # shebang line 12 | '^#!.*\\b(node)\\r?\\n' 13 | 14 | # vim modeline 15 | 'vim\\b.*\\bset\\b.*\\b(filetype|ft|syntax)=(js|javascript)' 16 | ] 17 | 18 | folds: [ 19 | { 20 | type: 'comment' 21 | } 22 | { 23 | type: ['jsx_element', 'template_string'], 24 | start: {index: 0} 25 | end: {index: -1} 26 | } 27 | { 28 | type: 'jsx_self_closing_element' 29 | start: {index: 1} 30 | end: {index: -2} 31 | } 32 | { 33 | start: {index: 0, type: '{'} 34 | end: {index: -1, type: '}'} 35 | } 36 | { 37 | start: {index: 0, type: '['} 38 | end: {index: -1, type: ']'} 39 | } 40 | { 41 | start: {index: 0, type: '('} 42 | end: {index: -1, type: ')'} 43 | } 44 | { 45 | type: ['switch_case', 'switch_default'] 46 | start: {index: 0} 47 | end: {type: 'break_statement', index: -1} 48 | } 49 | { 50 | type: ['switch_case', 'switch_default'] 51 | start: {index: 0} 52 | } 53 | ] 54 | 55 | comments: 56 | start: '// ' 57 | 58 | scopes: 59 | 'program': 'source.js' 60 | 61 | 'property_identifier': [ 62 | { 63 | match: '^[\$A-Z_]+$', 64 | scopes: 'constant.other.property.js' 65 | } 66 | 67 | 'variable.other.object.property' 68 | ] 69 | 70 | 'member_expression > property_identifier': 'variable.other.object.property.unquoted' 71 | 72 | 'formal_parameters > identifier': 'variable.parameter.function' 73 | 'formal_parameters > rest_parameter > identifier': 'variable.parameter.rest.function' 74 | 75 | 'shorthand_property_identifier': [ 76 | { 77 | match: '^[\$A-Z_]{2,}$', 78 | scopes: 'constant.other' 79 | } 80 | ] 81 | 82 | ' 83 | class > identifier, 84 | new_expression > identifier 85 | ': 'meta.class' 86 | 87 | ' 88 | jsx_opening_element > identifier, 89 | jsx_closing_element > identifier, 90 | jsx_self_closing_element > identifier 91 | ': [ 92 | { 93 | match: '^[A-Z]', 94 | scopes: 'meta.class.component.jsx' 95 | } 96 | ] 97 | 98 | 'call_expression > identifier': {match: '^[A-Z]', scopes: 'meta.class'} 99 | 'arrow_function > identifier:nth-child(0)': 'variable.parameter.function' 100 | 101 | 'function > identifier': 'entity.name.function' 102 | 'function_declaration > identifier': 'entity.name.function' 103 | 'generator_function > identifier': 'entity.name.function' 104 | 105 | 'call_expression > identifier': [ 106 | {match: '^require$', scopes: 'support.function'}, 107 | 'entity.name.function' 108 | ] 109 | 110 | 'call_expression > super': 'support.function.super' 111 | 112 | 'method_definition > property_identifier': 'entity.name.function' 113 | 'call_expression > member_expression > property_identifier': 'entity.name.function' 114 | 115 | 'identifier': [ 116 | { 117 | match: '^(global|globalThis|module|exports|__filename|__dirname)$', 118 | scopes: 'support.variable' 119 | }, 120 | { 121 | match: '^(window|self|frames|event|document|performance|screen|navigator|console)$' 122 | scopes: 'support.variable.dom' 123 | }, 124 | { 125 | exact: 'require', 126 | scopes: 'support.function' 127 | }, 128 | { 129 | match: '^[\$A-Z_]{2,}$', 130 | scopes: 'constant.other' 131 | }, 132 | { 133 | match: '^[A-Z]', 134 | scopes: 'meta.class' 135 | }, 136 | ] 137 | 138 | 'number': 'constant.numeric' 139 | 'string': 'string.quoted' 140 | 'regex': 'string.regexp' 141 | 'escape_sequence': 'constant.character.escape' 142 | 'template_string': 'string.quoted.template' 143 | 'undefined': 'constant.language' 144 | 'null': 'constant.language.null' 145 | 'true': 'constant.language.boolean.true' 146 | 'false': 'constant.language.boolean.false' 147 | 'comment': [ 148 | { 149 | match: "^//", 150 | scopes: 'comment.line' 151 | }, 152 | 'comment.block' 153 | ] 154 | 'hash_bang_line': 'comment.block' 155 | 156 | ' 157 | jsx_expression > "{", 158 | jsx_expression > "}", 159 | template_substitution > "${", 160 | template_substitution > "}" 161 | ': 'punctuation.section.embedded' 162 | 'template_substitution': 'embedded.source' 163 | 164 | '"("': 'punctuation.definition.parameters.begin.bracket.round' 165 | '")"': 'punctuation.definition.parameters.end.bracket.round' 166 | '"{"': 'punctuation.definition.function.body.begin.bracket.curly' 167 | '"}"': 'punctuation.definition.function.body.end.bracket.curly' 168 | '";"': 'punctuation.terminator.statement.semicolon' 169 | '"["': 'punctuation.definition.array.begin.bracket.square' 170 | '"]"': 'punctuation.definition.array.end.bracket.square' 171 | 172 | '"var"': 'storage.type' 173 | '"let"': 'storage.type' 174 | '"class"': 'storage.type' 175 | '"extends"': 'storage.modifier' 176 | '"const"': 'storage.modifier' 177 | '"static"': 'storage.modifier' 178 | '"function"': 'storage.type.function' 179 | '"=>"': 'storage.type.function.arrow' 180 | 181 | '"="': 'keyword.operator.js' 182 | '"+="': 'keyword.operator.js' 183 | '"-="': 'keyword.operator.js' 184 | '"*="': 'keyword.operator.js' 185 | '"/="': 'keyword.operator.js' 186 | '"%="': 'keyword.operator.js' 187 | '"<<="': 'keyword.operator.js' 188 | '">>="': 'keyword.operator.js' 189 | '">>>="': 'keyword.operator.js' 190 | '"&="': 'keyword.operator.js' 191 | '"^="': 'keyword.operator.js' 192 | '"|="': 'keyword.operator.js' 193 | '"!"': 'keyword.operator.js' 194 | '"+"': 'keyword.operator.js' 195 | '"-"': 'keyword.operator.js' 196 | '"*"': 'keyword.operator.js' 197 | '"/"': 'keyword.operator.js' 198 | '"%"': 'keyword.operator.js' 199 | '"=="': 'keyword.operator.js' 200 | '"==="': 'keyword.operator.js' 201 | '"!="': 'keyword.operator.js' 202 | '"!=="': 'keyword.operator.js' 203 | '">="': 'keyword.operator.js' 204 | '"<="': 'keyword.operator.js' 205 | '">"': 'keyword.operator.js' 206 | '"<"': 'keyword.operator.js' 207 | '":"': 'keyword.operator.js' 208 | '"?"': 'keyword.operator.js' 209 | '"&&"': 'keyword.operator.js' 210 | '"||"': 'keyword.operator.js' 211 | '"&"': 'keyword.operator.js' 212 | '"~"': 'keyword.operator.js' 213 | '"^"': 'keyword.operator.js' 214 | '">>"': 'keyword.operator.js' 215 | '">>>"': 'keyword.operator.js' 216 | '"<<"': 'keyword.operator.js' 217 | '"|"': 'keyword.operator.js' 218 | '"++"': 'keyword.operator.js' 219 | '"--"': 'keyword.operator.js' 220 | '"..."': 'keyword.operator.spread.js' 221 | 222 | '"in"': 'keyword.operator.in' 223 | '"instanceof"': 'keyword.operator.instanceof' 224 | '"of"': 'keyword.operator.of' 225 | '"new"': 'keyword.operator.new' 226 | '"typeof"': 'keyword.operator.typeof' 227 | 228 | '"get"': 'keyword.operator.setter' 229 | '"set"': 'keyword.operator.setter' 230 | 231 | '"."': 'meta.delimiter.period' 232 | '","': 'meta.delimiter.comma' 233 | 234 | '"as"': 'keyword.control' 235 | '"if"': 'keyword.control' 236 | '"do"': 'keyword.control' 237 | '"else"': 'keyword.control' 238 | '"while"': 'keyword.control' 239 | '"for"': 'keyword.control' 240 | '"return"': 'keyword.control' 241 | '"break"': 'keyword.control' 242 | '"continue"': 'keyword.control' 243 | '"throw"': 'keyword.control' 244 | '"try"': 'keyword.control' 245 | '"catch"': 'keyword.control' 246 | '"finally"': 'keyword.control' 247 | '"switch"': 'keyword.control' 248 | '"case"': 'keyword.control' 249 | '"default"': 'keyword.control' 250 | '"export"': 'keyword.control' 251 | '"import"': 'keyword.control' 252 | '"from"': 'keyword.control' 253 | '"yield"': 'keyword.control' 254 | '"async"': 'keyword.control' 255 | '"await"': 'keyword.control' 256 | '"debugger"': 'keyword.control' 257 | '"delete"': 'keyword.control' 258 | 259 | 'jsx_attribute > property_identifier': 'entity.other.attribute-name' 260 | 'jsx_opening_element > identifier': 'entity.name.tag' 261 | 'jsx_closing_element > identifier': 'entity.name.tag' 262 | 'jsx_self_closing_element > identifier': 'entity.name.tag' 263 | -------------------------------------------------------------------------------- /grammars/tree-sitter-jsdoc.cson: -------------------------------------------------------------------------------- 1 | name: 'JSDoc' 2 | scopeName: 'source.jsdoc' 3 | type: 'tree-sitter' 4 | parser: 'tree-sitter-jsdoc' 5 | 6 | injectionRegex: '^jsdoc$' 7 | 8 | scopes: 9 | 'tag_name': 'keyword.control' 10 | 'identifier': 'variable.other.jsdoc' 11 | 'type': 'support.type' 12 | 'path_expression > identifier': 'string' 13 | '"."': 'meta.delimiter.period' 14 | '":"': 'meta.delimiter.colon' 15 | '"/"': 'meta.delimiter.slash' 16 | '"#", "~"': 'meta.delimiter' 17 | -------------------------------------------------------------------------------- /grammars/tree-sitter-regex.cson: -------------------------------------------------------------------------------- 1 | name: 'Javascript RegExp' 2 | scopeName: 'source.js.regexp' 3 | type: 'tree-sitter' 4 | parser: 'tree-sitter-regex' 5 | 6 | injectionRegex: 'regex' 7 | 8 | scopes: 9 | 'pattern': 'string.quoted', 10 | 'group_name': 'variable.other.object.property' 11 | 'identity_escape, control_letter_escape, control_escape, class_escape': 'constant.character.character-class.regexp' 12 | 'start_assertion, end_assertion, boundary_assertion, non_boundary_assertion': 'constant.character.character-class.regexp' 13 | 'count_quantifier, one_or_more, zero_or_more, optional': 'storage.modifier' 14 | 'character_class': 'string.regexp' 15 | '"(", "(?", "(?:", "(?<"': 'punctuation.definition.parameters.begin.bracket.round' 16 | '">", ")"': 'punctuation.definition.parameters.end.bracket.round' 17 | '"=", "<=", "!", "~!#@%^&*|+=[]{}`?-…' 4 | 'commentStart': '// ' 5 | 'foldEndPattern': '^\\s*\\}|^\\s*\\]|^\\s*\\)' 6 | 'increaseIndentPattern': '(?x) 7 | \\{ [^}"\']*(//.*)? $ 8 | | \\[ [^\\]"\']*(//.*)? $ 9 | | \\( [^)"\']*(//.*)? $ 10 | ' 11 | 'decreaseIndentPattern': '(?x) 12 | ^ \\s* (\\s* /[*] .* [*]/ \\s*)* [}\\])] 13 | ' 14 | -------------------------------------------------------------------------------- /snippets/language-javascript.cson: -------------------------------------------------------------------------------- 1 | '.source.js, .source.flow': 2 | 'Object Method': 3 | 'prefix': 'kf' 4 | 'body': '${1:methodName}: function (${2:attribute}) {\n\t$3\n}${4:,}' 5 | 'Object key — key: "value"': 6 | 'prefix': 'kv' 7 | 'body': '${1:key}: ${2:\'${3:value}\'}${4:, }' 8 | 'Prototype': 9 | 'prefix': 'proto' 10 | 'body': '${1:ClassName}.prototype.${2:methodName} = function ($3) {\n\t$0\n};' 11 | 'do': 12 | 'prefix': 'do' 13 | 'body': 'do {\n\t$2\n} while (${1:true});' 14 | 'condition ? true : false': 15 | 'prefix': 'tern' 16 | 'body': '${1:condition} ? ${2:true} : ${3:false}' 17 | 'if': 18 | 'prefix': 'if' 19 | 'body': 'if (${1:true}) {\n\t$2\n}' 20 | 'if … else': 21 | 'prefix': 'ife' 22 | 'body': 'if (${1:true}) {\n\t$2\n} else {\n\t$3\n}' 23 | 'else': 24 | 'prefix': 'else' 25 | 'body': 'else {\n\t$1\n}' 26 | 'else if': 27 | 'prefix': 'elseif' 28 | 'body': 'else if (${1:true}) {\n\t$2\n}' 29 | 'for': 30 | 'prefix' : 'for' 31 | 'body' : 'for (var ${2:i} = 0; ${2:i} < ${1:array}.length; ${2:i}++) {\n\t${1:array}[${2:i}]$3\n}' 32 | 'for in': 33 | 'prefix': 'forin' 34 | 'body': 'for (var ${1:variable} in ${2:object}) {\n\t${3:if (${2:object}.hasOwnProperty(${1:variable})) {\n\t\t$4\n\t\\}}\n}' 35 | 'for of': 36 | 'prefix': 'forof' 37 | 'body': 'for (var ${1:variable} of ${2:iterable}) {\n\t$3\n}' 38 | 'forEach': 39 | 'prefix' : 'foreach' 40 | 'body' : 'forEach((${1:item}, ${2:i}) => {\n\t$3\n});\n' 41 | 'Function': 42 | 'prefix': 'fun' 43 | 'body': 'function ${1:functionName}($2) {\n\t$0\n}' 44 | 'Anonymous Function': 45 | 'prefix': 'f' 46 | 'body': 'function ($1) {\n\t$2\n}' 47 | 'Arrow Function': 48 | 'prefix': 'af' 49 | 'body': '($1) => {\n\t$2\n}' 50 | 'Generator': 51 | 'prefix': 'gen', 52 | 'body': 'function* ${1:functionName}($2) {\n\t$0\n}' 53 | 'Anonymous Generator': 54 | 'prefix': 'g' 55 | 'body': 'function* ($1) {\n\t$2\n}' 56 | 'getElementsByClassName': 57 | 'prefix': 'get' 58 | 'body': 'getElementsByClassName(${1:\'${2:className}\'})$3' 59 | 'getElementsByName': 60 | 'prefix': 'getn' 61 | 'body': 'getElementsByName(${1:\'${2:name}\'})$3' 62 | 'getElementsByTagName': 63 | 'prefix': 'gett' 64 | 'body': 'getElementsByTagName(${1:\'${2:tagName}\'})$3' 65 | 'getElementById': 66 | 'prefix': 'geti' 67 | 'body': 'getElementById(${1:\'${2:id}\'})$3' 68 | 'querySelector': 69 | 'prefix': 'qs' 70 | 'body': 'querySelector(${1:\'${2:query}\'})$3' 71 | 'querySelectorAll': 72 | 'prefix': 'qsa' 73 | 'body': 'querySelectorAll(${1:\'${2:query}\'})$3' 74 | 'Immediately-Invoked Function Expression': 75 | 'prefix': 'iife' 76 | 'body': '(function() {\n\t${1:\'use strict\';\n}\t$2\n}());' 77 | 'log': 78 | 'prefix': 'log' 79 | 'body': 'console.log($1);$0' 80 | 'dir': 81 | 'prefix': 'dir' 82 | 'body': 'console.dir($1);$0' 83 | 'warn': 84 | 'prefix': 'warn' 85 | 'body': 'console.warn($1);$0' 86 | 'error': 87 | 'prefix': 'error' 88 | 'body': 'console.error($1);$0' 89 | 'inspect': 90 | 'prefix': 'inspect' 91 | 'body': 'console.log(require(\'util\').inspect($0, { depth: null }));' 92 | 'new Promise': 93 | 'prefix': 'prom' 94 | 'body': 'new Promise(function(resolve, reject) {\n\t$1\n});$0' 95 | 'setInterval function': 96 | 'prefix': 'interval' 97 | 'body': 'setInterval(${2:function () {\n\t$3\n\\}}, ${1:10});' 98 | 'setTimeout function': 99 | 'prefix': 'timeout' 100 | 'body': 'setTimeout(${2:function () {\n\t$3\n\\}}, ${1:10});' 101 | 'switch': 102 | 'prefix': 'switch' 103 | 'body': 'switch (${1:expression}) {\n\tcase ${2:expression}:\n\t\t$4\n\t\tbreak;$5\n\tdefault:\n\t\t$3\n}' 104 | 'case': 105 | 'prefix': 'case' 106 | 'body': 'case ${1:expression}:\n\t$2\n\tbreak;' 107 | 'try': 108 | 'prefix': 'try' 109 | 'body': 'try {\n\t$1\n} catch (${2:e}) {\n\t$3\n}${4: finally {\n\t$5\n\\}}' 110 | 'while': 111 | 'prefix': 'while' 112 | 'body': 'while (${1:true}) {\n\t$2\n}' 113 | 'Start Docblock': 114 | 'prefix': '/**' 115 | 'body': '/**\n * $1\n */$0' 116 | 'CommonJS require': 117 | 'prefix': 'req' 118 | 'body': 'const ${1:module} = require(\'${1:module}\');' 119 | 'Class': 120 | 'prefix': 'class' 121 | 'body': 'class ${1:ClassName} {\n\tconstructor($2) {\n\t\t$3\n\t}\n}' 122 | 'export function': 123 | 'prefix': 'expfun' 124 | 'body': 'exports.${1:functionName} = function ($2) {\n\t${3:// body...}\n};' 125 | 'export module': 126 | 'prefix': 'expmod' 127 | 'body': 'module.exports = ${1:name};' 128 | 'return': 129 | 'prefix': 'ret' 130 | 'body': 'return $1;$0' 131 | -------------------------------------------------------------------------------- /spec/regular-expression-replacement-spec.coffee: -------------------------------------------------------------------------------- 1 | describe "Regular Expression Replacement grammar", -> 2 | grammar = null 3 | 4 | beforeEach -> 5 | atom.config.set('core.useTreeSitterParsers', false) 6 | 7 | waitsForPromise -> 8 | atom.packages.activatePackage("language-javascript") 9 | 10 | runs -> 11 | grammar = atom.grammars.grammarForScopeName("source.js.regexp.replacement") 12 | 13 | it "parses the grammar", -> 14 | expect(grammar).toBeTruthy() 15 | expect(grammar.scopeName).toBe "source.js.regexp.replacement" 16 | 17 | describe "basic strings", -> 18 | it "tokenizes with no extra scopes", -> 19 | {tokens} = grammar.tokenizeLine('Hello [world]. (hi to you)') 20 | expect(tokens[0]).toEqual value: 'Hello [world]. (hi to you)', scopes: ['source.js.regexp.replacement'] 21 | 22 | describe "escaped characters", -> 23 | it "tokenizes with as an escape character", -> 24 | {tokens} = grammar.tokenizeLine('\\n') 25 | expect(tokens[0]).toEqual value: '\\n', scopes: ['source.js.regexp.replacement', 'constant.character.escape.backslash.regexp.replacement'] 26 | 27 | it "tokenizes '$$' as an escaped '$' character", -> 28 | {tokens} = grammar.tokenizeLine('$$') 29 | expect(tokens[0]).toEqual value: '$$', scopes: ['source.js.regexp.replacement', 'constant.character.escape.dollar.regexp.replacement'] 30 | 31 | it "doesn't treat '\\$' as an escaped '$' character", -> 32 | {tokens} = grammar.tokenizeLine('\\$') 33 | expect(tokens[0]).toEqual value: '\\$', scopes: ['source.js.regexp.replacement'] 34 | 35 | it "tokenizes '$$1' as an escaped '$' character followed by a '1' character", -> 36 | {tokens} = grammar.tokenizeLine('$$1') 37 | expect(tokens[0]).toEqual value: '$$', scopes: ['source.js.regexp.replacement', 'constant.character.escape.dollar.regexp.replacement'] 38 | expect(tokens[1]).toEqual value: '1', scopes: ['source.js.regexp.replacement'] 39 | 40 | describe "Numeric placeholders", -> 41 | it "doesn't tokenize $0 as a variable", -> 42 | {tokens} = grammar.tokenizeLine('$0') 43 | expect(tokens[0]).toEqual value: '$0', scopes: ['source.js.regexp.replacement'] 44 | 45 | it "doesn't tokenize $00 as a variable", -> 46 | {tokens} = grammar.tokenizeLine('$00') 47 | expect(tokens[0]).toEqual value: '$00', scopes: ['source.js.regexp.replacement'] 48 | 49 | it "tokenizes $1 as a variable", -> 50 | {tokens} = grammar.tokenizeLine('$1') 51 | expect(tokens[0]).toEqual value: '$1', scopes: ['source.js.regexp.replacement', 'variable.regexp.replacement'] 52 | 53 | it "tokenizes $01 as a variable", -> 54 | {tokens} = grammar.tokenizeLine('$01') 55 | expect(tokens[0]).toEqual value: '$01', scopes: ['source.js.regexp.replacement', 'variable.regexp.replacement'] 56 | 57 | it "tokenizes $3 as a variable", -> 58 | {tokens} = grammar.tokenizeLine('$3') 59 | expect(tokens[0]).toEqual value: '$3', scopes: ['source.js.regexp.replacement', 'variable.regexp.replacement'] 60 | 61 | it "tokenizes $10 as a variable", -> 62 | {tokens} = grammar.tokenizeLine('$10') 63 | expect(tokens[0]).toEqual value: '$10', scopes: ['source.js.regexp.replacement', 'variable.regexp.replacement'] 64 | 65 | it "tokenizes $99 as a variable", -> 66 | {tokens} = grammar.tokenizeLine('$99') 67 | expect(tokens[0]).toEqual value: '$99', scopes: ['source.js.regexp.replacement', 'variable.regexp.replacement'] 68 | 69 | it "doesn't tokenize the third numberic character in '$100' as a variable", -> 70 | {tokens} = grammar.tokenizeLine('$100') 71 | expect(tokens[0]).toEqual value: '$10', scopes: ['source.js.regexp.replacement', 'variable.regexp.replacement'] 72 | expect(tokens[1]).toEqual value: '0', scopes: ['source.js.regexp.replacement'] 73 | 74 | describe "Matched sub-string placeholder", -> 75 | it "tokenizes $& as a variable", -> 76 | {tokens} = grammar.tokenizeLine('$&') 77 | expect(tokens[0]).toEqual value: '$&', scopes: ['source.js.regexp.replacement', 'variable.regexp.replacement'] 78 | 79 | describe "Preceeding portion placeholder", -> 80 | it "tokenizes $` as a variable", -> 81 | {tokens} = grammar.tokenizeLine('$`') 82 | expect(tokens[0]).toEqual value: '$`', scopes: ['source.js.regexp.replacement', 'variable.regexp.replacement'] 83 | 84 | describe "Following portion placeholder", -> 85 | it "tokenizes $' as a variable", -> 86 | {tokens} = grammar.tokenizeLine('$\'') 87 | expect(tokens[0]).toEqual value: '$\'', scopes: ['source.js.regexp.replacement', 'variable.regexp.replacement'] 88 | --------------------------------------------------------------------------------