2010-03-17 15 views
23

Vorrei modificare un programma per rilevare automaticamente se un terminale è o meno compatibile con il colore, quindi quando eseguo detto programma da un terminale non compatibile con il colore (ad esempio shell Mx in (X) Emacs), il colore viene automaticamente spento.Come determinare se un terminale è compatibile con i colori?

Non voglio eseguire l'hardcode del programma per rilevare TERM = {emacs, dumb}.

Sto pensando che termcap/terminfo dovrebbe essere in grado di aiutare con questo, ma finora sono riuscito a mettere insieme solo questo (n) curses-usando snippet di codice, che fallisce male quando non riesce a trovare il terminale:

#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); 
} 

Ie Ho capito:

$ 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. 
$ 

che è ... non ottimale.

+2

Nell'analisi finale non è possibile, perché non è possibile stabilire con quale tipo di CRT viene implementato il terminale. –

+3

Mi interessa sapere se il terminale (tipo) dice che è a colori o no - non in un'analisi dello spettro della luce che emana da un CRT :-) – asjo

risposta

18

Un amico mi ha segnalato in direzione tput (1), e ho cucinato questa soluzione:

#!/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]" 

che funziona per me. Sarebbe bello se avessi un modo per integrarlo in ack, però.

+1

Nota che 'has_colors()' di ncurses esegue un controllo più completo prova piuttosto che esaminare il numero di colori, poiché non è l'unico modo in cui il supporto cromatico può essere espresso in terminfo. –

3

Cercare la voce terminfo (5) per il tipo di terminale e controllare la voce Co (max_colors). Ecco quanti colori supporta il terminale.

8

Quasi ce l'hai, tranne che è necessario utilizzare la funzione curses di livello inferiore setupterm anziché initscr. setupterm esegue solo un'inizializzazione sufficiente per leggere i dati terminfo e se si passa un puntatore a un valore del risultato dell'errore (l'ultimo argomento) verrà restituito un valore di errore anziché emettere messaggi di errore ed uscire (il comportamento predefinito per 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; 
} 

Ulteriori informazioni sull'utilizzo setupterm è disponibile nella pagina man curs_terminfo (3X) (x-man-page: // 3x/curs_terminfo) e Writing Programs with NCURSES.

+2

In C++ sulla mia macchina Mac OSX devo anche includere #include . –

Problemi correlati