Skip to content

Commit 7e3f360

Browse files
jrappenAshwin Shenoyjfcherngjwortmannjskinner
committed
[JSON] Rewrite syntax
- 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]>
1 parent 258ace9 commit 7e3f360

34 files changed

+2682
-313
lines changed

JSON/Comments - JSONC.tmPreferences

+25
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<plist version="1.0">
3+
<dict>
4+
<key>scope</key>
5+
<string>source.json.jsonc</string>
6+
<key>settings</key>
7+
<dict>
8+
<key>shellVariables</key>
9+
<array>
10+
<dict>
11+
<key>name</key><string>TM_COMMENT_START</string>
12+
<key>value</key><string>// </string>
13+
</dict>
14+
<dict>
15+
<key>name</key><string>TM_COMMENT_START_2</string>
16+
<key>value</key><string>/*</string>
17+
</dict>
18+
<dict>
19+
<key>name</key><string>TM_COMMENT_END_2</string>
20+
<key>value</key><string>*/</string>
21+
</dict>
22+
</array>
23+
</dict>
24+
</dict>
25+
</plist>

JSON/Comments.tmPreferences

-31
This file was deleted.

JSON/Default.sublime-keymap

+1-1
Original file line numberDiff line numberDiff line change
@@ -60,4 +60,4 @@
6060
{ "key": "following_text", "operator": "regex_contains", "operand": "^\\]", "match_all": true }
6161
]
6262
},
63-
]
63+
]

JSON/JSON (Basic).sublime-syntax

