终端 emacs 颜色仅适用于 TERM=xterm-256color
我发现终端 emacs 不会呈现正确的颜色,除非我明确设置 TERM=xterm-256color。我使用 gnome-terminal,据我了解,TERM 应设置为 gnome-256color。同样,我倾向于经常使用 tmux,这建议不要使用 screen-256color 之外的任何 TERM 设置。不幸的是,这两个设置(在各自的上下文中 - gnome-terminal 或 tmux)都会导致 emacs 出现错误的颜色,而 vim 会正确显示颜色。但是,如果我导出 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
),我会同意的。
I've found that terminal emacs does not render the correct colors unless I explicitly set TERM=xterm-256color. I use gnome-terminal, and from what I understand, TERM should be set to gnome-256color. Similarly, I tend to use tmux a lot, which advises against any TERM setting other than screen-256color. Unfortunately, both of those settings (within their respective context - gnome-terminal
or tmux
) result in emacs having wrong colors, whereas vim displays colors correctly. However, if I export TERM=xterm-256color
, the colors work just fine in emacs.
Can anyone explain what's going on, or offer a solution?
Update
Here's what I'm dealing with:
I can get the colors to look correct in the terminal by adding the following to my 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"))
This feels really, really wrong though. There has to be a logical explanation for this...
P.S.
I have very little knowledge of terminfo and the precise role that $TERM
plays in the process of color terminal behavior. If it's safe to always use xterm-256color
(even when $TERM
"should" be gnome-256color
or screen-256color
), I'll go with that.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(6)
也许我不明白一些事情,为什么你不这样运行 emacs:
这样 Emacs 就有了自己的 TERM 设置,你知道它可以工作。您还可以创建别名或将其包装在 shell 脚本中。
Maybe I'm not understanding something, buy why don't you run emacs like this:
This way Emacs has its own TERM setting that you know works. You can also make an alias or wrap this in shell-script.
终端是一种特殊类型的设备。当进程向终端发送特殊字节序列(称为控制序列)时,它会执行某些操作(如光标定位、更改颜色等)。
您可以阅读ANSI 终端代码以查找有关控制序列的更多详细信息。
但终端来自 70 年代,当时硬件的功能有限,终端无法提供有关其功能的信息(即它支持哪些序列)。
$TERM 用于解决此问题 - 它允许程序知道要发送到终端的内容以完成工作。 termcap 和 terminfo 是存储有关许多 $TERM 名称的终端功能信息的数据库。如果您的 $TERM 不在数据库中,您必须要求管理员添加它。
所有终端仿真器都继承了旧硬件终端的这些限制。因此,他们需要正确设置$TERM,并且terminfo/termcap数据库必须具有该终端的数据。当虚拟终端启动时,它会为您设置 $TERM 变量(以及 bash 等程序内部)。如果 $TERM 不在 terminfo/termcap 中,您可以快速定义从 $TERM 到 xterm-256color 的别名> (您可以在 termcap 文件中找到有关如何执行此操作的示例)。
Terminals are a special type of device. When a process sends special byte sequences (called control sequences) to the terminal, it performs some action (like cursor positioning, change colors, etc).
You can read the ANSI terminal codes to find more detail about control sequences.
But terminals come from 70s, when hardware was limited in its capabilities, and a terminal cannot provide info about its capabilities (ie. which sequences it supports).
$TERM was used to resolve this issue - it allows programs to know what to send to the terminal to get the job done. termcap and terminfo are databases that store info about terminal capabilities for many $TERM names. If your $TERM is not in the db, you must ask an administrator to add it.
All terminal emulators inherit these limitations from old hardware terminals. So they need a properly set $TERM, and the terminfo/termcap DB MUST have data for this terminal. When a virtual terminal starts it sets the $TERM variable for you (and inside programs like bash). If $TERM is not in the terminfo/termcap you can quickly define an alias from $TERM to xterm-256color (you can find examples in the termcap file on how to do that).
此行为与 EMACS 用于确定终端背景是深色还是浅色的逻辑有关。运行
Mx list-colors-display
并将TERM
设置为xterm-256color
或screen-256color
即可您会看到列出了完全相同的颜色。正如您在评论中指出的,您观察到的配色方案的差异是由于框架背景模式造成的。 中的颜色要看到这一点,请将
TERM
设置为screen-256color
,比较和函数
frame-set-background-mode
(在frame.el
) 检查终端类型是否匹配"^\\(xterm\\|\\rxvt\\|dtterm\\|eterm\\)"
如果它不能推断背景颜色,否则。在正在运行的会话中,您可以通过评估将颜色方案更改为
'light
This behavior has to do with the logic EMACS uses to determine whether the terminal background is dark or light. Run
M-x list-colors-display
withTERM
set to eitherxterm-256color
orscreen-256color
and you'll see that the exact same colors are listed. As you pointed out in the comments, the difference in color schemes that you've observed is due to the frame background mode. To see this, with yourTERM
set toscreen-256color
, compare the colors inand
The function
frame-set-background-mode
(inframe.el
) checks to see whether the terminal type matches"^\\(xterm\\|\\rxvt\\|dtterm\\|eterm\\)"
if it can't deduce the background color otherwise.Within a running session, you can change the color scheme to
'light
by evaluating我不太熟悉 emacs 如何准确处理不同的终端。但是查看 emacs 源代码中的
lisp/term
目录,我发现存在一个函数terminal-init-xxx
允许您添加对不同终端的支持。例如,我的
.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。可以将
xterm
重定向到另一个终端,例如gnome-256color
,而不是更改TERM
变量。只需创建目录$(HOME)/.terminfo/x
,然后运行 ln -s /usr/share/terminfo/g/gnome-256color ~/.terminfo/x/xterm< /代码>。我认为这比在 .bashrc 中手动设置 TERM 更好,因为它仅将特定终端重定向到其他终端。控制台登录仍会将
TERM
保留为linux
,而不是xterm-256color
。I am not that familiar with how emacs handles different terminals exactly. But looking at
lisp/term
directory in emacs sources, I found out that the existence of a functionterminal-init-xxx
allows you to add support for different terminals. For example, I've got:in my
.emacs
, which adds support forscreen-256color
. You may try defining a similar function for gnome by renaming the above function toterminal-init-gnome
.NOTE: If you are interested, you can try to track down the calls from
tty-run-terminal-initialization
code. It first gets the terminal type usingtty-type
function, then looks at certain locations to load a relevant terminal file, then tries to locate the matchingterminal-init-xxx
function, and finally calls it. It may help you figure out the correct name forgnome-terminal
.It looks like unless your TERM indicates that your terminal has 256 colors, emacs will only use 8. Changing
TERM
tognome-256color
allowed the color registration functions to work.There is a way to cheat, after all. When I run
gnome-terminal
, my terminal is set toxterm
by default. Instead of changingTERM
variable, it is possible to redirectxterm
to another terminal, say,gnome-256color
. Simply create the directory$(HOME)/.terminfo/x
, then runln -s /usr/share/terminfo/g/gnome-256color ~/.terminfo/x/xterm
. I think this is better than settingTERM
manually in.bashrc
, because it only redirects a particular terminal to something else. A console login would still leaveTERM
aslinux
, and notxterm-256color
.将其添加到您的
~/.emacs
中:它告诉 emacs,如果它看到
TERM=st-256color
那么它应该初始化终端,就像它看到TERM 一样=xterm-256color
。更长的答案:
Emacs 显示奇怪的颜色,因为它认为您的终端只能支持 8 种颜色。在 Emacs 中,运行
Mx list-colors-display
以查看它认为可用的颜色。在特定于终端的初始化过程中检测到正确的颜色数量< /a>.它部分地说:在我的机器上,特定于终端的初始化文件位于
/usr/local/share/emacs/25.*/lisp/term
中。它有 xterm、rxvt、screen 等的文件,但没有 st 的文件。我们需要帮助 Emacs 找到正确的初始化文件。该文档进一步指出:因此关联列表是处理未知终端的推荐方法。它无需您手动覆盖 TERM 环境变量即可工作。
Add this to your
~/.emacs
:It tells emacs that if it sees
TERM=st-256color
then it should initialize the terminal as if it had seenTERM=xterm-256color
.Longer answer:
Emacs is showing strange colors because it thinks your terminal can only support 8 colors. In Emacs, run
M-x list-colors-display
to see the colors it thinks are available. The correct number of colors is detected during terminal-specific initialization. It says, in part:On my machine, the terminal-specific initialization files are in
/usr/local/share/emacs/25.*/lisp/term
. It has files for xterm, rxvt, screen, etc. but nothing for st. We need to help Emacs find the right initialization file. The documentation further says:So that association list is a recommended way to handle unknown terminals. It works without you having to manually override the TERM environment variable.
在 ubuntu 10.04 上,我也注意到在
byobu/tmux/screen
中运行emacs -nw
使用了与常规中的emacs -nw
不同的颜色gnome 终端。我发现这是因为
byobu
将TERM
设置为screen-bce
。然后将TERM
设置为xterm
(对我来说,在正常的gnome-terminal
TERM=xterm
中)给了我不通过byobu/screen
运行时,相同的语法会突出显示。所以仍然不确定正确的解决方案是什么。
另请参阅这篇文章:
Emacs Python 模式语法突出显示
On ubuntu 10.04 I too had noticed that running
emacs -nw
insidebyobu/tmux/screen
was using different colours fromemacs -nw
in the regular gnome-terminal.I found that this is because
byobu
was settingTERM
toscreen-bce
. Then settingTERM
toxterm
(for me, in the normalgnome-terminal
TERM=xterm
) gave me the same syntax highlighting when not running throughbyobu/screen
.So still not sure what the proper solution is.
See also this post:
Emacs Python-mode syntax highlighting