/** \file output.c Generic output functions */ #include "config.h" #include #include #include #include #include #include #include #include #include #include #include #if HAVE_NCURSES_H #include #else #include #endif #if HAVE_TERMIO_H #include #endif #if HAVE_TERM_H #include #elif HAVE_NCURSES_TERM_H #include #endif #include #include #include #include #include #include "util.h" #include "wutil.h" #include "expand.h" #include "common.h" #include "output.h" #include "halloc_util.h" #include "highlight.h" /** Number of color names in the col array */ #define COLORS (sizeof(col)/sizeof(wchar_t *)) static int writeb_internal( char c ); /** Names of different colors. */ static wchar_t *col[]= { L"black", L"red", L"green", L"brown", L"yellow", L"blue", L"magenta", L"purple", L"cyan", L"white" L"normal" } ; /** Mapping from color name (the 'col' array) to color index as used in ANSI color terminals, and also the fish_color_* constants defined in highlight.h. Non-ANSI terminals will display the wrong colors, since they use a different mapping. */ static int col_idx[]= { 0, 1, 2, 3, 3, 4, 5, 5, 6, 7, FISH_COLOR_NORMAL, } ; /** Size of writestr_buff */ static size_t writestr_buff_sz=0; /** Temp buffer used for converting from wide to narrow strings */ static char *writestr_buff = 0; /** The function used for output */ static int (*out)(char c) = &writeb_internal; static void output_destroy() { free( writestr_buff ); } void output_set_writer( int (*writer)(char) ) { out = writer; } void set_color( int c, int c2 ) { static int last_color = FISH_COLOR_NORMAL; static int last_color2 = FISH_COLOR_NORMAL; int bg_set=0, last_bg_set=0; char *fg = 0, *bg=0; if( (set_a_foreground != 0) && (strlen( set_a_foreground) != 0 ) ) { fg = set_a_foreground; bg = set_a_background; } else if( (set_foreground != 0) && (strlen( set_foreground) != 0 ) ) { fg = set_foreground; bg = set_background; } if( (c == FISH_COLOR_RESET) || (c2 == FISH_COLOR_RESET)) { c = c2 = FISH_COLOR_NORMAL; if( fg ) { writembs( tparm( fg, 0 ) ); } writembs( exit_attribute_mode ); return; } if( last_color2 != FISH_COLOR_NORMAL && last_color2 != FISH_COLOR_RESET && last_color2 != FISH_COLOR_IGNORE ) { /* Background was set */ last_bg_set=1; } if( c2 != FISH_COLOR_NORMAL && c2 != FISH_COLOR_RESET && c2 != FISH_COLOR_IGNORE ) { /* Background is set */ bg_set=1; c = (c2==FISH_COLOR_WHITE)?FISH_COLOR_BLACK:FISH_COLOR_WHITE; } if( (enter_bold_mode != 0) && (strlen(enter_bold_mode) > 0)) { if(bg_set && !last_bg_set) { /* Background color changed and is set, so we enter bold mode to make reading easier */ writembs( enter_bold_mode ); } if(!bg_set && last_bg_set) { /* Background color changed and is no longer set, so we exit bold mode */ writembs( exit_attribute_mode ); /* We don't know if exit_attribute_mode resets colors, so we set it to something known. */ if( fg ) { writembs( tparm( fg, 0 ) ); last_color=0; } } } if( last_color != c ) { if( c==FISH_COLOR_NORMAL ) { if( fg ) { writembs( tparm( fg, 0 ) ); } writembs( exit_attribute_mode ); last_color2 = FISH_COLOR_NORMAL; } else if( ( c >= 0 ) && ( c < FISH_COLOR_NORMAL ) ) { if( fg ) { writembs( tparm( fg, c ) ); } } } last_color = c; if( last_color2 != c2 ) { if( c2 == FISH_COLOR_NORMAL ) { if( bg ) { writembs( tparm( bg, 0 ) ); } writembs( exit_attribute_mode ); if( ( last_color != FISH_COLOR_NORMAL ) && fg ) { writembs( tparm( fg, last_color ) ); } last_color2 = c2; } else if ( ( c2 >= 0 ) && ( c2 < FISH_COLOR_NORMAL ) ) { if( bg ) { writembs( tparm( bg, c2 ) ); } last_color2 = c2; } } } /** perm_left_cursor and parm_right_cursor don't seem to be properly emulated by many terminal emulators, so we only use plain curor_left, curor_right... */ void move_cursor( int steps ) { int i; if( !steps ) return; if( steps < 0 ){ for( i=0; i>steps; i--) { writembs(cursor_left); } } else { for( i=0; i= ENCODE_DIRECT_BASE) && ( ch < ENCODE_DIRECT_BASE+256) ) { buff[0] = ch- ENCODE_DIRECT_BASE; bytes=1; } else { memset( &state, 0, sizeof(state) ); bytes= wcrtomb( buff, ch, &state ); switch( bytes ) { case (size_t)(-1): { return 1; } } } for( i=0; imax_width ) { break; } written+=w; writech( *(str++) ); } written += wcwidth( ellipsis_char ); writech( ellipsis_char ); while( written < max_width ) { written++; writestr( L" " ); } } int write_escaped_str( const wchar_t *str, int max_len ) { wchar_t *out = escape( str, 1 ); int i; int len = my_wcswidth( out ); int written=0; if( max_len && (max_len < len)) { for( i=0; (written+wcwidth(out[i]))<=(max_len-1); i++ ) { writech( out[i] ); written += wcwidth( out[i] ); } writech( ellipsis_char ); written += wcwidth( ellipsis_char ); for( i=written; i= 0 ) { return color; } else { return FISH_COLOR_NORMAL; } }