+245
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,245 @@
1+
%YAML 1.2
2+
---
3+
# https://yaml.org/spec/1.2/spec.html
4+
# https://www.sublimetext.com/docs/syntax.html#ver-dev
5+
# https://www.sublimetext.com/docs/syntax.html#testing:ver-dev
6+
# https://www.sublimetext.com/docs/scope_naming.html
7+
name: JSON (Basic)
8+
scope: source.json.basic
9+
version: 2
10+
hidden: true
11+
12+
13+
variables:
14+
exponent: '(?:[eE][-+]?\d+)'
15+
optional_exponent: '(?:{{exponent}}?)'
16+
optional_neg_sign: '(?:[-]?)'
17+
pos_integer_decimal: '(?:0|[1-9]\d*)'
18+
19+
20+
contexts:
21+
22+
main:
23+
- include: any
24+
25+
any:
26+
- include: constants
27+
- include: numbers
28+
- include: strings
29+
- include: sequence
30+
- include: mapping
31+
32+
####[ Constants ]#######################################################################################################
33+
34+
constants:
35+
- match: \b(?:null)\b
36+
scope: constant.language.null.json
37+
- match: \b(?:false|true)\b
38+
scope: constant.language.boolean.json
39+
40+
####[ Numbers ]#########################################################################################################
41+
42+
numbers:
43+
- include: floats
44+
- include: integers
45+
46+
floats:
47+
- include: decimal-float
48+
49+
decimal-float:
50+
- include: explicitly-positive-decimal-float-json
51+
- include: decimal-float-json
52+
53+
explicitly-positive-decimal-float-json:
54+
- match: |-
55+
(?x: # ignore whitespace
56+
([+])
57+
(
58+
{{pos_integer_decimal}}
59+
(?:
60+
((\.)\d+)({{optional_exponent}})
61+
|
62+
({{exponent}})
63+
)
64+
)
65+
)
66+
scope: invalid.illegal.unrecognized-float-decimal.json
67+
captures:
68+
1: keyword.operator.arithmetic.json
69+
2: constant.numeric.value.json
70+
3: constant.numeric.value.fraction.json
71+
4: punctuation.separator.decimal.json
72+
5: constant.numeric.value.exponent.json
73+
6: constant.numeric.value.exponent.json
74+
75+
decimal-float-json:
76+
- match: |-
77+
(?x: # ignore whitespace
78+
({{optional_neg_sign}})
79+
(
80+
{{pos_integer_decimal}}
81+
(?:
82+
((\.)\d+)({{optional_exponent}})
83+
|
84+
({{exponent}})
85+
)
86+
)
87+
)
88+
scope: meta.number.float.decimal.json
89+
captures:
90+
1: keyword.operator.arithmetic.json
91+
2: constant.numeric.value.json
92+
3: constant.numeric.value.fraction.json
93+
4: punctuation.separator.decimal.json
94+
5: constant.numeric.value.exponent.json
95+
6: constant.numeric.value.exponent.json
96+
97+
integers:
98+
- include: decimal-integer
99+
100+
decimal-integer:
101+
- include: explicitly-positive-decimal-integer-json
102+
- include: decimal-integer-json
103+
104+
explicitly-positive-decimal-integer-json:
105+
- match: '([+])({{pos_integer_decimal}})'
106+
scope: invalid.illegal.unrecognized-integer-decimal.json
107+
captures:
108+
1: keyword.operator.arithmetic.json
109+
2: constant.numeric.value.json
110+
111+
decimal-integer-json:
112+
- match: '({{optional_neg_sign}})({{pos_integer_decimal}})'
113+
scope: meta.number.integer.decimal.json
114+
captures:
115+
1: keyword.operator.arithmetic.json
116+
2: constant.numeric.value.json
117+
118+
####[ Strings ]#########################################################################################################
119+
120+
strings:
121+
- include: double-quoted-string-ahead
122+
123+
double-quoted-string-ahead:
124+
- match: '(?=\")'
125+
push: double-quoted-string
126+
127+
double-quoted-string:
128+
- meta_scope: meta.string.json string.quoted.double.json
129+
- match: '"'
130+
scope: punctuation.definition.string.begin.json
131+
set: inside-double-quoted-string
132+
133+
inside-double-quoted-string:
134+
- meta_scope: meta.string.json string.quoted.double.json
135+
- meta_include_prototype: false # for inheriting syntaxes
136+
- match: '"'
137+
scope: punctuation.definition.string.end.json
138+
pop: 1
139+
- include: double-quoted-string-escape-characters
140+
- match: \n
141+
scope: invalid.illegal.unclosed-string.json
142+
pop: 1
143+
144+
double-quoted-string-escape-characters:
145+
- match: \\\"
146+
scope: constant.character.escape.double-quote.json
147+
- include: string-escape-characters
148+
149+
string-escape-characters:
150+
- match: \\\\
151+
scope: constant.character.escape.back-slash.json
152+
- match: \\\/
153+
scope: constant.character.escape.forward-slash.json
154+
- match: \\b
155+
scope: constant.character.escape.backspace.json
156+
- match: \\f
157+
scope: constant.character.escape.form-feed.json
158+
- match: \\n
159+
scope: constant.character.escape.newline.json # linefeed
160+
- match: \\r
161+
scope: constant.character.escape.carriage-return.json
162+
- match: \\t
163+
scope: constant.character.escape.horizontal-tab.json
164+
- match: \\u[0-9a-fA-F]{4}
165+
scope: constant.character.escape.unicode-symbol.json
166+
- match: \\.
167+
scope: invalid.illegal.unrecognized-string-escape.json
168+
169+
####[ Sequence ]########################################################################################################
170+
171+
# FIXME: move trailing commas to JSONC
172+
173+
sequence:
174+
- match: \[
175+
scope: punctuation.definition.sequence.begin.json
176+
push: meta-sequence
177+
178+
meta-sequence:
179+
- meta_scope: meta.sequence.json
180+
- match: \]
181+
scope: punctuation.definition.sequence.end.json
182+
pop: 1
183+
- include: any
184+
- match: ','
185+
scope: punctuation.separator.sequence.json
186+
- match: '[^\s\]]'
187+
scope: invalid.illegal.expected-sequence-separator.json
188+
189+
####[ Mapping ]#########################################################################################################
190+
191+
# TODO: add `meta.toc-list` to top level object keys
192+
# FIXME: move trailing commas to JSONC
193+
194+
mapping:
195+
- match: \{
196+
scope: punctuation.definition.mapping.begin.json
197+
push: meta-mapping
198+
199+
meta-mapping:
200+
- meta_scope: meta.mapping.json
201+
- match: \}
202+
scope: punctuation.definition.mapping.end.json
203+
pop: 1
204+
- include: mapping-key
205+
- include: mapping-separator
206+
- match: '[^\s\}]'
207+
scope: invalid.illegal.expected-mapping-key.json
208+
209+
mapping-key:
210+
- match: '"'
211+
scope: punctuation.definition.string.begin.json
212+
push: mapping-key-double-quoted
213+
214+
mapping-key-double-quoted:
215+
- clear_scopes: 1
216+
- meta_scope: meta.mapping.key.json meta.string.json string.quoted.double.json
217+
- meta_include_prototype: false # for inheriting syntaxes
218+
- include: inside-double-quoted-string
219+
220+
mapping-separator:
221+
- match: ':'
222+
scope: punctuation.separator.mapping.key-value.json
223+
push: mapping-expect-value
224+
225+
mapping-expect-value:
226+
- match: ',|\s?(?=\})'
227+
scope: invalid.illegal.expected-mapping-value.json
228+
pop: 1
229+
- match: (?=\S)
230+
set: mapping-value
231+
232+
mapping-value:
233+
- clear_scopes: 1
234+
- meta_scope: meta.mapping.value.json
235+
- include: any
236+
- match: ''
237+
set:
238+
- match: ','
239+
scope: punctuation.separator.mapping.pair.json
240+
pop: 1
241+
- match: \s*(?=\})
242+
pop: 1
243+
- match: \s(?!/[/*])(?=[^\s,])|[^\s,]
244+
scope: invalid.illegal.expected-mapping-separator.json
245+
pop: 1

0 commit comments

Comments
 (0)