56

This is all in iTerm2 on OS X.

I used to have

export TERM='xterm-256color'

in my .bashrc. This meant Vim in tmux did use 256 colors.

And once I added

set -g xterm-keys on

then keyboard shortcuts with modifiers worked fine in Vim. Namely: shift+left/right that I mapped to switch Vim tabs, ctrl+up/down that I mapped to move ("bubble") lines, and shift+left/right which worked out of the box to jump by word in the command-line mode (e.g. when typing something like :e foo bar baz).

However, this setup had the problem that the Vim background color only shows behind text, as mentioned here.

So I removed

export TERM='xterm-256color'

from my .bashrc and instead put this in my .tmux.conf:

set -g default-terminal "screen-256color"

That fixed the Vim background color, but broke the keyboard shortcuts - they do unexpected things (move the cursor, delete text) instead.

By using ctrl+v to insert the verbatim output from the key combinations (as described here), I was able to work around it:

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

This makes the shortcuts work, but it doesn't feel like the right solution. Could anyone tell me what's happening here and how to fix it?

Henrik N
  • 1,626
  • 2
  • 14
  • 14

2 Answers2

86

You need to set the tmux window option xterm-keys so that tmux will pass these keys through to its terminals. You probably want to put this in your ~/.tmux.conf:

set-window-option -g xterm-keys on

Vim will usually automatically set up its handling of these keys when TERM is xterm-something, but it skips this since TERM is screen-256color. You can manually configure these keys in your ~/.vimrc like this:

if &term =~ '^screen'
    " tmux will send xterm-style keys when its xterm-keys option is on
    execute "set <xUp>=\e[1;*A"
    execute "set <xDown>=\e[1;*B"
    execute "set <xRight>=\e[1;*C"
    execute "set <xLeft>=\e[1;*D"
endif

At least that way you do not have to map all the various combinations.

Chris Johnsen
  • 39,401
  • 6
  • 111
  • 111
  • 2
    Thank you! That looks better than what I had, and I appreciate the explanation. One thing that was fixed by what I had, but not by your lines, was that up/down arrows didn't work in the Command-T plugin as described here: http://superuser.com/questions/237751/messed-up-keys-in-vim-when-running-inside-tmux I just added `map [B ` from one of the answers. Seems the reason there is some bad assumptions made by the plugin itself. – Henrik N Mar 18 '12 at 20:51
  • Just to be clear, your solution plus `map [B `from that other thread means everything now works fine. – Henrik N Mar 18 '12 at 21:02
  • @HenrikN Could you please clarify what ``map [B `` does? I don't see any difference by adding it to my .vimrc file. – Tropilio Apr 10 '19 at 12:01
  • @Francesco Boccardo: If you follow the link in my previous comment, and then follow the link again from there, you get to https://superuser.com/a/215181 which seems to explain it in excruciating detail :) – Henrik N Apr 10 '19 at 18:54
  • @HenrikN Thanks. So it is probably an OSX related issue, or maybe it's been resolved in these 7 years, because pressing command (control?) + r doesn't mess up the arrow keys in vim in tmux for me (I am on Linux). – Tropilio Apr 11 '19 at 07:39
  • `xterm-keys` is [not available](https://github.com/tmux/tmux/blob/3.2/CHANGES#L1120) since [2.4](https://github.com/tmux/tmux/blob/3.2/options-table.c#L1079-L1085). | `vim` automatically sets up handling of keys if they exist in the corresponding `terminfo` entry. Or rather, unless they are in the `terminfo` entry, `vim` doesn't know what to expect, and doesn't handle keys it doesn't know. Actually `vim` has some [builtin `termcap` entries](https://github.com/vim/vim/blob/v8.2.4036/src/term.c#L217-L1337)... – x-yuri Jan 07 '22 at 23:30
  • ...Fields from the host entries are added if they're [missing](https://github.com/vim/vim/blob/v8.2.4036/src/term.c#L1742) in the builtin entry (or no builtin entries matched). But I didn't see the keys in the builtin entries. To find out what keys are available: `:set termcap`. – x-yuri Jan 07 '22 at 23:30
11

As explained here, disable Background Color Erase (BCE) by clearing the t_ut terminal option (run :set t_ut= in Vim and then press Control+L to refresh the terminal's display) so that color schemes work properly when Vim is used inside tmux and GNU screen.

This way, you can keep your TERM value as xterm-256color for proper key detection while also getting proper Vim color scheme rendering too! :-)

sunaku
  • 1,176
  • 11
  • 7
  • 1
    Beautiful! Great detective work. – Henrik N Mar 08 '13 at 19:58
  • 2
    This is what I changed exactly: https://github.com/henrik/dotfiles/commit/f8347e465fe9c4b9ff7ea211e2263d6e34ace9dd Colors and modifier keys seem to work well both outside and inside tmux. – Henrik N Mar 08 '13 at 19:59
  • The [docs](https://man.archlinux.org/man/community/tmux/tmux.1.en) says: "The TERM environment variable must be set to ‘screen’ or ‘tmux’ for all programs running inside tmux. New windows will automatically have ‘TERM=screen’ added to their environment, but care must be taken not to reset this in shell start-up files or by the -e option." And: " For tmux to work correctly, this must be set to ‘screen’, ‘tmux’ or a derivative of them." – x-yuri Jan 07 '22 at 22:24