Skip to content

Commit

Permalink
[JSON] Rewrite syntax
Browse files Browse the repository at this point in the history
- Using inheritance split up `JSON.sublime-syntax` into:
    - `JSON.sublime-syntax` with `scope:source.json`
    - `JSONC.sublime-syntax` with `scope:source.json.jsonc`
    - `JSON5.sublime-syntax` with `scope:source.json.json5`
    - `JSON_dotNET.sublime-syntax` with `scope:source.json.json-dotnet`
- Add many more file extensions for `JSON` & `JSONC`:
    - add doc links to extensions where applicable as a reference to be
      able to more quickly verify that they (still) use said syntax
      flavor
- JSON:
    - Make use of newer syntax features including those only available
      in `version: 2` syntaxes
    - Make use of `variables` (with optimizations provided by @deathaxe
      and regex patterns provided by @Thom1729)
    - Context names now more closely match the naming scheme of other
      (recently re-written) default syntaxes
    - (correctly formatted) JSON code can now be prettified or minified
      via the context menu or the command palette. JSON code can
      optionally be auto-prettified on pre save events.
    - highlight leading, trailing & multiple commas as invalid
    - only allow exactly one structure (object, array) or value
      (constant, number, string) at top level (thanks to @keith-hall)
    - links (`meta.link.inet`) and email addresses (`meta.link.email`) are
      scoped the same as in Markdown (thanks to @deathaxe)
- JSONC:
    - highlight some files by default as `JSONC` (as decided by
      @jskinner in sublimehq#285)
    - highlight leading & multiple commas as invalid, trailing as valid
    - scope empty block comments as such
    - support syntax based folding of ST4131+,
      compare sublimehq#3291
- JSON5:
    - explicitly pos numbers, hexadecimal ints, Infinity and NaN
    - single quoted strings
    - more escape chars for strings
    - ECMA identifierName as object keys (regexes thanks to @Thom1729)
        - scoped as plain unquoted strings (thanks to @Thom1729)
        - support string interpolation (thanks to @deathaxe)
    - line continuation in strings (with tests thanks to @keith-hall)
- JSON.NET:
    - support requested by @keith-hall,
      built with feedback from @michaelblyons
- Objects:
    - Highlighting speed improvements for empty objects (thanks to
      @FichteFoll)
    - Make `mapping.*` contexts more modular
- Arrays:
    - Highlighting speed improvements for empty arrays (thanks to
      @FichteFoll)
- Numbers:
    - Correctly scope number signs with `constant.numeric.sign` instead
      of `keyword.operator.arithmetic`
    - Significantly improve number highlighting (thanks to @deathaxe)
- Completions:
    - completions have been added for language constants, including kind info
      and details (with links to docs)
        - `null`, `false`, `true` for JSON
        - `Infinity` and `NaN` for JSON5
- Settings:
    - a `default_extension` is now set for all JSON flavors
- Symbol index:
    - with an object structure at the top-level, only top-level keys
      within now show up in the index (including tests for symbols and
      syntax)
- Tests:
    - test files now test the base scope
    - Significantly extend tests to cover more parts of the syntaxes
    - Split original test file into logical parts
    - Add indentation tests for:
        - `json`, `json5` & `jsonc`
        - `mapping` (objects), `sequence` (arrays)
    - Add symbols tests for:
        - top-level keys of object structures (thanks to deathaxe)
        - languages: `json`, `json5` & `jsonc`
    - Fix tests for `meta.mapping meta.mapping.*`
- Leave `JSON` headers in `Markdown` as `json` only, but split up fenced
  code blocks into `json`, `json5` & `jsonc` to behave similarly to
  `GitHub Flavored Markdown`

BREAKING CHANGES:

- JSON does not have values that can be set via an inline calculation
  with the help of operators, but only simple number values. Scopes for
  number signs have changed from being `keyword.operator.arithmetic` to
  `constant.numeric.sign`. Color scheme authors should add this, should
  it be missing.
- The `JSON.sublime-syntax` now marks comments as `invalid`, third party
  plugin authors should instead target `JSONC.sublime-syntax` to keep
  the user experience as-is.
- Indexed symbols (i.e. top-level keys in JSON object structures) are
  scoped as `source.json meta.mapping.key - (meta.mapping.value meta.mapping.key | meta.sequence.list meta.mapping.key)`.
  Color scheme authors should add special highlighting to differentiate
  them from other keys.

- fix sublimehq#285
- address sublimehq#421 (thanks to @FichteFoll)
- address sublimehq#481 to remove incompatible regex patterns according
  to @wbond
- address sublimehq#757 to fix line comments for `JSONC` (thanks to
  @keith-hall)
- address sublimehq#2430 using sort-order (as requested by @deathaxe)
- address sublimehq#2711 with regards to `constant.language.null`
  vs. `constant.language.empty` (thanks to @FichteFoll)
- address sublimehq#2852 to fix scopes of curly braces & square
  brackets in `JSON` (thanks to @Thom1729)
- address sublimehq#3228 to fix `punctuation.separator` scopes,
  compare sublimehq#3270
- address sublimehq/sublime_text#3154 and add symbol tests

