カスタムエディター API
カスタムエディターを使用すると、拡張機能は、特定の種類のリソースに対して VS Code の標準テキストエディターの代わりに使用される、完全にカスタマイズ可能な読み取り/書き込みエディターを作成できます。これらには、次のような幅広いユースケースがあります。
- シェーダーや 3D モデルなどのアセットを VS Code で直接プレビューする。
- Markdown や XAML などの言語用の WYSIWYG エディターを作成する。
- CSV、JSON、XML などのデータファイルに代替の視覚的レンダリングを提供する。
- バイナリファイルまたはテキストファイル用の完全にカスタマイズ可能な編集エクスペリエンスを構築する。
このドキュメントでは、カスタムエディター API の概要とカスタムエディターを実装する基本について説明します。2 種類のカスタムエディターと、それらの違い、およびユースケースに最適なエディターについて説明します。次に、これらの各カスタムエディタータイプについて、適切に動作するカスタムエディターを構築する基本について説明します。
カスタムエディターは強力な新しい拡張ポイントですが、基本的なカスタムエディターの実装は実際にはそれほど難しくありません。ただし、初めての VS Code 拡張機能に取り組んでいる場合は、VS Code API の基本に慣れるまで、カスタムエディターに深く入り込むのを控えることを検討することをお勧めします。カスタムエディターは、webview やテキストドキュメントなど、VS Code の多くの概念に基づいて構築されているため、これらの新しいアイデアをすべて同時に学ぶ場合は、少し overwhelming に感じるかもしれません。
しかし、準備ができていて、これから構築する素晴らしいカスタムエディターについて考えているのであれば、始めましょう!ドキュメントに沿って、カスタムエディター 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
では独自のドキュメントモデルを提供できるため、非テキストファイル形式でも使用できます。
カスタムエディターはリソースごとに単一のドキュメントモデルを持ちますが、このドキュメントには複数のエディターインスタンス(ビュー)が存在する場合があります。たとえば、CustomTextEditorProvider
を持つファイルを開き、**「ビュー: エディターを分割」**コマンドを実行することを想像してみてください。この場合、ワークスペース内のリソースのコピーは1つしかないため、TextDocument
は1つだけですが、そのリソースには2つのwebviewが存在することになります。
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
- カスタムエディターの一意の識別子。これは、VS Code が
package.json
のカスタムエディターコントリビューションをコード内のカスタムエディター実装に結び付ける方法です。これはすべての拡張機能で一意である必要があるため、"preview"
のような一般的なviewType
の代わりに、"viewType": "myAmazingExtension.svgPreview"
のように拡張機能に一意なものを使用するようにしてください。 -
displayName
- VS Code の UI でカスタムエディターを識別する名前。表示名は、**ビュー: 再び開く**ドロップダウンなどのVS Code UIでユーザーに表示されます。
-
selector
- カスタムエディターが有効になるファイルを指定します。selector
は、1つ以上のglob パターンの配列です。これらのglobパターンは、ファイル名と照合され、カスタムエディターを使用できるかどうかが判断されます。*.png
のようなfilenamePattern
は、すべてのPNGファイルでカスタムエディターを有効にします。ファイル名やディレクトリ名に一致する、より具体的なパターンを作成することもできます。たとえば、
**/translations/*.json
。 -
priority
- (オプション) カスタムエディターが使用される時期を指定します。priority
は、リソースが開かれたときにカスタムエディターがいつ使用されるかを制御します。可能な値は次のとおりです。"default"
- カスタムエディターのselector
に一致するすべてのファイルにカスタムエディターを使用しようとします。特定のファイルに複数のカスタムエディターがある場合、ユーザーは使用したいカスタムエディターを選択する必要があります。"option"
- デフォルトではカスタムエディターを使用しませんが、ユーザーが切り替えたり、デフォルトとして設定したりできるようにします。
カスタムエディターのアクティベーション
ユーザーがカスタムエディターのいずれかを開くと、VS Code は onCustomEditor:VIEW_TYPE
アクティベーションイベントを発生させます。アクティベーション中に、拡張機能は期待される viewType
を持つカスタムエディターを登録するために registerCustomEditorProvider
を呼び出す必要があります。
onCustomEditor
は、VS Code がカスタムエディターのインスタンスを作成する必要がある場合にのみ呼び出されることに注意することが重要です。VS Code が利用可能なカスタムエディターに関する情報を単に表示するだけの場合(**ビュー: 再び開く**コマンドなど)、拡張機能はアクティブ化されません。
カスタムテキストエディター
カスタムテキストエディターを使用すると、テキストファイル用のカスタムエディターを作成できます。これには、構造化されていないプレーンテキストから、CSV、JSON、XML まで、あらゆるものが含まれます。カスタムテキストエディターは、VS Code の標準のTextDocumentをドキュメントモデルとして使用します。
カスタムエディター拡張機能サンプルには、猫のスクラッチファイル(.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
を更新する責任があり、またTextDocument
が変更されるたびに自身を更新する責任があります。
webviewからTextDocument
へ
カスタムテキストエディターでの編集は、ボタンのクリック、テキストの変更、項目のドラッグなど、さまざまな形式をとることができます。ユーザーがカスタムテキストエディター内でファイル自体を編集するたびに、拡張機能はTextDocument
を更新する必要があります。猫のスクラッチ拡張機能がこれをどのように実装しているかを見てみましょう。
-
ユーザーがwebviewの**「スクラッチを追加」**ボタンをクリックします。これにより、webviewから拡張機能にメッセージがポストされます。
-
拡張機能がメッセージを受信します。その後、ドキュメントの内部モデルを更新します(猫のスクラッチの例では、JSON に新しいエントリを追加するだけです)。
-
拡張機能は、更新されたJSONをドキュメントに書き込む
WorkspaceEdit
を作成します。この編集はvscode.workspace.applyEdit
を使用して適用されます。
ワークスペース編集をドキュメントを更新するために必要な最小限の変更に留めるようにしてください。また、JSONのような言語を扱っている場合、拡張機能はユーザーの既存の書式設定規則(スペースとタブ、インデントサイズなど)を遵守するように努めるべきであることを念頭に置いてください。
TextDocument
からwebviewへ
TextDocument
が変更されると、拡張機能もwebviewがドキュメントの新しい状態を反映するようにする必要があります。TextDocumentは、元に戻す、やり直す、ファイルの復元などのユーザーアクション、他の拡張機能によるWorkspaceEdit
の使用、またはVS Codeのデフォルトのテキストエディターでファイルを開くユーザーによって変更される可能性があります。猫のスクラッチ拡張機能がこれをどのように実装しているかを見てみましょう。
-
拡張機能では、
vscode.workspace.onDidChangeTextDocument
イベントを購読します。このイベントは、TextDocument
へのすべての変更(カスタムエディターが行う変更も含む!)に対して発火されます。 -
エディターを持つドキュメントに変更があった場合、新しいドキュメントの状態をWebviewにメッセージとして送信します。このWebviewは、更新されたドキュメントをレンダリングするために自身を更新します。
カスタムエディターがトリガーするファイル編集はすべてonDidChangeTextDocument
を発生させることを覚えておくことが重要です。ユーザーがwebviewで編集を行い、それがonDidChangeTextDocument
を発火し、webviewが更新され、それがwebviewで拡張機能の別の更新をトリガーし、onDidChangeTextDocument
が発火し続けるといった更新ループに拡張機能が陥らないように注意してください。
また、JSONやXMLのような構造化言語を扱っている場合、ドキュメントが常に有効な状態にあるとは限らないことを覚えておいてください。拡張機能は、エラーを適切に処理できるか、ユーザーにエラーメッセージを表示して、何が問題でどうすれば修正できるかを理解できるようにする必要があります。
最後に、webviewの更新にコストがかかる場合は、webviewの更新のデバウンスを検討してください。
カスタムエディター
CustomEditorProvider
と CustomReadonlyEditorProvider
を使用すると、バイナリファイル形式用のカスタムエディターを作成できます。この API は、ファイルの表示方法、編集方法を完全に制御でき、拡張機能が save
やその他のファイル操作にフックできるようにします。繰り返しになりますが、テキストベースのファイル形式用のエディターを構築する場合は、はるかに簡単に実装できるCustomTextEditor
を使用することを強く検討してください。
カスタムエディター拡張機能サンプルには、猫の爪痕ファイル(.pawdraw
ファイル拡張子で終わる単なるJPEGファイル)用の簡単なカスタムバイナリエディターの例が含まれています。バイナリファイル用のカスタムエディターを構築する際に必要なものを見てみましょう。
CustomDocument
カスタムエディターでは、拡張機能はCustomDocument
インターフェースを使用して独自のドキュメントモデルを実装する責任があります。これにより、拡張機能はカスタムエディターと対話するために必要なデータをCustomDocument
に自由に格納できますが、保存やホットイグジットのためのファイルデータのバックアップなどの基本的なドキュメント操作を拡張機能が実装する必要があることも意味します。
開かれたファイルごとにCustomDocument
は1つだけです。ユーザーは1つのリソースに対して複数のエディターを開くことができますが(現在のカスタムエディターを分割するなど)、それらのすべてのエディターは同じ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
を使用すると、編集をサポートしないカスタムエディターを作成できます。これらはインタラクティブであることはできますが、元に戻すや保存などの操作はサポートしていません。また、読み取り専用のカスタムエディターは、完全に編集可能なエディターに比べてはるかに実装が簡単です。
編集可能なカスタムエディターの基本
編集可能なカスタムエディターを使用すると、元に戻す、やり直す、保存、ホットイグジットなどの標準的なVS Codeの操作にフックできます。これにより、編集可能なカスタムエディターは非常に強力になりますが、正しく実装するには、編集可能なカスタムテキストエディターや読み取り専用カスタムエディターを実装するよりもはるかに複雑になります。
編集可能なカスタムエディターは、CustomEditorProvider
によって実装されます。このインターフェースはCustomReadonlyEditorProvider
を拡張しているため、openCustomDocument
やresolveCustomEditor
などの基本的な操作と、編集固有の操作を実装する必要があります。CustomEditorProvider
の編集固有の部分を見てみましょう。
編集
編集可能なカスタムドキュメントへの変更は、編集によって表現されます。編集は、テキストの変更、画像の回転、リストの並べ替えなど、何でもかまいません。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は編集の内部スタックを維持しているため、拡張機能がonDidChangeCustomDocument
を3つの編集(a
、b
、c
としましょう)で発火した場合、
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 の拡張性についてさらに詳しく知りたい場合は、以下のトピックを試してみてください。