🚀 在 VS Code 中

虛擬工作區

如同 GitHub Repositories 擴充功能,有些擴充功能會在由 檔案系統提供者 支援的一或多個資料夾上開啟 VS Code。當擴充功能實作檔案系統提供者時,工作區資源可能不會位於本機磁碟上,而是虛擬的,位於伺服器或雲端上,並且編輯操作在那裡發生。

此組態稱為虛擬工作區。當虛擬工作區在 VS Code 視窗中開啟時,這會在左下角的遠端指示器中以標籤指示,類似於其他 遠端開發 視窗。

Remote indicator

並非所有擴充功能都能與虛擬資源搭配運作,並且可能需要資源位於磁碟上。某些擴充功能使用依賴磁碟存取的工具、需要同步檔案存取,或沒有必要的檔案系統抽象概念。在這些情況下,當在虛擬工作區中時,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 結構描述是 fileURI.fsPath 只能在 URI 結構描述為 file 時使用。
  • 留意 fs node 模組在檔案系統操作中的使用。如果可以,請使用 vscode.workspace.fs API,它會委派給適當的檔案系統提供者。
  • 檢查依賴 fs 存取的第三方元件(例如,語言伺服器或 node 模組)。
  • 如果您從命令執行可執行檔和任務,請檢查這些命令在虛擬工作區視窗中是否有意義,或者是否應該停用它們。

發出訊號表示您的擴充功能是否可以處理虛擬工作區

package.jsoncapabilities 下的 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."
    }
  }
}

描述會顯示在擴充功能檢視中

Extensions view

然後,擴充功能應停用虛擬工作區中不支援的功能,如下所述。

預設值

"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 中追蹤。