VS Codeのエージェントモードを拡張するには、を試してください!

カスタムエディター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のドキュメントを参照してください。

カスタムエディターのもう1つの部分はドキュメントモデルです。このモデルは、拡張機能が操作するリソース (ファイル) をどのように理解するかを定義します。`CustomTextEditorProvider`は、VS Codeの標準のTextDocumentをドキュメントモデルとして使用し、ファイルへのすべての変更はVS Codeの標準のテキスト編集APIを使用して表現されます。一方、`CustomReadonlyEditorProvider`と`CustomEditorProvider`では独自のドキュメントモデルを提供できるため、非テキストファイル形式にも使用できます。

カスタムエディターにはリソースごとに単一のドキュメントモデルがありますが、このドキュメントには複数のエディターインスタンス (ビュー) が存在する可能性があります。たとえば、`CustomTextEditorProvider`を持つファイルを開き、次に**表示: エディターの分割**コマンドを実行するとします。この場合、ワークスペースにはリソースのコピーが1つしかないため、`TextDocument`は引き続き1つだけですが、そのリソースには2つのWebviewが存在します。

CustomEditorCustomTextEditor

カスタムエディターには、カスタムテキストエディターとカスタムエディターの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つ以上のグロブパターンの配列です。これらのグロブパターンは、ファイル名と照合され、カスタムエディターがそれらに使用できるかどうかを判断します。*.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をドキュメントモデルとして使用します。

カスタムエディター拡張機能サンプルには、猫のスクラッチファイル(.cscratchファイル拡張子で終わるJSONファイル)用の簡単なカスタムテキストエディターの例が含まれています。カスタムテキストエディターを実装する上で重要な点をいくつか見てみましょう。

カスタムテキストエディターのライフサイクル

VS Codeは、カスタムテキストエディターのビューコンポーネント(webviews)とモデルコンポーネント(TextDocument)の両方のライフサイクルを管理します。VS Codeは、新しいカスタムエディターインスタンスを作成する必要があるときに拡張機能に呼び出しを行い、ユーザーがタブを閉じるとエディターインスタンスとドキュメントモデルをクリーンアップします。

これらが実際にどのように機能するかを理解するために、ユーザーがカスタムテキストエディターを開いたとき、そしてユーザーがカスタムテキストエディターを閉じたときに、拡張機能の観点から何が起こるかを見ていきましょう。

カスタムテキストエディターを開く

カスタムエディター拡張機能サンプルを使用して、ユーザーが最初に.cscratchファイルを開いたときに何が起こるかを示します。

  1. VS CodeはonCustomEditor:catCustoms.catScratchアクティベーションイベントを発生させます。

    これにより、拡張機能がまだアクティブ化されていない場合はアクティブ化されます。アクティブ化中に、拡張機能はregisterCustomEditorProviderを呼び出すことにより、catCustoms.catScratchCustomTextEditorProviderを登録する必要があります。

  2. VS Codeは、catCustoms.catScratch用に登録されたCustomTextEditorProviderresolveCustomTextEditorを呼び出します。

    このメソッドは、開いているリソースのTextDocumentWebviewPanelを受け取ります。拡張機能は、この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を更新する必要があります。猫のスクラッチ拡張機能がこれを実装する方法を次に示します。

  1. ユーザーはWebviewの**スクラッチを追加**ボタンをクリックします。これにより、Webviewから拡張機能にメッセージが送信されます

  2. 拡張機能がメッセージを受信します。次に、ドキュメントの内部モデル(cat scratchの例では、JSONに新しいエントリを追加するだけです)を更新します。

  3. 拡張機能は、更新されたJSONをドキュメントに書き込むWorkspaceEditを作成します。この編集はvscode.workspace.applyEditを使用して適用されます。

ワークスペースの編集は、ドキュメントを更新するために必要な最小限の変更に抑えるようにしてください。また、JSONなどの言語を使用している場合は、拡張機能がユーザーの既存の書式設定規則(スペースとタブ、インデントサイズなど)を尊重するように努める必要があることにも留意してください。

TextDocumentからWebviewへ

TextDocumentが変更されると、拡張機能はそのWebviewがドキュメントの新しい状態を反映していることを確認する必要もあります。TextDocumentは、元に戻す、やり直し、ファイルの復元などのユーザーアクション、WorkspaceEditを使用する他の拡張機能、またはVS Codeのデフォルトのテキストエディターでファイルを開くユーザーによって変更される可能性があります。猫のスクラッチ拡張機能がこれを実装する方法を次に示します。

  1. 拡張機能では、vscode.workspace.onDidChangeTextDocumentイベントを購読します。このイベントは、TextDocumentへのすべての変更(カスタムエディターが行う変更も含む!)に対して発生します。

  2. エディターを持つドキュメントに変更があった場合、新しいドキュメントの状態をWebviewにメッセージで送信します。このWebviewは、更新されたドキュメントをレンダリングするために自身を更新します。

