仮想ワークスペース
GitHub Repositories 拡張機能などの拡張機能は、ファイルシステムプロバイダーによってサポートされる1つ以上のフォルダーで VS Code を開きます。拡張機能がファイルシステムプロバイダーを実装すると、ワークスペースリソースはローカルディスクに存在せず、仮想的にサーバーやクラウドに存在し、編集操作はそこで行われます。
この構成は「仮想ワークスペース」と呼ばれます。仮想ワークスペースが VS Code ウィンドウで開かれている場合、その状態は左下隅のリモートインジケーターのラベルで示され、他のリモート開発ウィンドウと同様です。
すべての拡張機能が仮想リソースで動作できるわけではなく、リソースがディスク上にあることを要求する場合があります。一部の拡張機能はディスクアクセスに依存するツールを使用したり、同期ファイルアクセスを必要としたり、必要なファイルシステム抽象化を持っていません。これらのケースでは、仮想ワークスペースで VS Code は、制限モードで実行されており、一部の拡張機能が非アクティブ化されているか、限定された機能で動作していることをユーザーに示します。
一般的に、ユーザーは可能な限り多くの拡張機能が仮想ワークスペースで動作し、リモートリソースの閲覧および編集時に良好なユーザーエクスペリエンスを得ることを望んでいます。このガイドでは、拡張機能が仮想ワークスペースに対してどのようにテストできるか、仮想ワークスペースで動作させるための変更点、そして `virtualWorkspaces` 機能プロパティについて説明します。
拡張機能を仮想ワークスペースで動作するように変更することは、VS Code for the Web で適切に動作するための重要なステップでもあります。VS Code for the Web は完全にブラウザ内で動作し、ブラウザのサンドボックスによりワークスペースは仮想となります。詳細については、Web 拡張機能ガイドを参照してください。
自分の拡張機能は影響を受けますか?
拡張機能に実行可能コードがなく、テーマ、キーバインド、スニペット、文法拡張機能のように純粋に宣言型である場合、仮想ワークスペースで実行でき、変更は必要ありません。
コードを持つ拡張機能、つまり `main` エントリポイントを定義する拡張機能は、検査と、場合によっては変更が必要です。
仮想ワークスペースに対して拡張機能を実行する
GitHub Repositories 拡張機能をインストールし、コマンドパレットから「Open GitHub Repository...」コマンドを実行します。このコマンドはクイックピックのドロップダウンを表示し、任意の 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` Node モジュールの使用に注意してください。可能な場合は、適切なファイルシステムプロバイダーに委譲する `vscode.workspace.fs` API を使用してください。
- `fs` アクセスに依存するサードパーティ製コンポーネント (例: 言語サーバーまたは Node モジュール) を確認する。
- コマンドから実行可能ファイルやタスクを実行する場合、これらのコマンドが仮想ワークスペースウィンドウで意味があるか、それとも無効にすべきかをチェックしてください。
拡張機能が仮想ワークスペースを扱えるかどうかを通知する
`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` 機能がまだ設定されていないすべての拡張機能について、`"virtualWorkspaces": true` がデフォルトです。
ただし、仮想ワークスペースをテストしている間に、仮想ワークスペースで無効にすべきと考える拡張機能のリストを作成しました。そのリストは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 で追跡されています。