You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

VSCode能否无需外部库解析含注释的keybindings.json文件?

如何不依赖外部库解析VSCode带注释的keybindings.json文件?

我正在开发VSCode扩展,需要获取快捷键列表,得解析包含注释的keybindings.json文件。目前用JSON5包完成解析,但想移除这个外部依赖,想问VSCode有没有内置的方法可以直接解析带注释的JSON文件?

当前实现代码

//get keybindings
const keybindings = new Promise(resolve => {
  //default keybindings
  const data = require("../package.json").contributes.keybindings.reduce((a,b)=>(a[b.command]=b.key,a),{});
  const parse = list => {
    for(let i = 0; i < list.length; i++) {
      if (list[i].command in data)
        data[list[i].command] = list[i].key;
    }
    for(let i in data) {
      //capitalize first letter
      data[i] = data[i].replace(/\w+/g, w => (w.substring(0,1).toUpperCase()) + w.substring(1));
      //add spaces around "+"
      // data[i] = data[i].replace(/\+/g, " $& ");
    }

    Object.assign(keybindings, data);
    resolve(data);
  };
  const path = {
    windows: process.env.APPDATA + "/Code",
    macos: process.env.HOME + "/Library/Application Support/Code",
    linux: process.env.HOME + "/config/Code"
  }[{
    aix: "linux",
    darwin: "macos",
    freebsd: "linux",
    linux: "linux",
    openbsd: "linux",
    sunos: "linux",
    win32: "windows"
  }[process.platform]||"windows"];
  const file = ((process.env.VSCODE_PORTABLE ? process.env.VSCODE_PORTABLE + "/user-data/User/" : path) + "/User/keybindings.json")
    .replace(/\//g, process.platform == "win32" ? "\\" : "/");

  //read file
  workspace.openTextDocument(file).then(doc => {
    //we can't use JSON.parse() because file may contain comments
    const JSON5 = require("json5").default;
    parse(JSON5.parse(doc.getText()));
  }).catch(er => {
    parse([]);
  });
});

解决方案:使用VSCode内置JSON解析器

VSCode本身就提供了支持带注释JSON的解析能力,完全可以替代JSON5,不需要额外依赖。核心是用vscode.json.parse方法,这个方法是VSCode内置的,专门用来处理自身配置文件(比如keybindings.json、settings.json这种允许加注释的JSON格式)。

修改步骤:

  1. 删掉代码里引入JSON5的那一行:const JSON5 = require("json5").default;
  2. 把解析文本的代码从JSON5.parse(doc.getText())替换成vscode.json.parse(doc.getText())
  3. 确保你的代码已经导入了vscode模块(既然你已经在使用workspace.openTextDocument,这一步应该已经满足)

修改后的完整代码

//get keybindings
const keybindings = new Promise(resolve => {
  //default keybindings
  const data = require("../package.json").contributes.keybindings.reduce((a,b)=>(a[b.command]=b.key,a),{});
  const parse = list => {
    for(let i = 0; i < list.length; i++) {
      if (list[i].command in data)
        data[list[i].command] = list[i].key;
    }
    for(let i in data) {
      //capitalize first letter
      data[i] = data[i].replace(/\w+/g, w => (w.substring(0,1).toUpperCase()) + w.substring(1));
      //add spaces around "+"
      // data[i] = data[i].replace(/\+/g, " $& ");
    }

    Object.assign(keybindings, data);
    resolve(data);
  };
  const path = {
    windows: process.env.APPDATA + "/Code",
    macos: process.env.HOME + "/Library/Application Support/Code",
    linux: process.env.HOME + "/config/Code"
  }[{
    aix: "linux",
    darwin: "macos",
    freebsd: "linux",
    linux: "linux",
    openbsd: "linux",
    sunos: "linux",
    win32: "windows"
  }[process.platform]||"windows"];
  const file = ((process.env.VSCODE_PORTABLE ? process.env.VSCODE_PORTABLE + "/user-data/User/" : path) + "/User/keybindings.json")
    .replace(/\//g, process.platform == "win32" ? "\\" : "/");

  //read file
  workspace.openTextDocument(file).then(doc => {
    // 使用VSCode内置JSON解析器支持注释
    parse(vscode.json.parse(doc.getText()));
  }).catch(er => {
    parse([]);
  });
});

补充说明

vscode.json.parse默认支持单行//和多行/* */注释,和你之前用JSON5的效果完全一致。如果需要更精细的控制,还可以传入第二个参数配置解析选项,比如:

vscode.json.parse(doc.getText(), { allowComments: true, allowTrailingCommas: true })

不过对于keybindings.json来说,默认配置已经足够应对绝大多数场景了。

内容的提问来源于stack exchange,提问作者vanowm

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.17 19:10:32