diff --git a/HTML/syntax_test_html.html b/HTML/syntax_test_html.html
index 9c1539aa100..2d2aedcd40e 100644
--- a/HTML/syntax_test_html.html
+++ b/HTML/syntax_test_html.html
@@ -127,23 +127,23 @@
diff --git a/JSON/.python-version b/JSON/.python-version
new file mode 100644
index 00000000000..cc1923a40b1
--- /dev/null
+++ b/JSON/.python-version
@@ -0,0 +1 @@
+3.8
diff --git a/JSON/Comments - JSON5.tmPreferences b/JSON/Comments - JSON5.tmPreferences
new file mode 100644
index 00000000000..75aac0ef338
--- /dev/null
+++ b/JSON/Comments - JSON5.tmPreferences
@@ -0,0 +1,25 @@
+
+
+
+ scope
+ source.json.json5
+ settings
+
+ shellVariables
+
+
+ nameTM_COMMENT_START
+ value//
+
+
+ nameTM_COMMENT_START_2
+ value/*
+
+
+ nameTM_COMMENT_END_2
+ value*/
+
+
+
+
+
diff --git a/JSON/Comments - JSONC.tmPreferences b/JSON/Comments - JSONC.tmPreferences
new file mode 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/Context.sublime-menu b/JSON/Context.sublime-menu
new file mode 100644
index 00000000000..c55090cced5
--- /dev/null
+++ b/JSON/Context.sublime-menu
@@ -0,0 +1,29 @@
+// Packages/JSON/Context.sublime-menu
+
+
+// This file is being maintained at:
+// https://github.com/sublimehq/Packages/blob/master/JSON/Context.sublime-menu
+
+
+[
+ // visible only with JSON syntax highlighting
+ {
+ "caption": "JSON: Minify",
+ "command": "json_minify"
+ },
+ {
+ "caption": "JSON: Prettify",
+ "command": "json_prettify"
+ },
+
+
+ // visible only with JSONC syntax highlighting
+ {
+ "caption": "JSONC: Minify",
+ "command": "jsonc_minify"
+ },
+ {
+ "caption": "JSONC: Prettify",
+ "command": "jsonc_prettify"
+ }
+]
diff --git a/JSON/Default.sublime-commands b/JSON/Default.sublime-commands
new file mode 100644
index 00000000000..c6a9be5e676
--- /dev/null
+++ b/JSON/Default.sublime-commands
@@ -0,0 +1,29 @@
+// Packages/JSON/Default.sublime-commands
+
+
+// This file is being maintained at:
+// https://github.com/sublimehq/Packages/blob/master/JSON/Default.sublime-commands
+
+
+[
+ // visible only with JSON syntax highlighting
+ {
+ "caption": "JSON: Minify JSON",
+ "command": "json_minify"
+ },
+ {
+ "caption": "JSON: Prettify JSON",
+ "command": "json_prettify"
+ },
+
+
+ // visible only with JSONC syntax highlighting
+ {
+ "caption": "JSONC: Minify JSONC",
+ "command": "jsonc_minify"
+ },
+ {
+ "caption": "JSONC: Prettify JSONC",
+ "command": "jsonc_prettify"
+ }
+]
diff --git a/JSON/Default.sublime-keymap b/JSON/Default.sublime-keymap
index e11d9bce5c6..56ef9e4a4e7 100644
--- a/JSON/Default.sublime-keymap
+++ b/JSON/Default.sublime-keymap
@@ -1,63 +1,70 @@
+// Packages/JSON/Default.sublime-keymap
+
+
+// This file is being maintained at:
+// https://github.com/sublimehq/Packages/blob/master/JSON/Default.sublime-keymap
+
+
[
- // Auto-pair quotations: "key": '|',
- { "keys": ["'"], "command": "insert_snippet", "args": {"contents": "'$0'"}, "context":
- [
- { "key": "setting.auto_match_enabled" },
- { "key": "selector", "operand": "source.json" },
- { "key": "selection_empty", "match_all": true },
- { "key": "preceding_text", "operator": "not_regex_contains", "operand": "['\\w]$", "match_all": true },
- { "key": "following_text", "operator": "regex_contains", "operand": "^(?:\t| |]|,|:|\\}|$)", "match_all": true }
- ]
- },
-
- // Auto-pair quotations: "key": "|",
- { "keys": ["\""], "command": "insert_snippet", "args": {"contents": "\"$0\""}, "context":
- [
- { "key": "setting.auto_match_enabled" },
- { "key": "selector", "operand": "source.json" },
- { "key": "selection_empty", "match_all": true },
- { "key": "preceding_text", "operator": "not_regex_contains", "operand": "[\"\\w]$", "match_all": true },
- { "key": "following_text", "operator": "regex_contains", "operand": "^(?:\t| |]|,|:|\\}|$)", "match_all": true }
- ]
- },
-
- // Auto-pair braces: "key": {|},
- { "keys": ["{"], "command": "insert_snippet", "args": {"contents": "{$0}"}, "context":
- [
- { "key": "setting.auto_match_enabled" },
- { "key": "selector", "operand": "source.json" },
- { "key": "selection_empty", "match_all": true },
- { "key": "following_text", "operator": "regex_contains", "operand": "^(?:\t| |]|,|:|\\}|$)", "match_all": true }
- ]
- },
-
- // Auto-pair square brackets: "key": [|],
- { "keys": ["["], "command": "insert_snippet", "args": {"contents": "[$0]"}, "context":
- [
- { "key": "setting.auto_match_enabled" },
- { "key": "selector", "operand": "source.json" },
- { "key": "selection_empty", "match_all": true },
- { "key": "following_text", "operator": "regex_contains", "operand": "^(?:\t| |]|,|:|\\}|$)", "match_all": true }
- ]
- },
-
- // Add indented line in square brackets
- { "keys": ["enter"], "command": "insert_snippet", "args": {"contents": "\n\t$0\n"}, "context":
- [
- { "key": "setting.auto_indent" },
- { "key": "selector", "operand": "source.json" },
- { "key": "selection_empty", "match_all": true },
- { "key": "preceding_text", "operator": "regex_contains", "operand": "\\[$", "match_all": true },
- { "key": "following_text", "operator": "regex_contains", "operand": "^\\]", "match_all": true }
- ]
- },
- { "keys": ["shift+enter"], "command": "insert_snippet", "args": {"contents": "\n\t$0\n"}, "context":
- [
- { "key": "setting.auto_indent" },
- { "key": "selector", "operand": "source.json" },
- { "key": "selection_empty", "match_all": true },
- { "key": "preceding_text", "operator": "regex_contains", "operand": "\\[$", "match_all": true },
- { "key": "following_text", "operator": "regex_contains", "operand": "^\\]", "match_all": true }
- ]
- },
-]
\ No newline at end of file
+ // Auto-pair quotations: "key": '|',
+ { "keys": ["'"], "command": "insert_snippet", "args": {"contents": "'$0'"}, "context":
+ [
+ { "key": "setting.auto_match_enabled" },
+ { "key": "selector", "operand": "source.json" },
+ { "key": "selection_empty", "match_all": true },
+ { "key": "preceding_text", "operator": "not_regex_contains", "operand": "['\\w]$", "match_all": true },
+ { "key": "following_text", "operator": "regex_contains", "operand": "^(?:\t| |]|,|:|\\}|$)", "match_all": true }
+ ]
+ },
+
+ // Auto-pair quotations: "key": "|",
+ { "keys": ["\""], "command": "insert_snippet", "args": {"contents": "\"$0\""}, "context":
+ [
+ { "key": "setting.auto_match_enabled" },
+ { "key": "selector", "operand": "source.json" },
+ { "key": "selection_empty", "match_all": true },
+ { "key": "preceding_text", "operator": "not_regex_contains", "operand": "[\"\\w]$", "match_all": true },
+ { "key": "following_text", "operator": "regex_contains", "operand": "^(?:\t| |]|,|:|\\}|$)", "match_all": true }
+ ]
+ },
+
+ // Auto-pair braces: "key": {|},
+ { "keys": ["{"], "command": "insert_snippet", "args": {"contents": "{$0}"}, "context":
+ [
+ { "key": "setting.auto_match_enabled" },
+ { "key": "selector", "operand": "source.json" },
+ { "key": "selection_empty", "match_all": true },
+ { "key": "following_text", "operator": "regex_contains", "operand": "^(?:\t| |]|,|:|\\}|$)", "match_all": true }
+ ]
+ },
+
+ // Auto-pair square brackets: "key": [|],
+ { "keys": ["["], "command": "insert_snippet", "args": {"contents": "[$0]"}, "context":
+ [
+ { "key": "setting.auto_match_enabled" },
+ { "key": "selector", "operand": "source.json" },
+ { "key": "selection_empty", "match_all": true },
+ { "key": "following_text", "operator": "regex_contains", "operand": "^(?:\t| |]|,|:|\\}|$)", "match_all": true }
+ ]
+ },
+
+ // Add indented line in square brackets
+ { "keys": ["enter"], "command": "insert_snippet", "args": {"contents": "\n\t$0\n"}, "context":
+ [
+ { "key": "setting.auto_indent" },
+ { "key": "selector", "operand": "source.json" },
+ { "key": "selection_empty", "match_all": true },
+ { "key": "preceding_text", "operator": "regex_contains", "operand": "\\[$", "match_all": true },
+ { "key": "following_text", "operator": "regex_contains", "operand": "^\\]", "match_all": true }
+ ]
+ },
+ { "keys": ["shift+enter"], "command": "insert_snippet", "args": {"contents": "\n\t$0\n"}, "context":
+ [
+ { "key": "setting.auto_indent" },
+ { "key": "selector", "operand": "source.json" },
+ { "key": "selection_empty", "match_all": true },
+ { "key": "preceding_text", "operator": "regex_contains", "operand": "\\[$", "match_all": true },
+ { "key": "following_text", "operator": "regex_contains", "operand": "^\\]", "match_all": true }
+ ]
+ },
+]
diff --git a/JSON/Fold.tmPreferences b/JSON/Fold.tmPreferences
deleted file mode 100644
index 09d2cbf5356..00000000000
--- a/JSON/Fold.tmPreferences
+++ /dev/null
@@ -1,27 +0,0 @@
-
-
-
- scope
- source.json
- settings
-
- indentationFoldingEnabled
-
- foldScopes
-
-
- begin
- punctuation.section.sequence.begin
- end
- punctuation.section.sequence.end
-
-
- begin
- punctuation.section.mapping.begin
- end
- punctuation.section.mapping.end
-
-
-
-
-
diff --git a/JSON/Folding Rules - JSON.tmPreferences b/JSON/Folding Rules - JSON.tmPreferences
new file mode 100644
index 00000000000..6fbb72cbbe6
--- /dev/null
+++ b/JSON/Folding Rules - JSON.tmPreferences
@@ -0,0 +1,27 @@
+
+
+
+ scope
+ source.json - (source.json.json-dotnet | source.json.json5 | source.json.jsonc)
+ settings
+
+ indentationFoldingEnabled
+
+ foldScopes
+
+
+ begin
+ punctuation.definition.mapping.begin
+ end
+ punctuation.definition.mapping.end
+
+
+ begin
+ punctuation.definition.sequence.begin
+ end
+ punctuation.definition.sequence.end
+
+
+
+
+
diff --git a/JSON/Folding Rules - JSON5.tmPreferences b/JSON/Folding Rules - JSON5.tmPreferences
new file mode 100644
index 00000000000..a77da66569c
--- /dev/null
+++ b/JSON/Folding Rules - JSON5.tmPreferences
@@ -0,0 +1,31 @@
+
+
+
+ scope
+ source.json.json5
+ settings
+
+ foldScopes
+
+
+ begin
+ punctuation.definition.comment.begin
+ end
+ punctuation.definition.comment.end
+
+
+ begin
+ punctuation.definition.mapping.begin
+ end
+ punctuation.definition.mapping.end
+
+
+ begin
+ punctuation.definition.sequence.begin
+ end
+ punctuation.definition.sequence.end
+
+
+
+
+
diff --git a/JSON/Folding Rules - JSONC.tmPreferences b/JSON/Folding Rules - JSONC.tmPreferences
new file mode 100644
index 00000000000..5c219270eeb
--- /dev/null
+++ b/JSON/Folding Rules - JSONC.tmPreferences
@@ -0,0 +1,31 @@
+
+
+
+ scope
+ source.json.jsonc
+ settings
+
+ foldScopes
+
+
+ begin
+ punctuation.definition.comment.begin
+ end
+ punctuation.definition.comment.end
+
+
+ begin
+ punctuation.definition.mapping.begin
+ end
+ punctuation.definition.mapping.end
+
+
+ begin
+ punctuation.definition.sequence.begin
+ end
+ punctuation.definition.sequence.end
+
+
+
+
+
diff --git a/JSON/Folding Rules - JSON_dotNET.tmPreferences b/JSON/Folding Rules - JSON_dotNET.tmPreferences
new file mode 100644
index 00000000000..6b1b4bd8892
--- /dev/null
+++ b/JSON/Folding Rules - JSON_dotNET.tmPreferences
@@ -0,0 +1,27 @@
+
+
+
+ scope
+ source.json.json-dotnet
+ settings
+
+ indentationFoldingEnabled
+
+ foldScopes
+
+
+ begin
+ punctuation.definition.mapping.begin
+ end
+ punctuation.definition.mapping.end
+
+
+ begin
+ punctuation.definition.sequence.begin
+ end
+ punctuation.definition.sequence.end
+
+
+
+
+
diff --git a/JSON/JSON.sublime-completions b/JSON/JSON.sublime-completions
new file mode 100644
index 00000000000..2bffbac3e4a
--- /dev/null
+++ b/JSON/JSON.sublime-completions
@@ -0,0 +1,27 @@
+{
+ "scope": "source.json",
+ "completions":
+ [
+ {
+ "trigger": "true",
+ "contents": "true",
+ "annotation": "constant.language",
+ "kind": ["snippet", "s", "Snippet"],
+ "details": "literal JSON constant"
+ },
+ {
+ "trigger": "false",
+ "contents": "false",
+ "annotation": "constant.language",
+ "kind": ["snippet", "s", "Snippet"],
+ "details": "literal JSON constant"
+ },
+ {
+ "trigger": "null",
+ "contents": "null",
+ "annotation": "constant.language",
+ "kind": ["snippet", "s", "Snippet"],
+ "details": "literal JSON constant"
+ }
+ ]
+}
diff --git a/JSON/JSON.sublime-settings b/JSON/JSON.sublime-settings
new file mode 100644
index 00000000000..40b58cd7ac7
--- /dev/null
+++ b/JSON/JSON.sublime-settings
@@ -0,0 +1,13 @@
+// Packages/JSON/JSON.sublime-settings
+// Settings - Syntax Specific (Default)
+//
+// This file is being maintained at:
+// https://github.com/sublimehq/Packages/blob/master/JSON/JSON.sublime-settings
+
+
+{
+ "default_extension": "json",
+
+ // whether `on_pre_save_async` events auto-trigger the `json_prettify` command
+ "json.auto_prettify": false
+}
diff --git a/JSON/JSON.sublime-syntax b/JSON/JSON.sublime-syntax
index 9d1aa3aa281..239981a8d96 100644
--- a/JSON/JSON.sublime-syntax
+++ b/JSON/JSON.sublime-syntax
@@ -1,171 +1,534 @@
%YAML 1.2
---
+# YAML Documentation:
+# https://yaml.org/spec/1.2/spec.html
+# Sublime Text Documentation:
+# https://www.sublimetext.com/docs/syntax.html#ver-dev
+# https://www.sublimetext.com/docs/syntax.html#testing:ver-dev
+# https://www.sublimetext.com/docs/scope_naming.html
+# This file is being maintained at:
+# https://github.com/sublimehq/Packages/blob/master/JSON/JSON.sublime-syntax
+
name: JSON
scope: source.json
version: 2
file_extensions:
- json
- - sublime-build
- - sublime-color-scheme
- - sublime-commands
- - sublime-completions
- - sublime-keymap
- - sublime-macro
- - sublime-menu
- - sublime-mousemap
- - sublime-project
- - sublime-settings
- - sublime-theme
- - sublime-workspace
- - ipynb
+ # https://www.json.org/json-en.html
+ # https://datatracker.ietf.org/doc/html/rfc7159
+ # https://www.ecma-international.org/publications-and-standards/standards/ecma-404/
+
+hidden_file_extensions:
+ - .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
+
+ - .markdownlintrc
+ # https://github.com/DavidAnson/markdownlint
+
+ - .tern-config
+ # Tern.js Server Configuration
+ # https://ternjs.net/doc/manual.html#server
+
+ - .tern-project
+ # Tern.js Project Configuration
+ # https://ternjs.net/doc/manual.html#configuration
+
+ - .watchmanconfig
+ # Facebook Watchman
+ # root specific configuration file
+ # https://facebook.github.io/watchman/docs/config.html
+
- Pipfile.lock
+ # Pipfile
+ # https://github.com/pypa/pipfile
+
+ - avsc
+ # Pure JavaScript implementation of the Avro specification
+ # https://github.com/mtth/avsc
+
+ - composer.lock
+ # Composer lock file
+ # https://getcomposer.org/doc/01-basic-usage.md
+
+ - css.map
+ # CSS Source Map
+
+ - geojson
+ # JSON for geographic data structures
+ # https://geojson.org
+ # https://datatracker.ietf.org/wg/geojson/charter/
+ # https://datatracker.ietf.org/doc/html/rfc7946
+
- gltf
+ # glTF Runtime 3D asset delivery
+ # https://www.khronos.com/gltf
+
+ - har
+ # HTTP Archive Format
+
+ - ipynb
+ # Jupyter Notebook, formerly known as iPython Notebook
+ # https://jupyter.org/documentation
+
+ - js.map
+ # JavaScript Source Map
+
+ - jsonld
+ # JSON for Linking Data
+ # https://json-ld.org
+
+ - ldjson
+ # JSON for Linking Data
+ # https://json-ld.org
+
+ - schema
+ # JSON Schema
+ # https://json-schema.org/learn
+
+ - tfstate
+ # Hashicorp Terraform State
+ # https://www.terraform.io/docs/language/state/index.html
+
+ - tfstate.backup
+ # Hashicorp Terraform State
+ # https://www.terraform.io/docs/language/state/index.html
+
+ - topojson
+ # TopoJSON, an extension to GeoJSON
+ # https://github.com/topojson/topojson-specification
+
+ - ts.map
+ # TypeScript Source Map
+
+ - webapp
+ # Web app manifests
+ # https://developer.mozilla.org/en-US/docs/Web/Manifest
+
+ - webmanifest
+ # Web app manifests
+ # https://developer.mozilla.org/en-US/docs/Web/Manifest
first_line_match: |-
(?xi:
- ^ \s* // .*? -\*- .*? \bjson\b .*? -\*- # editorconfig
+ ^ \s* // .*? -\*- .*? \bjson\b .*? -\*- # editorconfig
)
+variables:
+ exponent: (?:[eE][-+]?\d+)
+ pos_integer_decimal: (?:0|[1-9]\d*)
+ html_entity: '&([a-zA-Z0-9]+|#\d+|#[Xx]\h+);'
+ email_domain: '[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?'
+ email_user: '[a-zA-Z0-9.!#$%&''*+/=?^_`{|}~-]+'
+
+########################################################################################################################
+
contexts:
prototype:
- include: comments
main:
- - include: value
+ - match: (?=\S)
+ push:
+ - invalid-remainder
+ - any-else-pop
- value:
- - include: constant
- - include: number
- - include: string
- - include: array
- - include: object
+####[ Helpers ]#########################################################################################################
- 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
+ any:
+ - include: structures
+ - include: values
+
+ any-else-pop:
+ - include: any
+ - include: else-pop
+
+ structures:
+ - include: objects
+ - include: arrays
+
+ values:
+ - include: constants
+ - include: numbers
+ - include: strings
+
+ invalid-remainder:
+ - match: '[,:]'
+ scope: invalid.illegal.unexpected-separator.json
+ - match: '[^,:\s]+'
+ scope: invalid.illegal.unexpected-code-after-first-structure-or-value.json
+
+####[ Prototypes ]######################################################################################################
+
+ else-pop:
+ - match: (?=\S)
+ pop: 1
+
+ eol-pop:
+ - match: '$\n?'
+ pop: 1
+
+####[ Comments ]########################################################################################################
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
+ - include: comment-line
+ - include: comment-block
+
+ comment-line:
+ - match: //
+ push: comment-line-content
+
+ comment-line-content:
+ - meta_include_prototype: false
+ - meta_scope: invalid.illegal.comment.json
+ - include: eol-pop
+
+ comment-block:
+ - match: /\*\*+/
+ scope: invalid.illegal.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
+ push: comment-block-content
+
+ comment-block-content:
+ - meta_include_prototype: false
+ - meta_scope: invalid.illegal.comment.json
+ - match: \*/
+ pop: 1
+
+####[ Constants ]#######################################################################################################
+
+ constants:
+ - include: valid-constants
+ - include: invalid-constants
- constant:
+ valid-constants:
+ - match: \b(?:null)\b
+ scope: constant.language.null.json
+ pop: 1
- match: \b(?:false|true)\b
scope: constant.language.boolean.json
- - match: \bnull\b
- scope: constant.language.null.json
+ pop: 1
- number:
- # handles integer and decimal numbers
- - match: (-?)((?:0|[1-9]\d*)(?:(?:(\.)\d+)(?:[eE][-+]?\d+)?|(?:[eE][-+]?\d+)))
+ invalid-constants:
+ # when erroneously containing upper case letters
+ - match: \b(?i:null)\b
+ scope: invalid.illegal.expected-lower-case-null.json
+ pop: 1
+ - match: \b(?i:false|true)\b
+ scope: invalid.illegal.expected-lower-case-boolean.json
+ pop: 1
+
+####[ Numbers ]#########################################################################################################
+
+ numbers:
+ - include: float
+ - include: integer
+
+ float:
+ - include: decimal-float
+
+ decimal-float:
+ - match: |-
+ (?x:
+ (?:(-)|(\+))?
+ (
+ {{pos_integer_decimal}}
+ (?:
+ (\.)\d+ {{exponent}}? # 1.1 1.1e1 1.1e-1 1.1e+1
+ | {{exponent}} # 1e1 1+e1 1-e1
+ )
+ )
+ )
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*)
+ 1: constant.numeric.sign.json
+ 2: invalid.illegal.numeric-sign.json
+ 3: constant.numeric.value.json
+ 4: punctuation.separator.decimal.json
+ pop: 1
+
+ integer:
+ - include: decimal-integer
+
+ decimal-integer:
+ - match: (?:(-)|(\+))?({{pos_integer_decimal}})
scope: meta.number.integer.decimal.json
captures:
- 1: keyword.operator.arithmetic.json
- 2: constant.numeric.value.json
+ 1: constant.numeric.sign.json
+ 2: invalid.illegal.numeric-sign.json
+ 3: constant.numeric.value.json
+ pop: 1
- 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.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.sequence.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:
+####[ Strings ]#########################################################################################################
+
+ strings:
+ - include: double-quoted-string
+
+ double-quoted-string:
- match: \"
scope: punctuation.definition.string.begin.json
- push: inside-string
+ set: double-quoted-string-content
- inside-string:
- - meta_scope: string.quoted.double.json
+ double-quoted-string-content:
- meta_include_prototype: false
+ - meta_scope: >-
+ meta.string.json
+ string.quoted.double.json
- match: \"
scope: punctuation.definition.string.end.json
pop: 1
- - include: string-escape
+ - include: double-quoted-string-escape-characters
+ - include: links
- match: \n
scope: invalid.illegal.unclosed-string.json
pop: 1
- string-escape:
+ links:
+ - include: autolink-email
+ - include: autolink-inet
+
+ autolink-email:
- 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
+ (?x:
+ (<)
+ (
+ (?:mailto(:))?
+ {{email_user}}
+ (@)
+ {{email_domain}}(?:\.{{email_domain}})*
)
+ (>)
)
- scope: constant.character.escape.json
+ scope: meta.link.email.json
+ captures:
+ 1: punctuation.definition.link.begin.json
+ 2: markup.underline.link.json
+ 3: punctuation.separator.path.json
+ 4: punctuation.separator.path.json
+ 5: punctuation.definition.link.end.json
+ - match: |-
+ (?x:
+ [\w.+-]+
+ (@)
+ [\w-]+(?:\.(?:(?![._-][\W])[\w_-])+)+(?![_-])
+ )
+ scope: >-
+ meta.link.email.json
+ markup.underline.link.json
+ captures:
+ 1: punctuation.separator.path.json
+
+ autolink-inet:
+ - match: <(?=[[:alpha:]][[:alnum:].+-]+:)
+ scope: punctuation.definition.link.begin.json
+ push:
+ - autolink-inet-angled-content
+ - link-url-scheme-separator
+ - match: (?:(?:https|http|ftp)(://)|www\.)[\w-]+
+ captures:
+ 1: punctuation.separator.path.json
+ push: autolink-inet-unquoted-content
+
+ autolink-inet-angled-content:
+ - meta_scope: meta.link.inet.json
+ - meta_content_scope: markup.underline.link.json
+ - match: \>
+ scope: punctuation.definition.link.end.json
+ pop: 1
+ - match: (?=\s)
+ pop: 1
+ - include: autolink-inet-common
+
+ autolink-inet-unquoted-content:
+ - meta_scope: >-
+ meta.link.inet.json
+ markup.underline.link.json
+ - match: (?=(?:\)|(?:{{html_entity}})*)[?!.,:*_~]*[\s<])
+ pop: 1
+ - include: autolink-inet-common
+
+ autolink-inet-group:
+ - match: \)
+ pop: 1
+ - match: (?=(?:{{html_entity}})*[?!.,:*_~]*[\s<])
+ pop: 1
+ - include: autolink-inet-common
+
+ autolink-inet-common:
+ - match: \(
+ push: autolink-inet-group
+ - match: '[/&?#]'
+ scope: punctuation.separator.path.json
+ - match: (%)\h{2}
+ scope: constant.character.escape.url.json
+ captures:
+ 1: punctuation.definition.escape.json
+
+ link-url-scheme-separator:
+ - match: ':/{,2}'
+ scope: punctuation.separator.path.json
+ pop: 1
+
+ double-quoted-string-escape-characters:
+ - match: (\\)\"
+ scope: constant.character.escape.double-quote.json # quotation mark
+ captures:
+ 1: punctuation.definition.escape.json
+ - include: string-escape-characters
+
+ string-escape-characters:
+ - include: valid-string-escape-characters
+ - include: invalid-string-escape-characters
+
+ valid-string-escape-characters:
+ - match: (\\)\\
+ scope: constant.character.escape.back-slash.json # reverse solidus
+ captures:
+ 1: punctuation.definition.escape.json
+ - match: (\\)\/
+ scope: constant.character.escape.forward-slash.json # solidus
+ captures:
+ 1: punctuation.definition.escape.json
+ - match: (\\)b
+ scope: constant.character.escape.backspace.json
+ captures:
+ 1: punctuation.definition.escape.json
+ - match: (\\)f
+ scope: constant.character.escape.form-feed.json
+ captures:
+ 1: punctuation.definition.escape.json
+ - match: (\\)n
+ scope: constant.character.escape.newline.json # linefeed
+ captures:
+ 1: punctuation.definition.escape.json
+ - match: (\\)r
+ scope: constant.character.escape.carriage-return.json
+ captures:
+ 1: punctuation.definition.escape.json
+ - match: (\\)t
+ scope: constant.character.escape.horizontal-tab.json
+ captures:
+ 1: punctuation.definition.escape.json
+ - match: (\\)u[0-9a-fA-F]{4}
+ scope: >-
+ constant.character.escape.unicode-symbol.basic-multilingual-plane.json
+ captures:
+ 1: punctuation.definition.escape.json
+
+ invalid-string-escape-characters:
- match: \\.
scope: invalid.illegal.unrecognized-string-escape.json
+
+####[ Sequences ]#######################################################################################################
+
+ arrays:
+ - match: \[
+ scope: punctuation.definition.sequence.begin.json
+ set:
+ - array-body
+ - array-item
+
+ array-body:
+ - meta_scope: meta.sequence.list.json
+ - match: \]
+ scope: punctuation.definition.sequence.end.json
+ pop: 1
+ - include: array-separators
+
+ array-separators:
+ - match: (?=,)
+ branch_point: array-separators
+ branch:
+ - valid-array-separator
+ - invalid-array-separator
+ - match: (?=\S)
+ push: array-item
+
+ valid-array-separator:
+ - match: ','
+ scope: punctuation.separator.sequence.json
+ set: array-expect-value
+
+ array-expect-value:
+ - match: (?=\])
+ fail: array-separators
+ - include: array-item
+
+ array-item:
+ - include: any
+ - include: invalid-array-separator
+
+ invalid-array-separator:
+ - match: ','
+ scope: invalid.illegal.unexpected-separator.json
+ - include: else-pop
+
+####[ Mappings ]########################################################################################################
+
+ # FIXME: leading separators
+ # FIXME: trailing commas
+
+ objects:
+ - match: \{
+ scope: punctuation.definition.mapping.begin.json
+ set: object-body
+
+ object-body:
+ - 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_include_prototype: false
+ - meta_scope: >-
+ meta.mapping.key.json
+ meta.string.json
+ string.quoted.double.json
+ - include: double-quoted-string-content
+
+ mapping-separator:
+ - match: ':'
+ scope: punctuation.separator.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
+ - any-else-pop
+
+ mapping-value:
+ - clear_scopes: 1
+ - meta_scope: meta.mapping.value.json
+ - match: ','
+ scope: punctuation.separator.sequence.json
+ pop: 1
+ - match: \s*(?=\})
+ pop: 1
+ - match: \s(?!/[/*])(?=[^\s,])|[^\s,]
+ scope: invalid.illegal.expected-mapping-separator.json
+ pop: 1
diff --git a/JSON/JSON5.sublime-completions b/JSON/JSON5.sublime-completions
new file mode 100644
index 00000000000..6cfbd1d9c3d
--- /dev/null
+++ b/JSON/JSON5.sublime-completions
@@ -0,0 +1,48 @@
+{
+ "scope": "source.json.json5",
+ "completions":
+ [
+ {
+ "trigger": "Infinity",
+ "contents": "Infinity",
+ "annotation": "constant.language",
+ "kind": ["snippet", "s", "Snippet"],
+ "details": "JSON5 number
IEEE 754 positive infinity
literal constant \"Infinity\""
+ },
+ {
+ "trigger": "Infinity",
+ "contents": "+Infinity",
+ "annotation": "constant.language",
+ "kind": ["snippet", "s", "Snippet"],
+ "details": "JSON5 number
IEEE 754 positive infinity
literal constant \"Infinity\" with an optional plus as prefix"
+ },
+ {
+ "trigger": "Infinity",
+ "contents": "-Infinity",
+ "annotation": "constant.language",
+ "kind": ["snippet", "s", "Snippet"],
+ "details": "JSON5 number
IEEE 754 negative infinity
literal constant \"-Infinity\""
+ },
+ {
+ "trigger": "NaN",
+ "contents": "NaN",
+ "annotation": "constant.language",
+ "kind": ["snippet", "s", "Snippet"],
+ "details": "JSON5 number
IEEE 754 NaN
literal constant \"NaN\""
+ },
+ {
+ "trigger": "NaN",
+ "contents": "+NaN",
+ "annotation": "constant.language",
+ "kind": ["snippet", "s", "Snippet"],
+ "details": "JSON5 number
IEEE 754 NaN
literal constant \"NaN\" with an optional plus as prefix"
+ },
+ {
+ "trigger": "NaN",
+ "contents": "-NaN",
+ "annotation": "constant.language",
+ "kind": ["snippet", "s", "Snippet"],
+ "details": "JSON5 number
IEEE 754 NaN
literal constant \"NaN\" with an optional minus as prefix"
+ }
+ ]
+}
diff --git a/JSON/JSON5.sublime-settings b/JSON/JSON5.sublime-settings
new file mode 100644
index 00000000000..047cb2547ad
--- /dev/null
+++ b/JSON/JSON5.sublime-settings
@@ -0,0 +1,10 @@
+// Packages/JSON/JSON5.sublime-settings
+// Settings - Syntax Specific (Default)
+//
+// This file is being maintained at:
+// https://github.com/sublimehq/Packages/blob/master/JSON/JSON5.sublime-settings
+
+
+{
+ "default_extension": "json5"
+}
diff --git a/JSON/JSON5.sublime-syntax b/JSON/JSON5.sublime-syntax
new file mode 100644
index 00000000000..ffe7c7a8c1f
--- /dev/null
+++ b/JSON/JSON5.sublime-syntax
@@ -0,0 +1,255 @@
+%YAML 1.2
+---
+# YAML Documentation:
+# https://yaml.org/spec/1.2/spec.html
+# Sublime Text Documentation:
+# https://www.sublimetext.com/docs/syntax.html#ver-dev
+# https://www.sublimetext.com/docs/syntax.html#testing:ver-dev
+# https://www.sublimetext.com/docs/scope_naming.html
+# This file is being maintained at:
+# https://github.com/sublimehq/Packages/blob/master/JSON/JSON5.sublime-syntax
+
+name: JSON5
+scope: source.json.json5
+version: 2
+
+# https://www.sublimetext.com/docs/syntax.html#inheritance
+extends: Packages/JSON/JSONC.sublime-syntax
+
+file_extensions:
+ - json5
+ # https://json5.org/
+ # https://spec.json5.org/#summary-of-features
+ # https://262.ecma-international.org/5.1/
+
+hidden_file_extensions:
+ - .babelrc
+ # Babel.js File-relative Configuration
+ # https://babeljs.io/docs/en/config-files
+
+ - .babelrc.json
+ # Babel.js File-relative Configuration
+ # https://babeljs.io/docs/en/config-files
+
+ - .jupyterlab-settings
+ # JupyterLab User Settings
+ # https://jupyterlab.readthedocs.io/en/stable/user/directories.html?highlight=json5#jupyterlab-user-settings-directory
+
+ - .parcelrc
+ # parcel Bundler Configuration
+ # https://github.com/parcel-bundler/parcel
+ # https://parceljs.org/features/plugins/#.parcelrc
+
+ - .postcssrc.json
+ # PostCSS Configuration
+ # https://postcss.org
+
+ - babel.config.json
+ # Babel.js Project-wide Configuration
+ # https://babeljs.io/docs/en/config-files
+
+ - next.config.json
+ # Vercel Next.js Configuration
+ # https://nextjs.org/docs/api-reference/next.config.js/introduction
+
+ - nextrc.json
+ # Vercel Next.js Configuration
+ # https://nextjs.org/docs/api-reference/next.config.js/introduction
+
+ - techdocs_metadata.json
+ # Spotify's @backstage/techdocs_common Configuration
+ # https://github.com/backstage/backstage/tree/master/packages/techdocs-common
+ # https://backstage.io/docs/features/techdocs/techdocs-overview
+
+first_line_match: |-
+ (?xi:
+ ^ \s* // .*? -\*- .*? \bjson5\b .*? -\*- # editorconfig
+ )
+
+variables:
+
+ # Boost documentation:
+ # https://www.boost.org/doc/libs/1_64_0/libs/regex/doc/html/boost_regex/syntax/perl_syntax.html
+ # Unicode documentation:
+ # https://www.unicode.org/versions/latest/
+ # https://www.unicode.org/Public/UCD/latest/ucd/
+ # Oniguruma documentation:
+ # https://github.com/kkos/oniguruma/blob/master/doc/RE
+ # https://github.com/kkos/oniguruma/blob/master/doc/UNICODE_PROPERTIES
+
+ identifier_escape: (?:\\u(?:\h{4}|\{\h+\}))
+ identifier_start: (?:[_$\p{L}\p{Nl}]|{{identifier_escape}})
+ identifier_part: (?:[_$\p{L}\p{Nl}\p{Mn}\p{Mc}\p{Nd}\p{Pc}\x{200C}\x{200D}]|{{identifier_escape}})
+ identifier_break: (?!{{identifier_part}})
+
+ identifier_name: (?:{{identifier_start}}{{identifier_part}}*{{identifier_break}})
+
+########################################################################################################################
+
+contexts:
+
+ # TODO: check whitespace valid chars
+
+####[ Numbers ]#########################################################################################################
+
+ decimal-float:
+ - match: |-
+ (?x:
+ ([-+]?)
+ (
+ {{pos_integer_decimal}}
+ (?:
+ (\.)\d* {{exponent}}? # 1. 1.e1 1.e-1 1.e+1 1.1 1.1e1 1.1e-1 1.1e+1
+ | {{exponent}} # 1e1 1+e1 1-e1
+ )
+ | (\.)\d+ {{exponent}}? # .1 .1e1 .1e+1 .1e-1
+ )
+ )
+ scope: meta.number.float.decimal.json5
+ captures:
+ 1: constant.numeric.sign.json5
+ 2: constant.numeric.value.json5
+ 3: punctuation.separator.decimal.json5
+ 4: punctuation.separator.decimal.json5
+ pop: 1
+ - match: ([-+]?)(Infinity)
+ scope: meta.number.float.decimal.json5
+ captures:
+ 1: constant.numeric.sign.json5
+ 2: constant.language.infinity.json5
+ pop: 1
+ - match: ([-+]?)(NaN)
+ scope: meta.number.float.decimal.json5
+ captures:
+ 1: constant.numeric.sign.json5
+ 2: constant.language.nan.json5
+ pop: 1
+
+ # when erroneously containing wrongly cased letters
+ - match: ([-+]?)(?i:(infinity))
+ scope: meta.number.float.decimal.json5
+ captures:
+ 1: constant.numeric.sign.json5
+ 2: invalid.illegal.expected-language-constant.json5
+ pop: 1
+ - match: ([-+]?)(?i:(nan))
+ scope: meta.number.float.decimal.json5
+ captures:
+ 1: constant.numeric.sign.json5
+ 2: invalid.illegal.expected-language-constant.json5
+ pop: 1
+
+ integer:
+ - meta_prepend: true
+ - include: hexadecimal-integer
+
+ decimal-integer:
+ - match: ([-+]?)({{pos_integer_decimal}})
+ scope: meta.number.integer.decimal.json5
+ captures:
+ 1: constant.numeric.sign.json5
+ 2: constant.numeric.value.json5
+ pop: 1
+
+ hexadecimal-integer:
+ - match: ([-+]?)(0[xX])(\h+)
+ scope: meta.number.integer.hexadecimal.json5
+ captures:
+ 1: constant.numeric.sign.json5
+ 2: constant.numeric.base.json5
+ 3: constant.numeric.value.json5
+ pop: 1
+
+####[ Strings ]#########################################################################################################
+
+ strings:
+ - meta_append: true
+ - include: single-quoted-string
+
+ single-quoted-string:
+ - match: \'
+ scope: punctuation.definition.string.begin.json5
+ set: single-quoted-string-content
+
+ single-quoted-string-content:
+ - meta_include_prototype: false
+ - meta_scope: >-
+ meta.string.json5
+ string.quoted.single.json5
+ - match: \'
+ scope: punctuation.definition.string.end.json5
+ pop: 1
+ - include: single-quoted-string-escape-characters
+ - match: \n
+ scope: invalid.illegal.unclosed-string.json5
+ pop: 1
+
+ single-quoted-string-escape-characters:
+ - match: \\\'
+ scope: constant.character.escape.single-quote.json5
+ - include: string-escape-characters
+
+ valid-string-escape-characters:
+ - meta_prepend: true
+ - match: ((\\)\x{2028})(.*)$\n?
+ captures:
+ 1: constant.character.escape.line-separator.json5
+ 2: punctuation.separator.continuation.line.json5
+ 3: invalid.illegal.expected-eol-after-line-continuation.json5
+ - match: ((\\)\x{2029})(.*)$\n?
+ captures:
+ 1: constant.character.escape.paragraph-separator.json5
+ 2: punctuation.separator.continuation.line.json5
+ 3: invalid.illegal.expected-eol-after-line-continuation.json5
+ - match: (\\)$\n?
+ captures:
+ 1: punctuation.separator.continuation.line.json5
+ - match: \\v
+ scope: constant.character.escape.vertical-tab.json5
+ - match: (\\0)([0-9])?
+ captures:
+ 1: constant.character.escape.null.json5
+ 2: invalid.illegal.unexpected-digit-character.json5
+ - match: \\x[0-9a-fA-F]{2}
+ scope: constant.character.escape.unicode-symbol.basic-latin-or-latin-1-supplement.json5
+ - match: \\u[0-9a-fA-F]{4}\\u[0-9a-fA-F]{4}
+ scope: constant.character.escape.unicode-symbol.utf16-surrogate-pair.json5
+
+ invalid-string-escape-characters:
+ - meta_prepend: true
+ - match: ([^\\])(?:\x{2028}|\x{2029})
+ captures:
+ 1: invalid.illegal.expected-backslash-char.json5
+
+####[ Mappings ]########################################################################################################
+
+ mapping-key:
+ - meta_append: true
+ - match: \'
+ scope: punctuation.definition.string.begin.json5
+ push: mapping-key-single-quoted
+
+ # looking ahead at `identifier_start` would've been faster with possibly
+ # invalid matches, but we want to make sure we only match valid ecma
+ # `identifier_name`s as keys
+ - match: (?={{identifier_name}})
+ push: mapping-key-ecma
+
+ mapping-key-ecma:
+ - clear_scopes: 1
+ - meta_include_prototype: false
+ - meta_scope: >-
+ meta.mapping.key.json5
+ meta.string.json5
+ string.unquoted.plain.json5
+ - match: '{{identifier_break}}'
+ pop: 1
+
+ mapping-key-single-quoted:
+ - clear_scopes: 1
+ - meta_include_prototype: false
+ - meta_scope: >-
+ meta.mapping.key.json5
+ meta.string.json5
+ string.quoted.single.json5
+ - include: single-quoted-string-content
diff --git a/JSON/JSONC.sublime-settings b/JSON/JSONC.sublime-settings
new file mode 100644
index 00000000000..9bd53bcb1f2
--- /dev/null
+++ b/JSON/JSONC.sublime-settings
@@ -0,0 +1,10 @@
+// Packages/JSON/JSONC.sublime-settings
+// Settings - Syntax Specific (Default)
+//
+// This file is being maintained at:
+// https://github.com/sublimehq/Packages/blob/master/JSON/JSONC.sublime-settings
+
+
+{
+ "default_extension": "jsonc"
+}
diff --git a/JSON/JSONC.sublime-syntax b/JSON/JSONC.sublime-syntax
new file mode 100644
index 00000000000..280dccc816a
--- /dev/null
+++ b/JSON/JSONC.sublime-syntax
@@ -0,0 +1,136 @@
+%YAML 1.2
+---
+# YAML Documentation:
+# https://yaml.org/spec/1.2/spec.html
+# Sublime Text Documentation:
+# https://www.sublimetext.com/docs/syntax.html#ver-dev
+# https://www.sublimetext.com/docs/syntax.html#testing:ver-dev
+# https://www.sublimetext.com/docs/scope_naming.html
+# This file is being maintained at:
+# https://github.com/sublimehq/Packages/blob/master/JSON/JSONC.sublime-syntax
+
+name: JSONC
+scope: source.json.jsonc
+version: 2
+
+# https://www.sublimetext.com/docs/syntax.html#inheritance
+extends: Packages/JSON/JSON.sublime-syntax
+
+file_extensions:
+ - jsonc
+
+ - sublime-build # https://www.sublimetext.com/docs/build_systems.html
+ - sublime-color-scheme # https://www.sublimetext.com/docs/color_schemes.html
+ - sublime-commands
+ - sublime-completions # https://www.sublimetext.com/docs/completions.html
+ - sublime-keymap # https://www.sublimetext.com/docs/key_bindings.html
+ - sublime-macro
+ - sublime-menu # https://www.sublimetext.com/docs/menus.html
+ - sublime-mousemap
+ - sublime-project # https://www.sublimetext.com/docs/projects.html
+ - sublime-settings # https://www.sublimetext.com/docs/settings.html
+ - sublime-theme # https://www.sublimetext.com/docs/themes.html
+ - sublime-workspace # https://www.sublimetext.com/docs/projects.html
+
+hidden_file_extensions:
+ - .ember-cli
+
+ - .esformatter
+ # esformatter: ECMAScript code formatter
+ # https://github.com/millermedeiros/esformatter
+
+ - .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
+
+ - .jsfmtrc
+ # jsfmt: For formatting, searching and re-writing JavaScript
+ # https://github.com/rdio/jsfmt#formatting
+
+ - .jshintrc
+ # JSHint
+ # https://www.jshint.com/docs/#options
+
+ - .jslintrc
+ # JSLint's implementation of JSHint
+ # https://www.jslint.com/lint.html
+
+ - .stylintrc
+ # stylint Configuration
+ # https://github.com/SimenB/stylint
+
+ - .swcrc
+ # swc Configuration
+ # https://swc.rs/docs/configuring-swc
+
+ - eslintrc.json
+ # ESLint Configuration
+ # https://eslint.org/docs/user-guide/configuring/
+
+ - languagebabel
+
+ - tsconfig.json
+ # TypeScript Configuration
+ # https://www.typescriptlang.org/docs/handbook/tsconfig-json.html
+
+first_line_match: |-
+ (?xi:
+ ^ \s* // .*? -\*- .*? \bjsonc\b .*? -\*- # editorconfig
+ )
+
+########################################################################################################################
+
+contexts:
+
+####[ Comments ]########################################################################################################
+
+ comment-line:
+ - match: //
+ scope: punctuation.definition.comment.jsonc
+ push: comment-line-content
+
+ comment-line-content:
+ - meta_include_prototype: false
+ - meta_scope: comment.line.double-slash.jsonc
+ - include: eol-pop
+
+ comment-block:
+ # empty block comments
+ - match: (/\*)\**(\*/)
+ scope: comment.block.empty.jsonc
+ captures:
+ 1: punctuation.definition.comment.begin.jsonc
+ 2: punctuation.definition.comment.end.jsonc
+ # normal block comments
+ - match: /\*
+ scope: punctuation.definition.comment.begin.jsonc
+ push: comment-block-content
+
+ comment-block-content:
+ - meta_include_prototype: false
+ - meta_scope: comment.block.jsonc
+ - include: comment-block-end
+
+ comment-block-end:
+ - match: \*/
+ scope: punctuation.definition.comment.end.jsonc
+ pop: 1
+
+####[ Sequences ]#######################################################################################################
+
+ array-separators:
+ - match: ','
+ scope: punctuation.separator.sequence.jsonc
+ push: array-item
diff --git a/JSON/JSON_dotNET.sublime-syntax b/JSON/JSON_dotNET.sublime-syntax
new file mode 100644
index 00000000000..cd20d59dbae
--- /dev/null
+++ b/JSON/JSON_dotNET.sublime-syntax
@@ -0,0 +1,106 @@
+%YAML 1.2
+---
+# YAML Documentation:
+# https://yaml.org/spec/1.2/spec.html
+# Sublime Text Documentation:
+# https://www.sublimetext.com/docs/syntax.html#ver-dev
+# https://www.sublimetext.com/docs/syntax.html#testing:ver-dev
+# https://www.sublimetext.com/docs/scope_naming.html
+# This file is being maintained at:
+# https://github.com/sublimehq/Packages/blob/master/JSON/JSON_dotNET.sublime-syntax
+#
+# Date formatting:
+# https://www.iso.org/standard/70907.html (Basic rules)
+# https://www.iso.org/standard/70908.html (Extensions)
+# https://docs.microsoft.com/en-us/dotnet/standard/base-types/custom-date-and-time-format-strings
+
+name: 'JSON .NET'
+scope: source.json.json-dotnet
+version: 2
+
+# https://www.sublimetext.com/docs/syntax.html#inheritance
+extends: Packages/JSON/JSON.sublime-syntax
+
+first_line_match: |-
+ (?xi:
+ ^ \s* // .*? -\*- .*? \bjson\.net\b .*? -\*- # editorconfig
+ )
+
+########################################################################################################################
+
+contexts:
+
+####[ Strings ]#########################################################################################################
+
+ strings:
+ - meta_prepend: true
+ - include: datetime-string
+
+ datetime-string:
+
+ # for date strings of json.Net v4.5+ with an ISO Date
+ # like "2000-01-01T00:00:00Z"
+ - match: |-
+ (?x:
+ (\")
+ (
+ \d{4} [-] \d{2} [-] \d{2}
+ [Tt]
+ \d{2} [:] \d{2} [:] \d{2}
+ (?:
+ Z | [-+] \d{1,2} (?: [:]\d{1,2})?
+ )?
+ )
+ (\")
+ )
+ scope: >-
+ meta.string.json-dotnet
+ string.quoted.double.datetime.json-dotnet
+ captures:
+ 1: punctuation.definition.string.begin.json-dotnet
+ 2: constant.other.timestamp.json-dotnet
+ 3: punctuation.definition.string.end.json-dotnet
+
+ # for date strings (of the old discontinued format) erroneously containing
+ # double escapes like "\/Date(1234)\/"
+ - match: |-
+ (?x:
+ (\")
+ (
+ (\\)
+ \/Date\(
+ \d+
+ \)
+ (\\)
+ \/
+ )
+ (\")
+ )
+ scope: >-
+ meta.string.json-dotnet
+ string.quoted.double.datetime.json-dotnet
+ captures:
+ 1: punctuation.definition.string.begin.json-dotnet
+ 2: constant.other.timestamp.json-dotnet
+ 3: invalid.illegal.double-escape.json-dotnet
+ 4: invalid.illegal.double-escape.json-dotnet
+ 5: punctuation.definition.string.end.json-dotnet
+
+ # the old discontinued format like "/Date(1234)/"
+ - match: |-
+ (?x:
+ (\")
+ (
+ \/Date\(
+ \d+
+ \)\/
+ )
+ (\")
+ )
+ scope: >-
+ meta.string.json-dotnet
+ string.quoted.double.datetime.json-dotnet
+ captures:
+ 1: punctuation.definition.string.begin.json-dotnet
+ 2: constant.other.timestamp.json-dotnet
+ 3: punctuation.definition.string.end.json-dotnet
diff --git a/JSON/Main.sublime-menu b/JSON/Main.sublime-menu
new file mode 100644
index 00000000000..fe6d5172c22
--- /dev/null
+++ b/JSON/Main.sublime-menu
@@ -0,0 +1,130 @@
+// Packages/JSON/Main.sublime-menu
+//
+// This file is being maintained at:
+// https://github.com/sublimehq/Packages/blob/master/JSON/Main.sublime-menu
+
+
+[
+ {
+ "id": "preferences",
+ "children":
+ [
+ {
+ "id": "package-settings",
+ "children":
+ [
+ {
+ "caption": "JSON",
+ "children":
+ [
+ {
+ "caption": "JSON",
+ "children":
+ [
+ {
+ "caption": "Minify",
+ "command": "json_minify"
+ },
+ {
+ "caption": "Prettify",
+ "command": "json_prettify"
+ },
+ { "caption": "-" },
+ {
+ "caption": "Automatically prettify before saving",
+ "command": "json_toggle_auto_prettify"
+ },
+ {
+ "caption": "Settings - Syntax Specific",
+ "command": "edit_settings",
+ "args":
+ {
+ "base_file": "${packages}/JSON/JSON.sublime-settings",
+ "default": "{\n\t$0\n}\n"
+ }
+ },
+ { "caption": "-" },
+ {
+ "caption": "Documentation: Specs",
+ "command": "open_url",
+ "args":
+ {
+ "url": "https://www.json.org/json-en.html"
+ }
+ },
+ {
+ "caption": "Documentation: RFC 7159",
+ "command": "open_url",
+ "args":
+ {
+ "url": "https://datatracker.ietf.org/doc/html/rfc7159"
+ }
+ },
+ {
+ "caption": "Documentation: ECMA 404",
+ "command": "open_url",
+ "args":
+ {
+ "url": "https://www.ecma-international.org/publications-and-standards/standards/ecma-404/"
+ }
+ }
+ ]
+ },
+ {
+ "caption": "JSONC (JSON with Comments)",
+ "children":
+ [
+ {
+ "caption": "Minify",
+ "command": "jsonc_minify"
+ },
+ {
+ "caption": "Prettify",
+ "command": "jsonc_prettify"
+ }
+ ]
+ },
+ {
+ "caption": "JSON5",
+ "children":
+ [
+ {
+ "caption": "Documentation: Specs",
+ "command": "open_url",
+ "args":
+ {
+ "url": "https://spec.json5.org/#summary-of-features"
+ }
+ }
+ ]
+ },
+ { "caption": "-" },
+ {
+ "caption": "Support",
+ "children":
+ [
+ {
+ "caption": "Changelog (Packages/JSON)",
+ "command": "open_url",
+ "args":
+ {
+ "url": "https://github.com/sublimehq/Packages/commits/master/JSON"
+ }
+ },
+ {
+ "caption": "Report a (JSON package) issue",
+ "command": "open_url",
+ "args":
+ {
+ "url": "https://github.com/sublimehq/Packages/issues"
+ }
+ }
+ ]
+ }
+ ]
+ }
+ ]
+ }
+ ]
+ }
+]
diff --git a/JSON/Symbol List.tmPreferences b/JSON/Symbol List.tmPreferences
new file mode 100644
index 00000000000..22c59c8cf92
--- /dev/null
+++ b/JSON/Symbol List.tmPreferences
@@ -0,0 +1,14 @@
+
+
+
+ scope
+ source.json meta.mapping.key - (meta.mapping.value meta.mapping.key | meta.sequence.list meta.mapping.key)
+ settings
+
+ showInSymbolList
+ 1
+ showInIndexedSymbolList
+ 1
+
+
+
diff --git a/JSON/main.py b/JSON/main.py
new file mode 100644
index 00000000000..8ddf5603bdb
--- /dev/null
+++ b/JSON/main.py
@@ -0,0 +1,18 @@
+#!/usr/bin/env python
+# coding: utf-8
+
+# This file is being maintained at:
+# https://github.com/sublimehq/Packages/blob/master/JSON/main.py
+
+
+import sublime
+
+from .src import *
+
+
+def plugin_loaded() -> None:
+ json_prettify.plugin_loaded()
+
+
+def plugin_unloaded() -> None:
+ json_prettify.plugin_unloaded()
diff --git a/JSON/src/__init__.py b/JSON/src/__init__.py
new file mode 100644
index 00000000000..181339e8b50
--- /dev/null
+++ b/JSON/src/__init__.py
@@ -0,0 +1,9 @@
+#!/usr/bin/env python
+# coding: utf-8
+
+# This file is being maintained at:
+# https://github.com/sublimehq/Packages/blob/master/JSON/src/__init__.py
+
+
+from .json_prettify import *
+from .jsonc_prettify import *
diff --git a/JSON/src/json_prettify.py b/JSON/src/json_prettify.py
new file mode 100644
index 00000000000..87edd9af8e5
--- /dev/null
+++ b/JSON/src/json_prettify.py
@@ -0,0 +1,217 @@
+#!/usr/bin/env python
+# coding: utf-8
+
+# This file is being maintained at:
+# https://github.com/sublimehq/Packages/blob/master/JSON/src/json_prettify.py
+
+
+import sublime
+import sublime_plugin
+
+from __future__ import annotations
+import collections
+import decimal
+import json
+from typing import (
+ Union
+)
+
+
+PKG_NAME: str = __package__.split('.')[0]
+settings: Union[sublime.Settings, None] = None
+base_settings: str = 'JSON.sublime-settings'
+base_scope: str = 'source.json - (source.json.json-dotnet | source.json.json5 | source.json.jsonc)'
+
+
+def status_msg(msg: str = '') -> None:
+ if msg == '': return
+ sublime.status_message(f'{PKG_NAME}: {msg}')
+
+
+def print_msg(msg_header: str = '', msg_body: str = '') -> None:
+ if msg_body == '': return
+ print(f'JSON: {msg_header}:\n\n{msg_body}\n\n')
+
+
+def json2py(view: sublime.View) -> sublime.Value:
+ old_contents: str = view.substr(
+ x=whole_view(view)
+ )
+ try:
+ return json.loads( # https://docs.python.org/3.8/library/json.html#json.loads
+ s=old_contents,
+ object_pairs_hook=collections.OrderedDict,
+ parse_float=decimal.Decimal
+ )
+ except Exception as e:
+ print_msg(
+ msg_header='Conversion failed due to error:',
+ msg_body=f'{e}'
+ )
+ return None
+
+
+def whole_view(view: sublime.View) -> sublime.Region:
+ return sublime.Region(
+ a=0,
+ b=view.size()
+ )
+
+
+def is_json(view: sublime.View) -> bool:
+ return view.match_selector(
+ pt=0,
+ selector=base_scope
+ )
+
+
+def plugin_loaded(reload: bool = False) -> None:
+ try:
+ global settings
+ settings = sublime.load_settings(base_name=base_settings)
+ settings.clear_on_change(tag='reload')
+ settings.add_on_change(
+ tag='reload',
+ callback=lambda: plugin_loaded(reload=True)
+ )
+ except Exception as e:
+ print_msg(
+ msg_header=f'Loading "{base_settings}" failed due to error',
+ msg_body=f'{e}'
+ )
+
+ if reload:
+ status_msg('Reloaded settings on change.')
+
+
+def plugin_unloaded() -> None:
+ global settings
+ settings = None
+
+
+class JsonToggleAutoPrettify(sublime_plugin.WindowCommand):
+
+ _is_checked: bool = False
+ _key: str = 'json.auto_prettify'
+
+ def __init__(self, window: sublime.Window) -> None:
+ self.window: sublime.Window = window
+
+ try:
+ if settings is None:
+ return
+ self._is_checked = settings.get(key=self._key, default=False)
+ except Exception:
+ pass
+
+ def run(self) -> None:
+ try:
+ global settings
+ if settings is None:
+ return
+ if self._is_checked:
+ settings.erase(key=self._key) # remove the override (true) of the default (false)
+ else:
+ settings.set(key=self._key, value=True)
+ sublime.save_settings(base_name=base_settings)
+ self._is_checked = not self._is_checked # toggle
+ except Exception:
+ pass
+
+ def is_checked(self) -> bool:
+ return self._is_checked
+
+
+class JsonAutoPrettifyListener(sublime_plugin.EventListener):
+
+ _key: str = 'json.auto_prettify'
+
+ def on_pre_save_async(self, view) -> None:
+ if not is_json(view):
+ return
+ if settings is None:
+ return
+ if not settings.get(key=self._key, default=False):
+ return
+ view.run_command(cmd='json_prettify')
+
+
+class JsonPrettify(sublime_plugin.TextCommand):
+
+ def run(self, edit_token: sublime.Edit) -> None:
+ """
+ Attempt to prettify the current view's JSON contents. Print errors to
+ the console when it fails.
+ """
+
+ try:
+ json_as_python: sublime.Value = json2py(self.view)
+ if json_as_python is None: return
+ self.view.replace(
+ edit_token,
+ r=whole_view(self.view),
+ text=json.dumps( # https://docs.python.org/3.8/library/json.html#json.dumps
+ obj=json_as_python,
+ allow_nan=False,
+ indent=4,
+ sort_keys=True
+ )
+ )
+ status_msg('Prettified.')
+ except Exception as e:
+ print_msg(
+ msg_header='Conversion failed due to error',
+ msg_body=f'{e}'
+ )
+ status_msg('Prettifying failed. See console for details.')
+ pass
+
+ def is_enabled(self) -> bool:
+ return is_json(self.view)
+
+ def is_visible(self) -> bool:
+ return is_json(self.view)
+
+ def description(self) -> str:
+ return 'Prettify JSON'
+
+
+class JsonMinify(sublime_plugin.TextCommand):
+
+ def run(self, edit_token: sublime.Edit) -> None:
+ """
+ Attempt to minify the current view's JSON contents. Print errors to
+ the console when it fails.
+ """
+
+ try:
+ json_as_python: sublime.Value = json2py(self.view)
+ if json_as_python is None: return
+ self.view.replace(
+ edit_token,
+ r=whole_view(self.view),
+ text=json.dumps( # https://docs.python.org/3.8/library/json.html#json.dumps
+ obj=json_as_python,
+ allow_nan=False,
+ indent=None,
+ separators=(',', ':'),
+ sort_keys=True
+ )
+ )
+ status_msg('Minified.')
+ except Exception as e:
+ print_msg(
+ msg_header='Conversion failed due to error',
+ msg_body=f'{e}'
+ )
+ status_msg('Minifying failed. See console for details.')
+ pass
+
+ def is_enabled(self) -> bool:
+ return is_json(self.view)
+
+ def is_visible(self) -> bool:
+ return is_json(self.view)
+
+ def description(self) -> str:
+ return 'Minify JSON'
diff --git a/JSON/src/jsonc_prettify.py b/JSON/src/jsonc_prettify.py
new file mode 100644
index 00000000000..40a4a3c5b3d
--- /dev/null
+++ b/JSON/src/jsonc_prettify.py
@@ -0,0 +1,140 @@
+#!/usr/bin/env python
+# coding: utf-8
+
+# This file is being maintained at:
+# https://github.com/sublimehq/Packages/blob/master/JSON/src/jsonc_prettify.py
+
+
+import sublime
+import sublime_plugin
+
+from __future__ import annotations
+import json
+
+
+PKG_NAME: str = __package__.split('.')[0]
+base_scope: str = 'source.json.jsonc'
+
+
+def status_msg(msg: str = '') -> None:
+ if msg == '': return
+ sublime.status_message(f'{PKG_NAME}: {msg}')
+
+
+def print_msg(msg_header: str = '', msg_body: str = '') -> None:
+ if msg_body == '': return
+ print(f'JSONC: {msg_header}:\n\n{msg_body}\n\n')
+
+
+def json2py(view: sublime.View) -> sublime.Value:
+ old_contents: str = view.substr(
+ x=whole_view(view)
+ )
+ return sublime.decode_value(
+ data=old_contents
+ )
+
+
+def whole_view(view: sublime.View) -> sublime.Region:
+ return sublime.Region(
+ a=0,
+ b=view.size()
+ )
+
+
+def is_jsonc(view: sublime.View) -> bool:
+ return view.match_selector(
+ pt=0,
+ selector=base_scope
+ )
+
+
+class JsoncPrettify(sublime_plugin.TextCommand):
+
+ def run(self, edit_token: sublime.Edit, auto: bool = False) -> None:
+ """
+ Attempt to prettify the current view's JSONC contents. Print errors to
+ the console when it fails.
+ """
+
+ try:
+ if not auto and not sublime.ok_cancel_dialog(
+ msg='Prettifying JSONC will remove included comments and trailing commas.',
+ ok_title='Continue',
+ title='JSONC: Prettify' # only shown on Windows
+ ):
+ return
+ json_as_python: sublime.Value = json2py(self.view)
+ self.view.replace(
+ edit_token,
+ r=whole_view(self.view),
+ text=json.dumps( # https://docs.python.org/3.8/library/json.html#json.dumps
+ obj=json_as_python,
+ allow_nan=False,
+ indent=4,
+ sort_keys=True
+ )
+ )
+ status_msg('Prettified.')
+ except Exception as e:
+ print_msg(
+ msg_header='Conversion failed due to error',
+ msg_body=f'{e}'
+ )
+ status_msg('Prettifying failed. See console for details.')
+ pass
+
+ def is_enabled(self) -> bool:
+ return is_jsonc(self.view)
+
+ def is_visible(self) -> bool:
+ return is_jsonc(self.view)
+
+ def description(self) -> str:
+ return 'Prettify JSONC'
+
+
+class JsoncMinify(sublime_plugin.TextCommand):
+
+ def run(self, edit_token: sublime.Edit, auto: bool = False) -> None:
+ """
+ Attempt to minify the current view's JSONC contents. Print errors to
+ the console when it fails.
+ """
+
+ try:
+ if not auto and not sublime.ok_cancel_dialog(
+ msg='Minifying JSONC will remove included comments and trailing commas.',
+ ok_title='Continue',
+ title='JSONC: Minify' # only shown on Windows
+ ):
+ return
+ json_as_python: sublime.Value = json2py(self.view)
+ self.view.replace(
+ edit_token,
+ r=whole_view(self.view),
+ text=json.dumps( # https://docs.python.org/3.8/library/json.html#json.dumps
+ obj=json_as_python,
+ allow_nan=False,
+ indent=None,
+ separators=(',', ':'),
+ sort_keys=True
+ )
+ )
+ status_msg('Minified.')
+ except Exception as e:
+ print_msg(
+ msg_header='Conversion failed due to error',
+ msg_body=f'{e}'
+ )
+ status_msg('Minifying failed. See console for details.')
+ pass
+
+ def is_enabled(self) -> bool:
+ return is_jsonc(self.view)
+
+ def is_visible(self) -> bool:
+ return is_jsonc(self.view)
+
+ def description(self) -> str:
+ return 'Minify JSONC'
diff --git a/JSON/syntax_test_json.json b/JSON/syntax_test_json.json
deleted file mode 100644
index ae0760eb3fb..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.sequence.json
-//^ invalid.illegal.expected-mapping-key.json
-
- "sep": {},
-// ^ punctuation.separator.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.sequence.json
- "foo": "bar"
- /* comment */
-// ^ - invalid
-// ^^^^^^^^^^^^^ comment.block.json
- },
-//^ punctuation.section.mapping.end.json
-// ^ punctuation.separator.sequence.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.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.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/Markdown/Markdown.sublime-syntax b/Markdown/Markdown.sublime-syntax
index 64ee99ad7b7..fd47d68c828 100644
--- a/Markdown/Markdown.sublime-syntax
+++ b/Markdown/Markdown.sublime-syntax
@@ -910,7 +910,9 @@ contexts:
- include: fenced-html
- include: fenced-java
- include: fenced-javascript
+ - include: fenced-json5
- include: fenced-jsonc
+ - include: fenced-json
- include: fenced-jspx
- include: fenced-jsx
- include: fenced-lisp
@@ -1258,11 +1260,49 @@ contexts:
0: meta.code-fence.definition.end.javascript.markdown-gfm
1: punctuation.definition.raw.code-fence.end.markdown
+ fenced-json5:
+ - match: |-
+ (?x)
+ {{fenced_code_block_start}}
+ ((?i:json5))
+ {{fenced_code_block_trailing_infostring_characters}}
+ captures:
+ 0: meta.code-fence.definition.begin.json5.markdown-gfm
+ 2: punctuation.definition.raw.code-fence.begin.markdown
+ 5: constant.other.language-name.markdown
+ embed: scope:source.json.json5
+ embed_scope:
+ markup.raw.code-fence.json5.markdown-gfm
+ source.json.json5
+ escape: '{{fenced_code_block_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?))
+ ((?i:jsonc))
+ {{fenced_code_block_trailing_infostring_characters}}
+ captures:
+ 0: meta.code-fence.definition.begin.jsonc.markdown-gfm
+ 2: punctuation.definition.raw.code-fence.begin.markdown
+ 5: constant.other.language-name.markdown
+ embed: scope:source.json.jsonc
+ embed_scope:
+ markup.raw.code-fence.jsonc.markdown-gfm
+ source.json.jsonc
+ escape: '{{fenced_code_block_escape}}'
+ escape_captures:
+ 0: meta.code-fence.definition.end.jsonc.markdown-gfm
+ 1: punctuation.definition.raw.code-fence.end.markdown
+
+ fenced-json:
+ - match: |-
+ (?x)
+ {{fenced_code_block_start}}
+ ((?i:json))
{{fenced_code_block_trailing_infostring_characters}}
captures:
0: meta.code-fence.definition.begin.json.markdown-gfm
diff --git a/Markdown/tests/syntax_test_markdown.md b/Markdown/tests/syntax_test_markdown.md
index d7e6ec89173..d9f6b9b9b52 100644
--- a/Markdown/tests/syntax_test_markdown.md
+++ b/Markdown/tests/syntax_test_markdown.md
@@ -1862,6 +1862,27 @@ for (var i = 0; i < 10; i++) {
| <- meta.code-fence.definition.end.jsx.markdown-gfm punctuation.definition.raw.code-fence.end.markdown
|^^ meta.code-fence.definition.end.jsx.markdown-gfm punctuation.definition.raw.code-fence.end.markdown
+```json5
+
+| <- markup.raw.code-fence.json5.markdown-gfm
+```
+| <- meta.code-fence.definition.end.json5.markdown-gfm punctuation.definition.raw.code-fence.end.markdown
+|^^ meta.code-fence.definition.end.json5.markdown-gfm punctuation.definition.raw.code-fence.end.markdown
+
+```jsonc
+
+| <- markup.raw.code-fence.jsonc.markdown-gfm
+```
+| <- meta.code-fence.definition.end.jsonc.markdown-gfm punctuation.definition.raw.code-fence.end.markdown
+|^^ meta.code-fence.definition.end.jsonc.markdown-gfm punctuation.definition.raw.code-fence.end.markdown
+
+```json
+
+| <- markup.raw.code-fence.json.markdown-gfm
+```
+| <- meta.code-fence.definition.end.json.markdown-gfm punctuation.definition.raw.code-fence.end.markdown
+|^^ meta.code-fence.definition.end.json.markdown-gfm punctuation.definition.raw.code-fence.end.markdown
+
```lisp
| <- markup.raw.code-fence.lisp.markdown-gfm source.lisp
diff --git a/Perl/Perl.sublime-syntax b/Perl/Perl.sublime-syntax
index 954cdeba3a4..c0fb678dab2 100644
--- a/Perl/Perl.sublime-syntax
+++ b/Perl/Perl.sublime-syntax
@@ -251,6 +251,18 @@ contexts:
embed: scope:source.js
embed_scope: source.js.embedded.perl
escape: (?=^{{pod}})
+ # embedded json5
+ - match: \bjson5\b
+ scope: constant.other.language-name.json5.perl
+ embed: scope:source.json.json5
+ embed_scope: source.json5.embedded.perl
+ escape: (?=^{{pod}})
+ # embedded jsonc
+ - match: \bjsonc\b
+ scope: constant.other.language-name.jsonc.perl
+ embed: scope:source.json.jsonc
+ embed_scope: source.jsonc.embedded.perl
+ escape: (?=^{{pod}})
# embedded json
- match: \bjson\b
scope: constant.other.language-name.json.perl
@@ -930,6 +942,22 @@ contexts:
3: entity.name.tag.heredoc.js.perl
4: punctuation.definition.tag.end.perl
set: [string-heredoc-javascript, string-heredoc-expr]
+ # embedded json5
+ - match: \s*((['"]?)(\s*JSON5)(\2))
+ captures:
+ 1: meta.tag.heredoc.perl
+ 2: punctuation.definition.tag.begin.perl
+ 3: entity.name.tag.heredoc.json5.perl
+ 4: punctuation.definition.tag.end.perl
+ set: [string-heredoc-json5, string-heredoc-expr]
+ # embedded jsonc
+ - match: \s*((['"]?)(\s*JSONC)(\2))
+ captures:
+ 1: meta.tag.heredoc.perl
+ 2: punctuation.definition.tag.begin.perl
+ 3: entity.name.tag.heredoc.jsonc.perl
+ 4: punctuation.definition.tag.end.perl
+ set: [string-heredoc-jsonc, string-heredoc-expr]
# embedded json
- match: \s*((['"]?)(\s*JSON)(\2))
captures:
@@ -1013,6 +1041,24 @@ contexts:
embed: scope:source.js
escape: (?=^ *JAVASCRIPT$)
+ string-heredoc-json5:
+ - meta_content_scope: source.json5.embedded.perl
+ - match: ^\3$
+ scope: meta.tag.heredoc.perl entity.name.tag.heredoc.json5.perl
+ pop: true
+ - match: ''
+ embed: scope:source.json.json5
+ escape: (?=^ *JSON5$)
+
+ string-heredoc-jsonc:
+ - meta_content_scope: source.jsonc.embedded.perl
+ - match: ^\3$
+ scope: meta.tag.heredoc.perl entity.name.tag.heredoc.jsonc.perl
+ pop: true
+ - match: ''
+ embed: scope:source.json.jsonc
+ escape: (?=^ *JSONC$)
+
string-heredoc-json:
- meta_content_scope: source.json.embedded.perl
- match: ^\3$
diff --git a/Perl/syntax_test_perl.pl b/Perl/syntax_test_perl.pl
index ba96ed7b8b3..44ea4a7e016 100644
--- a/Perl/syntax_test_perl.pl
+++ b/Perl/syntax_test_perl.pl
@@ -112,18 +112,38 @@ =head1 B<--param>
# <- meta.comment.perl meta.interpolation.perl entity.name.tag.pod.perl
#^^^ meta.comment.perl meta.interpolation.perl entity.name.tag.pod.perl
+=begin json5
+# <- meta.comment.perl meta.interpolation.perl entity.name.tag.pod.perl
+#^^^^^^^^^^ meta.comment.perl meta.interpolation.perl
+#^^^^^ entity.name.tag.pod.perl
+# ^ - constant - entity
+# ^^^^ constant.other.language-name.json5.perl
+
+# <- meta.comment.perl meta.interpolation.perl source.json5.embedded.perl source.json.json5
+=end
+# <- meta.comment.perl meta.interpolation.perl entity.name.tag.pod.perl
+#^^^ meta.comment.perl meta.interpolation.perl entity.name.tag.pod.perl
+
+=begin jsonc
+# <- meta.comment.perl meta.interpolation.perl entity.name.tag.pod.perl
+#^^^^^^^^^^ meta.comment.perl meta.interpolation.perl
+#^^^^^ entity.name.tag.pod.perl
+# ^ - constant - entity
+# ^^^^ constant.other.language-name.jsonc.perl
+
+# <- meta.comment.perl meta.interpolation.perl source.jsonc.embedded.perl source.json.jsonc
+=end
+# <- meta.comment.perl meta.interpolation.perl entity.name.tag.pod.perl
+#^^^ meta.comment.perl meta.interpolation.perl entity.name.tag.pod.perl
+
=begin json
# <- meta.comment.perl meta.interpolation.perl entity.name.tag.pod.perl
#^^^^^^^^^^ meta.comment.perl meta.interpolation.perl
#^^^^^ entity.name.tag.pod.perl
# ^ - constant - entity
# ^^^^ constant.other.language-name.json.perl
- {
-# ^ meta.comment.perl meta.interpolation.perl source.json.embedded.perl source.json
- "key": "value",
-# ^^^^^^^^^^^^^^^ meta.comment.perl meta.interpolation.perl source.json.embedded.perl source.json
- }
-# ^ meta.comment.perl meta.interpolation.perl source.json.embedded.perl source.json
+
+# <- meta.comment.perl meta.interpolation.perl source.json.embedded.perl source.json
=end
# <- meta.comment.perl meta.interpolation.perl entity.name.tag.pod.perl
#^^^ meta.comment.perl meta.interpolation.perl entity.name.tag.pod.perl