🚀 在 VS Code 中免費取得

虛擬文件

文字文件內容提供者 API 允許您從任意來源在 Visual Studio Code 中建立唯讀文件。您可以在以下位置找到包含原始碼的範例擴充功能:https://github.com/microsoft/vscode-extension-samples/blob/main/virtual-document-sample/README.md

TextDocumentContentProvider

此 API 的運作方式是宣告一個 URI 結構描述,您的提供者會針對該結構描述傳回文字內容。結構描述必須在註冊提供者時提供,且之後無法變更。相同的提供者可用於多個結構描述,且可以為單一結構描述註冊多個提供者。

vscode.workspace.registerTextDocumentContentProvider(myScheme, myProvider);

呼叫 registerTextDocumentContentProvider 會傳回一個可處置物件,可用於還原註冊。提供者僅必須實作 provideTextDocumentContent 函式,該函式會使用 URI 和取消符號呼叫。

const myProvider = new (class implements vscode.TextDocumentContentProvider {
  provideTextDocumentContent(uri: vscode.Uri): string {
    // invoke cowsay, use uri-path as text
    return cowsay.say({ text: uri.path });
  }
})();

請注意,提供者不會為虛擬文件建立 URI - 其角色是針對指定的 URI 提供內容。反過來說,內容提供者會連線到開啟文件邏輯,以便始終考量提供者。

此範例使用 'cowsay' 命令,該命令會製作編輯器應顯示的 URI

vscode.commands.registerCommand('cowsay.say', async () => {
  let what = await vscode.window.showInputBox({ placeHolder: 'cow say?' });
  if (what) {
    let uri = vscode.Uri.parse('cowsay:' + what);
    let doc = await vscode.workspace.openTextDocument(uri); // calls back into the provider
    await vscode.window.showTextDocument(doc, { preview: false });
  }
});

此命令會提示輸入,建立 cowsay 結構描述的 URI,開啟該 URI 的文件,最後開啟該文件的編輯器。在步驟 3 開啟文件時,系統會要求提供者提供該 URI 的內容。

有了這個,我們就有了一個功能完整的文字文件內容提供者。接下來的章節將說明如何更新虛擬文件,以及如何為虛擬文件註冊 UI 命令。

更新虛擬文件

虛擬文件可能會根據情境而變更。為了支援這一點,提供者可以實作 onDidChange 事件。

vscode.Event 類型定義了 VS Code 中事件處理的合約。實作事件最簡單的方法是 vscode.EventEmitter,如下所示

const myProvider = new (class implements vscode.TextDocumentContentProvider {
  // emitter and its event
  onDidChangeEmitter = new vscode.EventEmitter<vscode.Uri>();
  onDidChange = this.onDidChangeEmitter.event;

  //...
})();

事件發射器具有 fire 方法,可用於在文件發生變更時通知 VS Code。已變更的文件會透過其 URI 識別,URI 會以引數形式提供給 fire 方法。然後,系統將再次呼叫提供者以提供更新的內容,前提是文件仍為開啟狀態。

這就是讓 VS Code 監聽虛擬文件變更所需的一切。若要查看更複雜的範例,其中運用了此功能,請參閱:https://github.com/microsoft/vscode-extension-samples/blob/main/contentprovider-sample/README.md

新增編輯器命令

可以新增僅與相關聯內容提供者所提供文件互動的編輯器動作。這是一個範例命令,可反轉乳牛剛才說的話

// register a command that updates the current cowsay
subscriptions.push(
  vscode.commands.registerCommand('cowsay.backwards', async () => {
    if (!vscode.window.activeTextEditor) {
      return; // no editor
    }
    let { document } = vscode.window.activeTextEditor;
    if (document.uri.scheme !== myScheme) {
      return; // not my scheme
    }
    // get path-components, reverse it, and create a new uri
    let say = document.uri.path;
    let newSay = say
      .split('')
      .reverse()
      .join('');
    let newUri = document.uri.with({ path: newSay });
    await vscode.window.showTextDocument(newUri, { preview: false });
  })
);

上面的程式碼片段檢查我們是否有活動中的編輯器,以及其文件是否為我們的結構描述之一。需要這些檢查,因為命令對所有人皆可用 (且可執行)。然後,URI 的路徑元件會反轉,並從中建立新的 URI,最後開啟編輯器。

若要使用編輯器命令來完成工作,則需要在 package.json 中新增宣告式部分。在 contributes 區段中,新增此組態

"menus": {
  "editor/title": [
    {
      "command": "cowsay.backwards",
      "group": "navigation",
      "when": "resourceScheme == cowsay"
    }
  ]
}

這會參考 contributes/commands 區段中定義的 cowsay.backwards 命令,並說明它應出現在編輯器標題選單 (右上角的工具列) 中。現在,僅此一項就表示命令始終顯示,適用於每個編輯器。這就是 when 條件子句的用途 - 它描述了必須為真才能顯示動作的條件。在此範例中,它指出編輯器中文件的結構描述必須為 cowsay 結構描述。然後,針對 commandPalette 選單重複組態 - 預設會顯示所有命令。

cowsay-bwd

事件與可見性

文件提供者在 VS Code 中是一等公民,其內容會顯示在一般文字文件中,它們使用與檔案等相同的基礎結構。然而,這也表示「您的」文件無法隱藏,它們會出現在 onDidOpenTextDocumentonDidCloseTextDocument 事件中,它們是 vscode.workspace.textDocuments 的一部分等等。適用於所有人的規則是檢查文件的 scheme,然後決定您是否要對文件執行某些操作/為了文件執行某些操作。

檔案系統 API

如果您需要更高的彈性和功能,請查看 FileSystemProvider API。它允許實作完整檔案系統,具有檔案、資料夾、二進位資料、檔案刪除、建立等功能。

您可以在以下位置找到包含原始碼的範例擴充功能:https://github.com/microsoft/vscode-extension-samples/tree/main/fsprovider-sample/README.md

當 VS Code 在此類檔案系統的資料夾或工作區上開啟時,我們稱之為虛擬工作區。當虛擬工作區在 VS Code 視窗中開啟時,這會顯示在左下角遠端指示器中的標籤中,類似於遠端視窗。請參閱虛擬工作區指南,了解擴充功能如何支援該設定。