WezTerm関連

WezTermを使い始めた背景

  • sixel対応があり、タブ機能がある。

    • Tmuxもsixel対応が徐々に始まっているが正式にリリースされていない(2023/12時点)
    • Tmuxの機能を満たしていこうとしているように見える(が、もちろん併用もできる)
  • ドキュメントが充実している

    • とはいえLuaでカスタマイズできる範囲が広いので、自分で試す部分はある
  • フォントの指定が柔軟にできる

  • Windows、macOS、Linuxに対応している

    • 設定をまとめることができる

OSごとに設定を変える

wezterm.target_triple - Wez’s Terminal Emulator

キーテーブルを固定する機能がある

例えばペインのサイズを変更する場合、私はHJKLのキーでサイズ調整している。 ペインのサイズを変更するたびに「ctrl + shift + h」を繰り返したりしている。 が、一度、リーダーキーを押してキーテーブルに入ったら、連続して「h」を押すだけで、サイズを調整できたりすると連続してサイズ調整できるので嬉しい。

WezTermに移行してみている

one_shot=false とするとモードに入ったかのようにできるので嬉しい。

{ key = 'y', mods = 'CTRL', action = wezterm.action.ActivateKeyTable { name = 'leader_option', one_shot = false } },

素敵な機能なのは間違いがない。ただ私個人の問題としてprefixキーがそろそろ使い切るというか、モードに入るためのキーバイドって悩ましい。

  • 私がprefix使いすぎている

    • WezTerm(ctrl + y)
    • Tmux用2つ(ctrl + t, ctrl + b)
  • モードの切り替えはWezTermとTmuxで共通にしたい。が、Tmux側で一つのセッション内でprefixを異なるものに設定する方法が分からない

    • Tmuxのペイン作成は ctrl + t、サイズ調整は ctrl + p とかにしたい、がTmux用の設定がわからず

という訳で使いこなせてない。

tmux と同じキーでペイン分割する

2026-05-27 に Ubuntu Desktop 上の wezterm 20240203-110809-5046fc22 で確認した。

tmux 側では prefix -> | を左右分割、prefix -> - を上下分割にしている。 WezTerm 側も Ctrl+yleader_option key table に入り、同じ | / - でペイン分割できるようにした。

{ key = 'y', mods = 'CTRL', action = act.ActivateKeyTable { name = 'leader_option', one_shot = true } },

leader_option = {
  { key = '|', mods = 'SHIFT', action = act.SplitHorizontal { domain = 'CurrentPaneDomain' } },
  { key = '-', action = act.SplitVertical { domain = 'CurrentPaneDomain' } },
}

WezTerm の SplitHorizontal は左右にペインを並べる分割、SplitVertical は上下にペインを並べる分割として扱う。 tmux の split-window -h / split-window -v と名前の見え方が混乱しやすいため、キーの意味は表示結果で合わせる。

| は Shift を伴う文字なので、mods = 'SHIFT' を明示する必要があった。 最初は key = '|'mods なし定義や、key = '\\', mods = 'SHIFT' も候補にしたが、この環境では不要だった。 最終的に key = '|', mods = 'SHIFT' のみで動作した。

確認には次を使った。

wezterm --config-file ~/.config/wezterm/wezterm.lua show-keys --lua --key-table leader_option

WezTerm の key binding は Shift を含むキーで解釈に注意が必要。 公式ドキュメントにも key = '|'mods = '...|SHIFT' を組み合わせる例がある。

Key Binding - Wez’s Terminal Emulator

私が使っているカラースキーム

一時期は穏やかなカラースキームを使っていたのだけど、ターミナルを透過する設定で使い出すと見えづらくなったので、コントラストが強いカラースキームを使うようになった。

https://wezfurlong.org/wezterm/colorschemes/n/index.html#neobones_light

個人的なTodo

ハイパーリンクの正規表現を設定する

Hyperlinks - Wez’s Terminal Emulator

ルールは、下記のURLを参考にした hyperlink_rules - Wez’s Terminal Emulator

tmux関連の設定を変更する時は、一度、ログアウトするなりしてtmuxのセッションを完全に停止してからの方が良い

コピーモードの挙動を変えたいとき

私はデフォルトの設定で問題ないが変えたくなった時のためにメモ local act = wezterm.action – act は copy_mode で使う Copy Mode - Wez’s Terminal Emulator

KDE Waylandでcopy modeからwl-pasteが更新されない問題

2026-05-16 に wezterm 20260331-040028-577474d8 で確認した問題。

やりたい操作は、Ctrl+y -> [ で WezTerm の copy mode に入り、v または Space で選択開始、y でコピーし、Ctrl+y -> ] で貼り付ける、というもの。

この環境では、copy mode のキー入力と選択自体は動いていた。 ログ上も CopyTo(ClipboardAndPrimarySelection) は実行されていた。

table:copy_mode Char('y') NONE -> perform Multiple([CopyTo(ClipboardAndPrimarySelection), ScrollToBottom, CopyMode(Close)])

しかし wl-pastewl-paste --primary は更新されなかった。 同じ Wayland セッションで wl-copy を直接実行すると clipboard と primary selection の両方が更新できたため、WezTerm の copy action から Wayland clipboard への経路が、この環境では期待通りに動いていないと判断した。

