Hiding ^M in Emacs
Asked Answered
J

12

61

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).

Justinn answered 8/4, 2009 at 16:20 Comment(2)
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.Justinn
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.Orangeism
J
84
(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.

Julijulia answered 15/4, 2009 at 9:33 Comment(5)
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)Citriculture
YEARS I've been suffering the ^M. Thank you.Nickel
@Citriculture 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?Justinn
@Russell, does C-h m (describe-mode) help?Orangeism
This worked for me. I also extended @Henrik's solution with an addition to magit-diff-mode-hook. Sanity reigns again :-)Kohn
P
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.

Palmitin answered 9/4, 2009 at 7:0 Comment(2)
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'.Nickel
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.Redemption
B
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.

Burkey answered 8/4, 2009 at 17:43 Comment(1)
Slightly modified for a file already open: C-x RET c dos RET M-x revert-buffer RETFarrel
N
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.

Neu answered 8/4, 2009 at 16:32 Comment(3)
Not helpful, I think. set-buffer-file-coding-system seems to change the actual contents of the edited file.Etheridge
Specifying coding system unix did not work for me -- but specifying dos did (after I reverted the buffer).Coel
@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)Neu
S
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'

Script answered 8/4, 2009 at 16:49 Comment(1)
Thanks for the plug, Justin. I added another (different) solution, below. More than one way to skin a cat...Shebat
Z
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.

Zero answered 27/7, 2012 at 3:29 Comment(1)
M-x replace-string C-q C-m RET (from lists.netisland.net/archives/plug/plug-1999-06/msg00365.html)Jaala
S
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.

Shebat answered 1/1, 2012 at 8:49 Comment(0)
B
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.

Bethesda answered 7/11, 2013 at 7:51 Comment(0)
O
1

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

(setq gnus-treat-strip-cr t)
Orangeism answered 21/9, 2014 at 6:41 Comment(0)
E
0

what about using dos2unix, unix2dos (now tofrodos)?

Eighty answered 16/12, 2010 at 16:0 Comment(0)
O
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 "")))
Obeah answered 4/3, 2015 at 15:50 Comment(1)
In the future use an @ before a person's name: @ObeahCrayton
B
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)
Bursa answered 24/4, 2019 at 15:37 Comment(4)
should i sugest a change itn the anser of binOr instead ?Whiteside
Once you have sufficient reputation you will be able to comment on any post. See also: Why do I need 50 reputation to comment? What can I do instead?.Fixate
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 @Julijulia 's answer is : To show ^M you may want to add a (defun show-dos-eol ()and (aset buffer-display-table ?\^M ?\^M)).Fixate
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 !Whiteside

© 2022 - 2024 — McMap. All rights reserved.