Optimize interactive input reader by allowing multiple input characters between redraws

darcs-hash:20051013140833-ac50b-f652fada56ca7359246b03a4bdf2116fb8c52435.gz
This commit is contained in:
axel 2005-10-14 00:08:33 +10:00
parent 7e3f9c222c
commit 0385fbe2be
8 changed files with 161 additions and 20 deletions

View file

@ -788,10 +788,6 @@ int writeb( tputs_arg_t b )
void die_mem() void die_mem()
{ {
/*
int *foo=0;
*foo = 6;
*/
debug( 0, L"Out of memory, shutting down fish." ); debug( 0, L"Out of memory, shutting down fish." );
exit(1); exit(1);
} }

View file

@ -38,8 +38,6 @@
#include "input_common.h" #include "input_common.h"
#include "env_universal.h" #include "env_universal.h"
#define WCHAR_END 0x80000000
enum enum
{ {
LINE_UP = R_NULL+1, LINE_UP = R_NULL+1,
@ -857,6 +855,7 @@ static void init()
out_file = fdopen( out, "w" ); out_file = fdopen( out, "w" );
sb_init( &out_buff ); sb_init( &out_buff );
output_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 );
@ -928,6 +927,7 @@ void destroy()
{ {
env_universal_destroy(); env_universal_destroy();
input_common_destroy(); input_common_destroy();
output_destroy();
del_curterm( cur_term ); del_curterm( cur_term );
sb_destroy( &out_buff ); sb_destroy( &out_buff );
fclose( out_file ); fclose( out_file );

View file

@ -616,6 +616,7 @@ int main( int argc, char **argv )
say( L"Testing low-level functionality"); 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:'." ); 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(); event_init();
exec_init(); exec_init();
parser_init(); parser_init();
@ -647,5 +648,6 @@ int main( int argc, char **argv )
wutil_destroy(); wutil_destroy();
exec_destroy(); exec_destroy();
event_destroy(); event_destroy();
output_destroy();
} }

2
main.c
View file

@ -207,6 +207,7 @@ int main( int argc, char **argv )
if( force_interactive ) if( force_interactive )
is_interactive_session=1; is_interactive_session=1;
output_init();
event_init(); event_init();
exec_init(); exec_init();
parser_init(); parser_init();
@ -303,6 +304,7 @@ int main( int argc, char **argv )
common_destroy(); common_destroy();
exec_destroy(); exec_destroy();
event_destroy(); event_destroy();
output_destroy();
intern_free_all(); intern_free_all();

View file

@ -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 ) void set_color( int c, int c2 )
{ {
static int last_color = FISH_COLOR_NORMAL, last_color2=FISH_COLOR_NORMAL; 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 ) void writestr( const wchar_t *str )
{ {
while( *str != 0 ) while( *str )
writech( *(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 ) );
*/
} }

View file

@ -93,4 +93,8 @@ int writespace( int c );
int output_color_code( const wchar_t *val ); int output_color_code( const wchar_t *val );
void output_init();
void output_destroy();
#endif #endif

116
reader.c
View file

@ -7,7 +7,6 @@ syntax highlighting, tab-completion and various other interactive features.
Internally the interactive mode functions rely in the functions of the Internally the interactive mode functions rely in the functions of the
input library to read individual characters of input. input library to read individual characters of input.
Token search is handled incrementally. Actual searches are only done Token search is handled incrementally. Actual searches are only done
on when searching backwards, since the previous results are saved. The on when searching backwards, since the previous results are saved. The
last search position is remembered and a new search continues from the last search position is remembered and a new search continues from the
@ -32,6 +31,7 @@ commence.
#include <sys/ioctl.h> #include <sys/ioctl.h>
#include <sys/time.h> #include <sys/time.h>
#include <sys/wait.h> #include <sys/wait.h>
#include <sys/poll.h>
#include <unistd.h> #include <unistd.h>
#include <wctype.h> #include <wctype.h>
@ -90,6 +90,14 @@ commence.
*/ */
#define DEFAULT_TITLE L"echo $_ \" \"; pwd" #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 A struct describing the state of the interactive reader. These
states can be stacked, in case reader_readline is called from 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) static int insert_str(wchar_t *str)
{ {
while( (*str)!=0 ) int len = wcslen( str );
if(!insert_char( *str++ )) if( len < 4 )
return 0; {
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; return 1;
} }
@ -2383,6 +2425,20 @@ static int read_i()
return 0; 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) (~) to digit)
*/ */
check_winch(); 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; i<READAHEAD_MAX; i++ )
{
if( !can_read( 0 ) )
{
c = 0;
break;
}
c = input_readch();
if( (c< WCHAR_END) && (c>31) && (c != 127) )
{
arr[i]=c;
c=0;
}
else
break;
}
insert_str( arr );
}
}
if( c != 0 )
break;
}
check_winch(); check_winch();
reader_check_status(); reader_check_status();
@ -2447,6 +2542,9 @@ wchar_t *reader_readline()
if( last_char != R_YANK && last_char != R_YANK_POP ) if( last_char != R_YANK && last_char != R_YANK_POP )
yank=0; yank=0;
switch (c) switch (c)
{ {
@ -2789,9 +2887,9 @@ wchar_t *reader_readline()
default: default:
{ {
if( (c< WCHAR_END) && (c>31) && (c != 127) ) if( (c< WCHAR_END) && (c>31) && (c != 127) )
{
insert_char( c ); insert_char( c );
} else
debug( 0, L"Unknown keybinding %d", c );
break; break;
} }

15
wutil.c
View file

@ -416,21 +416,30 @@ static int vgwprintf( void (*writer)(wchar_t),
case 0: case 0:
{ {
unsigned d = va_arg( va, unsigned ); 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; break;
} }
case 1: case 1:
{ {
unsigned long d = va_arg( va, unsigned long ); 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; break;
} }
case 2: case 2:
{ {
unsigned long long d = va_arg( va, unsigned long long ); 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; break;
} }