文档选择器
扩展可以根据语言、文件类型和位置使用文档选择器来过滤其功能。本主题将讨论文档选择器、文档方案以及扩展作者应注意的事项。
不在磁盘上的文本文档
并非所有文本文档都存储在磁盘上,例如,新创建的文档。除非另有说明,否则文档选择器适用于所有文档类型。使用 DocumentFilter 的 scheme
属性来缩小到特定的方案,例如 { scheme: 'file', language: 'typescript' }
用于存储在磁盘上的 TypeScript 文件。
文档选择器
Visual Studio Code 扩展 API 通过 DocumentSelector 类型将特定语言的功能(如 IntelliSense)与文档选择器结合在一起。它们是简化功能到特定语言的便捷机制。
下面的代码片段为 TypeScript 文件注册了一个 HoverProvider,文档选择器是 typescript
语言标识符字符串。
vscode.languages.registerHoverProvider('typescript', {
provideHover(doc: vscode.TextDocument) {
return new vscode.Hover('For *all* TypeScript documents.');
}
});
文档选择器不仅仅可以是语言标识符,更复杂的选择器可以使用 DocumentFilter 通过 scheme
和文件位置(通过 pattern
路径 glob 模式)进行过滤。
vscode.languages.registerHoverProvider(
{ pattern: '**/test/**' },
{
provideHover(doc: vscode.TextDocument) {
return new vscode.Hover('For documents inside `test`-folders only');
}
}
);
下一个代码片段使用了 scheme
过滤器并将其与语言标识符结合。untitled
方案用于尚未保存到磁盘的新文件。
vscode.languages.registerHoverProvider(
{ scheme: 'untitled', language: 'typescript' },
{
provideHover(doc: vscode.TextDocument) {
return new vscode.Hover('For new, unsaved TypeScript documents only');
}
}
);
文档方案
文档的 scheme
常常被忽视,但它是一条重要的信息。大多数文档都保存在磁盘上,扩展作者通常会假设他们处理的是磁盘上的文件。例如,对于简单的 typescript
选择器,默认假设是**磁盘上的 TypeScript 文件**。然而,在某些场景下,这种假设过于宽松,应使用更明确的选择器,例如 { scheme: 'file', language: 'typescript' }
。
当功能依赖于从磁盘读取/写入文件时,这一点的重要性就会体现出来。请看下面的代码片段:
// 👎 too lax
vscode.languages.registerHoverProvider('typescript', {
provideHover(doc: vscode.TextDocument) {
const { size } = fs.statSync(doc.uri.fsPath); // ⚠️ what about 'untitled:/Untitled1.ts' or others?
return new vscode.Hover(`Size in bytes is ${size}`);
}
});
上面的悬停提示提供者想要显示磁盘上文档的大小,但它没有检查文档是否实际存储在磁盘上。例如,文档可能是新创建的,尚未保存。正确的方法是告诉 VS Code,该提供者只能处理磁盘上的文件。
// 👍 only works with files on disk
vscode.languages.registerHoverProvider(
{ scheme: 'file', language: 'typescript' },
{
provideHover(doc: vscode.TextDocument) {
const { size } = fs.statSync(doc.uri.fsPath);
return new vscode.Hover(`Size in bytes is ${size}`);
}
}
);
总结
文档通常存储在文件系统上,但并非总是如此:有无标题文档、Git 使用的缓存文档、来自 FTP 等远程源的文档等等。如果你的功能依赖于磁盘访问,请务必使用带有 file
方案的文档选择器。
后续步骤
要了解有关 VS Code 扩展模型,请参阅以下主题: