/tmp$ vim -u /dev/null -N -W foo
/tmp$ hd foo
00000000 80 fd 35 5a 5a |..5ZZ|
00000005
This affected quite a few people playing on vimgolf.com.
After some adventures through vim's source, I think I've tracked down exactly
what happens to cause the problem:
- Vim asks the terminal for its version string when it starts, in the
may_req_termresponse function, by sending the kPRV string from the
terminfo record, and then calling vpeekc_nomap.
- That reads the response from stdin into typebuf, and eventually ends
up in check_termcode, which handles terminal escape sequences.
- check_termcode finds the version response, and if it manages to
extract an xterm version number, it sets various features based on
that version number.
- check_termcode then translates the escape sequence into the key_name
array as KS_EXTRA and KE_IGNORE, which match the second and third
bytes of the escape sequence.
- Towards the end of check_termcode (near the comment "Add any modifier
codes to our string."), this becomes a three-byte sequence K_SPECIAL
KS_EXTRA KE_IGNORE, which matches the three bytes that appear in the
script file.
- check_termcode then puts this sequence into the typebuf, and doesn't
seem to set anything to make vim treat this sequence as something not
typed by the user.
- Later on, this character gets read, and ends up in vgetorpeek. Near
the comment "get a character: 2. from the typeahead buffer",
vgetorpeek ends up considering this character a typed character, and
feeds it to gotchars, which calls updatescript on each character to
write it to the script file.
I don't know the correct fix. Possibly something should set tb_maplen
to mark the character as the result of a map, or possibly the character
shouldn't get re-inserted into typebuf at all.
- Josh Triplett