This autocmd in your vimrc will do just that. If it finds any occurrences of a carriage return at the end of a line, and the file was read in Unix format, it will automatically re-read the file in DOS format. This will automatically correct the issue for good when you save the file, but it is most useful for times when you cannot save the file for some reason (maybe it is in a code module that is "locked down" for example).

Most of this is self-explanatory, but there are a couple tricks to it:

The 'n' flag is used on the search, so that the cursor does not move.

The autocmd is nested. This allows other autocmds, like those that load syntax highlighting, etc., to also fire on the reload.

Because the autocmd is nested, it will itself fire again on the reload. Thus, we use the b:reload_dos variable to detect when it has already fired so we do not keep firing recursively.

This can be improved a bit. It might be nice to have a warning of some sort when this auto-reload occurs. Or maybe you want to change as few lines as possible, so you can manually convert the fileformat to the one that changes the fewest lines (for example, if only 2 lines out of 12000 have DOS-style endings, why convert the whole file to DOS?). Also, the detection of DOS-format endings uses a search, which could take a very long time on very large files.

The following version (when possible) limits the length of time allowed for the search before giving up, and additionally gives a message to the user by redirecting the output of an :s command with the 'n' flag to count matches without making changes and parsing it to output a message like, "File has 2 DOS-style lined endings out of 12000 lines."

It is not trivial to make this work alongside plugins which also reload the buffer. See comments below.

If you use a plugin which relies on byte counts within a file (like eclim), buffers reloaded in this way will no longer match the byte counts in the file on disk, so any communication about the byte position can easily fail.

This takes advantage of the fact that adding zero to a String gives the Number found at the start of the string (or zero if the string starts with a non-numeric character or is empty) — see (of all places) :help octal

Doesn't work for me. It looks like you're trying to cleverly auto-convert the first number in the substitute string to a number, but when I try that it always comes out with zero, because the string contains something like:

^@^@3 matches on 3 lines^@3 matches on 3 lines^@

Using the substitute call used in the main script seems to fix it, that's probably why it was there in the first place.

I have &ff shown in my statusline so I didn't need the additional echo about the decision made, and I prefer ignoring &modifiable/&readonly and instead setting nomodified after converting back to Unix (not technically true, but close enough to being true for the reasons I use this script).