ソース管理 API
ソース管理 API を使用すると、拡張機能の開発者はソース管理管理 (SCM) 機能を定義できます。小規模ながら強力な API インターフェースにより、さまざまな SCM システムを Visual Studio Code に統合でき、かつそれらすべてで共通のユーザーインターフェイスを利用することが可能です。

VS Code 自体には Git 拡張機能という一つのソース管理プロバイダーが同梱されています。これは本 API の最適なリファレンスであり、独自の SCM プロバイダーを作成したい場合には素晴らしい出発点となります。Marketplace には、SVN 拡張機能など、他にも優れた例が多数存在します。
このドキュメントでは、あらゆる SCM システムを VS Code で動作させるための拡張機能の構築方法を説明します。
注: ドキュメント内の
vscode名前空間 API リファレンスはいつでも参照できます。
ソース管理モデル
SourceControl は、ソース管理モデルにリソース状態(SourceControlResourceState のインスタンス)を取り込む責任を持つエンティティです。リソース状態は、それ自体がグループ(SourceControlResourceGroup のインスタンス)に整理されます。
vscode.scm.createSourceControl を使用して、新しい SourceControl を作成できます。
これら 3 つのエンティティがどのように相互に関連しているかをよりよく理解するために、例として 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 は 2 つのリソースグループを定義します。ワーキングツリーとインデックスです。そのグループ内の各ファイルの変更がリソース状態となります。
- インデックス - リソースグループ
README.md, 変更済み - リソース状態src/test/api.ts,src/api.tsから名前変更 - リソース状態
- ワーキングツリー - リソースグループ
.travis.yml, 削除済み - リソース状態README.md, 変更済み - リソース状態
同じファイルである README.md が、2 つの異なるリソース状態の一部となっていることに注目してください。
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;
}
メニュー
よりリッチなユーザーインターフェイスを提供するために、メニュー項目を配置できる 6 つのソース管理メニュー ID があります。
scm/title メニューは、SCM ビュータイトルの右側に配置されます。navigation グループ内のメニュー項目はインラインで表示され、その他の項目は … ドロップダウンメニュー内に表示されます。
以下の 3 つは同様です。
scm/resourceGroup/contextは、SourceControlResourceGroupアイテムにコマンドを追加します。scm/resourceState/contextは、SourceControlResourceStateアイテムにコマンドを追加します。scm/resourceFolder/contextは、SourceControlResourceStateのresourceUriパスにフォルダが含まれており、ユーザーがリストビューではなくツリービューモードを選択している場合に表示される中間フォルダにコマンドを追加します。
メニュー項目を inline グループに配置するとインライン表示されます。他のメニュー項目グループは、通常マウスの右クリックでアクセス可能なコンテキストメニューに表示されます。
SCM ビューは複数選択をサポートしているため、コマンドは引数として 1 つまたは複数のリソースの配列を受け取ることに注意してください。
例えば Git は、scm/resourceState/context メニューに git.stage コマンドを追加し、そのようなメソッド宣言を使用することで、複数のファイルのステージングをサポートしています。
stage(...resourceStates: SourceControlResourceState[]): Promise<void>;
SourceControl および SourceControlResourceGroup インスタンスを作成する際、id 文字列を提供する必要があります。これらの値は、それぞれ scmProvider および scmResourceGroup コンテキストキーに格納されます。メニュー項目の when 句でこれらのコンテキストキーを利用できます。Git がどのようにして git.stage コマンドのインラインメニュー項目を表示しているかの例を以下に示します。
{
"command": "git.stage",
"when": "scmProvider == git && scmResourceGroup == merge",
"group": "inline"
}
scm/repository メニューは、ソース管理リポジトリビュー内の各 SourceControl インスタンスのメニューです。メニュー項目を inline グループに配置するとインライン表示されます。他のグループのメニュー項目は ... メニューに表示されます。inline グループは利用可能なスペースに応じてレンダリングされ、収まらないメニュー項目は自動的に ... メニューに移動されます。
scm/sourceControl メニューは、ソース管理リポジトリビュー内の各 SourceControl インスタンスのコンテキストメニューです。

scm/change/title を使用すると、後述のクイック差分 (Quick Diff) インライン差分エディターのタイトルバーにコマンドを追加できます。コマンドには、ドキュメントの URI、ドキュメント内の変更配列、およびインライン差分エディターが現在フォーカスしている変更のインデックスが引数として渡されます。例えば、originalResourceScheme コンテキストキーが git であることを確認する when 句を使用して、このメニューに貢献する stageChange 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 は、クイック差分エディターのガター装飾の表示もサポートしています。その装飾をクリックするとインライン差分体験が表示され、そこにコンテキストコマンドを追加できます。

これらの装飾は VS Code 自体によって計算されます。必要なのは、特定のファイルの元の内容を VS Code に提供することだけです。
export interface SourceControl {
quickDiffProvider?: QuickDiffProvider;
}
QuickDiffProvider の provideOriginalResource メソッドを使用すると、実装側はメソッドの引数として提供された Uri に一致する、元のリソースの Uri を VS Code に伝えることができます。
この API を workspace 名前空間の registerTextDocumentContentProvider メソッドと組み合わせることで、登録されたカスタム scheme に一致する Uri が与えられた際に、任意のリソースの内容を提供できるようになります。
次のステップ
VS Code 拡張機能モデルの詳細については、次のトピックを参照してください。
- SCM API リファレンス - SCM API の完全なドキュメントを読む
- Git 拡張機能 - Git 拡張機能の実装を読んで学ぶ
- 拡張機能 API 概要 - VS Code の完全な拡張性モデルについて学ぶ
- 拡張機能マニフェストファイル - VS Code の package.json 拡張機能マニフェストファイルのリファレンス
- 貢献ポイント - VS Code 貢献ポイントのリファレンス。