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格式)。
修改步骤:
- 删掉代码里引入JSON5的那一行:
const JSON5 = require("json5").default; - 把解析文本的代码从
JSON5.parse(doc.getText())替换成vscode.json.parse(doc.getText()) - 确保你的代码已经导入了
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
相关产品推荐
相关产品推荐

