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

カスタムエディター 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を使用して表現されます。一方、CustomReadonlyEditorProviderCustomEditorProviderでは独自のドキュメントモデルを提供できるため、非テキストファイル形式でも使用できます。

カスタムエディターはリソースごとに単一のドキュメントモデルを持ちますが、このドキュメントには複数のエディターインスタンス(ビュー)が存在する場合があります。たとえば、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つ以上の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ファイルを開いたときに何が起こるかを見てみましょう。

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

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

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

    このメソッドは、開かれているリソースのTextDocumentWebviewPanelを受け取ります。拡張機能は、このwebviewパネルの初期HTMLコンテンツを埋める必要があります。

resolveCustomTextEditorが戻ると、カスタムエディターがユーザーに表示されます。webview内に何が描画されるかは、完全に拡張機能次第です。

カスタムエディターを分割する場合でも、カスタムエディターが開かれるたびに同じフローが発生します。カスタムエディターのすべてのインスタンスは独自のWebviewPanelを持っていますが、複数のカスタムテキストエディターが同じリソース用である場合は、同じTextDocumentを共有します。覚えておいてください:TextDocumentはリソースのモデルであり、webviewパネルはそのモデルのビューであると考えてください。

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

ユーザーがカスタムテキストエディターを閉じると、VS Code は閉じられたエディターのWebviewPanelWebviewPanel.onDidDisposeイベントを発生させます。この時点で、拡張機能はそのエディターに関連付けられたリソース(イベント購読、ファイルウォッチャーなど)をクリーンアップする必要があります。

特定のリソースに対する最後のカスタムエディターが閉じられると、そのリソースのTextDocumentも、他のエディターが使用しておらず、他の拡張機能が保持していない限り、破棄されます。TextDocument.isClosedプロパティをチェックして、TextDocumentが閉じられたかどうかを確認できます。TextDocumentが閉じられた後、カスタムエディターを使用して同じリソースを開くと、新しいTextDocumentが開かれます。

変更をTextDocumentと同期する

カスタムテキストエディターはTextDocumentをドキュメントモデルとして使用するため、カスタムエディターで編集が行われるたびにTextDocumentを更新する責任があり、またTextDocumentが変更されるたびに自身を更新する責任があります。

webviewからTextDocument

カスタムテキストエディターでの編集は、ボタンのクリック、テキストの変更、項目のドラッグなど、さまざまな形式をとることができます。ユーザーがカスタムテキストエディター内でファイル自体を編集するたびに、拡張機能はTextDocumentを更新する必要があります。猫のスクラッチ拡張機能がこれをどのように実装しているかを見てみましょう。

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

  2. 拡張機能がメッセージを受信します。その後、ドキュメントの内部モデルを更新します(猫のスクラッチの例では、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の更新にコストがかかる場合は、webviewの更新のデバウンスを検討してください。

カスタムエディター

CustomEditorProviderCustomReadonlyEditorProvider を使用すると、バイナリファイル形式用のカスタムエディターを作成できます。この 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エディターに対して発生する順序付けされたリストです。

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

    これにより、まだアクティブ化されていない場合は拡張機能がアクティブ化されます。また、アクティベーション中に、拡張機能がcatCustoms.pawDrawCustomReadonlyEditorProviderまたは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は、最初のエディターが開かれたときに作成したのと同じCustomDocumentを使用してresolveCustomEditorを呼び出すだけです。

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

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

最初のエディターインスタンスが閉じられると、VS Codeは閉じられたエディターのWebviewPanelWebviewPanel.onDidDisposeイベントを発生させます。この時点で、拡張機能はその特定のエディターインスタンスに関連付けられたすべてのリソースをクリーンアップする必要があります。

2番目のエディターが閉じられると、VS Codeは再びWebviewPanel.onDidDisposeを発火します。しかし、これでCustomDocumentに関連付けられたすべてのエディターも閉じられました。CustomDocumentに対してこれ以上エディターがない場合、VS CodeはCustomDocument.disposeを呼び出します。拡張機能のdisposeの実装は、ドキュメントに関連付けられたリソースをすべてクリーンアップする必要があります。

その後、ユーザーがカスタムエディターを使用して同じリソースを再度開くと、新しいCustomDocumentを使用して、openCustomDocumentresolveCustomEditorのフロー全体が繰り返されます。

読み取り専用カスタムエディター

以下のセクションの多くは編集をサポートするカスタムエディターにのみ適用され、逆説的に聞こえるかもしれませんが、多くのカスタムエディターは編集機能をまったく必要としません。たとえば、画像プレビューを考えてみてください。または、メモリダンプの視覚的レンダリング。どちらもカスタムエディターを使用して実装できますが、どちらも編集可能である必要はありません。そこでCustomReadonlyEditorProviderの出番です。

CustomReadonlyEditorProviderを使用すると、編集をサポートしないカスタムエディターを作成できます。これらはインタラクティブであることはできますが、元に戻すや保存などの操作はサポートしていません。また、読み取り専用のカスタムエディターは、完全に編集可能なエディターに比べてはるかに実装が簡単です。

編集可能なカスタムエディターの基本

編集可能なカスタムエディターを使用すると、元に戻す、やり直す、保存、ホットイグジットなどの標準的なVS Codeの操作にフックできます。これにより、編集可能なカスタムエディターは非常に強力になりますが、正しく実装するには、編集可能なカスタムテキストエディターや読み取り専用カスタムエディターを実装するよりもはるかに複雑になります。

編集可能なカスタムエディターは、CustomEditorProviderによって実装されます。このインターフェースはCustomReadonlyEditorProviderを拡張しているため、openCustomDocumentresolveCustomEditorなどの基本的な操作と、編集固有の操作を実装する必要があります。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 — 作成された編集の種類を記述するオプションのテキスト(例: "Crop"、"Insert"、...)
  • undo — 編集を元に戻す必要があるときにVS Codeによって呼び出される関数。
  • redo — 編集をやり直す必要があるときにVS Codeによって呼び出される関数。

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

エディターのundoおよびredoメソッドは、特定の編集を元に戻すまたは再適用する必要があるときにVS Codeによって呼び出されます。VS Codeは編集の内部スタックを維持しているため、拡張機能がonDidChangeCustomDocumentを3つの編集(abcとしましょう)で発火した場合、

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タイプと、拡張機能が内部で編集をどのように追跡するかに大きく依存します。

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

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

    たとえば、基本的な画像エディターはピクセルデータのバッファを保持する場合があります。

  • 前回の保存からの編集を再生して、新しいファイルを生成する。

    より効率的な画像エディターは、例えば、前回の保存以降の編集(croprotatescaleなど)を追跡するかもしれません。保存時に、これらの編集をファイルの最後に保存された状態に適用して、新しいファイルを生成します。

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