How do I display ANSI color codes in emacs for any mode?

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?

Tags:

Emacs

Ansi