You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

如何在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自己编写校验逻辑,完全控制错误信息的内容和展示。

大致步骤:

  1. 在扩展的激活函数中,创建一个诊断集合,用来存储我们自定义的诊断信息。
  2. 监听文件的打开、修改事件,对*.target.json类型的文件进行校验。
  3. 编写自定义校验逻辑,生成带有友好提示的诊断信息,添加到诊断集合中。

示例代码(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

火山引擎 最新活动