From 0385fbe2be6d1fb03c6fdbc7ca2efb6fe2ff7ce6 Mon Sep 17 00:00:00 2001 From: axel Date: Fri, 14 Oct 2005 00:08:33 +1000 Subject: [PATCH] Optimize interactive input reader by allowing multiple input characters between redraws darcs-hash:20051013140833-ac50b-f652fada56ca7359246b03a4bdf2116fb8c52435.gz --- common.c | 4 -- fish_pager.c | 4 +- fish_tests.c | 2 + main.c | 2 + output.c | 34 ++++++++++++++- output.h | 4 ++ reader.c | 116 +++++++++++++++++++++++++++++++++++++++++++++++---- wutil.c | 15 +++++-- 8 files changed, 161 insertions(+), 20 deletions(-) diff --git a/common.c b/common.c index 82e67db42..14ea33569 100644 --- a/common.c +++ b/common.c @@ -788,10 +788,6 @@ int writeb( tputs_arg_t b ) void die_mem() { - /* - int *foo=0; - *foo = 6; - */ debug( 0, L"Out of memory, shutting down fish." ); exit(1); } diff --git a/fish_pager.c b/fish_pager.c index 50074dfa2..e46744383 100644 --- a/fish_pager.c +++ b/fish_pager.c @@ -38,8 +38,6 @@ #include "input_common.h" #include "env_universal.h" -#define WCHAR_END 0x80000000 - enum { LINE_UP = R_NULL+1, @@ -857,6 +855,7 @@ static void init() out_file = fdopen( out, "w" ); sb_init( &out_buff ); + output_init(); env_universal_init( 0, 0, 0, 0); input_common_init( &interrupt_handler ); @@ -928,6 +927,7 @@ void destroy() { env_universal_destroy(); input_common_destroy(); + output_destroy(); del_curterm( cur_term ); sb_destroy( &out_buff ); fclose( out_file ); diff --git a/fish_tests.c b/fish_tests.c index 613bd916c..ad37c4c8f 100644 --- a/fish_tests.c +++ b/fish_tests.c @@ -616,6 +616,7 @@ int main( int argc, char **argv ) say( L"Testing low-level functionality"); say( L"Lines beginning with '(ignore):' are not errors, they are warning messages\ngenerated by the fish parser library when given broken input, and can be\nignored. All actual errors begin with 'Error:'." ); + output_init(); event_init(); exec_init(); parser_init(); @@ -647,5 +648,6 @@ int main( int argc, char **argv ) wutil_destroy(); exec_destroy(); event_destroy(); + output_destroy(); } diff --git a/main.c b/main.c index a899d0814..8fecbdef5 100644 --- a/main.c +++ b/main.c @@ -207,6 +207,7 @@ int main( int argc, char **argv ) if( force_interactive ) is_interactive_session=1; + output_init(); event_init(); exec_init(); parser_init(); @@ -303,6 +304,7 @@ int main( int argc, char **argv ) common_destroy(); exec_destroy(); event_destroy(); + output_destroy(); intern_free_all(); diff --git a/output.c b/output.c index ebb7785b1..856586844 100644 --- a/output.c +++ b/output.c @@ -82,6 +82,19 @@ static int col_idx[]= } ; +static size_t writestr_buff_sz=0; +static char *writestr_buff = 0; + +void output_init() +{ +} + +void output_destroy() +{ + free( writestr_buff ); +} + + void set_color( int c, int c2 ) { static int last_color = FISH_COLOR_NORMAL, last_color2=FISH_COLOR_NORMAL; @@ -245,8 +258,25 @@ int writech( wint_t ch ) */ void writestr( const wchar_t *str ) { - while( *str != 0 ) - writech( *(str++) ); + while( *str ) + writech( *str++ ); +/* + size_t len = MAX_UTF8_BYTES*wcslen(str)+1; + + if( writestr_buff_sz < len ) + { + writestr_buff = realloc( writestr_buff, writestr_buff_sz ); + if( !writestr_buff ) + die_mem(); + writestr_buff_sz = len; + } + + wcstombs( writestr_buff, + str, + writestr_buff_sz ); + + write( 1, writestr_buff, strlen( writestr_buff ) ); +*/ } diff --git a/output.h b/output.h index a3d38bdef..8fac423d1 100644 --- a/output.h +++ b/output.h @@ -93,4 +93,8 @@ int writespace( int c ); int output_color_code( const wchar_t *val ); +void output_init(); + +void output_destroy(); + #endif diff --git a/reader.c b/reader.c index dc19a006f..5586c2704 100644 --- a/reader.c +++ b/reader.c @@ -7,7 +7,6 @@ syntax highlighting, tab-completion and various other interactive features. Internally the interactive mode functions rely in the functions of the input library to read individual characters of input. - Token search is handled incrementally. Actual searches are only done on when searching backwards, since the previous results are saved. The last search position is remembered and a new search continues from the @@ -32,6 +31,7 @@ commence. #include #include #include +#include #include #include @@ -90,6 +90,14 @@ commence. */ #define DEFAULT_TITLE L"echo $_ \" \"; pwd" +/** + The maximum number of characters to read from the keyboard without + repainting. Note that this readahead wil only occur if new + characters are avaialble for reading, fish will never block for + more input without repainting. +*/ +#define READAHEAD_MAX 256 + /** A struct describing the state of the interactive reader. These states can be stacked, in case reader_readline is called from @@ -1013,9 +1021,43 @@ static int insert_char( int c ) */ static int insert_str(wchar_t *str) { - while( (*str)!=0 ) - if(!insert_char( *str++ )) - return 0; + int len = wcslen( str ); + if( len < 4 ) + { + while( (*str)!=0 ) + if(!insert_char( *str++ )) + return 0; + } + else + { + + data->buff_len += len; + check_size(); + + /* Insert space for extra character at the right position */ + if( data->buff_pos < data->buff_len ) + { + memmove( &data->buff[data->buff_pos+len], + &data->buff[data->buff_pos], + sizeof(wchar_t)*(data->buff_len-data->buff_pos) ); + } + memmove( &data->buff[data->buff_pos], str, sizeof(wchar_t)*len ); + data->buff_pos += len; + data->buff[data->buff_len]='\0'; + + /* Syntax highlight */ + + reader_super_highlight_me_plenty( data->buff, + data->new_color, + data->buff_pos-1, + 0 ); + memcpy( data->color, data->new_color, sizeof(int) * data->buff_len ); + + /* repaint */ + + repaint(); + + } return 1; } @@ -2383,6 +2425,20 @@ static int read_i() return 0; } +static int can_read( int fd ) +{ + struct pollfd pfd = + { + fd, POLLIN, 0 + } + ; + switch( poll( &pfd, 1, 0 ) ) + { + case 1: + return 1; + } + return 0; +} @@ -2432,9 +2488,48 @@ wchar_t *reader_readline() (~) to digit) */ check_winch(); - while( (c=input_readch()) == 0 ) - ; - + while( 1 ) + { + c=input_readch(); + if( (c< WCHAR_END) && (c>31) && (c != 127) ) + { + if( can_read(0) ) + { + + wchar_t arr[READAHEAD_MAX+1]; + int i; + + memset( arr, 0, sizeof( arr ) ); + arr[0] = c; + + for( i=1; i31) && (c != 127) ) + { + arr[i]=c; + c=0; + } + else + break; + } + + insert_str( arr ); + + } + } + + if( c != 0 ) + break; + } + + check_winch(); reader_check_status(); @@ -2447,6 +2542,9 @@ wchar_t *reader_readline() if( last_char != R_YANK && last_char != R_YANK_POP ) yank=0; + + + switch (c) { @@ -2789,9 +2887,9 @@ wchar_t *reader_readline() default: { if( (c< WCHAR_END) && (c>31) && (c != 127) ) - { insert_char( c ); - } + else + debug( 0, L"Unknown keybinding %d", c ); break; } diff --git a/wutil.c b/wutil.c index 4563f4073..09b26d768 100644 --- a/wutil.c +++ b/wutil.c @@ -416,21 +416,30 @@ static int vgwprintf( void (*writer)(wchar_t), case 0: { unsigned d = va_arg( va, unsigned ); - snprintf( str, 32, "%d", d ); + if( precision >= 0 ) + snprintf( str, 32, "%.*u", precision, d ); + else + snprintf( str, 32, "%u", d ); break; } case 1: { unsigned long d = va_arg( va, unsigned long ); - snprintf( str, 32, "%ld", d ); + if( precision >= 0 ) + snprintf( str, 32, "%.*lu", precision, d ); + else + snprintf( str, 32, "%lu", d ); break; } case 2: { unsigned long long d = va_arg( va, unsigned long long ); - snprintf( str, 32, "%lld", d ); + if( precision >= 0 ) + snprintf( str, 32, "%.*llu", precision, d ); + else + snprintf( str, 32, "%llu", d ); break; }