如何在VSCode扩展中自定义JSON校验的问题描述
如何在VSCode扩展中自定义JSON校验的问题描述
我完全懂你的困扰——给VSCode扩展配置了JSON Schema校验后,默认的错误提示里会带出正则表达式之类的技术细节,普通用户根本看不懂,你想把这类提示换成更直白的表述,比如“请使用十六进制值”对吧?下面给你两种可行的解决方案,从简单到灵活:
方法一:直接在JSON Schema中自定义错误提示
这是最省心的方式,因为VSCode的JSON校验引擎(基于AJV)支持在Schema里直接指定自定义错误信息。比如你的Schema里有一个要求十六进制值的字段,原来的规则可能是这样:
{ "type": "object", "properties": { "targetValue": { "type": "string", "pattern": "^0x[0-9A-Fa-f]+$" } } }
现在给这个字段加上errorMessage属性,替换默认的正则不匹配提示:
{ "type": "object", "properties": { "targetValue": { "type": "string", "pattern": "^0x[0-9A-Fa-f]+$", "errorMessage": "请使用十六进制值(格式示例:0x1A3F)" } } }
这样用户输入不符合规则的内容时,VSCode就会显示你自定义的友好提示,完全看不到背后的正则表达式。
方法二:用VSCode扩展API自定义诊断提供者
如果你的需求更复杂(比如需要动态生成提示、结合额外逻辑校验),可以通过VSCode的Diagnostic API自己编写校验逻辑,完全控制错误信息的内容和展示。
大致步骤:
- 在扩展的激活函数中,创建一个诊断集合,用来存储我们自定义的诊断信息。
- 监听文件的打开、修改事件,对
*.target.json类型的文件进行校验。 - 编写自定义校验逻辑,生成带有友好提示的诊断信息,添加到诊断集合中。
示例代码(TypeScript):
import * as vscode from 'vscode'; import * as jsonc from 'jsonc-parser'; // 需要安装这个库来精准定位JSON节点位置 export function activate(context: vscode.ExtensionContext) { // 创建专属诊断集合 const targetJsonDiagnostics = vscode.languages.createDiagnosticCollection('target-json-validation'); // 监听文件修改 const changeDisposable = vscode.workspace.onDidChangeTextDocument(event => { validateTargetJson(event.document, targetJsonDiagnostics); }); // 监听文件打开 const openDisposable = vscode.workspace.onDidOpenTextDocument(document => { validateTargetJson(document, targetJsonDiagnostics); }); // 初始化已打开的目标文件 vscode.workspace.textDocuments.forEach(doc => { validateTargetJson(doc, targetJsonDiagnostics); }); // 注册清理函数 context.subscriptions.push(changeDisposable, openDisposable, targetJsonDiagnostics); } function validateTargetJson(document: vscode.TextDocument, diagnostics: vscode.DiagnosticCollection) { // 只处理*.target.json文件 if (!document.fileName.endsWith('.target.json')) { diagnostics.delete(document.uri); return; } const diagnosticsList: vscode.Diagnostic[] = []; const text = document.getText(); // 解析JSON(支持注释) const parseResult = jsonc.parseTree(text); if (!parseResult) { // 处理JSON语法错误,自定义提示 const syntaxError = jsonc.parse(text, [], { allowTrailingComma: true })[0]; if (syntaxError) { const startPos = document.positionAt(syntaxError.offset); const endPos = document.positionAt(syntaxError.offset + syntaxError.length); const range = new vscode.Range(startPos, endPos); diagnosticsList.push(new vscode.Diagnostic( range, 'JSON格式错误,请检查语法(支持注释)', vscode.DiagnosticSeverity.Error )); } diagnostics.set(document.uri, diagnosticsList); return; } // 遍历JSON节点,检查目标字段(示例:检查targetValue是否为十六进制) jsonc.visit(parseResult, (node) => { if (node.type === 'property' && node.key.value === 'targetValue' && node.value?.type === 'string') { const value = node.value.value; if (!/^0x[0-9A-Fa-f]+$/.test(value)) { // 获取字段值的位置范围 const startPos = document.positionAt(node.value.offset); const endPos = document.positionAt(node.value.offset + node.value.length); const range = new vscode.Range(startPos, endPos); diagnosticsList.push(new vscode.Diagnostic( range, '请使用十六进制值(格式示例:0x1A3F)', vscode.DiagnosticSeverity.Error )); } } }); diagnostics.set(document.uri, diagnosticsList); }
这个方法的优势是完全可控,你可以根据任何逻辑生成提示,甚至结合外部数据。不过需要注意安装jsonc-parser库来精准定位JSON节点的位置,避免错误提示的位置不准。
备注:内容来源于stack exchange,提问作者obelisk0114