カスタムエディターがトリガーするファイル編集はすべて、`onDidChangeTextDocument`を発火させることを覚えておくことが重要です。ユーザーがWebviewで編集を行い、それが`onDidChangeTextDocument`を発火させ、Webviewを更新させ、それがWebviewが拡張機能に対して別の更新をトリガーさせ、それが`onDidChangeTextDocument`を発火させる、といった更新ループに陥らないように、拡張機能がループに陥らないようにしてください。

また、JSONやXMLなどの構造化言語を使用している場合、ドキュメントが常に有効な状態であるとは限らないことを忘れないでください。拡張機能は、エラーを適切に処理できるか、ユーザーにエラーメッセージを表示して、何が問題でどうすれば修正できるかを理解できるようにする必要があります。

最後に、Webviewの更新にコストがかかる場合は、デバウンスすることを検討してください。

カスタムエディター

CustomEditorProviderCustomReadonlyEditorProvider を使用すると、バイナリファイル形式用のカスタムエディターを作成できます。この API は、ファイルがユーザーにどのように表示されるか、編集がどのように行われるか、および拡張機能が save やその他のファイル操作にフックできるように、完全に制御できます。繰り返しになりますが、テキストベースのファイル形式用のエディターを構築する場合は、はるかに簡単に実装できるため、代わりにCustomTextEditor を使用することを強く検討してください。

カスタムエディター拡張機能サンプルには、猫の足跡ファイル(.pawdrawファイル拡張子で終わるjpegファイル)用の簡単なカスタムバイナリエディターの例が含まれています。バイナリファイル用のカスタムエディターを構築するために何が必要かを見てみましょう。

CustomDocument

カスタムエディターでは、拡張機能はCustomDocumentインターフェイスを使用して独自のドキュメントモデルを実装する必要があります。これにより、拡張機能はカスタムエディターと対話するために必要なデータをCustomDocumentに自由に保存できますが、保存やホットエグジットのためのファイルデータのバックアップなどの基本的なドキュメント操作も実装する必要があることを意味します。

開いているファイルごとに1つのCustomDocumentがあります。ユーザーは単一のリソースに対して複数のエディターを開くことができます(現在のカスタムエディターを分割するなど)が、それらのエディターはすべて同じCustomDocumentによってバックアップされます。

カスタムエディターのライフサイクル

supportsMultipleEditorsPerDocument

デフォルトでは、VS Codeは各カスタムドキュメントに1つのエディターしか許可していません。この制限により、複数のカスタムエディターインスタンスを相互に同期させることを心配する必要がないため、カスタムエディターを正しく実装することが容易になります。

ただし、拡張機能がサポートできる場合は、カスタムエディターを登録する際に`supportsMultipleEditorsPerDocument: true`を設定することをお勧めします。これにより、同じドキュメントに対して複数のエディターインスタンスを開くことができます。これにより、カスタムエディターがVS Codeの通常のテキストエディターのように動作するようになります。

カスタムエディターを開く ユーザーが`customEditor`の貢献ポイントに一致するファイルを開くと、VS Codeは`onCustomEditor` アクティベーションイベントを発火させ、提供されたビュータイプに登録されたプロバイダーを呼び出します。`CustomEditorProvider`には2つの役割があります。カスタムエディターのドキュメントを提供すること、そしてエディター自体を提供することです。以下は、カスタムエディター拡張機能サンプルの`catCustoms.pawDraw`エディターで発生する事柄の順序付きリストです。

  1. VS CodeはonCustomEditor:catCustoms.pawDrawアクティベーションイベントを発火します。

    これにより、まだアクティベートされていない場合は、拡張機能がアクティベートされます。また、アクティベーション中に、catCustoms.pawDrawエディター用にCustomReadonlyEditorProviderまたはCustomEditorProviderを登録していることを確認する必要があります。

  2. VS Codeは、catCustoms.pawDrawエディター用に登録されているCustomReadonlyEditorProviderまたはCustomEditorProvideropenCustomDocumentを呼び出します。

    ここでは、拡張機能にリソースURIが与えられ、そのリソースの新しい`CustomDocument`を返す必要があります。これが、拡張機能がそのリソースのドキュメント内部モデルを作成する時点です。これには、ディスクから初期リソース状態を読み取って解析したり、新しい`CustomDocument`を初期化したりする作業が含まれる場合があります。

    拡張機能は、`CustomDocument`を実装する新しいクラスを作成することで、このモデルを定義できます。この初期化段階は完全に拡張機能に依存することに注意してください。VS Codeは、拡張機能が`CustomDocument`に保存する追加情報には関心がありません。

  3. VS Codeは、ステップ2の`CustomDocument`と新しい`WebviewPanel`を使用して`resolveCustomEditor`を呼び出します。

    ここで、拡張機能はカスタムエディターの初期HTMLを入力する必要があります。必要に応じて、後でコマンド内などで参照できるように、`WebviewPanel`への参照を保持することもできます。

