參加你附近的 ,瞭解 VS Code 中的 AI 輔助開發。

虛擬文件

文字文件內容提供程式 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,編輯器隨後應顯示該 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。發生更改的文件由作為引數傳遞給 fire 方法的 URI 標識。然後,如果文件仍然開啟,將再次呼叫提供程式以提供更新的內容。

這就是讓 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 視窗中開啟時,這會在左下角的遠端指示器中顯示一個標籤,類似於遠端視窗。請參閱虛擬工作區指南,瞭解擴充套件如何支援此設定。