Why is Vim eating up Ctrl when used with Ctrl+v and how to fix it

readlineterminalvim

I'm using Vim /etc/zsh/zshrc to add key bindings for zsh because it doesn't work with inputrc. In my terminal with tmux when I type Ctrl+v then Ctrl+LeftArrow the shell will show ^[OD. However, when I'm in Vim insert mode, pressing the same sequence will result in ^[[D.

I found out that ^[[D is what the shell produces when I type Ctrl+v then LeftArrow. I have also changed ^[[D to ^[OD in the file /etc/zsh/zshrc and it works as expected (pressing Ctrl+LeftArrow causes the cursor to move back a word). Here is the line I'm talking about:

bindkey "^[OD" backward-word

I guess something is wrong with Vim because it's consuming the Ctrl. How do I fix this?

Best Answer

This is actually your terminal doing something weird, not Vim. Terminals have two sets of control sequences associated with cursor keys, for historical reasons: one for full-screen applications, often called “application cursor keys mode”, and one for read-eval-print applications (e.g. shells).

In the old days, read-eval-print applications didn't have any line-editing features, and it was intended that the terminal, or the OS terminal driver, would eventually become more sophisticated. So the terminal sent control sequences intended for the terminal driver. Somehow the Unix terminal drivers never gained decent line-editing features; these were added to applications instead (e.g. through the readline library).

Your terminal is sending ␛OD for Ctrl+Left in line edition cursor keys mode, and ␛[D in application cursor keys mode. You have two options:

  • Configure your terminal not to make a difference between the two modes. How to do this is entirely dependent on your terminal emulator.
  • Live with it. Since any given application always sets the terminal in the same mode, just configure its key bindings according to the mode it uses.
Related Question