WezTermをセットアップする

昨今では、WezTermというターミナルエミュレータが流行っているらしい。自分も試してみたところ、普段使っているiTerm2からの乗り換え先として最適だと思ったので、本格的に乗り換えることにした。この記事では、WezTermをセットアップするにあたって、設定しておくと良い設定項目を紹介する。

# この記事を読むと得しそうな人
- ターミナルエミュレータをデフォルトのままにしてある人
- iTerm2より良いターミナルエミュレータを探している人
- WezTermって何？と思っている人

# WezTermとは
とりあえず、どこの馬の骨ともわからんターミナルエミュレータを使いたいという人は少ないと思うので、WezTermの紹介を行う。WezTermとは、Wez氏の趣味のプロジェクトで開発されている、Rust製のターミナルエミュレータである。特徴は以下の通りである。

- luaスクリプトによる設定
- マルチプラットフォーム対応(Windows, macOS, Linux)
- 体感でわかるレベルの高速動作(Rust製だからか？)
- かなり整った[ドキュメント](https://wezfurlong.org/wezterm/config/files.html)
- 透過対応
- 仮想フルスクリーン対応
- 素で日本語に対応
- フォールバックフォントの設定が可能

iTerm2と比べた際の特に強い長所は、マルチプラットフォーム対応とluaスクリプトによる設定だろうか。iTerm2は使いやすいが、macOS以外に対応していなかった上、セットアップの度にGUIで設定を行わなくてはならなかった。WezTermであれば、一度設定ファイルを書いてしまえば、後は設定ファイルをコピペするだけでセットアップが終わる。PC複数台持ちの人や、すぐにOSを飛ばす人、新米の後輩を指導する人にとっては重宝するだろう。

alacrittyも似たような特徴を持っているが、こちらにはドキュメントの整備具合や仮想フルスクリーン対応の面などで勝る。

また、iTerm2はビジュアル面が優れており、透過・仮想フルスクリーンに対応しているが、WezTermも同様に透過・仮想フルスクリーンに対応しており、iTerm2と遜色ないビジュアルを維持することができる。

一方で、iTerm2に対するWezTermの短所は、HotKeyに対応していないところだろうか。こちらは後でAutoHotKeyやHammerspoonを使って設定しようと思う。

# セットアップ
macOSであれば、ターミナルを開いて、以下のコマンドで導入可能。
```bash
# macOS bash
brew install --cask wezterm
```
Windowsであれば、Powershellを開いて、以下のコマンドで導入可能。
```powershell
# Windows powershell
winget install wez.wezterm
```
万が一入らなかったら公式ページからインストーラでも持ってくれば良いだろう。

https://wezfurlong.org/wezterm/installation.html

また、設定ファイルはホームディレクトリに`.wezterm.lua`という名前で設置する。
```bash
# macOS bash
cd
touch .wezterm.lua
```
```powershell
# Windows powershell
cd
New-Item .wezterm.lua
```

`.wezterm.lua`の中身は一旦こうする。VSCodeでもVimでもメモ帳でもなんでも良いから、好きなアプリケーションで編集する。
```.wezterm.lua
local wezterm = require 'wezterm'

local config = {}

if wezterm.config_builder then
  config = wezterm.config_builder()
end

-- カラースキームの設定
config.color_scheme = 'AdventureTime'

return config
```
これが、カラースキーム以外何も設定していない場合の`.wezterm.lua`である。この状態でWezTermを起動すると、少し青みがかったターミナルが表示される。真っ黒なターミナルが表示されたら`.wezterm.lua`の設置場所が間違っている。

# フルスクリーン表示 & 背景透過
全画面にデカデカとターミナルを表示すると見やすくて便利なので、設定する。`.wezterm.lua`に以下を追記する。
```.wezterm.lua
-- 背景透過
config.window_background_opacity = 0.85

-- 最初からフルスクリーンで起動
local mux = wezterm.mux
wezterm.on("gui-startup", function(cmd)
    local tab, pane, window = mux.spawn_window(cmd or {})
    window:gui_window():toggle_fullscreen()
end)

-- ショートカットキー設定
local act = wezterm.action
config.keys = {
  -- Alt(Opt)+Shift+Fでフルスクリーン切り替え
  {
    key = 'f',
    mods = 'SHIFT|META',
    action = wezterm.action.ToggleFullScreen,
  },
}
```
`config.window_background_opacity`を下げると、透明度を上げることができる。また、ショートカットキーは各々の好みで設定して欲しい。

このように設定すると、「後ろ側のブラウザを見ながら、手前のターミナルを操作する」ということができるようになる。便利なので試してみて欲しい。

# フォントの設定
フォントは以下のように設定する
```.wezterm.lua
-- フォントの設定
config.font = wezterm.font("好きなフォント", {weight="Medium", stretch="Normal", style="Normal"})

-- フォントサイズの設定
config.font_size = 16
```

また、ターミナルから以下のコマンドを実行することで、設定可能なフォントの一覧を確認することができる。
```bash
wezterm ls-fonts --list-system

# 以下のような形式で出力される
# wezterm.font("好きなフォント", {weight="Medium", stretch="Normal", style="Normal"})
# wezterm.font("好きなフォント2", {weight="Medium", stretch="Normal", style="Normal"})
# ...
```
`wezterm.font(...)`という形式で出力されるため、これをそのまま`.wezterm.lua`にコピペすることができる。

また、「斜体だけ違うフォントで表示したい！」という場合や、「フォントが存在しなかった場合の予備のフォントを設定したい！」という場合は、[font_rules](https://wezfurlong.org/wezterm/config/lua/config/font_rules.html)や[font_with_fallback](https://wezfurlong.org/wezterm/config/fonts.html#fallback)で設定可能である。

# タブとペイン分けのショートカットキーを設定する
フルスクリーン切り替えのショートカットを設定していた`config.keys`に更に追記する形で、タブ作成とペイン分け(画面分割)のショートカットキーを設定する。複数のターミナルを同時に操作したいときに重宝する。
```.wezterm.lua
-- ショートカットキー設定
local act = wezterm.action
config.keys = {
  -- Alt(Opt)+Shift+Fでフルスクリーン切り替え
  {
    key = 'f',
    mods = 'SHIFT|META',
    action = wezterm.action.ToggleFullScreen,
  },
  -- Ctrl+Shift+tで新しいタブを作成
  {
    key = 't',
    mods = 'SHIFT|CTRL',
    action = act.SpawnTab 'CurrentPaneDomain',
  },
  -- Ctrl+Shift+dで新しいペインを作成(画面を分割)
  {
    key = 'd',
    mods = 'SHIFT|CTRL',
    action = wezterm.action.SplitHorizontal { domain = 'CurrentPaneDomain' },
  },
}
```

# Ctrl+矢印キーで単語単位のカーソル移動
`config.keys`に更に更に追記する形で、単語単位のカーソル移動のショートカットキーを設定する。(ついでに単語削除のショートカットキーも設定)
```.wezterm.lua
-- ショートカットキー設定
local act = wezterm.action
config.keys = {
  --
  -- ... 他のショートカットキー(省略) ...
  --

  -- Ctrl+左矢印でカーソルを前の単語に移動
  {
    key = "LeftArrow",
    mods = "CTRL",
    action = act.SendKey {
      key = "b",
      mods = "META",
    },
  },
  -- Ctrl+右矢印でカーソルを次の単語に移動
  {
    key = "RightArrow",
    mods = "CTRL",
    action = act.SendKey {
      key = "f",
      mods = "META",
    },
  },
  -- Ctrl+Backspaceで前の単語を削除
  {
    key = "Backspace",
    mods = "CTRL",
    action = act.SendKey {
      key = "w",
      mods = "CTRL",
    },
  },
}
```
`act.SendKey`を使って何をしているのかというと、`bash`や`zsh`の[デフォルトショートカットキー](https://qiita.com/odacoh/items/b94be0deecaaa27b0263)を叩いている。なので、大抵の`bash`や`zsh`では動くと思うけど、時と場合によっては動かないかもしれない。そうなったら適宜直して欲しい。

# HotKeyの設定
こればっかりは、WezTermでは設定できない。HotKeyとは、あるショートカットキーを叩くだけで、ターミナルを起動したり、呼び出したりすることができる機能のことである。個人的にはかなり欲しいので、WindowsではAutoHotKey、macOSではHammerspoonを使って実装した。

### AutoHotKeyによる実装
AutoHotKeyとは、Windowsマシンの様々な制御機能をショートカットキーに割り当てるためのスクリプト言語である。とにかく色々できるのだが、これを使えば、WezTermを呼び出すようなHotKeyを実装することができる。

まず、Powershellから以下のコマンドでインストールを行う。
```powershell
winget install Lexikos.AutoHotkey
```

次に、`wezterm.ahk`というファイルを作成する。ファイル作成場所はどこでも良い。
```powershell
New-Item wezterm.ahk
```

`wezterm.ahk`には、以下のスクリプトを記述する。これは、`Alt+Shift+T`を押すとWezTermを呼び出すショートカットキーのスクリプトである。
```wezterm.ahk
!+t::
  ApplicationBinaryName=wezterm-gui.exe
  ApplicationBinaryPath="C:\Program Files\WezTerm\wezterm-gui.exe"

  Process, Exist, %ApplicationBinaryName%
  if ErrorLevel=0
  {
    Run, %ApplicationBinaryPath%, %A_WorkingDir%
    WinWait, ahk_exe %ApplicationBinaryName%
    WinActivate, ahk_exe %ApplicationBinaryName%
    Exit
  }

  WinGet, WinState, MinMax, ahk_exe %ApplicationBinaryName%
  if WinState=-1
  {
    WinActivate, ahk_exe %ApplicationBinaryName%
  }
  else
  {
    WinMinimize, ahk_exe %ApplicationBinaryName%
  }

  return
```

作成した`wezterm.ahk`を、エクスプローラーからダブルクリックするなどの方法で起動すると、ショートカットキーが使えるようになるはずである。`wezterm.ahk`をスタートアップメニューに追加して、Windowsを起動する度に`wezterm.ahk`も起動するようにすると良い。

https://pc-karuma.net/windows-10-app-startup/

また、こちらの記事では二度押しによるHotKeyの実装が紹介されている。「Ctrlを2回押すとターミナルが起動する」というショートカットキーを設定したい場合は参考になるだろう。

https://neokixblog.wordpress.com/2018/01/31/autohotkey%E5%85%A5%E9%96%80-%E5%AD%A6%E7%BF%92%E3%82%B7%E3%83%AA%E3%83%BC%E3%82%BA17-%E4%BA%8C%E5%BA%A6%E6%8A%BC%E3%81%97%E3%82%92%E4%BD%BF%E3%81%A3%E3%81%A6%E3%82%B7%E3%83%A7%E3%83%BC%E3%83%88/

### Hammerspoonによる実装
`Hammerspoon`とは、macOSマシンの様々な制御機能をショートカットキーに割り当てるためのアプリケーションである。とにかく色々できるのだが、これを使えば、WezTermを呼び出すようなHotKeyを実装することができる。

まず、ターミナルから以下のコマンドでインストールを行う。
```bash
brew install hammerspoon
```

次に、`init.lua`というファイルを、ホームディレクトリの`.hammerspoon`ディレクトリに設置する。
```bash
cd
mkdir .hammerspoon
cd .hammerspoon
touch init.lua
```

`init.lua`には、以下のスクリプトを記述する。これは、`Option+Shift+T`を押すとWezTermを呼び出すショートカットキーのスクリプトである。

```init.lua
hs.hotkey.bind({ "option", "shift" }, "t", function()
  local appName = "WezTerm"
  local app = hs.application.get(appName)

  if app == nil or app:isHidden() then
    hs.application.launchOrFocus(appName)
  else
    app:hide()
  end
end)
```

Hammerspoonを起動すると、ショートカットキーが使えるようになるはずである。Hammerspoonをログイン項目に追加して、macを起動する度にHammerspoonも起動するようにすると良い。

https://support.apple.com/ja-jp/guide/mac-help/mtusr003/mac

また、Hammerspoonを使ったHotKeyの設定についてはこちらの記事の方が詳しく書かれているので、一度参照してみて欲しい。「Ctrlを2回押すとターミナルが起動する」というショートカットキーの設定方法や、アクティブなデスクトップにターミナルを呼び出す方法などが記載されている。

https://moriso.hatenablog.com/entry/2022/03/20/175922

# まとめ
このぐらい設定しておけば、ひとまず困ることはないだろう。他のターミナルエミュレータと比べて、本当に公式ドキュメントが整っているので、納得できない部分があれば自分好みにカスタマイズすると良いだろう。

https://wezfurlong.org/wezterm/config/files.html

また、自分で設定した`.wezterm.lua`を自慢するスレッドがWezTermのリポジトリにあるようだ。こちらはかなり上級者向けのようだが、冒険してみたい人は見てみると良いかもしれない。

https://github.com/wez/wezterm/discussions/628

最後に、今回設定した`.wezterm.lua`の全体を示して記事を締めたいと思う。
```.wezterm.lua
local wezterm = require 'wezterm'

local config = {}

if wezterm.config_builder then
  config = wezterm.config_builder()
end

-- カラースキームの設定(おすすめはMaterialDesignColors)
config.color_scheme = 'MaterialDesignColors'

-- 背景透過
config.window_background_opacity = 0.85

-- 最初からフルスクリーンで起動
local mux = wezterm.mux
wezterm.on("gui-startup", function(cmd)
    local tab, pane, window = mux.spawn_window(cmd or {})
    window:gui_window():toggle_fullscreen()
end)

-- フォントの設定
config.font = wezterm.font("好きなフォント", {weight="Medium", stretch="Normal", style="Normal"})

-- フォントサイズの設定
config.font_size = 16

-- ショートカットキー設定
local act = wezterm.action
config.keys = {
  -- Alt(Opt)+Shift+Fでフルスクリーン切り替え
  {
    key = 'f',
    mods = 'SHIFT|META',
    action = wezterm.action.ToggleFullScreen,
  },
  -- Ctrl+Shift+tで新しいタブを作成
  {
    key = 't',
    mods = 'SHIFT|CTRL',
    action = act.SpawnTab 'CurrentPaneDomain',
  },
  -- Ctrl+Shift+dで新しいペインを作成(画面を分割)
  {
    key = 'd',
    mods = 'SHIFT|CTRL',
    action = wezterm.action.SplitHorizontal { domain = 'CurrentPaneDomain' },
  },
  -- Ctrl+左矢印でカーソルを前の単語に移動
  {
    key = "LeftArrow",
    mods = "CTRL",
    action = act.SendKey {
      key = "b",
      mods = "META",
    },
  },
  -- Ctrl+右矢印でカーソルを次の単語に移動
  {
    key = "RightArrow",
    mods = "CTRL",
    action = act.SendKey {
      key = "f",
      mods = "META",
    },
  },
  -- Ctrl+Backspaceで前の単語を削除
  {
    key = "Backspace",
    mods = "CTRL",
    action = act.SendKey {
      key = "w",
      mods = "CTRL",
    },
  },
}

return config
```