I have a log file that uses ANSI escape color codes to format the text. The mode is fundamental
. There are other answered questions that address this issue but I'm not sure how to apply it to this mode or any other mode. I know the solution has something to do with configuring ansi-color
in some way.
In fact, any code we type into this prompt will also be colored red, as will any subsequent output! That is how Ansi colors work: once you print out the special code enabling a color, the color persists forever until someone else prints out the code for a different color, or prints out the Reset code to disable it.
ANSI escape sequences are a standard for in-band signaling to control cursor location, color, font styling, and other options on video text terminals and terminal emulators. Certain sequences of bytes, most starting with an ASCII escape character and a bracket character, are embedded into text.
You could use code below
(require 'ansi-color)
(defun display-ansi-colors ()
(interactive)
(ansi-color-apply-on-region (point-min) (point-max)))
Then you can execute display-ansi-colors
via M-x, via a key-binding of your choosing, or via some programmatic condition (maybe your log files have a extension or name that matches some regexp)
If you want to do this with read-only buffers (log files, grep results), you may use inhibit-read-only
, so the function will be:
(defun display-ansi-colors ()
(interactive)
(let ((inhibit-read-only t))
(ansi-color-apply-on-region (point-min) (point-max))))
User defined function:
(defun my-ansi-color (&optional beg end)
"Interpret ANSI color esacape sequence by colorifying cotent.
Operate on selected region on whole buffer."
(interactive
(if (use-region-p)
(list (region-beginning) (region-end))
(list (point-min) (point-max))))
(ansi-color-apply-on-region beg end))
For buffers that uses comint/compilation use filter:
(ignore-errors
(require 'ansi-color)
(defun my-colorize-compilation-buffer ()
(when (eq major-mode 'compilation-mode)
(ansi-color-apply-on-region compilation-filter-start (point-max))))
(add-hook 'compilation-filter-hook 'my-colorize-compilation-buffer))
Gavenkoa's and Juanleon's solutions worked for me, but were not satisfying as they were modifying the contents of the file I was reading.
To colorize without modifying the contents of the file, download tty-format.el and add the following to your .emacs:
(add-to-list 'load-path "path/to/your/tty-format.el/")
(require 'tty-format)
;; M-x display-ansi-colors to explicitly decode ANSI color escape sequences
(defun display-ansi-colors ()
(interactive)
(format-decode-buffer 'ansi-colors))
;; decode ANSI color escape sequences for *.txt or README files
(add-hook 'find-file-hooks 'tty-format-guess)
;; decode ANSI color escape sequences for .log files
(add-to-list 'auto-mode-alist '("\\.log\\'" . display-ansi-colors))
tty-format is based on ansi-color.el which is only shipped natively with recent versions of emacs.
On large files, performance of ansi-color-apply-on-region
is slow. Here's a solution that colors the current region and works with read-only buffers.
(require 'ansi-color)
(defun ansi-color-region ()
"Color the ANSI escape sequences in the acitve region.
Sequences start with an escape \033 (typically shown as \"^[\")
and end with \"m\", e.g. this is two sequences
^[[46;1mTEXT^[[0m
where the first sequence says to diplay TEXT as bold with
a cyan background and the second sequence turns it off.
This strips the ANSI escape sequences and if the buffer is saved,
the sequences will be lost."
(interactive)
(if (not (region-active-p))
(message "ansi-color-region: region is not active"))
(if buffer-read-only
;; read-only buffers may be pointing a read-only file system, so don't mark the buffer as
;; modified. If the buffer where to become modified, a warning will be generated when emacs
;; tries to autosave.
(let ((inhibit-read-only t)
(modified (buffer-modified-p)))
(ansi-color-apply-on-region (region-beginning) (region-end))
(set-buffer-modified-p modified))
(ansi-color-apply-on-region (region-beginning) (region-end))))
The one downside is that ansi-color-apply-on-region
removes the ANSI escape sequence characters from the buffer, so when you save, they are lost. I wonder if there's a way to hide the characters instead of stripping them?
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With