代码之家  ›  专栏  ›  技术社区  ›  Reinderien

为什么init_color()在terminal.app中无效?

  •  2
  • Reinderien  · 技术社区  · 7 年前

    相关问题

    ncurses: init_color() has no effect (针对油灰、xterm和gnome终端)

    NCurses: Why does init_color return OK but still not set the color? (特定于Xterm)

    问题

    init_color 正在将颜色信息保存在ncurses内存中并报告成功—但对macos(mojave 10.14.2)terminal.app版本2.9.1(421.1)没有影响。 ncurses 通过自制安装:

    $ brew info ncurses
    ncurses: stable 6.1 (bottled) [keg-only]
    Text-based UI library
    https://www.gnu.org/software/ncurses/
    /usr/local/Cellar/ncurses/6.1 (3,869 files, 8.3MB)
      Poured from bottle on 2018-12-31 at 21:59:36
    

    我的解决方法可能必须依赖于默认的ncurses调色板。

    基于之前问题中的一个答案,我回顾了 terminfo source . 相关章节如下:

    # The AppKit Terminal.app descriptions all have names beginning with
    # "nsterm".
    

    特别地:

    # For Apple_Terminal v309+, use "nsterm-256color" (or "nsterm-bce")
    

    10.14似乎没有具体的章节,最新的条目是10.13:

    # reviewed Terminal.app in High Sierra (version 2.8 build 400) -TD
    # Comparing with build361, little has changed, except that italics work.
    # Direct-color is not supported, by the way.
    #
    # Improved rmso/rmul -TD
    nsterm-build400|Terminal.app in OS X 10.13,
            rmso=\E[27m, rmul=\E[24m, use=xterm+sm+1006,
            use=ecma+italics, use=nsterm-build361,
    
    # This is an alias which should always point to the "current" version
    nsterm|nsterm-256color|Apple_Terminal|AppKit Terminal.app,
            use=nsterm-build400,
    

    一读到这一点,我就不清楚这是否是预期行为。

    最小可重复示例

    当我运行这个命令时,所有断言都会通过,但是前台和后台会显示默认颜色(而不是编辑后的颜色)。

    #include <assert.h>
    #include <fcntl.h>
    #include <ncursesw/ncurses.h>
    #include <unistd.h>
    
    
    int main() {
        int fdump = open("/tmp/ncurses_dump", O_WRONLY|O_CREAT|O_TRUNC, 0600);
        dup2(fdump, STDOUT_FILENO);
    
        assert(initscr() != NULL);
        assert(ERR != start_color());
        assert(has_colors());
        assert(can_change_color());
        assert(COLOR_PAIRS >= 256);
        assert(COLORS >= 256);
    
        // color 21 is blue by default
        // let's make it white
        const NCURSES_COLOR_T fore = 21;
        assert(ERR != init_color(fore, 998, 999, 1000));
        NCURSES_COLOR_T r, g, b;
        assert(ERR != color_content(fore, &r, &g, &b));
        assert(r == 998);
        assert(g == 999);
        assert(b == 1000);
    
        // color 195 is light blue by default
        // let's make it black
        const NCURSES_COLOR_T back = 195;
        assert(ERR != init_color(back, 0, 1, 2));
        assert(ERR != color_content(back, &r, &g, &b));
        assert(r == 0);
        assert(g == 1);
        assert(b == 2);
    
        // arbitrary
        const NCURSES_PAIRS_T pair = 100;
        assert(ERR != init_pair(pair, fore, back));
        NCURSES_COLOR_T fc, bc;
        assert(ERR != pair_content(pair, &fc, &bc));
        assert(fc == fore);
        assert(bc == back);
    
        // The pair init works, but the color init doesn't - this still outputs blue
        // on light blue
        assert(ERR != attron(COLOR_PAIR(pair)));
        assert(ERR != addch('X'));
    
        while (getch() != 'q');
    
        endwin();
        return 0;
    }
    

    然后,转储文件包含以下内容:

    $ hexdump -C /tmp/ncurses_dump 
    00000000  1b 5b 3f 31 30 34 39 68  1b 5b 32 32 3b 30 3b 30  |.[?1049h.[22;0;0|
    00000010  74 1b 5b 31 3b 34 37 72  1b 28 42 1b 5b 6d 1b 5b  |t.[1;47r.(B.[m.[|
    00000020  34 6c 1b 5b 3f 37 68 1b  5b 33 39 3b 34 39 6d 1b  |4l.[?7h.[39;49m.|
    00000030  5d 34 3b 32 31 3b 72 67  62 3a 46 45 2f 46 45 2f  |]4;21;rgb:FE/FE/|
    00000040  46 46 1b 5c 1b 5d 34 3b  31 39 35 3b 72 67 62 3a  |FF.\.]4;195;rgb:|
    00000050  30 30 2f 30 30 2f 30 30  1b 5c 1b 5b 33 39 3b 34  |00/00/00.\.[39;4|
    00000060  39 6d 1b 5b 33 37 6d 1b  5b 34 30 6d 1b 5b 48 1b  |9m.[37m.[40m.[H.|
    00000070  5b 32 4a 1b 5b 33 38 3b  35 3b 32 31 6d 1b 5b 34  |[2J.[38;5;21m.[4|
    00000080  38 3b 35 3b 31 39 35 6d  58 1b 28 42 1b 5b 6d 1b  |8;5;195mX.(B.[m.|
    00000090  5b 33 39 3b 34 39 6d 1b  5b 33 37 6d 1b 5b 34 30  |[39;49m.[37m.[40|
    000000a0  6d 1b 5b 33 38 3b 35 3b  32 31 6d 1b 5b 34 38 3b  |m.[38;5;21m.[48;|
    000000b0  35 3b 31 39 35 6d 71 1b  28 42 1b 5b 6d 1b 5b 33  |5;195mq.(B.[m.[3|
    000000c0  39 3b 34 39 6d 1b 5b 33  37 6d 1b 5b 34 30 6d 1b  |9;49m.[37m.[40m.|
    000000d0  5b 33 39 3b 34 39 6d 0d  1b 5b 34 37 64 1b 5b 4b  |[39;49m..[47d.[K|
    000000e0  1b 5b 33 39 3b 34 39 6d  1b 5d 31 30 34 07 1b 5b  |.[39;49m.]104..[|
    000000f0  34 37 3b 31 48 1b 5b 3f  31 30 34 39 6c 1b 5b 32  |47;1H.[?1049l.[2|
    00000100  33 3b 30 3b 30 74 0d 1b  5b 3f 31 6c 1b 3e        |3;0;0t..[?1l.>|
    0000010e
    
    2 回复  |  直到 7 年前
        1
  •  2
  •   Thomas Dickey    7 年前

    从注释中,您需要一个terminfo条目(source) 喜欢 使用Mohave中的新功能:

    nsterm-direct|nsterm with direct color,
            use=xterm+indirect, use=nsterm,
    

    使用随BREW一起安装的ncurses 6.1 tic编译/安装。

    这是一个起点(苹果确实做出了不兼容的更改,正如您在 history NSterm条目)。还有其他细节需要通过测试进行调查(请参见 tack vttest 例如)。

    然而: init_color 在这种情况下(即 直接颜色 ,因为它假定您可以重新编程RGB条目的颜色内容。你不能,你做什么? 可以 使用就是 init_extended_pair 如图所示 picsmap 例子。有些人可能会觉得这很有用(参见 discussion )颜色对只影响ncurses中的数据;颜色内容更改终端。

    256色…除非是最近完成的,否则terminal.app没有可更改的调色板。这就是为什么 nsterm-256color 使用 xterm+256setaf 作为一个积木 have-not 在这个领域)。如果按照链接返回定义,您将看到:

    # palette is hardcoded...
    xterm+256setaf|xterm 256-color (set-only),
            ccc@,
            colors#0x100, pairs#0x10000,
            initc@, op=\E[39;49m,
            setab=\E[%?%p1%{8}%<%t4%p1%d%e%p1%{16}%<%t10%p1%{8}%-%d%e48;
                  5;%p1%d%;m,
            setaf=\E[%?%p1%{8}%<%t3%p1%d%e%p1%{16}%<%t9%p1%{8}%-%d%e38;5
                  ;%p1%d%;m,
            setb@, setf@,
    
        2
  •  3
  •   zneak    7 年前

    此时,我确信MacOS终端不支持修改颜色索引。你得到了 xterm escape sequence for doing so α \e]4 )在你的垃圾堆里,但苹果的终端不是真正的xterm。

    最有可能的解释是,苹果的终端宣称自己是 xterm 因为它是 几乎 兼容 X术语 .如果您转到终端的首选项“高级配置文件”,第一个设置是“将终端声明为”,正确答案(就ncurses而言)是 nsterm 不是 xterm-256color 明显的违约。

    但是,就像浏览器用户代理一样,声明未知的内容有时比执行假声明更糟糕。你的大多数其他程序可能都知道如何处理 恩斯特姆 但也许不是。例如,当使用 恩斯特姆 , the bash 安装与MacOS一起提供的停止识别 删除符号 钥匙和打印件 ~ 相反。

    Ncurses知道 恩斯特姆 . 如果你改变你的 $TERM 为此,您编写的示例程序不再有效:它断言颜色索引不能在此终端仿真器上更改,这显然是正确的。

    可以在MacOS终端上使用24位RGB颜色,使用 \e[C;2;R;G;Bm 命令,在哪里 C 是38表示前景,48表示背景,以及 R , G B 是0…255范围内的数值。然而,无论出于什么原因,ncurses似乎无法使用此功能。