2

When editing a dos-format file from a codebase which is mainly used with Visual Studio in a Windows environment on my local Ubuntu machine with VIM, I get to see the ^M character instead of a newline.

According to the VIM documentation, this represents the carriage return character.

Further complicating the problem is that this only occurs in certain places in the file, so the newlines don't seem to have a consistent format.

By default, VIM recognizes the file as dos file-format, which I see by executing :set ff?.

My goal is to edit the file without breaking its platform conformity; I don't want to persistently convert the file, only because I'm editing in VIM. Hence, the existing answer doesn't satisfy my problem. This answer, doesn't either.

Given this requirement, can I get VIM to just display all ^M's as newlines via some syntax highlighting setting?

Note that ^M isn't composed out of plain characters. If you'd insert them manually in VIM, you'd have to insert Cntr-V before inserting each character.

7
  • You want to display them as newlines? Wouldn't you have double spacing on those lines then? Just hiding the ^M won't do the trick?
    – B Layer
    Jan 22, 2018 at 8:56
  • @BLayer Why would I have double spacing? When I edit the file in Visual Studio on a Windows machine the ^Ms that occur inbetween lines in VIM are actually newlines, where the newlines give the correct view.
    – easytarget
    Jan 22, 2018 at 12:35
  • 1
    Because you already have linefeed (visually a newline). Now you're treating ^M as newline, too. That's two newlines. Double spacing.
    – B Layer
    Jan 22, 2018 at 14:00
  • 2
    @BLayer We both misinterpreted the original issue. See the comments under my answer or my answer update for the actual situation.
    – Rich
    Jan 22, 2018 at 14:26
  • Thanks @Rich ... not how I first read it at all.
    – B Layer
    Jan 22, 2018 at 20:04

1 Answer 1

4

^M visible with ff=dos

If set ff? reports that the file is dos and you are seeing ^M carriage return characters at the end of any lines, then your file already has broken, non-conforming line-endings.

e.g. if the file displays like this:

regular line
another regular line
line with an extra carriage return^M
third regular line    

This means that the actual content of your file looks something like (broken into lines for clarity):

regular line^M^J
another regular line^M^J
line with an extra carriage return^M^M^J
third regular line^M^J

If this is the case, the appropriate cause of action is simply to delete the extra carriage return and to look into how the file came to have such odd line endings.

^M visible with ff=unix

A more common scenario is that you have a file with mixed endings. This would result in a file where certain (dos-formatted) lines are displayed with a ^M at the end of the line. If you were seeing a file like this, however, :set ff? would report unix, not dos.

This scenario can be fixed by adding carriage returns to lines which do not have them. I usually do this by yanking a carriage return from one of the lines that has one, and then using a :global command:

:g/[^\r]$/norm! $p

N.B. As far as I am aware, you cannot easily perform the above fix with a :substitute command, because the carriage return in the replacement would be interpreted as a newline and instead a linefeed will be added.

The carriage returns will still be visible after running command, but when you save and reopen, Vim will reinterpret the file as dos format.

An alternative fix is to remove all the carriage returns at the end of lines:

:%s/\r$/

This leaves you with a file with unix line endings, but it's easy to get Vim to convert these back into dos line endings:

:set fileformat=dos

UPDATE: ^M instead of newlines

It turns out that what the OP is seeing is something like this:

first line^Msecond line
third line

This means that some of the line-endings don't contain linefeeds at all, they are just a carriage return. (This is old "Classic" MacOS style for line-endings — mac in 'fileformats'.)

Similarly to the situations described above, this is incorrect in a dos formatted file: the file is malformed, even if Visual Studio displays it in a way that looks correct.

This can be fixed with the following confusing :substitute command:

:%s/\r/\r/g

Of course, the command doesn't actually replace all carriage returns with carriage returns!

In the "search" part of the command the \r carriage return will only match the ones that are not being using in a CRLF line-ending pair. In the "replace" part, the carriage return is interpreted as a newline, splitting the lines correctly.

After making the edit, the file will now be correctly formatted with dos endings throughout, and so will display correctly both in Vim and Visual Studio.

Viewing the actual contents with xxd

Vim comes with a hex editor that can be used to view (or edit) the byte-level contents of the file. If you're sceptical about what I've written above, you can double-check what actual line-endings are being used with the command:

:%!xxd

N.B. This will replace the contents of your file with a hex-dump: when you are done, press u to undo the change and return to your file.

The regular contents are displayed on the right, the corresponding hex-codes on the left. On the right-hand side, both carriage returns and linefeeds are displayed as dots, so a unix line-ending will be shown as . a dos line ending as .. and a dos ending with an extra carriage return as ....

7
  • If set ff? reports that the file is dos and you are seeing ^Mcarriage return characters at the end of any lines, then your file already has broken, non-conforming line-endings. e.g. if the file displays like this: (...) It's worse. At the start of the file the ^Ms occur inbetween lines, where the line should suppose to be multiple lines; the ^M should be interpreted as a newline.
    – easytarget
    Jan 22, 2018 at 12:30
  • @MusséRedi I've updated my answer in response to your comment.
    – Rich
    Jan 22, 2018 at 13:32
  • On the update, your second example first line ^Msecond line precisely replicates the problem.
    – easytarget
    Jan 22, 2018 at 13:33
  • @MusséRedi Okay, then the actual content must look something like this: first line ^Msecond line, when it should look like this. first line ^M^Jsecond line. I'll update again to include a command to fix the issue.
    – Rich
    Jan 22, 2018 at 13:35
  • If deleting the carriage return and inserting newlines in its place doesn't malform the view on a Windows machine using Visual Studio, I think I'll be fine. I'll try and reproduce it to tomorrow. :)
    – easytarget
    Jan 22, 2018 at 13:36

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.