如何在VS Code中让未加双引号的JSON键成为有效令牌
问题场景
拿到一组开发者提供的JSON文件,键未使用双引号标注,示例如下:
{ ingredientPattern: "PPP,PSP,PRP", ingredients: { "S": { type: "item", code: "saw-*", isTool: true, toolDurabilityCost: 60 }, "P": { type: "item", code: "plank-*", quantity: 6 }, "R": { type: "block", code: "rock-*", name: "rock", allowedVariants: ["andesite", "granite", "basalt", "peridotite"] } }, width: 3, height: 3, output: { type: "block", code: "pulverizerframe-north", quantity: 1 } }
每次在VS Code中打开这类文件都会显示大量错误。将*.json关联为jsonl以消除红色下划线,但深色主题下键仍被标红。通过启用「Developer: Inspect Editor Tokens and Scopes」查看,发现语法解析器将这些键标记为invalid。
不想修改主题的无效令牌颜色(红色提示对排查语法问题很有用),希望调整语法解析逻辑,让未加双引号的键像加双引号的键一样被识别为support.type.property-name。
找到JSONL语法文件位于%LocalAppData%\Programs\Microsoft VS Code\resources\app\extensions\json\syntaxes\JSONL.tmLanguage.json,其中处理JSONL键的代码片段如下:
"objectkey": { "begin": "\"", "beginCaptures": { "0": { "name": "punctuation.support.type.property-name.begin.json.lines" } }, "end": "\"", "endCaptures": { "0": { "name": "punctuation.support.type.property-name.end.json.lines" } }, "name": "string.json.lines support.type.property-name.json.lines", "patterns": [ { "include": "#stringcontent" } ] }
不清楚该修改哪些正则表达式,或是否需要调整文件其他部分来实现需求,寻求相关建议。
修改方案
要让无引号的键被正确识别,需要修改JSONL语法文件中的objectkey定义,同时调整相关模式匹配逻辑:
1. 扩展objectkey的匹配规则
原规则仅匹配带双引号的键,需扩展为同时匹配符合JS标识符规则的无引号键(以字母、下划线或$开头,后续可跟字母、数字、下划线或$)。将原objectkey替换为以下内容:
"objectkey": { "patterns": [ // 保留原有带双引号键的匹配逻辑 { "begin": "\"", "beginCaptures": { "0": { "name": "punctuation.support.type.property-name.begin.json.lines" } }, "end": "\"", "endCaptures": { "0": { "name": "punctuation.support.type.property-name.end.json.lines" } }, "name": "string.json.lines support.type.property-name.json.lines", "patterns": [ { "include": "#stringcontent" } ] }, // 添加无引号键的匹配规则 { "match": "^\\s*([a-zA-Z_$][a-zA-Z0-9_$]*)(?=\\s*:)", "captures": { "1": { "name": "support.type.property-name.json.lines" } } } ] }
2. 检查并调整父模式的优先级
找到文件中引用#objectkey的property模式,确保无引号键的匹配规则优先级高于invalidstring:
"property": { "patterns": [ { "include": "#objectkey" }, { "include": "#invalidstring" } ] }
如果invalidstring的正则会误匹配无引号键,可修改其规则,比如添加排除条件,避免和无引号键的规则冲突。
3. 验证修改效果
保存修改后的语法文件,重启VS Code,打开目标JSON文件,通过「Developer: Inspect Editor Tokens and Scopes」查看无引号键的令牌类型,确认是否被标记为support.type.property-name.json.lines。
注意事项
- 修改VS Code内置扩展文件会在软件更新后被覆盖,建议将修改后的语法文件导出为自定义语法扩展,或通过
settings.json中的files.associations配置关联到自定义语法。 - 无引号键的匹配规则严格遵循合法标识符规则,避免和其他语法元素(如数字、关键字)冲突。
内容的提问来源于stack exchange,提问作者Pakoco

