粗体字体 (ANSI: CSI 1 m
) 的效果似乎取决于终端仿真器。例如,在不同的终端模拟器上运行以下脚本
#!/bin/sh
echo "TERM = $TERM"
for mode in 0 2 1 '1;2'; do
printf '\033[%s;38;5;%dm\033[48;5;%dm%s\033[0m\n' "$mode" 0 15 "testing ($mode)"
done
给出以下输出
在测试的终端仿真器中,只能xterm
正确呈现粗体文本(模式=1)。其他终端仿真器似乎为粗体字体选择了更亮的颜色(通常也将其与粗体字体结合使用)。奇怪的是,st
当给定参数时,会产生正确着色的粗体文本1;2
,对应于bold;faint
.
认为也许这些终端仿真器期望粗体字体的不同控制序列,我检查了terminfo
,但发现一致
$ for term in xterm-256color st-256color rxvt-unicode-256color tmux-256color; do printf "%-24s" "$term"; TERM=$term tput bold | cat -v; echo; done
xterm-256color ^[[1m
st-256color ^[[1m
rxvt-unicode-256color ^[[1m
tmux-256color ^[[1m
这就引出了一个问题,哪些终端仿真器参数控制粗体字体的效果?如何防止转向更亮的颜色?这可以通过Xresources
或terminfo
定制来解决吗?(顺便说一句,是否有对应的参数vim
?它表现出类似的行为,不一定对应于运行它的终端仿真器的行为。)
CSI 1 m
正如您所指出的,只有一个转义序列会导致粗体字。正因为如此,实际上没有一种方法可以从应用程序(例如
vim
's)端更改行为,甚至无法通过诸如 terminfo 定义之类的配置。(我将在稍后完善此声明。)实现所需行为的方法是相应地配置终端仿真器。您正在寻找
xterm +pc
orurxvt +is
,或者他们相应的 Xresource 设置,如他们的手册中所示。不知道st
有没有这样的选择。我真的不认为
tmux
有这样的选择,因为它无法控制图形模拟器的实际行为方式。从理论上讲,它可能会尝试我稍后会提到的技巧,但我真的不认为它会这样做。提供一些历史背景:
按照标准,
CSI 1 m
意思是“大胆或加大力度”,所以严格来说,这两种行为都是正确的。从历史上看,图形终端仿真器同时启用了两者。这对于传统的 8/16 调色板来说是有意义的。与后来广泛使用的扩展 256 色调色板相比,现在大多数图形终端仿真器都支持的 RGB 完全没有。非常糟糕的是,没有转义序列可以可靠地生成粗体字体的前 8 种调色板颜色(实际上是用户最喜欢的 8 种颜色)。
看到这一点,最近几个终端仿真器转向不使颜色变亮,只使字体更粗(你正在寻找的东西)。我认为您提到的任何终端都没有更改默认设置,但我的知识可能很容易过时。
我提到可能有一种方法可以改变应用程序的行为。
有两个转义序列来请求前 8 种调色板颜色中的一种:传统的 (
CSI 30..37 m
) 和具有此类索引的 256 色 (CSI 38;5;0..7 m
)。如果与粗体/明亮属性结合使用,某些终端仿真器的某些版本可能对两者表现不同CSI 1 m
。例如,如果我没记错的话,某些版本xterm
只有在使用传统颜色转义时才会更改为更亮的颜色,但如果使用 256 色转义则不会。如果我没记错的话,xterm 后来改变了这种行为。无论如何,如果您碰巧使用这样的终端仿真器,解决方法可能是
setaf
在您的 terminfo 中进行修改以发出前 8 种颜色的 256 色序列,而不是旧代码。这不会改变
CSI 1 m
默认前景色的粗体/明亮行为,我绝对建议配置终端仿真器而不是使用这个 terminfo hack。如果您对更多多汁/毛茸茸的细节感兴趣,您可能对这些链接以及从那里链接的其他页面感兴趣: https://bugzilla.gnome.org/show_bug.cgi?id
=
762247 https:// bugzilla.gnome.org/show_bug.cgi?id=791596
正如egmont 指出
xterm
的那样,可以urxvt
通过运行xterm +pc
or来抑制粗体行为urxvt +is
。对于那些想知道的人st
,它的粗体行为是xdrawglyphfontspecs()
在xc中实现的,BETWEEN()
顾名思义,在哪里,替换仅适用于传统 8/16 调色板的前 8 种颜色,这与 egmont 的说法一致。标头st.h定义
ATTR_BOLD_FAINT
为 and 的按位ATTR_BOLD = 1<<0
或ATTR_FAINT = 1<<1
。因此,颜色重新映射仅在设置了粗体属性但未设置模糊属性时发生。无论是否有意,为粗体 (CSI 1 m
) 和微弱 (CSI 2 m
) 属性传递转义序列都会产生粗体字体,如问题所示,不满足此条件。原则上,可以通过将st.info中粗体属性的转义序列从其规范值 (
\E[1m
) 更改为\E[1;2m
,或者通过设置设置粗体属性时的属性(通过将st.c中的 修改为case 1
)。尽管这些更改中的任何一个都产生了所需的结果(使用问题中的脚本进行了测试),但都不推荐使用任何一个(出于多种原因)。tsetattr()
term.c.attr.mode |= (ATTR_BOLD | ATTR_FAINT)
一种更直接(也是首选)的方法是简单地删除 中的粗体条件条件
xdrawglyphfontspecs()
,并且事实证明,已经有一个补丁可以做到这一点。