Skip to content

Commit

Permalink
[JSON] Rewrite syntax
Browse files Browse the repository at this point in the history
- Split `JSON.sublime-syntax` into ... using inheritance:
    - `JSON (Basic).sublime-syntax` with `scope:source.json.basic`
    - `JSON.sublime-syntax` with `scope:source.json`
    - `JSONC.sublime-syntax` with `scope:source.json.jsonc`
    - `JSON5.sublime-syntax` with `scope:source.json.json5`
- Although the base syntax does not define a `prototype`, we add
  `meta_include_prototype: false` to the base syntax, to prevent
  inheriting syntaxes from injecting rules.
- make use of `variables`
- Add many more file extensions for `JSON` and `JSONC`
- Significantly extend tests to cover more parts of the syntaxes
  defined:
    - Split original test file into logical parts
    - Add indentation tests for:
        - `JSON`, `JSONC`
        - `mapping` (objects), `sequence` (arrays)
- leave `JSON` headers in `Markdown` as json only, but split up
  fenced code blocks into `json` and `jsonc` to behave similarly
  to `GitHub Flavored Markdown`
- fix tests for `meta.mapping meta.mapping.*`
- make `mapping.*` contexts more modular

- fix sublimehq#285 as requested by Jon
- address sublimehq#757 and use tips to fix line comments for `JSONC`
- address sublimehq#2430 and use sort-order as requested by deathaxe
- address sublimehq#2852 and use tips to fix scopes of curly braces &
  square brackets in `JSON`

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: deathaxe <[email protected]>
  • Loading branch information
10 people committed Oct 28, 2021
1 parent 258ace9 commit 3619e45
Show file tree
Hide file tree
Showing 33 changed files with 2,418 additions and 314 deletions.
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.

2 changes: 1 addition & 1 deletion JSON/Default.sublime-keymap
Original file line number Diff line number Diff line change
Expand Up @@ -60,4 +60,4 @@
{ "key": "following_text", "operator": "regex_contains", "operand": "^\\]", "match_all": true }
]
},
]
]
2 changes: 1 addition & 1 deletion JSON/Indentation Rules.tmPreferences
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
247 changes: 247 additions & 0 deletions JSON/JSON (Basic).sublime-syntax
Original file line number Diff line number Diff line change
@@ -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
Loading

0 comments on commit 3619e45

Please sign in to comment.