The help text for fileencodings says this:
This is a list of character encodings considered when starting to edit an existing file. When a file is read, Vim tries to use the first mentioned character encoding. If an error is detected, the next one in the list is tried. When an encoding is found that works, 'fileencoding' is set to it.
Since all byte strings are valid latin1 text, but utf-8 is more common, I have set my fileencodings as:
set fileencodings=utf-8,latin1
However, vim appears to use utf-8 even when there are decoding errors. A minimal example is the file containing the bytes 0x00 0xfd:
% xxd test.in
00000000: 00fd ..
% vim test.in
"test.in" [noeol][ILLEGAL BYTE in line 1] 1L, 2C
:set fileencoding?
fileencoding=utf-8
Why is this? How can I ask vim to fall back to latin1 when it sees illegal bytes?
[noeol]makes it invalid for everything infileencodings. When this fails, the value ofencodingis used.encodingdefaults to latin1, unless a suitable value is found in the environmental variable$LANG, which is likely utf-8 these days.echo $LANGis likely to reveal the source of the ultimate utf-8 fallback. This shouldn't happen with a file that ends in a newline, however... and you won't get the[noeol]error.set nofixeolin your.vimrcwill 'fix' this by ignoring files that don't end in newlines. – brhfl Mar 29 '18 at 21:16[noeol]before, it almost seems to be the combination of the leading NULL byte and the lack of a trailing eol in this case. Regardless,$LANGis almost certainly where the ultimate fallback is coming from. – brhfl Mar 29 '18 at 21:38nofixeoltrick to work though: even after setting it, a file with no final eol doesn't fall back to latin1 (and the documentation fornofixeolseems to imply it is used only when writing, not reading). – Daniel Wagner Mar 29 '18 at 23:28