mirror of
https://github.com/fish-shell/fish-shell
synced 2024-12-26 04:43:10 +00:00
Add documentation, fix memory leaks and do minor code tweaks in fish_pager
darcs-hash:20061022110414-ac50b-e5ba776e795e0273d819d4eb51d5f60fba967db2.gz
This commit is contained in:
parent
5a7a8003a0
commit
e2dca4273a
1 changed files with 125 additions and 39 deletions
164
fish_pager.c
164
fish_pager.c
|
@ -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
|
||||
resizes, and as such always contain the correct current size.
|
||||
|
@ -81,11 +99,23 @@ enum
|
|||
|
||||
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 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;
|
||||
|
||||
/**
|
||||
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;
|
||||
|
||||
/**
|
||||
|
@ -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;
|
||||
/**
|
||||
This is the file to which the output text should be sent. It is really a pipe.
|
||||
*/
|
||||
static FILE *out_file;
|
||||
|
||||
/**
|
||||
|
@ -136,6 +172,10 @@ typedef struct
|
|||
}
|
||||
comp_t;
|
||||
|
||||
/**
|
||||
This function translates from a highlight code to a specific color
|
||||
by check invironement variables
|
||||
*/
|
||||
static int get_color( int highlight )
|
||||
{
|
||||
wchar_t *val;
|
||||
|
@ -160,6 +200,12 @@ static int get_color( int highlight )
|
|||
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 )
|
||||
{
|
||||
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 )
|
||||
{
|
||||
int j, k;
|
||||
|
@ -196,6 +246,9 @@ static int try_sequence( char *seq )
|
|||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
Read a character from keyboard
|
||||
*/
|
||||
static wint_t readch()
|
||||
{
|
||||
struct mapping
|
||||
|
@ -255,13 +308,18 @@ static wint_t readch()
|
|||
return input_common_readch(0);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
Write specified character to the output buffer \c pager_buffer
|
||||
*/
|
||||
static int pager_buffered_writer( char c)
|
||||
{
|
||||
b_append( pager_buffer, &c, 1 );
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
Flush \c pager_buffer to stdout
|
||||
*/
|
||||
static void pager_flush()
|
||||
{
|
||||
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 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,
|
||||
|
@ -455,13 +513,13 @@ static int completion_try_print( int cols,
|
|||
|
||||
int pref_tot_width=0;
|
||||
int min_tot_width = 0;
|
||||
int res=0;
|
||||
int res=PAGER_RETRY;
|
||||
/*
|
||||
Skip completions on tiny terminals
|
||||
*/
|
||||
|
||||
if( termsize.ws_col < 16 )
|
||||
return 1;
|
||||
return PAGER_DONE;
|
||||
|
||||
memset( pref_width, 0, sizeof(pref_width) );
|
||||
memset( min_width, 0, sizeof(min_width) );
|
||||
|
@ -550,7 +608,7 @@ static int completion_try_print( int cols,
|
|||
|
||||
if( print )
|
||||
{
|
||||
res=1;
|
||||
res=PAGER_DONE;
|
||||
if( rows < termsize.ws_row )
|
||||
{
|
||||
/* List fits on screen. Print it and leave */
|
||||
|
@ -585,11 +643,10 @@ static int completion_try_print( int cols,
|
|||
while(do_loop)
|
||||
{
|
||||
wchar_t msg[30];
|
||||
int percent = 100*(pos+rows)/(2*rows-termsize.ws_row+1);
|
||||
set_color( FISH_COLOR_BLACK,
|
||||
get_color(HIGHLIGHT_PAGER_PROGRESS) );
|
||||
swprintf( msg, 30,
|
||||
L" %d to %d of %d \r",
|
||||
_(L" %d to %d of %d \r"),
|
||||
pos, pos+termsize.ws_row-1, rows );
|
||||
writestr(msg);
|
||||
set_color( FISH_COLOR_NORMAL, FISH_COLOR_NORMAL );
|
||||
|
@ -689,7 +746,7 @@ static int completion_try_print( int cols,
|
|||
case R_NULL:
|
||||
{
|
||||
do_loop=0;
|
||||
res=2;
|
||||
res=PAGER_RESIZE;
|
||||
break;
|
||||
|
||||
}
|
||||
|
@ -887,6 +944,10 @@ static int interrupt_handler()
|
|||
static void init()
|
||||
{
|
||||
struct sigaction act;
|
||||
|
||||
static struct termios pager_modes;
|
||||
|
||||
|
||||
program_name = L"fish_pager";
|
||||
wsetlocale( LC_ALL, L"" );
|
||||
|
||||
|
@ -903,21 +964,21 @@ static void init()
|
|||
{
|
||||
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 );
|
||||
}
|
||||
|
||||
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 );
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
debug( 0, L"Could not open tty for pager" );
|
||||
{
|
||||
debug( 0, _(L"Could not open tty for pager") );
|
||||
exit( 1 );
|
||||
}
|
||||
}
|
||||
out_file = fdopen( out, "w" );
|
||||
|
||||
/**
|
||||
|
@ -925,7 +986,6 @@ static void init()
|
|||
*/
|
||||
sb_init( &out_buff );
|
||||
|
||||
halloc_util_init();
|
||||
env_universal_init( 0, 0, 0, 0);
|
||||
input_common_init( &interrupt_handler );
|
||||
output_set_writer( &pager_buffered_writer );
|
||||
|
@ -966,7 +1026,7 @@ static void init()
|
|||
|
||||
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);
|
||||
}
|
||||
|
||||
|
@ -977,6 +1037,7 @@ void destroy()
|
|||
env_universal_destroy();
|
||||
input_common_destroy();
|
||||
halloc_util_destroy();
|
||||
wutil_destroy();
|
||||
if( del_curterm( cur_term ) == ERR )
|
||||
{
|
||||
debug( 0, _(L"Error while closing terminfo") );
|
||||
|
@ -986,43 +1047,54 @@ void destroy()
|
|||
fclose( out_file );
|
||||
}
|
||||
|
||||
#define BUFSIZE 1024
|
||||
void read_array( FILE* file, array_list_t *comp )
|
||||
{
|
||||
char buffer[BUFSIZE];
|
||||
buffer_t buffer;
|
||||
int c;
|
||||
int i;
|
||||
char cc;
|
||||
wchar_t *wcs, *unescaped;
|
||||
|
||||
b_init( &buffer );
|
||||
|
||||
while( !feof( file ) )
|
||||
{
|
||||
i = 0;
|
||||
while( i < BUFSIZE-1 )
|
||||
buffer.used=0;
|
||||
|
||||
while( 1 )
|
||||
{
|
||||
c = getc( file );
|
||||
if( c == EOF )
|
||||
{
|
||||
return;
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
if( c == '\n' )
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
cc=c;
|
||||
|
||||
buffer[ i++ ] = c;
|
||||
b_append( &buffer, &cc, 1 );
|
||||
}
|
||||
|
||||
buffer[ i ] = '\0';
|
||||
|
||||
wcs = str2wcs( buffer );
|
||||
if( wcs )
|
||||
if( buffer.used )
|
||||
{
|
||||
unescaped = unescape( wcs, 0 );
|
||||
al_push( comp, unescaped );
|
||||
free( wcs );
|
||||
cc=0;
|
||||
b_append( &buffer, &cc, 1 );
|
||||
|
||||
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 )
|
||||
|
@ -1032,12 +1104,19 @@ int main( int argc, char **argv )
|
|||
array_list_t *comp;
|
||||
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 )
|
||||
{
|
||||
debug( 0, L"Insufficient arguments" );
|
||||
debug( 0, _(L"Insufficient arguments") );
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
comp = al_halloc( global_context );
|
||||
prefix = str2wcs( argv[2] );
|
||||
is_quoted = strcmp( "1", argv[1] )==0;
|
||||
|
@ -1061,28 +1140,35 @@ int main( int argc, char **argv )
|
|||
read_array( stdin, comp );
|
||||
}
|
||||
|
||||
|
||||
init();
|
||||
|
||||
mangle_descriptions( comp );
|
||||
|
||||
if( wcscmp( prefix, L"-" ) == 0 )
|
||||
join_completions( comp );
|
||||
join_completions( comp );
|
||||
|
||||
mangle_completions( comp, prefix );
|
||||
|
||||
for( i = 6; i>0; i-- )
|
||||
{
|
||||
switch( completion_try_print( i, prefix, is_quoted, comp ) )
|
||||
{
|
||||
case 0:
|
||||
|
||||
case PAGER_RETRY:
|
||||
break;
|
||||
case 1:
|
||||
|
||||
case PAGER_DONE:
|
||||
i=0;
|
||||
break;
|
||||
case 2:
|
||||
|
||||
case PAGER_RESIZE:
|
||||
/*
|
||||
This means we got a resize event, so we start over from the beginning
|
||||
*/
|
||||
i=7;
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
free(prefix );
|
||||
|
|
Loading…
Reference in a new issue