Терминальные цвета emacs работают только с TERM = xterm-256color
Я обнаружил, что терминал emacs не отображает правильные цвета, если я явно не установил TERM = xterm-256color. Я использую gnome-terminal и, насколько я понимаю, TERM должен быть установлен в gnome-256color. Аналогично, я очень часто использую tmux, который советует использовать любую настройку TERM, отличную от screen-256color. К сожалению, обе эти настройки (в их соответствующем контексте - gnome-terminal
или tmux
) приводят к тому, что emacs имеют неправильные цвета, тогда как vim отображает цвета правильно. Однако, если я export TERM=xterm-256color
, цвета работают нормально в emacs.
Может кто-нибудь объяснить, что происходит или предложить решение?
Update
Вот что я имею в виду:
![enter image description here]()
Я могу заставить цвета выглядеть корректно в терминале, добавив следующее к моему 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"))
Это действительно действительно, действительно неправильно. Для этого должно быть логическое объяснение...
P.S.
У меня очень мало знаний о terminfo и точной роли, которую $TERM
играет в процессе поведения цветового терминала. Если вы всегда можете использовать xterm-256color
(даже если $TERM
"должно быть gnome-256color
или screen-256color
), я пойду с этим.
Ответы
Ответ 1
Возможно, я что-то не понимаю, покупайте, почему бы вам не запустить emacs следующим образом:
TERM=xterm-256color emacs -nw
Таким образом, Emacs имеет собственную настройку TERM, которую вы знаете, работает. Вы также можете сделать псевдоним или обернуть его в shell- script.
Ответ 2
Терминалы - это особый тип устройства. Когда процесс отправляет на терминал специальные последовательности байтов (называемые управляющими последовательностями), он выполняет некоторые действия (например, позиционирование курсора, изменение цветов и т.д.).
Вы можете прочитать коды терминалов ANSI, чтобы найти более подробную информацию о контрольных последовательностях.
Но терминалы поступают с 70-х, когда аппаратное обеспечение ограничено по своим возможностям, а терминал не может предоставить информацию о своих возможностях (то есть, какие последовательности он поддерживает).
$TERM был использован для решения этой проблемы - он позволяет программам знать, что отправить на терминал, чтобы выполнить задание. termcap и terminfo - это базы данных, которые хранят информацию о возможностях терминала для многих имен $TERM. Если ваш $TERM не находится в db, вы должны попросить администратора добавить его.
Все эмуляторы терминала наследуют эти ограничения от старых аппаратных терминалов. Поэтому им нужно правильно установить $TERM, а в базе данных terminfo/termcap ДОЛЖЕН иметь данные для этого терминала. Когда виртуальный терминал запускается, он устанавливает для вас переменную $TERM (и внутри программ, таких как bash). Если $TERM не находится в terminfo/termcap, вы можете быстро определить псевдоним от $TERM до xterm-256color. > (примеры того, как это сделать, можно найти в файле termcap).
Ответ 3
Я не знаю, как 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
.
Ответ 4
Это поведение связано с использованием логики, используемой 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))
Ответ 5
В Ubuntu 10.04 я тоже заметил, что запуск emacs -nw
внутри byobu/tmux/screen
использовал разные цвета от emacs -nw
в обычном терминале gnome.
Я обнаружил, что это потому, что byobu
устанавливал TERM
на screen-bce
. Затем установка TERM
в xterm
(для меня в нормальном gnome-terminal
TERM=xterm
) я получил ту же подсветку синтаксиса, когда не работал через byobu/screen
.
Так что пока не уверен, что такое правильное решение.
Смотрите также эту запись:
подсветка синтаксиса Emacs Python