How do I create CTRL key bindings in vim when using tmux?
Solution 1:
The recommended TERM
setting for tmux is screen-256color
and the snippet you added to your vimrc
works only for a TERM
that starts with screen
so you can be sure that code block will never be executed if your TERM
is xterm
.
I've been successfully using that very snippet in the past on this machine, without set-window-option -g xterm-keys on
, but for whatever reason it doesn't seem to work anymore for me (I didn't use tmux in the last three months). I wonder what's going on. An iTerm upgrade? A tmux upgrade?
Adding set-window-option -g xterm-keys on
to my ~/.tmux.conf
fixes the problem.
Anyway, you could directly map the raw sequences produced by <C-Left>
and <C-Right>
as a temporary workaround.
nnoremap <C-v><C-Left> :tabprevious<CR>
should give you something like:
nnoremap ^[[D :tabprevious<CR>
Solution 2:
Unless you see the code (e.g. <C-Left>
) you're using in the section "Terminal keys" of :set termcap
, you can't use it right away.
The docs lists 3 ways to map a special key. First in Insert or Cmdline mode press Ctrl-K
, then the key sequence you want to map (e.g. Ctrl-K Ctrl-Left
). If it prints <...>
, you can use that for the left-hand side of your mapping. Or else, prepend it with <Esc>
(Ctrl-V Esc
), or use Ctrl-V Ctrl-Left
. For example, under tmux
I get [1;5D
for Ctrl-Left
, and <Left>
for Left
. Which means that for Left
I can use <Left>
, and for Ctrl-Left
I need ^[[1;5D
(^[
should be one character, Ctrl-V Esc
, and do note the trailing <CR>
):
nnoremap ^[[1;5D <Cmd>tabprevious<CR>
Or (:h :set-termcap
):
set <C-Left>=^[[1;5D
nnoremap <C-Left> <Cmd>tabprevious<CR>
If you work under different terminals you probably want the second approach:
if &term =~ '^screen'
set <C-Left>=...
elseif &term =~ '^tmux'
set <C-Left>=...
endif
nnoremap <C-Left> <Cmd>tabprevious<CR>
Some keys work with some terminals, but doesn't work with others (when they have no field in the corresponding terminfo entry). Let's take <S-Left>
, for example. From :set termcap
not under tmux
(TERM=rxvt-unicode-256color
) I can see that it resides in the t_#4
termcap
field:
t_#4 <S-Left> ^[[d
man terminfo
says:
key_sleft kLFT #4 shifted left-arrow
key
Which means that the terminfo
name is kLFT
. Now let's see the value of this field for TERM=rxvt-unicode-256color
(not under tmux
), TERM=screen
(under tmux
) and TERM=tmux
(which we might need later):
$ infocmp rxvt-unicode-256color | grep kLFT
kLFT=\E[d, kNXT=\E[6$, kPRV=\E[5$, kRIT=\E[c, ka1=\EOw,
$ infocmp screen | grep kLFT
$ infocmp tmux | grep kLFT
kHOM=\E[1;2H, kIC=\E[2;2~, kLFT=\E[1;2D, kNXT=\E[6;2~,
It's missing in the screen
terminfo
entry. To resolve this:
if &term =~ '^screen'
set <S-Left>=...
endif
nnoremap <S-Left> <Cmd>tabprevious<CR>
Or (with vim
we must use termcap
names):
if &term =~ '^screen'
set t_#4=...
endif
nnoremap <S-Left> <Cmd>tabprevious<CR>
Alternatively, you can tell tmux
to use its own terminfo
entry:
set -g default-terminal tmux
On a side note, avoid using the <Esc>
character if possible in your config (or generally in a text file). It's one character that looks like 2. If you e.g. copy it with a mouse, ^[
becomes 2 characters and this way it doesn't work. Particularly in the documentation you can find examples where ^[
is 2 characters, that you can't just copy. This sort of thing is easy to overlook.
And by the way, xterm-keys
is not available since 2.4
.
If it still doesn't work, tell me what you press and the escape sequence it produces (use Ctrl-V
).