虛擬工作區
像 GitHub Repositories 這樣的擴充套件會在由檔案系統提供程式支援的一個或多個資料夾上開啟 VS Code。當擴充套件實現檔案系統提供程式時,工作區資源可能不在本地磁碟上,而是虛擬的,位於伺服器或雲端,並且編輯操作在那裡進行。
這種配置稱為虛擬工作區。當 VS Code 視窗中開啟虛擬工作區時,左下角的遠端指示器中會顯示一個標籤,類似於其他遠端開發視窗。
並非所有擴充套件都能與虛擬資源一起工作,可能需要資源位於磁碟上。有些擴充套件使用依賴磁碟訪問的工具,需要同步檔案訪問,或者沒有必要的檔案系統抽象。在這些情況下,當處於虛擬工作區時,VS Code 會向用戶指示它們正在受限模式下執行,並且某些擴充套件已停用或功能受限。
通常,使用者希望儘可能多的擴充套件在虛擬工作區中工作,並在瀏覽和編輯遠端資源時獲得良好的使用者體驗。本指南介紹了擴充套件如何針對虛擬工作區進行測試,描述了允許它們在虛擬工作區中工作的修改,並介紹了 virtualWorkspaces
能力屬性。
修改擴充套件以在虛擬工作區中工作也是在 VS Code for the Web 中良好工作的重要一步。VS Code for the Web 完全在瀏覽器中執行,並且由於瀏覽器沙盒,工作區是虛擬的。有關更多詳細資訊,請參閱Web 擴充套件指南。
我的擴充套件是否受影響?
當擴充套件沒有可執行程式碼,而純粹是宣告性的,例如主題、鍵繫結、片段或語法擴充套件時,它可以在虛擬工作區中執行,無需修改。
帶有程式碼的擴充套件,即定義 main
入口的擴充套件,需要檢查,並可能需要修改。
針對虛擬工作區執行您的擴充套件
安裝 GitHub Repositories 擴充套件,並從命令面板執行開啟 GitHub 儲存庫...命令。該命令會顯示一個快速選擇下拉列表,您可以貼上任何 GitHub URL,或選擇搜尋特定的儲存庫或拉取請求。
這會為虛擬工作區開啟一個 VS Code 視窗,其中所有資源都是虛擬的。
檢查擴充套件程式碼是否已準備好處理虛擬資源
VS Code API 對虛擬檔案系統的支援已經存在很長時間了。您可以檢視 檔案系統提供程式 API。
檔案系統提供程式是為新的 URI 方案(例如 vscode-vfs
)註冊的,該檔案系統上的資源將由使用該方案的 URI(vscode-vfs://github/microsoft/vscode/package.json
)表示。
檢查您的擴充套件如何處理從 VS Code API 返回的 URI
- 永遠不要假設 URI 方案是
file
。URI.fsPath
只能在 URI 方案為file
時使用。 - 注意檔案系統操作中
fs
節點模組的用法。如果可能,請使用vscode.workspace.fs
API,它會委託給適當的檔案系統提供程式。 - 檢查依賴
fs
訪問的第三方元件(例如,語言伺服器或節點模組)。 - 如果您從命令執行可執行檔案和任務,請檢查這些命令在虛擬工作區視窗中是否有意義,或者是否應該停用它們。
指示您的擴充套件是否可以處理虛擬工作區
package.json
中 capabilities
下的 virtualWorkspaces
屬性用於指示擴充套件是否與虛擬工作區一起工作。
不支援虛擬工作區
以下示例宣告擴充套件不支援虛擬工作區,並且不應在此設定中由 VS Code 啟用。
{
"capabilities": {
"virtualWorkspaces": {
"supported": false,
"description": "Debugging is not possible in virtual workspaces."
}
}
}
對虛擬工作區的部分和完全支援
當擴充套件與虛擬工作區一起工作或部分工作時,它應該定義 "virtualWorkspaces": true
。
{
"capabilities": {
"virtualWorkspaces": true
}
}
如果擴充套件工作,但功能受限,則應向用戶解釋限制。
{
"capabilities": {
"virtualWorkspaces": {
"supported": "limited",
"description": "In virtual workspaces, resolving and finding references across files is not supported."
}
}
}
描述顯示在擴充套件檢視中。
然後,擴充套件應停用虛擬工作區中不支援的功能,如下所述。
預設值
"virtualWorkspaces": true
是所有尚未填寫 virtualWorkspaces
能力的擴充套件的預設值。
然而,在測試虛擬工作區時,我們列出了一系列我們認為應該在虛擬工作區中停用的擴充套件。該列表可以在 issue #122836 中找到。這些擴充套件預設設定為 "virtualWorkspaces": false
。
當然,擴充套件作者更適合做出這個決定。擴充套件 package.json
中的 virtualWorkspaces
能力將覆蓋我們的預設值,我們最終將取消我們的列表。
當開啟虛擬工作區時停用功能
停用命令和檢視貢獻
命令和檢視以及許多其他貢獻的可用性可以透過when 子句中的上下文鍵進行控制。
當所有工作區資料夾都位於虛擬檔案系統上時,將設定 virtualWorkspace
上下文鍵。以下示例僅在不處於虛擬工作區時才在命令面板中顯示命令 npm.publish
。
{
"menus": {
"commandPalette": [
{
"command": "npm.publish",
"when": "!virtualWorkspace"
}
]
}
}
resourceScheme
上下文鍵設定為檔案瀏覽器中當前選定元素或編輯器中開啟的元素的 URI 方案。
在下面的示例中,只有當基礎資源位於本地磁碟上時,才會在編輯器上下文選單中顯示 npm.runSelectedScript
命令。
{
"menus": {
"editor/context": [
{
"command": "npm.runSelectedScript",
"when": "resourceFilename == 'package.json' && resourceScheme == file"
}
]
}
}
以程式設計方式檢測虛擬工作區
要檢查當前工作區是否包含非 file
方案並且是虛擬的,可以使用以下原始碼:
const isVirtualWorkspace =
workspace.workspaceFolders &&
workspace.workspaceFolders.every(f => f.uri.scheme !== 'file');
語言擴充套件和虛擬工作區
對虛擬工作區的語言支援有什麼期望?
所有擴充套件都能完全與虛擬資源一起工作是不現實的。許多擴充套件使用需要同步檔案訪問和磁碟上檔案的外部工具。因此,只提供有限的功能是可以的,例如下面列出的基本和單檔案支援。
A. 基本語言支援
- TextMate 分詞和著色
- 特定於語言的編輯支援:括號對、註釋、輸入規則、摺疊標記
- 程式碼片段
B. 單檔案語言支援
- 文件符號(大綱)、摺疊、選擇範圍
- 文件高亮顯示、語義高亮顯示、文件顏色
- 基於當前檔案和靜態語言庫中的符號的補全、懸停、簽名幫助、查詢引用/宣告
- 格式化、連結編輯
- 語法驗證和同一檔案語義驗證以及程式碼操作
C. 跨檔案、工作區感知語言支援
- 跨檔案引用
- 工作區符號
- 驗證工作區/專案中的所有檔案
VS Code 附帶的富語言擴充套件(TypeScript、JSON、CSS、HTML、Markdown)在處理虛擬資源時僅限於單檔案語言支援。
停用語言擴充套件
如果處理單個檔案不是一個選項,語言擴充套件也可以決定在虛擬工作區中停用該擴充套件。
如果您的擴充套件同時提供語法和需要停用的富語言支援,那麼語法也將被停用。為避免這種情況,您可以建立一個與富語言支援分離的基本語言擴充套件(語法、語言配置、片段),並擁有兩個擴充套件。
- 基本語言擴充套件具有
"virtualWorkspaces": true
並提供語言 ID、配置、語法和片段。 - 富語言擴充套件具有
"virtualWorkspaces": false
幷包含main
檔案。它提供語言支援、命令,並對基本語言擴充套件具有擴充套件依賴項 (extensionDependencies
)。富語言擴充套件應保留已建立擴充套件的擴充套件 ID,以便使用者可以透過安裝單個擴充套件繼續擁有完整功能。
您可以在內建語言擴充套件(例如 JSON)中看到這種方法,它由 JSON 擴充套件和 JSON 語言功能擴充套件組成。
這種分離還有助於在受限模式下執行的不受信任的工作區。富語言擴充套件通常需要信任,而基本語言功能可以在任何設定中執行。
語言選擇器
註冊語言功能提供程式時(例如,補全、懸停、程式碼操作等),請務必指定提供程式支援的方案。
return vscode.languages.registerCompletionItemProvider(
{ language: 'typescript', scheme: 'file' },
{
provideCompletionItems(document, position, token) {
// ...
}
}
);
語言伺服器協議 (LSP) 中對訪問虛擬資源的支援如何?
目前正在努力將檔案系統提供程式支援新增到 LSP。在語言伺服器協議 issue #1264 中進行跟蹤。