What's causing the behaviour
When you press the left arrow, your terminal is sending the following escape sequence:
ESC O D
This can also be notated as ^[OD
, where ^[
is notation for Ctrl-[
, which is another way of notating or entering the ESC character. (Try it in insert mode!)
Vim is not recognising this as an escape sequence, and therefore it is treating those keystrokes as if you had typed them out yourself:
- Esc: Leave insert mode,
- O: Begin a new line above the cursor and enter insert mode,
- D: Enter a 'D' character.
You can confirm that this is what your terminal is sending by entering insert mode and then pressing Ctrl-V followed by the Left arrow.
What's going wrong
The escape sequence might be timing out
The only way that Vim can distinguish the escape sequence from the same three characters manually typed in is by the time that occurs between the receipt of each character. It's possible therefore on slow terminals or very busy systems that there is sufficient delay between each character that Vim is deciding it's not an escape sequence and just interpreting the keystrokes as described above.
This is described in :help vt100-cursor-keys
and further in :help timeout
— the suggested solution is to set a sufficiently large ttimeoutlen
, but disabling timeouts entirely by setting both notimeout
and nottimeout
would also work.
However, given your setup, this is pretty unlikely to be the issue.
Vim doesn't recognise the sequence
It's more likely that the problem is that Vim doesn't recognise the escape sequence sent, and so is interpreting it as keystrokes. You can check this with the following command:
:set <left>?
In a working setup with your current terminal configuration, this should give either of the following outputs:
t_kl <Left> ^[O*D
t_kl <Left> ^[OD
If you see anything else1, then Vim and your terminal are not quite speaking the same language.
The correct way to fix this would be to fix your terminal configuration so that your terminfo database reports the sequences that are actually sent when you press the arrow keys, but doing so can be complicated. A slightly hacky fix is to change what your terminal sends to match what Vim is expecting. I infer from your comments that you are using the default Mac Terminal.app: You can change what escape sequences are sent for each keystroke in Preferences → Profiles → Your profile → Keyboard.
However, the easiest fix is probably to inform Vim directly what escape sequences to expect. You can do this by setting its terminal options thus:
set <up>=^[OA
set <down>=^[OB
set <right>=^[OC
set <left>=^[OD
Note that the ^[
in the above is a literal ESC
character. You cannot just type ^ followed by [! The easiest way to enter the mappings is to enter e.g.
set <left>=
and then, still in insert mode, press Ctrl-V followed by the left arrow. Note that you are then setting the escape sequence directly to what Vim receives when you press the arrow key... by sending it that sequence!
1: One likely possibility is the CSI sequence: ^[[D