From 3619e459f8acd5e9cfa5bd2750831bc5d11984af Mon Sep 17 00:00:00 2001 From: Johannes Rappen Date: Thu, 21 Oct 2021 01:59:26 +0200 Subject: [PATCH] [JSON] Rewrite syntax MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Split `JSON.sublime-syntax` into ... using inheritance: - `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` - Although the base syntax does not define a `prototype`, we add `meta_include_prototype: false` to the base syntax, to prevent inheriting syntaxes from injecting rules. - make use of `variables` - Add many more file extensions for `JSON` and `JSONC` - Significantly extend tests to cover more parts of the syntaxes defined: - Split original test file into logical parts - Add indentation tests for: - `JSON`, `JSONC` - `mapping` (objects), `sequence` (arrays) - leave `JSON` headers in `Markdown` as json only, but split up fenced code blocks into `json` and `jsonc` to behave similarly to `GitHub Flavored Markdown` - fix tests for `meta.mapping meta.mapping.*` - make `mapping.*` contexts more modular - fix #285 as requested by Jon - address #757 and use tips to fix line comments for `JSONC` - address #2430 and use sort-order as requested by deathaxe - address #2852 and use tips to fix scopes of curly braces & square brackets in `JSON` 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: deathaxe --- JSON/Comments - JSONC.tmPreferences | 25 ++ JSON/Comments.tmPreferences | 31 -- JSON/Default.sublime-keymap | 2 +- JSON/Indentation Rules.tmPreferences | 2 +- JSON/JSON (Basic).sublime-syntax | 247 ++++++++++++++++ JSON/JSON.sublime-syntax | 274 ++++++++---------- JSON/JSON5.sublime-syntax | 232 +++++++++++++++ JSON/JSONC.sublime-syntax | 164 +++++++++++ JSON/Line Terminator.tmPreferences | 17 ++ JSON/syntax_test_json.json | 123 -------- .../syntax_test_indentation_json.mapping.json | 36 +++ ...syntax_test_indentation_json.sequence.json | 89 ++++++ ...yntax_test_indentation_jsonc.mapping.jsonc | 36 +++ ...ntax_test_indentation_jsonc.sequence.jsonc | 89 ++++++ .../syntax/syntax_test_json5.comment.json5 | 42 +++ .../syntax_test_json5.meta.mapping.json5 | 78 +++++ ...er.float.decimal.explicitly_positive.json5 | 117 ++++++++ ..._json5.number.float.decimal.ieee_754.json5 | 19 ++ ....number.float.decimal.leading_period.json5 | 21 ++ ...number.float.decimal.trailing_period.json5 | 21 ++ ...est_json5.number.integer.hexadecimal.json5 | 64 ++++ .../syntax/syntax_test_json5.string.json5 | 24 ++ .../syntax/syntax_test_jsonc.comment.jsonc | 256 ++++++++++++++++ .../syntax/syntax_test_jsonc.constant.jsonc | 14 + .../syntax_test_jsonc.invalid.illegal.jsonc | 79 +++++ ...d.illegal.unrecognized_float_decimal.jsonc | 147 ++++++++++ ...illegal.unrecognized_integer_decimal.jsonc | 16 + JSON/tests/syntax/syntax_test_jsonc.jsonc | 56 ++++ .../syntax_test_jsonc.meta.mapping.jsonc | 44 +++ .../syntax/syntax_test_jsonc.number.jsonc | 251 ++++++++++++++++ .../syntax/syntax_test_jsonc.string.jsonc | 80 +++++ Markdown/Markdown.sublime-syntax | 22 +- Markdown/syntax_test_markdown.md | 14 + 33 files changed, 2418 insertions(+), 314 deletions(-) create mode 100644 JSON/Comments - JSONC.tmPreferences delete mode 100644 JSON/Comments.tmPreferences create mode 100644 JSON/JSON (Basic).sublime-syntax create mode 100644 JSON/JSON5.sublime-syntax create mode 100644 JSON/JSONC.sublime-syntax create mode 100644 JSON/Line Terminator.tmPreferences delete mode 100644 JSON/syntax_test_json.json create mode 100644 JSON/tests/indentation/syntax_test_indentation_json.mapping.json create mode 100644 JSON/tests/indentation/syntax_test_indentation_json.sequence.json create mode 100644 JSON/tests/indentation/syntax_test_indentation_jsonc.mapping.jsonc create mode 100644 JSON/tests/indentation/syntax_test_indentation_jsonc.sequence.jsonc create mode 100644 JSON/tests/syntax/syntax_test_json5.comment.json5 create mode 100644 JSON/tests/syntax/syntax_test_json5.meta.mapping.json5 create mode 100644 JSON/tests/syntax/syntax_test_json5.number.float.decimal.explicitly_positive.json5 create mode 100644 JSON/tests/syntax/syntax_test_json5.number.float.decimal.ieee_754.json5 create mode 100644 JSON/tests/syntax/syntax_test_json5.number.float.decimal.leading_period.json5 create mode 100644 JSON/tests/syntax/syntax_test_json5.number.float.decimal.trailing_period.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.jsonc create mode 100644 JSON/tests/syntax/syntax_test_jsonc.invalid.illegal.unrecognized_float_decimal.jsonc create mode 100644 JSON/tests/syntax/syntax_test_jsonc.invalid.illegal.unrecognized_integer_decimal.jsonc create mode 100644 JSON/tests/syntax/syntax_test_jsonc.jsonc create mode 100644 JSON/tests/syntax/syntax_test_jsonc.meta.mapping.jsonc create mode 100644 JSON/tests/syntax/syntax_test_jsonc.number.jsonc create mode 100644 JSON/tests/syntax/syntax_test_jsonc.string.jsonc diff --git a/JSON/Comments - JSONC.tmPreferences b/JSON/Comments - JSONC.tmPreferences new file mode 100644 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/Default.sublime-keymap b/JSON/Default.sublime-keymap index e11d9bce5c6..d710b8aab89 100644 --- a/JSON/Default.sublime-keymap +++ b/JSON/Default.sublime-keymap @@ -60,4 +60,4 @@ { "key": "following_text", "operator": "regex_contains", "operand": "^\\]", "match_all": true } ] }, -] \ No newline at end of file +] diff --git a/JSON/Indentation Rules.tmPreferences b/JSON/Indentation Rules.tmPreferences index 456889183d4..7d4559b5d80 100644 --- a/JSON/Indentation Rules.tmPreferences +++ b/JSON/Indentation Rules.tmPreferences @@ -51,7 +51,7 @@ "(?:[^"\\]|\\.)*" | # Consume all chars that don't start a string, comment or - # end the array that was opened on this line + # end the object that was opened on this line [^"/\]] )* # Stop matching at the end of the line, or once we hit a comment diff --git a/JSON/JSON (Basic).sublime-syntax b/JSON/JSON (Basic).sublime-syntax new file mode 100644 index 00000000000..35d02323bb3 --- /dev/null +++ b/JSON/JSON (Basic).sublime-syntax @@ -0,0 +1,247 @@ +%YAML 1.2 +--- +# https://yaml.org/spec/1.2/spec.html +# 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 +name: JSON (Basic) +scope: source.json.basic +version: 2 +hidden: true + + +####[ Variables ]####################################################################################################### + + +variables: + exponent: '(?:[eE][-+]?\d+)' + optional_exponent: '(?:{{exponent}}?)' + optional_neg_sign: '(?:[-]?)' + pos_integer_decimal: '(?:0|[1-9]\d*)' + + +####[ Contexts ]######################################################################################################## + + +contexts: + + main: + - include: any + + any: + - include: constants + - include: numbers + - include: strings + - include: sequence + - include: mapping + +####[ Constants ]####################################################################################################### + + constants: + - match: \b(?:null)\b + scope: constant.language.null.json + - match: \b(?:false|true)\b + scope: constant.language.boolean.json + +####[ Numbers ]######################################################################################################### + + # TODO: maybe define decimal fraction + # TODO: maybe define decimal exponent + + numbers: + - include: floats + - include: integers + + floats: + - include: decimal-float + + decimal-float: + - include: explicitly-positive-decimal-float-json + - include: decimal-float-json + + explicitly-positive-decimal-float-json: + - match: |- + (?x: # ignore whitespace + ([+]) + ( + {{pos_integer_decimal}} + (?: + (?:(\.)\d+){{optional_exponent}} + | + {{exponent}} + ) + ) + ) + scope: invalid.illegal.unrecognized-float-decimal.json + captures: + 1: keyword.operator.arithmetic.json + 2: constant.numeric.value.json + 3: punctuation.separator.decimal.json + + decimal-float-json: + - match: |- + (?x: # ignore whitespace + ({{optional_neg_sign}}) + ( + {{pos_integer_decimal}} + (?: + (?:(\.)\d+){{optional_exponent}} + | + {{exponent}} + ) + ) + ) + scope: meta.number.float.decimal.json + captures: + 1: keyword.operator.arithmetic.json + 2: constant.numeric.value.json + 3: punctuation.separator.decimal.json + + integers: + - include: decimal-integer + + decimal-integer: + - include: explicitly-positive-decimal-integer-json + - include: decimal-integer-json + + explicitly-positive-decimal-integer-json: + - match: '([+])({{pos_integer_decimal}})' + scope: invalid.illegal.unrecognized-integer-decimal.json + captures: + 1: keyword.operator.arithmetic.json + 2: constant.numeric.value.json + + decimal-integer-json: + - match: '({{optional_neg_sign}})({{pos_integer_decimal}})' + scope: meta.number.integer.decimal.json + captures: + 1: keyword.operator.arithmetic.json + 2: constant.numeric.value.json + +####[ Strings ]######################################################################################################### + + strings: + - include: double-quoted-string-ahead + + double-quoted-string-ahead: + - match: '(?=\")' + push: double-quoted-string + + double-quoted-string: + - meta_scope: meta.string.json string.quoted.double.json + - match: '"' + scope: punctuation.definition.string.begin.json + set: inside-double-quoted-string + + inside-double-quoted-string: + - meta_scope: meta.string.json string.quoted.double.json + - meta_include_prototype: false # for inheriting syntaxes + - 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: + - match: \\\" + scope: constant.character.escape.double-quote.json + - include: string-escape-characters + + string-escape-characters: + - 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.json + - match: \\. + scope: invalid.illegal.unrecognized-string-escape.json + +####[ Sequence ]######################################################################################################## + + # FIXME: move trailing commas to JSONC + + sequence: + - match: \[ + scope: punctuation.definition.sequence.begin.json + push: meta-sequence + + meta-sequence: + - meta_scope: meta.sequence.json + - match: \] + scope: punctuation.definition.sequence.end.json + pop: 1 + - include: any + - match: ',' + scope: punctuation.separator.sequence.json + - match: '[^\s\]]' + scope: invalid.illegal.expected-sequence-separator.json + +####[ Mapping ]######################################################################################################### + + # FIXME: move trailing commas to JSONC + + mapping: + - match: \{ + scope: punctuation.definition.mapping.begin.json + push: meta-mapping + + 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 + + mapping-key: + - match: '"' + scope: punctuation.definition.string.begin.json + push: mapping-key-double-quoted + + mapping-key-double-quoted: + - clear_scopes: 1 + - meta_scope: meta.mapping.key.json meta.string.json string.quoted.double.json + - meta_include_prototype: false # for inheriting syntaxes + - 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-syntax b/JSON/JSON.sublime-syntax index c391ca6687e..267ce9c05e2 100644 --- a/JSON/JSON.sublime-syntax +++ b/JSON/JSON.sublime-syntax @@ -1,165 +1,127 @@ %YAML 1.2 --- +# https://yaml.org/spec/1.2/spec.html +# 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 name: JSON scope: source.json version: 2 + +####[ Inheritance ]##################################################################################################### +####[ https://www.sublimetext.com/docs/syntax.html#inheritance ]######################################################## + + +extends: 'Packages/JSON/JSON (Basic).sublime-syntax' + + +####[ File Extensions ]################################################################################################# + + +# To not confuse beginners too much with comments being marked as invalid and +# not knowing where to change from `JSON` to `JSONC (JSON with Comments)`, it +# was decided by Jon to apply the `JSONC (JSON with Comments)` syntax by +# default to `*.json` files instead. +# See: https://github.com/sublimehq/Packages/issues/285 + 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 + + - .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 + + - .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 -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 + - webmanifest + # Web app manifests + # https://developer.mozilla.org/en-US/docs/Web/Manifest diff --git a/JSON/JSON5.sublime-syntax b/JSON/JSON5.sublime-syntax new file mode 100644 index 00000000000..7c48d6525da --- /dev/null +++ b/JSON/JSON5.sublime-syntax @@ -0,0 +1,232 @@ +%YAML 1.2 +--- +# https://yaml.org/spec/1.2/spec.html +# 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 +name: JSON5 +scope: source.json.json5 +version: 2 + + +####[ Inheritance ]##################################################################################################### +####[ https://www.sublimetext.com/docs/syntax.html#inheritance ]######################################################## + + +extends: Packages/JSON/JSONC.sublime-syntax + + +####[ File Extensions ]################################################################################################# + + +file_extensions: + + - json5 + # https://json5.org/ + # https://spec.json5.org/ + + - .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 + + - 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 + + +####[ Variables ]####################################################################################################### + + +variables: + optional_sign: '(?:[-+]?)' + + +####[ Contexts ]######################################################################################################## + + +contexts: + + # TODO: check whitespace valid chars + +####[ Numbers ]######################################################################################################### + + # we completely override here instead of prepending + decimal-float: + # (!) do not `meta_prepend: true` + - include: decimal-float-ieee-754 + - include: decimal-float-with-leading-period-in-base + - include: decimal-float-with-trailing-period-in-base + # (!) do not `include: explicitly-positive-decimal-float-json` + - include: explicitly-positive-decimal-float-json5 + - include: decimal-float-json + + decimal-float-ieee-754: + - match: '({{optional_sign}})(Infinity)' + scope: meta.number.float.decimal.json5 constant.language.infinity.json5 + captures: + 1: keyword.operator.arithmetic.json5 + 2: constant.numeric.value.json5 + - match: '({{optional_sign}})(NaN)' + scope: meta.number.float.decimal.json5 constant.language.nan.json5 + captures: + 1: keyword.operator.arithmetic.json5 + 2: constant.numeric.value.json5 + + decimal-float-with-leading-period-in-base: + - match: |- + (?x: + ({{optional_neg_sign}}) + ( + (?:(\.)\d+) + {{optional_exponent}} + ) + ) + scope: meta.number.float.decimal.json5 + captures: + 1: keyword.operator.arithmetic.json5 + 2: constant.numeric.value.json5 + 3: punctuation.separator.decimal.json5 + + decimal-float-with-trailing-period-in-base: + - match: |- + (?x: + ({{optional_neg_sign}}) + ( + {{pos_integer_decimal}} + (\.) + (?!\d) + {{optional_exponent}} + ) + ) + scope: meta.number.float.decimal.json5 + captures: + 1: keyword.operator.arithmetic.json5 + 2: constant.numeric.value.json5 + 3: punctuation.separator.decimal.json5 + + explicitly-positive-decimal-float-json5: + - match: |- + (?x: # ignore whitespace + ([+]) + ( + {{pos_integer_decimal}} + (?: + (?:(\.)\d+){{optional_exponent}} + | + {{exponent}} + ) + ) + ) + scope: meta.number.float.decimal.json5 + captures: + 1: keyword.operator.arithmetic.json5 + 2: constant.numeric.value.json5 + 3: punctuation.separator.decimal.json5 + + integers: + - meta_prepend: true + - include: hexadecimal-integer + + # we completely override here instead of prepending + decimal-integer: + # (!) do not `meta_prepend: true` + - include: explicitly-positive-decimal-integer-json5 + # (!) do not `include: explicitly-positive-decimal-integer-json` + - include: decimal-integer-json + + explicitly-positive-decimal-integer-json5: + - match: '([+])({{pos_integer_decimal}})' + scope: meta.number.integer.decimal.json5 + captures: + 1: keyword.operator.arithmetic.json5 + 2: constant.numeric.value.json5 + + hexadecimal-integer: + - match: |- + (?xi: # ignore whitespace and case + ({{optional_sign}}) + (0[x]) + (\h+) + ) + scope: meta.number.integer.hexadecimal.json5 + captures: + 1: keyword.operator.arithmetic.json5 + 2: constant.numeric.base.json5 + 3: constant.numeric.value.json5 + +####[ Strings ]######################################################################################################### + + # TODO: add multiline with new-line-escapes + # TODO: add escapes with 2 hex + # TODO: add escapes for UTF-16, pair with four hex each + # TODO: no decimal digit after null escpae allowed + # TODO: add warnings for paragraph separator & line separator + + strings: + - meta_append: true + - include: single-quoted-string-ahead + + single-quoted-string-ahead: + - match: (?=') + push: single-quoted-string + + single-quoted-string: + - meta_scope: meta.string.json5 string.quoted.single.json5 + - match: "'" + scope: punctuation.definition.string.begin.json5 + set: inside-single-quoted-string + + inside-single-quoted-string: + - meta_scope: meta.string.json5 string.quoted.single.json5 + - meta_include_prototype: false + - 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: + - match: \\\' + scope: constant.character.escape.single-quote.json5 + - include: string-escape-characters + + string-escape-characters: + - meta_prepend: true + - match: \\v + scope: constant.character.escape.vertical-tab.json5 + - match: \\0 + scope: constant.character.escape.null.json5 + +####[ Mapping ]######################################################################################################### + + # TODO: add ECMAScript identifier + + mapping-key: + - meta_append: true + - match: "'" + scope: punctuation.definition.string.begin.json5 + push: mapping-key-single-quoted + + mapping-key-single-quoted: + - clear_scopes: 1 + - meta_scope: meta.mapping.key.json5 meta.string.json5 string.quoted.single.json5 + - meta_include_prototype: false # for inheriting syntaxes + - include: inside-single-quoted-string diff --git a/JSON/JSONC.sublime-syntax b/JSON/JSONC.sublime-syntax new file mode 100644 index 00000000000..8fb1edb141a --- /dev/null +++ b/JSON/JSONC.sublime-syntax @@ -0,0 +1,164 @@ +%YAML 1.2 +--- +# https://yaml.org/spec/1.2/spec.html +# 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 +name: JSONC (JSON with Comments) +scope: source.json.jsonc +version: 2 + + +####[ Inheritance ]##################################################################################################### +####[ https://www.sublimetext.com/docs/syntax.html#inheritance ]######################################################## + + +extends: Packages/JSON/JSON.sublime-syntax + + +####[ File Extensions ]################################################################################################# + + +# To not confuse beginners too much with comments being marked as invalid and +# not knowing where to change from `JSON` to `JSONC (JSON with Comments)`, it +# was decided by Jon to apply the `JSONC (JSON with Comments)` syntax by +# default to `*.json` files instead. +# See: https://github.com/sublimehq/Packages/issues/285 + +file_extensions: + + - json + # 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/ + + - 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 + + +####[ Contexts ]######################################################################################################## + + +contexts: + + # The syntax we are inheriting from already excludes prototype from the + # relevant contexts, although not having a prototype itself. + prototype: + - include: comments + + +####[ Comments / Add to inherited syntax ]############################################################################## + + comments: + - include: comment-line + - include: comment-doc-block + - include: comment-block + + comment-line: + - match: '//' + scope: punctuation.definition.comment.jsonc + push: + - meta_scope: comment.line.double-slash.jsonc + - meta_include_prototype: false + - match: $\n? + pop: 1 + + comment-doc-block: + - match: '/\*\*(?!/)' + scope: punctuation.definition.comment.begin.jsonc + push: + - meta_scope: comment.block.documentation.jsonc + - meta_include_prototype: false + - include: comment-block-end + - match: '^\s*(\*)(?!/)' + captures: + 1: punctuation.definition.comment.jsonc + + comment-block: + - match: '/\*' + scope: punctuation.definition.comment.begin.jsonc + push: + - meta_scope: comment.block.jsonc + - meta_include_prototype: false + - include: comment-block-end + + comment-block-end: + - match: '\*/' + scope: punctuation.definition.comment.end.jsonc + pop: 1 diff --git a/JSON/Line Terminator.tmPreferences b/JSON/Line Terminator.tmPreferences new file mode 100644 index 00000000000..9482e9a53f1 --- /dev/null +++ b/JSON/Line Terminator.tmPreferences @@ -0,0 +1,17 @@ + + + + scope + source.json + settings + + shellVariables + + + nameTM_LINE_TERMINATOR + value, + + + + + 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_json.mapping.json b/JSON/tests/indentation/syntax_test_indentation_json.mapping.json new file mode 100644 index 00000000000..cb36ba9613b --- /dev/null +++ b/JSON/tests/indentation/syntax_test_indentation_json.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_json.sequence.json b/JSON/tests/indentation/syntax_test_indentation_json.sequence.json new file mode 100644 index 00000000000..e84350cae63 --- /dev/null +++ b/JSON/tests/indentation/syntax_test_indentation_json.sequence.json @@ -0,0 +1,89 @@ +// 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_jsonc.mapping.jsonc b/JSON/tests/indentation/syntax_test_indentation_jsonc.mapping.jsonc new file mode 100644 index 00000000000..77dbaad820f --- /dev/null +++ b/JSON/tests/indentation/syntax_test_indentation_jsonc.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_jsonc.sequence.jsonc b/JSON/tests/indentation/syntax_test_indentation_jsonc.sequence.jsonc new file mode 100644 index 00000000000..0499df39f34 --- /dev/null +++ b/JSON/tests/indentation/syntax_test_indentation_jsonc.sequence.jsonc @@ -0,0 +1,89 @@ +// 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/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.meta.mapping.json5 b/JSON/tests/syntax/syntax_test_json5.meta.mapping.json5 new file mode 100644 index 00000000000..c1bebfd0e68 --- /dev/null +++ b/JSON/tests/syntax/syntax_test_json5.meta.mapping.json5 @@ -0,0 +1,78 @@ +// SYNTAX TEST "Packages/JSON/JSON5.sublime-syntax" + +// <- source.json.json5 + +{ +// <- meta.mapping punctuation.definition.mapping.begin + + 'meta-mapping-value-constant': null, +// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.mapping.key +// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - meta.mapping meta.mapping.key +// ^ 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.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.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.mapping punctuation.separator.mapping.key-value +// ^^^^^^^ meta.mapping.value +// ^^^^^^^ - meta.mapping meta.mapping.value + + 'meta-mapping-value-sequence': [1, 2, 3], +// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.mapping.key +// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - meta.mapping meta.mapping.key +// ^ meta.mapping punctuation.separator.mapping.key-value +// ^^^^^^^^^ meta.mapping.value +// ^^^^^^^^^ - meta.mapping meta.mapping.value +// ^ meta.mapping.value meta.sequence punctuation.definition.sequence.begin +// ^ meta.mapping.value meta.sequence punctuation.definition.sequence.end + + 'meta-mapping-value-mapping': { "a": 1, "b": 2 }, +// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.mapping.key +// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - meta.mapping meta.mapping.key +// ^ 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.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.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.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.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.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.number.float.decimal.explicitly_positive.json5 b/JSON/tests/syntax/syntax_test_json5.number.float.decimal.explicitly_positive.json5 new file mode 100644 index 00000000000..f2ad01c19b8 --- /dev/null +++ b/JSON/tests/syntax/syntax_test_json5.number.float.decimal.explicitly_positive.json5 @@ -0,0 +1,117 @@ +// SYNTAX TEST "Packages/JSON/JSON5.sublime-syntax" + +// <- source.json.json5 + +{ + "float-explicitly-positive-zero": +0.0, +// ^^^^ meta.number.float.decimal +// ^ keyword.operator.arithmetic +// ^^^ constant.numeric.value +// ^ punctuation.separator.decimal + +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + + "float-explicitly-positive-zero-with-zero-exponent": +0.0e0, +// ^^^^^^ meta.number.float.decimal +// ^ keyword.operator.arithmetic +// ^^^^^ constant.numeric.value +// ^ punctuation.separator.decimal + + "float-explicitly-positive-zero-with-negative-zero-exponent": +0.0e-0, +// ^^^^^^^ meta.number.float.decimal +// ^ keyword.operator.arithmetic +// ^^^^^^ constant.numeric.value +// ^ punctuation.separator.decimal + + "float-explicitly-positive-zero-no-fraction-with-zero-exponent": +0e0, +// ^^^^ meta.number.float.decimal +// ^ keyword.operator.arithmetic +// ^^^constant.numeric.value + + "float-explicitly-positive-zero-no-fraction-with-negative-zero-exponent": +0e-0, +// ^^^^^ meta.number.float.decimal +// ^ keyword.operator.arithmetic +// ^^^^ constant.numeric.value + +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + + "float-explicitly-positive-zero-with-exponent": +0.0e9, +// ^^^^^^ meta.number.float.decimal +// ^ keyword.operator.arithmetic +// ^^^^^ constant.numeric.value +// ^ punctuation.separator.decimal + + "float-explicitly-positive-zero-with-negative-exponent": +0.0e-9, +// ^^^^^^^ meta.number.float.decimal +// ^ keyword.operator.arithmetic +// ^^^^^^ constant.numeric.value +// ^ punctuation.separator.decimal + + "float-explicitly-positive-zero-no-fraction-with-exponent": +0e9, +// ^^^^ meta.number.float.decimal +// ^ keyword.operator.arithmetic +// ^^^ constant.numeric.value + + "float-explicitly-positive-zero-no-fraction-with-negative-exponent": +0e-9, +// ^^^^^ meta.number.float.decimal +// ^ keyword.operator.arithmetic +// ^^^^ constant.numeric.value + +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + + "float-explicitly-positive": +9.0, +// ^^^^ meta.number.float.decimal +// ^ keyword.operator.arithmetic +// ^^^ constant.numeric.value +// ^ punctuation.separator.decimal + +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + + "float-explicitly-positive-with-zero-exponent": +9.0e0, +// ^^^^^^ meta.number.float.decimal +// ^ keyword.operator.arithmetic +// ^^^^^ constant.numeric.value +// ^ punctuation.separator.decimal + + "float-explicitly-positive-with-negative-zero-exponent": +9.0e-0, +// ^^^^^^^ meta.number.float.decimal +// ^ keyword.operator.arithmetic +// ^^^^^^ constant.numeric.value +// ^ punctuation.separator.decimal + + "float-explicitly-positive-no-fraction-with-zero-exponent": +9e0, +// ^^^^ meta.number.float.decimal +// ^ keyword.operator.arithmetic +// ^^^ constant.numeric.value + + "float-explicitly-positive-no-fraction-with-negative-zero-exponent": +9e-0, +// ^^^^^ meta.number.float.decimal +// ^ keyword.operator.arithmetic +// ^^^^ constant.numeric.value + +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + + "float-explicitly-positive-with-exponent": +9.0e9, +// ^^^^^^ meta.number.float.decimal +// ^ keyword.operator.arithmetic +// ^^^^^ constant.numeric.value +// ^ punctuation.separator.decimal + + "float-explicitly-positive-with-negative-exponent": +9.0e-9, +// ^^^^^^^ meta.number.float.decimal +// ^ keyword.operator.arithmetic +// ^^^^^^ constant.numeric.value +// ^ punctuation.separator.decimal + +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + + "float-explicitly-positive-no-fraction-with-exponent": +9e9, +// ^^^^ meta.number.float.decimal +// ^ keyword.operator.arithmetic +// ^^^ constant.numeric.value + + "float-explicitly-positive-no-fraction-with-negative-exponent": +9e-9 +// ^^^^^ meta.number.float.decimal +// ^ keyword.operator.arithmetic +// ^^^^ constant.numeric.value +} diff --git a/JSON/tests/syntax/syntax_test_json5.number.float.decimal.ieee_754.json5 b/JSON/tests/syntax/syntax_test_json5.number.float.decimal.ieee_754.json5 new file mode 100644 index 00000000000..82f1e90a33b --- /dev/null +++ b/JSON/tests/syntax/syntax_test_json5.number.float.decimal.ieee_754.json5 @@ -0,0 +1,19 @@ +// SYNTAX TEST "Packages/JSON/JSON5.sublime-syntax" + +// <- source.json.json5 + +{ + "constant-language-nan": NaN, +// ^^^ meta.number.float.decimal constant.language.nan + "constant-language-nan-pos": +NaN, +// ^^^^ meta.number.float.decimal constant.language.nan + "constant-language-nan-neg": -NaN, +// ^^^^ meta.number.float.decimal constant.language.nan + + "constant-language-infinity": Infinity, +// ^^^^^^^^ meta.number.float.decimal constant.language.infinity + "constant-language-infinity-pos": +Infinity, +// ^^^^^^^^^ meta.number.float.decimal constant.language.infinity + "constant-language-infinity-neg": -Infinity +// ^^^^^^^^^ meta.number.float.decimal constant.language.infinity +} diff --git a/JSON/tests/syntax/syntax_test_json5.number.float.decimal.leading_period.json5 b/JSON/tests/syntax/syntax_test_json5.number.float.decimal.leading_period.json5 new file mode 100644 index 00000000000..5a3dd4628e3 --- /dev/null +++ b/JSON/tests/syntax/syntax_test_json5.number.float.decimal.leading_period.json5 @@ -0,0 +1,21 @@ +// SYNTAX TEST "Packages/JSON/JSON5.sublime-syntax" + +// <- source.json.json5 + +{ + "float-leading-period-followed-by-zero": .0, +// ^^ meta.number.float.decimal +// ^^ - invalid.illegal.meta-number-float-decimal + + "float-leading-period-followed-by-nonzero": .9, +// ^^ meta.number.float.decimal +// ^^ - invalid.illegal.meta-number-float-decimal + + "negative-float-leading-period-followed-by-zero": -.0, +// ^^^ meta.number.float.decimal +// ^^^ - invalid.illegal.meta-number-float-decimal + + "negative-float-leading-period-followed-by-nonzero": -.9 +// ^^^ meta.number.float.decimal +// ^^^ - invalid.illegal.meta-number-float-decimal +} diff --git a/JSON/tests/syntax/syntax_test_json5.number.float.decimal.trailing_period.json5 b/JSON/tests/syntax/syntax_test_json5.number.float.decimal.trailing_period.json5 new file mode 100644 index 00000000000..687a6430f3a --- /dev/null +++ b/JSON/tests/syntax/syntax_test_json5.number.float.decimal.trailing_period.json5 @@ -0,0 +1,21 @@ +// SYNTAX TEST "Packages/JSON/JSON5.sublime-syntax" + +// <- source.json.json5 + +{ + "float-trailing-period-lead-by-zero": 0., +// ^^ meta.number.float.decimal +// ^^ - invalid.illegal.meta-number-float-decimal + + "float-trailing-period-lead-by-nonzero": 9., +// ^^ meta.number.float.decimal +// ^^ - invalid.illegal.meta-number-float-decimal + + "negative-float-trailing-period-lead-by-zero": -0., +// ^^^ meta.number.float.decimal +// ^^^ - invalid.illegal.meta-number-float-decimal + + "negative-float-trailing-period-lead-by-nonzero": -9. +// ^^^ meta.number.float.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..556a4f8ea06 --- /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 +// ^ keyword.operator.arithmetic +// ^^ constant.numeric.base +// ^ constant.numeric.value + "lower-case-negative-hexadecimal-zero-integer": -0x0, +// ^^^^ meta.number.integer.hexadecimal +// ^ keyword.operator.arithmetic +// ^^ 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 +// ^ keyword.operator.arithmetic +// ^^ constant.numeric.base +// ^ constant.numeric.value + "lower-case-negative-hexadecimal-integer": -0x1, +// ^^^^ meta.number.integer.hexadecimal +// ^ keyword.operator.arithmetic +// ^^ 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 +// ^ keyword.operator.arithmetic +// ^^ constant.numeric.base +// ^ constant.numeric.value + "upper-case-negative-hexadecimal-zero-integer": -0X0, +// ^^^^ meta.number.integer.hexadecimal +// ^ keyword.operator.arithmetic +// ^^ 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 +// ^ keyword.operator.arithmetic +// ^^ constant.numeric.base +// ^ constant.numeric.value + "upper-case-negative-hexadecimal-integer": -0X1 +// ^^^^ meta.number.integer.hexadecimal +// ^ keyword.operator.arithmetic +// ^^ 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..a8c6f58c91a --- /dev/null +++ b/JSON/tests/syntax/syntax_test_json5.string.json5 @@ -0,0 +1,24 @@ +// 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 + + '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 +} 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..69ac253e53b --- /dev/null +++ b/JSON/tests/syntax/syntax_test_jsonc.comment.jsonc @@ -0,0 +1,256 @@ +// 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 + + + + + + "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 + + + + + + "dict": {"foo"/*comment*/:/*comment*/"bar"/*comment*/}, +// ^^^^^^^^^^^ comment.block +// ^^^^^^^^^^^ comment.block +// ^^^^^^^^^^^ comment.block + + "dict": { + "foo": "bar" + // comment +// ^^^^^^^^^^ comment.line.double-slash + , +// ^ punctuation.separator.mapping.pair + "foo": "bar" + /* comment */ +// ^^^^^^^^^^^^^ comment.block + }, + + "unterminated string + /**/: "test" +// ^^^^ meta.mapping comment.block +} 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.jsonc b/JSON/tests/syntax/syntax_test_jsonc.invalid.illegal.jsonc new file mode 100644 index 00000000000..e9c1c35142d --- /dev/null +++ b/JSON/tests/syntax/syntax_test_jsonc.invalid.illegal.jsonc @@ -0,0 +1,79 @@ +// 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 + + + + +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + + + + + "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.unrecognized_float_decimal.jsonc b/JSON/tests/syntax/syntax_test_jsonc.invalid.illegal.unrecognized_float_decimal.jsonc new file mode 100644 index 00000000000..86a4c5b62ed --- /dev/null +++ b/JSON/tests/syntax/syntax_test_jsonc.invalid.illegal.unrecognized_float_decimal.jsonc @@ -0,0 +1,147 @@ +// SYNTAX TEST "Packages/JSON/JSONC.sublime-syntax" + +// <- source.json.jsonc + +{ + "float-explicitly-positive-zero": +0.0, +// ^^^^ invalid.illegal.unrecognized-float-decimal +// ^ keyword.operator.arithmetic +// ^^^ constant.numeric.value +// ^ punctuation.separator.decimal + +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + + "float-explicitly-positive-zero-with-zero-exponent": +0.0e0, +// ^^^^^^ invalid.illegal.unrecognized-float-decimal +// ^ keyword.operator.arithmetic +// ^^^^^ constant.numeric.value +// ^ punctuation.separator.decimal + + "float-explicitly-positive-zero-with-negative-zero-exponent": +0.0e-0, +// ^^^^^^^ invalid.illegal.unrecognized-float-decimal +// ^ keyword.operator.arithmetic +// ^^^^^^ constant.numeric.value +// ^ punctuation.separator.decimal + + "float-explicitly-positive-zero-no-fraction-with-zero-exponent": +0e0, +// ^^^^ invalid.illegal.unrecognized-float-decimal +// ^ keyword.operator.arithmetic +// ^^^ constant.numeric.value + + "float-explicitly-positive-zero-no-fraction-with-negative-zero-exponent": +0e-0, +// ^^^^^ invalid.illegal.unrecognized-float-decimal +// ^ keyword.operator.arithmetic +// ^^^^ constant.numeric.value + + + + +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + + + + + "float-explicitly-positive-zero-with-exponent": +0.0e9, +// ^^^^^^ invalid.illegal.unrecognized-float-decimal +// ^ keyword.operator.arithmetic +// ^^^^^ constant.numeric.value +// ^ punctuation.separator.decimal + + "float-explicitly-positive-zero-with-negative-exponent": +0.0e-9, +// ^^^^^^^ invalid.illegal.unrecognized-float-decimal +// ^ keyword.operator.arithmetic +// ^^^^^^ constant.numeric.value +// ^ punctuation.separator.decimal + + "float-explicitly-positive-zero-no-fraction-with-exponent": +0e9, +// ^^^^ invalid.illegal.unrecognized-float-decimal +// ^ keyword.operator.arithmetic +// ^^^ constant.numeric.value + + "float-explicitly-positive-zero-no-fraction-with-negative-exponent": +0e-9, +// ^^^^^ invalid.illegal.unrecognized-float-decimal +// ^ keyword.operator.arithmetic +// ^^^^ constant.numeric.value + + + + +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + + + + + "float-explicitly-positive": +9.0, +// ^^^^ invalid.illegal.unrecognized-float-decimal +// ^ keyword.operator.arithmetic +// ^^^ constant.numeric.value +// ^ punctuation.separator.decimal + + + + +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + + + + + "float-explicitly-positive-with-zero-exponent": +9.0e0, +// ^^^^^^ invalid.illegal.unrecognized-float-decimal +// ^ keyword.operator.arithmetic +// ^^^^^ constant.numeric.value +// ^ punctuation.separator.decimal + + "float-explicitly-positive-with-negative-zero-exponent": +9.0e-0, +// ^^^^^^^ invalid.illegal.unrecognized-float-decimal +// ^ keyword.operator.arithmetic +// ^^^^^^ constant.numeric.value +// ^ punctuation.separator.decimal + + "float-explicitly-positive-no-fraction-with-zero-exponent": +9e0, +// ^^^^ invalid.illegal.unrecognized-float-decimal +// ^ keyword.operator.arithmetic +// ^^^ constant.numeric.value + + "float-explicitly-positive-no-fraction-with-negative-zero-exponent": +9e-0, +// ^^^^^ invalid.illegal.unrecognized-float-decimal +// ^ keyword.operator.arithmetic +// ^^^^ constant.numeric.value + + + + +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + + + + + "float-explicitly-positive-with-exponent": +9.0e9, +// ^^^^^^ invalid.illegal.unrecognized-float-decimal +// ^ keyword.operator.arithmetic +// ^^^^^ constant.numeric.value +// ^ punctuation.separator.decimal + + "float-explicitly-positive-with-negative-exponent": +9.0e-9, +// ^^^^^^^ invalid.illegal.unrecognized-float-decimal +// ^ keyword.operator.arithmetic +// ^^^^^^ constant.numeric.value +// ^ punctuation.separator.decimal + + + + +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + + + + + "float-explicitly-positive-no-fraction-with-exponent": +9e9, +// ^^^^ invalid.illegal.unrecognized-float-decimal +// ^ keyword.operator.arithmetic +// ^^^ constant.numeric.value + + "float-explicitly-positive-no-fraction-with-negative-exponent": +9e-9 +// ^^^^^ invalid.illegal.unrecognized-float-decimal +// ^ keyword.operator.arithmetic +// ^^^^ constant.numeric.value +} diff --git a/JSON/tests/syntax/syntax_test_jsonc.invalid.illegal.unrecognized_integer_decimal.jsonc b/JSON/tests/syntax/syntax_test_jsonc.invalid.illegal.unrecognized_integer_decimal.jsonc new file mode 100644 index 00000000000..b0b81277f36 --- /dev/null +++ b/JSON/tests/syntax/syntax_test_jsonc.invalid.illegal.unrecognized_integer_decimal.jsonc @@ -0,0 +1,16 @@ +// SYNTAX TEST "Packages/JSON/JSONC.sublime-syntax" + +// <- source.json.jsonc + +{ + + "explicitly-positive-zero": +0, +// ^^ invalid.illegal.unrecognized-integer-decimal +// ^ keyword.operator.arithmetic +// ^ constant.numeric.value + + "explicitly-positive-integer": +9 +// ^^ invalid.illegal.unrecognized-integer-decimal +// ^ keyword.operator.arithmetic +// ^ constant.numeric.value +} diff --git a/JSON/tests/syntax/syntax_test_jsonc.jsonc b/JSON/tests/syntax/syntax_test_jsonc.jsonc new file mode 100644 index 00000000000..f0b01930b81 --- /dev/null +++ b/JSON/tests/syntax/syntax_test_jsonc.jsonc @@ -0,0 +1,56 @@ +// SYNTAX TEST "Packages/JSON/JSONC.sublime-syntax" + +// <- source.json.jsonc + +{ + "array": [ /**/ ], +// ^^^^^^^^ meta.mapping.value meta.sequence +// ^ punctuation.definition.sequence.begin +// ^^^^ comment.block +// ^ punctuation.definition.sequence.end + + "dict": {"foo"/*comment*/:/*comment*/"bar"/*comment*/}, +// ^^^^^^^^^^^ comment.block +// ^^^^^^^^^^^ comment.block +// ^^^^^^^^^^^ comment.block + + "dict": { + "foo": "bar" + // comment +// ^ - invalid +// ^^^^^^^^^^ comment.line.double-slash + , +// ^ punctuation.separator.mapping.pair + "foo": "bar" + /* comment */ +// ^ - invalid +// ^^^^^^^^^^^^^ comment.block + }, +//^ punctuation.definition.mapping.end +// ^ punctuation.separator.mapping.pair + + "string": "string", +// ^ punctuation.definition.string.begin +// ^^^^^^^^ meta.mapping.value string.quoted.double +// ^ punctuation.definition.string.end + + "unterminated string +//^^^^^^^^^^^^^^^^^^^^ string.quoted.double +// ^ string.quoted.double invalid.illegal.unclosed-string + +// <- - string + +/**/: "test", +// ^ meta.mapping comment.block +// ^ punctuation.separator.mapping.key-value - comment +// ^^^^^^ meta.mapping.value string.quoted.double + + "array2": + [ + "foobar", +// ^^^^^^^^ meta.mapping.value meta.sequence string.quoted.double - meta.mapping.key + ] + + "typing json": {} + ,,,, "another key": false +} 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..ddf605af57d --- /dev/null +++ b/JSON/tests/syntax/syntax_test_jsonc.meta.mapping.jsonc @@ -0,0 +1,44 @@ +// 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.mapping.json meta.mapping.key +// ^ meta.mapping punctuation.separator.mapping.key-value +// ^^^^ meta.mapping.value - meta.mapping.json meta.mapping.value + + "meta-mapping-value-number": 0, +// ^^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.mapping.key - meta.mapping.json meta.mapping.key +// ^ meta.mapping punctuation.separator.mapping.key-value +// ^ meta.mapping.value - meta.mapping.json meta.mapping.value + + "meta-mapping-value-string": "value", +// ^^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.mapping.key - meta.mapping.json meta.mapping.key +// ^ meta.mapping punctuation.separator.mapping.key-value +// ^^^^^^^ meta.mapping.value - meta.mapping.json meta.mapping.value + + "meta-mapping-value-sequence": [1, 2, 3], +// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.mapping.key - meta.mapping.json meta.mapping.key +// ^ meta.mapping punctuation.separator.mapping.key-value +// ^^^^^^^^^ meta.mapping.value - meta.mapping.json meta.mapping.value +// ^ meta.mapping.value meta.sequence punctuation.definition.sequence.begin +// ^ meta.mapping.value meta.sequence punctuation.definition.sequence.end + + "meta-mapping-value-mapping": { "a": 1, "b": 2 } +// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.mapping.key - meta.mapping.json meta.mapping.key +// ^ 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 punctuation.definition.mapping.end +// ^^^ meta.mapping.value meta.mapping.key +// ^ 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.mapping.value meta.mapping punctuation.separator.mapping.key-value +// ^ meta.mapping.value meta.mapping.value +} +// <- meta.mapping punctuation.definition.mapping.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..ef7beba6cc5 --- /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 +// ^ keyword.operator.arithmetic +// ^ constant.numeric.value + + + + +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + + + + + "integer": 9, +// ^ meta.number.integer.decimal +// ^ constant.numeric.value + + "negative-integer": -9, +// ^^ meta.number.integer.decimal +// ^ keyword.operator.arithmetic +// ^ 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 +// ^ keyword.operator.arithmetic +// ^^^ 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 +// ^ keyword.operator.arithmetic +// ^^^^^ constant.numeric.value +// ^ punctuation.separator.decimal + + "float-negative-zero-with-negative-zero-exponent": -0.0e-0, +// ^^^^^^^ meta.number.float.decimal +// ^ keyword.operator.arithmetic +// ^^^^^^ 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 +// ^ keyword.operator.arithmetic +// ^^^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 +// ^ keyword.operator.arithmetic +// ^^^^ 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 +// ^ keyword.operator.arithmetic +// ^^^^^ constant.numeric.value +// ^ punctuation.separator.decimal + + "float-negative-zero-with-negative-exponent": -0.0e-9, +// ^^^^^^^ meta.number.float.decimal +// ^ keyword.operator.arithmetic +// ^^^^^^ 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 +// ^ keyword.operator.arithmetic +// ^^^ 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 +// ^ keyword.operator.arithmetic +// ^^^^ constant.numeric.value + + + + +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + + + + + "float": 9.0, +// ^^^ meta.number.float.decimal constant.numeric.value +// ^ punctuation.separator.decimal + + "float-negative": -9.0, +// ^^^^ meta.number.float.decimal +// ^ keyword.operator.arithmetic +// ^^^ 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 +// ^ keyword.operator.arithmetic +// ^^^^^ constant.numeric.value +// ^ punctuation.separator.decimal + + "float-negative-with-negative-zero-exponent": -9.0e-0, +// ^^^^^^^ meta.number.float.decimal +// ^ keyword.operator.arithmetic +// ^^^^^^ 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 +// ^ keyword.operator.arithmetic +// ^^^ 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 +// ^ keyword.operator.arithmetic +// ^^^^ 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 +// ^ keyword.operator.arithmetic +// ^^^^^ constant.numeric.value +// ^ punctuation.separator.decimal + + "float-negative-with-negative-exponent": -9.0e-9, +// ^^^^^^^ meta.number.float.decimal +// ^ keyword.operator.arithmetic +// ^^^^^^ 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 +// ^ keyword.operator.arithmetic +// ^^^ 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 +// ^ keyword.operator.arithmetic +// ^^^^ 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..556648363c4 --- /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 + + "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 +// ^ - 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 6989819597e..03b1b63c0f1 100644 --- a/Markdown/Markdown.sublime-syntax +++ b/Markdown/Markdown.sublime-syntax @@ -1186,6 +1186,7 @@ contexts: - include: fenced-html - include: fenced-java - include: fenced-javascript + - include: fenced-json - include: fenced-jsonc - include: fenced-jspx - include: fenced-jsx @@ -1431,11 +1432,11 @@ 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 @@ -1448,6 +1449,23 @@ contexts: 0: meta.code-fence.definition.end.json.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 + 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.md b/Markdown/syntax_test_markdown.md index 310a52f0f0b..f2c638f2151 100644 --- a/Markdown/syntax_test_markdown.md +++ b/Markdown/syntax_test_markdown.md @@ -1968,6 +1968,20 @@ for (var i = 0; i < 10; i++) { ``` | <- punctuation.definition.raw.code-fence.end +```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 +``` + +```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 */" } +``` + ```ts | ^^ constant.other.language-name declare type foo = 'bar'