原始碼控制 API

原始碼控制(SCM)API 允許擴充功能開發者定義 SCM 功能。這是一個精簡但強大的 API 介面,讓各種不同的 SCM 系統都能整合進 Visual Studio Code 中,同時保有統一的使用者介面。

VS Code SCM

VS Code 本身內建了一個原始碼控制提供者,即 Git 擴充功能。它是此 API 最好的參考範例,如果您想開發自己的 SCM 提供者,這是一個極佳的起點。在市集上還有其他優秀的範例,例如 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 定義了兩個資源群組:工作樹 (Working Tree)索引 (Index)。該群組內的每個檔案變更即為一個資源狀態

  • 索引 (Index) - 資源群組
    • README.md,已修改 - 資源狀態
    • src/test/api.ts,從 src/api.ts 重新命名 - 資源狀態
  • 工作樹 (Working Tree) - 資源群組
    • .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 群組中的功能表項目會顯示為內嵌,而其他所有項目將位於 下拉式功能表中。

以下這三個功能表類似:

  • scm/resourceGroup/context:將指令新增至 SourceControlResourceGroup 項目。
  • scm/resourceState/context:將指令新增至 SourceControlResourceState 項目。
  • scm/resourceFolder/context:當 SourceControlResourceState 的 resourceUri 路徑包含資料夾,且使用者選擇「樹狀檢視」而非「清單檢視」模式時,會將指令新增至中間層級的資料夾。

將功能表項目放在 inline 群組中即可使其顯示為內嵌。所有其他功能表項目群組通常會出現在滑鼠右鍵點擊時顯示的操作功能表中。

請注意,SCM 檢視支援多重選擇,因此指令接收的參數是一個包含一個或多個資源的陣列。

例如,Git 透過將 git.stage 指令新增至 scm/resourceState/context 功能表,並使用此類方法宣告來支援暫存多個檔案:

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

建立時,SourceControlSourceControlResourceGroup 實例需要您提供一個 id 字串。這些值將分別填入 scmProviderscmResourceGroup 內容索引鍵中。您可以在功能表項目的 when 子句中依賴這些 內容索引鍵 (context keys)。以下說明 Git 如何為其 git.stage 指令顯示內嵌功能表項目:

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

scm/repository 功能表是「原始碼控制儲存庫」檢視中每個 SourceControl 實例上的功能表。將功能表項目放入 inline 群組,使其以內嵌方式顯示。所有其他功能表項目群組將顯示在 ... 功能表中。inline 群組會根據可用空間進行轉譯,不適合放入的項目會自動移動至 ... 功能表中。

scm/sourceControl 功能表是「原始碼控制儲存庫」檢視中每個 SourceControl 實例上的內容功能表。

source control menu

scm/change/title 允許您將指令貢獻至 快速差異 (Quick Diff) 內嵌差異編輯器的標題列中(詳見下文 Quick Diff 章節)。指令將接收文件 URI、其中包含的變更陣列,以及目前內嵌差異編輯器所聚焦的變更索引作為參數。例如,以下是 stageChange Git 指令的宣告,它透過一個測試 originalResourceScheme 內容索引鍵是否為 gitwhen 子句,貢獻至此功能表:

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;
}

快速差異 (Quick Diff)

VS Code 也支援顯示快速差異編輯器裝訂槽裝飾。點擊這些裝飾將顯示內嵌差異體驗,您可以對其貢獻上下文相關的指令。

SCM quick diff

這些裝飾由 VS Code 本身計算。您只需要提供任何給定檔案的原始內容給 VS Code 即可。

export interface SourceControl {
  quickDiffProvider?: QuickDiffProvider;
}

透過 QuickDiffProviderprovideOriginalResource 方法,您的實作可以告訴 VS Code 與參數中提供的 Uri 相匹配的原始資源 Uri

將此 API 與 workspace 命名空間中的 registerTextDocumentContentProvider 方法結合使用,該方法可讓您為任意資源提供內容,只要提供與註冊的自訂 scheme 相匹配的 Uri 即可。

後續步驟

若要進一步了解 VS Code 的擴充性模型,請嘗試閱讀這些主題:

© . This site is unofficial and not affiliated with Microsoft.