黄瓜的ANSI颜色破坏了Emacs编译缓冲区。

45

在Emacs中工作时,我使用编译命令(默认为F12)运行程序。当我在Emacs中运行Cucumber时,Cucumber输出的ANSI颜色Emacs编译模式不解释。结果很难看和难以阅读。下面是*compilation*缓冲区显示丑陋的片段:

^[[31m(::) failed steps (::)^[[0m

我正在使用的命令:

( cd ~/lab/rails/todolist && rake cucumber:all )

版本:

  • Emacs 23.1
  • Cucumber 0.8.3
  • Cucumber-rails 0.3.2

如果我可以做到以下任何一点,世界将充满阳光和鸟语:

  • 使 Emacs 解释其编译缓冲区中的 ANSI 颜色代码,或
  • 使 Cucumber 停止输出 ANSI 颜色代码。

有什么想法吗?

3个回答

77
我使用这个命令在我的编译缓冲区中启用ansi颜色解释:
(require 'ansi-color)
(defun colorize-compilation-buffer ()
  (let ((inhibit-read-only t))
    (ansi-color-apply-on-region (point-min) (point-max))))
(add-hook 'compilation-filter-hook 'colorize-compilation-buffer)

正是我正在寻找的!不幸的是,在我的环境(cygwin-xemacs)中,它在 (buffer-read-only #<buffer "*compilation*">) 处崩溃,并显示“进程过滤器中的错误”,这似乎非常奇怪。有什么想法吗? - thoni56
这对我也非常有效。在(toggle-read-only)后,我还添加了(linum-mode 0)(第一次尝试为(line-number-mode 0),但它没有起作用,但我仍然留下来了,可能会对其他人有用),这使我更加高兴(一堆刚好换行的行现在已经不需要了)。 - lindes
我决定给我的 makefiles 输出添加一些颜色,然后在 Emacs 中遇到了这个问题。非常好的解决方案! - Maxim Egorushkin
11
对于现代版的Emacs,应该使用let-bind inhibit-read-onlyt,而不是调用toggle-read-only - user355252
有没有办法在添加新文本的同时使其工作?我已经在ack的结果上进行了测试,但挂钩似乎在内容填充缓冲区之前运行,因此内容没有被解释。 - Gauthier

22

我改进代码,这样它就不会像 M-x grep 命令那样污染环境,并且更加高效:

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

注意:我只在Emacs 24.x版本中测试了这段代码,可能无法在23.x或更低版本中运行... - gavenkoa
这个能正常工作,为什么(add-hook 'compilation-filter-hook 'ansi-color-for-comint-mode-on)不行呢? - Andrea Richiardi

7

截至2023年,最现代的方法似乎是使用xterm-color Emacs包。

  1. 执行带有xterm-color参数的M-x package-install命令。

  2. 将以下行添加到您的~/.emacs~/.emacs.d/init.el文件中:

(require 'xterm-color)
(setq compilation-environment '("TERM=xterm-256color"))
(defun my/advice-compilation-filter (f proc string)
  (funcall f proc (xterm-color-filter string)))
(advice-add 'compilation-filter :around #'my/advice-compilation-filter)

(见xterm-color文档。)
请注意,如果未正确安装xterm-color,将会提供错误消息。这是强烈建议的,因为在不完整的Emacs安装中,它将清楚地向您解释问题所在,而不是让您想知道为什么颜色无法正常工作。
但是,如果你真的不想被告知是否缺少xterm-color,则改用:
(when (require 'ansi-color nil t)
  (setq compilation-environment '("TERM=xterm-256color"))
  (defun my/advice-compilation-filter (f proc string)
    (funcall f proc (xterm-color-filter string)))
  (advice-add 'compilation-filter :around #'my/advice-compilation-filter))

这对于给我的pytest编译命令上色效果很好,但是它破坏了我的ag-mode - 它失去了交互性并变慢了。 - simno
@simno 我建议提交一个错误报告: https://github.com/atomontage/xterm-color/issues - vog
已经有针对 rg.elag.el 包的解决方案了:https://github.com/dajva/rg.el/issues/65。这两个包都依赖于匹配终端颜色转义,并且不提供忽略高亮的选项。我会为特定的 ag-mode 关闭 my/advice-compilation-filter,但我需要自己想一下。 - simno
这对我来说无法解决sbt在编译缓冲区中的颜色输出问题。转义代码仍然会被打印出来。 - Jack Viers

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接