Как отображать цветовые коды ANSI в emacs для любого режима?

У меня есть файл журнала, в котором для форматирования текста используются коды escape-цветов ANSI. Режим fundamental. Есть и другие ответы на вопросы, касающиеся этой проблемы, но я не уверен, как применить ее к этому или любому другому режиму. Я знаю, что решение каким-то образом связано с настройкой ansi-color.


person Avery    schedule 30.04.2014    source источник
comment
Я не знаю ответа на ваш вопрос, но это цветовые коды ANSI, а не цветовые коды ASCII.   -  person Chris    schedule 30.04.2014
comment
Спасибо! Я сделал изменение.   -  person Avery    schedule 30.04.2014
comment
github.com/atomontage/xterm-color   -  person HappyFace    schedule 16.05.2021


Ответы (4)


Вы можете использовать код ниже

(require 'ansi-color)
(defun display-ansi-colors ()
  (interactive)
  (ansi-color-apply-on-region (point-min) (point-max)))

Затем вы можете выполнить display-ansi-colors через M-x, с помощью привязки клавиш по вашему выбору или с помощью некоторого программного условия (возможно, ваши файлы журналов имеют расширение или имя, которое соответствует некоторому регулярному выражению)

Если вы хотите сделать это с буферами только для чтения (файлы журналов, результаты grep), вы можете использовать inhibit-read-only, поэтому функция будет такой:

(defun display-ansi-colors ()
  (interactive)
  (let ((inhibit-read-only t))
    (ansi-color-apply-on-region (point-min) (point-max))))
person juanleon    schedule 30.04.2014
comment
@Эвери, да. Кроме того, если кому-то еще интересно, как это сделать, добавление этого в ваш .emacs включит цветное отображение для всех .log файлов (выберите соответствующее расширение файла): (add-to-list 'auto-mode-alist '("\\.log\\'" . display-ansi-colors)) - person Avery; 01.05.2014
comment
Я пробую это для окрашивания результатов подтверждения (beyondgrep.com). Буфер результатов доступен только для чтения, и это решение не работает. - person Gauthier; 27.08.2014
comment
@juanleon: это ОТЛИЧНО! Теперь осталось только заставить работать ссылки из результатов поиска, но это уже другой вопрос. - person Gauthier; 28.08.2014
comment
Это странно. Я использовал аналогичное решение, чтобы применить это после некоторой компиляции (которая запускает тесты). при попытке использовать эту функцию для файла с [0m[32m[ OK ] [0mfetches the definintion for the correct view, помещенного либо в буфер с нуля, либо в новый файл с именем foobar.example, это не работает, был ли материал, который я копировал-вставлял, неправильным ansi-color? - person Mike H-R; 10.09.2015
comment
Есть ли способ сделать это (например, обработать escape-последовательности и отобразить цвета ansi) без изменения файла? - person deb0ch; 12.05.2016
comment
ansi-color-apply-on-region работает хорошо, но кажется слишком медленным (30 секунд для обработки области из 13 000 строк). - person Curt; 19.10.2017

Пользовательская функция:

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

Для буферов, использующих comint/compilation, используйте фильтр:

(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))
person gavenkoa    schedule 10.12.2015

Решения Гавенкоа и Хуанлеона сработали для меня, но не удовлетворяли, поскольку они изменяли содержимое файла, который я читал.

Чтобы раскрасить без изменения содержимого файла, загрузите tty-format.el и добавьте следующее в свой .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 основан на файле ansi-color.el, который поставляется только с последними версиями emacs.

person deb0ch    schedule 12.05.2016
comment
Это сработало для меня, однако, предупреждение - не пытайтесь делать это с большими файлами! Я только что попробовал это с файлом журнала размером 9 мегабайт, и он заблокировал emacs. - person adamc; 07.12.2016

На больших файлах производительность ansi-color-apply-on-region низкая. Вот решение, которое окрашивает текущую область и работает с буферами только для чтения.

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

Единственным недостатком является то, что ansi-color-apply-on-region удаляет символы управляющей последовательности ANSI из буфера, поэтому при сохранении они теряются. Интересно, есть ли способ скрыть символы вместо их удаления?

person John32ma    schedule 04.05.2020