tags : Emacs
Emacs のコードフォーマッタ比較
1. format-all (emacs-format-all-the-code)
- 概要 `format-all` は、多くのプログラミング言語に対応した統一的なコードフォーマットパッケージ。
- 特徴
- 複数のフォーマッタ(`black`, `prettier`, `clang-format`, `gofmt`, `shfmt`, etc.)を自動検出して実行。
- `format-all-buffer` でバッファ全体をフォーマット。
- `format-all-region` で選択範囲のみフォーマット(対応フォーマッタのみ)。
- `format-all-mode` を有効にすると、自動でファイル保存時にフォーマットを適用。
- 使い方
(use-package format-all :hook (prog-mode . format-all-mode)) - メリット
- 複数の言語に対応し、一括でフォーマット可能。
- 言語ごとの設定が不要(自動検出)。
- デメリット
- 言語ごとのカスタマイズがしづらい。
- 外部フォーマッタを必要とする(インストールが必要)。
2. reformatter (emacs-reformatter)
- 概要 `reformatter` は、外部のコードフォーマッタを Emacs から簡単にラップするためのヘルパーパッケージ。
- 特徴
- 任意のフォーマッタをシンプルに定義可能。
- バッファ全体または選択範囲をフォーマットできる。
- フォーマッタごとに個別のコマンドを作成可能。
- 使い方(例:Prettier を使った JS フォーマッタ)
(use-package reformatter) (reformatter-define js-format :program "prettier" :args '("--stdin-filepath" buffer-file-name "--parser" "babel")) - メリット
- 設定がシンプルで、言語ごとにカスタムフォーマッタを作成しやすい。
- バッファと選択範囲のフォーマットを統一的なインターフェースで扱える。
- デメリット
- フォーマッタの指定を自分で行う必要がある(自動判別はしない)。
- `format-all` のような一括対応ではなく、個別に設定が必要。
3. apheleia
- 概要 `apheleia` は、フォーマッタを非同期で実行することに特化したパッケージ。
- 特徴
- `format-all` や `reformatter` はフォーマット時に一時的に Emacs の UI をブロックするが、`apheleia` は非同期で動作し、スムーズにフォーマット可能。
- 言語ごとのフォーマッタを設定可能。
- `apheleia-mode` を有効にすると保存時に自動フォーマット。
- 使い方
(use-package apheleia :config (apheleia-global-mode +1)) - メリット
- 非同期処理により、フォーマット時のラグが少ない。
- 言語ごとに細かくフォーマッタを指定できる。
- デメリット
- `reformatter` のようにカスタムフォーマッタを簡単に定義する仕組みはない(設定ファイルをいじる必要がある)。
- `format-all` のような一括対応ではなく、設定を自分で追加する必要がある。
どれを選ぶべきか?
| 特徴 | format-all | reformatter | apheleia |
|---|---|---|---|
| フォーマット対象 | バッファ全体 | バッファ/範囲 | バッファ全体 |
| 言語ごとの設定 | ほぼ不要(自動) | 必要(個別に設定) | 必要(設定ファイル) |
| フォーマット方法 | 同期(ブロックあり) | 同期(ブロックあり) | 非同期(スムーズ) |
| カスタマイズ性 | 低い | 高い | 高い |
| 導入の手軽さ | 簡単 | 中程度 | 難しい |
- 手軽に使いたい → `format-all`
- いろいろな言語のコードをすぐにフォーマットしたいなら、これが一番簡単。
- 言語ごとに細かく制御したい → `reformatter`
- 特定のフォーマッタを使いたい場合や、自作のフォーマッタを簡単に追加したいならこれ。
- 非同期でラグなく使いたい → `apheleia`
- 保存時に遅延なく自動フォーマットしたいならこれ。
結論
- 初心者向け → `format-all`
- 中級者向け(カスタム設定したい) → `reformatter`
- 上級者向け(非同期フォーマットを重視) → `apheleia`
どれを選ぶかは、**フォーマット時のブロックが気になるかどうか**と、**カスタマイズの必要性**によって決めるのがよさそう。