终端emacs颜色仅适用于TERM = xterm-256color

时间:2011-10-01 01:05:11

标签: emacs

我发现除非我明确设置TERM = xterm-256color,否则终端emacs不会呈现正确的颜色。我使用gnome-terminal,根据我的理解,TERM应该设置为gnome-256color。同样,我倾向于使用tmux,它建议不要使用除screen-256color之外的任何TERM设置。不幸的是,这两个设置(在各自的上下文中gnome-terminaltmux)导致emacs颜色错误,而vim正确显示颜色。但是,如果我export TERM=xterm-256color,这些颜色在emacs中运行得很好。

任何人都可以解释发生了什么,或提供解决方案吗?

更新

以下是我正在处理的内容:

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-256colorscreen-256color)是安全的,我会继续使用。

6 个答案:

答案 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设置为TERMxterm-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的不同颜色。

我发现这是因为byobuTERM设置为screen-bce。然后将TERM设置为xterm(对我来说,在正常的gnome-terminal TERM=xterm中),在没有通过byobu/screen的情况下为我提供了相同的语法。

所以仍然不确定适当的解决方案是什么。

另见这篇文章: Emacs Python-mode syntax highlighting