カスタムエディタ API
カスタムエディタを使用すると、拡張機能は、特定の種類のファイル(リソース)に対して、VS Code の標準テキストエディタの代わりとなる、完全にカスタマイズ可能な読み取り/書き込み用エディタを作成できます。これには以下のような幅広い用途があります。
- シェーダーや 3D モデルなどのアセットを VS Code 内で直接プレビューする。
- Markdown や XAML などの言語向けの WYSIWYG エディタを作成する。
- CSV、JSON、XML などのデータファイルに対して代替の視覚的レンダリングを提供する。
- バイナリファイルやテキストファイル向けに、完全にカスタマイズ可能な編集エクスペリエンスを構築する。
本書では、カスタムエディタ API の概要とカスタムエディタ実装の基礎について説明します。2 種類のカスタムエディタとその違い、およびユースケースに適した選択方法について見ていきます。その後、それぞれのカスタムエディタタイプについて、適切に動作するカスタムエディタを構築するための基礎知識を解説します。
カスタムエディタは強力な新しい拡張ポイントですが、基本的なカスタムエディタの実装はそれほど難しくありません。ただし、初めて VS Code 拡張機能を作成する場合は、VS Code API の基礎に慣れるまでカスタムエディタへの着手は少し待つことを検討したほうがよいかもしれません。カスタムエディタは、webview やテキストドキュメントなど、多くの VS Code のコンセプトの上に成り立っているため、これらの新しいアイデアを同時に学習するのは少し大変かもしれません。
しかし、準備ができていると感じていて、これから構築するクールなカスタムエディタについて考えているのなら、さっそく始めましょう!ドキュメントの内容に沿って学習し、カスタムエディタ API がどのように連携するかを確認するために、必ず カスタムエディタ拡張機能サンプル をダウンロードしてください。
リンク
VS Code API の使用法
カスタムエディタ API の基礎
カスタムエディタとは、特定のリソースに対して VS Code の標準テキストエディタの代わりとして表示される代替ビューのことです。カスタムエディタには、ユーザーが操作する「ビュー」と、拡張機能が基盤となるリソースとやり取りするために使用する「ドキュメントモデル」という 2 つの側面があります。
カスタムエディタのビュー側は、webview を使用して実装されます。これにより、標準的な HTML、CSS、JavaScript を使用してカスタムエディタのユーザーインターフェイスを構築できます。Webview は VS Code API に直接アクセスすることはできませんが、メッセージの送受信を行うことで拡張機能と通信できます。Webview とそのベストプラクティスに関する詳細については、webview のドキュメント を参照してください。
カスタムエディタのもう一つの側面はドキュメントモデルです。このモデルは、拡張機能が操作しているリソース(ファイル)をどのように理解するかを定義するものです。CustomTextEditorProvider は、ドキュメントモデルとして VS Code の標準である TextDocument を使用し、ファイルへのすべての変更は VS Code の標準的なテキスト編集 API を使用して表現されます。一方で CustomReadonlyEditorProvider と CustomEditorProvider は、独自のドキュメントモデルを提供できるため、非テキストファイル形式に対しても使用可能です。
カスタムエディタはリソースごとに 1 つのドキュメントモデルを持ちますが、そのドキュメントに対するエディタインスタンス(ビュー)は複数存在することがあります。例えば、CustomTextEditorProvider を持つファイルを開き、[エディタの分割] (View: Split editor) コマンドを実行したとします。この場合、ワークスペース内にはリソースのコピーが 1 つしかないため TextDocument も 1 つですが、そのリソースに対する webview は 2 つ存在することになります。
CustomEditor と CustomTextEditor の比較
カスタムエディタには、カスタムテキストエディタとカスタムエディタの 2 つのクラスがあります。これらの主な違いは、ドキュメントモデルをどのように定義するかです。
CustomTextEditorProvider は、データモデルとして VS Code の標準である TextDocument を使用します。テキストベースのファイル形式であればどのようなものにも CustomTextEditor を使用できます。VS Code は既にテキストファイルの扱い方を知っており、保存やホットエグジット(終了時の状態保存)のためのバックアップといった操作を自動的に実装できるため、CustomTextEditor の方が実装はずっと簡単です。
一方で CustomEditorProvider を使用する場合、拡張機能側が独自のドキュメントモデルを持ち込みます。これは、画像のようなバイナリ形式に CustomEditor を使用できることを意味しますが、同時に保存やバックアップの実装など、拡張機能側の責任が大幅に増えることも意味します。プレビュー用カスタムエディタのように読み取り専用であれば、この複雑さの多くを回避できます。
どちらのタイプのカスタムエディタを使用するかを決定する際、通常は単純です。テキストベースのファイル形式を扱う場合は CustomTextEditorProvider を、バイナリファイル形式の場合は CustomEditorProvider を使用してください。
貢献ポイント
customEditors 貢献ポイントは、拡張機能が提供するカスタムエディタを VS Code に伝えるための方法です。例えば、VS Code はカスタムエディタがどのような種類のファイルで動作するか、また UI 上でどのようにカスタムエディタを識別するかを知る必要があります。
以下は、カスタムエディタ拡張機能サンプル の基本的な customEditor 貢献設定です。
"contributes": {
"customEditors": [
{
"viewType": "catEdit.catScratch",
"displayName": "Cat Scratch",
"selector": [
{
"filenamePattern": "*.cscratch"
}
],
"priority": "default"
}
]
}
customEditors は配列であるため、拡張機能は複数のカスタムエディタを登録できます。カスタムエディタのエントリ自体を詳しく見ていきましょう。
-
viewType- カスタムエディタの一意の識別子。これは、
package.jsonでのカスタムエディタ貢献と、コード内の実装を VS Code が結びつける方法です。これはすべての拡張機能間で一意である必要があるため、"preview"のような汎用的なviewTypeは避け、"viewType": "myAmazingExtension.svgPreview"のように拡張機能固有のものを使用してください。 -
displayName- VS Code の UI 上でカスタムエディタを識別するための名前。表示名は、[次で開く] (View: Reopen with) ドロップダウンなどの VS Code UI でユーザーに表示されます。
-
selector- カスタムエディタが有効になるファイルを指定します。selectorは 1 つ以上の glob パターン の配列です。これらの glob パターンはファイル名と照合され、カスタムエディタがそれらに対して使用できるかどうかを判断します。*.pngのようなfilenamePatternは、すべての PNG ファイルに対してカスタムエディタを有効にします。また、ファイル名やディレクトリ名に一致する、より具体的なパターンを作成することもできます(例:
**/translations/*.json)。 -
priority- (オプション) カスタムエディタが使用されるタイミングを指定します。priorityは、リソースが開かれたときにカスタムエディタが使用されるタイミングを制御します。可能な値は以下の通りです。"default"- カスタムエディタのselectorに一致するすべてのファイルでカスタムエディタの使用を試みます。特定のファイルに対して複数のカスタムエディタがある場合、ユーザーは使用するものを選択する必要があります。"option"- デフォルトではカスタムエディタを使用せず、ユーザーが手動で切り替えるか、デフォルトとして構成できるようにします。
カスタムエディタの有効化
ユーザーがカスタムエディタを開くと、VS Code は onCustomEditor:VIEW_TYPE アクティベーションイベントを発火します。アクティベーション中、拡張機能は registerCustomEditorProvider を呼び出し、期待される viewType でカスタムエディタを登録する必要があります。
重要な注意点として、onCustomEditor は VS Code がカスタムエディタのインスタンスを作成する必要があるときにのみ呼び出されます。VS Code が単に使用可能なカスタムエディタに関する情報をユーザーに表示しているだけの場合([次で開く] コマンドなど)、拡張機能はアクティブ化されません。
カスタムテキストエディタ
カスタムテキストエディタを使用すると、テキストファイル用のカスタムエディタを作成できます。これはプレーンな非構造化テキストから CSV、JSON、XML まで何でも構いません。カスタムテキストエディタは、ドキュメントモデルとして VS Code の標準である TextDocument を使用します。
カスタムエディタ拡張機能サンプル には、Cat Scratch ファイル(.cscratch という拡張子を持つ JSON ファイル)用の単純なカスタムテキストエディタの例が含まれています。カスタムテキストエディタの実装における重要なポイントをいくつか見てみましょう。
カスタムテキストエディタのライフサイクル
VS Code は、カスタムテキストエディタのビューコンポーネント(webview)とモデルコンポーネント(TextDocument)の両方のライフサイクルを管理します。新しいカスタムエディタインスタンスを作成する必要があるとき、VS Code は拡張機能を呼び出し、ユーザーがタブを閉じるときにはエディタインスタンスとドキュメントモデルをクリーンアップします。
これが実際にどのように機能するかを理解するために、ユーザーがカスタムテキストエディタを開いてから閉じるまでの間、拡張機能から見て何が起こるかを確認しましょう。
カスタムテキストエディタを開く
カスタムエディタ拡張機能サンプル を使用して、ユーザーが最初に .cscratch ファイルを開いたときに何が起こるかを示します。
-
VS Code は
onCustomEditor:catCustoms.catScratchアクティベーションイベントを発火します。まだアクティブ化されていない場合、拡張機能がアクティブ化されます。アクティベーション中、拡張機能は
registerCustomEditorProviderを呼び出して、catCustoms.catScratch用のCustomTextEditorProviderを確実に登録する必要があります。 -
次に VS Code は、
catCustoms.catScratch用に登録されたCustomTextEditorProviderのresolveCustomTextEditorを呼び出します。このメソッドは、開かれているリソースの
TextDocumentとWebviewPanelを受け取ります。拡張機能は、この webview パネルの初期 HTML コンテンツを入力する必要があります。
resolveCustomTextEditor が返されると、カスタムエディタがユーザーに表示されます。webview 内に何を描画するかは、拡張機能次第です。
このフローは、カスタムエディタを開くたびに発生します。カスタムエディタを分割した場合でも同様です。カスタムエディタの各インスタンスには独自の WebviewPanel がありますが、同じリソースであれば、複数のカスタムテキストエディタが同じ TextDocument を共有します。覚えておいてください:TextDocument はリソースのモデルであり、webview パネルはそのモデルのビューであると考えてください。
カスタムテキストエディタを閉じる
ユーザーがカスタムテキストエディタを閉じると、VS Code は WebviewPanel 上で WebviewPanel.onDidDispose イベントを発火します。この時点で、拡張機能はエディタに関連付けられたリソース(イベント購読、ファイル監視など)をクリーンアップする必要があります。
特定のリソースに対する最後のカスタムエディタが閉じられると、他にそれを使用しているエディタや、他の拡張機能が保持していない限り、そのリソースの TextDocument も破棄されます。TextDocument.isClosed プロパティを確認して、ドキュメントが閉じられたかどうかを確認できます。一旦 TextDocument が閉じられると、同じリソースをカスタムエディタで開き直すと、新しい TextDocument が開かれます。
TextDocument との変更の同期
カスタムテキストエディタは TextDocument をドキュメントモデルとして使用するため、カスタムエディタ内で編集が発生したときは TextDocument を更新し、TextDocument が変更されたときは自身を更新する責任があります。
Webview から TextDocument へ
カスタムテキストエディタでの編集は、ボタンのクリック、テキストの変更、アイテムのドラッグなど、さまざまな形をとります。ユーザーがカスタムテキストエディタ内で直接ファイルを編集するたびに、拡張機能は TextDocument を更新する必要があります。Cat Scratch 拡張機能での実装例は以下の通りです。
-
ユーザーが webview 内の [Add scratch] ボタンをクリックします。これは、webview から拡張機能へメッセージをポストします。
-
拡張機能がメッセージを受け取ります。次に、ドキュメントの内部モデルを更新します(Cat Scratch の例では、JSON に新しいエントリを追加するだけです)。
-
拡張機能は、更新された JSON をドキュメントに書き込む
WorkspaceEditを作成します。この編集はvscode.workspace.applyEditを使用して適用されます。
ワークスペースの編集は、ドキュメントの更新に必要な最小限の変更にとどめるようにしてください。また、JSON のような言語を扱う場合は、ユーザーの既存のフォーマット規則(スペース vs タブ、インデントサイズなど)に従うように努めてください。
TextDocument から webview へ
TextDocument が変更されたとき、拡張機能は webview がドキュメントの新しい状態を反映していることを確認する必要もあります。TextDocument は、元に戻す (undo)、やり直し (redo)、ファイルのリバートなどのユーザー操作や、他の拡張機能による WorkspaceEdit、またはユーザーが VS Code の標準テキストエディタでファイルを開いた際などに変更される可能性があります。Cat Scratch 拡張機能での実装例は以下の通りです。
-
拡張機能内で、
vscode.workspace.onDidChangeTextDocumentイベントを購読します。このイベントは、TextDocumentに対するすべての変更に対して発火されます(カスタムエディタ自身による変更も含まれます!)。 -
エディタを開いているドキュメントに変更があった場合、新しいドキュメントの状態を webview にメッセージとして送ります。webview は、更新されたドキュメントをレンダリングするために自身を更新します。
カスタムエディタがトリガーするファイル編集が onDidChangeTextDocument を発火させることを忘れないでください。拡張機能が更新ループに陥らないようにしてください。例えば:webview 内での編集 → onDidChangeTextDocument が発火 → webview が更新 → 拡張機能への別の更新がトリガー → onDidChangeTextDocument が再度発火、という無限ループです。
また、JSON や XML のような構造化言語を扱う場合、ドキュメントが常に有効な状態であるとは限りません。拡張機能は、エラーを適切に処理するか、何が問題でどう修正すべきかをユーザーが理解できるようにエラーメッセージを表示する必要があります。
最後に、webview の更新処理が重い場合は、デバウンス (debouncing) を検討してください。
カスタムエディタ
CustomEditorProvider と CustomReadonlyEditorProvider を使用すると、バイナリファイル形式用のカスタムエディタを作成できます。この API は、ファイルの表示方法、編集方法、そして保存 (save) やその他のファイル操作へのフックなど、ユーザーに対する表示方法を完全に制御できます。繰り返しになりますが、テキストベースのファイル形式用のエディタを構築している場合は、実装が非常に単純な CustomTextEditor の使用を強く検討してください。
カスタムエディタ拡張機能サンプル には、Paw Draw ファイル(.pawdraw という拡張子を持つ JPEG ファイル)用の単純なカスタムバイナリエディタの例が含まれています。バイナリファイル用のカスタムエディタ構築について見ていきましょう。
CustomDocument
カスタムエディタでは、拡張機能が CustomDocument インターフェイスを使用して独自のドキュメントモデルを実装する責任を負います。これにより、カスタムエディタとやり取りするために必要なデータは自由に CustomDocument に格納できますが、同時に、保存やホットエグジットのためのファイルデータバックアップといった基本的なドキュメント操作をすべて実装する必要があります。
開かれたファイルごとに 1 つの CustomDocument が存在します。ユーザーは単一のリソースに対して複数のエディタ(現在のカスタムエディタの分割など)を開くことができますが、それらすべてのエディタは同じ CustomDocument によって支えられます。
カスタムエディタのライフサイクル
supportsMultipleEditorsPerDocument
デフォルトでは、VS Code は各カスタムドキュメントにつき 1 つのエディタしか許可しません。この制限により、複数のカスタムエディタインスタンスを相互に同期させることを心配する必要がなくなり、カスタムエディタを正しく実装しやすくなります。
ただし、拡張機能がサポートできる場合は、カスタムエディタ登録時に supportsMultipleEditorsPerDocument: true を設定することをお勧めします。これにより、同じドキュメントに対して複数のエディタインスタンスを開くことができ、カスタムエディタが VS Code の通常のテキストエディタのような挙動をするようになります。
カスタムエディタを開く ユーザーが customEditor 貢献ポイントに一致するファイルを開くと、VS Code は onCustomEditor アクティベーションイベントを発火し、提供されたビュータイプに対して登録されたプロバイダーを呼び出します。CustomEditorProvider には、カスタムエディタ用のドキュメントを提供する役割と、エディタ自体を提供する役割の 2 つがあります。カスタムエディタ拡張機能サンプル の catCustoms.pawDraw エディタで起こることの順序付きリストを以下に示します。
-
VS Code は
onCustomEditor:catCustoms.pawDrawアクティベーションイベントを発火します。まだアクティブ化されていない場合、拡張機能がアクティブ化されます。拡張機能は、アクティベーション中に
catCustoms.pawDraw用のCustomReadonlyEditorProviderまたはCustomEditorProviderを確実に登録する必要があります。 -
VS Code は、
catCustoms.pawDrawエディタ用に登録されたCustomReadonlyEditorProviderまたはCustomEditorProviderのopenCustomDocumentを呼び出します。ここで拡張機能にはリソース URI が与えられ、そのリソースに対する新しい
CustomDocumentを返す必要があります。このタイミングで、拡張機能はそのリソースに対する内部モデルを作成します。これには、ディスクからリソースの初期状態を読み取ってパースしたり、新しいCustomDocumentを初期化したりする作業が含まれます。拡張機能は、
CustomDocumentを実装する新しいクラスを作成することで、このモデルを定義できます。この初期化フェーズは完全に拡張機能次第です。VS Code は、拡張機能がCustomDocumentに保存する追加情報については関与しません。 -
VS Code は、手順 2 で作成した
CustomDocumentと新しいWebviewPanelを引数としてresolveCustomEditorを呼び出します。ここで拡張機能はカスタムエディタ用の初期 HTML を入力する必要があります。必要に応じて、コマンド内などで後から参照できるように
WebviewPanelへの参照を保持することも可能です。
resolveCustomEditor が返されると、カスタムエディタがユーザーに表示されます。
ユーザーが同じカスタムエディタを使用して別のエディタグループで同じリソースを開いた場合(最初のエディタを分割するなど)、拡張機能の仕事は単純化されます。この場合、VS Code は最初のエディタが開かれたときに作成したのと同じ CustomDocument を使用して resolveCustomEditor を呼び出します。
カスタムエディタを閉じる
同じリソースに対して 2 つのカスタムエディタインスタンスが開かれているとします。ユーザーがこれらのエディタを閉じると、VS Code は拡張機能に通知し、エディタに関連付けられたリソースをクリーンアップできるようにします。
最初のエディタインスタンスが閉じられると、VS Code は閉じたエディタの WebviewPanel 上で WebviewPanel.onDidDispose イベントを発火します。この時点で、拡張機能はその特定のエディタインスタンスに関連付けられたリソースをクリーンアップする必要があります。
2 つ目のエディタが閉じられると、VS Code は再び WebviewPanel.onDidDispose を発火します。しかし今度は CustomDocument に関連付けられたすべてのエディタが閉じられたことになります。CustomDocument に対するエディタがこれ以上ない場合、VS Code はその CustomDocument.dispose を呼び出します。拡張機能の dispose 実装は、ドキュメントに関連付けられたリソースをクリーンアップしなければなりません。
ユーザーが同じカスタムエディタを使用して同じリソースを開き直すと、新しい CustomDocument を伴う openCustomDocument と resolveCustomEditor の全フローが再度実行されます。
読み取り専用カスタムエディタ
以下のセクションの多くは編集をサポートするカスタムエディタのみに適用されますが、逆説的に聞こえるかもしれませんが、多くのカスタムエディタは編集機能を全く必要としません。例えば画像プレビューや、メモリダンプの視覚的レンダリングなどを考えてみてください。どちらもカスタムエディタを使用して実装できますが、編集可能である必要はありません。そこで CustomReadonlyEditorProvider の出番です。
CustomReadonlyEditorProvider を使用すると、編集をサポートしないカスタムエディタを作成できます。それらは依然として対話可能ですが、元に戻す (undo) や保存 (save) といった操作はサポートされません。完全に編集可能なエディタと比べて、読み取り専用のカスタムエディタの実装はずっと簡単です。
編集可能なカスタムエディタの基礎
編集可能なカスタムエディタを使用すると、元に戻す/やり直し、保存、ホットエグジットといった標準的な VS Code 操作にフックできます。これにより非常に強力になりますが、適切に実装するには、カスタムテキストエディタや読み取り専用のカスタムエディタよりもはるかに複雑な処理が必要になります。
編集可能なカスタムエディタは CustomEditorProvider によって実装されます。このインターフェイスは CustomReadonlyEditorProvider を継承しているため、openCustomDocument や resolveCustomEditor といった基本操作に加え、編集専用の操作セットを実装する必要があります。CustomEditorProvider の編集固有の部分を見ていきましょう。
編集(Edits)
編集可能なカスタムドキュメントへの変更は「編集 (edits)」として表現されます。編集とは、テキスト変更から画像の回転、リストの順序変更まで何でもありえます。編集が具体的に何を行うかの詳細は VS Code ではなく拡張機能に委ねられていますが、VS Code はいつ編集が行われたかを知る必要があります。編集は VS Code がドキュメントを「ダーティ(未保存状態)」としてマークするための手段であり、これにより自動保存やバックアップが有効になります。
ユーザーがカスタムエディタのいずれかの webview で編集を行うたびに、拡張機能は CustomEditorProvider から onDidChangeCustomDocument イベントを発火させる必要があります。onDidChangeCustomDocument イベントは、カスタムエディタの実装に応じて CustomDocumentContentChangeEvent と CustomDocumentEditEvent という 2 つのイベントタイプを発火できます。
CustomDocumentContentChangeEvent
CustomDocumentContentChangeEvent は、最小限の編集イベントです。その唯一の機能は、ドキュメントが編集されたことを VS Code に伝えることです。
拡張機能が onDidChangeCustomDocument から CustomDocumentContentChangeEvent を発火させると、VS Code は関連付けられたドキュメントを「ダーティ」としてマークします。この時点で、ドキュメントがダーティでなくなる唯一の方法は、ユーザーが保存するかリバート(元に戻す)することだけです。CustomDocumentContentChangeEvent を使用するカスタムエディタは、元に戻す/やり直しをサポートしません。
CustomDocumentEditEvent
CustomDocumentEditEvent は、元に戻す/やり直しを可能にする、より複雑な編集イベントです。常に CustomDocumentEditEvent を使用してカスタムエディタを実装するように努め、元に戻す/やり直しの実装が不可能な場合にのみ CustomDocumentContentChangeEvent の使用にフォールバックしてください。
CustomDocumentEditEvent には以下のフィールドがあります。
document— 編集対象のCustomDocument。label— どのような種類の編集が行われたかを記述するオプションのテキスト(例: "Crop", "Insert" など)。undo— 編集を元に戻す必要があるときに VS Code によって呼び出される関数。redo— 編集をやり直す必要があるときに VS Code によって呼び出される関数。
拡張機能が onDidChangeCustomDocument から CustomDocumentEditEvent を発火させると、VS Code は関連付けられたドキュメントを「ダーティ」としてマークします。ドキュメントをダーティでなくすには、ユーザーがドキュメントを保存するかリバートするか、あるいは元に戻す/やり直し操作によってドキュメントを最後に保存された状態まで戻す必要があります。
エディタ上の undo メソッドと redo メソッドは、その特定の編集を元に戻すか再適用する必要があるときに VS Code によって呼び出されます。VS Code は編集の内部スタックを保持しているため、拡張機能が 3 つの編集(a、b、c としましょう)で onDidChangeCustomDocument を発火させたとすると、
onDidChangeCustomDocument(a);
onDidChangeCustomDocument(b);
onDidChangeCustomDocument(c);
以下のユーザー操作シーケンスにより、これらの呼び出しが発生します。
undo — c.undo()
undo — b.undo()
redo — b.redo()
redo — c.redo()
redo — no op, no more edits
元に戻す/やり直しを実装するには、拡張機能が関連付けられたカスタムドキュメントの内部状態を更新し、すべての関連する webview に対してドキュメントの新しい状態を反映させる必要があります。1 つのリソースに対して複数の webview が存在する可能性があることを忘れないでください。これらは常に同じドキュメントデータを表示しなければなりません。例えば、画像エディタの複数のインスタンスは、常に同じピクセルデータを表示する必要がありますが、各エディタインスタンスが独自のズームレベルや UI 状態を持つことは許容されます。
保存
ユーザーがカスタムエディタを保存すると、拡張機能は保存されたリソースを現在の状態でディスクに書き込む責任を負います。カスタムエディタがこれをどのように行うかは、主に拡張機能の CustomDocument タイプと、拡張機能がどのように編集を内部的に追跡しているかに依存します。
保存の最初のステップは、ディスクに書き込むデータストリームを取得することです。一般的なアプローチは以下の通りです。
-
リソースの状態を追跡し、迅速にシリアライズできるようにする。
例えば、基本的な画像エディタはピクセルデータのバッファを保持します。
-
最後の保存以降の編集をリプレイして、新しいファイルを生成する。
より効率的な画像エディタであれば、最後の保存以降の編集(
crop、rotate、scaleなど)を追跡するかもしれません。保存時に、これらの編集をファイルの最後の保存済み状態に適用して、新しいファイルを生成します。 -
カスタムエディタの
WebviewPanelに保存用のファイルデータを要求する。ただし、カスタムエディタは非表示の状態でも保存される可能性があることを念頭に置いてください。このため、拡張機能の
save実装はWebviewPanelに依存しないことが推奨されます。それが不可能な場合は、WebviewPanelOptions.retainContextWhenHidden設定を使用して、webview が非表示でも生存し続けるようにできます。retainContextWhenHiddenは大きなメモリオーバーヘッドを伴うため、使用には注意が必要です。
リソースのデータを取得した後、一般的には ワークスペース FS API を使用してディスクに書き込みます。FS API は UInt8Array のデータを受け取り、バイナリファイルとテキストファイルの両方を書き出すことができます。バイナリファイルデータの場合は、バイナリデータをそのまま UInt8Array に入れます。テキストファイルデータの場合は、Buffer を使用して文字列を UInt8Array に変換します。
const writeData = Buffer.from('my text data', 'utf8');
vscode.workspace.fs.writeFile(fileUri, writeData);
次のステップ
VS Code の拡張機能開発についてさらに学習したい場合は、以下のトピックを試してください。