💻

Wezterm の Workspace を使う

2023/12/27に公開

概要

Wezterm は高機能なターミナルエミュレータで、tmux 相当の端末多重化機能も備えています。
ひとつの画面を垂直/水平方向に分割する pane の機能や、pane のまとまりを切り替える tab の機能 (tmux でいう window 相当) はデフォルトでもキーバインドの設定がなされており、多くの人が使っていると思われます。
これらに加えてさらに、tab のまとまりを切り替えられる workspace と呼ばれる機能 (tmux のsession 相当) があるのですが、こちらは知らない方も多いのではないでしょうか。
この記事では、workspace の使いどころや設定方法について説明します。

自分はもともと tmux で session を常用していて、wezterm を触りはじめた当初 wezterm で tmux session 相当のものが扱えるのかよくわからず移行をためらった経験もありました。この記事で少しでも workspace の認知度を高められたら幸いです。

Workspace の使いどころ

ターミナル上で作業していて、途中で何か別の画面で新しい端末を開きたくなることというのは多くあります。例えば、これから実行するコマンドを打ちこみながら man を参照したくなったり、今いる場所と違うところのディレクトリやファイルを確認したくなったり、あるいはプロジェクトで使いたい言語機能を実験するための小さいコードを別の場所で動かしてみたくなったり...。

このように端末を増やしたくなったとき、最初に候補になるのは pane でしょう。特に 2つの画面を比較しながら作業したいといった用途では pane は重宝します。一方で、あまり無闇に pane 分割しているとすぐに端末の縦横幅が小さくなって非常に見づらくなってしまいます。筆者の個人的な使いかたとしては、1つの画面で 3つ以上の pane に分割することはほとんどありません[1]

次に候補になるのは tab でしょう。tab なら一画面広々と新しいタスクに使えますし、tab に名前をつけることでどの tab がどの作業をしていたものなのかもある程度管理しやすくなります。しかし、それでもだんだん tab が増えてくると関連性の薄い tab が大量に横に並ぶという自体になりがちで、管理が大変だし tab どうしの移動もツラくなってきます。

このようなときに使いたいのが workspace の機能です。workspace を使うと、関連性のある tab をまとめてひとつの作業単位としてまとめることができます。基本的には、プロジェクトなどわかりやすい作業単位で workspace をつくるのが良いでしょう。例えば自分はよく以下のような単位で workspace をつくったりしています。

  • 特定のプロジェクト用の workspace
  • Zenn の記事を書く用の workspace
  • 言語の実験用の workspace
  • エディタや端末等の設定いじる用の workspace

Workspace の設定 (お手軽編)

ここからは、実際に wezterm 上で workspace を使うための設定例を紹介します。
デフォルトでは workspace 関連のキーバインドは設定されていないので、workspace を使いたい場合は基本的にすべて自分で設定を書く必要があります。
ここではひとまず少ない設定量で一通りの機能を使えるような設定を紹介します。

Workspace の作成・切り替え (ShowLauncherArgs)

Workspace の作成および切り替えに関して、一番お手軽なのは、ShowLauncherArgs というアクションを使うことです。これは、launcher menu という wezterm 上で行える様々な操作の一覧のようなものを表示するためのアクションで、flags にオプションを指定することで表示項目を絞ることができます。

local act = require "wezterm".action

config.keys = {
  {
    mods = 'LEADER',
    key = 's',
    action = act.ShowLauncherArgs { flags = 'WORKSPACES' , title = "Select workspace" },
  },
}

選択メニュー起動時のイメージは以下のような感じです。

j,k で上下移動して Enter で項目を選択すれば、workspace を移動したり新しく作成したりできます。また、メニュー画面で / を押すと fuzzy finder モードで検索することができます。あるいは、flagsFUZZY を追加するとはじめから fuzzy finder モードで起動することもできます。
なお、workspace の削除については明示的なコマンドはないですが、workspace 内の最後の tab を閉じれば自動的に workspace が削除されます。

Workspace のリネーム

上の方法で新しく作った workspace はランダムになるので、わかりやすい名前にリネームしたほうが良いでしょう。そこで使えるのが、wezterm.mux.rename_workspace() という関数です。また、新しい workspace の名前としてユーザーの入力を受けとるには PromptInputLine というアクションが使えます。これらを組みあわせて以下のように workspace のリネーム用のキーバインドをつくることができます。

local wezterm = require "wezterm"
local act = wezterm.action

local 
config.keys = {
  {
    -- Rename workspace
    mods = 'LEADER',
    key = '$',
    action = act.PromptInputLine {
      description = '(wezterm) Set workspace title:',
      action = wezterm.action_callback(function(win,pane,line)
        if line then
          wezterm.mux.rename_workspace(
            wezterm.mux.get_active_workspace(),
            line
          )
        end
      end),
    },
  },
}

