1

在urxvt中运行ncurses程序会挤压字符串中的重复字符。例如,我期望但我得到. "--------""-"

我写了一个简短的程序来重现这个问题。代码如下。

我已经验证了使用xterm而不是urxvt时输出是正确的。

这是我第一次使用 ncurses,但是,示例程序非常简单。因此,我认为问题不大可能在于我如何使用 ncurses。xterm 给出预期结果的事实也支持这一点。

我在 Arch Linux 上使用 urxvt。我也在下面提供相关配置。我安装了 vanilla xterm,没有任何额外的配置。两者都运行了 zsh。

示例程序 (C)

#include <curses.h>

int main(){
  initscr();
  printw("------\n");        // (1) 6 '-' chars          urxvt: "------"   xterm: "------"
  printw("-------\n");       // (2) 7 '-' chars          urxvt: "-"        xterm: "-------"
  printw("--------\n");      // (3) 8 '-' chars          urxvt: "-"        xterm: "--------"
  printw("0--------0\n");    // (4) 8 '-' between '0'    urxvt: "0-0"      xterm: "0--------0"
  printw("xxxxxxxx\n");      // (5) Replacing '-' with 'x' does not make a difference.
  printw("---- ----\n");     // (6) Two '-' sequences separated by ' ' display correctly.
  printw("12345678\n");      // (7) Strings with different characters display correctly.
  for(int i=0; i<8; i++) addch('-');    // (8) 8 '-' chars      urxvt: "-"   xterm: "--------" 
  addch('\n');
  for(char c='0'; c<'8'; c++) addch(c); // (9) Both display correctly
  addch('\n');
  refresh();
  getch();
  endwin();
  return 0;
}

xterm 输出(正确)

------
-------
--------
0--------0
xxxxxxxx
---- ----
12345678
--------
01234567

urxvt 输出(不正确)

------
-
-
0-0
x
---- ----
12345678
-
01234567

观察

  • 最多可正确显示 6 个重复字符。
  • 7 个或更多重复字符显示为单个字符。
  • 如果字符不重复,则不会出现此问题,因此字符串本身的长度不是问题。
  • 重复子串的位置并不重要。'0'在 (7) 中,被压缩的子串被每端的字符夹在中间。
    • 问题不是由于特定的字符。它发生'-'在 以及'x'
  • 使用printwaddch函数观察到该问题。相关的联机帮助页声明这些函数会移动光标,因此不需要显式移动光标。显然是这样,否则问题将不仅限于重复字符,xterm 也会发生。

urxvt 配置

  • rxvt-unicode v9.22
  • $TERMxterm-256color
4

1 回答 1

0

urxvt 不是 xterm,所以$TERM应该是rxvt-unicode而不是xterm-256color

直到我输入问题的最后,当我添加 urxvt 配置时,我才弄清楚这一点。我想考虑将哪些信息放入 SO 问题中可能会导致解决您自己的问题。与其删除所有内容,我想我还不如发布,也许它对那里的其他人有用。

问题是,很久很久以前,当我第一次尝试 Arch Linux 和 urxvt 时,我添加了 env 设置。我必须承认,我并没有真正花太多时间思考它。我记得当时我所关心的只是正确显示 unicode 字符、字体和颜色(除了漂亮的配色方案)。设置$TERMxterm-256color当时似乎工作,并且在使用该系统的所有时间里,它似乎继续工作,直到今天。当然,这里和那里都有小故障,也许它们就是这个的结果。话又说回来,也许他们是由于其他原因。我不得不说我对这个问题原来如此愚蠢和简单感到很有趣。

看到这个错误导致的奇怪行为也很有趣。我仍然很想知道为什么我的错误会导致我在问题中记录的行为。当我有时间的时候,我可能会回到这个只是为了好玩。

编辑

正如Thomas Dickey所指出的,ncurses 的FAQ中提到了这个确切的问题。

...,在 2017 年年中,对 xterm 终端描述的更新添加了 ECMA-48 REP(重复字符)控件。自 1997 年 1 月以来,它是 xterm 的一部分,但使用该功能的终端描述只是 xterm 的一部分(不是 ncurses)。

使用 TERM=xterm 但不支持此 xterm 功能的终端仿真器在将此功能引入 ncurses 后会出现错误。rxvt 不受影响,因为它不使用 TERM=xterm,或者更确切地说,它不应该使用 TERM=xterm,就像我一直在做的那样。

REP用于表示数据流中的前一个字符,如果是包含SPACE的图形字符(由一个或多个位组合表示),则重复n次,其中n等于Pn的值。如果 REP 前面的字符是控制功能或控制功能的一部分,则 REP 的效果不在本标准中定义。 代表 - ECMA-048

我还应该提到,ncurses 常见问题解答包括关于人们为什么倾向于使用 TERM=xterm 以及为什么不应该使用的精彩讨论,直接从马嘴里说出来!

于 2017-09-30T22:08:41.170 回答