PuTTY+tmux 環境で Ctrl+矢印 が効かなかった原因が解ったかも

tmux で <Ctrl+矢印> を使いたい場合は、.tmux.confに以下のように設定しろという記事をよく見かけます。

set-window-option -g xterm-keys on

しかし、PuTTY から SSH アクセスしている時に、この設定をしていても、<Ctrl+矢印> が tmux の中で実行しているプログラムにうまく伝わってくれなくて、そのために Ctrl + 左右キーで vim のタブ切り替えをする という設定が使えず、もう何年も tmux を使うのを諦めていました。

ところが、ようやくxterm-keysの意味と、PuTTY を使った環境でなぜこの設定が効かなかったのかが解ってきたので、改めてここに記しておきます。

termcapとterminfo | doda's blog という記事に詳しく書かれていたのですが、<Ctrl+なんとか> みたいな入力をしたときに送られる信号1 には、ターミナルごとに方言があるそうです。
前に Ctrl + 左右キーで screen のウィンドウ切り替えをする という記事を書いた時に調べた、^[^[OCというのがそれで、これが Linux でよく使われている Xterm のものとは違った方言のものだったみたいです。2

PuTTY で <Ctrl+矢印> を入力した時に、Xterm と同じコードを送るようにする設定の仕方が、GDI 版 PuTTY を配布されている iceiv+putty のページに書かれていました。

プライベートキー定義

キーを押したときに送信されるコードシーケンスを独自に定義できます。 たとえば、Shift + Up キーで xterm と同様の ^[[1;2A を送信したり、 Shift + Ctrl + Alt + Up キーで適当に決めた ^[[1;9A を送信したりできます。

ここでは、以下の設定をputty.iniに書くことで、<↑>, <↓>, <←>, <→> キーと <Shift>, <Ctrl>, <Alt> キーを組み合わせた入力があった時に、Xterm で送られるのと同じ信号を送るようになると書かれています。

# Normal,Shift,Ctrl,Shift-Ctrl,Alt,Shift-Alt,Ctrl-Alt,Shift-Ctrl-Alt
# LEFT UP DOWN RIGHT
VKey37=\033OD,\033[1;2D,\033[1;5D,\033[1;6D,\033[1;3D,\033[1;4D,\033[1;13D,\033[1;14D
VKey38=\033OA,\033[1;2A,\033[1;5A,\033[1;6A,\033[1;3A,\033[1;4A,\033[1;13A,\033[1;14A
VKey39=\033OC,\033[1;2C,\033[1;5C,\033[1;6C,\033[1;3C,\033[1;4C,\033[1;13C,\033[1;14C
VKey40=\033OB,\033[1;2B,\033[1;5B,\033[1;6B,\033[1;3B,\033[1;4B,\033[1;13B,\033[1;14B

僕の場合は、PuTTY の設定はレジストリに保存しているので、これらの設定もレジストリに追加しました。
レジストリエディタでHKEY_CURRENT_USER\SOFTWARE\SimonTatham\PuTTY\Sessions\<セッション名>を開き、VKey37からVKey40までを文字列値 (REG_SZ) として追加します。

これで、例えば <Alt+→> を入力した時に、^[^[OCが送られていたのが、Xterm と同じく^[[1;3Cが送られるようになりました。
^[^[OC^[[1;3Cって全然違いますよね……。

そして、tmux の設定でxterm-keysがなぜ効かなかったかですが、これは名前の通り、Xterm の方言を受け入れるようにするというような意味なんでしょうね。
PuTTY から Xterm と同じ信号を送るように設定したことで、xterm-keysの設定が効果を発揮するようになり、tmux を使っている時でも <Ctrl+左右> キーが Vim に渡されるようになりました。

最後に.vimrcでこれらの信号を<C-Up>などにマップしていきます。

map ^[[1;5A <C-Up>
map ^[[1;5B <C-Down>
map ^[[1;5C <C-Right>
map ^[[1;5D <C-Left>
map ^[[1;2A <S-Up>
map ^[[1;2B <S-Down>
map ^[[1;2C <S-Right>
map ^[[1;2D <S-Left>

なお、^[は、<Ctrl+v> を押してから <ESC> キーを押すことで入力できます。

キーのマッピングができたら、それらのキーに機能を割り当てます。

" Ctrl + 左右キーでタブを切り替え
nnoremap <C-Right> :<C-u>tabn<CR>
nnoremap <C-Left> :<C-u>tabp<CR>
inoremap <C-Right> <ESC>:tabn<CR>
inoremap <C-Left> <ESC>:tabp<CR>
cnoremap <C-Right> <C-u>tabn
cnoremap <C-Left> <C-u>tabp

これで、PuTTY から tmux を使っている時でも、<Ctrl+左右> キーで Vim のタブが切り替えられるようになりました。

  1. 制御シーケンス、コードシーケンスなどと呼ばれているみたい
  2. PuTTY 独自の方言なのか、Windows の方言なのかは解ってないのですが

One thought on “PuTTY+tmux 環境で Ctrl+矢印 が効かなかった原因が解ったかも

  1. ピンバック: 匿名

コメントを残す