虚拟工作空间

诸如GitHub Repositories扩展之类的扩展可在文件系统提供程序支持的一个或多个文件夹上打开 VS Code 。当扩展实现文件系统提供程序时,工作区资源可能不位于本地磁盘上,而是虚拟的,位于服务器或云上,并且编辑操作在那里发生。

这种配置称为虚拟工作空间。当虚拟工作区在 VS Code 窗口中打开时,左下角远程指示器中的标签会指示这一点,与其他远程开发窗口类似。

远程指示器

并非所有扩展都能够使用虚拟资源,并且可能需要磁盘上的资源。某些扩展使用依赖磁盘访问、需要同步文件访问或没有必要的文件系统抽象的工具。在这些情况下,在虚拟工作区中时,VS Code 会向用户指示它们正在受限模式下运行,并且某些扩展已停用或只能使用有限的功能。

一般来说,用户希望尽可能多的扩展能够在虚拟工作空间中工作,并在浏览和编辑远程资源时拥有良好的用户体验。本指南展示了扩展如何针对虚拟工作区进行测试,描述了允许它们在虚拟工作区中工作的修改,并介绍了功能属性virtualWorkspaces

修改扩展以使用虚拟工作区也是在VS Code for Web中良好运行的重要一步。VS Code for Web 完全在浏览器内运行,并且由于浏览器沙箱的存在,工作区是虚拟的。有关更多详细信息,请参阅Web 扩展指南。

我的分机受到影响吗?

当扩展没有可执行代码但纯粹是声明性的(如主题、键绑定、片段或语法扩展)时,它可以在虚拟工作区中运行,无需进行任何修改。

带代码的扩展,意味着定义main入口点的扩展,需要检查,可能还需要修改。

针对虚拟工作区运行您的扩展

安装GitHub 存储库扩展并从命令面板运行打开 GitHub 存储库...命令。该命令显示“快速选择”下拉列表,您可以粘贴任何 GitHub URL,或选择搜索特定存储库或拉取请求。

这将打开一个虚拟工作区的 VS Code 窗口,其中所有资源都是虚拟的。

检查扩展代码是否已准备好用于虚拟资源

VS Code API 对虚拟文件系统的支持已经存在很长一段时间了。您可以查看文件系统提供程序 API

