WezTermの設定ファイルをEmacsで
編集するためにlua-modeを入れた話

WezTermはLuaで設定を書くターミナルエミュレータです1
設定ファイルは ~/.config/wezterm/wezterm.lua に置きます2

Emacsでこのファイルを開くと、デフォルトでは Fundamental モードになります。
シンタックスハイライトが一切かかっていない状態で、キーワードもコメントも文字列も同じ色です。
コードが短ければ問題ありませんが、gui-startup イベントでウィンドウ位置を制御するような処理を書き始めると、色がないと途端に読みにくくなります。

そこで lua-mode を追加しました3

関連記事

1. use-packageでの設定

1. use-packageでの設定
(use-package lua-mode
  :ensure t
  :defer t
  :mode ("\\.lua\\'" . lua-mode)
  :interpreter ("lua" . lua-mode)
  :config
  (setq lua-indent-level 4))Code language: Lisp (lisp)

:ensure t はパッケージが未インストールなら自動でダウンロードします。
:defer t を付けると、Emacsの起動時ではなくLuaファイルを開いた瞬間にパッケージを読み込むため、起動時間への影響をゼロに抑えられます4

:mode はファイル名が .lua で終わるファイルに自動でこのモードを適用します。
:interpreter はファイル先頭の shebang 行に lua と書かれているファイルを対象とします5

lua-indent-level はインデント幅の設定で、デフォルトは3です6
ここでは4に変えています。

2. 見た目の変化

モードラインに表示されるモード名が Fundamental から Lua に変わり、シンタックスハイライトがかかります。
localfunctionendreturn といったキーワードが色付きで表示され、コメントとリテラル文字列が視覚的に区別されます。

WezTermの設定でよく使うパターン、たとえば次のようなウィンドウ位置の制御コードを書くとき、guiscreen などのローカル変数と組み込み関数が見分けやすくなります7

wezterm.on('gui-startup', function(cmd)
  local screen = wezterm.gui.screens().main
  local half_w = math.floor(screen.width / 2)
  local h = screen.height

  local tab, pane, win = mux.spawn_window(cmd or {})
  local gui = win:gui_window()

  gui:set_position(screen.x + half_w, screen.y)
  gui:set_inner_size(half_w, h)
end)Code language: Lua (lua)

起動時にウィンドウを画面右半分に配置する例です。
set_position でウィンドウの左上座標を指定し、set_inner_size で内側のサイズを設定します。

3. WezTermの設定をEmacsから触る流れ

WezTermは設定ファイルを保存した瞬間に自動で再読み込みします8
Emacsで編集して保存すれば即座に反映されるので、フォントを変えたりカラースキームを試したりする作業でエディタとターミナルを行き来する手間が減ります。

lua-mode を入れたきっかけは設定ファイルの色分けが欲しかっただけですが、設定を繰り返し触る環境では見やすさが作業のテンポに直結します。

  1. WezTermが使うLuaはバージョン5.4です。 – Full Config & Lua Reference – Wez’s Terminal Emulator
  2. 設定ファイルの検索順はOSやXDG環境変数の有無によって変わります。Windowsでは %USERPROFILE%\.wezterm.lua%USERPROFILE%\.config\wezterm\wezterm.lua が候補になります。 – Configuration – Wez’s Terminal Emulator
  3. lua-modeはimmerrr氏が開発するEmacsのメジャーモードで、MELPAからのインストールが公式の方法です。シンタックスハイライトのほか、Lua REPLとの連携やFlymakeによるLintもサポートしています。 – GitHub – immerrr/lua-mode
  4. :mode:interpreter を指定するとuse-packageが自動的にオートロードを設定するため、:defer t はこのケースでは厳密には不要です。ただし明示的に書いておくと設定の意図が伝わりやすくなります。 – Deferring loading – use-package User Manual
  5. shebangとは、スクリプトファイルの1行目に書く #!/usr/bin/lua のような行で、どのインタープリタで実行するかをシェルに伝えます。Emacsはこの行を読み取り、interpreter-mode-alist の設定に従って適切なメジャーモードを自動選択します。 – GitHub – immerrr/lua-mode
  6. lua-modeのREADMEに「Var lua-indent-level (default 3): indentation offset in spaces」と明記されています。Lua言語にはインデント幅の公式スタイル規定がなく、3はlua-modeが独自に採用している値です。 – GitHub – immerrr/lua-mode
  7. gui-startup イベントはWezTermのGUI起動完了時に一度だけ発火します。引数 cmd には wezterm start に渡されたコマンド情報が入りますが、nil になることもあるため cmd or {} で安全に処理するパターンが定番です。 – gui-startup – Wez’s Terminal Emulator
  8. この挙動は automatically_reload_config オプションで制御できます。デフォルトは true で、false にした場合は Ctrl+Shift+R で手動リロードできます。 – automatically_reload_config – Wez’s Terminal Emulator