🐚

WezTerm in Windows で現在のシェルを保持して新しい Pane を開く

に公開

WezTerm - Wez's Terminal Emulator を使い始めました。

https://wezterm.org/

クロスプラットフォーム対応が魅力で、今のところWindows / macOSで快適に動いていますが、課題もあります。

特にWindows環境においては、WSL2、PowerShell、Git Bashなど複数のシェルを使い分けることも多いと思いますが、新しいPane (1つのTabに複数置けるターミナル画面) を開いたときに現在開いているシェルを引き継いでほしいものです。

WezTermの場合cmd.exeから指定した wsl.exepwsh.exe といったコマンドを実行しているだけなので、コマンドの実行後にWezTerm自身がそのコマンドを保持しておくことはありません。

ここではとりあえず現在のPaneのタイトルを取得し (pane:get_title()) 、今から開く新しいPaneの実行コマンドを決めることにしました。
プロセス名を取得する (pane:get_foreground_process_info()) を使うほうが確実だとは思いますが、現在のところこれで何とかなっています。

他にも、それぞれのシェルの環境変数を見て出し分ける方法などもあると思います。

~/.config/wezterm/wezterm.lua
local wezterm = require("wezterm")
local is_windows = wezterm.target_triple == "x86_64-pc-windows-msvc"

local windows_shells = {
  wsl2 = { "wsl", "~" },
  gitbash = { "C:\\Program Files\\Git\\bin\\bash.exe" },
  pwsh = { "pwsh" },
}

--- @param title string
--- @return table | nil
local function get_windows_shell(title)
  if not is_windows then
    return nil
  end

  local t = (title or ""):lower()
  if t == "wsl.exe" or t == "wslhost.exe" then
    return windows_shells.wsl2
  elseif t == "bash.exe"  then
    return windows_shells.gitbash
  elseif t == "pwsh.exe" then
    return windows_shells.pwsh
  else
    return nil
  end
end

local config = wezterm.config_builder()
if is_windows then
  config.default_prog = windows_shells.wsl2.args
  config.launch_menu = {
    windows_shells.wsl2,
    windows_shells.gitbash,
    windows_shells.pwsh,
  }

  config.keys = config.keys or {}
  -- Leader+D to split vertically 
  table.insert(config.keys, {
    key = "d",
    mods = "LEADER",
    action = act_cb(function(window, pane)
      local param = { domain = "CurrentPaneDomain" }
      local shell_args = get_windows_shell(pane:get_title())
      if shell_args then
        param.args = shell_args
      end
      window:perform_action(act.SplitVertical(param), pane)
    end),
  })
end

return config

Discussion