2010-03-17 3 views
23

Я хотел бы изменить программу, чтобы автоматически определять, поддерживает ли терминал цветопередачу или нет, поэтому, когда я запускаю указанную программу из не-цветного терминала (скажем, Mx shell in (X) Emacs), цвет автоматически выключен.Как определить, совместим ли терминал с цветом?

Я не хочу жестко программировать программу для обнаружения TERM = {emacs, dumb}.

Я думаю, что termcap/terminfo должен быть в состоянии помочь с этим, но до сих пор мне удалось только совместить этот (n) проклятия, используя фрагмент кода, который плохо работает, когда он не может найти терминал:

#include <stdlib.h> 
#include <curses.h> 

int main(void) { 
int colors=0; 

initscr(); 
start_color(); 
colors=has_colors() ? 1 : 0; 
endwin(); 

printf(colors ? "YES\n" : "NO\n"); 

exit(0); 
} 

Т.е. Т.е. Я получаю это:

$ gcc -Wall -lncurses -o hep hep.c 
$ echo $TERM 
xterm 
$ ./hep 
YES 
$ export TERM=dumb 
$ ./hep   
NO 
$ export TERM=emacs 
$ ./hep    
Error opening terminal: emacs. 
$ 

который ... субоптимальный.

+2

В конечном счете вы не можете, потому что вы не можете сказать, с каким ЭЛТ-терминалом реализован терминал. – 2010-03-17 20:01:47

+3

Меня интересует, говорит ли терминал (тип), что он способен к цвету или нет - не в анализе спектра света, исходящего из ЭЛТ :-) – asjo

ответ

18

друг указал мне на tput (1), и я приготовил это решение:

#!/bin/sh 

# ack-wrapper - use tput to try and detect whether the terminal is 
#    color-capable, and call ack-grep accordingly. 

OPTION='--nocolor' 

COLORS=$(tput colors 2> /dev/null) 
if [ $? = 0 ] && [ $COLORS -gt 2 ]; then 
    OPTION='' 
fi 

exec ack-grep $OPTION "[email protected]" 

, который работает для меня. Было бы здорово, если бы у меня был способ интегрировать его в ack.

+1

Обратите внимание, что 'has_colors()' ncurses выполняет более комплексную чем просто изучение количества цветов, поскольку это не единственный способ поддержки цвета в terminfo. –

3

Просмотрите запись terminfo (5) для типа терминала и проверьте запись Co (max_colors). Вот сколько цветов поддерживает терминал.

8

У вас почти было это, за исключением того, что вам нужно использовать функцию curses нижнего уровня setupterm вместо initscr. setupterm просто выполняет достаточную инициализацию для чтения данных terminfo, и если вы передадите указатель на значение результата ошибки (последний аргумент), оно вернет значение ошибки вместо того, чтобы испускать сообщения об ошибках и выходить (поведение по умолчанию для initscr).

#include <stdlib.h> 
#include <curses.h> 

int main(void) { 
    char *term = getenv("TERM"); 

    int erret = 0; 
    if (setupterm(NULL, 1, &erret) == ERR) { 
    char *errmsg = "unknown error"; 
    switch (erret) { 
    case 1: errmsg = "terminal is hardcopy, cannot be used for curses applications"; break; 
    case 0: errmsg = "terminal could not be found, or not enough information for curses applications"; break; 
    case -1: errmsg = "terminfo entry could not be found"; break; 
    } 
    printf("Color support for terminal \"%s\" unknown (error %d: %s).\n", term, erret, errmsg); 
    exit(1); 
    } 

    bool colors = has_colors(); 

    printf("Terminal \"%s\" %s colors.\n", term, colors ? "has" : "does not have"); 

    return 0; 
} 

Дополнительная информация об использовании setupterm доступна в справочной странице curs_terminfo (3X) (х человек страниц: // 3x/curs_terminfo) и Writing Programs with NCURSES.

+2

В C++ на моей машине Mac OSX мне также нужно #include . –

Смежные вопросы