elisp:在回显区输出彩色信息

elisp: output colorful message in echo area

以下是我的 shell 命令的输出

Result [31mERROR[0m Invalid Transition "Backlog" from "In Progress", Available: Ready for Code Review, Stop Development

我正在尝试以这种方式在回显区输出它:

(setq result (shell-command-to-string (
            concat "j transition \"" state "\" " jira-ticket " --noedit")))
  (message "Result %s" result))

但它不打印红色 "ERROR"、

在 emacs 中可以吗?

如果不可能 - 如何自动去除这些字母?

系统信息:计算机:

n.b。我假设您正在 获得正确的 ansi 转义码,而转义字符只是在发布问题的过程中丢失了。


这是从 alter-text-property 代码派生的解决方案。

(defun copy-font-lock-face-to-face (from to &optional object)
  "Programmatically copy `font-lock-face' text-properties as `face' properties.

Optional third argument OBJECT specifies the string or buffer to operate on."
  ;; Derived from `alter-text-property'.
  (let ((begin from)
        end val)
    (while (setq val (get-text-property begin 'font-lock-face object)
                 end (text-property-not-all begin to 'font-lock-face val object))
      (put-text-property begin end 'face val object)
      (setq begin end))
    (if (< begin to)
        (put-text-property begin to 'face val object))))

(defun message-with-ansi-color (format-string &rest args)
  "A variant of `message' which supports ansi color escape codes."
  (require 'ansi-color)
  (let* ((text (ansi-color-apply (apply #'format format-string args))))
    (copy-font-lock-face-to-face 0 (length text) text)
    (message "%s" text)))

(message-with-ansi-color "%s" "Result \e[31mERROR\e[0m Invalid Transition")

原回答如下...


我曾预计 ansi-color-apply 会成功:

(require 'ansi-color)
(message "%s" (ansi-color-apply "Result \e[31mERROR\e[0m Invalid Transition \"Backlog\" from \"In Progress\", Available: Ready for Code Review, Stop Development"))

但看起来 message 处理 1 face 文本属性,而不是 font-lock-face 文本属性,并且 ansi-color-apply生成后者(如果您修改该函数的定义以将 font-lock-face 更改为 face 那么您将收到彩色消息)。

如果你想惹麻烦,你可以操纵生成的字符串来转换那些文本属性,根据我的阅读,这应该是一个完全安全的事情:

‘font-lock-face’
This property specifies a value for the ‘face’ property that Font Lock mode should apply to the underlying text.

我假设字体锁定代码中有一些东西可以为您做到这一点,但我不知道那是什么——希望更熟悉的人可以填补这个空白。

从字符串中去除转义码,您可以使用ansi-color-filter-apply代替ansi-color-apply


1 仅用于回声区输出;正如 lawlist 指出的那样,文本属性未应用于 *Messages* 缓冲区。