Почему init_color () неэффективен в Terminal.app? - PullRequest
0 голосов
/ 11 января 2019

Похожие вопросы

ncurses: init_color () не действует (специфично для PuTTY, xterm и gnome-Terminal)

NCurses: почему init_color возвращает OK, но все еще не устанавливает цвет? (специфично для xterm)

выпуск

init_color сохраняет информацию о цвете в памяти ncurses и сообщает об успехе, но не влияет на MacOS (Mojave 10.14.2) Terminal.app версии 2.9.1 (421.1). ncurses был установлен через HomeBrew:

$ 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 . Соответствующий раздел находится под этим текстом:

# 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 ]

0 голосов
/ 12 января 2019

Из комментариев вам потребуется запись terminfo (источник) , как , чтобы использовать новую функциональность в Mohave:

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

Скомпилируйте / установите, используя тик ncurses 6.1, который вы установили с brew.

Это отправная точка (Apple вносит несовместимые изменения, как вы могли заметить в истории записей nsterm). Существуют и другие детали, которые необходимо проверить при тестировании (см., Например, tack и vttest ).

Однако: init_color не слишком используется в этом сценарии (т. Е. прямые цвета ), поскольку предполагается, что вы можете перепрограммировать цветовое содержимое записи RGB. Ты не можешь может сделать, что вы используете init_extended_pair , как показано в примере picsmap . Некоторые люди могут найти это полезным (см. обсуждение ). Цветовая пара влияет только на данные в ncurses; цвет содержимого меняет терминал.

Для 256 цветов ... Terminal.app не имеет изменяемой палитры, если это не было сделано недавно. Вот почему nsterm-256color использует xterm+256setaf в качестве строительного блока (это не имеет в этой области). Если вы перейдете по ссылкам обратно к определению, вы увидите это:

# 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@,
0 голосов
/ 11 января 2019

На данный момент я почти уверен, что терминал MacOS не поддерживает изменение индексов цвета. Вы получаете xterm escape-последовательность для этого (\e]4) в вашем дампе, но терминал Apple не является настоящим xterm.

Наиболее вероятное объяснение состоит в том, что терминал Apple объявляет себя xterm, потому что он почти совместим с xterm. Если вы перейдете в «Настройки терминала» → «Профили» → «Дополнительно», то первой настройкой будет «Объявить терминал как», и правильный ответ (в отношении ncurses) будет nsterm, а не xterm-256color, очевидное значение по умолчанию.

Однако, как и в случае с пользовательскими агентами браузера, объявление чего-то неизвестного иногда хуже, чем ложное объявление. Вполне вероятно, что большинство других ваших программ будут знать, как обрабатывать nsterm, но, возможно, нет. Например, при использовании nsterm установка bash, поставляемая с macOS, перестает распознавать ключ delete⌦ и вместо этого печатает ~.

Ncurses знает о nsterm. Если вы измените $TERM на это, пример программы, которую вы написали, больше не работает: он утверждает, что индексы цвета не могут быть изменены в этом эмуляторе терминала, что, по-видимому, правильно.

Можно использовать 24-битные цвета RGB на терминале macOS с помощью команды \e[C;2;R;G;Bm, где C равно 38 для переднего плана и 48 для фона, а R, G и B являются числовыми значениями в диапазоне 0 ... 255. Однако, похоже, что ncurses не может использовать эту возможность по любой причине.

...