即使使用 export NCURSES_NO_UTF8_ACS=1,ACS 字符也无法在 putty 中工作

ACS characters not working in putty even with export NCURSES_NO_UTF8_ACS=1

我正在用 C 自己开发一个 ncurses 应用程序。问题是 putty 将 ACS_VLINE 等替代字符集字符显示为字母。我的语言环境是

LANG=en_US.UTF-8

我已经设置了

export NCURSES_NO_UTF8_ACS=1

我也将putty设置为UTF-8并尝试了不同的字体。这些字符在实际机器上的 tty 上显示正常,所以我认为问题出在腻子上。我还尝试链接 ncursesw 而不是 ncurses。

它是事物的组合。 PuTTY 的推荐 TERM"putty", but due to inertia, most people use "xterm". The line-drawing support in the xterm terminal description is different from PuTTY's assumptions because xterm supports luit,它对备用字符集的管理方式有一些限制(请参阅 Debian 错误报告 #254316: ncurses-base:屏幕处理寄存器 sgr0 的解决方法不太正确)。

如果您使用infocmp进行比较,您可能会看到这些处理备用字符集的行:

    acsc: '``aaffggiijjkkllmmnnooppqqrrssttuuvvwwxxyyzz{{||}}~~', '``aaffggjjkkllmmnnooppqqrrssttuuvvwwxxyyzz{{||}}~~'.
    enacs: NULL, '\E(B\E)0'.
    rmacs: '\E(B', '^O'.
    smacs: '\E(0', '^N'.

VT100s可以有两个字符集"designated",简称G0和G1:

  • "xterm"画线是通过改变ASCII和画线字符之间G0的指定来实现的,
  • 画线"putty"的工作原理是在G0中指定ASCII,在G1中指定画线,并通过shift-in/shift-out控制字符在两者之间切换。

虽然两者都兼容 VT100,但 xterm 方案不适用于 PuTTY。由于与 luit 的搭配,xterm 的正常终端描述不会改变(除非证明可以修改 luit 以解决其用户的问题),因此解决方法PuTTY 用户需要:

  • 使用建议的不同终端描述,例如 TERM=putty。 PuTTY 的设置对话框允许您设置环境变量以传递给远程机器。

    由于 "size"(在我的本地机器上是 6.8Mb),有些系统没有安装完整的 ncurses 终端数据库。此外,TERM 可能不在允许的 ssh 环境变量列表中。

  • 您可以使用 ncurses 的 tic 编译您自己的 terminfo 条目,例如,

    cat >foo <<"EOF" xterm|my terminfo entry, enacs=\E(B\E)0, rmacs=^O, smacs=^N, use=xterm-new, EOF tic foo

  • 使用 GNU 屏幕。它有自己的修复,恰好弥补了 PuTTY 的问题。

进一步阅读

我想做一些补充。我遇到了同样的问题:许多基于 ncurses 的工具,如来自 Linux kenrel 来源的 dialogmenuconfignconfig,甚至 mc 在使用 ncurses 构建时也被破坏了(尽管 mc 是在许多操作系统上使用俚语构建的并且不受影响)。

事情是这样的

ncurses 使用来自 terminfo 的 smacs 记录切换到 "alternative charset",然后使用 acsc 绘制框。它发送 a,这是替代字符集 (ACS) 中的方框绘图字符。 这是VT100显卡。

现在一些终端仿真器在 UTF-8 中不支持 ACS,因为应用程序能够发送真实的方框绘图代码点。

terminfo 中有非官方功能 U8(大写 U!)告诉 ncurses:"Instead of ACS use real box-drawing codepoints."

我有这个能力 infocmp -x xterm-utf 和 putty,但不适合 xterm

正如您在 ncurses(3) (https://invisible-island.net/ncurses/man/ncurses.3x.html) 中所读到的,ncurses 知道 Linux 控制台和 GNU 屏幕(以及 tmux,它也使用 screen as TERM) 并且总是表现得像设置了 U8 一样。

其他不支持UTF ACS的终端,可以设置NCURSES_NO_UTF8_ACS.

不幸的是,ncurses 不知道 putty。

还有 luit 可以将 ACS 转换为 Unicode 点。

所以,这是我们可以对 运行 ncurses + putty 在 UTF-8 中做的事情:

  • 使用具有 U8#1 能力的终端。这是为 putty 设置的(顺便说一句,我建议改用 putty-256color)。您可以使用 U8#1colors#256 创建您自己的条目并使用 tic -x 编译它。请注意,鼠标可能无法在不以 xterm 开头的终端上工作(请参阅 mouseinterval(3),BUGS 部分)。这就是我不使用 putty 终端的原因。我建议复制 xterm-utf8,添加 colors#256,编译并使用它:它与 putty、mouse 和 utf8 完美配合。

  • 您可以在个人资料中设置NCURSES_NO_UTF8_ACS

  • 您可以 运行 screentmux:它会将 TERM 设置为 screen 并修复 ncurses

  • 您可以 运行 luit:它会为您完成所有转换。

  • 从 putty 0.71 开始,您可以要求 putty 支持 ACS 绘图,即使是 UTF-8 格式