From 5f71a8e47462ba35829aa1cd871c6b88165aeead Mon Sep 17 00:00:00 2001 From: Johannes Rappen Date: Fri, 12 Nov 2021 06:56:58 +0100 Subject: [PATCH] [JSON] Rewrite syntax MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Using inheritance split up `JSON.sublime-syntax` into: - `JSON (Basic).sublime-syntax` with `scope:source.json.basic` - `JSON.sublime-syntax` with `scope:source.json` - `JSONC.sublime-syntax` with `scope:source.json.jsonc` - `JSON5.sublime-syntax` with `scope:source.json.json5` - Add many more file extensions for `JSON` & `JSONC`: - add doc links to extensions where applicable as a reference to be able to more quickly verify that they (still) use said syntax flavor - JSON: - (correctly formatted) JSON code can now be prettified or minified via the context menu or the command palette - highlight leading, trailing & multiple commas as invalid - only allow exactly one structure (object, array) or value (constant, number, string) at top level (thanks to Keith) - JSONC: - highlight some files by default as `JSONC` (as decided by Jon in #285) - highlight leading & multiple commas as invalid, trailing as valid - JSON5: - explicitly pos numbers, hexadecimal ints, Infinity and NaN - single quoted strings - more escape chars for strings - ECMA identifierName as object keys (thanks to Thomas) - scoped as plain unquoted strings - line continuation in strings (with tests thanks to Keith) - Objects: - Add `meta.toc-list` scope to top level object keys to add them to the symbol list (also add tests, see below) - Highlighting speed improvements for empty objects (thanks to FichteFoll) - Make `mapping.*` contexts more modular - Arrays: - Highlighting speed improvements for empty arrays (thanks to FichteFoll) - Numbers: - Correctly scope number signs with `constant.numeric.sign` instead of `keyword.operator.arithmetic` - Significantly improve number highlighting (thanks to deathaxe) - Syntaxes: - Make use of newer syntax features including those only available in `version: 2` syntaxes - Make use of `variables` (with optimizations provided by deathaxe and regex patterns provided by Thomas) - Tests: - Significantly extend tests to cover more parts of the syntaxes defined. - Split original test file into logical parts - Add indentation tests for: - `json`, `jsonc` & `json5` - `mapping` (objects), `sequence` (arrays) - Add symbols tests for: - scope: `meta.toc-list.json | meta.toc-list.json5` - languages: `json`, `jsonc` & `json5` - Fix tests for `meta.mapping meta.mapping.*` - Leave `JSON` headers in `Markdown` as `json` only, but split up fenced code blocks into `json`, `jsonc` & `json5` to behave similarly to `GitHub Flavored Markdown` BREAKING CHANGES: - JSON does not have values that can be set via an inline calculation with the help of operators, but only simple number values. Scopes for number signs have changed from being `keyword.operator.arithmetic` to `constant.numeric.sign`. Color scheme authors should add this, should it be missing. - The `JSON.sublime-syntax` now marks comments as `invalid`, third party plugin authors should target `JSONC.sublime-syntax` instead to have the same user experience as before. - fix #285 - address #481 to remove incompatible regex patterns according to Will - address #757 to fix line comments for `JSONC` (thanks to Keith) - address #2430 using sort-order (as requested by deathaxe) - address #2852 to fix scopes of curly braces & square brackets in `JSON` (thanks to Thomas) - address sublimehq/sublime_text#3154 and add symbol tests Co-authored-by: Ashwin Shenoy Co-authored-by: Jack Cherng Co-authored-by: Janos Wortmann Co-authored-by: Jon Skinner Co-authored-by: FichteFoll Co-authored-by: Keith Hall Co-authored-by: Michael B. Lyons Co-authored-by: Rafał Chłodnicki Co-authored-by: Thomas Smith Co-authored-by: Will Bond Co-authored-by: deathaxe --- JSON/.python-version | 1 + JSON/Comments - JSON5.tmPreferences | 25 ++ JSON/Comments - JSONC.tmPreferences | 25 ++ JSON/Comments.tmPreferences | 31 -- JSON/Context.sublime-menu | 25 ++ JSON/Default.sublime-commands | 25 ++ JSON/Default.sublime-keymap | 65 +-- JSON/JSON (Basic).sublime-syntax | 388 ++++++++++++++++ JSON/JSON.sublime-settings | 11 + JSON/JSON.sublime-syntax | 272 +++++------ JSON/JSON5.sublime-syntax | 254 +++++++++++ JSON/JSONC.sublime-syntax | 155 +++++++ JSON/Main.sublime-menu | 124 +++++ JSON/Symbol List - JSON.tmPreferences | 11 + JSON/Symbol List - JSON5.tmPreferences | 11 + JSON/main.py | 18 + JSON/src/__init__.py | 9 + JSON/src/json_prettify.py | 211 +++++++++ JSON/src/jsonc_prettify.py | 136 ++++++ JSON/syntax_test_json.json | 123 ----- .../syntax_test_indentation.mapping.json | 36 ++ .../syntax_test_indentation.mapping.json5 | 36 ++ .../syntax_test_indentation.mapping.jsonc | 36 ++ .../syntax_test_indentation.sequence.json | 90 ++++ .../syntax_test_indentation.sequence.json5 | 90 ++++ .../syntax_test_indentation.sequence.jsonc | 90 ++++ JSON/tests/symbols/syntax_test_symbols.json | 15 + JSON/tests/symbols/syntax_test_symbols.json5 | 37 ++ JSON/tests/symbols/syntax_test_symbols.jsonc | 15 + .../syntax/syntax_test_json.comment.json | 10 + ....leading_or_trailing_comma_in_mapping.json | 11 + ....invalid.illegal.unexpected_separator.json | 23 + ...illegal.unexpected_structure_or_value.json | 10 + .../syntax/syntax_test_json5.comment.json5 | 42 ++ .../syntax_test_json5.invalid.illegal.json5 | 57 +++ .../syntax_test_json5.meta.mapping.json5 | 160 +++++++ .../syntax_test_json5.meta.sequence.json5 | 58 +++ ...ntax_test_json5.number.float.decimal.json5 | 240 ++++++++++ ...est_json5.number.integer.hexadecimal.json5 | 64 +++ .../syntax/syntax_test_json5.string.json5 | 65 +++ .../syntax/syntax_test_jsonc.comment.jsonc | 425 ++++++++++++++++++ .../syntax/syntax_test_jsonc.constant.jsonc | 14 + ...illegal.expected_lower_case_constant.jsonc | 18 + .../syntax_test_jsonc.invalid.illegal.jsonc | 26 ++ ...t_jsonc.invalid.illegal.numeric_sign.jsonc | 172 +++++++ ...sonc.invalid.illegal.unclosed_string.jsonc | 15 + ...d.illegal.unrecognized_string_escape.jsonc | 50 +++ .../syntax_test_jsonc.meta.mapping.jsonc | 109 +++++ .../syntax_test_jsonc.meta.sequence.jsonc | 67 +++ .../syntax/syntax_test_jsonc.number.jsonc | 251 +++++++++++ .../syntax/syntax_test_jsonc.string.jsonc | 80 ++++ Markdown/Markdown.sublime-syntax | 45 +- .../syntax_test_markdown.fenced_code_json.md | 30 ++ Perl/Perl.sublime-syntax | 51 ++- Perl/syntax_test_perl.embedded_json.pl | 25 ++ Perl/syntax_test_perl.pl | 16 - 56 files changed, 4140 insertions(+), 359 deletions(-) create mode 100755 JSON/.python-version create mode 100755 JSON/Comments - JSON5.tmPreferences create mode 100755 JSON/Comments - JSONC.tmPreferences delete mode 100644 JSON/Comments.tmPreferences create mode 100755 JSON/Context.sublime-menu create mode 100755 JSON/Default.sublime-commands create mode 100755 JSON/JSON (Basic).sublime-syntax create mode 100755 JSON/JSON.sublime-settings create mode 100755 JSON/JSON5.sublime-syntax create mode 100755 JSON/JSONC.sublime-syntax create mode 100755 JSON/Main.sublime-menu create mode 100755 JSON/Symbol List - JSON.tmPreferences create mode 100755 JSON/Symbol List - JSON5.tmPreferences create mode 100755 JSON/main.py create mode 100755 JSON/src/__init__.py create mode 100755 JSON/src/json_prettify.py create mode 100755 JSON/src/jsonc_prettify.py delete mode 100644 JSON/syntax_test_json.json create mode 100644 JSON/tests/indentation/syntax_test_indentation.mapping.json create mode 100644 JSON/tests/indentation/syntax_test_indentation.mapping.json5 create mode 100644 JSON/tests/indentation/syntax_test_indentation.mapping.jsonc create mode 100644 JSON/tests/indentation/syntax_test_indentation.sequence.json create mode 100644 JSON/tests/indentation/syntax_test_indentation.sequence.json5 create mode 100644 JSON/tests/indentation/syntax_test_indentation.sequence.jsonc create mode 100644 JSON/tests/symbols/syntax_test_symbols.json create mode 100644 JSON/tests/symbols/syntax_test_symbols.json5 create mode 100644 JSON/tests/symbols/syntax_test_symbols.jsonc create mode 100644 JSON/tests/syntax/syntax_test_json.comment.json create mode 100644 JSON/tests/syntax/syntax_test_json.invalid.illegal.leading_or_trailing_comma_in_mapping.json create mode 100644 JSON/tests/syntax/syntax_test_json.invalid.illegal.unexpected_separator.json create mode 100644 JSON/tests/syntax/syntax_test_json.invalid.illegal.unexpected_structure_or_value.json create mode 100644 JSON/tests/syntax/syntax_test_json5.comment.json5 create mode 100644 JSON/tests/syntax/syntax_test_json5.invalid.illegal.json5 create mode 100644 JSON/tests/syntax/syntax_test_json5.meta.mapping.json5 create mode 100644 JSON/tests/syntax/syntax_test_json5.meta.sequence.json5 create mode 100644 JSON/tests/syntax/syntax_test_json5.number.float.decimal.json5 create mode 100644 JSON/tests/syntax/syntax_test_json5.number.integer.hexadecimal.json5 create mode 100644 JSON/tests/syntax/syntax_test_json5.string.json5 create mode 100644 JSON/tests/syntax/syntax_test_jsonc.comment.jsonc create mode 100644 JSON/tests/syntax/syntax_test_jsonc.constant.jsonc create mode 100644 JSON/tests/syntax/syntax_test_jsonc.invalid.illegal.expected_lower_case_constant.jsonc create mode 100644 JSON/tests/syntax/syntax_test_jsonc.invalid.illegal.jsonc create mode 100644 JSON/tests/syntax/syntax_test_jsonc.invalid.illegal.numeric_sign.jsonc create mode 100644 JSON/tests/syntax/syntax_test_jsonc.invalid.illegal.unclosed_string.jsonc create mode 100644 JSON/tests/syntax/syntax_test_jsonc.invalid.illegal.unrecognized_string_escape.jsonc create mode 100644 JSON/tests/syntax/syntax_test_jsonc.meta.mapping.jsonc create mode 100644 JSON/tests/syntax/syntax_test_jsonc.meta.sequence.jsonc create mode 100644 JSON/tests/syntax/syntax_test_jsonc.number.jsonc create mode 100644 JSON/tests/syntax/syntax_test_jsonc.string.jsonc create mode 100644 Markdown/syntax_test_markdown.fenced_code_json.md create mode 100644 Perl/syntax_test_perl.embedded_json.pl diff --git a/JSON/.python-version b/JSON/.python-version new file mode 100755 index 00000000000..cc1923a40b1 --- /dev/null +++ b/JSON/.python-version @@ -0,0 +1 @@ +3.8 diff --git a/JSON/Comments - JSON5.tmPreferences b/JSON/Comments - JSON5.tmPreferences new file mode 100755 index 00000000000..75aac0ef338 --- /dev/null +++ b/JSON/Comments - JSON5.tmPreferences @@ -0,0 +1,25 @@ + + + + scope + source.json.json5 + settings + + shellVariables + + + nameTM_COMMENT_START + value// + + + nameTM_COMMENT_START_2 + value/* + + + nameTM_COMMENT_END_2 + value*/ + + + + + diff --git a/JSON/Comments - JSONC.tmPreferences b/JSON/Comments - JSONC.tmPreferences new file mode 100755 index 00000000000..1ee8dd7e2af --- /dev/null +++ b/JSON/Comments - JSONC.tmPreferences @@ -0,0 +1,25 @@ + + + + scope + source.json.jsonc + settings + + shellVariables + + + nameTM_COMMENT_START + value// + + + nameTM_COMMENT_START_2 + value/* + + + nameTM_COMMENT_END_2 + value*/ + + + + + diff --git a/JSON/Comments.tmPreferences b/JSON/Comments.tmPreferences deleted file mode 100644 index d9695e9cf24..00000000000 --- a/JSON/Comments.tmPreferences +++ /dev/null @@ -1,31 +0,0 @@ - - - - scope - source.json - settings - - shellVariables - - - name - TM_COMMENT_START - value - // - - - name - TM_COMMENT_START_2 - value - /* - - - name - TM_COMMENT_END_2 - value - */ - - - - - diff --git a/JSON/Context.sublime-menu b/JSON/Context.sublime-menu new file mode 100755 index 00000000000..4329c528ff4 --- /dev/null +++ b/JSON/Context.sublime-menu @@ -0,0 +1,25 @@ +// Packages/JSON/Context.sublime-menu + + +// This file is being maintained at: +// https://github.com/sublimehq/Packages/blob/master/JSON/Context.sublime-menu + + +[ + { + "caption": "JSON: Minify", + "command": "json_minify" + }, + { + "caption": "JSON: Prettify", + "command": "json_prettify" + }, + { + "caption": "JSONC: Minify", + "command": "jsonc_minify" + }, + { + "caption": "JSONC: Prettify", + "command": "jsonc_prettify" + } +] diff --git a/JSON/Default.sublime-commands b/JSON/Default.sublime-commands new file mode 100755 index 00000000000..91ac0be852a --- /dev/null +++ b/JSON/Default.sublime-commands @@ -0,0 +1,25 @@ +// Packages/JSON/Default.sublime-commands + + +// This file is being maintained at: +// https://github.com/sublimehq/Packages/blob/master/JSON/Default.sublime-commands + + +[ + { + "caption": "JSON: Minify JSON", + "command": "json_minify" + }, + { + "caption": "JSON: Prettify JSON", + "command": "json_prettify" + }, + { + "caption": "JSONC: Minify JSONC", + "command": "jsonc_minify" + }, + { + "caption": "JSONC: Prettify JSONC", + "command": "jsonc_prettify" + } +] diff --git a/JSON/Default.sublime-keymap b/JSON/Default.sublime-keymap index e11d9bce5c6..eab203888dd 100644 --- a/JSON/Default.sublime-keymap +++ b/JSON/Default.sublime-keymap @@ -1,63 +1,70 @@ +// Packages/JSON/Default.sublime-keymap + + +// This file is being maintained at: +// https://github.com/sublimehq/Packages/blob/master/JSON/Default.sublime-keymap + + [ // Auto-pair quotations: "key": '|', { "keys": ["'"], "command": "insert_snippet", "args": {"contents": "'$0'"}, "context": [ - { "key": "setting.auto_match_enabled" }, - { "key": "selector", "operand": "source.json" }, - { "key": "selection_empty", "match_all": true }, - { "key": "preceding_text", "operator": "not_regex_contains", "operand": "['\\w]$", "match_all": true }, - { "key": "following_text", "operator": "regex_contains", "operand": "^(?:\t| |]|,|:|\\}|$)", "match_all": true } + { "key": "setting.auto_match_enabled" }, + { "key": "selector", "operand": "source.json" }, + { "key": "selection_empty", "match_all": true }, + { "key": "preceding_text", "operator": "not_regex_contains", "operand": "['\\w]$", "match_all": true }, + { "key": "following_text", "operator": "regex_contains", "operand": "^(?:\t| |]|,|:|\\}|$)", "match_all": true } ] }, // Auto-pair quotations: "key": "|", { "keys": ["\""], "command": "insert_snippet", "args": {"contents": "\"$0\""}, "context": [ - { "key": "setting.auto_match_enabled" }, - { "key": "selector", "operand": "source.json" }, - { "key": "selection_empty", "match_all": true }, - { "key": "preceding_text", "operator": "not_regex_contains", "operand": "[\"\\w]$", "match_all": true }, - { "key": "following_text", "operator": "regex_contains", "operand": "^(?:\t| |]|,|:|\\}|$)", "match_all": true } + { "key": "setting.auto_match_enabled" }, + { "key": "selector", "operand": "source.json" }, + { "key": "selection_empty", "match_all": true }, + { "key": "preceding_text", "operator": "not_regex_contains", "operand": "[\"\\w]$", "match_all": true }, + { "key": "following_text", "operator": "regex_contains", "operand": "^(?:\t| |]|,|:|\\}|$)", "match_all": true } ] }, // Auto-pair braces: "key": {|}, { "keys": ["{"], "command": "insert_snippet", "args": {"contents": "{$0}"}, "context": [ - { "key": "setting.auto_match_enabled" }, - { "key": "selector", "operand": "source.json" }, - { "key": "selection_empty", "match_all": true }, - { "key": "following_text", "operator": "regex_contains", "operand": "^(?:\t| |]|,|:|\\}|$)", "match_all": true } + { "key": "setting.auto_match_enabled" }, + { "key": "selector", "operand": "source.json" }, + { "key": "selection_empty", "match_all": true }, + { "key": "following_text", "operator": "regex_contains", "operand": "^(?:\t| |]|,|:|\\}|$)", "match_all": true } ] }, // Auto-pair square brackets: "key": [|], { "keys": ["["], "command": "insert_snippet", "args": {"contents": "[$0]"}, "context": [ - { "key": "setting.auto_match_enabled" }, - { "key": "selector", "operand": "source.json" }, - { "key": "selection_empty", "match_all": true }, - { "key": "following_text", "operator": "regex_contains", "operand": "^(?:\t| |]|,|:|\\}|$)", "match_all": true } + { "key": "setting.auto_match_enabled" }, + { "key": "selector", "operand": "source.json" }, + { "key": "selection_empty", "match_all": true }, + { "key": "following_text", "operator": "regex_contains", "operand": "^(?:\t| |]|,|:|\\}|$)", "match_all": true } ] }, // Add indented line in square brackets { "keys": ["enter"], "command": "insert_snippet", "args": {"contents": "\n\t$0\n"}, "context": [ - { "key": "setting.auto_indent" }, - { "key": "selector", "operand": "source.json" }, - { "key": "selection_empty", "match_all": true }, - { "key": "preceding_text", "operator": "regex_contains", "operand": "\\[$", "match_all": true }, - { "key": "following_text", "operator": "regex_contains", "operand": "^\\]", "match_all": true } + { "key": "setting.auto_indent" }, + { "key": "selector", "operand": "source.json" }, + { "key": "selection_empty", "match_all": true }, + { "key": "preceding_text", "operator": "regex_contains", "operand": "\\[$", "match_all": true }, + { "key": "following_text", "operator": "regex_contains", "operand": "^\\]", "match_all": true } ] }, { "keys": ["shift+enter"], "command": "insert_snippet", "args": {"contents": "\n\t$0\n"}, "context": [ - { "key": "setting.auto_indent" }, - { "key": "selector", "operand": "source.json" }, - { "key": "selection_empty", "match_all": true }, - { "key": "preceding_text", "operator": "regex_contains", "operand": "\\[$", "match_all": true }, - { "key": "following_text", "operator": "regex_contains", "operand": "^\\]", "match_all": true } + { "key": "setting.auto_indent" }, + { "key": "selector", "operand": "source.json" }, + { "key": "selection_empty", "match_all": true }, + { "key": "preceding_text", "operator": "regex_contains", "operand": "\\[$", "match_all": true }, + { "key": "following_text", "operator": "regex_contains", "operand": "^\\]", "match_all": true } ] }, -] \ No newline at end of file +] diff --git a/JSON/JSON (Basic).sublime-syntax b/JSON/JSON (Basic).sublime-syntax new file mode 100755 index 00000000000..0193a607530 --- /dev/null +++ b/JSON/JSON (Basic).sublime-syntax @@ -0,0 +1,388 @@ +%YAML 1.2 +--- +# YAML Documentation: +# https://yaml.org/spec/1.2/spec.html +# Sublime Text Documentation: +# https://www.sublimetext.com/docs/syntax.html#ver-dev +# https://www.sublimetext.com/docs/syntax.html#testing:ver-dev +# https://www.sublimetext.com/docs/scope_naming.html +# This file is being maintained at: +# https://github.com/sublimehq/Packages/blob/master/JSON/JSON%20(Basic).sublime-syntax +# +name: JSON (Basic) +scope: source.json.basic +version: 2 +hidden: true + + +variables: + exponent: (?:[eE][-+]?\d+) + pos_integer_decimal: (?:0|[1-9]\d*) + + +contexts: + + prototype: + - include: comments + + main: + - match: '(?=\S)' + push: top-level-expect-object + +####[ Top level ]####################################################################################################### + + # Try these below one-by-one. + + top-level-expect-object: + - include: top-level-objects + - match: '' + push: top-level-expect-array + + top-level-expect-array: + - include: arrays + - match: '' + push: top-level-expect-constant + + top-level-expect-constant: + - include: constants + - match: '' + push: top-level-expect-number + + top-level-expect-number: + - include: numbers + - match: '' + push: top-level-expect-string + + top-level-expect-string: + - include: strings + - match: '' + push: top-level-expect-invalid-remainder + + top-level-expect-invalid-remainder: + - match: ',' + scope: invalid.illegal.unexpected-separator.json + - match: ':' + scope: invalid.illegal.unexpected-separator.json + - match: '\S*' + scope: invalid.illegal.unexpected-code-after-first-structure-or-value.json + +####[ Structural helpers ]############################################################################################## + + any: + - include: structures + - include: values + + structures: + - include: objects + - include: arrays + + values: + - include: constants + - include: numbers + - include: strings + +####[ Helpers ]######################################################################################################### + + eol-pop: + - match: '$\n?' + pop: 1 + +####[ Comments ]######################################################################################################## + + comments: + - meta_include_prototype: false + - include: comment-line + - include: comment-doc-block + - include: comment-block + + comment-line: + - meta_include_prototype: false + - match: '//' + scope: invalid.illegal.comment.json + push: + - meta_include_prototype: false + - meta_content_scope: invalid.illegal.comment.json + - include: eol-pop + + comment-doc-block: + - meta_include_prototype: false + - match: '/\*\*(?!/)' + scope: invalid.illegal.comment.json + push: + - meta_include_prototype: false + - meta_content_scope: invalid.illegal.comment.json + - include: comment-block-end + - match: '^\s*(\*)(?!/)' + captures: + 1: invalid.illegal.comment.json + + comment-block: + - meta_include_prototype: false + - match: '/\*' + scope: invalid.illegal.comment.json + push: + - meta_include_prototype: false + - meta_content_scope: invalid.illegal.comment.json + - include: comment-block-end + + comment-block-end: + - meta_include_prototype: false + - match: '\*/' + scope: invalid.illegal.comment.json + pop: 1 + +####[ Constants ]####################################################################################################### + + constants: + - match: \b(?:null)\b + scope: constant.language.null.json + - match: \b(?:false|true)\b + scope: constant.language.boolean.json + # when erroneously containing upper case letters + - match: \b(?i:null)\b + scope: invalid.illegal.expected-lower-case-null.json + - match: \b(?i:false|true)\b + scope: invalid.illegal.expected-lower-case-boolean.json + +####[ Numbers ]######################################################################################################### + + numbers: + - include: floats + - include: integers + + floats: + - include: decimal-floats + + decimal-floats: + - match: |- + (?x: + (?:(-)|(\+))? + ( + {{pos_integer_decimal}} + (?: + # 1.1 1.1e1 1.1e-1 1.1e+1 + (\.)\d+ {{exponent}}? + # 1e1 1+e1 1-e1 + | {{exponent}} + ) + ) + ) + scope: meta.number.float.decimal.json + captures: + 1: constant.numeric.sign.json + 2: invalid.illegal.numeric-sign.json + 3: constant.numeric.value.json + 4: punctuation.separator.decimal.json + + integers: + - include: decimal-integers + + decimal-integers: + - match: (?:(-)|(\+))?({{pos_integer_decimal}}) + scope: meta.number.integer.decimal.json + captures: + 1: constant.numeric.sign.json + 2: invalid.illegal.numeric-sign.json + 3: constant.numeric.value.json + +####[ Strings ]######################################################################################################### + + strings: + - include: double-quoted-strings + + double-quoted-strings: + - match: \" + scope: punctuation.definition.string.begin.json + push: inside-double-quoted-string + + inside-double-quoted-string: + - meta_include_prototype: false + - meta_scope: meta.string.json string.quoted.double.json + - match: \" + scope: punctuation.definition.string.end.json + pop: 1 + - include: double-quoted-string-escape-characters + - match: \n + scope: invalid.illegal.unclosed-string.json + pop: 1 + + double-quoted-string-escape-characters: + - meta_include_prototype: false + - match: \\\" + scope: constant.character.escape.double-quote.json + - include: string-escape-characters + + string-escape-characters: + - meta_include_prototype: false + - include: valid-string-escape-characters + - include: invalid-string-escape-characters + + valid-string-escape-characters: + - meta_include_prototype: false + - match: \\\\ + scope: constant.character.escape.back-slash.json + - match: \\\/ + scope: constant.character.escape.forward-slash.json + - match: \\b + scope: constant.character.escape.backspace.json + - match: \\f + scope: constant.character.escape.form-feed.json + - match: \\n + scope: constant.character.escape.newline.json # linefeed + - match: \\r + scope: constant.character.escape.carriage-return.json + - match: \\t + scope: constant.character.escape.horizontal-tab.json + - match: \\u[0-9a-fA-F]{4} + scope: constant.character.escape.unicode-symbol.basic-multilingual-plane.json + + invalid-string-escape-characters: + - meta_include_prototype: false + - match: \\. + scope: invalid.illegal.unrecognized-string-escape.json + +####[ Sequence ]######################################################################################################## + + arrays: + - include: empty-arrays + - match: \[ + scope: punctuation.definition.sequence.begin.json + push: + - array-body + - array-illegal-separator + + array-body: + - meta_scope: meta.sequence.list.json + - match: \] + scope: punctuation.definition.sequence.end.json + pop: 1 + - include: array-separators + - include: any + - match: '[^\s\]]' + scope: invalid.illegal.expected-separator.json + + array-separators: + - match: (?=,) + branch_point: array-separators + branch: + - array-separator + - array-illegal-separator + + array-separator: + - match: ',' + scope: punctuation.separator.sequence.json + set: array-expect-value + + array-expect-value: + - match: (?=\]) + fail: array-separators + - include: array-illegal-separator + + array-illegal-separator: + - match: ',' + scope: invalid.illegal.unexpected-separator.json + - match: (?=\S) + pop: 1 + + empty-arrays: + - match: (\[)\s*(\]) + scope: meta.sequence.list.empty.json + captures: + 1: punctuation.definition.sequence.begin.json + 2: punctuation.definition.sequence.end.json + +####[ Mapping ]######################################################################################################### + + # FIXME: leading separators + # FIXME: trailing commas + + # The top-level contexts here are to ensure that we can apply `meta.toc-list` + # to the top-level object keys to index them as symbols. + + top-level-objects: + - include: empty-object + - match: \{ + scope: punctuation.definition.mapping.begin.json + push: top-level-meta-mapping + + objects: + - include: empty-object + - match: \{ + scope: punctuation.definition.mapping.begin.json + push: meta-mapping + + empty-object: + - match: (\{)\s*(\}) + scope: meta.mapping.empty.json + captures: + 1: punctuation.definition.mapping.begin.json + 2: punctuation.definition.mapping.end.json + + top-level-meta-mapping: + - meta_scope: meta.mapping.json + - match: \} + scope: punctuation.definition.mapping.end.json + pop: 1 + - include: top-level-mapping-key + - include: mapping-separator + - match: '[^\s\}]' + scope: invalid.illegal.expected-mapping-key.json + + meta-mapping: + - meta_scope: meta.mapping.json + - match: \} + scope: punctuation.definition.mapping.end.json + pop: 1 + - include: mapping-key + - include: mapping-separator + - match: '[^\s\}]' + scope: invalid.illegal.expected-mapping-key.json + + top-level-mapping-key: + - match: '"' + scope: punctuation.definition.string.begin.json + push: top-level-mapping-key-double-quoted + + mapping-key: + - match: '"' + scope: punctuation.definition.string.begin.json + push: mapping-key-double-quoted + + top-level-mapping-key-double-quoted: + - clear_scopes: 1 + - meta_include_prototype: false + - meta_scope: meta.mapping.key.json meta.toc-list.json meta.string.json string.quoted.double.json + - include: inside-double-quoted-string + + mapping-key-double-quoted: + - clear_scopes: 1 + - meta_include_prototype: false + - meta_scope: meta.mapping.key.json meta.string.json string.quoted.double.json + - include: inside-double-quoted-string + + mapping-separator: + - match: ':' + scope: punctuation.separator.mapping.key-value.json + push: mapping-expect-value + + mapping-expect-value: + - match: ',|\s?(?=\})' + scope: invalid.illegal.expected-mapping-value.json + pop: 1 + - match: (?=\S) + set: mapping-value + + mapping-value: + - clear_scopes: 1 + - meta_scope: meta.mapping.value.json + - include: any + - match: '' + set: + - match: ',' + scope: punctuation.separator.mapping.pair.json + pop: 1 + - match: \s*(?=\}) + pop: 1 + - match: \s(?!/[/*])(?=[^\s,])|[^\s,] + scope: invalid.illegal.expected-mapping-separator.json + pop: 1 diff --git a/JSON/JSON.sublime-settings b/JSON/JSON.sublime-settings new file mode 100755 index 00000000000..f2bcd73da13 --- /dev/null +++ b/JSON/JSON.sublime-settings @@ -0,0 +1,11 @@ +// Packages/JSON/JSON.sublime-settings +// Settings - Syntax Specific (Default) +// +// This file is being maintained at: +// https://github.com/sublimehq/Packages/blob/master/JSON/JSON.sublime-settings + + +{ + // whether `on_pre_save_async` events auto-trigger the `json_prettify` command + "json.auto_prettify": false +} diff --git a/JSON/JSON.sublime-syntax b/JSON/JSON.sublime-syntax index b7bd6a312df..903c25e8c4f 100644 --- a/JSON/JSON.sublime-syntax +++ b/JSON/JSON.sublime-syntax @@ -1,170 +1,130 @@ %YAML 1.2 --- +# YAML Documentation: +# https://yaml.org/spec/1.2/spec.html +# Sublime Text Documentation: +# https://www.sublimetext.com/docs/syntax.html#ver-dev +# https://www.sublimetext.com/docs/syntax.html#testing:ver-dev +# https://www.sublimetext.com/docs/scope_naming.html +# This file is being maintained at: +# https://github.com/sublimehq/Packages/blob/master/JSON/JSON.sublime-syntax +# name: JSON scope: source.json version: 2 +# https://www.sublimetext.com/docs/syntax.html#inheritance +extends: 'Packages/JSON/JSON (Basic).sublime-syntax' + file_extensions: - json - - sublime-build - - sublime-color-scheme - - sublime-commands - - sublime-completions - - sublime-keymap - - sublime-macro - - sublime-menu - - sublime-mousemap - - sublime-project - - sublime-settings - - sublime-theme - - sublime-workspace - - ipynb + # https://www.json.org/json-en.html + # https://datatracker.ietf.org/doc/html/rfc7159 + # https://www.ecma-international.org/publications-and-standards/standards/ecma-404/ + + - .bowerrc + # Bower + # https://bower.io/docs/config/ + + - .htmlhintrc + # HTML hint + # https://htmlhint.com/docs/user-guide/getting-started + + - .jscsrc + # JavaScript Code Style Configuration + # https://jscs-dev.github.io + + - .jsfmtrc + # jsfmt Configuration + # https://github.com/rdio/jsfmt + + - .markdownlintrc + # https://github.com/DavidAnson/markdownlint + + - .tern-config + # Tern.js Server Configuration + # https://ternjs.net/doc/manual.html#server + + - .tern-project + # Tern.js Project Configuration + # https://ternjs.net/doc/manual.html#configuration + + - .watchmanconfig + # Facebook Watchman + # root specific configuration file + # https://facebook.github.io/watchman/docs/config.html + - Pipfile.lock + # Pipfile + # https://github.com/pypa/pipfile + + - avsc + # Pure JavaScript implementation of the Avro specification + # https://github.com/mtth/avsc + + - composer.lock + # Composer lock file + # https://getcomposer.org/doc/01-basic-usage.md + + - css.map + # CSS Source Map + + - geojson + # JSON for geographic data structures + # https://geojson.org + # https://datatracker.ietf.org/wg/geojson/charter/ + # https://datatracker.ietf.org/doc/html/rfc7946 + + - gltf + # glTF Runtime 3D asset delivery + # https://www.khronos.com/gltf + + - har + # HTTP Archive Format + + - ipynb + # Jupyter Notebook, formerly known as iPython Notebook + # https://jupyter.org/documentation + + - js.map + # JavaScript Source Map + + - jsonld + # JSON for Linking Data + # https://json-ld.org + + - ldjson + # JSON for Linking Data + # https://json-ld.org + + - schema + # JSON Schema + # https://json-schema.org/learn + + - tfstate + # Hashicorp Terraform State + # https://www.terraform.io/docs/language/state/index.html + + - tfstate.backup + # Hashicorp Terraform State + # https://www.terraform.io/docs/language/state/index.html + + - topojson + # TopoJSON, an extension to GeoJSON + # https://github.com/topojson/topojson-specification + + - ts.map + # TypeScript Source Map + + - webapp + # Web app manifests + # https://developer.mozilla.org/en-US/docs/Web/Manifest + + - webmanifest + # Web app manifests + # https://developer.mozilla.org/en-US/docs/Web/Manifest first_line_match: |- (?xi: ^ \s* // .*? -\*- .*? \bjson\b .*? -\*- # editorconfig ) - -contexts: - - prototype: - - include: comments - - main: - - include: value - - value: - - include: constant - - include: number - - include: string - - include: array - - include: object - - array: - - match: \[ - scope: punctuation.section.sequence.begin.json - push: - - meta_scope: meta.sequence.json - - match: \] - scope: punctuation.section.sequence.end.json - pop: 1 - - include: value - - match: ',' - scope: punctuation.separator.sequence.json - - match: '[^\s\]]' - scope: invalid.illegal.expected-sequence-separator.json - - comments: - - match: /\*\*(?!/) - scope: punctuation.definition.comment.json - push: - - meta_scope: comment.block.documentation.json - - meta_include_prototype: false - - match: \*/ - pop: 1 - - match: ^\s*(\*)(?!/) - captures: - 1: punctuation.definition.comment.json - - match: /\* - scope: punctuation.definition.comment.json - push: - - meta_scope: comment.block.json - - meta_include_prototype: false - - match: \*/ - pop: 1 - - match: (//).*$\n? - scope: comment.line.double-slash.js - captures: - 1: punctuation.definition.comment.json - - constant: - - match: \b(?:false|true)\b - scope: constant.language.boolean.json - - match: \bnull\b - scope: constant.language.null.json - - number: - # handles integer and decimal numbers - - match: (-?)((?:0|[1-9]\d*)(?:(?:(\.)\d+)(?:[eE][-+]?\d+)?|(?:[eE][-+]?\d+))) - scope: meta.number.float.decimal.json - captures: - 1: keyword.operator.arithmetic.json - 2: constant.numeric.value.json - 3: punctuation.separator.decimal.json - - match: (-?)(0|[1-9]\d*) - scope: meta.number.integer.decimal.json - captures: - 1: keyword.operator.arithmetic.json - 2: constant.numeric.value.json - - object: - # a JSON object - - match: \{ - scope: punctuation.section.mapping.begin.json - push: - - meta_scope: meta.mapping.json - - match: \} - scope: punctuation.section.mapping.end.json - pop: 1 - - match: \" - scope: punctuation.definition.string.begin.json - push: - - clear_scopes: 1 - - meta_scope: meta.mapping.key.json string.quoted.double.json - - meta_include_prototype: false - - include: inside-string - - match: ':' - scope: punctuation.separator.mapping.key-value.json - push: - - match: ',|\s?(?=\})' - scope: invalid.illegal.expected-mapping-value.json - pop: 1 - - match: (?=\S) - set: - - clear_scopes: 1 - - meta_scope: meta.mapping.value.json - - include: value - - match: '' - set: - - match: ',' - scope: punctuation.separator.mapping.pair.json - pop: 1 - - match: \s*(?=\}) - pop: 1 - - match: \s(?!/[/*])(?=[^\s,])|[^\s,] - scope: invalid.illegal.expected-mapping-separator.json - pop: 1 - - match: '[^\s\}]' - scope: invalid.illegal.expected-mapping-key.json - - string: - - match: \" - scope: punctuation.definition.string.begin.json - push: inside-string - - inside-string: - - meta_scope: string.quoted.double.json - - meta_include_prototype: false - - match: \" - scope: punctuation.definition.string.end.json - pop: 1 - - include: string-escape - - match: \n - scope: invalid.illegal.unclosed-string.json - pop: 1 - - string-escape: - - match: |- - (?x: # turn on extended mode - \\ # a literal backslash - (?: # ...followed by... - ["\\/bfnrt] # one of these characters - | # ...or... - u # a u - [0-9a-fA-F]{4} # and four hex digits - ) - ) - scope: constant.character.escape.json - - match: \\. - scope: invalid.illegal.unrecognized-string-escape.json diff --git a/JSON/JSON5.sublime-syntax b/JSON/JSON5.sublime-syntax new file mode 100755 index 00000000000..a8b4001a8e7 --- /dev/null +++ b/JSON/JSON5.sublime-syntax @@ -0,0 +1,254 @@ +%YAML 1.2 +--- +# YAML Documentation: +# https://yaml.org/spec/1.2/spec.html +# Sublime Text Documentation: +# https://www.sublimetext.com/docs/syntax.html#ver-dev +# https://www.sublimetext.com/docs/syntax.html#testing:ver-dev +# https://www.sublimetext.com/docs/scope_naming.html +# This file is being maintained at: +# https://github.com/sublimehq/Packages/blob/master/JSON/JSON5.sublime-syntax +# +name: JSON5 +scope: source.json.json5 +version: 2 + +# https://www.sublimetext.com/docs/syntax.html#inheritance +extends: Packages/JSON/JSONC.sublime-syntax + +file_extensions: + + - json5 + # https://json5.org/ + # https://spec.json5.org/#summary-of-features + # https://262.ecma-international.org/5.1/ + + - .babelrc + # Babel.js File-relative Configuration + # https://babeljs.io/docs/en/config-files + + - .babelrc.json + # Babel.js File-relative Configuration + # https://babeljs.io/docs/en/config-files + + - .jupyterlab-settings + # JupyterLab User Settings + # https://jupyterlab.readthedocs.io/en/stable/user/directories.html?highlight=json5#jupyterlab-user-settings-directory + + - .parcelrc + # parcel Bundler Configuration + # https://github.com/parcel-bundler/parcel + # https://parceljs.org/features/plugins/#.parcelrc + + - .postcssrc.json + # PostCSS Configuration + # https://postcss.org + + - babel.config.json + # Babel.js Project-wide Configuration + # https://babeljs.io/docs/en/config-files + + - next.config.json + # Vercel Next.js Configuration + # https://nextjs.org/docs/api-reference/next.config.js/introduction + + - nextrc.json + # Vercel Next.js Configuration + # https://nextjs.org/docs/api-reference/next.config.js/introduction + + - techdocs_metadata.json + # Spotify's @backstage/techdocs_common Configuration + # https://github.com/backstage/backstage/tree/master/packages/techdocs-common + # https://backstage.io/docs/features/techdocs/techdocs-overview + +first_line_match: |- + (?xi: + ^ \s* // .*? -\*- .*? \bjson5\b .*? -\*- # editorconfig + ) + + +variables: + + # Unicode documentation: + # https://www.unicode.org/versions/latest/ + # https://www.unicode.org/Public/UCD/latest/ucd/ + # Oniguruma documentation: + # https://github.com/kkos/oniguruma/blob/master/doc/RE + # https://github.com/kkos/oniguruma/blob/master/doc/UNICODE_PROPERTIES + + identifier_escape: (?:\\u(?:\h{4}|\{\h+\})) + identifier_start: (?:[_$\p{L}\p{Nl}]|{{identifier_escape}}) + identifier_part: (?:[_$\p{L}\p{Nl}\p{Mn}\p{Mc}\p{Nd}\p{Pc}\x{200C}\x{200D}]|{{identifier_escape}}) + identifier_break: (?!{{identifier_part}}) + + identifier_name: (?:{{identifier_start}}{{identifier_part}}*{{identifier_break}}) + + +contexts: + + # TODO: check whitespace valid chars + +####[ Numbers ]######################################################################################################### + + # completely override original context + decimal-floats: + - match: |- + (?x: + ([-+]?) + ( + {{pos_integer_decimal}} + (?: + # 1. 1.e1 1.e-1 1.e+1 1.1 1.1e1 1.1e-1 1.1e+1 + (\.)\d* {{exponent}}? + # 1e1 1+e1 1-e1 + | {{exponent}} + ) + # .1 .1e1 .1e+1 .1e-1 + | (\.)\d+ {{exponent}}? + ) + ) + scope: meta.number.float.decimal.json5 + captures: + 1: constant.numeric.sign.json5 + 2: constant.numeric.value.json5 + 3: punctuation.separator.decimal.json5 + 4: punctuation.separator.decimal.json5 + - match: ([-+]?)(Infinity) + scope: meta.number.float.decimal.json5 + captures: + 1: constant.numeric.sign.json5 + 2: constant.language.infinity.json5 + - match: ([-+]?)(NaN) + scope: meta.number.float.decimal.json5 + captures: + 1: constant.numeric.sign.json5 + 2: constant.language.nan.json5 + + integers: + - meta_prepend: true + - include: hexadecimal-integers + + # completely override original context + decimal-integers: + - match: ([-+]?)({{pos_integer_decimal}}) + scope: meta.number.integer.decimal.json5 + captures: + 1: constant.numeric.sign.json5 + 2: constant.numeric.value.json5 + + hexadecimal-integers: + - match: ([-+]?)(0[xX])(\h+) + scope: meta.number.integer.hexadecimal.json5 + captures: + 1: constant.numeric.sign.json5 + 2: constant.numeric.base.json5 + 3: constant.numeric.value.json5 + +####[ Strings ]######################################################################################################### + + strings: + - meta_append: true + - include: single-quoted-strings + + single-quoted-strings: + - match: \' + scope: punctuation.definition.string.begin.json5 + push: inside-single-quoted-string + + inside-single-quoted-string: + - meta_include_prototype: false + - meta_scope: meta.string.json5 string.quoted.single.json5 + - match: \' + scope: punctuation.definition.string.end.json5 + pop: 1 + - include: single-quoted-string-escape-characters + - match: \n + scope: invalid.illegal.unclosed-string.json5 + pop: 1 + + single-quoted-string-escape-characters: + - meta_include_prototype: false + - match: \\\' + scope: constant.character.escape.single-quote.json5 + - include: string-escape-characters + + valid-string-escape-characters: + - meta_prepend: true + - meta_include_prototype: false + - match: ((\\)\x{2028})(?:(.*)(?:$\n)) + captures: + 1: constant.character.escape.line-separator.json5 + 2: punctuation.separator.continuation.line.json5 + 3: invalid.illegal.expected-eol-after-line-continuation.json5 + - match: ((\\)\x{2029})(?:(.*)(?:$\n)) + captures: + 1: constant.character.escape.paragraph-separator.json5 + 2: punctuation.separator.continuation.line.json5 + 3: invalid.illegal.expected-eol-after-line-continuation.json5 + - match: '(\\)(?:$\n)' + captures: + 1: punctuation.separator.continuation.line.json5 + - match: \\v + scope: constant.character.escape.vertical-tab.json5 + - match: (\\0)([0-9])? + captures: + 1: constant.character.escape.null.json5 + 2: invalid.illegal.unexpected-digit-character.json5 + - match: \\x[0-9a-fA-F]{2} + scope: constant.character.escape.unicode-symbol.basic-latin-or-latin-1-supplement.json5 + - match: \\u[0-9a-fA-F]{4}\\u[0-9a-fA-F]{4} + scope: constant.character.escape.unicode-symbol.utf16-surrogate-pair.json5 + + invalid-string-escape-characters: + - meta_prepend: true + - meta_include_prototype: false + - match: ([^\\])(?:\x{2028}|\x{2029}) + captures: + 1: invalid.illegal.expected-backslash-char.json5 + +####[ Mapping ]######################################################################################################### + + # The top-level contexts here are to ensure that we can apply `meta.toc-list` + # to the top-level object keys to index them as symbols. + + top-level-mapping-key: + - meta_append: true + - match: '(?={{identifier_name}})' + push: top-level-mapping-key-ecma + - match: "'" + scope: punctuation.definition.string.begin.json5 + push: top-level-mapping-key-single-quoted + + top-level-mapping-key-ecma: + - clear_scopes: 1 + - meta_include_prototype: false + - match: '{{identifier_name}}' + scope: meta.mapping.key.json5 meta.toc-list.json5 meta.string.json5 string.unquoted.plain.json5 + pop: 1 + + top-level-mapping-key-single-quoted: + - clear_scopes: 1 + - meta_include_prototype: false + - meta_scope: meta.mapping.key.json5 meta.toc-list.json5 meta.string.json5 string.quoted.single.json5 + - include: inside-single-quoted-string + + mapping-key: + - meta_append: true + - match: "'" + scope: punctuation.definition.string.begin.json5 + push: mapping-key-single-quoted + - match: '(?={{identifier_name}})' + push: mapping-key-ecma + + mapping-key-ecma: + - clear_scopes: 1 + - meta_include_prototype: false + - match: '{{identifier_name}}' + scope: meta.mapping.key.json5 meta.string.json5 string.unquoted.plain.json5 + pop: 1 + + mapping-key-single-quoted: + - clear_scopes: 1 + - meta_include_prototype: false + - meta_scope: meta.mapping.key.json5 meta.string.json5 string.quoted.single.json5 + - include: inside-single-quoted-string diff --git a/JSON/JSONC.sublime-syntax b/JSON/JSONC.sublime-syntax new file mode 100755 index 00000000000..58b4556da04 --- /dev/null +++ b/JSON/JSONC.sublime-syntax @@ -0,0 +1,155 @@ +%YAML 1.2 +--- +# YAML Documentation: +# https://yaml.org/spec/1.2/spec.html +# Sublime Text Documentation: +# https://www.sublimetext.com/docs/syntax.html#ver-dev +# https://www.sublimetext.com/docs/syntax.html#testing:ver-dev +# https://www.sublimetext.com/docs/scope_naming.html +# This file is being maintained at: +# https://github.com/sublimehq/Packages/blob/master/JSON/JSONC.sublime-syntax +# +name: JSONC +scope: source.json.jsonc +version: 2 + +# https://www.sublimetext.com/docs/syntax.html#inheritance +extends: Packages/JSON/JSON.sublime-syntax + +file_extensions: + - jsonc + + - sublime-build + # https://www.sublimetext.com/docs/build_systems.html + + - sublime-color-scheme + # https://www.sublimetext.com/docs/color_schemes.html + + - sublime-commands + + - sublime-completions + # https://www.sublimetext.com/docs/completions.html + + - sublime-keymap + # https://www.sublimetext.com/docs/key_bindings.html + + - sublime-macro + + - sublime-menu + # https://www.sublimetext.com/docs/menus.html + + - sublime-mousemap + + - sublime-project + # https://www.sublimetext.com/docs/projects.html + + - sublime-settings + # https://www.sublimetext.com/docs/settings.html + + - sublime-theme + # https://www.sublimetext.com/docs/themes.html + + - sublime-workspace + # https://www.sublimetext.com/docs/projects.html + + - .ember-cli + + - .eslintrc + # ESLint Configuration + # https://eslint.org/docs/user-guide/configuring/ + + - .eslintrc.json + # ESLint Configuration + # https://eslint.org/docs/user-guide/configuring/ + + - .hintrc + # Webhint Configuration + # https://webhint.io/docs/user-guide/configuring-webhint/summary/ + + - .htmlhintrc + # HTMLHint Configuration + # https://htmlhint.com/docs/user-guide/configuration + + - .jshintrc + # JSHint + # https://www.jshint.com/docs/#options + + - .jslintrc + # JSLint's implementation of JSHint + # https://www.jslint.com/lint.html + + - .stylintrc + # stylint Configuration + # https://github.com/SimenB/stylint + + - .swcrc + # swc Configuration + # https://swc.rs/docs/configuring-swc + + - eslintrc.json + # ESLint Configuration + # https://eslint.org/docs/user-guide/configuring/ + + - languagebabel + + - tsconfig.json + # TypeScript Configuration + # https://www.typescriptlang.org/docs/handbook/tsconfig-json.html + +first_line_match: |- + (?xi: + ^ \s* // .*? -\*- .*? \bjsonc\b .*? -\*- # editorconfig + ) + + +contexts: + +####[ Comments ]######################################################################################################## + + # completely override original context + comment-line: + - meta_include_prototype: false + - match: '//' + scope: punctuation.definition.comment.jsonc + push: + - meta_include_prototype: false + - meta_scope: comment.line.double-slash.jsonc + - include: eol-pop + + # completely override original context + comment-doc-block: + - meta_include_prototype: false + - match: '/\*\*(?!/)' + scope: punctuation.definition.comment.begin.jsonc + push: + - meta_include_prototype: false + - meta_scope: comment.block.documentation.jsonc + - include: comment-block-end + - match: '^\s*(\*)(?!/)' + captures: + 1: punctuation.definition.comment.jsonc + + # completely override original context + comment-block: + - meta_include_prototype: false + - match: '/\*' + scope: punctuation.definition.comment.begin.jsonc + push: + - meta_include_prototype: false + - meta_scope: comment.block.jsonc + - include: comment-block-end + + # completely override original context + comment-block-end: + - meta_include_prototype: false + - match: '\*/' + scope: punctuation.definition.comment.end.jsonc + pop: 1 + +####[ Sequence ]######################################################################################################## + + # completely override original context + array-separators: + - match: ',' + scope: punctuation.separator.sequence.jsonc + push: array-illegal-separator diff --git a/JSON/Main.sublime-menu b/JSON/Main.sublime-menu new file mode 100755 index 00000000000..2d376cf973a --- /dev/null +++ b/JSON/Main.sublime-menu @@ -0,0 +1,124 @@ +// Packages/JSON/Main.sublime-menu +// +// This file is being maintained at: +// https://github.com/sublimehq/Packages/blob/master/JSON/Main.sublime-menu + + +[ + { + "id": "preferences", + "children": + [ + { + "id": "package-settings", + "children": + [ + { + "caption": "JSON", + "children": + [ + { + "caption": "JSON: Minify", + "command": "json_minify" + }, + { + "caption": "JSON: Prettify", + "command": "json_prettify" + }, + { + "command": "json_toggle_auto_prettify", + "caption": "JSON: Automatically prettify before saving", + "checkbox": false + }, + { + "caption": "JSONC: Minify", + "command": "jsonc_minify" + }, + { + "caption": "JSONC: Prettify", + "command": "jsonc_prettify" + }, + { "caption": "-" }, + + // entries at this level above may be hidden depending + // upon the current view's syntax + + { + "caption": "JSON: Settings - Syntax Specific", + "command": "edit_settings", + "args": + { + "base_file": "${packages}/JSON/JSON.sublime-settings", + "default": "{\n\t$0\n}\n" + } + }, + { "caption": "-" }, + { + "caption": "Documentation", + "children": + [ + { + "caption": "JSON: Specs", + "command": "open_url", + "args": + { + "url": "https://www.json.org/json-en.html" + } + }, + { + "caption": "JSON: RFC 7159", + "command": "open_url", + "args": + { + "url": "https://datatracker.ietf.org/doc/html/rfc7159" + } + }, + { + "caption": "JSON: ECMA 404", + "command": "open_url", + "args": + { + "url": "https://www.ecma-international.org/publications-and-standards/standards/ecma-404/" + } + }, + { "caption": "-" }, + { + "caption": "JSON5: Specs", + "command": "open_url", + "args": + { + "url": "https://spec.json5.org/#summary-of-features" + } + } + ] + }, + { "caption": "-" }, + { + "caption": "Support", + "children": + [ + { + "caption": "Changelog", + "command": "open_url", + "args": + { + "url": "https://github.com/sublimehq/Packages/commits/master/JSON" + } + }, + { + "caption": "Report an issue", + "command": "open_url", + "args": + { + "url": "https://github.com/sublimehq/Packages/issues" + } + } + ] + } + ] + } + ] + } + ] + } +] diff --git a/JSON/Symbol List - JSON.tmPreferences b/JSON/Symbol List - JSON.tmPreferences new file mode 100755 index 00000000000..141613fb0e6 --- /dev/null +++ b/JSON/Symbol List - JSON.tmPreferences @@ -0,0 +1,11 @@ + + + + scopemeta.toc-list.json + settings + + showInSymbolList1 + showInIndexedSymbolList1 + + + diff --git a/JSON/Symbol List - JSON5.tmPreferences b/JSON/Symbol List - JSON5.tmPreferences new file mode 100755 index 00000000000..facdefaadf9 --- /dev/null +++ b/JSON/Symbol List - JSON5.tmPreferences @@ -0,0 +1,11 @@ + + + + scopemeta.toc-list.json5 | meta.toc-list.json + settings + + showInSymbolList1 + showInIndexedSymbolList1 + + + diff --git a/JSON/main.py b/JSON/main.py new file mode 100755 index 00000000000..8ddf5603bdb --- /dev/null +++ b/JSON/main.py @@ -0,0 +1,18 @@ +#!/usr/bin/env python +# coding: utf-8 + +# This file is being maintained at: +# https://github.com/sublimehq/Packages/blob/master/JSON/main.py + + +import sublime + +from .src import * + + +def plugin_loaded() -> None: + json_prettify.plugin_loaded() + + +def plugin_unloaded() -> None: + json_prettify.plugin_unloaded() diff --git a/JSON/src/__init__.py b/JSON/src/__init__.py new file mode 100755 index 00000000000..181339e8b50 --- /dev/null +++ b/JSON/src/__init__.py @@ -0,0 +1,9 @@ +#!/usr/bin/env python +# coding: utf-8 + +# This file is being maintained at: +# https://github.com/sublimehq/Packages/blob/master/JSON/src/__init__.py + + +from .json_prettify import * +from .jsonc_prettify import * diff --git a/JSON/src/json_prettify.py b/JSON/src/json_prettify.py new file mode 100755 index 00000000000..9e7e86e7e78 --- /dev/null +++ b/JSON/src/json_prettify.py @@ -0,0 +1,211 @@ +#!/usr/bin/env python +# coding: utf-8 + +# This file is being maintained at: +# https://github.com/sublimehq/Packages/blob/master/JSON/src/json_prettify.py + + +import sublime +import sublime_plugin + +import json +from typing import ( + Any, + Union +) + + +PKG_NAME: str = __package__.split('.')[0] +settings: Union[sublime.Settings, None] = None +base_settings: str = 'JSON.sublime-settings' +base_scope: str = 'source.json - (source.json.jsonc | source.json.json5)' + + +def status_msg(msg: str = '') -> None: + if msg == '': return + sublime.status_message(f'{PKG_NAME}: {msg}') + + +def print_msg(msg_header: str = '', msg_body: str = '') -> None: + if msg_body == '': return + print(f'JSON: {msg_header}:\n\n{msg_body}\n\n') + + +def json2py(view: sublime.View) -> Any: + old_contents: str = view.substr( + x=whole_view(view) + ) + try: + return json.loads( # https://docs.python.org/3.8/library/json.html#json.loads + s=old_contents + ) + except Exception as e: + print_msg(msg_header='Conversion failed due to error:', msg_body=f'{e}') + return None + + +def whole_view(view: sublime.View) -> sublime.Region: + return sublime.Region( + a=0, + b=view.size() + ) + + +def is_json(view: sublime.View) -> bool: + return view.match_selector( + pt=0, + selector=base_scope + ) + + +def plugin_loaded(reload: bool = False) -> None: + try: + global settings + settings = sublime.load_settings(base_name=base_settings) + settings.clear_on_change(tag='reload') + settings.add_on_change( + tag='reload', + callback=lambda: plugin_loaded(reload=True) + ) + except Exception as e: + print_msg(msg_header=f'Loading "{base_settings}" failed due to error', msg_body=f'{e}') + + if reload: + status_msg('Reloaded settings on change.') + + +def plugin_unloaded() -> None: + global settings + settings = None + + +class JsonToggleAutoPrettify(sublime_plugin.WindowCommand): + + _is_checked: bool = False + _key: str = 'json.auto_prettify' + + def __init__(self, window: sublime.Window) -> None: + self.window = window + + try: + if settings is None: + return + self._is_checked = settings.has(key=self._key) + except Exception: + pass + + def run(self) -> None: + try: + global settings + if settings is None: + return + if self._is_checked: + settings.erase(key=self._key) # remove the override (true) of the default (false) + else: + settings.set(key=self._key, value=True) + sublime.save_settings(base_name=base_settings) + self._is_checked = not self._is_checked # toggle + except Exception: + pass + + def is_checked(self) -> bool: + return self._is_checked + + def is_visible(self) -> bool: + try: + view: Union[sublime.View, None] = self.window.active_view() + if view is None: + return False + return is_json(view) + except Exception as e: + print_msg('Error while trying to check if active view is JSON', msg_body=f'{e}') + return False + + +class JsonAutoPrettifyListener(sublime_plugin.EventListener): + + _key: str = 'json.auto_prettify' + + def on_pre_save_async(self, view) -> None: + if not is_json(view): + return + if settings is None: + return + if not settings.get(key=self._key, default=False): + return + view.run_command(cmd='json_prettify') + + +class JsonPrettify(sublime_plugin.TextCommand): + + def run(self, edit_token: sublime.Edit) -> None: + """ + Attempt to prettify the current view's JSON contents. Print errors to + the console when it fails. + """ + + try: + json_as_python: Any = json2py(self.view) + if json_as_python is None: return + self.view.replace( + edit_token, + r=whole_view(self.view), + text=json.dumps( # https://docs.python.org/3.8/library/json.html#json.dumps + obj=json_as_python, + allow_nan=False, + indent=4, + sort_keys=True + ) + ) + status_msg('Prettified.') + except Exception as e: + print_msg(msg_header='Conversion failed due to error', msg_body=f'{e}') + status_msg('Prettifying failed. See console for details.') + pass + + def is_enabled(self) -> bool: + return is_json(self.view) + + def is_visible(self) -> bool: + return is_json(self.view) + + def description(self) -> str: + return 'Prettify JSON' + + +class JsonMinify(sublime_plugin.TextCommand): + + def run(self, edit_token: sublime.Edit) -> None: + """ + Attempt to minify the current view's JSON contents. Print errors to + the console when it fails. + """ + + try: + json_as_python: Any = json2py(self.view) + if json_as_python is None: return + self.view.replace( + edit_token, + r=whole_view(self.view), + text=json.dumps( # https://docs.python.org/3.8/library/json.html#json.dumps + obj=json_as_python, + allow_nan=False, + indent=None, + separators=(',', ':'), + sort_keys=True + ) + ) + status_msg('Minified.') + except Exception as e: + print_msg(msg_header='Conversion failed due to error', msg_body=f'{e}') + status_msg('Minifying failed. See console for details.') + pass + + def is_enabled(self) -> bool: + return is_json(self.view) + + def is_visible(self) -> bool: + return is_json(self.view) + + def description(self) -> str: + return 'Minify JSON' diff --git a/JSON/src/jsonc_prettify.py b/JSON/src/jsonc_prettify.py new file mode 100755 index 00000000000..88dd3aeafb9 --- /dev/null +++ b/JSON/src/jsonc_prettify.py @@ -0,0 +1,136 @@ +#!/usr/bin/env python +# coding: utf-8 + +# This file is being maintained at: +# https://github.com/sublimehq/Packages/blob/master/JSON/src/jsonc_prettify.py + + +import sublime +import sublime_plugin + +import json +from typing import ( + Any +) + + +PKG_NAME: str = __package__.split('.')[0] +base_scope: str = 'source.json.jsonc' + + +def status_msg(msg: str = '') -> None: + if msg == '': return + sublime.status_message(f'{PKG_NAME}: {msg}') + + +def print_msg(msg_header: str = '', msg_body: str = '') -> None: + if msg_body == '': return + print(f'JSONC: {msg_header}:\n\n{msg_body}\n\n') + + +def json2py(view: sublime.View) -> Any: + old_contents: str = view.substr( + x=whole_view(view) + ) + return sublime.decode_value( + data=old_contents + ) + + +def whole_view(view: sublime.View) -> sublime.Region: + return sublime.Region( + a=0, + b=view.size() + ) + + +def is_jsonc(view: sublime.View) -> bool: + return view.match_selector( + pt=0, + selector=base_scope + ) + + +class JsoncPrettify(sublime_plugin.TextCommand): + + def run(self, edit_token: sublime.Edit, auto: bool = False) -> None: + """ + Attempt to prettify the current view's JSONC contents. Print errors to + the console when it fails. + """ + + try: + if not auto and not sublime.ok_cancel_dialog( + msg='Prettifying JSONC will remove included comments and trailing commas.', + ok_title='Continue', + title='JSONC: Prettify' # only shown on Windows + ): + return + json_as_python = json2py(self.view) + self.view.replace( + edit_token, + r=whole_view(self.view), + text=json.dumps( # https://docs.python.org/3.8/library/json.html#json.dumps + obj=json_as_python, + allow_nan=False, + indent=4, + sort_keys=True + ) + ) + status_msg('Prettified.') + except Exception as e: + print_msg(msg_header='Conversion failed due to error', msg_body=f'{e}') + status_msg('Prettifying failed. See console for details.') + pass + + def is_enabled(self) -> bool: + return is_jsonc(self.view) + + def is_visible(self) -> bool: + return is_jsonc(self.view) + + def description(self) -> str: + return 'Prettify JSONC' + + +class JsoncMinify(sublime_plugin.TextCommand): + + def run(self, edit_token: sublime.Edit, auto: bool = False) -> None: + """ + Attempt to minify the current view's JSONC contents. Print errors to + the console when it fails. + """ + + try: + if not auto and not sublime.ok_cancel_dialog( + msg='Minifying JSONC will remove included comments and trailing commas.', + ok_title='Continue', + title='JSONC: Minify' # only shown on Windows + ): + return + json_as_python = json2py(self.view) + self.view.replace( + edit_token, + r=whole_view(self.view), + text=json.dumps( # https://docs.python.org/3.8/library/json.html#json.dumps + obj=json_as_python, + allow_nan=False, + indent=None, + separators=(',', ':'), + sort_keys=True + ) + ) + status_msg('Minified.') + except Exception as e: + print_msg(msg_header='Conversion failed due to error', msg_body=f'{e}') + status_msg('Minifying failed. See console for details.') + pass + + def is_enabled(self) -> bool: + return is_jsonc(self.view) + + def is_visible(self) -> bool: + return is_jsonc(self.view) + + def description(self) -> str: + return 'Minify JSONC' diff --git a/JSON/syntax_test_json.json b/JSON/syntax_test_json.json deleted file mode 100644 index 77718007718..00000000000 --- a/JSON/syntax_test_json.json +++ /dev/null @@ -1,123 +0,0 @@ -// SYNTAX TEST "Packages/JSON/JSON.sublime-syntax" - -{ -// <- meta.mapping.json punctuation.section.mapping.begin.json - "bool": false, -//^^^^^^ meta.mapping.key.json -//^^^^^^^^^^^^^^ - meta.mapping meta.mapping -// ^^^^^ constant.language.boolean.json - - "null": null, -//^^^^^^ meta.mapping.key.json -//^^^^^^^^^^^^^ - meta.mapping meta.mapping -// ^^^^ constant.language.null.json - - "dict": { "key": "value" } -// ^^^^^^^^^^^^^^^^^^ meta.mapping.value.json meta.mapping - meta.mapping meta.mapping meta.mapping -// ^ punctuation.section.mapping.begin.json -// ^ punctuation.section.mapping.end.json -// ^^ meta.mapping.value.json meta.mapping.json -// ^^^^^ meta.mapping.key.json string.quoted.double.json -// ^^ meta.mapping.value.json meta.mapping.json -// ^^^^^^^ meta.mapping.value.json meta.mapping.value.json string.quoted.double.json -// ^^ meta.mapping.value.json meta.mapping.json - -, , -// <- punctuation.separator.mapping.pair.json -//^ invalid.illegal.expected-mapping-key.json - - "sep": {}, -// ^ punctuation.separator.mapping.key-value.json - - "array": [ /**/ ], -// ^^^^^^^^ meta.mapping.value.json meta.sequence.json -// ^ punctuation.section.sequence.begin.json -// ^^^^ comment.block.json -// ^ punctuation.section.sequence.end.json - - "dict": {"foo": }, -// ^ invalid.illegal.expected-mapping-value.json -// ^ punctuation.section.mapping.end.json - "dict": {"foo": - }, -//^ invalid.illegal.expected-mapping-value.json -// ^ punctuation.section.mapping.end.json - - "dict": {"foo"/*comment*/:/*comment*/"bar"/*comment*/}, -// ^^^^^^^^^^^ comment.block.json -// ^^^^^^^^^^^ comment.block.json -// ^^^^^^^^^^^ comment.block.json - - "dict": { - "foo": "bar" - // comment -// ^ - invalid -// ^^^^^^^^^^ comment.line.double-slash.js - , -// ^ punctuation.separator.mapping.pair.json - "foo": "bar" - /* comment */ -// ^ - invalid -// ^^^^^^^^^^^^^ comment.block.json - }, -//^ punctuation.section.mapping.end.json -// ^ punctuation.separator.mapping.pair.json - - "string": "string", -// ^ punctuation.definition.string.begin.json -// ^^^^^^^^ meta.mapping.value.json string.quoted.double.json -// ^ punctuation.definition.string.end.json - - "num": 20.09, -// ^^^^^ meta.number.float.decimal.json constant.numeric.value.json -// ^ punctuation.separator.decimal.json - - "neg": -9, -// ^^ meta.number.integer.decimal.json -// ^ keyword.operator.arithmetic.json -// ^ constant.numeric.value.json - - "E": 20e10, -// ^^^^^ meta.number.float.decimal.json constant.numeric.value.json -//^^^ meta.mapping.key.json string.quoted.double.json -// ^ punctuation.separator.mapping.key-value.json - meta.mapping.key - - "escape": "\n", -// ^^ constant.character.escape.json -// ^^^^ meta.mapping.value.json string.quoted.double.json - meta.mapping.key - - "illegal": "\.", -// ^^ invalid.illegal.unrecognized-string-escape.json - - "unterminated string -//^^^^^^^^^^^^^^^^^^^^ string.quoted.double.json -// ^ string.quoted.double.json invalid.illegal.unclosed-string.json - -// <- - string - -/**/: "test", -// ^ meta.mapping.json comment.block.json -// ^ punctuation.separator.mapping.key-value.json - comment -// ^^^^^^ meta.mapping.value.json string.quoted.double.json - - "array2": - [ - "foobar", -// ^^^^^^^^ meta.mapping.value meta.sequence.json string.quoted.double.json - meta.mapping.key - ] - - [], -//^ invalid.illegal.expected-mapping-separator.json -// ^^^ invalid.illegal.expected-mapping-key.json - - "typing json": {} - ,,,, "another key": false, - - "ke//y": "value" -//^^^^^^^ meta.mapping.key.json string.quoted.double.json - comment - -/** - * -// ^ meta.mapping.json comment.block.documentation.json punctuation.definition.comment.json -*/ -} diff --git a/JSON/tests/indentation/syntax_test_indentation.mapping.json b/JSON/tests/indentation/syntax_test_indentation.mapping.json new file mode 100644 index 00000000000..cb36ba9613b --- /dev/null +++ b/JSON/tests/indentation/syntax_test_indentation.mapping.json @@ -0,0 +1,36 @@ +// SYNTAX TEST reindent "Packages/JSON/JSON.sublime-syntax" + +// <- source.json - source.json.jsonc + +{ + "a": + [ + "a", + "b" + ], + "b": + [ + { + "a": "a", + "b": "b" + }, + { + "a": "a", + "b": "b" + } + ], + "c": + { + "a": + { + "a": "a", + "b": "b" + }, + "b": + [ + "a", + "b", + "c" + ] + } +} diff --git a/JSON/tests/indentation/syntax_test_indentation.mapping.json5 b/JSON/tests/indentation/syntax_test_indentation.mapping.json5 new file mode 100644 index 00000000000..bd8da806f7c --- /dev/null +++ b/JSON/tests/indentation/syntax_test_indentation.mapping.json5 @@ -0,0 +1,36 @@ +// SYNTAX TEST reindent "Packages/JSON/JSON5.sublime-syntax" + +// <- source.json.json5 + +{ + "a": + [ + "a", + "b" + ], + "b": + [ + { + "a": "a", + "b": "b" + }, + { + "a": "a", + "b": "b" + } + ], + "c": + { + "a": + { + "a": "a", + "b": "b" + }, + "b": + [ + "a", + "b", + "c" + ] + } +} diff --git a/JSON/tests/indentation/syntax_test_indentation.mapping.jsonc b/JSON/tests/indentation/syntax_test_indentation.mapping.jsonc new file mode 100644 index 00000000000..77dbaad820f --- /dev/null +++ b/JSON/tests/indentation/syntax_test_indentation.mapping.jsonc @@ -0,0 +1,36 @@ +// SYNTAX TEST reindent "Packages/JSON/JSONC.sublime-syntax" + +// <- source.json.jsonc + +{ + "a": + [ + "a", + "b" + ], + "b": + [ + { + "a": "a", + "b": "b" + }, + { + "a": "a", + "b": "b" + } + ], + "c": + { + "a": + { + "a": "a", + "b": "b" + }, + "b": + [ + "a", + "b", + "c" + ] + } +} diff --git a/JSON/tests/indentation/syntax_test_indentation.sequence.json b/JSON/tests/indentation/syntax_test_indentation.sequence.json new file mode 100644 index 00000000000..6c7ba39e55a --- /dev/null +++ b/JSON/tests/indentation/syntax_test_indentation.sequence.json @@ -0,0 +1,90 @@ +// SYNTAX TEST reindent "Packages/JSON/JSON.sublime-syntax" + +// <- source.json - source.json.jsonc + +[ + [ + "a", + "b", + "c" + ], + [ + 1, + 2, + 3 + ], + [ + [ + "a", + "b", + "c" + ], + [ + 1, + 2, + 3 + ], + [ + { + "a": "a", + "b": "b", + "c": "c" + }, + { + "a": "a", + "b": "b", + "c": "c" + }, + { + "a": "a", + "b": "b", + "c": "c" + } + ], + [ + [ + "a", + "b", + "c" + ], + [ + 1, + 2, + 3 + ], + [ + {"a": "a"}, + {"b": "b"}, + {"c": "c"} + ], + [ + [ + "a", + "b", + "c" + ], + [ + 1, + 2, + 3 + ], + [ + { + "a": "a" + }, + { + "b": "b" + }, + { + "c": "c" + } + ], + [ + [0], + [0], + [0] + ] + ] + ] + ] +] diff --git a/JSON/tests/indentation/syntax_test_indentation.sequence.json5 b/JSON/tests/indentation/syntax_test_indentation.sequence.json5 new file mode 100644 index 00000000000..647e32e2a7d --- /dev/null +++ b/JSON/tests/indentation/syntax_test_indentation.sequence.json5 @@ -0,0 +1,90 @@ +// SYNTAX TEST reindent "Packages/JSON/JSON5.sublime-syntax" + +// <- source.json.json5 + +[ + [ + "a", + "b", + "c" + ], + [ + 1, + 2, + 3 + ], + [ + [ + "a", + "b", + "c" + ], + [ + 1, + 2, + 3 + ], + [ + { + "a": "a", + "b": "b", + "c": "c" + }, + { + "a": "a", + "b": "b", + "c": "c" + }, + { + "a": "a", + "b": "b", + "c": "c" + } + ], + [ + [ + "a", + "b", + "c" + ], + [ + 1, + 2, + 3 + ], + [ + {"a": "a"}, + {"b": "b"}, + {"c": "c"} + ], + [ + [ + "a", + "b", + "c" + ], + [ + 1, + 2, + 3 + ], + [ + { + "a": "a" + }, + { + "b": "b" + }, + { + "c": "c" + } + ], + [ + [0], + [0], + [0] + ] + ] + ] + ] +] diff --git a/JSON/tests/indentation/syntax_test_indentation.sequence.jsonc b/JSON/tests/indentation/syntax_test_indentation.sequence.jsonc new file mode 100644 index 00000000000..dfb2ce15980 --- /dev/null +++ b/JSON/tests/indentation/syntax_test_indentation.sequence.jsonc @@ -0,0 +1,90 @@ +// SYNTAX TEST reindent "Packages/JSON/JSONC.sublime-syntax" + +// <- source.json.jsonc + +[ + [ + "a", + "b", + "c" + ], + [ + 1, + 2, + 3 + ], + [ + [ + "a", + "b", + "c" + ], + [ + 1, + 2, + 3 + ], + [ + { + "a": "a", + "b": "b", + "c": "c" + }, + { + "a": "a", + "b": "b", + "c": "c" + }, + { + "a": "a", + "b": "b", + "c": "c" + } + ], + [ + [ + "a", + "b", + "c" + ], + [ + 1, + 2, + 3 + ], + [ + {"a": "a"}, + {"b": "b"}, + {"c": "c"} + ], + [ + [ + "a", + "b", + "c" + ], + [ + 1, + 2, + 3 + ], + [ + { + "a": "a" + }, + { + "b": "b" + }, + { + "c": "c" + } + ], + [ + [0], + [0], + [0] + ] + ] + ] + ] +] diff --git a/JSON/tests/symbols/syntax_test_symbols.json b/JSON/tests/symbols/syntax_test_symbols.json new file mode 100644 index 00000000000..102c67dabb6 --- /dev/null +++ b/JSON/tests/symbols/syntax_test_symbols.json @@ -0,0 +1,15 @@ +// SYNTAX TEST "Packages/JSON/JSON.sublime-syntax" + +// <- source.json - source.json.jsonc + +{ + "key": "value", +// ^^^^^ meta.toc-list.json +// @@@@@ definition + + "key-two": { "key-two-one": "value", "key-two-two": "value" } +// ^^^^^^^^^ meta.toc-list.json +// ^^^^^^^^^^^^^ - meta.toc-list.json +// ^^^^^^^^^^^^^ - meta.toc-list.json +// @@@@@@@@@ definition +} diff --git a/JSON/tests/symbols/syntax_test_symbols.json5 b/JSON/tests/symbols/syntax_test_symbols.json5 new file mode 100644 index 00000000000..6946b6a96aa --- /dev/null +++ b/JSON/tests/symbols/syntax_test_symbols.json5 @@ -0,0 +1,37 @@ +// SYNTAX TEST "Packages/JSON/JSON5.sublime-syntax" + +// <- source.json.json5 + +{ + _keyOne: "value", +// ^^^^^^^ meta.toc-list.json5 +// @@@@@@@ definition + + $keyTwo: "value", +// ^^^^^^^ meta.toc-list.json5 +// @@@@@@@ definition + + \u1234keyThree: "value", +// ^^^^^^^^^^^^^^ meta.toc-list.json5 +// @@@@@@@@@@@@@@ definition + + "key-four": "value", +// ^^^^^^^^^^ meta.toc-list.json +// @@@@@@@@@@ definition + + 'key-five': 'value', +// ^^^^^^^^^^ meta.toc-list.json5 +// @@@@@@@@@@ definition + + "key-six": { "key-three-one": "value", "key-three-two": "value" }, +// ^^^^^^^^^ meta.toc-list.json +// ^^^^^^^^^^^^^^^ - meta.toc-list.json +// ^^^^^^^^^^^^^^^ - meta.toc-list.json +// @@@@@@@@@ definition + + 'key-seven': { 'key-four-one': 'value', 'key-four-two': 'value' } +// ^^^^^^^^^^^ meta.toc-list.json5 +// ^^^^^^^^^^^^^^ - meta.toc-list.json5 +// ^^^^^^^^^^^^^^ - meta.toc-list.json5 +// @@@@@@@@@@@ definition +} diff --git a/JSON/tests/symbols/syntax_test_symbols.jsonc b/JSON/tests/symbols/syntax_test_symbols.jsonc new file mode 100644 index 00000000000..1bbb9c71e97 --- /dev/null +++ b/JSON/tests/symbols/syntax_test_symbols.jsonc @@ -0,0 +1,15 @@ +// SYNTAX TEST "Packages/JSON/JSONC.sublime-syntax" + +// <- source.json.jsonc + +{ + "key": "value", +// ^^^^^ meta.toc-list.json +// @@@@@ definition + + "key-two": { "key-two-one": "value", "key-two-two": "value" } +// ^^^^^^^^^ meta.toc-list.json +// ^^^^^^^^^^^^^ - meta.toc-list.json +// ^^^^^^^^^^^^^ - meta.toc-list.json +// @@@@@@@@@ definition +} diff --git a/JSON/tests/syntax/syntax_test_json.comment.json b/JSON/tests/syntax/syntax_test_json.comment.json new file mode 100644 index 00000000000..5465aeec8fc --- /dev/null +++ b/JSON/tests/syntax/syntax_test_json.comment.json @@ -0,0 +1,10 @@ +// SYNTAX TEST "Packages/JSON/JSON.sublime-syntax" + +// <- source.json - source.json.jsonc + +// comment +// <- invalid.illegal.comment - invalid.illegal.cooment invalid.illegal.comment + // <- invalid.illegal.comment - invalid.illegal.cooment invalid.illegal.comment +//^^^^^^^^ invalid.illegal.comment - invalid.illegal.cooment invalid.illegal.comment + +"testing use of meta_content_scope vs meta_scope" diff --git a/JSON/tests/syntax/syntax_test_json.invalid.illegal.leading_or_trailing_comma_in_mapping.json b/JSON/tests/syntax/syntax_test_json.invalid.illegal.leading_or_trailing_comma_in_mapping.json new file mode 100644 index 00000000000..1b21ab889f0 --- /dev/null +++ b/JSON/tests/syntax/syntax_test_json.invalid.illegal.leading_or_trailing_comma_in_mapping.json @@ -0,0 +1,11 @@ +// SYNTAX TEST "Packages/JSON/JSON.sublime-syntax" + +// <- source.json + +{ + , +// ^ meta.mapping invalid.illegal.expected-mapping-key + "a": 1, + "b": { , "a": 1, "b": 2, }, +// ^ meta.mapping meta.mapping invalid.illegal.expected-mapping-key +} diff --git a/JSON/tests/syntax/syntax_test_json.invalid.illegal.unexpected_separator.json b/JSON/tests/syntax/syntax_test_json.invalid.illegal.unexpected_separator.json new file mode 100644 index 00000000000..aea2b898cd4 --- /dev/null +++ b/JSON/tests/syntax/syntax_test_json.invalid.illegal.unexpected_separator.json @@ -0,0 +1,23 @@ +// SYNTAX TEST "Packages/JSON/JSON.sublime-syntax" + +// <- source.json - source.json.jsonc + +[ + , +// ^^^ meta.sequence.list +// ^ invalid.illegal.unexpected-separator + + 1,, +// ^^^^^ meta.sequence.list +// ^ constant.numeric.value +// ^ punctuation.separator.sequence +// ^ invalid.illegal.unexpected-separator + + [, 1,, 2,], +// ^^^^^^^^^ meta.sequence.list meta.sequence.list +// ^ invalid.illegal.unexpected-separator +// ^ punctuation.separator.sequence +// ^ invalid.illegal.unexpected-separator +// ^ invalid.illegal.unexpected-separator +// ^ invalid.illegal.unexpected-separator +] diff --git a/JSON/tests/syntax/syntax_test_json.invalid.illegal.unexpected_structure_or_value.json b/JSON/tests/syntax/syntax_test_json.invalid.illegal.unexpected_structure_or_value.json new file mode 100644 index 00000000000..d8637690c3b --- /dev/null +++ b/JSON/tests/syntax/syntax_test_json.invalid.illegal.unexpected_structure_or_value.json @@ -0,0 +1,10 @@ +// SYNTAX TEST "Packages/JSON/JSON.sublime-syntax" + +// <- source.json - source.json.jsonc + + 5, 5 +// ^ invalid.illegal.unexpected-separator +// ^ invalid.illegal.unexpected-code-after-first-structure-or-value + + // comment +// ^^^^^^^^^^ invalid.illegal.comment - invalid.illegal.unexpected-code-after-first-structure-or-value diff --git a/JSON/tests/syntax/syntax_test_json5.comment.json5 b/JSON/tests/syntax/syntax_test_json5.comment.json5 new file mode 100644 index 00000000000..50a752e9b7b --- /dev/null +++ b/JSON/tests/syntax/syntax_test_json5.comment.json5 @@ -0,0 +1,42 @@ +// SYNTAX TEST "Packages/JSON/JSON5.sublime-syntax" + +// <- source.json.json5 + +{ + // comment 'not a string' +// ^^^^^^^^^^^^^^^^^^^^^^^^^^ comment.line.double-slash +// ^^ comment.line.double-slash punctuation.definition.comment +// ^^^^^^^^^^^^^^ - meta.string string.quoted.single +// ^ - punctuation.definition.string.begin +// ^ - punctuation.definition.string.end + + /** comment 'not a string' */ +// ^^^ comment.block.documentation punctuation.definition.comment.begin +// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ comment.block.documentation +// ^^^^^^^^^^^^^^ - meta.string string.quoted.single +// ^ - punctuation.definition.string.begin +// ^ - punctuation.definition.string.end +// ^^ comment.block.documentation punctuation.definition.comment.end + + /** comment + 'not a string' */ +// ^^^^^^^^^^^^^^ - meta.string string.quoted.single +// ^ - punctuation.definition.string.begin +// ^ - punctuation.definition.string.end +// ^^ comment.block.documentation punctuation.definition.comment.end + + /* comment 'not a string' */ +// ^^ comment.block punctuation.definition.comment.begin +// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ comment.block +// ^^^^^^^^^^^^^^ - meta.string string.quoted.single +// ^ - punctuation.definition.string.begin +// ^ - punctuation.definition.string.end +// ^^ comment.block punctuation.definition.comment.end + + /* comment + 'not a string' */ +// ^^^^^^^^^^^^^^ - meta.string string.quoted.single +// ^ - punctuation.definition.string.begin +// ^ - punctuation.definition.string.end +// ^^ comment.block punctuation.definition.comment.end +} diff --git a/JSON/tests/syntax/syntax_test_json5.invalid.illegal.json5 b/JSON/tests/syntax/syntax_test_json5.invalid.illegal.json5 new file mode 100644 index 00000000000..57ff925bcba --- /dev/null +++ b/JSON/tests/syntax/syntax_test_json5.invalid.illegal.json5 @@ -0,0 +1,57 @@ +// SYNTAX TEST "Packages/JSON/JSON5.sublime-syntax" + +// <- source.json.json5 + +{ + 'expected-backslash-char-line-separator': 'x
', +// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.mapping.key meta.string string.quoted.single +// ^^^^ meta.mapping.value meta.string string.quoted.single +// ^ invalid.illegal.expected-backslash-char +// ^ - constant.character.escape.line-separator + + 'expected-backslash-char-paragraph-separator': 'x
', +// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.mapping.key meta.string string.quoted.single +// ^^^^ meta.mapping.value meta.string string.quoted.single +// ^ invalid.illegal.expected-backslash-char +// ^ - constant.character.escape.paragraph-separator + + + + +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + + + + + 'escape-character-null': '\00', +// ^^^^^^^^^^^^^^^^^^^^^^^ meta.mapping.key meta.string string.quoted.single +// ^^^^^ meta.mapping.value meta.string string.quoted.single +// ^^ constant.character.escape.null +// ^ invalid.illegal.unexpected-digit-character + + + + +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + + + + + 'unrecognized-string-escape-unicode-symbol-too-short': '\x0', +// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.mapping.key meta.string string.quoted.single +// ^^^^^ meta.mapping.value meta.string string.quoted.single +// ^^ invalid.illegal.unrecognized-string-escape +// ^^^ - constant.character.escape + + 'unrecognized-string-escape-unicode-symbol-upper-case-too-short': '\X0', +// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.mapping.key meta.string string.quoted.single +// ^^^^^ meta.mapping.value meta.string string.quoted.single +// ^^ invalid.illegal.unrecognized-string-escape +// ^^^ - constant.character.escape + + 'unrecognized-string-escape-unicode-symbol-upper-case': '\X00' +// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.mapping.key meta.string string.quoted.single +// ^^^^^^ meta.mapping.value meta.string string.quoted.single +// ^^ invalid.illegal.unrecognized-string-escape +// ^^^^ - constant.character.escape +} diff --git a/JSON/tests/syntax/syntax_test_json5.meta.mapping.json5 b/JSON/tests/syntax/syntax_test_json5.meta.mapping.json5 new file mode 100644 index 00000000000..d75c6004285 --- /dev/null +++ b/JSON/tests/syntax/syntax_test_json5.meta.mapping.json5 @@ -0,0 +1,160 @@ +// SYNTAX TEST "Packages/JSON/JSON5.sublime-syntax" + +// <- source.json.json5 + +{ +// <- meta.mapping punctuation.definition.mapping.begin + + _identifierOne: null, +// ^^^^^^^^^^^^^^ meta.mapping.key +// ^^^^^^^^^^^^^^ - meta.mapping meta.mapping.key +// ^^^^^^^^^^^^^^ meta.toc-list +// ^^^^^^^^^^^^^^ meta.string string.unquoted.plain +// ^ meta.mapping punctuation.separator.mapping.key-value +// ^^^^ meta.mapping.value +// ^^^^ - meta.mapping meta.mapping.value + + $identifierTwo: null, +// ^^^^^^^^^^^^^^ meta.mapping.key +// ^^^^^^^^^^^^^^ - meta.mapping meta.mapping.key +// ^^^^^^^^^^^^^^ meta.toc-list +// ^^^^^^^^^^^^^^ meta.string string.unquoted.plain +// ^ meta.mapping punctuation.separator.mapping.key-value +// ^^^^ meta.mapping.value +// ^^^^ - meta.mapping meta.mapping.value + + \u1234abc: null, +// ^^^^^^^^^ meta.mapping.key +// ^^^^^^^^^ - meta.mapping meta.mapping.key +// ^^^^^^^^^ meta.toc-list +// ^^^^^^^^^ meta.string string.unquoted.plain +// ^ meta.mapping punctuation.separator.mapping.key-value +// ^^^^ meta.mapping.value +// ^^^^ - meta.mapping meta.mapping.value + + 'meta-mapping-value-constant': null, +// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.mapping.key +// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - meta.mapping meta.mapping.key +// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.toc-list +// ^ meta.mapping punctuation.separator.mapping.key-value +// ^^^^ meta.mapping.value +// ^^^^ - meta.mapping meta.mapping.value + + 'meta-mapping-value-number': 0, +// ^^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.mapping.key +// ^^^^^^^^^^^^^^^^^^^^^^^^^^^ - meta.mapping meta.mapping.key +// ^^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.toc-list +// ^ meta.mapping punctuation.separator.mapping.key-value +// ^ meta.mapping.value +// ^ - meta.mapping meta.mapping.value + + 'meta-mapping-value-string': "value", +// ^^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.mapping.key +// ^^^^^^^^^^^^^^^^^^^^^^^^^^^ - meta.mapping meta.mapping.key +// ^^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.toc-list +// ^ meta.mapping punctuation.separator.mapping.key-value +// ^^^^^^^ meta.mapping.value +// ^^^^^^^ - meta.mapping meta.mapping.value + + 'meta-mapping-value-string': 'value', +// ^^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.mapping.key +// ^^^^^^^^^^^^^^^^^^^^^^^^^^^ - meta.mapping meta.mapping.key +// ^^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.toc-list +// ^ meta.mapping punctuation.separator.mapping.key-value +// ^^^^^^^ meta.mapping.value +// ^^^^^^^ - meta.mapping meta.mapping.value + + 'meta-mapping-value-sequence-empty': [], +// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.mapping.key +// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - meta.mapping meta.mapping.key +// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.toc-list +// ^ meta.mapping punctuation.separator.mapping.key-value +// ^^ meta.mapping.value +// ^^ - meta.mapping meta.mapping.value +// ^^ meta.mapping.value meta.sequence.list.empty +// ^ punctuation.definition.sequence.begin +// ^ punctuation.definition.sequence.end + + 'meta-mapping-value-sequence-empty-with-space': [ ], +// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.mapping.key +// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - meta.mapping meta.mapping.key +// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.toc-list +// ^ meta.mapping punctuation.separator.mapping.key-value +// ^^^ meta.mapping.value +// ^^^ - meta.mapping meta.mapping.value +// ^^^ meta.mapping.value meta.sequence.list.empty +// ^ punctuation.definition.sequence.begin +// ^ punctuation.definition.sequence.end + + 'meta-mapping-value-sequence': [1, 2, 3], +// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.mapping.key +// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - meta.mapping meta.mapping.key +// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.toc-list +// ^ meta.mapping punctuation.separator.mapping.key-value +// ^^^^^^^^^ meta.mapping.value +// ^^^^^^^^^ - meta.mapping meta.mapping.value +// ^ meta.mapping.value meta.sequence.list punctuation.definition.sequence.begin +// ^ meta.mapping.value meta.sequence.list punctuation.definition.sequence.end + + 'meta-mapping-value-mapping-empty': {}, +// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.mapping.key +// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - meta.mapping meta.mapping.key +// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.toc-list +// ^ meta.mapping punctuation.separator.mapping.key-value +// ^^ meta.mapping.value +// ^^ - meta.mapping meta.mapping.value +// ^^ meta.mapping.value meta.mapping.empty +// ^ punctuation.definition.mapping.begin +// ^ punctuation.definition.mapping.end + + 'meta-mapping-value-mapping-empty-with-space': { }, +// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.mapping.key +// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - meta.mapping meta.mapping.key +// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.toc-list +// ^ meta.mapping punctuation.separator.mapping.key-value +// ^^^ meta.mapping.value +// ^^^ - meta.mapping meta.mapping.value +// ^^^ meta.mapping.value meta.mapping.empty +// ^ punctuation.definition.mapping.begin +// ^ punctuation.definition.mapping.end + + 'meta-mapping-value-mapping': { "a": 1, "b": 2 }, +// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.mapping.key +// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - meta.mapping meta.mapping.key +// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.toc-list +// ^ meta.mapping punctuation.separator.mapping.key-value +// ^ meta.mapping.value meta.mapping punctuation.definition.mapping.begin +// ^ - meta.mapping meta.mapping.value +// ^^^ meta.mapping.value meta.mapping.key +// ^^^ - meta.toc-list +// ^ meta.mapping.value meta.mapping punctuation.separator.mapping.key-value +// ^ meta.mapping.value meta.mapping.value +// ^ meta.mapping.value meta.mapping punctuation.separator.mapping.pair +// ^^^ meta.mapping.value meta.mapping.key +// ^^^ - meta.toc-list +// ^ meta.mapping.value meta.mapping punctuation.separator.mapping.key-value +// ^ meta.mapping.value meta.mapping.value +// ^ meta.mapping.value meta.mapping punctuation.definition.mapping.end +// ^ - meta.mapping meta.mapping.value + + 'meta-mapping-value-mapping': { 'a': 1, 'b': 2 } +// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.mapping.key +// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - meta.mapping meta.mapping.key +// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.toc-list +// ^ meta.mapping punctuation.separator.mapping.key-value +// ^ meta.mapping.value +// ^ - meta.mapping meta.mapping.value +// ^ meta.mapping.value meta.mapping punctuation.definition.mapping.begin +// ^^^ meta.mapping.value meta.mapping.key +// ^^^ - meta.toc-list +// ^ meta.mapping.value meta.mapping punctuation.separator.mapping.key-value +// ^ meta.mapping.value meta.mapping.value +// ^ meta.mapping.value meta.mapping punctuation.separator.mapping.pair +// ^^^ meta.mapping.value meta.mapping.key +// ^^^ - meta.toc-list +// ^ meta.mapping.value meta.mapping punctuation.separator.mapping.key-value +// ^ meta.mapping.value meta.mapping.value +// ^ meta.mapping.value meta.mapping punctuation.definition.mapping.end +// ^ - meta.mapping meta.mapping.value +} +// <- meta.mapping punctuation.definition.mapping.end diff --git a/JSON/tests/syntax/syntax_test_json5.meta.sequence.json5 b/JSON/tests/syntax/syntax_test_json5.meta.sequence.json5 new file mode 100644 index 00000000000..95e9965c1e2 --- /dev/null +++ b/JSON/tests/syntax/syntax_test_json5.meta.sequence.json5 @@ -0,0 +1,58 @@ +// SYNTAX TEST "Packages/JSON/JSON5.sublime-syntax" + +// <- source.json.json5 + + +[ +// <- meta.sequence.list punctuation.definition.sequence.begin + + true, +// ^^^^ constant.language.boolean + + false, +// ^^^^^ constant.language.boolean + + null, +// ^^^^ constant.language.null + + 0, +// ^ meta.number.integer.decimal constant.numeric.value + + 0.0, +// ^^^ meta.number.float.decimal constant.numeric.value + + "value", +// ^^^^^^^ string.quoted.double + + 'value', +// ^^^^^^^ string.quoted.single + + [], +// ^^ meta.sequence.list.empty + + [ ], +// ^^^ meta.sequence.list.empty + + [1, 2, 3], +// ^^^^^^^^^ meta.sequence.list +// ^ punctuation.definition.sequence.begin +// ^ constant.numeric.value +// ^ punctuation.separator.sequence +// ^ constant.numeric.value +// ^ punctuation.separator.sequence +// ^ constant.numeric.value +// ^ punctuation.definition.sequence.end +// ^ punctuation.separator.sequence + {}, +// ^^ meta.mapping.empty + + { }, +// ^^^ meta.mapping.empty + + { "a": 1, "b": 2, "c": 3 }, +// ^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.mapping + + { 'a': 1, 'b': 2, 'c': 3 } +// ^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.mapping +] +// <- meta.sequence.list punctuation.definition.sequence.end diff --git a/JSON/tests/syntax/syntax_test_json5.number.float.decimal.json5 b/JSON/tests/syntax/syntax_test_json5.number.float.decimal.json5 new file mode 100644 index 00000000000..5fb934bd6ec --- /dev/null +++ b/JSON/tests/syntax/syntax_test_json5.number.float.decimal.json5 @@ -0,0 +1,240 @@ +// SYNTAX TEST "Packages/JSON/JSON5.sublime-syntax" + +// <- source.json.json5 + +{ +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +////[ explicitly positive ]///////////////////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + + + + + "float-explicitly-positive-zero": +0.0, +// ^^^^ meta.number.float.decimal +// ^ constant.numeric.sign +// ^^^ constant.numeric.value +// ^ punctuation.separator.decimal + + +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + + + "float-explicitly-positive-zero-with-zero-exponent": +0.0e0, +// ^^^^^^ meta.number.float.decimal +// ^ constant.numeric.sign +// ^^^^^ constant.numeric.value +// ^ punctuation.separator.decimal + + "float-explicitly-positive-zero-with-negative-zero-exponent": +0.0e-0, +// ^^^^^^^ meta.number.float.decimal +// ^ constant.numeric.sign +// ^^^^^^ constant.numeric.value +// ^ punctuation.separator.decimal + + "float-explicitly-positive-zero-no-fraction-with-zero-exponent": +0e0, +// ^^^^ meta.number.float.decimal +// ^ constant.numeric.sign +// ^^^ constant.numeric.value + + "float-explicitly-positive-zero-no-fraction-with-negative-zero-exponent": +0e-0, +// ^^^^^ meta.number.float.decimal +// ^ constant.numeric.sign +// ^^^^ constant.numeric.value + + +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + + + "float-explicitly-positive-zero-with-exponent": +0.0e9, +// ^^^^^^ meta.number.float.decimal +// ^ constant.numeric.sign +// ^^^^^ constant.numeric.value +// ^ punctuation.separator.decimal + + "float-explicitly-positive-zero-with-negative-exponent": +0.0e-9, +// ^^^^^^^ meta.number.float.decimal +// ^ constant.numeric.sign +// ^^^^^^ constant.numeric.value +// ^ punctuation.separator.decimal + + "float-explicitly-positive-zero-no-fraction-with-exponent": +0e9, +// ^^^^ meta.number.float.decimal +// ^ constant.numeric.sign +// ^^^ constant.numeric.value + + "float-explicitly-positive-zero-no-fraction-with-negative-exponent": +0e-9, +// ^^^^^ meta.number.float.decimal +// ^ constant.numeric.sign +// ^^^^ constant.numeric.value + + +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + + + "float-explicitly-positive": +9.0, +// ^^^^ meta.number.float.decimal +// ^ constant.numeric.sign +// ^^^ constant.numeric.value +// ^ punctuation.separator.decimal + + +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + + + "float-explicitly-positive-with-zero-exponent": +9.0e0, +// ^^^^^^ meta.number.float.decimal +// ^ constant.numeric.sign +// ^^^^^ constant.numeric.value +// ^ punctuation.separator.decimal + + "float-explicitly-positive-with-negative-zero-exponent": +9.0e-0, +// ^^^^^^^ meta.number.float.decimal +// ^ constant.numeric.sign +// ^^^^^^ constant.numeric.value +// ^ punctuation.separator.decimal + + "float-explicitly-positive-no-fraction-with-zero-exponent": +9e0, +// ^^^^ meta.number.float.decimal +// ^ constant.numeric.sign +// ^^^ constant.numeric.value + + "float-explicitly-positive-no-fraction-with-negative-zero-exponent": +9e-0, +// ^^^^^ meta.number.float.decimal +// ^ constant.numeric.sign +// ^^^^ constant.numeric.value + + +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + + + "float-explicitly-positive-with-exponent": +9.0e9, +// ^^^^^^ meta.number.float.decimal +// ^ constant.numeric.sign +// ^^^^^ constant.numeric.value +// ^ punctuation.separator.decimal + + "float-explicitly-positive-with-negative-exponent": +9.0e-9, +// ^^^^^^^ meta.number.float.decimal +// ^ constant.numeric.sign +// ^^^^^^ constant.numeric.value +// ^ punctuation.separator.decimal + + +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + + + "float-explicitly-positive-no-fraction-with-exponent": +9e9, +// ^^^^ meta.number.float.decimal +// ^ constant.numeric.sign +// ^^^ constant.numeric.value + + "float-explicitly-positive-no-fraction-with-negative-exponent": +9e-9, +// ^^^^^ meta.number.float.decimal +// ^ constant.numeric.sign +// ^^^^ constant.numeric.value + + + + +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +////[ ieee 754 ]//////////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + + + + + "constant-language-nan": NaN, +// ^^^ meta.number.float.decimal constant.language.nan + "constant-language-nan-pos": +NaN, +// ^^^^ meta.number.float.decimal +// ^ constant.numeric.sign +// ^^^ constant.language.nan + "constant-language-nan-neg": -NaN, +// ^^^^ meta.number.float.decimal +// ^ constant.numeric.sign +// ^^^ constant.language.nan + + "constant-language-infinity": Infinity, +// ^^^^^^^^ meta.number.float.decimal constant.language.infinity + "constant-language-infinity-pos": +Infinity, +// ^^^^^^^^^ meta.number.float.decimal +// ^ constant.numeric.sign +// ^^^^^^^^ constant.language.infinity + "constant-language-infinity-neg": -Infinity, +// ^^^^^^^^^ meta.number.float.decimal +// ^ constant.numeric.sign +// ^^^^^^^^ constant.language.infinity + + + + +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +////[ leading period ]////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + + + + + "float-leading-period-followed-by-zero": .0, +// ^^ meta.number.float.decimal +// ^^ constant.numeric.value +// ^ punctuation.separator.decimal +// ^^ - invalid.illegal.meta-number-float-decimal + + "float-leading-period-followed-by-nonzero": .9, +// ^^ meta.number.float.decimal +// ^^ constant.numeric.value +// ^ punctuation.separator.decimal +// ^^ - invalid.illegal.meta-number-float-decimal + + "negative-float-leading-period-followed-by-zero": -.0, +// ^^^ meta.number.float.decimal +// ^ constant.numeric.sign +// ^^ constant.numeric.value +// ^ punctuation.separator.decimal +// ^^^ - invalid.illegal.meta-number-float-decimal + + "negative-float-leading-period-followed-by-nonzero": -.9, +// ^^^ meta.number.float.decimal +// ^ constant.numeric.sign +// ^^ constant.numeric.value +// ^ punctuation.separator.decimal +// ^^^ - invalid.illegal.meta-number-float-decimal + + + + +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +////[ trailing period ]///////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + + + + + "float-trailing-period-lead-by-zero": 0., +// ^^ meta.number.float.decimal +// ^^ constant.numeric.value +// ^ punctuation.separator.decimal +// ^^ - invalid.illegal.meta-number-float-decimal + + "float-trailing-period-lead-by-nonzero": 9., +// ^^ meta.number.float.decimal +// ^^ constant.numeric.value +// ^ punctuation.separator.decimal +// ^^ - invalid.illegal.meta-number-float-decimal + + "negative-float-trailing-period-lead-by-zero": -0., +// ^^^ meta.number.float.decimal +// ^ constant.numeric.sign +// ^^ constant.numeric.value +// ^ punctuation.separator.decimal +// ^^^ - invalid.illegal.meta-number-float-decimal + + "negative-float-trailing-period-lead-by-nonzero": -9. +// ^^^ meta.number.float.decimal +// ^ constant.numeric.sign +// ^^ constant.numeric.value +// ^ punctuation.separator.decimal +// ^^^ - invalid.illegal.meta-number-float-decimal +} diff --git a/JSON/tests/syntax/syntax_test_json5.number.integer.hexadecimal.json5 b/JSON/tests/syntax/syntax_test_json5.number.integer.hexadecimal.json5 new file mode 100644 index 00000000000..64209c1d96c --- /dev/null +++ b/JSON/tests/syntax/syntax_test_json5.number.integer.hexadecimal.json5 @@ -0,0 +1,64 @@ +// SYNTAX TEST "Packages/JSON/JSON5.sublime-syntax" + +// <- source.json.json5 + +{ + "lower-case-hexadecimal-zero-integer": 0x0, +// ^^^ meta.number.integer.hexadecimal +// ^^ constant.numeric.base +// ^ constant.numeric.value + "lower-case-explicitly-positive-hexadecimal-zero-integer": +0x0, +// ^^^^ meta.number.integer.hexadecimal +// ^ constant.numeric.sign +// ^^ constant.numeric.base +// ^ constant.numeric.value + "lower-case-negative-hexadecimal-zero-integer": -0x0, +// ^^^^ meta.number.integer.hexadecimal +// ^ constant.numeric.sign +// ^^ constant.numeric.base +// ^ constant.numeric.value + "lower-case-hexadecimal-integer": 0x1, +// ^^^ meta.number.integer.hexadecimal +// ^^ constant.numeric.base +// ^ constant.numeric.value + "lower-case-explicitly-positive-hexadecimal-integer": +0x1, +// ^^^^ meta.number.integer.hexadecimal +// ^ constant.numeric.sign +// ^^ constant.numeric.base +// ^ constant.numeric.value + "lower-case-negative-hexadecimal-integer": -0x1, +// ^^^^ meta.number.integer.hexadecimal +// ^ constant.numeric.sign +// ^^ constant.numeric.base +// ^ constant.numeric.value + + + "upper-case-hexadecimal-zero-integer": 0X0, +// ^^^ meta.number.integer.hexadecimal +// ^^ constant.numeric.base +// ^ constant.numeric.value + "upper-case-explicitly-positive-hexadecimal-zero-integer": +0X0, +// ^^^^ meta.number.integer.hexadecimal +// ^ constant.numeric.sign +// ^^ constant.numeric.base +// ^ constant.numeric.value + "upper-case-negative-hexadecimal-zero-integer": -0X0, +// ^^^^ meta.number.integer.hexadecimal +// ^ constant.numeric.sign +// ^^ constant.numeric.base +// ^ constant.numeric.value + "upper-case-hexadecimal-integer": 0X1, +// ^^^ meta.number.integer.hexadecimal +// ^^ constant.numeric.base +// ^ constant.numeric.value + "upper-case-explicitly-positive-hexadecimal-integer": +0X1, +// ^^^^ meta.number.integer.hexadecimal +// ^ constant.numeric.sign +// ^^ constant.numeric.base +// ^ constant.numeric.value + "upper-case-negative-hexadecimal-integer": -0X1 +// ^^^^ meta.number.integer.hexadecimal +// ^ constant.numeric.sign +// ^^ constant.numeric.base +// ^ constant.numeric.value +} diff --git a/JSON/tests/syntax/syntax_test_json5.string.json5 b/JSON/tests/syntax/syntax_test_json5.string.json5 new file mode 100644 index 00000000000..3a6942dfe43 --- /dev/null +++ b/JSON/tests/syntax/syntax_test_json5.string.json5 @@ -0,0 +1,65 @@ +// SYNTAX TEST "Packages/JSON/JSON5.sublime-syntax" \ + +// <- source.json.json5 + +{ + 'key': 'value', +// ^^^^^ meta.mapping.key meta.string string.quoted.single +// ^^^^^^^ meta.mapping.value meta.string string.quoted.single + + 'line-continuation-single': 'line\ +// ^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.mapping.key meta.string string.quoted.single \ +// ^^^^^^ meta.mapping.value meta.string string.quoted.single \ +// ^ punctuation.separator.continuation.line \ + continuation', +// ^ meta.mapping.value meta.string string.quoted.single + + "line-continuation-double": "line\ +// ^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.mapping.key meta.string string.quoted.double \ +// ^^^^^^ meta.mapping.value meta.string string.quoted.double \ +// ^ punctuation.separator.continuation.line \ + continuation", +// ^ meta.mapping.value meta.string string.quoted.double + + + 'escape-character-single-quote': '\'', +// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.mapping.key meta.string string.quoted.single +// ^^^^ meta.mapping.value meta.string string.quoted.single +// ^^ constant.character.escape.single-quote + + 'escape-character-vertical-tab': '\v', +// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.mapping.key meta.string string.quoted.single +// ^^^^ meta.mapping.value meta.string string.quoted.single +// ^^ constant.character.escape.vertical-tab + + 'escape-character-null': '\0', +// ^^^^^^^^^^^^^^^^^^^^^^^ meta.mapping.key meta.string string.quoted.single +// ^^^^ meta.mapping.value meta.string string.quoted.single +// ^^ constant.character.escape.null + + 'escape-character-unicode-symbol-basic': '\x00', +// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.mapping.key meta.string string.quoted.single +// ^^^^^^ meta.mapping.value meta.string string.quoted.single +// ^^^^ constant.character.escape.unicode-symbol.basic-latin-or-latin-1-supplement + + 'escape-character-unicode-symbol-utf16-surrogate-pair': '\u0000\u0000', +// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.mapping.key meta.string string.quoted.single +// ^^^^^^^^^^^^^^ meta.mapping.value meta.string string.quoted.single +// ^^^^^^^^^^^^ constant.character.escape.unicode-symbol.utf16-surrogate-pair +// ^^^^^^ - constant.character.escape.unicode-symbol.basic-multilingual-plane +// ^^^^^^^ - constant.character.escape.unicode-symbol.basic-multilingual-plane + + 'escape-character-line-separator': '\
 +// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.mapping.key meta.string string.quoted.single \ +// ^^^ meta.mapping.value meta.string string.quoted.single \ +// ^^ constant.character.escape.line-separator \ + ', +// ^ meta.mapping.value meta.string string.quoted.single + + 'escape-character-paragraph-separator': '\
 +// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.mapping.key meta.string string.quoted.single \ +// ^^^ meta.mapping.value meta.string string.quoted.single \ +// ^^ constant.character.escape.paragraph-separator \ + ' +// ^ meta.mapping.value meta.string string.quoted.single +} diff --git a/JSON/tests/syntax/syntax_test_jsonc.comment.jsonc b/JSON/tests/syntax/syntax_test_jsonc.comment.jsonc new file mode 100644 index 00000000000..bc2965a064d --- /dev/null +++ b/JSON/tests/syntax/syntax_test_jsonc.comment.jsonc @@ -0,0 +1,425 @@ +// SYNTAX TEST "Packages/JSON/JSONC.sublime-syntax" + +// <- source.json.jsonc + +{ + // comment // comment +// ^^^^^^^^^^^^^^^^^^^^^^ comment.line.double-slash +// ^^ comment.line.double-slash punctuation.definition.comment +// ^^^^^^^^^^ - comment.line comment.line + + // comment /** comment */ +// ^^^^^^^^^^^^^^^^^^^^^^^^^^ comment.line.double-slash +// ^^ comment.line.double-slash punctuation.definition.comment +// ^^^^^^^^^^^^^^ - comment.block.documentation +// ^^^ - punctuation.definition.comment.begin +// ^^ - punctuation.definition.comment.end + + // comment /* comment */ +// ^^^^^^^^^^^^^^^^^^^^^^^^^ comment.line.double-slash +// ^^ comment.line.double-slash punctuation.definition.comment +// ^^^^^^^^^^^^^ - comment.block +// ^^ - punctuation.definition.comment.begin +// ^^ - punctuation.definition.comment.end + + // comment "not a string" +// ^^^^^^^^^^^^^^^^^^^^^^^^^^ comment.line.double-slash +// ^^ comment.line.double-slash punctuation.definition.comment +// ^^^^^^^^^^^^^^ - meta.string string.quoted.double +// ^ - punctuation.definition.string.begin +// ^ - punctuation.definition.string.end + + + + + + /** comment // comment */ +// ^^^^^^^^^^^^^^^^^^^^^^^^^ comment.block.documentation +// ^^^ comment.block.documentation punctuation.definition.comment.begin +// ^^^^^^^^^^^^^ - comment.line +// ^^ comment.block.documentation punctuation.definition.comment.end + + /** comment /** comment */ +// ^^^^^^^^^^^^^^^^^^^^^^^^^^ comment.block.documentation +// ^^^ comment.block.documentation punctuation.definition.comment.begin +// ^^^^^^^^^^^^^^ - comment.block.documentation comment.block.documentation +// ^^ comment.block.documentation punctuation.definition.comment.end +// ^^ - comment.block.documentation comment.block.documentation punctuation.definition.comment.end + + /** comment /* comment */ +// ^^^ comment.block.documentation punctuation.definition.comment.begin +// ^^^^^^^^^^^^^^^^^^^^^^^^^ comment.block.documentation +// ^^^^^^^^^^^^^ - comment.block.documentation comment.block +// ^^ comment.block.documentation punctuation.definition.comment.end +// ^^ - comment.block.documentation comment.block punctuation.definition.comment.end + + /** comment "not a string" */ +// ^^^ comment.block.documentation punctuation.definition.comment.begin +// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ comment.block.documentation +// ^^^^^^^^^^^^^^ - meta.string string.quoted.double +// ^ - punctuation.definition.string.begin +// ^ - punctuation.definition.string.end +// ^^ comment.block.documentation punctuation.definition.comment.end + + + + + + /** comment + // comment */ +// ^^^^^^^^^^^^^ - comment.line +// ^^ punctuation.definition.comment.end + + /** comment + /** comment */ +// ^^^^^^^^^^^^^^ - comment.block.documentation comment.block.documentation +// ^^ comment.block.documentation punctuation.definition.comment.end +// ^^ - comment.block.documentation comment.block.documentation punctuation.definition.comment.end + + /** comment + /* comment */ +// ^^^^^^^^^^^^^ - comment.block.documentation comment.block +// ^^ comment.block.documentation punctuation.definition.comment.end +// ^^ - comment.block.documentation comment.block punctuation.definition.comment.end + + /** comment + "not a string" */ +// ^^^^^^^^^^^^^^ - meta.string string.quoted.double +// ^ - punctuation.definition.string.begin +// ^ - punctuation.definition.string.end +// ^^ comment.block.documentation punctuation.definition.comment.end + + + + + + /** + * comment +// ^ comment.block.documentation punctuation.definition.comment + * comment + */ + + + + + + /* comment // comment */ +// ^^ comment.block punctuation.definition.comment.begin +// ^^^^^^^^^^^^^^^^^^^^^^^^ comment.block +// ^^^^^^^^^^^^^ - comment.line +// ^^ comment.block punctuation.definition.comment.end + + /* comment /** comment */ +// ^^ comment.block punctuation.definition.comment.begin +// ^^^^^^^^^^^^^^^^^^^^^^^^^ comment.block +// ^^^^^^^^^^^^^^ - comment.block.documentation +// ^^ comment.block punctuation.definition.comment.end +// ^^ - comment.block.documentation punctuation.definition.comment.end + + /* comment /* comment */ +// ^^ comment.block punctuation.definition.comment.begin +// ^^^^^^^^^^^^^^^^^^^^^^^^ comment.block +// ^^^^^^^^^^^^^ - comment.block comment.block +// ^^ comment.block punctuation.definition.comment.end +// ^^ - comment.block comment.block punctuation.definition.comment.end + + /* comment "not a string" */ +// ^^ comment.block punctuation.definition.comment.begin +// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ comment.block +// ^^^^^^^^^^^^^^ - meta.string string.quoted.double +// ^ - punctuation.definition.string.begin +// ^ - punctuation.definition.string.end +// ^^ comment.block punctuation.definition.comment.end + + + + + + /* comment + // comment */ +// ^^^^^^^^^^^^^ - comment.line +// ^^ comment.block punctuation.definition.comment.end + + /* comment + /** comment */ +// ^^^^^^^^^^^^^^ - comment.block.documentation +// ^^ comment.block punctuation.definition.comment.end +// ^^ - comment.block.documentation punctuation.definition.comment.end + + /* comment + /* comment */ +// ^^^^^^^^^^^^^ - comment.block comment.block +// ^^ comment.block punctuation.definition.comment.end +// ^^ - comment.block comment.block punctuation.definition.comment.end + + /* comment + "not a string" */ +// ^^^^^^^^^^^^^^ - meta.string string.quoted.double +// ^ - punctuation.definition.string.begin +// ^ - punctuation.definition.string.end +// ^^ comment.block punctuation.definition.comment.end + + + + + + /* + * comment +// ^ comment.block +// ^ - punctuation.definition.comment + * comment + */ + + + + + + "empty-sequence-with-line-comment": [ + // line comment +// ^^^^^^^^^^^^^^^ comment.line +// ^^ punctuation.definition.comment + ], + + "empty-sequence-with-doc-block-comment-with-no-content": [ /***/ ], +// ^^^^^ comment.block.documentation +// ^^^ punctuation.definition.comment.begin +// ^^ punctuation.definition.comment.end + + "empty-sequence-with-doc-block-comment": [ /** */ ], +// ^^^^^^ comment.block.documentation +// ^^^ punctuation.definition.comment.begin +// ^^ punctuation.definition.comment.end + + "empty-sequence-with-block-comment-with-no-content": [ /**/ ], +// ^^^^ comment.block +// ^^ punctuation.definition.comment.begin +// ^^ punctuation.definition.comment.end + + "empty-sequence-with-block-comment": [ /* */ ], +// ^^^^^ comment.block +// ^^ punctuation.definition.comment.begin +// ^^ punctuation.definition.comment.end + + + + + + "full-sequence-with-line-comment": [ + // line comment +// ^^^^^^^^^^^^^^^ comment.line +// ^^ punctuation.definition.comment + 1, + // line comment +// ^^^^^^^^^^^^^^^ comment.line +// ^^ punctuation.definition.comment + 2 + // line comment +// ^^^^^^^^^^^^^^^ comment.line +// ^^ punctuation.definition.comment + , + 3 + // line comment +// ^^^^^^^^^^^^^^^ comment.line +// ^^ punctuation.definition.comment + ], + + "full-sequence-with-doc-block-comment-with-no-content": [ /***/ 1, /***/ 2 /***/ , 3 /***/ ], +// ^^^^^ comment.block.documentation +// ^^^ punctuation.definition.comment.begin +// ^^ punctuation.definition.comment.end +// ^^^^^ comment.block.documentation +// ^^^ punctuation.definition.comment.begin +// ^^ punctuation.definition.comment.end +// ^^^^^ comment.block.documentation +// ^^^ punctuation.definition.comment.begin +// ^^ punctuation.definition.comment.end +// ^^^^^ comment.block.documentation +// ^^^ punctuation.definition.comment.begin +// ^^ punctuation.definition.comment.end + + "full-sequence-with-doc-block-comment": [ /** */ 1, /** */ 2 /** */ , 3 /** */ ], +// ^^^^^^ comment.block.documentation +// ^^^ punctuation.definition.comment.begin +// ^^ punctuation.definition.comment.end +// ^^^^^^ comment.block.documentation +// ^^^ punctuation.definition.comment.begin +// ^^ punctuation.definition.comment.end +// ^^^^^^ comment.block.documentation +// ^^^ punctuation.definition.comment.begin +// ^^ punctuation.definition.comment.end +// ^^^^^^ comment.block.documentation +// ^^^ punctuation.definition.comment.begin +// ^^ punctuation.definition.comment.end + + "full-sequence-with-block-comment-with-no-content": [ /**/ 1, /**/ 2 /**/ , 3 /**/ ], +// ^^^^ comment.block +// ^^ punctuation.definition.comment.begin +// ^^ punctuation.definition.comment.end +// ^^^^ comment.block +// ^^ punctuation.definition.comment.begin +// ^^ punctuation.definition.comment.end +// ^^^^ comment.block +// ^^ punctuation.definition.comment.begin +// ^^ punctuation.definition.comment.end +// ^^^^ comment.block +// ^^ punctuation.definition.comment.begin +// ^^ punctuation.definition.comment.end + + "full-sequence-with-block-comment": [ /* */ 1, /* */ 2 /* */ , 3 /* */ ], +// ^^^^^ comment.block +// ^^ punctuation.definition.comment.begin +// ^^ punctuation.definition.comment.end +// ^^^^^ comment.block +// ^^ punctuation.definition.comment.begin +// ^^ punctuation.definition.comment.end +// ^^^^^ comment.block +// ^^ punctuation.definition.comment.begin +// ^^ punctuation.definition.comment.end +// ^^^^^ comment.block +// ^^ punctuation.definition.comment.begin +// ^^ punctuation.definition.comment.end + + + + + + "empty-mapping-with-line-comment": { + // line comment +// ^^^^^^^^^^^^^^^ comment.line +// ^^ punctuation.definition.comment + }, + + "empty-mapping-with-doc-block-comment-with-no-content": { /***/ }, +// ^^^^^ comment.block.documentation +// ^^^ punctuation.definition.comment.begin +// ^^ punctuation.definition.comment.end + + "empty-mapping-with-doc-block-comment": { /** */ }, +// ^^^^^^ comment.block.documentation +// ^^^ punctuation.definition.comment.begin +// ^^ punctuation.definition.comment.end + + "empty-mapping-with-block-comment-with-no-content": { /**/ }, +// ^^^^ comment.block +// ^^ punctuation.definition.comment.begin +// ^^ punctuation.definition.comment.end + + "empty-mapping-with-block-comment": { /* */ }, +// ^^^^^ comment.block +// ^^ punctuation.definition.comment.begin +// ^^ punctuation.definition.comment.end + + + + + + "full-mapping-with-line-comment": { + // line comment +// ^^^^^^^^^^^^^^^ comment.line +// ^^ punctuation.definition.comment + "a": 1, + // line comment +// ^^^^^^^^^^^^^^^ comment.line +// ^^ punctuation.definition.comment + "b" + // line comment +// ^^^^^^^^^^^^^^^ comment.line +// ^^ punctuation.definition.comment + : + // line comment +// ^^^^^^^^^^^^^^^ comment.line +// ^^ punctuation.definition.comment + 2 + // line comment +// ^^^^^^^^^^^^^^^ comment.line +// ^^ punctuation.definition.comment + , + // line comment +// ^^^^^^^^^^^^^^^ comment.line +// ^^ punctuation.definition.comment + "c": 3 + // line comment +// ^^^^^^^^^^^^^^^ comment.line +// ^^ punctuation.definition.comment + }, + + "full-mapping-with-doc-block-comment-with-no-content": { /***/ "a": 1, /***/ "b" /***/ : /***/ 2 /***/ , "c": 3 /***/ }, +// ^^^^^ comment.block.documentation +// ^^^ punctuation.definition.comment.begin +// ^^ punctuation.definition.comment.end +// ^^^^^ comment.block.documentation +// ^^^ punctuation.definition.comment.begin +// ^^ punctuation.definition.comment.end +// ^^^^^ comment.block.documentation +// ^^^ punctuation.definition.comment.begin +// ^^ punctuation.definition.comment.end +// ^^^^^ comment.block.documentation +// ^^^ punctuation.definition.comment.begin +// ^^ punctuation.definition.comment.end +// ^^^^^ comment.block.documentation +// ^^^ punctuation.definition.comment.begin +// ^^ punctuation.definition.comment.end +// ^^^^^ comment.block.documentation +// ^^^ punctuation.definition.comment.begin +// ^^ punctuation.definition.comment.end +// ^^^^^ comment.block.documentation +// ^^^ punctuation.definition.comment.begin +// ^^ punctuation.definition.comment.end + + "full-mapping-with-doc-block-comment": { /** */ "a": 1, /** */ "b" /** */ : /** */ 2 /** */ , "c": 3 /** */ }, +// ^^^^^^ comment.block.documentation +// ^^^ punctuation.definition.comment.begin +// ^^ punctuation.definition.comment.end +// ^^^^^^ comment.block.documentation +// ^^^ punctuation.definition.comment.begin +// ^^ punctuation.definition.comment.end +// ^^^^^^ comment.block.documentation +// ^^^ punctuation.definition.comment.begin +// ^^ punctuation.definition.comment.end +// ^^^^^^ comment.block.documentation +// ^^^ punctuation.definition.comment.begin +// ^^ punctuation.definition.comment.end +// ^^^^^^ comment.block.documentation +// ^^^ punctuation.definition.comment.begin +// ^^ punctuation.definition.comment.end +// ^^^^^^ comment.block.documentation +// ^^^ punctuation.definition.comment.begin +// ^^ punctuation.definition.comment.end + + "full-mapping-with-block-comment-with-no-content": { /**/ "a": 1, /**/ "b" /**/ : /**/ 2 /**/ , "c": 3 /**/ }, +// ^^^^ comment.block +// ^^ punctuation.definition.comment.begin +// ^^ punctuation.definition.comment.end +// ^^^^ comment.block +// ^^ punctuation.definition.comment.begin +// ^^ punctuation.definition.comment.end +// ^^^^ comment.block +// ^^ punctuation.definition.comment.begin +// ^^ punctuation.definition.comment.end +// ^^^^ comment.block +// ^^ punctuation.definition.comment.begin +// ^^ punctuation.definition.comment.end +// ^^^^ comment.block +// ^^ punctuation.definition.comment.begin +// ^^ punctuation.definition.comment.end +// ^^^^ comment.block +// ^^ punctuation.definition.comment.begin +// ^^ punctuation.definition.comment.end + + "full-mapping-with-block-comment": { /* */ "a": 1, /* */ "b" /* */ : 2 /* */ , "c": 3 /* */ } +// ^^^^^ comment.block +// ^^ punctuation.definition.comment.begin +// ^^ punctuation.definition.comment.end +// ^^^^^ comment.block +// ^^ punctuation.definition.comment.begin +// ^^ punctuation.definition.comment.end +// ^^^^^ comment.block +// ^^ punctuation.definition.comment.begin +// ^^ punctuation.definition.comment.end +// ^^^^^ comment.block +// ^^ punctuation.definition.comment.begin +// ^^ punctuation.definition.comment.end +// ^^^^^ comment.block +// ^^ punctuation.definition.comment.begin +// ^^ punctuation.definition.comment.end +} diff --git a/JSON/tests/syntax/syntax_test_jsonc.constant.jsonc b/JSON/tests/syntax/syntax_test_jsonc.constant.jsonc new file mode 100644 index 00000000000..b78b2a67b3f --- /dev/null +++ b/JSON/tests/syntax/syntax_test_jsonc.constant.jsonc @@ -0,0 +1,14 @@ +// SYNTAX TEST "Packages/JSON/JSONC.sublime-syntax" + +// <- source.json.jsonc + +{ + "bool-false": false, +// ^^^^^ constant.language.boolean + + "bool-true": true, +// ^^^^ constant.language.boolean + + "null": null +// ^^^^ constant.language.null +} diff --git a/JSON/tests/syntax/syntax_test_jsonc.invalid.illegal.expected_lower_case_constant.jsonc b/JSON/tests/syntax/syntax_test_jsonc.invalid.illegal.expected_lower_case_constant.jsonc new file mode 100644 index 00000000000..e0300f61762 --- /dev/null +++ b/JSON/tests/syntax/syntax_test_jsonc.invalid.illegal.expected_lower_case_constant.jsonc @@ -0,0 +1,18 @@ +// SYNTAX TEST "Packages/JSON/JSONC.sublime-syntax" + +// <- source.json.jsonc + +[ + Null, +// ^^^^ invalid.illegal.expected-lower-case-null + NULL, +// ^^^^ invalid.illegal.expected-lower-case-null + False, +// ^^^^^ invalid.illegal.expected-lower-case-boolean + FALSE, +// ^^^^^ invalid.illegal.expected-lower-case-boolean + True, +// ^^^^ invalid.illegal.expected-lower-case-boolean + TRUE +// ^^^^ invalid.illegal.expected-lower-case-boolean +] diff --git a/JSON/tests/syntax/syntax_test_jsonc.invalid.illegal.jsonc b/JSON/tests/syntax/syntax_test_jsonc.invalid.illegal.jsonc new file mode 100644 index 00000000000..9517b4f6e4a --- /dev/null +++ b/JSON/tests/syntax/syntax_test_jsonc.invalid.illegal.jsonc @@ -0,0 +1,26 @@ +// SYNTAX TEST "Packages/JSON/JSONC.sublime-syntax" + +// <- source.json.jsonc + +{ + "c": "c" + , , +// ^ meta.mapping punctuation.separator.mapping.pair +// ^ meta.mapping invalid.illegal.expected-mapping-key + + "d": { "d": }, +// ^ meta.mapping.value meta.mapping invalid.illegal.expected-mapping-value +// ^ meta.mapping.value meta.mapping punctuation.definition.mapping.end + + "e": { "e": + }, +// ^ invalid.illegal.expected-mapping-value +// ^ punctuation.definition.mapping.end + + [], +// ^^^ invalid.illegal.expected-mapping-key + + "f": "f" + "g": "g" +// ^ invalid.illegal.expected-mapping-separator +} diff --git a/JSON/tests/syntax/syntax_test_jsonc.invalid.illegal.numeric_sign.jsonc b/JSON/tests/syntax/syntax_test_jsonc.invalid.illegal.numeric_sign.jsonc new file mode 100644 index 00000000000..c9cb8b64402 --- /dev/null +++ b/JSON/tests/syntax/syntax_test_jsonc.invalid.illegal.numeric_sign.jsonc @@ -0,0 +1,172 @@ +// SYNTAX TEST "Packages/JSON/JSONC.sublime-syntax" + +// <- source.json.jsonc + +{ + + "explicitly-positive-zero": +0, +// ^^ meta.mapping.value meta.number.integer.decimal +// ^ invalid.illegal.numeric-sign +// ^ constant.numeric.value + + "explicitly-positive-integer": +9, +// ^^ meta.mapping.value meta.number.integer.decimal +// ^ invalid.illegal.numeric-sign +// ^ constant.numeric.value + + + + +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + + + + + "float-explicitly-positive-zero": +0.0, +// ^^^^ meta.number.float.decimal +// ^ invalid.illegal.numeric-sign +// ^^^ constant.numeric.value +// ^ punctuation.separator.decimal + + + + +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + + + + + "float-explicitly-positive-zero-with-zero-exponent": +0.0e0, +// ^^^^^^ meta.number.float.decimal +// ^ invalid.illegal.numeric-sign +// ^^^^^ constant.numeric.value +// ^ punctuation.separator.decimal + + "float-explicitly-positive-zero-with-negative-zero-exponent": +0.0e-0, +// ^^^^^^^ meta.number.float.decimal +// ^ invalid.illegal.numeric-sign +// ^^^^^^ constant.numeric.value +// ^ punctuation.separator.decimal + + "float-explicitly-positive-zero-no-fraction-with-zero-exponent": +0e0, +// ^^^^ meta.number.float.decimal +// ^ invalid.illegal.numeric-sign +// ^^^ constant.numeric.value + + "float-explicitly-positive-zero-no-fraction-with-negative-zero-exponent": +0e-0, +// ^^^^^ meta.number.float.decimal +// ^ invalid.illegal.numeric-sign +// ^^^^ constant.numeric.value + + + + +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + + + + + "float-explicitly-positive-zero-with-exponent": +0.0e9, +// ^^^^^^ meta.number.float.decimal +// ^ invalid.illegal.numeric-sign +// ^^^^^ constant.numeric.value +// ^ punctuation.separator.decimal + + "float-explicitly-positive-zero-with-negative-exponent": +0.0e-9, +// ^^^^^^^ meta.number.float.decimal +// ^ invalid.illegal.numeric-sign +// ^^^^^^ constant.numeric.value +// ^ punctuation.separator.decimal + + "float-explicitly-positive-zero-no-fraction-with-exponent": +0e9, +// ^^^^ meta.number.float.decimal +// ^ invalid.illegal.numeric-sign +// ^^^ constant.numeric.value + + "float-explicitly-positive-zero-no-fraction-with-negative-exponent": +0e-9, +// ^^^^^ meta.number.float.decimal +// ^ invalid.illegal.numeric-sign +// ^^^^ constant.numeric.value + + + + +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + + + + + "float-explicitly-positive": +9.0, +// ^^^^ meta.number.float.decimal +// ^ invalid.illegal.numeric-sign +// ^^^ constant.numeric.value +// ^ punctuation.separator.decimal + + + + +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + + + + + "float-explicitly-positive-with-zero-exponent": +9.0e0, +// ^^^^^^ meta.number.float.decimal +// ^ invalid.illegal.numeric-sign +// ^^^^^ constant.numeric.value +// ^ punctuation.separator.decimal + + "float-explicitly-positive-with-negative-zero-exponent": +9.0e-0, +// ^^^^^^^ meta.number.float.decimal +// ^ invalid.illegal.numeric-sign +// ^^^^^^ constant.numeric.value +// ^ punctuation.separator.decimal + + "float-explicitly-positive-no-fraction-with-zero-exponent": +9e0, +// ^^^^ meta.number.float.decimal +// ^ invalid.illegal.numeric-sign +// ^^^ constant.numeric.value + + "float-explicitly-positive-no-fraction-with-negative-zero-exponent": +9e-0, +// ^^^^^ meta.number.float.decimal +// ^ invalid.illegal.numeric-sign +// ^^^^ constant.numeric.value + + + + +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + + + + + "float-explicitly-positive-with-exponent": +9.0e9, +// ^^^^^^ meta.number.float.decimal +// ^ invalid.illegal.numeric-sign +// ^^^^^ constant.numeric.value +// ^ punctuation.separator.decimal + + "float-explicitly-positive-with-negative-exponent": +9.0e-9, +// ^^^^^^^ meta.number.float.decimal +// ^ invalid.illegal.numeric-sign +// ^^^^^^ constant.numeric.value +// ^ punctuation.separator.decimal + + + + +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + + + + + "float-explicitly-positive-no-fraction-with-exponent": +9e9, +// ^^^^ meta.number.float.decimal +// ^ invalid.illegal.numeric-sign +// ^^^ constant.numeric.value + + "float-explicitly-positive-no-fraction-with-negative-exponent": +9e-9 +// ^^^^^ meta.number.float.decimal +// ^ invalid.illegal.numeric-sign +// ^^^^ constant.numeric.value +} diff --git a/JSON/tests/syntax/syntax_test_jsonc.invalid.illegal.unclosed_string.jsonc b/JSON/tests/syntax/syntax_test_jsonc.invalid.illegal.unclosed_string.jsonc new file mode 100644 index 00000000000..1462439bb67 --- /dev/null +++ b/JSON/tests/syntax/syntax_test_jsonc.invalid.illegal.unclosed_string.jsonc @@ -0,0 +1,15 @@ +// SYNTAX TEST "Packages/JSON/JSONC.sublime-syntax" + +// <- source.json.jsonc + +{ + "unterminated string +// ^^^^^^^^^^^^^^^^^^^^ meta.mapping.key meta.toc-list meta.string string.quoted.double +// ^ invalid.illegal.unclosed-string + + /**/: "test" +// ^ - string.quoted.double +// ^^^^ meta.mapping comment.block +// ^ punctuation.separator.mapping.key-value +// ^^^^^^ meta.mapping.value meta.string string.quoted.double +} diff --git a/JSON/tests/syntax/syntax_test_jsonc.invalid.illegal.unrecognized_string_escape.jsonc b/JSON/tests/syntax/syntax_test_jsonc.invalid.illegal.unrecognized_string_escape.jsonc new file mode 100644 index 00000000000..8d2d68d1718 --- /dev/null +++ b/JSON/tests/syntax/syntax_test_jsonc.invalid.illegal.unrecognized_string_escape.jsonc @@ -0,0 +1,50 @@ +// SYNTAX TEST "Packages/JSON/JSONC.sublime-syntax" + +// <- source.json.jsonc + +{ + "unrecognized-string-escape": "\.", +// ^^^^ meta.mapping.value meta.string string.quoted.double +// ^^ invalid.illegal.unrecognized-string-escape +// ^^ - constant.character.escape + + "unrecognized-string-escape-upper-case-b": "\B", +// ^^^^ meta.mapping.value meta.string string.quoted.double +// ^^ invalid.illegal.unrecognized-string-escape +// ^^ - constant.character.escape + + "unrecognized-string-escape-upper-case-f": "\F", +// ^^^^ meta.mapping.value meta.string string.quoted.double +// ^^ invalid.illegal.unrecognized-string-escape +// ^^ - constant.character.escape + + "unrecognized-string-escape-upper-case-n": "\N", +// ^^^^ meta.mapping.value meta.string string.quoted.double +// ^^ invalid.illegal.unrecognized-string-escape +// ^^ - constant.character.escape + + "unrecognized-string-escape-upper-case-r": "\R", +// ^^^^ meta.mapping.value meta.string string.quoted.double +// ^^ invalid.illegal.unrecognized-string-escape +// ^^ - constant.character.escape + + "unrecognized-string-escape-upper-case-t": "\T", +// ^^^^ meta.mapping.value meta.string string.quoted.double +// ^^ invalid.illegal.unrecognized-string-escape +// ^^ - constant.character.escape + + "unrecognized-string-escape-unicode-symbol-too-short": "\u123", +// ^^^^^^^ meta.mapping.value meta.string string.quoted.double +// ^^^^^ - constant.character.escape +// ^^ invalid.illegal.unrecognized-string-escape + + "unrecognized-string-escape-unicode-symbol-upper-case-and-too-short": "\U123", +// ^^^^^^^ meta.mapping.value meta.string string.quoted.double +// ^^^^^ - constant.character.escape +// ^^ invalid.illegal.unrecognized-string-escape + + "unrecognized-string-escape-unicode-symbol-upper-case": "\U1234" +// ^^^^^^^^ meta.mapping.value meta.string string.quoted.double +// ^^^^^^ - constant.character.escape +// ^^ invalid.illegal.unrecognized-string-escape +} diff --git a/JSON/tests/syntax/syntax_test_jsonc.meta.mapping.jsonc b/JSON/tests/syntax/syntax_test_jsonc.meta.mapping.jsonc new file mode 100644 index 00000000000..81bec88d24f --- /dev/null +++ b/JSON/tests/syntax/syntax_test_jsonc.meta.mapping.jsonc @@ -0,0 +1,109 @@ +// SYNTAX TEST "Packages/JSON/JSONC.sublime-syntax" + +// <- source.json.jsonc + +{ +// <- meta.mapping punctuation.definition.mapping.begin + + "meta-mapping-value-constant": null, +// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.mapping.key meta.string string.quoted.double - meta.mapping.json meta.mapping.key +// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.toc-list +// ^ meta.mapping punctuation.separator.mapping.key-value +// ^^^^ meta.mapping.value - meta.mapping.json meta.mapping.value +// ^ punctuation.separator.mapping.pair + + "meta-mapping-value-number": 0, +// ^^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.mapping.key meta.string string.quoted.double - meta.mapping.json meta.mapping.key +// ^^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.toc-list +// ^ meta.mapping punctuation.separator.mapping.key-value +// ^ meta.mapping.value - meta.mapping.json meta.mapping.value +// ^ punctuation.separator.mapping.pair + + "meta-mapping-value-string": "value", +// ^^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.mapping.key meta.string string.quoted.double - meta.mapping.json meta.mapping.key +// ^^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.toc-list +// ^ meta.mapping punctuation.separator.mapping.key-value +// ^^^^^^^ meta.mapping.value - meta.mapping.json meta.mapping.value +// ^ punctuation.separator.mapping.pair + + "meta-mapping-value-sequence-empty": [], +// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.mapping.key +// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - meta.mapping meta.mapping.key +// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.toc-list +// ^ meta.mapping punctuation.separator.mapping.key-value +// ^^ meta.mapping.value +// ^^ - meta.mapping meta.mapping.value +// ^^ meta.mapping.value meta.sequence.list.empty +// ^ punctuation.definition.sequence.begin +// ^ punctuation.definition.sequence.end + + "meta-mapping-value-sequence-empty-with-space": [ ], +// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.mapping.key +// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - meta.mapping meta.mapping.key +// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.toc-list +// ^ meta.mapping punctuation.separator.mapping.key-value +// ^^^ meta.mapping.value +// ^^^ - meta.mapping meta.mapping.value +// ^^^ meta.mapping.value meta.sequence.list.empty +// ^ punctuation.definition.sequence.begin +// ^ punctuation.definition.sequence.end + + "meta-mapping-value-sequence": [1, 2 +// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.mapping.key meta.string string.quoted.double - meta.mapping.json meta.mapping.key +// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.toc-list +// ^ meta.mapping punctuation.separator.mapping.key-value +// ^^^^^ meta.mapping.value - meta.mapping.json meta.mapping.value +// ^ meta.mapping.value meta.sequence.list punctuation.definition.sequence.begin +// ^ meta.mapping.value meta.sequence.list punctuation.separator.sequence + , +// ^ - invalid +// ^ meta.mapping.value meta.sequence.list punctuation.separator.sequence + 3 + ], +// ^ meta.mapping.value meta.sequence.list punctuation.definition.sequence.end +// ^ punctuation.separator.mapping.pair + + "meta-mapping-value-mapping-empty": {}, +// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.mapping.key +// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - meta.mapping meta.mapping.key +// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.toc-list +// ^ meta.mapping punctuation.separator.mapping.key-value +// ^^ meta.mapping.value +// ^^ - meta.mapping meta.mapping.value +// ^^ meta.mapping.value meta.mapping.empty +// ^ punctuation.definition.mapping.begin +// ^ punctuation.definition.mapping.end + + "meta-mapping-value-mapping-empty-with-space": { }, +// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.mapping.key +// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - meta.mapping meta.mapping.key +// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.toc-list +// ^ meta.mapping punctuation.separator.mapping.key-value +// ^^^ meta.mapping.value +// ^^^ - meta.mapping meta.mapping.value +// ^^^ meta.mapping.value meta.mapping.empty +// ^ punctuation.definition.mapping.begin +// ^ punctuation.definition.mapping.end + + "meta-mapping-value-mapping": { "a": 1 +// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.mapping.key meta.string string.quoted.double - meta.mapping.json meta.mapping.key +// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.toc-list +// ^ meta.mapping punctuation.separator.mapping.key-value +// ^^^^^^^^^^^^^^^^^^ meta.mapping.value - meta.mapping.json meta.mapping.value +// ^ meta.mapping.value meta.mapping punctuation.definition.mapping.begin +// ^^^ meta.mapping.value meta.mapping.key +// ^^^ - meta.toc-list +// ^ meta.mapping.value meta.mapping punctuation.separator.mapping.key-value +// ^ meta.mapping.value meta.mapping.value + , +// ^ - invalid +// ^ meta.mapping.value meta.mapping punctuation.separator.mapping.pair + "b": 2 +// ^^^ meta.mapping.value meta.mapping.key +// ^^^ - meta.toc-list +// ^ meta.mapping.value meta.mapping punctuation.separator.mapping.key-value +// ^ meta.mapping.value meta.mapping.value + } +// ^ meta.mapping.value meta.mapping punctuation.definition.mapping.end +} +// <- meta.mapping punctuation.definition.mapping.end diff --git a/JSON/tests/syntax/syntax_test_jsonc.meta.sequence.jsonc b/JSON/tests/syntax/syntax_test_jsonc.meta.sequence.jsonc new file mode 100644 index 00000000000..cd677830f12 --- /dev/null +++ b/JSON/tests/syntax/syntax_test_jsonc.meta.sequence.jsonc @@ -0,0 +1,67 @@ +// SYNTAX TEST "Packages/JSON/JSONC.sublime-syntax" + +// <- source.json.jsonc + + +[ +// <- meta.sequence.list punctuation.definition.sequence.begin + + true, +// ^^^^ constant.language.boolean + + false, +// ^^^^^ constant.language.boolean + + null, +// ^^^^ constant.language.null + + 0, +// ^ meta.number.integer.decimal constant.numeric.value + + 0.0, +// ^^^ meta.number.float.decimal constant.numeric.value + + "value", +// ^^^^^^^ string.quoted.double + + [], +// ^^ meta.sequence.list.empty + + [ ], +// ^^^ meta.sequence.list.empty + + [1, 2 +// ^ meta.sequence.list punctuation.definition.sequence.begin +// ^ meta.sequence.list + , +// ^ - invalid +// ^ meta.sequence.list punctuation.separator.sequence + "three", +// ^^^^^^^ string.quoted.double - meta.mapping.key +// ^ punctuation.separator.sequence +// ^ - invalid.illegal.unexpected-separator + ], +// ^ meta.sequence.list punctuation.definition.sequence.end +// ^ meta.sequence.list punctuation.separator.sequence + + {}, +// ^^ meta.mapping.empty + + { }, +// ^^^ meta.mapping.empty + + { "a": 1, "b": 2 +// ^^^^^^^^^^^^^^^^ meta.mapping +// ^ meta.mapping punctuation.separator.mapping.key-value +// ^ meta.mapping punctuation.separator.mapping.pair + , +// ^ - invalid +// ^ meta.mapping punctuation.separator.mapping.pair + "c": 3 + } + + , +// ^ punctuation.separator.sequence +// ^ - invalid.illegal.unexpected-separator +] +// <- meta.sequence.list punctuation.definition.sequence.end diff --git a/JSON/tests/syntax/syntax_test_jsonc.number.jsonc b/JSON/tests/syntax/syntax_test_jsonc.number.jsonc new file mode 100644 index 00000000000..71a96cd0ff8 --- /dev/null +++ b/JSON/tests/syntax/syntax_test_jsonc.number.jsonc @@ -0,0 +1,251 @@ +// SYNTAX TEST "Packages/JSON/JSONC.sublime-syntax" + +// <- source.json.jsonc + +{ + "zero": 0, +// ^ meta.number.integer.decimal +// ^ constant.numeric.value + + "negative-zero": -0, +// ^^ meta.number.integer.decimal +// ^ constant.numeric.sign +// ^ constant.numeric.value + + + + +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + + + + + "integer": 9, +// ^ meta.number.integer.decimal +// ^ constant.numeric.value + + "negative-integer": -9, +// ^^ meta.number.integer.decimal +// ^ constant.numeric.sign +// ^ constant.numeric.value + + + + +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + + + + + "float-zero": 0.0, +// ^^^ meta.number.float.decimal constant.numeric.value +// ^ punctuation.separator.decimal + + "float-negative-zero": -0.0, +// ^^^^ meta.number.float.decimal +// ^ constant.numeric.sign +// ^^^ constant.numeric.value +// ^ punctuation.separator.decimal + + + + +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + + + + + "float-zero-with-zero-exponent": 0.0e0, +// ^^^^^ meta.number.float.decimal constant.numeric.value +// ^ punctuation.separator.decimal + + "float-zero-with-negative-zero-exponent": 0.0e-0, +// ^^^^^^ meta.number.float.decimal constant.numeric.value +// ^ punctuation.separator.decimal + + "float-negative-zero-with-zero-exponent": -0.0e0, +// ^^^^^^ meta.number.float.decimal +// ^ constant.numeric.sign +// ^^^^^ constant.numeric.value +// ^ punctuation.separator.decimal + + "float-negative-zero-with-negative-zero-exponent": -0.0e-0, +// ^^^^^^^ meta.number.float.decimal +// ^ constant.numeric.sign +// ^^^^^^ constant.numeric.value +// ^ punctuation.separator.decimal + + "float-zero-no-fraction-with-zero-exponent": 0e0, +// ^^^ meta.number.float.decimal constant.numeric.value + + "float-negative-zero-no-fraction-with-zero-exponent": -0e0, +// ^^^^ meta.number.float.decimal +// ^ constant.numeric.sign +// ^^^ constant.numeric.value + + "float-zero-no-fraction-with-negative-zero-exponent": 0e-0, +// ^^^^ meta.number.float.decimal constant.numeric.value + + "float-negative-zero-no-fraction-with-negative-zero-exponent": -0e-0, +// ^^^^^ meta.number.float.decimal +// ^ constant.numeric.sign +// ^^^^ constant.numeric.value + + + + +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + + + + + "float-zero-with-exponent": 0.0e9, +// ^^^^^ meta.number.float.decimal constant.numeric.value +// ^ punctuation.separator.decimal + + "float-zero-with-negative-exponent": 0.0e-9, +// ^^^^^^ meta.number.float.decimal constant.numeric.value +// ^ punctuation.separator.decimal + + "float-negative-zero-with-exponent": -0.0e9, +// ^^^^^^ meta.number.float.decimal +// ^ constant.numeric.sign +// ^^^^^ constant.numeric.value +// ^ punctuation.separator.decimal + + "float-negative-zero-with-negative-exponent": -0.0e-9, +// ^^^^^^^ meta.number.float.decimal +// ^ constant.numeric.sign +// ^^^^^^ constant.numeric.value +// ^ punctuation.separator.decimal + + "float-zero-no-fraction-with-exponent": 0e9, +// ^^^ meta.number.float.decimal constant.numeric.value + + "float-negative-zero-no-fraction-with-exponent": -0e9, +// ^^^^ meta.number.float.decimal +// ^ constant.numeric.sign +// ^^^ constant.numeric.value + + "float-zero-no-fraction-with-negative-exponent": 0e-9, +// ^^^^ meta.number.float.decimal constant.numeric.value + + "float-negative-zero-no-fraction-with-negative-exponent": -0e-9, +// ^^^^^ meta.number.float.decimal +// ^ constant.numeric.sign +// ^^^^ constant.numeric.value + + + + +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + + + + + "float": 9.0, +// ^^^ meta.number.float.decimal constant.numeric.value +// ^ punctuation.separator.decimal + + "float-negative": -9.0, +// ^^^^ meta.number.float.decimal +// ^ constant.numeric.sign +// ^^^ constant.numeric.value +// ^ punctuation.separator.decimal + + + + +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + + + + + "float-with-zero-exponent": 9.0e0, +// ^^^^^ meta.number.float.decimal constant.numeric.value +// ^ punctuation.separator.decimal + + "float-with-negative-zero-exponent": 9.0e-0, +// ^^^^^^ meta.number.float.decimal constant.numeric.value +// ^ punctuation.separator.decimal + + "float-negative-with-zero-exponent": -9.0e0, +// ^^^^^^ meta.number.float.decimal +// ^ constant.numeric.sign +// ^^^^^ constant.numeric.value +// ^ punctuation.separator.decimal + + "float-negative-with-negative-zero-exponent": -9.0e-0, +// ^^^^^^^ meta.number.float.decimal +// ^ constant.numeric.sign +// ^^^^^^ constant.numeric.value +// ^ punctuation.separator.decimal + + "float-no-fraction-with-zero-exponent": 9e0, +// ^^^ meta.number.float.decimal constant.numeric.value + + "float-negative-no-fraction-with-zero-exponent": -9e0, +// ^^^^ meta.number.float.decimal +// ^ constant.numeric.sign +// ^^^ constant.numeric.value + + "float-no-fraction-with-negative-zero-exponent": 9e-0, +// ^^^^ meta.number.float.decimal constant.numeric.value + + "float-negative-no-fraction-with-negative-zero-exponent": -9e-0, +// ^^^^^ meta.number.float.decimal +// ^ constant.numeric.sign +// ^^^^ constant.numeric.value + + + + +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + + + + + "float-with-exponent": 9.0e9, +// ^^^^^ meta.number.float.decimal constant.numeric.value +// ^ punctuation.separator.decimal + + "float-with-negative-exponent": 9.0e-9, +// ^^^^^^ meta.number.float.decimal constant.numeric.value +// ^ punctuation.separator.decimal + + "float-negative-with-exponent": -9.0e9, +// ^^^^^^ meta.number.float.decimal +// ^ constant.numeric.sign +// ^^^^^ constant.numeric.value +// ^ punctuation.separator.decimal + + "float-negative-with-negative-exponent": -9.0e-9, +// ^^^^^^^ meta.number.float.decimal +// ^ constant.numeric.sign +// ^^^^^^ constant.numeric.value +// ^ punctuation.separator.decimal + + + + +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + + + + + "float-no-fraction-with-exponent": 9e9, +// ^^^ meta.number.float.decimal constant.numeric.value + + "float-negative-no-fraction-with-exponent": -9e9, +// ^^^^ meta.number.float.decimal +// ^ constant.numeric.sign +// ^^^ constant.numeric.value + + "float-no-fraction-with-negative-exponent": 9e-9, +// ^^^^ meta.number.float.decimal constant.numeric.value + + "float-negative-no-fraction-with-negative-exponent": -9e-9 +// ^^^^^ meta.number.float.decimal +// ^ constant.numeric.sign +// ^^^^ constant.numeric.value +} diff --git a/JSON/tests/syntax/syntax_test_jsonc.string.jsonc b/JSON/tests/syntax/syntax_test_jsonc.string.jsonc new file mode 100644 index 00000000000..af86a377624 --- /dev/null +++ b/JSON/tests/syntax/syntax_test_jsonc.string.jsonc @@ -0,0 +1,80 @@ +// SYNTAX TEST "Packages/JSON/JSONC.sublime-syntax" + +// <- source.json.jsonc + +{ + "a": "\"", +// ^^^ meta.mapping.key meta.string string.quoted.double - meta.mapping.value +// ^^^^ meta.mapping.value meta.string string.quoted.double - meta.mapping.key +// ^^ constant.character.escape.double-quote + + "b": "\\", +// ^^^ meta.mapping.key meta.string string.quoted.double - meta.mapping.value +// ^^^^ meta.mapping.value meta.string string.quoted.double - meta.mapping.key +// ^^ constant.character.escape.back-slash + + "c": "\/", +// ^^^ meta.mapping.key meta.string string.quoted.double - meta.mapping.value +// ^^^^ meta.mapping.value meta.string string.quoted.double - meta.mapping.key +// ^^ constant.character.escape.forward-slash + + "d": "\b", +// ^^^ meta.mapping.key meta.string string.quoted.double - meta.mapping.value +// ^^^^ meta.mapping.value meta.string string.quoted.double - meta.mapping.key +// ^^ constant.character.escape.backspace + + "e": "\f", +// ^^^ meta.mapping.key meta.string string.quoted.double - meta.mapping.value +// ^^^^ meta.mapping.value meta.string string.quoted.double - meta.mapping.key +// ^^ constant.character.escape.form-feed + + "f": "\n", +// ^^^ meta.mapping.key meta.string string.quoted.double - meta.mapping.value +// ^^^^ meta.mapping.value meta.string string.quoted.double - meta.mapping.key +// ^^ constant.character.escape.newline + + "g": "\r", +// ^^^ meta.mapping.key meta.string string.quoted.double - meta.mapping.value +// ^^^^ meta.mapping.value meta.string string.quoted.double - meta.mapping.key +// ^^ constant.character.escape.carriage-return + + "h": "\t", +// ^^^ meta.mapping.key meta.string string.quoted.double - meta.mapping.value +// ^^^^ meta.mapping.value meta.string string.quoted.double - meta.mapping.key +// ^^ constant.character.escape.horizontal-tab + + "i": "\u1234", +// ^^^ meta.mapping.key meta.string string.quoted.double - meta.mapping.value +// ^^^^^^^^ meta.mapping.value meta.string string.quoted.double - meta.mapping.key +// ^^^^^^ constant.character.escape.unicode-symbol.basic-multilingual-plane + + "j": "\u12345", +// ^^^ meta.mapping.key meta.string string.quoted.double - meta.mapping.value +// ^^^^^^^^^ meta.mapping.value meta.string string.quoted.double - meta.mapping.key +// ^^^^^^ constant.character.escape.unicode-symbol.basic-multilingual-plane +// ^ - constant.character.escape + + "ke//y": "value", +// ^^^^^^^ meta.mapping.key meta.string string.quoted.double - comment +// ^^^^^^^ meta.mapping.value meta.string string.quoted.double + + "ke// y": "value", +// ^^^^^^^^ meta.mapping.key meta.string string.quoted.double - comment +// ^^^^^^^ meta.mapping.value meta.string string.quoted.double + + "ke/***/y": "value", +// ^^^^^^^^^^ meta.mapping.key meta.string string.quoted.double - comment +// ^^^^^^^ meta.mapping.value meta.string string.quoted.double + + "ke/** */y": "value", +// ^^^^^^^^^^^ meta.mapping.key meta.string string.quoted.double - comment +// ^^^^^^^ meta.mapping.value meta.string string.quoted.double + + "ke/**/y": "value", +// ^^^^^^^^^ meta.mapping.key meta.string string.quoted.double - comment +// ^^^^^^^ meta.mapping.value meta.string string.quoted.double + + "ke/* */y": "value" +// ^^^^^^^^^^ meta.mapping.key meta.string string.quoted.double - comment +// ^^^^^^^ meta.mapping.value meta.string string.quoted.double +} diff --git a/Markdown/Markdown.sublime-syntax b/Markdown/Markdown.sublime-syntax index c573f3cbe68..9610eba3494 100644 --- a/Markdown/Markdown.sublime-syntax +++ b/Markdown/Markdown.sublime-syntax @@ -1216,7 +1216,12 @@ contexts: - include: fenced-html - include: fenced-java - include: fenced-javascript + + # don't match json before json5 or jsonc + - include: fenced-json5 - include: fenced-jsonc + - include: fenced-json + - include: fenced-jspx - include: fenced-jsx - include: fenced-lisp @@ -1461,23 +1466,57 @@ contexts: 0: meta.code-fence.definition.end.javascript.markdown-gfm 1: punctuation.definition.raw.code-fence.end.markdown - fenced-jsonc: + fenced-json: - match: |- (?x) {{fenced_code_block_start}} - ((?i:jsonc?)) + ((?i:json)) {{fenced_code_block_trailing_infostring_characters}} captures: 0: meta.code-fence.definition.begin.json.markdown-gfm 2: punctuation.definition.raw.code-fence.begin.markdown 5: constant.other.language-name.markdown embed: scope:source.json - embed_scope: markup.raw.code-fence.json.markdown-gfm + embed_scope: markup.raw.code-fence.json.markdown-gfm source.json escape: '{{code_fence_escape}}' escape_captures: 0: meta.code-fence.definition.end.json.markdown-gfm 1: punctuation.definition.raw.code-fence.end.markdown + fenced-json5: + - match: |- + (?x) + {{fenced_code_block_start}} + ((?i:json5)) + {{fenced_code_block_trailing_infostring_characters}} + captures: + 0: meta.code-fence.definition.begin.json5.markdown-gfm + 2: punctuation.definition.raw.code-fence.begin.markdown + 5: constant.other.language-name.markdown + embed: scope:source.json.json5 + embed_scope: markup.raw.code-fence.json5.markdown-gfm source.json.json5 + escape: '{{code_fence_escape}}' + escape_captures: + 0: meta.code-fence.definition.end.json5.markdown-gfm + 1: punctuation.definition.raw.code-fence.end.markdown + + fenced-jsonc: + - match: |- + (?x) + {{fenced_code_block_start}} + ((?i:jsonc)) + {{fenced_code_block_trailing_infostring_characters}} + captures: + 0: meta.code-fence.definition.begin.jsonc.markdown-gfm + 2: punctuation.definition.raw.code-fence.begin.markdown + 5: constant.other.language-name.markdown + embed: scope:source.json.jsonc + embed_scope: markup.raw.code-fence.jsonc.markdown-gfm source.json.jsonc + escape: '{{code_fence_escape}}' + escape_captures: + 0: meta.code-fence.definition.end.jsonc.markdown-gfm + 1: punctuation.definition.raw.code-fence.end.markdown + fenced-jspx: - match: |- (?x) diff --git a/Markdown/syntax_test_markdown.fenced_code_json.md b/Markdown/syntax_test_markdown.fenced_code_json.md new file mode 100644 index 00000000000..aaf77d99928 --- /dev/null +++ b/Markdown/syntax_test_markdown.fenced_code_json.md @@ -0,0 +1,30 @@ +// SYNTAX TEST "Packages/Markdown/Markdown.sublime-syntax" + + +```json +// ^^^^ constant.other.language-name + { "key": "value", "sequence": ["one", "two"], "number": -0.9e1, "string": "\u1234 and // /** test */" } +// ^^^^^ markup.raw.code-fence.json source.json meta.mapping.key string.quoted.double +``` + +```json5 +// ^^^^^ constant.other.language-name + { "key": 0x123, "mapping": {"one": Infinity, "two": NaN}, +// ^^^^^ markup.raw.code-fence.json5 source.json.json5 meta.mapping.key string.quoted.double +// ^^^^^ meta.number.integer.hexadecimal.json5 +// ^^^^^^^^ constant.language.infinity.json5 +// ^^^ constant.language.nan.json5 + "number": +0.9e1, 'single-quoted-string': '\v' } +// ^^^^^^ meta.number.float.decimal.json5 +// ^^^^^^^^^^^^^^^^^^^^^^ meta.mapping.key string.quoted.single.json5 +// ^^^^ meta.mapping.value string.quoted.single.json5 +// ^^ constant.character.escape.vertical-tab.json5 +``` + +```jsonc +// ^^^^^ constant.other.language-name + { "key": "value", "sequence": ["one", "two"], // comment +// ^^^^^ markup.raw.code-fence.jsonc source.json.jsonc meta.mapping.key string.quoted.double +// ^^^^^^^^^^ comment.line.double-slash.jsonc + "number": -0.9e1, "string": "\u1234 and // /** test */" } +``` diff --git a/Perl/Perl.sublime-syntax b/Perl/Perl.sublime-syntax index 6ad29675b84..782154d26c0 100644 --- a/Perl/Perl.sublime-syntax +++ b/Perl/Perl.sublime-syntax @@ -251,12 +251,27 @@ contexts: embed: scope:source.js embed_scope: source.js.embedded.perl escape: (?=^{{pod}}) + + # don't match json before json5 and jsonc + # embedded json5 + - match: \bjson5\b + scope: constant.other.language-name.json5.perl + embed: scope:source.json.json5 + embed_scope: source.json5.embedded.perl source.json.json5 + escape: (?=^{{pod}}) + # embedded jsonc + - match: \bjsonc\b + scope: constant.other.language-name.jsonc.perl + embed: scope:source.json.jsonc + embed_scope: source.jsonc.embedded.perl source.json.jsonc + escape: (?=^{{pod}}) # embedded json - match: \bjson\b scope: constant.other.language-name.json.perl embed: scope:source.json - embed_scope: source.json.embedded.perl + embed_scope: source.json.embedded.perl source.json escape: (?=^{{pod}}) + # embedded sql - match: \bsql\b scope: constant.other.language-name.sql.perl @@ -928,6 +943,22 @@ contexts: 3: entity.name.tag.heredoc.js.perl 4: punctuation.definition.tag.end.perl set: [string-heredoc-javascript, string-heredoc-expr] + # embedded json5 + - match: \s*((['"]?)(\s*JSON5)(\2)) + captures: + 1: meta.tag.heredoc.perl + 2: punctuation.definition.tag.begin.perl + 3: entity.name.tag.heredoc.json5.perl + 4: punctuation.definition.tag.end.perl + set: [string-heredoc-json5, string-heredoc-expr] + # embedded jsonc + - match: \s*((['"]?)(\s*JSONC)(\2)) + captures: + 1: meta.tag.heredoc.perl + 2: punctuation.definition.tag.begin.perl + 3: entity.name.tag.heredoc.jsonc.perl + 4: punctuation.definition.tag.end.perl + set: [string-heredoc-jsonc, string-heredoc-expr] # embedded json - match: \s*((['"]?)(\s*JSON)(\2)) captures: @@ -1011,6 +1042,24 @@ contexts: embed: scope:source.js escape: (?=^ *JAVASCRIPT$) + string-heredoc-json5: + - meta_content_scope: source.json5.embedded.perl + - match: ^\3$ + scope: meta.tag.heredoc.perl entity.name.tag.heredoc.json5.perl + pop: true + - match: '' + embed: scope:source.json.json5 + escape: (?=^ *JSON5$) + + string-heredoc-jsonc: + - meta_content_scope: source.jsonc.embedded.perl + - match: ^\3$ + scope: meta.tag.heredoc.perl entity.name.tag.heredoc.jsonc.perl + pop: true + - match: '' + embed: scope:source.json.jsonc + escape: (?=^ *JSONC$) + string-heredoc-json: - meta_content_scope: source.json.embedded.perl - match: ^\3$ diff --git a/Perl/syntax_test_perl.embedded_json.pl b/Perl/syntax_test_perl.embedded_json.pl new file mode 100644 index 00000000000..c7e60ff1648 --- /dev/null +++ b/Perl/syntax_test_perl.embedded_json.pl @@ -0,0 +1,25 @@ +// SYNTAX TEST "Packages/Perl/Perl.sublime-syntax" + +###[ POD TESTS ] ############################################################# + +=pod + +=begin json +// <- meta.comment.perl meta.interpolation.perl entity.name.tag.pod.perl + // <- meta.comment.perl meta.interpolation.perl entity.name.tag.pod.perl +//^^^^ entity.name.tag.pod.perl +//^^^^^^^^^ meta.comment.perl meta.interpolation.perl +// ^ - constant - entity +// ^^^^ constant.other.language-name.json.perl + { +//^ meta.comment.perl meta.interpolation.perl source.json.embedded.perl source.json + "key": "value" +// ^^^^^^^^^^^^^^^ meta.comment.perl meta.interpolation.perl source.json.embedded.perl source.json + } +//^ meta.comment.perl meta.interpolation.perl source.json.embedded.perl source.json +=end +// <- meta.comment.perl meta.interpolation.perl entity.name.tag.pod.perl + // <- meta.comment.perl meta.interpolation.perl entity.name.tag.pod.perl +//^^ meta.comment.perl meta.interpolation.perl entity.name.tag.pod.perl + +=cut diff --git a/Perl/syntax_test_perl.pl b/Perl/syntax_test_perl.pl index e8c68e09549..66d499464b7 100644 --- a/Perl/syntax_test_perl.pl +++ b/Perl/syntax_test_perl.pl @@ -112,22 +112,6 @@ =head1 B<--param> # <- meta.comment.perl meta.interpolation.perl entity.name.tag.pod.perl #^^^ meta.comment.perl meta.interpolation.perl entity.name.tag.pod.perl -=begin json -# <- meta.comment.perl meta.interpolation.perl entity.name.tag.pod.perl -#^^^^^^^^^^ meta.comment.perl meta.interpolation.perl -#^^^^^ entity.name.tag.pod.perl -# ^ - constant - entity -# ^^^^ constant.other.language-name.json.perl - { -# ^ meta.comment.perl meta.interpolation.perl source.json.embedded.perl source.json - "key": "value", -# ^^^^^^^^^^^^^^^ meta.comment.perl meta.interpolation.perl source.json.embedded.perl source.json - } -# ^ meta.comment.perl meta.interpolation.perl source.json.embedded.perl source.json -=end -# <- meta.comment.perl meta.interpolation.perl entity.name.tag.pod.perl -#^^^ meta.comment.perl meta.interpolation.perl entity.name.tag.pod.perl - =begin sql # <- meta.comment.perl meta.interpolation.perl entity.name.tag.pod.perl #^^^^^^^^^^ meta.comment.perl meta.interpolation.perl