resolveCustomEditorが戻ると、カスタムエディターがユーザーに表示されます。

ユーザーが別のエディターグループでカスタムエディターを使用して同じリソースを開いた場合(例えば、最初のエディターを分割するなど)、拡張機能の作業は簡素化されます。この場合、VS Codeは最初のエディターを開いたときに作成したのと同じCustomDocumentresolveCustomEditorを呼び出すだけです。

カスタムエディターを閉じる

同じリソースに対してカスタムエディターのインスタンスが2つ開いているとします。ユーザーがこれらのエディターを閉じると、VS Codeは拡張機能にシグナルを送り、エディターに関連付けられているリソースをクリーンアップできるようにします。

最初のエディターインスタンスが閉じられると、VS Codeは閉じたエディターのWebviewPanelWebviewPanel.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イベントは、カスタムエディターの実装に応じて、CustomDocumentContentChangeEventCustomDocumentEditEventの2つのイベントタイプを発火させることができます。

CustomDocumentContentChangeEvent

CustomDocumentContentChangeEventは最低限の編集です。その唯一の機能は、ドキュメントが編集されたことをVS Codeに伝えることです。

拡張機能がonDidChangeCustomDocumentからCustomDocumentContentChangeEventを発火させると、VS Codeは関連するドキュメントをダーティとしてマークします。この時点では、ドキュメントがダーティでなくなる唯一の方法は、ユーザーが保存するか元に戻すことです。CustomDocumentContentChangeEventを使用するカスタムエディターは、元に戻す/やり直しをサポートしません。

CustomDocumentEditEvent

CustomDocumentEditEventは、元に戻す/やり直しを可能にするより複雑な編集です。元に戻す/やり直しを実装できない場合のみ、常にCustomDocumentEditEventを使用してカスタムエディターを実装し、CustomDocumentContentChangeEventの使用にフォールバックするようにしてください。

CustomDocumentEditEventには以下のフィールドがあります。

  • document — 編集対象のCustomDocument
  • label — 編集の種類を説明するオプションのテキスト(例:「切り抜き」、「挿入」、...)
  • undo — 編集を元に戻す必要があるときにVS Codeによって呼び出される関数。
  • redo — 編集をやり直す必要があるときにVS Codeによって呼び出される関数。

拡張機能がonDidChangeCustomDocumentからCustomDocumentEditEventを発生させると、VS Codeは関連するドキュメントをダーティとしてマークします。ドキュメントをダーティでない状態に戻すには、ユーザーはドキュメントを保存または元に戻すか、ドキュメントの最後の保存状態まで元に戻す/やり直すことができます。

エディターのundoおよびredoメソッドは、VS Codeによって、その特定の編集を元に戻したり再適用したりする必要があるときに呼び出されます。VS Codeは編集の内部スタックを保持しているため、拡張機能が3つの編集(abcとします)で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も更新して、ドキュメントの新しい状態を反映させる必要があります。単一のリソースに対して複数のWebviewが存在する場合があることを覚えておいてください。これらは常に同じドキュメントデータを表示する必要があります。たとえば、画像エディターの複数のインスタンスは常に同じピクセルデータを表示する必要がありますが、各エディターインスタンスは独自のズームレベルとUI状態を持つことができます。

保存

ユーザーがカスタムエディターを保存すると、拡張機能は、保存されたリソースの現在の状態をディスクに書き込む責任があります。カスタムエディターがこれをどのように行うかは、拡張機能の`CustomDocument`タイプと、拡張機能が編集を内部的にどのように追跡するかに大きく依存します。

保存の最初のステップは、ディスクに書き込むデータストリームを取得することです。これに対する一般的なアプローチには以下が含まれます。

  • リソースの状態を追跡し、迅速にシリアル化できるようにします。

    例えば、基本的な画像エディターはピクセルデータのバッファーを保持することができます。

  • 最終保存以降の編集をリプレイして、新しいファイルを生成します。

    例えば、より効率的な画像エディターは、最終保存以降の編集(「切り抜き」、「回転」、「拡大縮小」など)を追跡する可能性があります。保存時に、これらの編集をファイルの最終保存状態に適用して、新しいファイルを生成します。

  • 保存するファイルデータのために、カスタムエディターの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の拡張性についてさらに詳しく知りたい場合は、以下のトピックをお試しください。