Open17

WezTermに移行してみている

Yoshi YamaguchiYoshi Yamaguchi

iTerm2がもっさりしているのと、macOSでしか使えないので、マルチプラットフォーム対応の高速なターミナルエミュレータをいくつか検討している。候補としてはAlacritty、WezTerm、Kittyの3つ

Yoshi YamaguchiYoshi Yamaguchi

KittyはPythonで設定ファイルを書けるということで以前試してみたんだけれども、日本語の表示周りが壊滅的だったのですぐに捨てた記憶がある。

今日試しに入れてみたらちゃんと表示されていた。

しかしフォントを変更したらなぜか勝手に斜体になり(当然Regularも同梱されているフォント)、意味不明なのでやはり使わないことに。

Yoshi YamaguchiYoshi Yamaguchi

Alacrittyは設定ファイル等のドキュメントは無い。公式ドキュメントにもあるように、デフォルトで用意されている alacritty.yml に設定可能な項目と、コメントの形で各フィールドの内容が記載されている。

Yoshi YamaguchiYoshi Yamaguchi

Alacrittyでキーバインドを設定しようと思ったけれど

  • キーバインドは複数修飾キーを押さないとOSやtmuxやVimのキーバインドを潰しそう
  • 出来るアクションが限られている

ということもあって設定をするのを一旦やめた。

Yoshi YamaguchiYoshi Yamaguchi

Alacrittyの設定を一旦終えたので、次はWezTermの設定をしてみる。Alacrittyとは対象的にWezTermは圧倒的な量のドキュメントがあり、これを個人開発でサポートしているかと思うと頭が下がる。

設定ファイルはLuaで記述する形式で、Luaは書いたことがないけれどなんとなく雰囲気で書けそうなので、とりあえず見てみる。

WezTermのドキュメントは非常に丁寧で、「Luaで記述する」という特殊性でネガティブに判断されたり、心理的障壁を高く感じられないように、行えばいいことを1から記述している。自分もこれでだいぶ安心した。Luaで記述すると言っても、単純にTableをreturnすればそれで良いらしい。

local wezterm = require 'wezterm'
return {
  font = wezterm.font 'JetBrains Mono',
  color_scheme = 'Batman',
}
Yoshi YamaguchiYoshi Yamaguchi

公式ドキュメントが非常に丁寧なので、4. Configurationsの項目を上から順番に読みながら少しずつ設定していく。

フォントはKittyやAlacrittyよりも柔軟にフォントのフォールバックの設定が出来るのが良い。フォント周りは各OSでデフォルト環境でも最低これは入っているというフォントファミリーは確実に使ってもらいたいし、自分が追加でインストールするであろうフォントがあればそちらを優先してもらいたい。そのあたりを設定できるのは非常に高評価。

local wezterm = require 'wezterm'
return {
  font = wezterm.font_with_fallback {
    'Fira Code',
    'DengXian',
  },
}

特に驚いたのはカラースキームの設定の項目で、デフォルトで700種類以上のカラースキームが設定可能になっている。(実際は700+種類設定可能なのはnightly buildだけで、安定版リリースはできないものもあるが、それでも十分すぎるほど用意されている。)

自分がお気に入りで使っているNordカラースキームもデフォルトで用意されているので、それだけで設定の手間が省けた。

color_scheme = 'nord'
Yoshi YamaguchiYoshi Yamaguchi

またキーバインドに関してもかなり柔軟に対応出来ることに驚くとともに、沼だなと感じた。

キーバインドがかぶらないようにリーダーキーという概念があるのもだいぶ気に入っている。

local wezterm = require 'wezterm'

return {
  -- timeout_milliseconds defaults to 1000 and can be omitted
  leader = { key = 'a', mods = 'CTRL', timeout_milliseconds = 1000 },
  keys = {
    {
      key = '|',
      mods = 'LEADER|SHIFT',
      action = wezterm.action.SplitHorizontal { domain = 'CurrentPaneDomain' },
    },
    -- Send "CTRL-A" to the terminal when pressing CTRL-A, CTRL-A
    {
      key = 'a',
      mods = 'LEADER|CTRL',
      action = wezterm.action.SendString '\x01',
    },
  },
}
Yoshi YamaguchiYoshi Yamaguchi

またキーバインドに関しては既存のアクションだけではなく、自分で自由にLuaでアクションを記述して、それを呼び出せる自由度が気に入った。たとえば、自分がテストで設定してみた、ランダムにカラースキームを変更するキーバインドはこれ。

local wezterm = require 'wezterm'

function random_color_scheme()
  math.randomseed(os.time())
  local schemes = { 
    "Atom",
    "Builtin Pastel Dark",
    "Chalkboard",
    "Dracula+",
    "Japanesque",
    "nord",
    "rebecca",
    "Wombat",
  }
  local i = math.random(#schemes) 
  return schemes[i]
end

wezterm.on('random-color-scheme', function(window, pane)
  local overrides = window:get_config_overrides() or {}
  scheme = random_color_scheme()
  overrides.color_scheme = scheme
  window:set_config_overrides(overrides)
end)

keys = {
    { key = 'A', mods = 'CTRL', action = wezterm.action.EmitEvent 'random-color-scheme' },     
  }, 
}

これで Ctrl+Shift+a を押すと、wezterm.action.EmitEvent が呼び出され、'random-color-scheme'というイベントが発火される。すると wezterm.on でそのイベントハンドラーが定義されていて、そこで独自定義の関数 random_color_scheme が呼び出されたあとに、カラースキームがランダムで入れ替わる。

Yoshi YamaguchiYoshi Yamaguchi

wezterm.action.ScrollToPrompt を使いたくて OSC 133 について調べてるんだけどもいまいちよくわからない。

ここで OSC 133 という仕様に従って実装しているらしいんだけど、ドキュメントにリンクしてある gitlab.freedesktop.org が落ちていてリンク先のドキュメントが見れない。どうもこのドキュメントによるとシェルが何かしらのエスケープシーケンスを送信することによって、ターミナルエミュレーターがそれを元にプロンプトの区切りを理解する、ということみたいなんだけれども、シェルが差し込まなければいけないのか、適当にプロンプト文字列の中に入れておけば実現できるのかがよくわかっていない。

Yoshi YamaguchiYoshi Yamaguchi

キーバインドで、キーテーブルをごそっと変えられるのがなにげに便利だと気づいて使い始めた。Vimでいうところのモードみたいな感じ。たとえば Ctrl+Shift+presize_pane というキーテーブルを one_shot=false で割り当てるとあたかもモードに入ったような感じになって、その後 ESC が押されるまでキーバインドが固定される。

keys = {
    { key = 'p', mods = 'SHIFT|CTRL', action = wezterm.action.ActivateKeyTable { name = 'resize_pane', one_shot = false } },
},

key_tables = {
  resize_pane = {
    { key = 'h', action = wezterm.action.AdjustPaneSize {"Left", 1} },
    { key = 'j', action = wezterm.action.AdjustPaneSize {"Down", 1} },
    { key = 'k', action = wezterm.action.AdjustPaneSize {"Up", 1} },
    { key = 'l', action = wezterm.action.AdjustPaneSize {"Right", 1} },
    { key = 'Escape', action = 'PopKeyTable' },
  },
},

複雑なことをしようとしたときにキーバインドをシンプルに保てる機能。