我发现除非我明确设置TERM = xterm-256color,否则终端emacs不会呈现正确的颜色。我使用gnome-terminal,根据我的理解,TERM应该设置为gnome-256color。同样,我倾向于使用tmux,它建议不要使用除screen-256color之外的任何TERM设置。不幸的是,这两个设置(在各自的上下文中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"))
但这确实非常非常错误。必须有一个合乎逻辑的解释......
我对terminfo以及$TERM
在颜色终端行为过程中所扮演的确切角色知之甚少。 如果始终使用 xterm-256color
(即使$TERM
“应该”gnome-256color
或screen-256color
)是安全的,我会继续使用。
答案 0 :(得分:22)
也许我不理解某些东西,为什么不运行这样的emacs:
TERM=xterm-256color emacs -nw
这样Emacs就有自己的TERM设置,你知道它可以工作。您也可以创建别名或将其包装在shell脚本中。
答案 1 :(得分:18)
终端是一种特殊类型的设备。当进程向终端发送特殊字节序列(称为控制序列)时,它会执行一些操作(如光标定位,更改颜色等)。
您可以阅读ANSI terminal codes以查找有关控制序列的更多详细信息。
但终端来自70年代,当硬件的功能有限时,终端无法提供有关其功能的信息(即它支持的序列)。
$ TERM 用于解决此问题 - 它允许程序知道要发送到终端的内容以完成工作。 termcap 和 terminfo 是存储许多 $ TERM 名称的终端功能信息的数据库。如果 $ TERM 不在数据库中,则必须要求管理员添加它。
所有终端仿真器都从旧的硬件终端继承了这些限制。因此,他们需要正确设置 $ TERM , terminfo / termcap 数据库必须有此终端的数据。当虚拟终端启动时,它会为您设置 $ TERM 变量(以及像bash这样的程序内部)。如果 $ TERM 不在 terminfo / termcap 中,您可以快速定义从 $ TERM 到 xterm-256color (您可以在 termcap 文件中找到有关如何执行此操作的示例。)
答案 2 :(得分:8)
我并不熟悉emacs如何准确处理不同的终端。但是查看emacs源代码中的lisp/term
目录,我发现函数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
的支持。您可以尝试通过将上述函数重命名为terminal-init-gnome
来为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
。
答案 3 :(得分:6)
此行为与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))
答案 4 :(得分:5)
将此添加到您的~/.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
以查看它认为可用的颜色。在terminal-specific initialization期间检测到正确的颜色数。它部分地说:
每种终端类型都有自己的Lisp库,Emacs在该类终端上运行时会加载它。
在我的机器上,特定于终端的初始化文件位于/usr/local/share/emacs/25.*/lisp/term
。它有xterm,rxvt,screen等文件,但没有st。我们需要帮助Emacs找到正确的初始化文件。文件进一步说:
如果在term-file-aliases关联列表中存在匹配TERM的条目,则Emacs使用关联值代替TERM
因此,关联列表是处理未知终端的推荐方法。无需您手动覆盖TERM环境变量即可运行。
答案 5 :(得分:3)
在ubuntu 10.04上,我也注意到在emacs -nw
内运行byobu/tmux/screen
在常规gnome-terminal中使用了来自emacs -nw
的不同颜色。
我发现这是因为byobu
将TERM
设置为screen-bce
。然后将TERM
设置为xterm
(对我来说,在正常的gnome-terminal
TERM=xterm
中),在没有通过byobu/screen
的情况下为我提供了相同的语法。
所以仍然不确定适当的解决方案是什么。