I'm running a (start-process) which spits out terminal escape codes into a buffer and it looks ugly. Is there a mode that will interpret these codes into colors? Something similar to whatever ansi-term does?

  • You do need to set up the plumbing with ansi-color but I don't know how that works when you aren't in Comint mode. Jun 3, 2017 at 21:30

2 Answers 2


You can use "process sentinel" mentioned in @steve-lorimer's answer if it is OK for you to get color AFTER the process is finished, otherwise you should use "process filter" instead.

Take command echo -e "\e[31mHello World\e[0m" as an example, you can simply use comint-output-filter (I learnt this by reading shell-command's source code)

(let ((process
       (start-process "echo" "*echo*"
                      "echo" "-e" "\e[31mHello World\e[0m")))
  (with-current-buffer (process-buffer process)
    (display-buffer (current-buffer))
    (require 'shell)
    (set-process-filter process 'comint-output-filter)))

besides colors, comint-output-filter can also handle progress bar (used by commands like wget) correctly.

Or you can also make your own filter:

(let ((process
       (start-process "echo" "*echo*"
                      "echo" "-e" "\e[31mHello World\e[0m")))
  (with-current-buffer (process-buffer process)
    (display-buffer (current-buffer))

;; Base on `ordinary-insertion-filter' from (info "(elisp) Filter Functions")
(defun echo-output-filter (proc string)
  (when (buffer-live-p (process-buffer proc))
    (with-current-buffer (process-buffer proc)
      (let ((moving (= (point) (process-mark proc))))
          ;; Insert the text, advancing the process marker.
          (goto-char (process-mark proc))
          (insert (ansi-color-apply string))
          (set-marker (process-mark proc) (point)))
        (if moving (goto-char (process-mark proc)))))))

Both of them work from here.


This SO answer makes reference to ansi-color-apply-on-region.

The idea is you use set-process-sentinel to get notified when your process exits, and then use ansi-color-apply-on-region on the buffer

 (start-process "foo" "*Foo*" foo-command foo-args)
 (lambda (p _m)
   (when (eq 0 (process-exit-status p))
     (with-current-buffer (process-buffer p)
       (ansi-color-apply-on-region (point-min) (point-max))))))

Your Answer

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

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