diff options
author | Łukasz Niemier <lukasz@niemier.pl> | 2012-11-18 11:23:22 +0100 |
---|---|---|
committer | Łukasz Niemier <lukasz@niemier.pl> | 2012-11-18 11:23:22 +0100 |
commit | 47df1ae40adecd0a02fc7dd06ab0745cb18c3fe0 (patch) | |
tree | 13bf3e8fdcae60fdfb5fa5e26c95818dc7a49790 /fish_pager.cpp | |
parent | b79854ad1aa814d9d35d76a1929b4726fa4bffa5 (diff) |
Remove trailing whitespaces and change tabs to spaces
Diffstat (limited to 'fish_pager.cpp')
-rw-r--r-- | fish_pager.cpp | 2116 |
1 files changed, 1058 insertions, 1058 deletions
diff --git a/fish_pager.cpp b/fish_pager.cpp index 4fc0a44c..88ef8d3b 100644 --- a/fish_pager.cpp +++ b/fish_pager.cpp @@ -62,42 +62,42 @@ #include "env_universal.h" #include "print_help.h" -enum +enum { - LINE_UP = R_NULL+1, - LINE_DOWN, - PAGE_UP, - PAGE_DOWN + LINE_UP = R_NULL+1, + LINE_DOWN, + PAGE_UP, + PAGE_DOWN } - ; + ; enum { - HIGHLIGHT_PAGER_PREFIX, - HIGHLIGHT_PAGER_COMPLETION, - HIGHLIGHT_PAGER_DESCRIPTION, - HIGHLIGHT_PAGER_PROGRESS, - HIGHLIGHT_PAGER_SECONDARY + HIGHLIGHT_PAGER_PREFIX, + HIGHLIGHT_PAGER_COMPLETION, + HIGHLIGHT_PAGER_DESCRIPTION, + HIGHLIGHT_PAGER_PROGRESS, + HIGHLIGHT_PAGER_SECONDARY } - ; + ; enum { - /* - Returnd by the pager if no more displaying is needed - */ - PAGER_DONE, - /* - Returned by the pager if the completions would not fit in the specified number of columns - */ - PAGER_RETRY, - /* - Returned by the pager if the terminal changes size - */ - PAGER_RESIZE + /* + Returnd by the pager if no more displaying is needed + */ + PAGER_DONE, + /* + Returned by the pager if the completions would not fit in the specified number of columns + */ + PAGER_RETRY, + /* + Returned by the pager if the terminal changes size + */ + PAGER_RESIZE } - ; + ; /** The minimum width (in characters) the terminal may have for fish_pager to not refuse showing the completions @@ -148,15 +148,15 @@ static std::vector<char> pager_buffer; The environment variables used to specify the color of different tokens. */ -static const wchar_t *hightlight_var[] = +static const wchar_t *hightlight_var[] = { - L"fish_pager_color_prefix", - L"fish_pager_color_completion", - L"fish_pager_color_description", - L"fish_pager_color_progress", - L"fish_pager_color_secondary" + L"fish_pager_color_prefix", + L"fish_pager_color_completion", + L"fish_pager_color_description", + L"fish_pager_color_progress", + L"fish_pager_color_secondary" } - ; + ; /** This string contains the text that should be sent back to the calling program @@ -172,30 +172,30 @@ static FILE *out_file; */ struct comp_t { - /** - The list of all completin strings this entry applies to - */ - wcstring_list_t comp; - /** - The description - */ - wcstring desc; - /** - On-screen width of the completion string - */ - int comp_width; - /** - On-screen width of the description information - */ - int desc_width; - /** - Preffered total width - */ - int pref_width; - /** - Minimum acceptable width - */ - int min_width; + /** + The list of all completin strings this entry applies to + */ + wcstring_list_t comp; + /** + The description + */ + wcstring desc; + /** + On-screen width of the completion string + */ + int comp_width; + /** + On-screen width of the description information + */ + int desc_width; + /** + Preffered total width + */ + int pref_width; + /** + Minimum acceptable width + */ + int min_width; }; /** @@ -204,26 +204,26 @@ struct comp_t */ static rgb_color_t get_color( int highlight ) { - const wchar_t *val; - - if( highlight < 0 ) - return rgb_color_t::normal(); - if( highlight >= (5) ) - return rgb_color_t::normal(); - - val = wgetenv( hightlight_var[highlight]); - - if( !val ) - { - val = env_universal_get( hightlight_var[highlight]); - } - - if( !val ) - { - return rgb_color_t::normal(); - } - - return parse_color( val, false ); + const wchar_t *val; + + if( highlight < 0 ) + return rgb_color_t::normal(); + if( highlight >= (5) ) + return rgb_color_t::normal(); + + val = wgetenv( hightlight_var[highlight]); + + if( !val ) + { + val = env_universal_get( hightlight_var[highlight]); + } + + if( !val ) + { + return rgb_color_t::normal(); + } + + return parse_color( val, false ); } /** @@ -234,14 +234,14 @@ static rgb_color_t get_color( int highlight ) */ static void recalc_width( std::vector<comp_t *> &lst, const wchar_t *prefix ) { - for( size_t i=0; i<lst.size(); i++ ) - { - comp_t *c = lst.at(i); - - c->min_width = mini( c->desc_width, maxi(0,termsize.ws_col/3 - 2)) + - mini( c->desc_width, maxi(0,termsize.ws_col/5 - 4)) +4; - } - + for( size_t i=0; i<lst.size(); i++ ) + { + comp_t *c = lst.at(i); + + c->min_width = mini( c->desc_width, maxi(0,termsize.ws_col/3 - 2)) + + mini( c->desc_width, maxi(0,termsize.ws_col/5 - 4)) +4; + } + } /** @@ -250,25 +250,25 @@ static void recalc_width( std::vector<comp_t *> &lst, const wchar_t *prefix ) */ static int try_sequence( const char *seq ) { - int j, k; - wint_t c=0; - - for( j=0; - seq[j] != '\0' && seq[j] == (c=input_common_readch( j>0 )); - j++ ) - ; - - if( seq[j] == '\0' ) - { - return 1; - } - else - { - input_common_unreadch(c); - for(k=j-1; k>=0; k--) - input_common_unreadch(seq[k]); - } - return 0; + int j, k; + wint_t c=0; + + for( j=0; + seq[j] != '\0' && seq[j] == (c=input_common_readch( j>0 )); + j++ ) + ; + + if( seq[j] == '\0' ) + { + return 1; + } + else + { + input_common_unreadch(c); + for(k=j-1; k>=0; k--) + input_common_unreadch(seq[k]); + } + return 0; } /** @@ -276,66 +276,66 @@ static int try_sequence( const char *seq ) */ static wint_t readch() { - struct mapping - { - const char *seq; - wint_t bnd; - } - ; - - struct mapping m[]= - { - { - "\x1b[A", LINE_UP - } - , - { - key_up, LINE_UP - } - , - { - "\x1b[B", LINE_DOWN - } - , - { - key_down, LINE_DOWN - } - , - { - key_ppage, PAGE_UP - } - , - { - key_npage, PAGE_DOWN - } - , - { - " ", PAGE_DOWN - } - , - { - "\t", PAGE_DOWN - } - , - { - 0, 0 - } - - } - ; - int i; - - for( i=0; m[i].bnd; i++ ) - { - if( !m[i].seq ) - { - continue; - } - - if( try_sequence(m[i].seq ) ) - return m[i].bnd; - } - return input_common_readch(0); + struct mapping + { + const char *seq; + wint_t bnd; + } + ; + + struct mapping m[]= + { + { + "\x1b[A", LINE_UP + } + , + { + key_up, LINE_UP + } + , + { + "\x1b[B", LINE_DOWN + } + , + { + key_down, LINE_DOWN + } + , + { + key_ppage, PAGE_UP + } + , + { + key_npage, PAGE_DOWN + } + , + { + " ", PAGE_DOWN + } + , + { + "\t", PAGE_DOWN + } + , + { + 0, 0 + } + + } + ; + int i; + + for( i=0; m[i].bnd; i++ ) + { + if( !m[i].seq ) + { + continue; + } + + if( try_sequence(m[i].seq ) ) + return m[i].bnd; + } + return input_common_readch(0); } /** @@ -343,8 +343,8 @@ static wint_t readch() */ static int pager_buffered_writer( char c) { - pager_buffer.push_back(c); - return 0; + pager_buffer.push_back(c); + return 0; } /** @@ -368,24 +368,24 @@ static void pager_flush() */ static int print_max( const wchar_t *str, int max, int has_more ) { - int i; - int written = 0; - for( i=0; str[i]; i++ ) - { - - if( written + wcwidth(str[i]) > max ) - break; - if( ( written + wcwidth(str[i]) == max) && (has_more || str[i+1]) ) - { - writech( ellipsis_char ); - written += wcwidth(ellipsis_char ); - break; - } - - writech( str[i] ); - written+= wcwidth( str[i] ); - } - return written; + int i; + int written = 0; + for( i=0; str[i]; i++ ) + { + + if( written + wcwidth(str[i]) > max ) + break; + if( ( written + wcwidth(str[i]) == max) && (has_more || str[i+1]) ) + { + writech( ellipsis_char ); + written += wcwidth(ellipsis_char ); + break; + } + + writech( str[i] ); + written+= wcwidth( str[i] ); + } + return written; } /** @@ -393,72 +393,72 @@ static int print_max( const wchar_t *str, int max, int has_more ) */ static void completion_print_item( const wchar_t *prefix, comp_t *c, int width, bool secondary ) { - int comp_width=0, desc_width=0; - int written=0; - - if( c->pref_width <= width ) - { - /* - The entry fits, we give it as much space as it wants - */ - comp_width = c->comp_width; - desc_width = c->desc_width; - } - else - { - /* - The completion and description won't fit on the - allocated space. Give a maximum of 2/3 of the - space to the completion, and whatever is left to - the description. - */ - int desc_all = c->desc_width?c->desc_width+4:0; - - comp_width = maxi( mini( c->comp_width, - 2*(width-4)/3 ), - width - desc_all ); - if( c->desc_width ) - desc_width = width-comp_width-4; - else - c->desc_width=0; - - } - + int comp_width=0, desc_width=0; + int written=0; + + if( c->pref_width <= width ) + { + /* + The entry fits, we give it as much space as it wants + */ + comp_width = c->comp_width; + desc_width = c->desc_width; + } + else + { + /* + The completion and description won't fit on the + allocated space. Give a maximum of 2/3 of the + space to the completion, and whatever is left to + the description. + */ + int desc_all = c->desc_width?c->desc_width+4:0; + + comp_width = maxi( mini( c->comp_width, + 2*(width-4)/3 ), + width - desc_all ); + if( c->desc_width ) + desc_width = width-comp_width-4; + else + c->desc_width=0; + + } + rgb_color_t bg = secondary ? get_color(HIGHLIGHT_PAGER_SECONDARY) : rgb_color_t::normal(); - for( size_t i=0; i<c->comp.size(); i++ ) - { + for( size_t i=0; i<c->comp.size(); i++ ) + { const wcstring &comp = c->comp.at(i); - if( i != 0 ) - written += print_max( L" ", comp_width - written, 2 ); - set_color( get_color(HIGHLIGHT_PAGER_PREFIX), bg ); - written += print_max( prefix, comp_width - written, comp.empty()?0:1 ); - set_color( get_color(HIGHLIGHT_PAGER_COMPLETION), bg); - written += print_max( comp.c_str(), comp_width - written, i!=(c->comp.size()-1) ); - } - - - if( desc_width ) - { - while( written < (width-desc_width-2)) - { - written++; - writech( L' '); - } - set_color( get_color( HIGHLIGHT_PAGER_DESCRIPTION ), bg); - written += print_max( L"(", 1, 0 ); - written += print_max( c->desc.c_str(), desc_width, 0 ); - written += print_max( L")", 1, 0 ); - } - else - { - while( written < width ) - { - written++; - writech( L' '); - } - } - if ( secondary ) - set_color( rgb_color_t::normal(), rgb_color_t::normal() ); + if( i != 0 ) + written += print_max( L" ", comp_width - written, 2 ); + set_color( get_color(HIGHLIGHT_PAGER_PREFIX), bg ); + written += print_max( prefix, comp_width - written, comp.empty()?0:1 ); + set_color( get_color(HIGHLIGHT_PAGER_COMPLETION), bg); + written += print_max( comp.c_str(), comp_width - written, i!=(c->comp.size()-1) ); + } + + + if( desc_width ) + { + while( written < (width-desc_width-2)) + { + written++; + writech( L' '); + } + set_color( get_color( HIGHLIGHT_PAGER_DESCRIPTION ), bg); + written += print_max( L"(", 1, 0 ); + written += print_max( c->desc.c_str(), desc_width, 0 ); + written += print_max( L")", 1, 0 ); + } + else + { + while( written < width ) + { + written++; + writech( L' '); + } + } + if ( secondary ) + set_color( rgb_color_t::normal(), rgb_color_t::normal() ); } /** @@ -475,37 +475,37 @@ static void completion_print_item( const wchar_t *prefix, comp_t *c, int width, */ static void completion_print( int cols, - int *width, - int row_start, - int row_stop, - wchar_t *prefix, - int is_quoted, - const std::vector<comp_t *> &lst ) + int *width, + int row_start, + int row_stop, + wchar_t *prefix, + int is_quoted, + const std::vector<comp_t *> &lst ) { - size_t rows = (lst.size()-1)/cols+1; - size_t i, j; - - for( i = row_start; i<row_stop; i++ ) - { - for( j = 0; j < cols; j++ ) - { - comp_t *el; - - int is_last = (j==(cols-1)); - - if( lst.size() <= j*rows + i ) - continue; - - el = lst.at(j*rows + i ); - - completion_print_item( prefix, el, width[j] - (is_last?0:2), i%2 ); - - if( !is_last) - writestr( L" " ); - } - writech( L'\n' ); - } + size_t rows = (lst.size()-1)/cols+1; + size_t i, j; + + for( i = row_start; i<row_stop; i++ ) + { + for( j = 0; j < cols; j++ ) + { + comp_t *el; + + int is_last = (j==(cols-1)); + + if( lst.size() <= j*rows + i ) + continue; + + el = lst.at(j*rows + i ); + + completion_print_item( prefix, el, width[j] - (is_last?0:2), i%2 ); + + if( !is_last) + writestr( L" " ); + } + writech( L'\n' ); + } } @@ -528,301 +528,301 @@ static void completion_print( int cols, */ static int completion_try_print( int cols, - wchar_t *prefix, - int is_quoted, - std::vector<comp_t *> &lst ) + wchar_t *prefix, + int is_quoted, + std::vector<comp_t *> &lst ) { - /* - The calculated preferred width of each column - */ - int pref_width[PAGER_MAX_COLS]; - /* - The calculated minimum width of each column - */ - int min_width[PAGER_MAX_COLS]; - /* - If the list can be printed with this width, width will contain the width of each column - */ - int *width=pref_width; - /* - Set to one if the list should be printed at this width - */ - int print=0; - - long i, j; - - int rows = (int)((lst.size()-1)/cols+1); - - int pref_tot_width=0; - int min_tot_width = 0; - int res=PAGER_RETRY; - /* - Skip completions on tiny terminals - */ - - if( termsize.ws_col < PAGER_MIN_WIDTH ) - return PAGER_DONE; - - memset( pref_width, 0, sizeof(pref_width) ); - memset( min_width, 0, sizeof(min_width) ); - - /* Calculate how wide the list would be */ - for( j = 0; j < cols; j++ ) - { - for( i = 0; i<rows; i++ ) - { - int pref,min; - comp_t *c; - if( lst.size() <= j*rows + i ) - continue; - - c = lst.at(j*rows + i ); - pref = c->pref_width; - min = c->min_width; - - if( j != cols-1 ) - { - pref += 2; - min += 2; - } - min_width[j] = maxi( min_width[j], - min ); - pref_width[j] = maxi( pref_width[j], - pref ); - } - min_tot_width += min_width[j]; - pref_tot_width += pref_width[j]; - } - /* - Force fit if one column - */ - if( cols == 1) - { - if( pref_tot_width > termsize.ws_col ) - { - pref_width[0] = termsize.ws_col; - } - width = pref_width; - print=1; - } - else if( pref_tot_width <= termsize.ws_col ) - { - /* Terminal is wide enough. Print the list! */ - width = pref_width; - print=1; - } - else - { - long next_rows = (lst.size()-1)/(cols-1)+1; -/* fwprintf( stderr, + /* + The calculated preferred width of each column + */ + int pref_width[PAGER_MAX_COLS]; + /* + The calculated minimum width of each column + */ + int min_width[PAGER_MAX_COLS]; + /* + If the list can be printed with this width, width will contain the width of each column + */ + int *width=pref_width; + /* + Set to one if the list should be printed at this width + */ + int print=0; + + long i, j; + + int rows = (int)((lst.size()-1)/cols+1); + + int pref_tot_width=0; + int min_tot_width = 0; + int res=PAGER_RETRY; + /* + Skip completions on tiny terminals + */ + + if( termsize.ws_col < PAGER_MIN_WIDTH ) + return PAGER_DONE; + + memset( pref_width, 0, sizeof(pref_width) ); + memset( min_width, 0, sizeof(min_width) ); + + /* Calculate how wide the list would be */ + for( j = 0; j < cols; j++ ) + { + for( i = 0; i<rows; i++ ) + { + int pref,min; + comp_t *c; + if( lst.size() <= j*rows + i ) + continue; + + c = lst.at(j*rows + i ); + pref = c->pref_width; + min = c->min_width; + + if( j != cols-1 ) + { + pref += 2; + min += 2; + } + min_width[j] = maxi( min_width[j], + min ); + pref_width[j] = maxi( pref_width[j], + pref ); + } + min_tot_width += min_width[j]; + pref_tot_width += pref_width[j]; + } + /* + Force fit if one column + */ + if( cols == 1) + { + if( pref_tot_width > termsize.ws_col ) + { + pref_width[0] = termsize.ws_col; + } + width = pref_width; + print=1; + } + else if( pref_tot_width <= termsize.ws_col ) + { + /* Terminal is wide enough. Print the list! */ + width = pref_width; + print=1; + } + else + { + long next_rows = (lst.size()-1)/(cols-1)+1; +/* fwprintf( stderr, L"cols %d, min_tot %d, term %d, rows=%d, nextrows %d, termrows %d, diff %d\n", cols, min_tot_width, termsize.ws_col, rows, next_rows, termsize.ws_row, pref_tot_width-termsize.ws_col ); */ - if( min_tot_width < termsize.ws_col && - ( ( (rows < termsize.ws_row) && (next_rows >= termsize.ws_row ) ) || - ( pref_tot_width-termsize.ws_col< 4 && cols < 3 ) ) ) - { - /* - Terminal almost wide enough, or squeezing makes the - whole list fit on-screen. - - This part of the code is really important. People hate - having to scroll through the completion list. In cases - where there are a huge number of completions, it can't - be helped, but it is not uncommon for the completions to - _almost_ fit on one screen. In those cases, it is almost - always desirable to 'squeeze' the completions into a - single page. - - If we are using N columns and can get everything to - fit using squeezing, but everything would also fit - using N-1 columns, don't try. - */ - - int tot_width = min_tot_width; - width = min_width; - - while( tot_width < termsize.ws_col ) - { - for( i=0; (i<cols) && ( tot_width < termsize.ws_col ); i++ ) - { - if( width[i] < pref_width[i] ) - { - width[i]++; - tot_width++; - } - } - } - print=1; - } - } - - if( print ) - { - res=PAGER_DONE; - if( rows < termsize.ws_row ) - { - /* List fits on screen. Print it and leave */ - if( is_ca_mode ) - { - is_ca_mode = 0; - writembs(exit_ca_mode); - } - - completion_print( cols, width, 0, rows, prefix, is_quoted, lst); - pager_flush(); - } - else - { - int npos, pos = 0; - int do_loop = 1; - - /* - Enter ca_mode, which means that the terminal - content will be restored to the current - state on exit. - */ - if( enter_ca_mode && exit_ca_mode ) - { - is_ca_mode=1; - writembs(enter_ca_mode); - } - - - completion_print( cols, - width, - 0, - termsize.ws_row-1, - prefix, - is_quoted, - lst); - /* - List does not fit on screen. Print one screenfull and - leave a scrollable interface - */ - while(do_loop) - { - set_color( rgb_color_t::black(), get_color(HIGHLIGHT_PAGER_PROGRESS) ); + if( min_tot_width < termsize.ws_col && + ( ( (rows < termsize.ws_row) && (next_rows >= termsize.ws_row ) ) || + ( pref_tot_width-termsize.ws_col< 4 && cols < 3 ) ) ) + { + /* + Terminal almost wide enough, or squeezing makes the + whole list fit on-screen. + + This part of the code is really important. People hate + having to scroll through the completion list. In cases + where there are a huge number of completions, it can't + be helped, but it is not uncommon for the completions to + _almost_ fit on one screen. In those cases, it is almost + always desirable to 'squeeze' the completions into a + single page. + + If we are using N columns and can get everything to + fit using squeezing, but everything would also fit + using N-1 columns, don't try. + */ + + int tot_width = min_tot_width; + width = min_width; + + while( tot_width < termsize.ws_col ) + { + for( i=0; (i<cols) && ( tot_width < termsize.ws_col ); i++ ) + { + if( width[i] < pref_width[i] ) + { + width[i]++; + tot_width++; + } + } + } + print=1; + } + } + + if( print ) + { + res=PAGER_DONE; + if( rows < termsize.ws_row ) + { + /* List fits on screen. Print it and leave */ + if( is_ca_mode ) + { + is_ca_mode = 0; + writembs(exit_ca_mode); + } + + completion_print( cols, width, 0, rows, prefix, is_quoted, lst); + pager_flush(); + } + else + { + int npos, pos = 0; + int do_loop = 1; + + /* + Enter ca_mode, which means that the terminal + content will be restored to the current + state on exit. + */ + if( enter_ca_mode && exit_ca_mode ) + { + is_ca_mode=1; + writembs(enter_ca_mode); + } + + + completion_print( cols, + width, + 0, + termsize.ws_row-1, + prefix, + is_quoted, + lst); + /* + List does not fit on screen. Print one screenfull and + leave a scrollable interface + */ + while(do_loop) + { + set_color( rgb_color_t::black(), get_color(HIGHLIGHT_PAGER_PROGRESS) ); wcstring msg = format_string(_(L" %d to %d of %d"), pos, pos+termsize.ws_row-1, rows ); - msg.append(L" \r" ); - - writestr(msg.c_str()); - set_color( rgb_color_t::normal(), rgb_color_t::normal() ); - pager_flush(); - int c = readch(); - - switch( c ) - { - case LINE_UP: - { - if( pos > 0 ) - { - pos--; - writembs(tparm( cursor_address, 0, 0)); - writembs(scroll_reverse); - completion_print( cols, - width, - pos, - pos+1, - prefix, - is_quoted, - lst ); - writembs( tparm( cursor_address, - termsize.ws_row-1, 0) ); - writembs(clr_eol ); - - } - - break; - } - - case LINE_DOWN: - { - if( pos <= (rows - termsize.ws_row ) ) - { - pos++; - completion_print( cols, - width, - pos+termsize.ws_row-2, - pos+termsize.ws_row-1, - prefix, - is_quoted, - lst ); - } - break; - } - - case PAGE_DOWN: - { - - npos = mini( (int)(rows - termsize.ws_row+1), (int)(pos + termsize.ws_row-1) ); - if( npos != pos ) - { - pos = npos; - completion_print( cols, - width, - pos, - pos+termsize.ws_row-1, - prefix, - is_quoted, - lst ); - } - else - { - if( flash_screen ) - writembs( flash_screen ); - } - - break; - } - - case PAGE_UP: - { - npos = maxi( 0, - pos - termsize.ws_row+1 ); - - if( npos != pos ) - { - pos = npos; - completion_print( cols, - width, - pos, - pos+termsize.ws_row-1, - prefix, - is_quoted, - lst ); - } - else - { - if( flash_screen ) - writembs( flash_screen ); - } - break; - } - - case R_NULL: - { - do_loop=0; - res=PAGER_RESIZE; - break; - - } - - default: - { - out_buff.push_back( c ); - do_loop = 0; - break; - } - } - } - writembs(clr_eol); - } - } - return res; + msg.append(L" \r" ); + + writestr(msg.c_str()); + set_color( rgb_color_t::normal(), rgb_color_t::normal() ); + pager_flush(); + int c = readch(); + + switch( c ) + { + case LINE_UP: + { + if( pos > 0 ) + { + pos--; + writembs(tparm( cursor_address, 0, 0)); + writembs(scroll_reverse); + completion_print( cols, + width, + pos, + pos+1, + prefix, + is_quoted, + lst ); + writembs( tparm( cursor_address, + termsize.ws_row-1, 0) ); + writembs(clr_eol ); + + } + + break; + } + + case LINE_DOWN: + { + if( pos <= (rows - termsize.ws_row ) ) + { + pos++; + completion_print( cols, + width, + pos+termsize.ws_row-2, + pos+termsize.ws_row-1, + prefix, + is_quoted, + lst ); + } + break; + } + + case PAGE_DOWN: + { + + npos = mini( (int)(rows - termsize.ws_row+1), (int)(pos + termsize.ws_row-1) ); + if( npos != pos ) + { + pos = npos; + completion_print( cols, + width, + pos, + pos+termsize.ws_row-1, + prefix, + is_quoted, + lst ); + } + else + { + if( flash_screen ) + writembs( flash_screen ); + } + + break; + } + + case PAGE_UP: + { + npos = maxi( 0, + pos - termsize.ws_row+1 ); + + if( npos != pos ) + { + pos = npos; + completion_print( cols, + width, + pos, + pos+termsize.ws_row-1, + prefix, + is_quoted, + lst ); + } + else + { + if( flash_screen ) + writembs( flash_screen ); + } + break; + } + + case R_NULL: + { + do_loop=0; + res=PAGER_RESIZE; + break; + + } + + default: + { + out_buff.push_back( c ); + do_loop = 0; + break; + } + } + } + writembs(clr_eol); + } + } + return res; } /** @@ -832,39 +832,39 @@ static int completion_try_print( int cols, */ static void mangle_descriptions( wcstring_list_t &lst ) { - int skip; - for( size_t i=0; i<lst.size(); i++ ) - { + int skip; + for( size_t i=0; i<lst.size(); i++ ) + { wcstring &next = lst.at(i); - size_t in, out; - skip=1; - + size_t in, out; + skip=1; + size_t next_idx = 0; - while( next_idx < next.size() && next[next_idx] != COMPLETE_SEP ) - next_idx++; - - if( next_idx == next.size() ) - continue; - - in=out=next_idx + 1; - - while( in < next.size() ) - { - if( next[in] == L' ' || next[in]==L'\t' || next[in]<32 ) - { - if( !skip ) - next[out++]=L' '; - skip=1; - } - else - { - next[out++] = next[in]; - skip=0; - } - in++; - } + while( next_idx < next.size() && next[next_idx] != COMPLETE_SEP ) + next_idx++; + + if( next_idx == next.size() ) + continue; + + in=out=next_idx + 1; + + while( in < next.size() ) + { + if( next[in] == L' ' || next[in]==L'\t' || next[in]<32 ) + { + if( !skip ) + next[out++]=L' '; + skip=1; + } + else + { + next[out++] = next[in]; + skip=0; + } + in++; + } next.resize(out); - } + } } /** @@ -874,40 +874,40 @@ static void join_completions( wcstring_list_t lst ) { std::map<wcstring, long> desc_table; - for( size_t i=0; i<lst.size(); i++ ) - { - const wchar_t *item = lst.at(i).c_str(); - const wchar_t *desc = wcschr( item, COMPLETE_SEP ); - long prev_idx; - - if( !desc ) - continue; - desc++; + for( size_t i=0; i<lst.size(); i++ ) + { + const wchar_t *item = lst.at(i).c_str(); + const wchar_t *desc = wcschr( item, COMPLETE_SEP ); + long prev_idx; + + if( !desc ) + continue; + desc++; prev_idx = desc_table[desc] - 1; - if( prev_idx == -1 ) - { + if( prev_idx == -1 ) + { desc_table[desc] = (long)(i+1); - } - else - { - const wchar_t *old = lst.at(i).c_str(); - const wchar_t *old_end = wcschr( old, COMPLETE_SEP ); - - if( old_end ) - { - + } + else + { + const wchar_t *old = lst.at(i).c_str(); + const wchar_t *old_end = wcschr( old, COMPLETE_SEP ); + + if( old_end ) + { + wcstring foo; foo.append(old, old_end - old); foo.push_back(COMPLETE_ITEM_SEP); foo.append(item); - + lst.at(prev_idx) = foo; lst.at(i).clear(); - } - - } - - } + } + + } + + } /* Remove empty strings */ lst.erase(remove(lst.begin(), lst.end(), wcstring()), lst.end()); @@ -919,47 +919,47 @@ static void join_completions( wcstring_list_t lst ) static std::vector<comp_t *> mangle_completions( wcstring_list_t &lst, const wchar_t *prefix ) { std::vector<comp_t *> result; - for( size_t i=0; i<lst.size(); i++ ) - { + for( size_t i=0; i<lst.size(); i++ ) + { wcstring &next = lst.at(i); - size_t start, end; - + size_t start, end; + comp_t zerod = {}; - comp_t *comp = new comp_t(zerod); - - for( start=end=0; 1; end++ ) - { - wchar_t c = next.c_str()[end]; - - if( (c == COMPLETE_ITEM_SEP) || (c==COMPLETE_SEP) || !c) - { + comp_t *comp = new comp_t(zerod); + + for( start=end=0; 1; end++ ) + { + wchar_t c = next.c_str()[end]; + + if( (c == COMPLETE_ITEM_SEP) || (c==COMPLETE_SEP) || !c) + { wcstring start2 = wcstring(next, start, end - start); wcstring str = escape_string(start2, ESCAPE_ALL | ESCAPE_NO_QUOTED); - comp->comp_width += my_wcswidth( str.c_str() ); - comp->comp.push_back(str); - start = end+1; - } - - if( c == COMPLETE_SEP ) - { - comp->desc = next.c_str() + start; - break; - } - - if( !c ) - break; - - } - - comp->comp_width += (int)(my_wcswidth(prefix)*comp->comp.size() + 2*(comp->comp.size()-1)); - comp->desc_width = comp->desc.empty()?0:my_wcswidth( comp->desc.c_str() ); - - comp->pref_width = comp->comp_width + comp->desc_width + (comp->desc_width?4:0); - + comp->comp_width += my_wcswidth( str.c_str() ); + comp->comp.push_back(str); + start = end+1; + } + + if( c == COMPLETE_SEP ) + { + comp->desc = next.c_str() + start; + break; + } + + if( !c ) + break; + + } + + comp->comp_width += (int)(my_wcswidth(prefix)*comp->comp.size() + 2*(comp->comp.size()-1)); + comp->desc_width = comp->desc.empty()?0:my_wcswidth( comp->desc.c_str() ); + + comp->pref_width = comp->comp_width + comp->desc_width + (comp->desc_width?4:0); + result.push_back(comp); - } - - recalc_width( result, prefix ); + } + + recalc_width( result, prefix ); return result; } @@ -970,10 +970,10 @@ static std::vector<comp_t *> mangle_completions( wcstring_list_t &lst, const wch */ static void handle_winch( int sig ) { - if (ioctl(1,TIOCGWINSZ,&termsize)!=0) - { - return; - } + if (ioctl(1,TIOCGWINSZ,&termsize)!=0) + { + return; + } } /** @@ -983,7 +983,7 @@ static void handle_winch( int sig ) */ static int interrupt_handler() { - return R_NULL; + return R_NULL; } /** @@ -993,103 +993,103 @@ static int interrupt_handler() */ static void init( int mangle_descriptors, int out ) { - struct sigaction act; - - static struct termios pager_modes; - char *term; - - if( mangle_descriptors ) - { - - /* - Make fd 1 output to screen, and use some other fd for writing - the resulting output back to the caller - */ - int in; - out = dup( 1 ); - close(1); - close(0); + struct sigaction act; + + static struct termios pager_modes; + char *term; + + if( mangle_descriptors ) + { + + /* + Make fd 1 output to screen, and use some other fd for writing + the resulting output back to the caller + */ + int in; + out = dup( 1 ); + close(1); + close(0); /* OK to not use CLO_EXEC here because fish_pager is single threaded */ - if( (in = open( ttyname(2), O_RDWR )) != -1 ) - { - if( dup2( 2, 1 ) == -1 ) - { - debug( 0, _(L"Could not set up output file descriptors for pager") ); - exit( 1 ); - } - - if( dup2( in, 0 ) == -1 ) - { - debug( 0, _(L"Could not set up input file descriptors for pager") ); - exit( 1 ); - } - } - else - { - debug( 0, _(L"Could not open tty for pager") ); - exit( 1 ); - } - } - - if( !(out_file = fdopen( out, "w" )) ) - { - debug( 0, _(L"Could not initialize result pipe" ) ); - exit( 1 ); - } - - - env_universal_init( 0, 0, 0, 0); - input_common_init( &interrupt_handler ); - output_set_writer( &pager_buffered_writer ); - - sigemptyset( & act.sa_mask ); - act.sa_flags=0; - act.sa_handler=SIG_DFL; - act.sa_flags = 0; - act.sa_handler= &handle_winch; - if( sigaction( SIGWINCH, &act, 0 ) ) - { - wperror( L"sigaction" ); - exit(1); - } - - handle_winch( 0 ); /* Set handler for window change events */ - - tcgetattr(0,&pager_modes); /* get the current terminal modes */ - memcpy( &saved_modes, - &pager_modes, - sizeof(saved_modes)); /* save a copy so we can reset the terminal later */ - - pager_modes.c_lflag &= ~ICANON; /* turn off canonical mode */ - pager_modes.c_lflag &= ~ECHO; /* turn off echo mode */ - pager_modes.c_cc[VMIN]=1; - pager_modes.c_cc[VTIME]=0; - - /* - - */ - if( tcsetattr(0,TCSANOW,&pager_modes)) /* set the new modes */ - { - wperror(L"tcsetattr"); - exit(1); - } - - - if( setupterm( 0, STDOUT_FILENO, 0) == ERR ) - { - debug( 0, _(L"Could not set up terminal") ); - exit(1); - } - - term = getenv("TERM"); - if( term ) - { - wchar_t *wterm = str2wcs(term); - output_set_term( wterm ); - free( wterm ); - } - + if( (in = open( ttyname(2), O_RDWR )) != -1 ) + { + if( dup2( 2, 1 ) == -1 ) + { + debug( 0, _(L"Could not set up output file descriptors for pager") ); + exit( 1 ); + } + + if( dup2( in, 0 ) == -1 ) + { + debug( 0, _(L"Could not set up input file descriptors for pager") ); + exit( 1 ); + } + } + else + { + debug( 0, _(L"Could not open tty for pager") ); + exit( 1 ); + } + } + + if( !(out_file = fdopen( out, "w" )) ) + { + debug( 0, _(L"Could not initialize result pipe" ) ); + exit( 1 ); + } + + + env_universal_init( 0, 0, 0, 0); + input_common_init( &interrupt_handler ); + output_set_writer( &pager_buffered_writer ); + + sigemptyset( & act.sa_mask ); + act.sa_flags=0; + act.sa_handler=SIG_DFL; + act.sa_flags = 0; + act.sa_handler= &handle_winch; + if( sigaction( SIGWINCH, &act, 0 ) ) + { + wperror( L"sigaction" ); + exit(1); + } + + handle_winch( 0 ); /* Set handler for window change events */ + + tcgetattr(0,&pager_modes); /* get the current terminal modes */ + memcpy( &saved_modes, + &pager_modes, + sizeof(saved_modes)); /* save a copy so we can reset the terminal later */ + + pager_modes.c_lflag &= ~ICANON; /* turn off canonical mode */ + pager_modes.c_lflag &= ~ECHO; /* turn off echo mode */ + pager_modes.c_cc[VMIN]=1; + pager_modes.c_cc[VTIME]=0; + + /* + + */ + if( tcsetattr(0,TCSANOW,&pager_modes)) /* set the new modes */ + { + wperror(L"tcsetattr"); + exit(1); + } + + + if( setupterm( 0, STDOUT_FILENO, 0) == ERR ) + { + debug( 0, _(L"Could not set up terminal") ); + exit(1); + } + + term = getenv("TERM"); + if( term ) + { + wchar_t *wterm = str2wcs(term); + output_set_term( wterm ); + free( wterm ); + } + /* Infer term256 support */ char *fish_term256 = getenv("fish_term256"); bool support_term256; @@ -1098,7 +1098,7 @@ static void init( int mangle_descriptors, int out ) } else { support_term256 = term && strstr(term, "256color"); } - output_set_supports_term256(support_term256); + output_set_supports_term256(support_term256); } /** @@ -1106,15 +1106,15 @@ static void init( int mangle_descriptors, int out ) */ static void destroy() { - env_universal_destroy(); - input_common_destroy(); - wutil_destroy(); - if( del_curterm( cur_term ) == ERR ) - { - debug( 0, _(L"Error while closing terminfo") ); - } - - fclose( out_file ); + env_universal_destroy(); + input_common_destroy(); + wutil_destroy(); + if( del_curterm( cur_term ) == ERR ) + { + debug( 0, _(L"Error while closing terminfo") ); + } + + fclose( out_file ); } /** @@ -1123,319 +1123,319 @@ static void destroy() */ static void read_array( FILE* file, wcstring_list_t &comp ) { - std::vector<char> buffer; - int c; - wchar_t *wcs; - - while( !feof( file ) ) - { - buffer.clear(); - - while( 1 ) - { - c = getc( file ); - if( c == EOF ) - { - break; - } - - if( c == '\n' ) - { - break; - } + std::vector<char> buffer; + int c; + wchar_t *wcs; + + while( !feof( file ) ) + { + buffer.clear(); + + while( 1 ) + { + c = getc( file ); + if( c == EOF ) + { + break; + } + + if( c == '\n' ) + { + break; + } buffer.push_back(static_cast<char>(c)); - } + } - if( ! buffer.empty() ) - { + if( ! buffer.empty() ) + { buffer.push_back(0); - - wcs = str2wcs( &buffer.at(0) ); - if( wcs ) - { + + wcs = str2wcs( &buffer.at(0) ); + if( wcs ) + { wcstring tmp = wcs; if (unescape_string(tmp, 0)) { comp.push_back(tmp); - } - free( wcs ); - } - } - } + } + free( wcs ); + } + } + } } static int get_fd( const char *str ) { - char *end; - long fd; - - errno = 0; - fd = strtol( str, &end, 10 ); - if( fd < 0 || *end || errno ) - { - debug( 0, ERR_NOT_FD, program_name, optarg ); - exit( 1 ); - } - return (int)fd; + char *end; + long fd; + + errno = 0; + fd = strtol( str, &end, 10 ); + if( fd < 0 || *end || errno ) + { + debug( 0, ERR_NOT_FD, program_name, optarg ); + exit( 1 ); + } + return (int)fd; } int main( int argc, char **argv ) { - int i; - int is_quoted=0; - wcstring_list_t comp; - wchar_t *prefix = 0; - - int mangle_descriptors = 0; - int result_fd = -1; - set_main_thread(); + int i; + int is_quoted=0; + wcstring_list_t comp; + wchar_t *prefix = 0; + + int mangle_descriptors = 0; + int result_fd = -1; + set_main_thread(); setup_fork_guards(); - - /* - This initialization is made early, so that the other init code - can use global_context for memory managment - */ - program_name = L"fish_pager"; - - - wsetlocale( LC_ALL, L"" ); - - /* - The call signature for fish_pager is a mess. Because we want - to be able to upgrade fish without breaking running - instances, we need to support all previous - modes. Unfortunatly, the two previous ones are a mess. The - third one is designed to be extensible, so hopefully it will - be the last. - */ - - if( argc > 1 && argv[1][0] == '-' ) - { - /* - Third mode - */ - - int completion_fd = -1; - FILE *completion_file; - - while( 1 ) - { - static struct option - long_options[] = - { - { - "result-fd", required_argument, 0, 'r' - } - , - { - "completion-fd", required_argument, 0, 'c' - } - , - { - "prefix", required_argument, 0, 'p' - } - , - { - "is-quoted", no_argument, 0, 'q' - } - , - { - "help", no_argument, 0, 'h' - } - , - { - "version", no_argument, 0, 'v' - } - , - { - 0, 0, 0, 0 - } - } - ; - - int opt_index = 0; - - int opt = getopt_long( argc, - argv, - GETOPT_STRING, - long_options, - &opt_index ); - - if( opt == -1 ) - break; - - switch( opt ) - { - case 0: - { - break; - } - - case 'r': - { - result_fd = get_fd( optarg ); - break; - } - - case 'c': - { - completion_fd = get_fd( optarg ); - break; - } - - case 'p': - { - prefix = str2wcs(optarg); - break; - } - - case 'h': - { - print_help( argv[0], 1 ); - exit(0); - } - - case 'v': - { - debug( 0, L"%ls, version %s\n", program_name, PACKAGE_VERSION ); - exit( 0 ); - } - - case 'q': - { - is_quoted = 1; - } - - } - } - - if( completion_fd == -1 || result_fd == -1 ) - { - debug( 0, _(L"Unspecified file descriptors") ); - exit( 1 ); - } - - - if( (completion_file = fdopen( completion_fd, "r" ) ) ) - { - read_array( completion_file, comp ); - fclose( completion_file ); - } - else - { - debug( 0, _(L"Could not read completions") ); - wperror( L"fdopen" ); - exit( 1 ); - } - - if( !prefix ) - { - prefix = wcsdup( L"" ); - } - - - } - else - { - /* - Second or first mode. These suck, but we need to support - them for backwards compatibility. At least for some - time. - - Third mode was implemented in January 2007, and previous - modes should be considered deprecated from that point - forward. A reasonable time frame for removal of the code - below has yet to be determined. - */ - - if( argc < 3 ) - { - print_help( argv[0], 1 ); - exit( 0 ); - } - else - { - mangle_descriptors = 1; - - prefix = str2wcs( argv[2] ); - is_quoted = strcmp( "1", argv[1] )==0; - - if( argc > 3 ) - { - /* - First mode - */ - for( i=3; i<argc; i++ ) - { - wcstring wcs = str2wcstring( argv[i] ); + + /* + This initialization is made early, so that the other init code + can use global_context for memory managment + */ + program_name = L"fish_pager"; + + + wsetlocale( LC_ALL, L"" ); + + /* + The call signature for fish_pager is a mess. Because we want + to be able to upgrade fish without breaking running + instances, we need to support all previous + modes. Unfortunatly, the two previous ones are a mess. The + third one is designed to be extensible, so hopefully it will + be the last. + */ + + if( argc > 1 && argv[1][0] == '-' ) + { + /* + Third mode + */ + + int completion_fd = -1; + FILE *completion_file; + + while( 1 ) + { + static struct option + long_options[] = + { + { + "result-fd", required_argument, 0, 'r' + } + , + { + "completion-fd", required_argument, 0, 'c' + } + , + { + "prefix", required_argument, 0, 'p' + } + , + { + "is-quoted", no_argument, 0, 'q' + } + , + { + "help", no_argument, 0, 'h' + } + , + { + "version", no_argument, 0, 'v' + } + , + { + 0, 0, 0, 0 + } + } + ; + + int opt_index = 0; + + int opt = getopt_long( argc, + argv, + GETOPT_STRING, + long_options, + &opt_index ); + + if( opt == -1 ) + break; + + switch( opt ) + { + case 0: + { + break; + } + + case 'r': + { + result_fd = get_fd( optarg ); + break; + } + + case 'c': + { + completion_fd = get_fd( optarg ); + break; + } + + case 'p': + { + prefix = str2wcs(optarg); + break; + } + + case 'h': + { + print_help( argv[0], 1 ); + exit(0); + } + + case 'v': + { + debug( 0, L"%ls, version %s\n", program_name, PACKAGE_VERSION ); + exit( 0 ); + } + + case 'q': + { + is_quoted = 1; + } + + } + } + + if( completion_fd == -1 || result_fd == -1 ) + { + debug( 0, _(L"Unspecified file descriptors") ); + exit( 1 ); + } + + + if( (completion_file = fdopen( completion_fd, "r" ) ) ) + { + read_array( completion_file, comp ); + fclose( completion_file ); + } + else + { + debug( 0, _(L"Could not read completions") ); + wperror( L"fdopen" ); + exit( 1 ); + } + + if( !prefix ) + { + prefix = wcsdup( L"" ); + } + + + } + else + { + /* + Second or first mode. These suck, but we need to support + them for backwards compatibility. At least for some + time. + + Third mode was implemented in January 2007, and previous + modes should be considered deprecated from that point + forward. A reasonable time frame for removal of the code + below has yet to be determined. + */ + + if( argc < 3 ) + { + print_help( argv[0], 1 ); + exit( 0 ); + } + else + { + mangle_descriptors = 1; + + prefix = str2wcs( argv[2] ); + is_quoted = strcmp( "1", argv[1] )==0; + + if( argc > 3 ) + { + /* + First mode + */ + for( i=3; i<argc; i++ ) + { + wcstring wcs = str2wcstring( argv[i] ); comp.push_back(wcs); - } - } - else - { - /* - Second mode - */ - read_array( stdin, comp ); - } - } - - } - -// debug( 3, L"prefix is '%ls'", prefix ); - - init( mangle_descriptors, result_fd ); - - mangle_descriptions( comp ); - - if( wcscmp( prefix, L"-" ) == 0 ) - join_completions( comp ); - - std::vector<comp_t *> completions = mangle_completions( comp, prefix ); - - /** - Try to print the completions. Start by trying to print the - list in PAGER_MAX_COLS columns, if the completions won't - fit, reduce the number of columns by one. Printing a single - column never fails. - */ - for( i = PAGER_MAX_COLS; i>0; i-- ) - { - switch( completion_try_print( i, prefix, is_quoted, completions ) ) - { - - case PAGER_RETRY: - break; - - case PAGER_DONE: - i=0; - break; - - case PAGER_RESIZE: - /* - This means we got a resize event, so we start - over from the beginning. Since it the screen got - bigger, we might be able to fit all completions - on-screen. - */ - i=PAGER_MAX_COLS+1; - break; - - } - } - - free(prefix ); - - fwprintf( out_file, L"%ls", out_buff.c_str() ); - if( is_ca_mode ) - { - writembs(exit_ca_mode); - pager_flush(); - } - destroy(); + } + } + else + { + /* + Second mode + */ + read_array( stdin, comp ); + } + } + + } + +// debug( 3, L"prefix is '%ls'", prefix ); + + init( mangle_descriptors, result_fd ); + + mangle_descriptions( comp ); + + if( wcscmp( prefix, L"-" ) == 0 ) + join_completions( comp ); + + std::vector<comp_t *> completions = mangle_completions( comp, prefix ); + + /** + Try to print the completions. Start by trying to print the + list in PAGER_MAX_COLS columns, if the completions won't + fit, reduce the number of columns by one. Printing a single + column never fails. + */ + for( i = PAGER_MAX_COLS; i>0; i-- ) + { + switch( completion_try_print( i, prefix, is_quoted, completions ) ) + { + + case PAGER_RETRY: + break; + + case PAGER_DONE: + i=0; + break; + + case PAGER_RESIZE: + /* + This means we got a resize event, so we start + over from the beginning. Since it the screen got + bigger, we might be able to fit all completions + on-screen. + */ + i=PAGER_MAX_COLS+1; + break; + + } + } + + free(prefix ); + + fwprintf( out_file, L"%ls", out_buff.c_str() ); + if( is_ca_mode ) + { + writembs(exit_ca_mode); + pager_flush(); + } + destroy(); } |