This is because terminal translates X events into escape sequences like these:
<F1> -> ^[OP
<F2> -> ^[OQ
<F3> -> ^[OR
<F4> -> ^[OS
<F5> -> ^[[15~
<F6> -> ^[[17~
and so on (
^[ is a escape character). In some terminals vim is able to get these sequences from terminfo database, but sometimes terminfo database does not match characters actually send or does not contains
key_f* entries. In this case pressing
<F1> will result in getting escape (escapes current mode unless it is normal mode),
O (in normal mode: create a new line before cursor line and enter insert mode) and some character which is inserted on the new line (and for
~ is that command that inverts case). You may fix it by putting into vimrc something like that
" Condition should identify terminal in question so "
" that it won't change anything for terminals without this problem "
if !has("gui_running") && $TERM is "xterm"
for [key, code] in [["<F1>", "\eOP"],
execute "set" key."=".code
If your codes are different from that ones that I used as example, use
<C-v><F1> (in insert or command-line modes) to get what your terminal is sending (more info in