仮想ワークスペース
GitHub リポジトリ拡張機能のような拡張機能は、ファイルシステムプロバイダーによってバックアップされた1つ以上のフォルダーで VS Code を開きます。拡張機能がファイルシステムプロバイダーを実装すると、ワークスペースのリソースはローカルディスク上にはなく、サーバーやクラウド上に仮想的に存在し、そこで編集操作が行われます。
この構成は仮想ワークスペースと呼ばれます。VS Code ウィンドウで仮想ワークスペースが開かれている場合、他のリモート開発ウィンドウと同様に、左下隅のリモートインジケーターにラベルが表示されます。
すべての拡張機能が仮想リソースで動作できるわけではなく、リソースがディスク上にあることを要求する場合があります。一部の拡張機能は、ディスクアクセスに依存するツールを使用したり、同期ファイルアクセスを必要としたり、必要なファイルシステム抽象化を持っていません。これらの場合、仮想ワークスペースでは、VS Code はユーザーに制限モードで実行されており、一部の拡張機能が非アクティブ化されているか、機能が制限されていることを示します。
一般的に、ユーザーは仮想ワークスペースでできるだけ多くの拡張機能が動作し、リモートリソースの閲覧と編集時に優れたユーザーエクスペリエンスを得ることを望んでいます。このガイドでは、拡張機能が仮想ワークスペースに対してどのようにテストできるか、仮想ワークスペースで動作させるための変更点、およびvirtualWorkspaces
機能プロパティについて説明します。
仮想ワークスペースで動作するように拡張機能を変更することは、Web 用 VS Codeでうまく動作するための重要なステップでもあります。Web 用 VS Code はブラウザ内で完全に動作し、ブラウザのサンドボックスのためにワークスペースは仮想的です。詳細については、Web 拡張機能ガイドを参照してください。
私の拡張機能は影響を受けますか?
拡張機能に実行可能コードがなく、テーマ、キーバインディング、スニペット、文法拡張機能のような純粋に宣言型の場合、仮想ワークスペースで実行でき、変更は不要です。
コードを持つ拡張機能、つまりmain
エントリポイントを定義する拡張機能は、検査が必要であり、場合によっては変更が必要です。
仮想ワークスペースに対して拡張機能を実行する
GitHub リポジトリ拡張機能をインストールし、コマンドパレットからGitHub リポジトリを開く...コマンドを実行します。このコマンドはクイックピックドロップダウンを表示し、任意の GitHub URL を貼り付けるか、特定のレポジトリまたはプルリクエストを検索することを選択できます。
これにより、すべてのリソースが仮想である仮想ワークスペース用の VS Code ウィンドウが開きます。
拡張機能のコードが仮想リソースに対応しているか確認する
VS Code API の仮想ファイルシステムサポートはかなり前から存在します。ファイルシステムプロバイダー API を確認できます。
ファイルシステムプロバイダーは新しい URI スキーム (例: vscode-vfs
) に登録され、そのファイルシステム上のリソースは、そのスキーム (vscode-vfs://github/microsoft/vscode/package.json
) を使用する URI で表されます。
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) は、仮想リソースで作業する場合、単一ファイルの言語サポートに限定されます。
言語拡張機能を無効にする
単一ファイルでの作業が選択肢にない場合、言語拡張機能は仮想ワークスペースでの拡張機能を無効にすることもできます。
拡張機能が文法と、無効にする必要があるリッチな言語サポートの両方を提供している場合、文法も無効になります。これを避けるには、リッチな言語サポートとは別に基本的な言語拡張機能 (文法、言語設定、スニペット) を作成し、2つの拡張機能を持つことができます。
- 基本言語拡張機能は
"virtualWorkspaces": true
を持ち、言語ID、設定、文法、スニペットを提供します。 - リッチ言語拡張機能は
"virtualWorkspaces": false
を持ち、main
ファイルを含みます。これは言語サポート、コマンドに貢献し、基本言語拡張機能に拡張機能の依存関係 (extensionDependencies
) を持ちます。リッチ言語拡張機能は確立された拡張機能の拡張機能IDを保持すべきであり、そうすることでユーザーは単一の拡張機能をインストールすることで完全な機能を引き続き利用できます。
JSON のような組み込みの言語拡張機能 (JSON 拡張機能と JSON 言語機能拡張機能で構成されています) でこのアプローチを見ることができます。
この分離は、制限付きモードで実行されている信頼されていないワークスペースにも役立ちます。リッチな言語拡張機能は多くの場合信頼を必要としますが、基本的な言語機能はどのような設定でも実行できます。
言語セレクター
言語機能(例:補完、ホバー、コードアクションなど)のプロバイダーを登録する際、プロバイダーがサポートするスキームを指定するようにしてください。
return vscode.languages.registerCompletionItemProvider(
{ language: 'typescript', scheme: 'file' },
{
provideCompletionItems(document, position, token) {
// ...
}
}
);
Language Server Protocol (LSP) における仮想リソースへのアクセスサポートについてはどうですか?
LSP にファイルシステムプロバイダーのサポートを追加する作業が進められています。Language Server Protocol のissue #1264で追跡されています。