フォーマッター拡張機能の作成
2016年11月21日 Johannes Rieken、 @johannesrieken
Visual Studio Code の拡張機能 API は、導入以来、ソースコードフォーマッターのサポートを提供してきました。たとえば、TypeScript、C#、Go など、最初に構築した言語拡張機能は、フォーマット API を使用していました。このブログでは、フォーマッターを実装するためのベストプラクティスを説明します。
VS Code の拡張機能 API は、一連の指針に従っています。これらの原則の本質は、VS Code が骨格を提供し、拡張機能が「スマートさ」を提供するというものです。一般的なパターンは、VS Code が機能の UI を提供し、拡張機能がそれを輝かせるために必要なデータを提供するというものです。
フォーマッターを実装するために拡張機能 API を使用する主な利点は、ドキュメントのフォーマットおよび選択範囲のフォーマットアクションが公開されていることです。これらのアクションは、エディターのコンテキストメニューで利用でき、キーボードショートカットにバインドされ、コマンドパレットに表示されます。API を使用すると、すべてのフォーマッター拡張機能間で一貫したユーザーエクスペリエンスが得られます。
フォーマット API
以下のコードスニペットは、フォーマッターを実装する際に何をするべきか、何をすべきでないかを示しています。ベストプラクティスは、フォーマット API を使用し、「Foo ファイルのフォーマット」のような新しいアクションを作成しないことです。完全な拡張機能の例は、GitHub にあります。
// 👎 formatter implemented as separate command
vscode.commands.registerCommand('extension.format-foo', () => {
const { activeTextEditor } = vscode.window;
if (activeTextEditor && activeTextEditor.document.languageId === 'foo-lang') {
const { document } = activeTextEditor;
const firstLine = document.lineAt(0);
if (firstLine.text !== '42') {
const edit = new vscode.WorkspaceEdit();
edit.insert(document.uri, firstLine.range.start, '42\n');
return vscode.workspace.applyEdit(edit);
}
}
});
// 👍 formatter implemented using API
vscode.languages.registerDocumentFormattingEditProvider('foo-lang', {
provideDocumentFormattingEdits(document: vscode.TextDocument): vscode.TextEdit[] {
const firstLine = document.lineAt(0);
if (firstLine.text !== '42') {
return [vscode.TextEdit.insert(firstLine.range.start, '42\n')];
}
}
});
最近、「保存時にフォーマット」機能を追加しました。フォーマット API を適切に実装している拡張機能は、新しいコードなしでこの機能をサポートします。
ヒント: これを利用するには、フォーマット拡張機能は registerDocumentFormattingEditProvider API 呼び出しを使用して登録する必要があります。
複数のフォーマッター
フォーマッターに貢献する際に、すべてのプログラミング言語をサポートしなければならないという誤解がよくあります。拡張機能が registerDocumentFormattingEditProvider でフォーマッターとして登録する場合、DocumentSelector でサポートするプログラミング言語を示します。その情報により、たとえば HTML ドキュメントが開いている場合、エディターはフォーマットアクションを有効にできます。同様に、フォーマッターが登録されていないドキュメントを表示している場合、エディターはフォーマットアクションを無効にします。
1つの言語に複数のフォーマッターがある場合はどうなりますか?これは、異なるフォーマッターのアクションが矛盾する場合に問題となる可能性があります。10月のリリースでは、VS Code に同梱されているデフォルトのフォーマッターを有効または無効にする設定を追加しました。ベストプラクティスは、拡張機能の作成者が、以下に示すように VS Code で行ったのと同様の設定を追加することです。
"html.format.enable": true,
"javascript.format.enable": true,
"typescript.format.enable": true,
"json.format.enable": true
拡張機能は、contributes.configuration 拡張ポイントを通じて設定を追加します。
マーケットプレイスのフォーマッター
最後に、フォーマッターへの意識を高めるために、マーケットプレイスに新しい 「フォーマッター」カテゴリを追加しました。人気のあるフォーマット拡張機能でこれをシードし、フォーマッターの作成者にも追加するよう招待しています。また、拡張機能パックを使用して、フォーマッター拡張機能を好きな言語の他の拡張機能とバンドルすることもできます。
まとめ
まとめると、フォーマット拡張機能 API を適切に実装する拡張機能は次のことを行います。
- registerDocumentFormattingEditProvider 経由でフォーマッターを登録する。
- DocumentFormattingEditProvider インターフェースに従ってフォーマットロジックを実装する。
- フォーマッターを有効/無効にする設定を持つ。
- 拡張機能のマニフェストに「Formatters」カテゴリを追加する。
フォーマッターの機能開発はまだ終わっていません。「ペースト時にフォーマット」、「フォルダー内のファイルをフォーマット」などがロードマップにあり、皆様からのフィードバックやアイデアを心待ちにしています。
Johannes Rieken、VS Code チームメンバー
@johannesrieken