Add documentation, fix memory leaks and do minor code tweaks in fish_pager

darcs-hash:20061022110414-ac50b-e5ba776e795e0273d819d4eb51d5f60fba967db2.gz
This commit is contained in:
axel 2006-10-22 21:04:14 +10:00
parent 5a7a8003a0
commit e2dca4273a

View file

@ -74,6 +74,24 @@ enum
} }
; ;
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
}
;
/** /**
This struct should be continually updated by signals as the term This struct should be continually updated by signals as the term
resizes, and as such always contain the correct current size. resizes, and as such always contain the correct current size.
@ -81,11 +99,23 @@ enum
static struct winsize termsize; static struct winsize termsize;
/**
The termios modes the terminal had when the program started. These
should be restored on exit
*/
static struct termios saved_modes; static struct termios saved_modes;
static struct termios pager_modes;
/**
This flag is set to 1 of we have sent the enter_ca_mode terminfo
sequence to save the previous terminal contents.
*/
static int is_ca_mode = 0; static int is_ca_mode = 0;
/**
This buffer_t is used to buffer the output of the pager to improve
screen redraw performance bu cutting down the number of write()
calls to only one.
*/
static buffer_t *pager_buffer; static buffer_t *pager_buffer;
/** /**
@ -101,7 +131,13 @@ static wchar_t *hightlight_var[] =
} }
; ;
/**
This string_buffer_t contains the text that should be sent back to the calling program
*/
static string_buffer_t out_buff; static string_buffer_t out_buff;
/**
This is the file to which the output text should be sent. It is really a pipe.
*/
static FILE *out_file; static FILE *out_file;
/** /**
@ -136,6 +172,10 @@ typedef struct
} }
comp_t; comp_t;
/**
This function translates from a highlight code to a specific color
by check invironement variables
*/
static int get_color( int highlight ) static int get_color( int highlight )
{ {
wchar_t *val; wchar_t *val;
@ -160,6 +200,12 @@ static int get_color( int highlight )
return output_color_code( val ); return output_color_code( val );
} }
/**
This function calculates the minimum width for each completion
entry in the specified array_list. This width depends on the
terminal size, so this function should be called when the terminal
changes size.
*/
static void recalc_width( array_list_t *l, const wchar_t *prefix ) static void recalc_width( array_list_t *l, const wchar_t *prefix )
{ {
int i; int i;
@ -173,6 +219,10 @@ static void recalc_width( array_list_t *l, const wchar_t *prefix )
} }
/**
Test if the specified character sequence has been entered on the
keyboard
*/
static int try_sequence( char *seq ) static int try_sequence( char *seq )
{ {
int j, k; int j, k;
@ -196,6 +246,9 @@ static int try_sequence( char *seq )
return 0; return 0;
} }
/**
Read a character from keyboard
*/
static wint_t readch() static wint_t readch()
{ {
struct mapping struct mapping
@ -255,13 +308,18 @@ static wint_t readch()
return input_common_readch(0); return input_common_readch(0);
} }
/**
Write specified character to the output buffer \c pager_buffer
*/
static int pager_buffered_writer( char c) static int pager_buffered_writer( char c)
{ {
b_append( pager_buffer, &c, 1 ); b_append( pager_buffer, &c, 1 );
return 0; return 0;
} }
/**
Flush \c pager_buffer to stdout
*/
static void pager_flush() static void pager_flush()
{ {
write( 1, pager_buffer->buff, pager_buffer->used ); write( 1, pager_buffer->buff, pager_buffer->used );
@ -424,7 +482,7 @@ static void completion_print( int cols,
\param is_quoted whether the completions should be quoted \param is_quoted whether the completions should be quoted
\param l the list of completions \param l the list of completions
\return zero if the specified number of columns do not fit, no-zero otherwise \return one of PAGER_RETRY, PAGER_DONE and PAGER_RESIZE
*/ */
static int completion_try_print( int cols, static int completion_try_print( int cols,
@ -455,13 +513,13 @@ static int completion_try_print( int cols,
int pref_tot_width=0; int pref_tot_width=0;
int min_tot_width = 0; int min_tot_width = 0;
int res=0; int res=PAGER_RETRY;
/* /*
Skip completions on tiny terminals Skip completions on tiny terminals
*/ */
if( termsize.ws_col < 16 ) if( termsize.ws_col < 16 )
return 1; return PAGER_DONE;
memset( pref_width, 0, sizeof(pref_width) ); memset( pref_width, 0, sizeof(pref_width) );
memset( min_width, 0, sizeof(min_width) ); memset( min_width, 0, sizeof(min_width) );
@ -550,7 +608,7 @@ static int completion_try_print( int cols,
if( print ) if( print )
{ {
res=1; res=PAGER_DONE;
if( rows < termsize.ws_row ) if( rows < termsize.ws_row )
{ {
/* List fits on screen. Print it and leave */ /* List fits on screen. Print it and leave */
@ -585,11 +643,10 @@ static int completion_try_print( int cols,
while(do_loop) while(do_loop)
{ {
wchar_t msg[30]; wchar_t msg[30];
int percent = 100*(pos+rows)/(2*rows-termsize.ws_row+1);
set_color( FISH_COLOR_BLACK, set_color( FISH_COLOR_BLACK,
get_color(HIGHLIGHT_PAGER_PROGRESS) ); get_color(HIGHLIGHT_PAGER_PROGRESS) );
swprintf( msg, 30, swprintf( msg, 30,
L" %d to %d of %d \r", _(L" %d to %d of %d \r"),
pos, pos+termsize.ws_row-1, rows ); pos, pos+termsize.ws_row-1, rows );
writestr(msg); writestr(msg);
set_color( FISH_COLOR_NORMAL, FISH_COLOR_NORMAL ); set_color( FISH_COLOR_NORMAL, FISH_COLOR_NORMAL );
@ -689,7 +746,7 @@ static int completion_try_print( int cols,
case R_NULL: case R_NULL:
{ {
do_loop=0; do_loop=0;
res=2; res=PAGER_RESIZE;
break; break;
} }
@ -887,6 +944,10 @@ static int interrupt_handler()
static void init() static void init()
{ {
struct sigaction act; struct sigaction act;
static struct termios pager_modes;
program_name = L"fish_pager"; program_name = L"fish_pager";
wsetlocale( LC_ALL, L"" ); wsetlocale( LC_ALL, L"" );
@ -903,21 +964,21 @@ static void init()
{ {
if( dup2( 2, 1 ) == -1 ) if( dup2( 2, 1 ) == -1 )
{ {
debug( 0, L"Could not set up output file descriptors for pager" ); debug( 0, _(L"Could not set up output file descriptors for pager") );
exit( 1 ); exit( 1 );
} }
if( dup2( in, 0 ) == -1 ) if( dup2( in, 0 ) == -1 )
{ {
debug( 0, L"Could not set up input file descriptors for pager %d", in ); debug( 0, _(L"Could not set up input file descriptors for pager %d"), in );
exit( 1 ); exit( 1 );
} }
} }
else else
{ {
debug( 0, L"Could not open tty for pager" ); debug( 0, _(L"Could not open tty for pager") );
exit( 1 ); exit( 1 );
} }
out_file = fdopen( out, "w" ); out_file = fdopen( out, "w" );
/** /**
@ -925,7 +986,6 @@ static void init()
*/ */
sb_init( &out_buff ); sb_init( &out_buff );
halloc_util_init();
env_universal_init( 0, 0, 0, 0); env_universal_init( 0, 0, 0, 0);
input_common_init( &interrupt_handler ); input_common_init( &interrupt_handler );
output_set_writer( &pager_buffered_writer ); output_set_writer( &pager_buffered_writer );
@ -966,7 +1026,7 @@ static void init()
if( setupterm( 0, STDOUT_FILENO, 0) == ERR ) if( setupterm( 0, STDOUT_FILENO, 0) == ERR )
{ {
debug( 0, L"Could not set up terminal" ); debug( 0, _(L"Could not set up terminal") );
exit(1); exit(1);
} }
@ -977,6 +1037,7 @@ void destroy()
env_universal_destroy(); env_universal_destroy();
input_common_destroy(); input_common_destroy();
halloc_util_destroy(); halloc_util_destroy();
wutil_destroy();
if( del_curterm( cur_term ) == ERR ) if( del_curterm( cur_term ) == ERR )
{ {
debug( 0, _(L"Error while closing terminfo") ); debug( 0, _(L"Error while closing terminfo") );
@ -986,43 +1047,54 @@ void destroy()
fclose( out_file ); fclose( out_file );
} }
#define BUFSIZE 1024
void read_array( FILE* file, array_list_t *comp ) void read_array( FILE* file, array_list_t *comp )
{ {
char buffer[BUFSIZE]; buffer_t buffer;
int c; int c;
int i; char cc;
wchar_t *wcs, *unescaped; wchar_t *wcs, *unescaped;
b_init( &buffer );
while( !feof( file ) ) while( !feof( file ) )
{ {
i = 0; buffer.used=0;
while( i < BUFSIZE-1 )
while( 1 )
{ {
c = getc( file ); c = getc( file );
if( c == EOF ) if( c == EOF )
{ {
return; break;
} }
if( c == '\n' ) if( c == '\n' )
{ {
break; break;
} }
cc=c;
buffer[ i++ ] = c; b_append( &buffer, &cc, 1 );
} }
buffer[ i ] = '\0'; if( buffer.used )
wcs = str2wcs( buffer );
if( wcs )
{ {
unescaped = unescape( wcs, 0 ); cc=0;
al_push( comp, unescaped ); b_append( &buffer, &cc, 1 );
free( wcs );
wcs = str2wcs( buffer.buff );
if( wcs )
{
unescaped = unescape( wcs, 0 );
al_push( comp, unescaped );
free( wcs );
}
} }
} }
b_destroy( &buffer );
} }
int main( int argc, char **argv ) int main( int argc, char **argv )
@ -1032,12 +1104,19 @@ int main( int argc, char **argv )
array_list_t *comp; array_list_t *comp;
wchar_t *prefix; wchar_t *prefix;
/*
This initialization is made early, so that the other init code
can use global_context for memory managment
*/
halloc_util_init();
if( argc < 3 ) if( argc < 3 )
{ {
debug( 0, L"Insufficient arguments" ); debug( 0, _(L"Insufficient arguments") );
} }
else else
{ {
comp = al_halloc( global_context ); comp = al_halloc( global_context );
prefix = str2wcs( argv[2] ); prefix = str2wcs( argv[2] );
is_quoted = strcmp( "1", argv[1] )==0; is_quoted = strcmp( "1", argv[1] )==0;
@ -1061,28 +1140,35 @@ int main( int argc, char **argv )
read_array( stdin, comp ); read_array( stdin, comp );
} }
init(); init();
mangle_descriptions( comp ); mangle_descriptions( comp );
if( wcscmp( prefix, L"-" ) == 0 ) if( wcscmp( prefix, L"-" ) == 0 )
join_completions( comp ); join_completions( comp );
mangle_completions( comp, prefix ); mangle_completions( comp, prefix );
for( i = 6; i>0; i-- ) for( i = 6; i>0; i-- )
{ {
switch( completion_try_print( i, prefix, is_quoted, comp ) ) switch( completion_try_print( i, prefix, is_quoted, comp ) )
{ {
case 0:
case PAGER_RETRY:
break; break;
case 1:
case PAGER_DONE:
i=0; i=0;
break; break;
case 2:
case PAGER_RESIZE:
/*
This means we got a resize event, so we start over from the beginning
*/
i=7; i=7;
break; break;
}
}
} }
free(prefix ); free(prefix );