现已发布!阅读 10 月份的新功能和修复。

源代码管理 API

源代码管理 API 允许扩展作者定义源代码管理 (SCM) 功能。这是一个精简但功能强大的 API 表面,它允许将许多不同的 SCM 系统集成到 Visual Studio Code 中,同时为所有系统提供通用的用户界面。

VS Code SCM

VS Code 自身附带一个源代码管理提供程序,即 Git 扩展,它是此 API 的最佳参考,也是 一个很棒的起点,如果你想贡献你自己的 SCM 提供程序。在 Marketplace 中还有其他很棒的示例,例如 SVN 扩展

本文档将帮助您构建一个扩展,使任何 SCM 系统都能与 VS Code 配合使用。

注意:您始终可以参考我们文档中的 vscode 命名空间 API 参考

源代码管理模型

SourceControl 是负责使用 资源状态SourceControlResourceState 的实例)填充源代码管理模型的实体。资源状态本身组织在 SourceControlResourceGroup 的实例)中。

您可以使用 vscode.scm.createSourceControl 创建新的 SourceControl。

为了更好地理解这三个实体之间的相互关系,让我们以 Git 为例。考虑以下 git status 的输出

vsce main* → git status
On branch main
Your branch is up-to-date with 'origin/main'.
Changes to be committed:
  (use "git reset HEAD <file>..." to unstage)

        modified:   README.md
        renamed:    src/api.ts -> src/test/api.ts

Changes not staged for commit:
  (use "git add/rm <file>..." to update what will be committed)
  (use "git checkout -- <file>..." to discard changes in working directory)

        deleted:    .travis.yml
        modified:   README.md

在这个工作区中,发生了很多事情。首先,README.md 文件已被修改、暂存,然后再次修改。其次,src/api.ts 文件已移动到 src/test/api.ts,并且该移动已暂存。最后,.travis.yml 文件已被删除。

对于此工作区,Git 定义了两个资源组:工作树索引。该组中的每个文件更改都是资源状态

  • 索引 - 资源组
    • README.md,已修改 - 资源状态
    • src/test/api.ts,已重命名自 src/api.ts - 资源状态
  • 工作树 - 资源组
    • .travis.yml,已删除 - 资源状态
    • README.md,已修改 - 资源状态

请注意,同一个文件 README.md 是两个不同资源状态的一部分。

以下是 Git 如何创建此模型的示例

function createResourceUri(relativePath: string): vscode.Uri {
  const absolutePath = path.join(vscode.workspace.rootPath, relativePath);
  return vscode.Uri.file(absolutePath);
}

const gitSCM = vscode.scm.createSourceControl('git', 'Git');

const index = gitSCM.createResourceGroup('index', 'Index');
index.resourceStates = [
  { resourceUri: createResourceUri('README.md') },
  { resourceUri: createResourceUri('src/test/api.ts') }
];

const workingTree = gitSCM.createResourceGroup('workingTree', 'Changes');
workingTree.resourceStates = [
  { resourceUri: createResourceUri('.travis.yml') },
  { resourceUri: createResourceUri('README.md') }
];

对源代码管理和资源组的更改将传播到源代码管理视图。

源代码管理视图

VS Code 能够随着源代码管理模型的更改而填充源代码管理视图。可以使用 SourceControlResourceDecorations 自定义资源状态。

export interface SourceControlResourceState {
  readonly decorations?: SourceControlResourceDecorations;
}

前面的示例足以在源代码管理视图中填充一个简单的列表,但是用户可能希望对每个资源执行许多用户交互。例如,当用户单击资源状态时会发生什么?资源状态可以选择提供一个命令来处理此操作。

export interface SourceControlResourceState {
  readonly command?: Command;
}

有六个源代码管理菜单 ID 可以放置菜单项,以便为用户提供更丰富的用户界面。

scm/title 菜单位于 SCM 视图标题的右侧。navigation 组中的菜单项将处于内联状态,而其他所有菜单项都将位于 下拉菜单中。

以下三个菜单相似

将菜单项放置在 inline 组中以使其处于内联状态。所有其他菜单项组都将在通常使用鼠标右键访问的上下文菜单中表示。

请注意,SCM 视图支持多选,因此命令接收一个或多个资源的数组作为其参数。

例如,Git 通过将 git.stage 命令添加到 scm/resourceState/context 菜单并使用这样的方法声明,支持暂存多个文件

stage(...resourceStates: SourceControlResourceState[]): Promise<void>;

在创建它们时,SourceControlSourceControlResourceGroup 实例要求您提供一个 id 字符串。这些值将分别填充到 scmProviderscmResourceGroup 上下文键中。您可以依靠这些 上下文键 作为菜单项中的 when 子句。以下是 Git 如何为其 git.stage 命令显示一个内联菜单项的示例

{
  "command": "git.stage",
  "when": "scmProvider == git && scmResourceGroup == merge",
  "group": "inline"
}

scm/sourceControl 菜单是 源代码管理存储库 视图中每个 SourceControl 实例的上下文菜单

source control menu

scm/change/title 允许您向 快速差异 内联差异编辑器标题栏贡献命令,这将在 后面 进一步说明。该命令将作为参数传递文档的 URI、其中的更改数组以及内联更改差异编辑器当前聚焦的更改的索引。例如,以下是 stageChange Git 命令的声明,该命令被贡献到此菜单,并使用 when 子句测试 originalResourceScheme 上下文键 是否等于 git

async stageChange(uri: Uri, changes: LineChange[], index: number): Promise<void>;

SCM 输入框

源代码管理输入框位于每个源代码管理视图的顶部,允许用户输入消息。您可以获取(以及设置)此消息以执行操作。例如,在 Git 中,它用作提交框,用户在其中键入提交消息,git commit 命令会提取这些消息。

export interface SourceControlInputBox {
  value: string;
}

export interface SourceControl {
  readonly inputBox: SourceControlInputBox;
}

用户可以键入 Ctrl+Enter(或 macOS 上的 Cmd+Enter)以接受任何消息。您可以通过向 SourceControl 实例提供 acceptInputCommand 来处理此事件。

export interface SourceControl {
  readonly acceptInputCommand?: Command;
}

快速差异

VS Code 还支持显示 快速差异编辑器边距装饰。单击这些装饰将显示内联差异体验,您可以在其中贡献上下文命令。

SCM quick diff

这些装饰由 VS Code 自行计算。您只需要为 VS Code 提供任何给定文件的原始内容即可。

export interface SourceControl {
  quickDiffProvider?: QuickDiffProvider;
}

使用 QuickDiffProviderprovideOriginalResource 方法,您的实现能够告诉 VS Code 与资源匹配的原始资源的 Uri,该资源的 Uri 作为方法的参数提供。

将此 API 与 workspace 命名空间中的 registerTextDocumentContentProvider 方法 结合使用,该方法允许您为任意资源提供内容,前提是 Uri 与为其注册的自定义 scheme 匹配。

下一步

要详细了解 VS Code 可扩展性模型,请尝试以下主题