emacs 如何正确显示 ANSI 的转义符

ANSI 转义符可以控制光标移动,刷新屏幕,更改字体颜色等等,在emacs中好像不太支持,在运行 yarn serve 进入 compilation-mode 的时候,他显示的是这样的

猜测可能是进入 compilation-mode 的时候 ANSI 转义符没有正确显示,查google配置一下代码

(require 'ansi-color)
(defun endless/colorize-compilation ()
  "Colorize from `compilation-filter-start' to `point'."
  (interactive)
  (let ((inhibit-read-only t))
    (ansi-color-apply-on-region
     compilation-filter-start (point))))

(add-hook 'compilation-filter-hook
          #'endless/colorize-compilation)

(defun regexp-alternatives (regexps)
  "Return the alternation of a list of regexps."
  (mapconcat (lambda (regexp)
               (concat "\\(?:" regexp "\\)"))
             regexps "\\|"))

(defvar non-sgr-control-sequence-regexp nil
  "Regexp that matches non-SGR control sequences.")

(setq non-sgr-control-sequence-regexp
      (regexp-alternatives
       '(;; icon name escape sequences
         "\033\\][0-2];.*?\007"
         ;; non-SGR CSI escape sequences
         "\033\\[\\??[0-9;]*[^0-9;m]"
         ;; noop
         "\012\033\\[2K\033\\[1F"
         )))

(defun filter-non-sgr-control-sequences-in-region (begin end)
  (save-excursion
    (goto-char begin)
    (while (re-search-forward
            non-sgr-control-sequence-regexp end t)
      (replace-match ""))))

(defun filter-non-sgr-control-sequences-in-output (ignored)
  (let ((start-marker
         (or comint-last-output-start
             (point-min-marker)))
        (end-marker
         (process-mark
          (get-buffer-process (current-buffer)))))
    (filter-non-sgr-control-sequences-in-region
     start-marker
     end-marker)))

(add-hook 'comint-output-filter-functions
          'filter-non-sgr-control-sequences-in-output)

可惜,没个卵用

我觉得相似的问题还有,进度条在emacs中显示不正确,他把每一帧都打印出来了,而且没有清除上一帧

刚刚我发现 shell-command 的输出中的颜色也没有显示,不过我在 stackoverflow 上面找到了一个能用的解决方案 https://stackoverflow.com/a/5821668/8051317

(require 'ansi-color)

(defadvice display-message-or-buffer (before ansi-color activate)
  "Process ANSI color codes in shell output."
  (let ((buf (ad-get-arg 0)))
    (and (bufferp buf)
         (string= (buffer-name buf) "*Shell Command Output*")
         (with-current-buffer buf
           (ansi-color-apply-on-region (point-min) (point-max))))))

或许你把 *Shell Command Output* 换成 *compilation* 就可以了?

好像没什么用诶
不知道 *compilation* 与 vterm的显示区别是什么,vterm有为什么能够正确显示ANSI转义符