60

Sometimes I need to read log files that have ^M (control-M) in the line endings. I can do a global replace to get rid of them, but then something more is logged to the log file and, of course, they all come back.

Setting Unix-style or dos-style end-of-line encoding doesn't seem to make much difference (but Unix-style is my default). I'm using the undecided-(unix|dos) coding system.

I'm on Windows, reading log files created by log4net (although log4net obviously isn't the only source of this annoyance).

Henke
  • 4,445
  • 3
  • 31
  • 44
  • 1
    Unfortunately, set-buffer-file-encoding-system doesn't do it. The buffer opens with the mode line saying UNIX. Giving it C-x RET f UNIX RET just ends up marking the buffer as modified without hiding the pesky ^M's. –  Apr 08 '09 at 17:00
  • Emails in GNUS are another place you can encounter buffers with mixed end-of-line encoding. For instance if one is sending from a Windows-centric institution, perhaps Outlook. The header info is getting the Unix EOL encoding. – Brady Trainor Sep 19 '14 at 17:31

12 Answers12

82
(defun remove-dos-eol ()
  "Do not show ^M in files containing mixed UNIX and DOS line endings."
  (interactive)
  (setq buffer-display-table (make-display-table))
  (aset buffer-display-table ?\^M []))

Solution by Johan Bockgård. I found it here.

Lorem Ipsum
  • 4,020
  • 4
  • 41
  • 67
binOr
  • 2,551
  • 1
  • 22
  • 18
  • 6
    If you want this function to be run almost always add the following to your `.emacs` (took me some time to find out): `(add-hook 'text-mode-hook 'remove-dos-eol)` – Henrik Jun 26 '12 at 20:59
  • 2
    YEARS I've been suffering the ^M. Thank you. – EoghanM Dec 03 '13 at 16:05
  • @Henrik I realize that your comment is two years old, but I am unable to get my .emacs file to automatically call this function. Is there another mode that I might be in other than text-mode? – Russell Apr 30 '14 at 13:34
  • 1
    @Russell, does `C-h m` (`describe-mode`) help? – Brady Trainor Sep 19 '14 at 16:58
  • This worked for me. I also extended @Henrik's solution with an addition to magit-diff-mode-hook. Sanity reigns again :-) – Philip Daniels Jun 16 '16 at 08:52
19

Modern versions of emacs know how to handle both UNIX and DOS line endings, so when ^M shows up in the file, it means that there's a mixture of both in the file. When there is such a mixture, emacs defaults to UNIX mode, so the ^Ms are visible. The real fix is to fix the program creating the file so that it uses consistent line-endings.

Edric
  • 23,676
  • 2
  • 38
  • 40
  • 5
    Emacs is wrong. The real fix is to fix Emacs. E.g. git creates conflict files that don't have ^M s in the 'control' lines (e.g. lines beginning with <<<<<<). It is perfectly valid for git to ignore whatever line ending the file has, as the control lines are 'meta'. – EoghanM Dec 03 '13 at 16:08
  • 2
    This answer explains emacs behavior but does not address the question. The OP wants to *not see* the CR (^M) characters, although they are still there. – Stéphane Gourichon Apr 11 '18 at 09:51
7

What about?

C-x RET c dos RET C-x C-f FILENAME RET

I made a file that has two lines, with the second having a carriage return. Emacs would open the file in Unix coding, and switching coding system does nothing. However, the universal-coding-system-argument above works.

ashawley
  • 4,195
  • 1
  • 27
  • 40
5

I believe you can change the line coding system the file is using to the Unix format with

C-x RET f UNIX RET

If you do that, the mode line should change to add the word "(Unix)", and all those ^M's should go away.

T.E.D.
  • 44,016
  • 10
  • 73
  • 134
  • Not helpful, I think. set-buffer-file-coding-system seems to change the actual contents of the edited file. – hillu Apr 08 '09 at 16:37
  • Specifying coding system `unix` did not work for me -- but specifying `dos` did (after I reverted the buffer). – John H. Aug 15 '17 at 18:14
  • @JohnH. - I've seen this recently when a text file had both types of line endings. Emacs just has to pick one, and the lines with the other ending look weird. In general, best to pick the one you want it to be, and then fix the offending line endings. (eg: Use the mouse to put a ^M in the kill buffer, then use M-x query-replace to replace them with an empty string) – T.E.D. Aug 15 '17 at 19:12
