- 0 Talk
-
How to make fileencoding work in the modeline
created April 12, 2005 · complexity intermediate · author Wu Yongwei · version 6.0
Currently fileencoding does not work well in a modeline. When Vim sees the fileencoding setting, the file has already been read, and only output will be affected. That will cause even more trouble as, for example, if the default encoding is latin1 and the modeline has fileencoding=utf-8, then the resulting file will be a utf-8 file converted as latin1 to utf-8 again.
I have these lines in vimrc to workaround this problem:
function! CheckFileEncoding()
if &modified && &fileencoding != ''
exec 'e! ++enc=' . &fileencoding
endif
endfunction
au BufWinEnter *.txt call CheckFileEncoding()
Change the "*.txt" part if wanted. You may also want to put set encoding=utf-8 (to edit files of different encodings simultaneously) and "language messages en" (display all menus and messages in English) in your vimrc file.
Comments
Edit
For me, the 'fileencodings' option is a nice way to make Vim determine fileencoding itself. So the main topic of the tip is not so actual. But 'language messages en' -- that's very nice, I didn't know I can do that.
Of course, fileencodings is very useful, but it cannot handle some cases, e.g., one wants to edit simultaneously GB2312- and BIG5-encoded files. Fileencodings cannot distinguish between 8-bit encodings.
What the script does is:
If the file is modified (&modified; because "set fileencoding" is done after loading the file) and fileencoding is set (&fileencoding != ), then reload the file regardless of the changed state (e!) with the specified encoding (++enc=).
A command string like "e! ++enc=utf-8" will be produced by "'e! ++enc=' . &fileencoding", and then executed.
This breaks the following use case:
vim foo.c (where foo.c might not contain a modeline with an fenc) (modify foo.c) :e bar.c :b1 (to switch back to foo.c)
Now foo.c's modifications were lost, because BufWinEnter is fired under more circumstances than just initial file load.
Recommendation -- do the following to ensure this is only done on initial buffer read:
au BufReadPost * let b:reloadcheck = 1
au BufWinEnter * if exists('b:reloadcheck') | unlet b:reloadcheck | if &mod != 0 && &fenc != "" | exe 'e! ++enc=' . &fenc | endif | endif