はじめに
tmux,lazygit,vimはそれぞれCtrl-j,Ctrl-kを使います。
-
tmux: ペインの上下移動 -
vim: ウィンドウの上下移動 -
lazygit: commitの上下移動
これらを解決するまでの流れと、過程で生じた問題とその解決策を紹介します。
最初の Vim と Tmux の設定
まず、Vim と tmux のペイン移動を統一するため、以下の設定を追加しました。
vim側ではプラグイン(alexghergh/nvim-tmux-navigation)を使用しています。
こちらの設定も上記のプラグインのレポジトリのREADMEから拾ってきました。
is_vim="ps -o state= -o comm= -t '#{pane_tty}' \
| grep -iqE '^[^TXZ ]+ +(\\S+\/)?g?(view|l?n?vim?x?|fzf)(diff)?$'"
bind-key -n 'C-h' if-shell "$is_vim" 'send-keys C-h' 'select-pane -L'
bind-key -n 'C-j' if-shell "$is_vim" 'send-keys C-j' 'select-pane -D'
bind-key -n 'C-k' if-shell "$is_vim" 'send-keys C-k' 'select-pane -U'
bind-key -n 'C-l' if-shell "$is_vim" 'send-keys C-l' 'select-pane -R'
tmux_version='$(tmux -V | sed -En "s/^tmux ([0-9]+(.[0-9]+)?).*/\1/p")'
if-shell -b '[ "$(echo "$tmux_version < 3.0" | bc)" = 1 ]' \
"bind-key -n 'C-\\' if-shell \"$is_vim\" 'send-keys C-\\' 'select-pane -l'"
if-shell -b '[ "$(echo "$tmux_version >= 3.0" | bc)" = 1 ]' \
"bind-key -n 'C-\\' if-shell \"$is_vim\" 'send-keys C-\\\' 'select-pane -l'"
この設定により、Vimとtmux両方で C-h, C-j, C-k, C-l をウィンドウ、ペイン移動に使用できるようになりました。
Lazygit のキーバインド競合
その後、lazygit を tmux 内で使用するようになったところ、
リベース時に C-j, C-k を用いたコミットの移動が機能しない問題が発生しました。
これは、tmux が C-j, C-k をペイン移動に割り当てていたためです。
この問題を解決するため、lazygit を検出して適切なキーを送信するようにしました。
is_lg="ps -o state= -o comm= -t '#{pane_tty}' | grep -iqE '^[^TXZ ]+ +(\\S+\/)?lazygit$'"
bind -n C-j if "$is_lg" "send-keys C-j" "select-pane -D"
bind -n C-k if "$is_lg" "send-keys C-k" "select-pane -U"
参考: https://github.com/jesseduffield/lazygit/discussions/3201#discussioncomment-8037078
これにより、tmux 内でも lazygit のコミット移動が機能するようになりました。
Vim のウィンドウの上下の移動が機能しなくなる問題
しかし、この設定の影響で、Vim のウィンドウの上下移動 (C-j, C-k) が機能しなくなってしまいました。
そこで、lazygit と vim の両方の状況を考慮し、すべての動作を両立させるための設定を作成しました。
bind -n C-j if-shell "$is_lg" "send-keys C-j" "select-pane -D" \
\; if-shell "$is_vim" 'send-keys C-j' 'select-pane -D'
bind -n C-k if-shell "$is_lg" "send-keys C-k" "select-pane -U" \
\; if-shell "$is_vim" 'send-keys C-k' 'select-pane -U'
この設定により、tmux,lazygit,vimすべてでC-j,C-kが期待通りの動作をするようになりました。
まとめ
この問題を通じて、tmux の if-shell を適切に活用し、
lazygit, vim, tmux のキーマップ競合を解決する方法を学びました。
現在の設定では、
-
tmux内でもlazygitのキー操作が可能 -
vim内でのスプリット移動も動作 -
tmuxのペイン移動も維持
と、すべての動作が期待通りに動くようになっています。
もし tmux, lazygit, vim を同時に使用していて、キーバインドの競合に悩んでいる方がいれば、ぜひこの方法を試してみてください!