文件系统提供程序注册为新的 URI 方案(例如,vscode-vfs),并且该文件系统上的资源将由使用该方案的 URI 表示(vscode-vfs://github/microsoft/vscode/package.json

检查您的扩展如何处理从 VS Code API 返回的 URI:

  • 切勿假设 URI 方案是fileURI.fsPath仅当 URI 方案为 时才能使用file
  • 请注意fs文件系统操作的节点模块的用法。如果可能,请使用vscode.workspace.fsAPI,它将委托给适当的文件系统提供商。
  • 检查依赖于访问的第三方组件fs(例如,语言服务器或节点模块)。
  • 如果您通过命令运行可执行文件和任务,请检查这些命令在虚拟工作区窗口中是否有意义或者是否应禁用它们。

指示您的扩展是否可以处理虚拟工作区

invirtualWorkspaces下的属性用于指示扩展是否适用于虚拟工作区。capabilitiespackage.json

不支持虚拟工作空间

下面的示例声明扩展不支持虚拟工作区,并且不应在此设置中由 VS Code 启用。

{
  "capabilities": {
    "virtualWorkspaces": {
      "supported": false,
      "description": "Debugging is not possible in virtual workspaces."
    }
  }
}

对虚拟工作空间的部分和全面支持

当扩展与虚拟工作区一起工作或部分工作时,它应该定义"virtualWorkspaces": true.

{
  "capabilities": {
    "virtualWorkspaces": true
  }
}

如果扩展有效,但功能有限,则应向用户解释该限制:

{
  "capabilities": {
    "virtualWorkspaces": {
      "supported": "limited",
      "description": "In virtual workspaces, resolving and finding references across files is not supported."
    }
  }
}

描述显示在扩展视图中:

扩展视图

然后,扩展程序应禁用虚拟工作区中不支持的功能,如下所述。

默认

"virtualWorkspaces": true是所有尚未填写该virtualWorkspaces功能的分机的默认值。

然而,在测试虚拟工作空间时,我们提出了我们认为应该在虚拟工作空间中禁用的扩展列表。该列表可以在问题 #122836中找到。这些扩展名"virtualWorkspaces": false默认具有。

当然,扩展作者可以更好地做出这个决定。virtualWorkspaces扩展中的功能将package.json覆盖我们的默认设置,我们最终将废弃我们的列表。

打开虚拟工作区时禁用功能

禁用命令并查看贡献

命令和视图以及许多其他贡献的可用性可以通过when 子句中的上下文键来控制。

virtualWorkspace当所有工作区文件夹都位于虚拟文件系统上时,将设置上下文键。下面的示例仅npm.publish在不在虚拟工作区中时显示命令面板中的命令:

{
  "menus": {
    "commandPalette": [
      {
        "command": "npm.publish",
        "when": "!virtualWorkspace"
      }
    ]
  }
}

上下文resourceScheme键设置为文件资源管理器中当前选定元素或编辑器中打开的元素的 URI 方案。

在下面的示例中,npm.runSelectedScript如果底层资源位于本地磁盘上,则该命令仅显示在编辑器上下文菜单中。

{
  "menus": {
    "editor/context": [
      {
        "command": "npm.runSelectedScript",
        "when": "resourceFilename == 'package.json' && resourceScheme == file"
      }
    ]
  }
}

以编程方式检测虚拟工作区

要检查当前工作空间是否由非file方案组成并且是虚拟的,可以使用以下源代码:

const isVirtualWorkspace =
  workspace.workspaceFolders &&
  workspace.workspaceFolders.every(f => f.uri.scheme !== 'file');

语言扩展和虚拟工作空间

对虚拟工作空间的语言支持有何期望?

所有扩展都能够完全使用虚拟资源是不现实的。许多扩展使用需要同步文件访问和磁盘上的文件的外部工具。因此,只提供有限的功能是可以的,例如下面列出的基本单文件支持。

A.基本语言支持:

  • TextMate 标记化和着色
  • 特定于语言的编辑支持:括号对、注释、输入规则、折叠标记
  • 代码片段

B.单文件语言支持:

  • 文档符号(轮廓)、折叠、选择范围
  • 文档突出显示、语义突出显示、文档颜色
  • 完成、悬停、签名帮助、根据当前文件和静态语言库上的符号查找引用/声明
  • 格式化、链接编辑
  • 语法验证和同文件语义验证以及代码操作

C.跨文件、工作区感知语言支持:

  • 跨文件引用
  • 工作区符号
  • 验证工作区/项目中的所有文件

VS Code 附带的丰富语言扩展(TypeScript、JSON、CSS、HTML、Markdown)在处理虚拟资源时仅限于单文件语言支持。

禁用语言扩展

如果无法处理单个文件,语言扩展也可以决定在虚拟工作区中禁用扩展。

如果您的扩展同时提供需要禁用的语法和丰富的语言支持,则语法也将被禁用。为了避免这种情况,您可以创建一个独立于丰富语言支持的基本语言扩展(语法、语言配置、片段),并拥有两个扩展。

  • 基本语言扩展具有"virtualWorkspaces": true并提供语言 ID、配置、语法和片段。
  • 丰富的语言扩展具有"virtualWorkspaces": false并包含该main文件。extensionDependencies它提供语言支持、命令,并对基本语言扩展具有扩展依赖性 ( )。富语言扩展应该保留已建立的扩展的扩展 ID,以便用户可以通过安装单个扩展来继续拥有完整的功能。

您可以通过内置的语言扩展来看到这种方法,例如 JSON,它由 JSON 扩展和 JSON 语言功能扩展组成。

这种分离还有助于在受限模式下运行不受信任的工作区。丰富的语言扩展通常需要信任,而基本的语言功能可以在任何设置中运行。

语言选择器

为语言功能(例如,完成、悬停、代码操作等)注册提供程序时,请确保指定提供程序支持的方案:

return vscode.languages.registerCompletionItemProvider(
  { language: 'typescript', scheme: 'file' },
  {
    provideCompletionItems(document, position, token) {
      // ...
    }
  }
);

语言服务器协议 (LSP) 对访问虚拟资源的支持怎么样?

向 LSP 添加文件系统提供程序支持的工作正在进行中。在语言服务器协议问题 #1264中进行跟踪。