虛擬文件
文字文件內容提供程式 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
選單重複該配置——它預設顯示所有命令。
事件和可見性
文件提供程式是 VS Code 中的一等公民,它們的內容出現在常規文字文件中,它們使用與檔案等相同的結構。但是,這也意味著“您的”文件無法隱藏,它們將出現在 onDidOpenTextDocument
和 onDidCloseTextDocument
事件中,它們是 vscode.workspace.textDocuments
等的一部分。所有人的規則是檢查文件的 scheme
,然後決定是否要對文件執行某些操作。
檔案系統 API
如果您需要更大的靈活性和功能,請檢視 FileSystemProvider
API。它允許實現完整的檔案系統,包括檔案、資料夾、二進位制資料、檔案刪除、建立等。
您可以在以下位置找到包含原始碼的示例擴充套件:https://github.com/microsoft/vscode-extension-samples/tree/main/fsprovider-sample/README.md。
當 VS Code 在此類檔案系統的資料夾或工作區中開啟時,我們稱之為虛擬工作區。當虛擬工作區在 VS Code 視窗中開啟時,這會在左下角的遠端指示器中顯示一個標籤,類似於遠端視窗。請參閱虛擬工作區指南,瞭解擴充套件如何支援此設定。