Терминальные цвета Emacs работают только с TERM=xterm-256color
Я обнаружил, что терминальный emacs не отображает правильные цвета, если я явно не установил TERM=xterm-256color. Я использую gnome-терминал, и, насколько я понимаю, TERM должен быть установлен в gnome-256color. Точно так же я часто использую tmux, что не подходит для любого параметра TERM, кроме screen-256color. К сожалению, оба эти параметра (в их соответствующих контекстах - gnome-terminal
или же tmux
) приводит к тому, что emacs имеет неправильные цвета, тогда как vim отображает цвета правильно. Однако если я export TERM=xterm-256color
, цвета хорошо работают в Emacs.
Может кто-нибудь объяснить, что происходит, или предложить решение?
Обновить
Вот с чем я имею дело:
Я могу заставить цвета выглядеть правильно в терминале, добавив следующее к моему init.el
:
(defun terminal-init-gnome ()
"Terminal initialization function for gnome-terminal."
;; This is a dirty hack that I accidentally stumbled across:
;; initializing "rxvt" first and _then_ "xterm" seems
;; to make the colors work... although I have no idea why.
(tty-run-terminal-initialization (selected-frame) "rxvt")
(tty-run-terminal-initialization (selected-frame) "xterm"))
Это действительно очень неправильно, хотя. Там должно быть логическое объяснение этого...
PS
У меня очень мало знаний о terminfo и точной роли $TERM
играет в процессе поведения цветного терминала. Если безопасно всегда использовать xterm-256color
(даже когда $TERM
"должно быть gnome-256color
или же screen-256color
), Я пойду с этим.
6 ответов
Может быть, я чего-то не понимаю, купите, почему бы вам не запустить emacs вот так:
TERM=xterm-256color emacs -nw
Таким образом, Emacs имеет собственную настройку TERM, которая, как вы знаете, работает. Вы также можете сделать псевдоним или обернуть его в shell-скрипт.
Терминалы - это особый тип устройства. Когда процесс отправляет на терминал специальные байтовые последовательности (называемые управляющими последовательностями), он выполняет некоторое действие (например, позиционирование курсора, изменение цвета и т. Д.).
Вы можете прочитать коды терминала ANSI, чтобы найти более подробную информацию о последовательностях управления.
Но терминалы приходят с 70-х годов, когда аппаратные средства были ограничены в своих возможностях, и терминал не может предоставить информацию о своих возможностях (т. Е. Какие последовательности он поддерживает).
$TERM был использован для решения этой проблемы - он позволяет программам знать, что отправить в терминал, чтобы выполнить работу. termcap и terminfo - это базы данных, в которых хранится информация о возможностях терминала для многих имен $TERM. Если ваш $TERM отсутствует в базе данных, вы должны попросить администратора добавить его.
Все эмуляторы терминала наследуют эти ограничения от старых аппаратных терминалов. Поэтому им нужен правильно установленный $TERM, и БД terminfo/termcap ДОЛЖНА иметь данные для этого терминала. Когда виртуальный терминал запускается, он устанавливает переменную $TERM для вас (и внутри таких программ, как bash). Если $TERM отсутствует в terminfo/termcap, вы можете быстро определить псевдоним от $TERM до xterm-256color (примеры того, как это сделать, можно найти в файле termcap).
Это поведение связано с логикой, которую EMACS использует, чтобы определить, является ли фон терминала темным или светлым. Бежать M-x list-colors-display
с TERM
установить либо xterm-256color
или же screen-256color
и вы увидите, что точно такие же цвета перечислены. Как вы указали в комментариях, различие в цветовых схемах, которое вы наблюдали, связано с режимом фона рамки. Чтобы увидеть это, с вашим TERM
установлен в screen-256color
, сравните цвета в
emacs -Q -nw --eval "(setq frame-background-mode 'light)"
а также
emacs -Q -nw --eval "(setq frame-background-mode 'dark)"
Функция frame-set-background-mode
(в frame.el
) проверяет соответствие типа терминала "^\\(xterm\\|\\rxvt\\|dtterm\\|eterm\\)"
если это не может вывести цвет фона иначе.
В течение сеанса вы можете изменить цветовую схему на 'light
оценивая
(let ((frame-background-mode 'light)) (frame-set-background-mode nil))
Я не очень знаком с тем, как emacs точно обрабатывает различные терминалы. Но, глядя на lisp/term
каталог в источниках Emacs, я обнаружил, что существование функции terminal-init-xxx
позволяет добавить поддержку для разных терминалов. Например, у меня есть:
(defun terminal-init-screen ()
"Terminal initialization function for screen."
;; Use the xterm color initialization code.
(xterm-register-default-colors)
(tty-set-up-initial-frame-faces))
в моем .emacs
, который добавляет поддержку screen-256color
, Вы можете попробовать определить аналогичную функцию для gnome, переименовав вышеупомянутую функцию в terminal-init-gnome
,
ПРИМЕЧАНИЕ. Если вы заинтересованы, вы можете попробовать отследить tty-run-terminal-initialization
код. Сначала он получает тип терминала, используя tty-type
функция, затем просматривает определенные места для загрузки соответствующего файла терминала, а затем пытается найти соответствующий terminal-init-xxx
функция, и, наконец, вызывает его. Это может помочь вам определить правильное название gnome-terminal
,
Похоже, если ваш TERM не указывает, что ваш терминал имеет 256 цветов, emacs будет использовать только 8. Изменение TERM
в gnome-256color
позволил функциям регистрации цвета работать.
В конце концов, есть способ обмануть. Когда я бегу gnome-terminal
мой терминал настроен на xterm
по умолчанию. Вместо смены TERM
переменная, можно перенаправить xterm
на другой терминал, скажем, gnome-256color
, Просто создайте каталог $(HOME)/.terminfo/x
затем беги ln -s /usr/share/terminfo/g/gnome-256color ~/.terminfo/x/xterm
, Я думаю, что это лучше, чем установка TERM
вручную в .bashrc
, потому что он только перенаправляет определенный терминал на что-то другое. Вход в консоль все равно уйдет TERM
как linux
, и не xterm-256color
,
Добавьте это к вашему ~/.emacs
:
(add-to-list 'term-file-aliases
'("st-256color" . "xterm-256color"))
Это говорит Emacs, что если он видит TERM=st-256color
тогда он должен инициализировать терминал, как если бы он видел TERM=xterm-256color
,
Более длинный ответ:
Emacs показывает странные цвета, потому что думает, что ваш терминал может поддерживать только 8 цветов. В Emacs беги M-x list-colors-display
чтобы увидеть цвета, которые он считает доступными. Правильное количество цветов определяется во время специфической для терминала инициализации. Это говорит, частично:
Каждый тип терминала может иметь свою собственную библиотеку Lisp, которую Emacs загружает при запуске на этом типе терминала.
На моей машине файлы инициализации терминала находятся в /usr/local/share/emacs/25.*/lisp/term
, В нем есть файлы для xterm, rxvt, screen и т. Д., Но ничего для st. Нам нужно помочь Emacs найти правильный файл инициализации. Далее в документации сказано:
Если в списке ассоциаций term-file-aliases есть запись, соответствующая TERM, Emacs использует соответствующее значение вместо TERM
Таким образом, этот список ассоциаций является рекомендуемым способом обработки неизвестных терминалов. Это работает без необходимости вручную переопределять переменную окружения TERM.
На Ubuntu 10.04 я тоже заметил, что работает emacs -nw
внутри byobu/tmux/screen
использовал разные цвета из emacs -nw
в обычном гном-терминале.
Я обнаружил, что это потому, что byobu
устанавливал TERM
в screen-bce
, Затем настройка TERM
в xterm
(для меня в нормальном gnome-terminal
TERM=xterm
) дал мне ту же подсветку синтаксиса, когда не работает через byobu/screen
,
Так что до сих пор не уверен, что является правильным решением.
Смотрите также этот пост: Подсветка синтаксиса в Emacs Python-режиме