バッファ内のgitの差分が一目瞭然、diff-hlを紹介

2023年4月19日
thumbnail
diff-hlはファイルの差分をグラフィカルに表示してくれるパッケージです。
emacsのgitクライアントはmagitが最も有名です。magitはgitのコミットからプッシュまでのgitの操作が主体です。一方でdiff-hlはファイルの差分の表示がメインになります。ファイルの変更を確認したり、差分のハンクを移動したり、変更内容を確認できます。
こちらが完成済みのdiff-hlコードです。
(use-package diff-hl
  :ensure t
  :init
  (global-diff-hl-mode)
  (add-hook 'dired-mode-hook 'diff-hl-dired-mode)
  (unless (window-system) (diff-hl-margin-mode))
  :custom-face
  (diff-hl-change ((t (:background "#8adf80"))))
  (diff-hl-delete ((t (:background "#ff8f88"))))
  (diff-hl-insert ((t (:background "#bfc9ff"))))
  :config
  (add-hook 'magit-pre-refresh-hook 'diff-hl-magit-pre-refresh)
  (add-hook 'magit-post-refresh-hook 'diff-hl-magit-post-refresh))

設定の解説

global-diff-hl-modeはグローバルでdiff-hlを利用する宣言です。 (add-hook 'dired-mode-hook 'diff-hl-dired-mode)はemacsのdirモードで差分を表示します。C-x C-fでファイルを開く代わりにディレクトリを開くと、このように差分が強調表示されます。
article image
(unless (window-system) (diff-hl-margin-mode)) はCUIモードでemacを使っている場合、左にマージンを用意してそこに差分情報を表示します。GUIの場合はEmacsのフレームに描画されるのでこの設定は必要ないので省いています。
article image
カスタムフェイスは好きな色を使って良いと思います。デフォルトの色は多少禍々しかったので、modus-themsのカラーをセットしています。
(diff-hl-change ((t (:background "#8adf80"))))
(diff-hl-delete ((t (:background "#ff8f88"))))
(diff-hl-insert ((t (:background "#bfc9ff"))))

diff-hlハンク移動

diff-hlはファイルの差分を移動できます。デフォルトで割り振られているキーバインドはやや難解ですが使えなくもありません。"command diff-hl-next-hunk" C-x v ]は差分のハンクを前に進みます。
article image
"diff-hl-previous-hunk" C-x v [はハンクを上に戻ります。
article image

ハンクの変更状態を見る

ファイルを編集してしまうと、前の状態はgit diffを実行しないと確認できません。 例えば、下の画像では、なんらかのhtmlが削除されていますが、何が削除されたか分かりません。
article image
目的のハンクでコマンドを実行することで編集前の状態を表示することができます。 カーソルをハンクのあたりに移動させて"diff-hl-show-hunk" C-x v *を実行します。
article image
変更前の状態が表示されます。右下にdiff-hlが提供するキーが表示されています。
  • 「n」と「p」は別のハンクに移動します
  • 「c」は変更前のコードをkill-ringに保存します。
  • 「r」は変更前ハンクを適応させます。
  • 「q」はshow-hunk-modeを終了させます。

まとめ

magitとdiff-hlをうまく使うことで、emacsでのgit体験がずっと良くなるので試してみてください。
profile image
Ted
大学でコンセンサスアルゴリズムを研究。卒業後ベンチャー企業に入社してフルスタックでWebサービスを開発。現在は大手IT企業に転職し、プログラミングを行っている。AIにプログラマーの仕事を奪って欲しいと願っている。