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

Cha*_*les 32 emacs

我发现除非我明确设置TERM = xterm-256color,否则终端emacs不会呈现正确的颜色.我使用gnome-terminal,根据我的理解,TERM应该设置为gnome-256color.同样,我倾向于使用tmux,它建议不要使用除screen-256color之外的任何TERM设置.不幸的是,这两个设置(在它们各自的上下文中 - gnome-terminaltmux)导致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"))
Run Code Online (Sandbox Code Playgroud)

但这感觉真的非常错误.必须有一个合乎逻辑的解释...

PS

我对terminfo以及在$TERM彩色终端行为过程中扮演的确切角色知之甚少.如果总是使用它是安全的xterm-256color(即使$TERM"应该" gnome-256color或者screen-256color),我会继续使用它.

eve*_*_jr 24

也许我不理解某些东西,为什么不运行像这样的emacs:

TERM=xterm-256color emacs -nw
Run Code Online (Sandbox Code Playgroud)

这样Emacs就有自己的TERM设置.您也可以在shell脚本中创建别名或包装它.

  • 我宁愿修复实际问题而不是掩盖它.(虽然我没有向你投票...) (5认同)
  • 很公平.但是downvote是douchey.有人不知道他们可以为一个子shell分配一个特定的值到环境变量,这是不可想象的. (3认同)

gav*_*koa 19

终端是一种特殊类型的设备.当进程向终端发送特殊字节序列(称为控制序列)时,它会执行一些操作(如光标定位,更改颜色等).

您可以阅读ANSI终端代码以查找有关控制序列的更多详细信息.

但终端来自70年代,当硬件的能力有限时,终端无法提供有关其功能的信息(即它支持的序列).

$ TERM用于解决此问题 - 它允许程序知道要发送到终端的内容以完成工作.termcapterminfo是存储许多$ TERM名称的终端功能信息的数据库.如果$ TERM不在数据库中,则必须要求管理员添加它.

所有终端仿真器都从旧的硬件终端继承了这些限制.所以他们需要一个正确设置的$ TERM,而terminfo/termcap DB必须有这个终端的数据.当虚拟终端启动时,它会为您设置$ TERM变量(以及像bash这样的程序内部).如果$ TERM不在 terminfo/termcap中,您可以快速定义从$ TERMxterm-256color的别名(您可以在termcap文件中找到有关如何执行此操作的示例).


vha*_*lac 8

我并不熟悉emacs如何处理不同的终端.但是看看lisp/termemacs源码目录,我发现一个函数的存在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))
Run Code Online (Sandbox Code Playgroud)

在我的.emacs,这增加了支持screen-256color.您可以尝试通过将上述函数重命名为gnome来定义类似的函数terminal-init-gnome.

注意:如果您感兴趣,可以尝试从tty-run-terminal-initialization代码中跟踪调用.它首先使用tty-type函数获取终端类型,然后查看某些位置以加载相关的终端文件,然后尝试找到匹配的terminal-init-xxx函数,最后调用它.它可能会帮助您找出正确的名称gnome-terminal.


看起来除非您的TERM指示您的终端有256种颜色,否则emacs将只使用8.更改TERMgnome-256color允许颜色注册功能起作用.


毕竟,有一种方法可以作弊.当我运行时gnome-terminal,我的终端xterm默认设置为.例如TERM,可以重定向xterm到另一个终端,而不是更改变量gnome-256color.只需创建目录$(HOME)/.terminfo/x,然后运行ln -s /usr/share/terminfo/g/gnome-256color ~/.terminfo/x/xterm.我认为这比TERM手动设置更好.bashrc,因为它只将特定终端重定向到其他东西.控制台登录仍将保留TERMlinux,而不是xterm-256color.


Sam*_*son 7

此行为与EMACS用于确定终端背景是暗还是亮的逻辑有关.运行M-x list-colors-displayTERM设置为xterm-256colorscreen-256color,你会看到完全相同的颜色上市.正如您在评论中指出的那样,您观察到的颜色方案的差异是由于帧背景模式.要看到这一点,请TERM设置为screen-256color,比较颜色

emacs -Q -nw --eval "(setq frame-background-mode 'light)"
Run Code Online (Sandbox Code Playgroud)

emacs -Q -nw --eval "(setq frame-background-mode 'dark)"
Run Code Online (Sandbox Code Playgroud)

函数frame-set-background-mode(in frame.el)检查终端类型是否匹配"^\\(xterm\\|\\rxvt\\|dtterm\\|eterm\\)",否则无法推断出背景颜色.

在正在运行的会话中,您可以'light通过评估来更改颜色方案

(let ((frame-background-mode 'light)) (frame-set-background-mode nil))
Run Code Online (Sandbox Code Playgroud)


mnd*_*rix 5

将此添加到您的~/.emacs

(add-to-list 'term-file-aliases
    '("st-256color" . "xterm-256color"))
Run Code Online (Sandbox Code Playgroud)

它告诉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的,屏幕等,但没有为ST文件。我们需要帮助Emacs找到正确的初始化文件。该文件还称:

如果在术语,文件别名关联列表中的条目匹配TERM,Emacs使用相关的值到位的TERM

所以该关联列表处理未知端子推荐的方式。它可以工作,而不必手动覆盖TERM环境变量。