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

发布于 2024-12-07 22:33:58 字数 1161 浏览 1 评论 0原文

我发现终端 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-256colorscreen -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:

enter image description here

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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(6

咽泪装欢 2024-12-14 22:33:58

也许我不明白一些事情,为什么你不这样运行 emacs:

TERM=xterm-256color emacs -nw

这样 Emacs 就有了自己的 TERM 设置,你知道它可以工作。您还可以创建别名或将其包装在 shell 脚本中。

Maybe I'm not understanding something, buy why don't you run emacs like this:

TERM=xterm-256color emacs -nw

This way Emacs has its own TERM setting that you know works. You can also make an alias or wrap this in shell-script.

骄兵必败 2024-12-14 22:33:58

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

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

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

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

所有终端仿真器都继承了旧硬件终端的这些限制。因此,他们需要正确设置$TERM,并且terminfo/termcap数据库必须具有该终端的数据。当虚拟终端启动时,它会为您设置 $TERM 变量(以及 bash 等程序内部)。如果 $TERM 不在 terminfo/termcap 中,您可以快速定义从 $TERMxterm-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).

不甘平庸 2024-12-14 22:33:58

此行为与 EMACS 用于确定终端背景是深色还是浅色的逻辑有关。运行 Mx list-colors-display 并将 TERM 设置为 xterm-256colorscreen-256color 即可您会看到列出了完全相同的颜色。正如您在评论中指出的,您观察到的配色方案的差异是由于框架背景模式造成的。 中的颜色

emacs -Q -nw --eval "(setq frame-background-mode 'light)"

要看到这一点,请将 TERM 设置为 screen-256color,比较和

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))

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 with TERM set to either xterm-256color or screen-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 your TERM set to screen-256color, compare the colors in

emacs -Q -nw --eval "(setq frame-background-mode 'light)"

and

emacs -Q -nw --eval "(setq frame-background-mode 'dark)"

The function frame-set-background-mode (in frame.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

(let ((frame-background-mode 'light)) (frame-set-background-mode nil))
喜爱纠缠 2024-12-14 22:33:58

我不太熟悉 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。可以将 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 function terminal-init-xxx allows you to add support for different terminals. For example, I've got:

(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))

in my .emacs, which adds support for screen-256color. You may try defining a similar function for gnome by renaming the above function to terminal-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 using tty-type function, then looks at certain locations to load a relevant terminal file, then tries to locate the matching terminal-init-xxx function, and finally calls it. It may help you figure out the correct name for gnome-terminal.


It looks like unless your TERM indicates that your terminal has 256 colors, emacs will only use 8. Changing TERM to gnome-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 to xterm by default. Instead of changing TERM variable, it is possible to redirect xterm to another terminal, say, gnome-256color. Simply create the directory $(HOME)/.terminfo/x, then run ln -s /usr/share/terminfo/g/gnome-256color ~/.terminfo/x/xterm. I think this is better than setting TERM manually in .bashrc, because it only redirects a particular terminal to something else. A console login would still leave TERM as linux, and not xterm-256color.

明天过后 2024-12-14 22:33:58

将其添加到您的 ~/.emacs 中:

(add-to-list 'term-file-aliases
    '("st-256color" . "xterm-256color"))

它告诉 emacs,如果它看到 TERM=st-256color 那么它应该初始化终端,就像它看到 TERM 一样=xterm-256color


更长的答案:

Emacs 显示奇怪的颜色,因为它认为您的终端只能支持 8 种颜色。在 Emacs 中,运行 Mx list-colors-display 以查看它认为可用的颜色。在特定于终端的初始化过程中检测到正确的颜色数量< /a>.它部分地说:

每种终端类型都可以有自己的 Lisp 库,Emacs 在该类型的终端上运行时会加载该库。

在我的机器上,特定于终端的初始化文件位于 /usr/local/share/emacs/25.*/lisp/term 中。它有 xterm、rxvt、screen 等的文件,但没有 st 的文件。我们需要帮助 Emacs 找到正确的初始化文件。该文档进一步指出:

如果 term-file-aliases 关联列表中存在与 TERM 匹配的条目,Emacs 将使用关联值代替 TERM

因此关联列表是处理未知终端的推荐方法。它无需您手动覆盖 TERM 环境变量即可工作。

Add this to your ~/.emacs:

(add-to-list 'term-file-aliases
    '("st-256color" . "xterm-256color"))

It tells emacs that if it sees TERM=st-256color then it should initialize the terminal as if it had seen TERM=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:

Each terminal type can have its own Lisp library that Emacs loads when run on that type of terminal.

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:

If there is an entry matching TERM in the term-file-aliases association list, Emacs uses the associated value in place of TERM

So that association list is a recommended way to handle unknown terminals. It works without you having to manually override the TERM environment variable.

掌心的温暖 2024-12-14 22:33:58

在 ubuntu 10.04 上,我也注意到在 byobu/tmux/screen 中运行 emacs -nw 使用了与常规中的 emacs -nw 不同的颜色gnome 终端。

我发现这是因为 byobuTERM 设置为 screen-bce。然后将 TERM 设置为 xterm (对我来说,在正常的 gnome-terminal TERM=xterm 中)给了我不通过 byobu/screen 运行时,相同的语法会突出显示。

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

另请参阅这篇文章:
Emacs Python 模式语法突出显示

On ubuntu 10.04 I too had noticed that running emacs -nw inside byobu/tmux/screen was using different colours from emacs -nw in the regular gnome-terminal.

I found that this is because byobu was setting TERM to screen-bce. Then setting TERM to xterm (for me, in the normal gnome-terminal TERM=xterm) gave me the same syntax highlighting when not running through byobu/screen.

So still not sure what the proper solution is.

See also this post:
Emacs Python-mode syntax highlighting

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文