4

If you'd like to view the log files and simply hide the ^M's rather than actually replace them you can use Drew Adam's highlight extension to do so.

You can either write elisp code or make a keyboard macro to do the following

select the whole buffer
hlt-highlight-regexp-region
C-q C-M
hlt-hide-default-face

This will first highlight the ^M's and then hide them. If you want them back use `hlt-show-default-face'

justinhj
  • 11,147
  • 11
  • 58
  • 104
  • Thanks for the plug, Justin. I added another (different) solution, below. More than one way to skin a cat... – Drew Jan 01 '12 at 08:42
3

Edric's answer should get more attention. Johan Bockgård's solution does address the poster's complaint, insofar as it makes the ^M's invisible, but that just masks the underlying problem, and encourages further mixing of Unix and DOS line-endings.

The proper solution would be to do a global M-x replace-regexp to turn all line endings to DOS ones (or Unix, as the case may be). Then close and reopen the file (not sure if M-x revert-buffer would be enough) and the ^M's will either all be invisible, or all be gone.

2

Put this in your .emacs:

(defun dos2unix ()
  "Replace DOS eolns CR LF with Unix eolns CR"
  (interactive)
    (goto-char (point-min))
      (while (search-forward "\r" nil t) (replace-match "")))

Now you can simply call dos2unix and remove all the ^M characters.

sudeepdino008
  • 3,194
  • 5
  • 39
  • 73
2

You can change the display-table entry of the Control-M (^M) character, to make it displayable as whitespace or even disappear totally (vacuous). See the code in library pp-c-l.el (Pretty Control-L) for inspiration. It displays ^L chars in an arbitrary way.

Edited: Oops, I just noticed that @binOr already mentioned this method.

Drew
  • 29,895
  • 7
  • 74
  • 104
1

If you encounter ^Ms in received mail in Gnus, you can use W c (wash CRs), or

(setq gnus-treat-strip-cr t)
Brady Trainor
  • 2,026
  • 20
  • 18
0

sudeepdino008's answer did not work for me (I could not comment on his answer, so I had to add my own answer.).

I was able to fix it using this code:

(defun dos2unix ()
  "Replace DOS eolns CR LF with Unix eolns CR"
  (interactive)
    (goto-char (point-min))
      (while (search-forward (string ?\C-m) nil t) (replace-match "")))
RMK
  • 3
  • 2
0

what about using dos2unix, unix2dos (now tofrodos)?

Massagran
  • 1,781
  • 1
  • 20
  • 29
0

Like binOr said add this to your %APPDATA%.emacs.d\init.el on windows or where ever is your config.

;; Windows EOL
(defun hide-dos-eol ()
  "Hide ^M in files containing mixed UNIX and DOS line endings."
  (interactive)
  (setq buffer-display-table (make-display-table))
  (aset buffer-display-table ?\^M []))

(defun show-dos-eol ()
  "Show ^M in files containing mixed UNIX and DOS line endings."
  (interactive)
  (setq buffer-display-table (make-display-table))
  (aset buffer-display-table ?\^M ?\^M))

(add-hook 'text-mode-hook 'hide-dos-eol)
  • should i sugest a change itn the anser of binOr instead ? – Nicolas Lussier-Clément Apr 24 '19 at 16:57
  • Once you have sufficient [reputation](http://stackoverflow.com/help/whats-reputation) you will be able to [comment on any post](http://stackoverflow.com/help/privileges/comment). See also: [Why do I need 50 reputation to comment? What can I do instead?](http://meta.stackexchange.com/questions/214173/why-do-i-need-50-reputation-to-comment-what-can-i-do-instead). – help-info.de Apr 24 '19 at 17:12
  • My first comment from above is a note that should be observed for late answers. You can leave your answer of course. But please explain your program code e.g. Added configuration for **Show** and **Hide**. A possible comment as a quick way on @binOr 's answer is : To show ^M you may want to add a `(defun show-dos-eol ()`and `(aset buffer-display-table ?\^M ?\^M))`. – help-info.de Apr 24 '19 at 17:19
  • Cool for now i can't comment. I suggested a modification to binOr if or when he change it i'll remove my comment which is only a small improvement of his working solution ! – Nicolas Lussier-Clément Apr 24 '19 at 17:51