ShowLauncherArgs とリネームの 2つの機能を組みあわせて使えば、とりあえず一通り workspace の機能を使えるようになります。

Workspace の設定 (カスタマイズ編)

筆者はしばらく上の設定で workspace を利用していたのですが、ShowLauncherArgs の UI にやや不満がありました。というのは、現在いる workspace の名前が Create new Workspace の横に書いてあるのは少しわかりにくく感じましたし、見た目的にも他の workspace と現在の workspace の表示位置が横方向に少しずれてしまいます。
また、そもそも今ある workspace を選択して切り替えたいだけなのに新しく workspace を作成してしまうという誤操作もよく起こしていました。
そこで、この節では workspace まわりの操作をもう少し細かく設定する例を紹介します。

名前を指定して Workspace を作成

まず、workspace の作成部分の機能だけを切り出してみます。今回は workspace をランダムな名前でつくるのではなく、最初から名前を指定することにしましょう。SwitchToWorkspace は名前を指定して workspace を移動するアクションですが、もし指定された名前の workspace がまだなければ新しくつくるので、workspace を作成する用途にも使えます。
以下は、SwitchToWorkspace のページにある公式のサンプルを少し変えたものです。リネームのときと同じように PromptInputline と組み合わせてユーザー入力を取得しています。

config.keys = {
  {
    -- Create new workspace
    mods = 'LEADER|SHIFT',
    key = 'S',
    action = act.PromptInputLine {
      description = "(wezterm) Create new workspace:",
      action = wezterm.action_callback(function(window, pane, line)
        if line then
          window:perform_action(
            act.SwitchToWorkspace {
              name = line,
            },
            pane
          )
        end
      end),
    },
  },
}

となりあう Workspace の間で切り替え

並び順がとなりあう workspace の切り替えに関しては、SwitchToWorkspaceRelative が使えます。個人的には workspace は順序付きで管理しているという感覚がないので番号順の移動は今のところ使っていないのですが、特定のキーを連打して workspace を連続で切り替えたいといった用途には便利でしょう。
以下は SwitchToWorkspaceRelative のページにある設定例です。

config.keys = {
  { key = 'n', mods = 'CTRL', action = act.SwitchWorkspaceRelative(1) },
  { key = 'p', mods = 'CTRL', action = act.SwitchWorkspaceRelative(-1) },
}

Workspace のリストから選択メニューを組みたてる

Launcher menu 風の選択 UI を使いたいけれど、表示内容は少しカスタマイズ (e.g. 作成メニューは表示したくない) したいという場合には、自分で選択候補を生成してメニューを作成することができます。選択式のメニュー作成に使うのは InputSelector というアクションです。
以下は、wezterm.mux.get_workspace_names() 関数を用いて今ある workspace のリストを取得して選択メニューを組みたてる例です。

config.keys = {
  {
    mods = 'LEADER',
    key = 's',
    action = wezterm.action_callback (function (win, pane)
      -- workspace のリストを作成
      local workspaces = {}
      for i, name in ipairs(wezterm.mux.get_workspace_names()) do
        table.insert(workspaces, {
          id = name,
          label = string.format("%d. %s", i, name),
        })
      end
      local current = wezterm.mux.get_active_workspace()
      -- 選択メニューを起動
      win:perform_action(act.InputSelector {
        action = wezterm.action_callback(function (_, _, id, label)
          if not id and not label then
            wezterm.log_info "Workspace selection canceled"  -- 入力が空ならキャンセル
          else
            win:perform_action(act.SwitchToWorkspace { name = id }, pane)  -- workspace を移動
          end
        end),
        title = "Select workspace",
        choices = workspaces,
        fuzzy = true,
        -- fuzzy_description = string.format("Select workspace: %s -> ", current), -- requires nightly build
      }, pane)
    end),
  },
}

メニュー起動時のイメージは以下のような感じです。
シンプルで ShowLauncherArgs の表示より見やすく、個人的には気に入っています。

おわりに

この記事では wezterm の workspace の使いどころと設定方法を説明しました。Workspace 関連の機能についてはデフォルトのキーバインドが無くややハードルが高いと感じる部分もあるかもしれませんが、作業の切り替え単位としては workspace は結構便利な機能になっています。
この記事でもいくつか挙げましたが、公式ドキュメントにも実用的なサンプルが探すとあちこちに載っていたりします。これも参考にしてみると良いでしょう。
Wezterm 使ってる方は是非 workspace を試してみてください!

脚注
  1. これは筆者がメインで使っている環境がラップトップで画面が小さいからというのもあるでしょう ↩︎

GitHubで編集を提案

Discussion