You can paste Vim's builtin termcap database in the current buffer with the following command:
put =execute('set termcap')
In it, you should find the text t_ku <Up> ^[OA
, which means that when you press Up
, the terminal will send Esc O A
. Or you could just execute :echo &t_ku
, to get the value of the terminal option 't_ku'
(see :h t_ku
). It should display ^[OA
.
I don't know all the details about why there's a difference between $ cat
and Vim, but you may be interested in these links:
Here's an excerpt from the first link:
VTxxx (VT100 and up) terminals may send different escape sequences for the cursor (arrow) keys depending on how they are set up. The choices are referred to as the normal and application modes. Initially, the terminal is in normal mode.
VTxxx terminals are usually set up so that full-screen applications will use the cursor application mode strings. This is good for full-screen applications, including legacy applications which may have hard-coded behavior, but bad for interactive shells (e.g., ksh, tcsh, bash) which use arrow keys to scroll through a history of command strings.
To see the difference between normal/application modes, consider this example:
- In normal (non-application) mode, the terminal transmits a down-arrow as \E[C, which happens to echo as a down-arrow.
- In application mode the terminal transmits \EOC, which echoes as C. That is because the \EO is the SS3 control, which says to use the character from the G3 character set for the next cell.
And here's a table from the second one:
The cursor keys transmit the following escape sequences depending on the
mode specified via the DECCKM escape sequence.
Key Normal Application
-------------+----------+-------------
Cursor Up | CSI A | SS3 A
Cursor Down | CSI B | SS3 B
Cursor Right | CSI C | SS3 C
Cursor Left | CSI D | SS3 D
-------------+----------+-------------
Basically, it seems that the terminal is in “normal mode” when you are in the shell, and in “application mode” when you are in a full-screen application such as Vim.
When you press Up
, the terminal sends the sequence:
- (if it's in normal mode)
CSI A
, where CSI
means Control Sequence Introducer
and is produced by ESC [
; in caret notation, the whole sequence is displayed as ^[[A
- (if it's in application mode)
SS3 A
, where SS3
is described as Single Shift Select of G3 Character Set
here, and is produced by ESC O
; in caret notation, the whole sequence is displayed as ^[OA
You can also probably find these 2 sequences, Esc [ A
and Esc O A
, in the xterm-256color
entry of your terminfo database:
$ infocmp -x xterm-256color | vim -R -
Inside this buffer, if you look for the capabilities cuu1
and kcuu1
, you should find:
cuu1=\E[A
kcuu1=\EOA
In man terminfo
, these capabilities are described as follows:
cursor_up cuu1 up up one line
key_up kcuu1 ku up-arrow key
As rightly pointed out by @Rich, in the shell, you can make the terminal enter the application mode by sending the sequence stored in the smkx
capability. To do so, you may execute $ tput smkx
. And to make it re-enter the normal mode, you may execute $ tput rmkx
.
So, you could temporarily make the Up
key produce Esc O A
like in Vim, if you executed:
$ tput smkx
$ cat
Up
C-c
$ tput rmkx
The smkx
and rmkx
capabilities are also described in man terminfo
:
keypad_xmit smkx ks enter 'keyboard_transmit' mode
keypad_local rmkx ke leave 'keyboard_transmit' mode
For some reason, here, the application mode is called keyboard_transmit
mode. In Vim, it's called keypad transmit
mode (see :h t_ks
).