2021年7月28日星期三

VSCode Extension中的Virtual Documents使用笔记

  我们在用TypeScript编写VSCode Extension应用时,可以通过VSCode API提供的内置Command "vscode.diff"来快速比较两个文档,有关该命令的参数介绍可以查看官方文档。基本用法如下:

vscode.commands.executeCommand("vscode.diff", vscode.Uri.file(filePath1), vscode.Uri.file(filePath2), "Comparing Files");

  这里的filePath1和filePath2为要进行比较的两个文档的路径。也就是说,这两个文档是必须真实存在的,而且路径能够被VSCode访问。有时为了需要,在进行比较时我们也可以将文档内容暂时输出到系统临时目录,然后从临时目录加载文档内容。获取系统临时目录的方法可以参考下面的代码:

import * as os from "os";import * as path from "path";import * as process from "process";let platform = os.platform();let isWin = platform === "win32";let isLinux = platform === "linux";let tempDir = isWin ? process.env.TEMP : (isLinux ? path.join(process.env.HOME, 'tmp') : process.env.TMPDIR);console.log(tempDir);

   但是使用系统临时目录会带来另外一个问题,看下面的截图,在比较文档的界面右上角,有一个菜单可以直接点击打开文档,此时是从临时目录打开的,但有时我们并不想让用户知道文档是暂时存放在临时目录里的。有没有什么解决办法呢?我没有找到通过配置的方式将该菜单隐藏或者改变其行为,但是有两个变通的方法:一是不使用系统临时目录,仍然从文档的原始位置进行加载;二是使用VSCode提供的Virtual Documents

  下面是使用Virtual Documents之后的界面,可以看到与之前相比少了显示文档的路径和打开文档的菜单。

  下面是具体的实现。

  按照官方文档的介绍,我们需要定义一个TextDocumentContentProvider类的实例,其中的provideTextDocumentContent方法会返回Virtual Documents的具体内容。

 1 private async getDocumentText(fileFullPath: string): Promise<string> { 2  return new Promise<string>(resolve => { 3   fs.readFile(fileFullPath, "UTF-8", (err, data) => { 4    if (err) { 5     console.log(err); 6     resolve(""); 7    } else { 8     resolve(data); 9    }10   });11  });12 }13 14 private sourceProvider = new class implements vscode.TextDocumentContentProvider {15  onDidChangeEmitter = new vscode.EventEmitter<vscode.Uri>();16  onDidChange = this.onDidChangeEmitter.event;17 18  async provideTextDocumentContent(uri: vscode.Uri): Promise<string> {19   let oSource = await getDocumentText(uri.path);20   let oSourceContent = JSON.stringify(oSource, null, "\t");21   return oSourceContent;22  }23 };

  其中第19行通过getDocumentText方法从指定的路径读取了文档的内容,然后使用JSON.stringify将其格式化为标准的JSON文档,并返回对应的内容。onDidChange提供了文档被更新时的事件,我们可以在文档内容被修改时手动触发该事件,稍后会介绍。

  接下来是注册command。

subscriptions.push(vscode.workspace.registerTextDocumentContentProvider("sourceSchema", sourceProvider));

  注意这里的第一个参数schema非常重要!后面在传递文件url时都要带上这个schema,相当于它是一个标识,用来表示对该url的操作都通过sourceProvider类提供的方法来处理。

  相应地,如果vscode.diff的第二个文档你也希望使用Virtual Documents,那么就还需要定义TextDocumentContentProvider类的另一个实例。provideTextDocumentContent方法

1 subscriptions.push(vscode.workspace.registerTextDocumentContentProvider("compareSchema", new class implements vscode.TextDocumentContentProvider {2  onDidChangeEmitter = new vscode.EventEmitter<vscode.Uri>();3  onDidChange = this.onDidChangeEmitter.event;4 5  async provideTextDocumentContent(uri: vscode.Uri): Promise<string> {6   return ""; // return file content from here7  }8 }));

  这里我简化了代码实现,没有单独定义TextDocumentContentProvider原文转载:http://www.shaoqun.com/a/901546.html

跨境电商:https://www.ikjzd.com/

telegram:https://www.ikjzd.com/w/1734

腾邦:https://www.ikjzd.com/w/1382

logo免费制作:https://www.ikjzd.com/w/1998


我们在用TypeScript编写VSCodeExtension应用时,可以通过VSCodeAPI提供的内置Command"vscode.diff"来快速比较两个文档,有关该命令的参数介绍可以查看官方文档。基本用法如下:vscode.commands.executeCommand("vscode.diff",vscode.Uri.file(filePath1)
camel:https://www.ikjzd.com/w/331.html
云台山女娲造人的传说 - :http://www.30bags.com/a/407539.html
云台山娱乐介绍 - :http://www.30bags.com/a/407537.html
云台山在哪里_云台山在哪_云台山在什么地方 :http://www.30bags.com/a/412719.html
云台山竹筏漂流 - :http://www.30bags.com/a/407538.html
第一次玩交换真实经历 不带套交换真实感受:http://lady.shaoqun.com/a/247065.html
老汉粗大不带套 他的强壮让我欲仙欲死:http://lady.shaoqun.com/m/a/248321.html
男朋友公车猛烈的一进一出 又硬又粗又长爽死我了:http://www.30bags.com/m/a/249719.html
亚马逊广告烧钱不出单怎么办?如何提高曝光率:https://www.ikjzd.com/articles/146974
崩了!「解压玩具」侵权已"压垮"133家店铺,卖家快点撤离下架!:https://www.ikjzd.com/articles/146971
女人一旦出轨,通常会有这些变化。你遇到过他们吗?:http://lady.shaoqun.com/a/438500.html
男人晚上反应正常吗?一晚上几次比较好?看文章怎么说:http://lady.shaoqun.com/a/438501.html

没有评论:

发表评论