対象とする人
まず、前提として以下の様な人を対象にしています。
- vimライクなキーバインドが体に染み付いている人
- ペインの並び替え、ウィンドウ間の移動、ウィンドウの移動を多く行い、直感的な操作が好みの人(ペインを作ってしまってからウィンドウに配置したい人とも言う)
- tmuxのキーバインドの再設定を考えている人
キーバインドに関して考えるべきこと
tmuxにかかわらず、キーバインドに関して考えるべきことは以下の要素だと考えています。
- プレフィックスキーは押しやすく、他のアプリケーションのキーバインドと競合しないこと
- ウィンドウとペイン、ペインの配置の関係を直感的に理解できるキーバインド
- 操作とキーの意味の対応がつけられるようにしてあること
個人的にはさらに以下の条件をつけます。
- Prefix + キー という2段階のキー入力(しかもプレフィックスはキーの同時押し)ではなく、(メタキー+キー)の組み合わせで操作できるものは、できる限りこの形式でキーを登録する。
以上の条件を満たすように、キーバインドを考えていきましょう。
プレフィックスキー
プレフィックスキーの設定にはその人の性格というか好みが現れるような気がします。つまり、何を重視しますか、ということです。僕の場合、先程の条件であげたように、押しやすい位置にあり、他のアプリケーションのキーバインドと競合しないことを条件としているので、ターミナル上でよく使うアプリケーションであるVimのキーバインドと競合しないか、ということを考える必要があります。
ググって見る限り、よくある設定としては、C-a
、C-z
、C-t
、C-o
、"`"などがあるかもしれません。押しやすさを考えるなら、ホームポジションに近い方がいいでしょう。ただし、これらは既にキーバインドがある場合があるので、もし設定する場合には、Vimで:help CTRL-T
などとしてデフォルトの設定を確認しておくといいでしょう。僕の場合、押しやすさと、キーバインドの使用率を考慮して、プレフィックスはC-g
に割り当てました。Vimでは現在のファイル名とカーソルの位置の行番号や文字数を表示するキーバインドに割り当てられていますが、:set ruler
してあるので、全く使うことはないので問題ありません。他のキーの問題点は
-
C-a
shellの行頭に移動のキーバインドと競合。よく使うので駄目。 -
C-z
シェルをバックグラウンド処理にするのに使うキーバインドなので駄目。 -
C-t
自分はこのキーをVimで新しいタブを開くのに使っているので使えない。"t"muxであることと押しやすさからすれば次候補だった。 -
C-o
Vimで以前カーソルのあった位置に戻るのにC-i
とセットで使うので。 -
C-h,j,k,l
Vimのインサートモードでのカーソル移動に使うので駄目。 - "`"
押しにくくないですか?それとVimではmark全般はこのキーに依っているので駄目。
というわけで、押しやすさと、他のアプリケーションと競合しないことからC-g
をプレフィックスにします。~/.tmux.conf
に以下を追記。
unbind-key C-b
# prefix key ^b -> ^g
set -g prefix C-g
bind-key C-g send-prefix
ウィンドウ・ペインの作成・削除、ペインの分割・移動、ペイン間の移動
以下に設定ファイルに書いた説明をのせ、それぞれに関してキーバインドの説明をしていきます。
# Prefix key: ^g
#
# Abbreviation:
# - [key]
# - {key} <- with Prefix key
# - (key) <- with Alt (or in MacOS, Command key)
略記は"[]"で囲ったキーはそのキーそのものを表しており、"()"は、メタキー(Linux、WindowsならAlt、MacならOpt)プラス何かキーを押すことを表しています。
基本的にはAltキーを押しながら操作する形にしており、Prefix + 何かキーという2段階の操作にはしていません。これは特にペイン間の移動やリサイズ時に威力を発揮するので、これだけでも設定する価値はあるかもしれません。
1セッション内のウィンドウとペインの構造関係
#
# Structure in one session:
#
# ------------------
# | (Left,Right) ↓(num) OR click status bar ↓ (Enter)
# window1 <------> window2 window3 window4
# ===============================================================
# pane1 pane1 pane1 pane1
# ↕ (j,k)
# pane2 - - - pane2 - - - -> (pane2)
# | [Shift+Right]
# (pane3) <- - pane3
# [Shift+Left] ↓ (x) ↓ (X)
# x x
#
ペイン間の移動は(j),(k)で行います。Vimと同じように{h},{j},{k},{l}でも移動できます。
# move between panes
# (xmonad like)
bind-key -n M-j select-pane -t :.+
bind-key -n M-k select-pane -t :.-
# (vim window like)
bind-key h select-pane -L
bind-key j select-pane -D
bind-key k select-pane -U
bind-key l select-pane -R
ウィンドウ間の移動は(Left),(Right)か(num)で移動します。
# move between window
bind-key -n M-Right next-window
bind-key -n M-Left previous-window
新しいウィンドウを作成するには(Enter)です。
# create new window
bind-key -n M-Enter new-window
ペインを削除するには(x)、ウィンドウを削除するには(X)です。if文を使うことで、最後のペイン、最後のウィンドウであるときにだけ確認メッセージを表示させることができます。
# if session has > 1 windows in current, kill-pane without confirmation.
# But confirm before killing pane when it is the last pane in the window.
bind-key -n M-x if "tmux display -p \"#{window_panes}\" | grep ^1\$" \
"confirm-before -p \"Kill the only pane in the window? It will kill this window too. (y/n)\" kill-pane" \
"kill-pane"
# if session has > 1 windows in current, kill-window without confirmation.
# But confirm before killing window when it is the last window in the session.
bind-key -n M-X if "tmux display -p \"#{session_windows}\" | grep ^1\$"\
"confirm-before -p \"Kill the only window in this session? It will kill the session too. (y/n)\" kill-window" \
"kill-window"
アクティブなペインを隣のウィンドウに移すのは[S-Left],[S-Right]です。新しいウィンドウに移す場合、デフォルトの通り{!}です。
# join pane
bind-key -n S-Right join-pane -t :+
bind-key -n S-Left join-pane -t :-
アクティブなペインをある番号のウィンドウに移すには(S-num)です。
# switch windows Alt+number
bind-key -n M-! join-pane -t :1
bind-key -n M-'"' join-pane -t :2
bind-key -n M-'#' join-pane -t :3
bind-key -n M-'$' join-pane -t :4
bind-key -n M-% join-pane -t :5
bind-key -n M-& join-pane -t :6
bind-key -n M-"'" join-pane -t :7
bind-key -n M-( join-pane -t :8
bind-key -n M-) join-pane -t :9
ウィンドウ内でのペインの操作
#
# In a window:
#
# +---------------+------------+
# |pane1 |pane3 |
# | | |
# | | |
# +---------------+ |
# |pane2 | |
# | | |
# | | |
# +---------------+------------+
#
# split pane:
# - vertically : (|)
# - horizontally : (-)
# select pane : (j,k) OR click the pane with mouse
# shift pane : (J,K)
# kill pane : (x)
# change layout : (Space)
# fullscreen : (f)
# resize pane:
# (a)
# ↑
# (h) ← + → (l)
# ↓ OR drag pane-border with mouse
# (z)
# join to another window : [Shift+Left/Right]
# join to another window : (Shift+num)
#
ウィンドウの分割は(-),(|)でそれぞれ文字の形の通りに分割します。またVim的に{s},{v}でも分割できます。tmuxとVimで見かけのオプションの文字が違うのは混乱のもと。
# split window (easily remember)
bind-key -n M-- split-window -v
bind-key -n M-| split-window -h
# vim like
bind-key s split-window -v
bind-key v split-window -h
ペインのスワップ(ペイン番号をずらす)は、(J),(K)
# swap pane
bind-key -n M-J swap-pane -D
bind-key -n M-K swap-pane -U
アクティブなペインを最大化するには(f)
# maximize pane ("f"ull screen)
bind-key -n M-f resize-pane -Z
ペインのレイアウトを変更するには(Space)
# next layout
bind-key -n M-Space next-layout
ペインのリサイズをするには、(a),(z),(h),(l)で上下左右に境界を動かすことができます。
# resize panes (xmonad like)
bind-key -n M-h resize-pane -L 1
bind-key -n M-z resize-pane -D 1
bind-key -n M-a resize-pane -U 1
bind-key -n M-l resize-pane -R 1
まとめ
直感的なキーバインドを設定し、tmuxを使った作業が捗るようになりました。ぜひ現在のキーバインドに引っ掛かりを感じている人は、これを機に設定を見なおしてみるといいかもしれません。
こちらにあげてありますので、参考にしてください。
(この記事を書いた時点から変更されています)