2010-03-17 16 views
23

Je voudrais changer un programme pour détecter automatiquement si un terminal est compatible couleur ou non, donc quand j'exécute le programme à partir d'un terminal non compatible couleur (disons Mx shell dans (X) Emacs), la couleur est automatiquement éteindre.Comment déterminer si un terminal est compatible couleur?

Je ne veux pas coder en dur le programme pour détecter TERM = {emacs, dumb}. Je pense que termcap/terminfo devrait être en mesure d'aider avec ceci, mais jusqu'ici je n'ai réussi qu'à bricoler ensemble ce (n) extrait de code à l'aide de curses, qui échoue quand il ne trouve pas le terminal:

#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 Je reçois ceci:

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

qui est ... suboptimal.

+2

En dernière analyse, vous ne pouvez pas, car vous ne pouvez pas dire quel type de CRT le terminal est implémenté. –

+3

Je suis intéressé de savoir si le terminal (type) dit qu'il est compatible couleur ou non - pas dans une analyse du spectre de la lumière émanant d'un CRT :-) – asjo

Répondre

18

Un ami m'a pointé vers tput (1), et je mijoté cette solution:

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

qui fonctionne pour moi. Ce serait génial si j'avais un moyen de l'intégrer dans ack, cependant.

+1

Notez que 'has_colors()' de ncurses effectue un plus complet tester que d'examiner simplement le nombre de couleurs, car ce n'est pas le seul moyen d'exprimer la couleur dans terminfo. –

3

Recherchez l'entrée terminfo (5) pour le type de terminal et vérifiez l'entrée Co (max_colors). C'est le nombre de couleurs que le terminal supporte.

8

Vous l'avez presque eu, sauf que vous devez utiliser la fonction de curseurs de niveau inférieur setupterm au lieu de initscr. setupterm effectue une initialisation suffisante pour lire les données terminfo et si vous passez un pointeur vers une valeur de résultat d'erreur (le dernier argument), elle renvoie une valeur d'erreur au lieu d'émettre des messages d'erreur et de quitter (comportement par défaut pour 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; 
} 

informations sur l'utilisation setupterm est disponible dans la page de manuel curs_terminfo (3 fois) (x-man pages: // 3x/curs_terminfo) et Writing Programs with NCURSES.

+2

En C++ sur ma machine Mac OSX, j'ai besoin de #include . –