回避策として、copy mode の選択文字列を Lua で取得し、wl-copy に渡すようにした。

local function copy_text_with_wl_copy(text)
  local runtime_dir = os.getenv('XDG_RUNTIME_DIR') or '/tmp'
  local path = runtime_dir .. '/wezterm-copy-' .. tostring(os.time()) .. '-' .. tostring(math.random(1000000))
  local file = io.open(path, 'wb')
  if not file then
    return false, 'failed to open temp file: ' .. path
  end

  file:write(text)
  file:close()

  wezterm.background_child_process {
    'sh',
    '-lc',
    'wl-copy < "$1" && wl-copy --primary < "$1"; rm -f "$1"',
    'wezterm-wl-copy',
    path,
  }
  return true, path
end

wezterm.on('copy-selection-to-clipboard', function(win, pane)
  local selection = win:get_selection_text_for_pane(pane)
  if selection and selection ~= '' then
    local success, detail = copy_text_with_wl_copy(selection)
    if not success then
      win:copy_to_clipboard(selection)
      wezterm.log_error(detail)
    end
  else
    wezterm.log_info('No selection to copy')
  end
  win:perform_action(act.CopyMode 'Close', pane)
end)

copy mode 側は wezterm.gui.default_key_tables().copy_mode を土台にして、差し替えが必要なキーだけ上書きする。 これで WezTerm 側の既定操作、たとえば jump 系や Alt+b / Alt+f の word 移動を取り込みつつ、ローカルで必要な差分だけを維持できる。

現在の差分は、y, Y, Enter, c を同じコピー確定操作にすること、Space の physical / literal 両方を選択開始にすること、Ctrl+b を 1 画面戻る、Ctrl+n を 1 画面進む、にすること。 WezTerm の既定では Ctrl+bCtrl+f が 1 画面単位の上下移動で、半画面移動は Ctrl+u / Ctrl+d

local copy_selection_and_close = act.Multiple {
  act.EmitEvent 'copy-selection-to-clipboard',
}

local function replace_key_assignment(key_table, binding)
  for i = #key_table, 1, -1 do
    local item = key_table[i]
    if item.key == binding.key and (item.mods or 'NONE') == (binding.mods or 'NONE') then
      table.remove(key_table, i)
    end
  end
  table.insert(key_table, binding)
end

local copy_mode = nil
if wezterm.gui then
  copy_mode = wezterm.gui.default_key_tables().copy_mode
  local copy_mode_overrides = {
    { key = ' ', mods = 'NONE', action = act.CopyMode { SetSelectionMode = 'Cell' } },
    { key = 'phys:Space', mods = 'NONE', action = act.CopyMode { SetSelectionMode = 'Cell' } },
    { key = 'y', mods = 'NONE', action = copy_selection_and_close },
    { key = 'Y', mods = 'NONE', action = copy_selection_and_close },
    { key = 'Enter', mods = 'NONE', action = copy_selection_and_close },
    { key = 'c', mods = 'NONE', action = copy_selection_and_close },
    { key = 'b', mods = 'CTRL', action = act.CopyMode 'PageUp' },
    { key = 'n', mods = 'CTRL', action = act.CopyMode 'PageDown' },
  }

  for _, binding in ipairs(copy_mode_overrides) do
    replace_key_assignment(copy_mode, binding)
  end
end

Space については追加でハマった。 key = 'Space' だけだと実効設定では phys:Space として見える一方、実ログでは Char(' ') として来ていた。 そのため Space が copy mode に捕まらず pane に空白として送られていた。 key = ' ' も追加して、v と同じ SetSelectionMode = 'Cell' にした。

検証時は debug_key_events = trueCtrl+Shift+R の明示 reload を使ったが、通常運用では不要。 WezTerm は設定ファイルを監視して自動 reload する。

Luaのテーブルに簡単に追加する関数

local function append_table(table, other)
  for k, v in pairs(other) do
    table[k] = v
  end
end

メニューに何か追加する方法

  config.launch_menu = {
    {
      args = { 'top' },
    },
    {
      label = 'fish',
      set_environment_variables = { HOME = "/Users/exampleuser" },
      cwd = "/Users/exampleuser",
      args = { '/opt/homebrew/bin/fish', '--login' },
    },
    {
      label = 'memo',
      args = { '/User/exampleuser/.bin/memo.sh' },
    },
  }

Ubuntu Studio で透過ができないな…?

mac OSだとできるが Linux ではできない… たぶんKDEのどこかの設定が影響している、という状況。 KDEの設定を開き、「ディスプレィとモニタ」の「コンポジタ」の「Compositing : Enable on startup」をオンにすると透過できるようになった

他可能性としては

不透明ウィンドウを強制する設定をオフ

System Settings → Desktop Effects を開く
Force Blur や Background Contrast を無効にする

ウィンドウルールで透過を許可

System Settings → Window Management → Window Rules を開く Add New Rule を作成し、WezTermに対して透明度を適用する

Window class (application) に wezterm を指定
Opacity のルールを Apply Initially に設定し、透明度を 80% くらいに設定

Apply を押して適用

X11 vs Wayland

Plasmaでは X11 と Wayland のどちらで動かしているかによって、WezTermの透過挙動が変わることがあります。

echo $XDG_SESSION_TYPE を実行し、x11 なら X11, wayland なら Wayland で動作中

参考