Co-authored-by: Ashwin Shenoy <[email protected]>
Co-authored-by: Jack Cherng <[email protected]>
Co-authored-by: Janos Wortmann <[email protected]>
Co-authored-by: Jon Skinner <[email protected]>
Co-authored-by: FichteFoll <[email protected]>
Co-authored-by: Keith Hall <[email protected]>
Co-authored-by: Michael B. Lyons <[email protected]>
Co-authored-by: Rafał Chłodnicki <[email protected]>
Co-authored-by: Thomas Smith <[email protected]>
Co-authored-by: Will Bond <[email protected]>
Co-authored-by: deathaxe <[email protected]>
  • Loading branch information
12 people committed May 31, 2022
1 parent ee0146e commit 4c10320
Show file tree
Hide file tree
Showing 32 changed files with 2,044 additions and 370 deletions.
1 change: 1 addition & 0 deletions JSON/.python-version
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
3.8
25 changes: 25 additions & 0 deletions JSON/Comments - JSON5.tmPreferences
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
<?xml version="1.0" encoding="UTF-8"?>
<plist version="1.0">
<dict>
<key>scope</key>
<string>source.json.json5</string>
<key>settings</key>
<dict>
<key>shellVariables</key>
<array>
<dict>
<key>name</key><string>TM_COMMENT_START</string>
<key>value</key><string>// </string>
</dict>
<dict>
<key>name</key><string>TM_COMMENT_START_2</string>
<key>value</key><string>/*</string>
</dict>
<dict>
<key>name</key><string>TM_COMMENT_END_2</string>
<key>value</key><string>*/</string>
</dict>
</array>
</dict>
</dict>
</plist>
25 changes: 25 additions & 0 deletions JSON/Comments - JSONC.tmPreferences
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
<?xml version="1.0" encoding="UTF-8"?>
<plist version="1.0">
<dict>
<key>scope</key>
<string>source.json.jsonc</string>
<key>settings</key>
<dict>
<key>shellVariables</key>
<array>
<dict>
<key>name</key><string>TM_COMMENT_START</string>
<key>value</key><string>// </string>
</dict>
<dict>
<key>name</key><string>TM_COMMENT_START_2</string>
<key>value</key><string>/*</string>
</dict>
<dict>
<key>name</key><string>TM_COMMENT_END_2</string>
<key>value</key><string>*/</string>
</dict>
</array>
</dict>
</dict>
</plist>
31 changes: 0 additions & 31 deletions JSON/Comments.tmPreferences

This file was deleted.

29 changes: 29 additions & 0 deletions JSON/Context.sublime-menu
Original file line number Diff line number Diff line change
@@ -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"
}
]
29 changes: 29 additions & 0 deletions JSON/Default.sublime-commands
Original file line number Diff line number Diff line change
@@ -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"
}
]
131 changes: 69 additions & 62 deletions JSON/Default.sublime-keymap
Original file line number Diff line number Diff line change
@@ -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 }
]
},
]
// 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 }
]
},
]
27 changes: 0 additions & 27 deletions JSON/Fold.tmPreferences

This file was deleted.

27 changes: 27 additions & 0 deletions JSON/Folding Rules - JSON.tmPreferences
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
<?xml version="1.0" encoding="UTF-8"?>
<plist version="1.0">
<dict>
<key>scope</key>
<string>source.json - (source.json.json-dotnet | source.json.json5 | source.json.jsonc)</string>
<key>settings</key>
<dict>
<key>indentationFoldingEnabled</key>
<false/>
<key>foldScopes</key>
<array>
<dict>
<key>begin</key>
<string>punctuation.definition.mapping.begin</string>
<key>end</key>
<string>punctuation.definition.mapping.end</string>
</dict>
<dict>
<key>begin</key>
<string>punctuation.definition.sequence.begin</string>
<key>end</key>
<string>punctuation.definition.sequence.end</string>
</dict>
</array>
</dict>
</dict>
</plist>
31 changes: 31 additions & 0 deletions JSON/Folding Rules - JSON5.tmPreferences
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
<?xml version="1.0" encoding="UTF-8"?>
<plist version="1.0">
<dict>
<key>scope</key>
<string>source.json.json5</string>
<key>settings</key>
<dict>
<key>foldScopes</key>
<array>
<dict>
<key>begin</key>
<string>punctuation.definition.comment.begin</string>
<key>end</key>
<string>punctuation.definition.comment.end</string>
</dict>
<dict>
<key>begin</key>
<string>punctuation.definition.mapping.begin</string>
<key>end</key>
<string>punctuation.definition.mapping.end</string>
</dict>
<dict>
<key>begin</key>
<string>punctuation.definition.sequence.begin</string>
<key>end</key>
<string>punctuation.definition.sequence.end</string>
</dict>
</array>
</dict>
</dict>
</plist>
31 changes: 31 additions & 0 deletions JSON/Folding Rules - JSONC.tmPreferences
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
<?xml version="1.0" encoding="UTF-8"?>
<plist version="1.0">
<dict>
<key>scope</key>
<string>source.json.jsonc</string>
<key>settings</key>
<dict>
<key>foldScopes</key>
<array>
<dict>
<key>begin</key>
<string>punctuation.definition.comment.begin</string>
<key>end</key>
<string>punctuation.definition.comment.end</string>
</dict>
<dict>
<key>begin</key>
<string>punctuation.definition.mapping.begin</string>
<key>end</key>
<string>punctuation.definition.mapping.end</string>
</dict>
<dict>
<key>begin</key>
<string>punctuation.definition.sequence.begin</string>
<key>end</key>
<string>punctuation.definition.sequence.end</string>
</dict>
</array>
</dict>
</dict>
</plist>
Loading

0 comments on commit 4c10320

Please sign in to comment.