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..c968aaddfbb 100644
--- a/Markdown/Markdown.sublime-syntax
+++ b/Markdown/Markdown.sublime-syntax
@@ -1186,6 +1186,8 @@ contexts:
- include: fenced-html
- include: fenced-java
- include: fenced-javascript
+ - include: fenced-json
+ - include: fenced-json5
- include: fenced-jsonc
- include: fenced-jspx
- include: fenced-jsx
@@ -1431,11 +1433,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 +1450,40 @@ contexts:
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
+ 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
+ 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..43d42b5bea8 100644
--- a/Markdown/syntax_test_markdown.md
+++ b/Markdown/syntax_test_markdown.md
@@ -1968,6 +1968,34 @@ 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
+```
+
+```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 */" }
+```
+
```ts
| ^^ constant.other.language-name
declare type foo = 'bar'