WezTermのタブに作業ディレクトリを表示させる
はじめに
ある日、はてブを見てたら以下の記事でWezTerm
というのを知りました。
今まではiTerm2
を使っており、大きな不満点はありませんでしたが、設定をVCSで管理することが難しい点は微妙だなと思っていました。設定をexportすることでVCSで管理することもできるみたいなのですが、なんだかんだでGUIで出力・管理するのは煩雑なためです。
その点WezTerm
はLuaで設定を書くことができ、VCSで設定を管理できるのでいいなと思いました。そこで本記事では、WezTerm
の設定をしていきます。
WezTerm
設定を加えたWezTerm
を記事や公式ドキュメントなどを参考にしつつ、以下のように設定しました。
設定後のWezTerm
このターミナルでは、「複数の異なるディレクトリを同時に開いて、並行で作業をする」ことを想定しています。例えば、$ docker compose up
で複数コンテナを立ち上げつつ、同一のディレクトリで何かの作業をしたり、$ docker compose exec ...
でコンテナ内に入って作業したりなどです。また、ディレクトリAとディレクトリBで、並列で作業をすることを想定しています。そのため、作業中のディレクトリのルート(=gitリポジトリのルート)をタブに表示しています。
以下に実際に利用するシーンを想定したターミナルを表示しています。左のnode [ zenn-contents ]
タブではzennの記事のプレビューをしつつ、右のdocker [ zenn-symfony-docker ]
タブではdockerを立ち上げています。真ん中のzsh [ gsy0911 ]
タブではリポジトリでの何かしらの作業を想定しています。このように、リポジトリの名前がわかるだけで結構便利になります。
想定されるシーンでの利用画面
WezTerm
の設定
それでは、設定をしていきます。初期状態は以下のようになります。
local wezterm = require 'wezterm'
local config = wezterm.config_builder()
return config
初期状態
次に、ターミナル部分を透過させて、ぼかしを入れます。color_schema
はここにサンプルが載っています。ちなみに、Nightly
を選ぶとiTerm2
のデフォルトと同じ見た目になります。
config.color_scheme = 'Wombat'
-- 背景の非透過率(1なら完全に透過させない)
config.window_background_opacity = 0.70
-- 背景をぼかす
config.macos_window_background_blur = 20
ウィンドウの透過とぼかしを追加
ターミナルのフォントをJetBrains Mono
に設定します。Intellij系を使っていることもありますが、見やすくて好きなフォントです。
config.font = wezterm.font('JetBrains Mono', { weight = 'Bold' })
config.font_size = 14.0
ターミナル内のフォント調整
同様に、タブの文字列のフォントも調整します。あまり変化はないように見えますが・・・。
config.window_frame = {
font = wezterm.font('JetBrains Mono', { weight = 'Bold' }),
font_size = 14,
}
タブのフォント調整
タイトルバーとタブの追加ボタンを削除します。タブの追加は⌘ + T
でできるため不要です。
-- タイトルバーを非表示
config.window_decorations = "RESIZE"
-- タブの追加ボタンを非表示
config.show_new_tab_button_in_tab_bar = false
-- タブが一つしかない時に非表示
config.hide_tab_bar_if_only_one_tab = true
タイトルバーとタブの追加ボタンを削除
わかりにくいですが、非アクティブのタブの境界線を削除します。2: zsh X
のX
の隣にある線が消えているのがわかります。
config.colors = {
tab_bar = {
inactive_tab_edge = "none",
},
}
境界線を削除
次に、各タブ内における作業ディレクトリを取得、保持する処理を記述します。local title_cache
にpane_id
ごとの作業ディレクトリを保持できるようにします。
私の環境のルールとして、$HOME/Development/Projects
以下に各種Gitのリポジトリルートがあるようにしています。そのため、wezterm.on('update-status', function(...))
内にてos.getenv 'HOME'
と'/Development/Projects'
の文字列を消すようにしています。ここは人によって異なると思うので修正してください。参考にした記事ではgit
コマンドを利用していたのでそれでもいいかなと思います。
この設定を追加しただけでは、ターミナルの見た目に変化はありません。
function split(str, ts)
-- 引数がないときは空tableを返す
if ts == nil then return {} end
local t = {} ;
i=1
for s in string.gmatch(str, "([^"..ts.."]+)") do
t[i] = s
i = i + 1
end
return t
end
-- 各タブの「ディレクトリ名」を記憶しておくテーブル
local title_cache = {}
wezterm.on('update-status', function(window, pane)
local pane_id = pane:pane_id()
title_cache[pane_id] = "-"
local process_info = pane:get_foreground_process_info()
if process_info then
local cwd = process_info.cwd
-- 文字列を削除している
-- 環境に応じて変えること
local rm_home = string.gsub(cwd, os.getenv 'HOME', '')
local prj = string.gsub(rm_home, '/Development/Projects', '')
local dirs = split(prj, '/')
local root_dir = dirs[1]
title_cache[pane_id] = root_dir
end
end)
次に、上で定義した関数を利用してタブの見た目とテキストを変更します。タブがアクティブと非アクティブの状態で色が分かれるようになっています。加えて、非アクティブのタブでもどのディレクトリにいるのかがわかります。そのため、タブを選択するにしてもすぐに移動できます。
-- タブの形をカスタマイズ
-- タブの左側の装飾
local SOLID_LEFT_ARROW = wezterm.nerdfonts.ple_lower_right_triangle
-- タブの右側の装飾
local SOLID_RIGHT_ARROW = wezterm.nerdfonts.ple_upper_left_triangle
wezterm.on("format-tab-title", function(tab, tabs, panes, config, hover, max_width)
local background = "#5c6d74"
local foreground = "#FFFFFF"
local edge_background = "none"
if tab.is_active then
background = "#ae8b2d"
foreground = "#FFFFFF"
end
local edge_foreground = background
local pane = tab.active_pane
local pane_id = pane.pane_id
local cwd = "none"
if title_cache[pane_id] then
cwd = title_cache[pane_id]
else
cwd = "-"
end
local title = " " .. wezterm.truncate_right(tab.active_pane.title, max_width - 1) .. " [ " .. cwd .. " ] "
return {
{ Background = { Color = edge_background } },
{ Foreground = { Color = edge_foreground } },
{ Text = SOLID_LEFT_ARROW },
{ Background = { Color = background } },
{ Foreground = { Color = foreground } },
{ Text = title },
{ Background = { Color = edge_background } },
{ Foreground = { Color = edge_foreground } },
{ Text = SOLID_RIGHT_ARROW },
}
end)
タブの見た目を変更
最後に、タブの位置を下側に変更します。(後になって、macだとMission Controlが被ってきて操作しづらくなるので、このオプションはオフにしました。
-- タブを下に表示
config.tab_bar_at_bottom = true
タブの位置を変更
タブの移動に関しても以下の設定を加えます。デフォルトでは⌘ + Shift + [
で左方向、⌘ + Shift + ]
で右方向に移動できます。ただ、「ShiftとCtrlとどっちだっけ・・?」と悩むことが多々あったので、⌘ + Ctrl + [
と⌘ + Ctrl + ]
でタブの移動ができるように修正しています。
local act = wezterm.action
config.keys = {
-- ⌘ Ctrl [] でタブの移動
-- defaultは⌘ Shift []
{
key = '[',
mods = 'CMD|CTRL',
action = act.ActivateTabRelative(-1)
},
{
key = ']',
mods = 'CMD|CTRL',
action = act.ActivateTabRelative(1)
}
}
これにて、WezTerm
の設定はひとまず完了です。タブごとに起動してるディレクトリもわかりやすいので、使い勝手は良いです。見た目などは参考にした記事をほぼコピーした内容になっていますが・・・。誰かの参考になれば幸いです。
最後に、現時点でのファイル全体を置いておきます。これからも設定を追記していって使いやすいようにしていきたいです。
~/.config/wezter/wezterm.luaの全体
-- Pull in the wezterm API
local wezterm = require 'wezterm'
-- This table will hold the configuration.
local config = wezterm.config_builder()
----------------------------------------------------
-- Window
----------------------------------------------------
config.color_scheme = 'Wombat'
-- 背景の非透過率(1なら完全に透過させない)
config.window_background_opacity = 0.70
config.macos_window_background_blur = 20
config.default_cursor_style = 'BlinkingBar'
config.cursor_blink_rate = 1000
config.cursor_blink_ease_in = "Linear"
config.cursor_blink_ease_out = "Linear"
config.enable_scroll_bar = true
config.font = wezterm.font('JetBrains Mono', { weight = 'Bold' })
config.font_size = 14.0
config.command_palette_font_size = 14.0
config.command_palette_bg_color = '#4D07FF'
config.window_frame = {
font = wezterm.font('JetBrains Mono', { weight = 'Bold' }),
font_size = 14,
}
----------------------------------------------------
-- Tab
----------------------------------------------------
-- タイトルバーを非表示
config.window_decorations = "RESIZE"
-- タブの追加ボタンを非表示
config.show_new_tab_button_in_tab_bar = false
-- タブが一つしかない時に非表示
config.hide_tab_bar_if_only_one_tab = true
-- nightlyのみ使用可能
-- タブの閉じるボタンを非表示
-- config.show_close_tab_button_in_tabs = false
-- タブ同士の境界線を非表示
config.colors = {
tab_bar = {
inactive_tab_edge = "none",
},
}
function split(str, ts)
-- 引数がないときは空tableを返す
if ts == nil then return {} end
local t = {} ;
i=1
for s in string.gmatch(str, "([^"..ts.."]+)") do
t[i] = s
i = i + 1
end
return t
end
-- 各タブの「ディレクトリ名」を記憶しておくテーブル
local title_cache = {}
wezterm.on('update-status', function(window, pane)
local pane_id = pane:pane_id()
title_cache[pane_id] = "-"
local process_info = pane:get_foreground_process_info()
if process_info then
local cwd = process_info.cwd
local rm_home = string.gsub(cwd, os.getenv 'HOME', '')
local prj = string.gsub(rm_home, '/Development/Projects', '')
local dirs = split(prj, '/')
local root_dir = dirs[1]
title_cache[pane_id] = root_dir
end
end)
-- タブの形をカスタマイズ
-- タブの左側の装飾
local SOLID_LEFT_ARROW = wezterm.nerdfonts.ple_lower_right_triangle
-- タブの右側の装飾
local SOLID_RIGHT_ARROW = wezterm.nerdfonts.ple_upper_left_triangle
wezterm.on("format-tab-title", function(tab, tabs, panes, config, hover, max_width)
local background = "#5c6d74"
local foreground = "#FFFFFF"
local edge_background = "none"
if tab.is_active then
background = "#ae8b2d"
foreground = "#FFFFFF"
end
local edge_foreground = background
local pane = tab.active_pane
local pane_id = pane.pane_id
local cwd = "none"
if title_cache[pane_id] then
cwd = title_cache[pane_id]
else
cwd = "-"
end
local title = " " .. wezterm.truncate_right(tab.active_pane.title, max_width - 1) .. " [ " .. cwd .. " ] "
return {
{ Background = { Color = edge_background } },
{ Foreground = { Color = edge_foreground } },
{ Text = SOLID_LEFT_ARROW },
{ Background = { Color = background } },
{ Foreground = { Color = foreground } },
{ Text = title },
{ Background = { Color = edge_background } },
{ Foreground = { Color = edge_foreground } },
{ Text = SOLID_RIGHT_ARROW },
}
end)
----------------------------------------------------
-- Key Bindings
----------------------------------------------------
local act = wezterm.action
config.keys = {
-- ⌘ w でペインを閉じる(デフォルトではタブが閉じる)
{
key = "w",
mods = "CMD",
action = wezterm.action.CloseCurrentPane { confirm = true },
},
-- ⌘ Ctrl oでペインの中身を入れ替える
{
key = "o",
mods = "CMD|CTRL",
action = wezterm.action.RotatePanes 'Clockwise'
},
-- ⌘ Enterで最大化・縮小化のトグル
{
key = 'Enter',
mods = 'CMD',
action = act.ToggleFullScreen
},
-- ⌘ Ctrl [] でタブの移動
-- defaultは⌘ Shift []
{
key = '[',
mods = 'CMD|CTRL',
action = act.ActivateTabRelative(-1)
},
{
key = ']',
mods = 'CMD|CTRL',
action = act.ActivateTabRelative(1)
}
}
-- 最初からフルスクリーンで起動
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.tab_bar_at_bottom = true
return config
参考
Discussion