diff --git a/complete.h b/complete.h index ef5077451..5abd44530 100644 --- a/complete.h +++ b/complete.h @@ -53,6 +53,17 @@ */ #define COMPLETE_SEP_STR L"\004" +/** + Sent to the fish_pager to signify the end of input +*/ + +#define PAGER_EOT '\003' + +/** + Sent to the fish_pager to signify the end of input +*/ +#define PAGER_EOT_STR L"\003" + /** Separator between completion items in fish_pager. This is used for completion grouping, e.g. when putting completions with the same @@ -66,6 +77,10 @@ */ #define PROG_COMPLETE_SEP L'\t' +/** + Terminator for completions sent to the fish_pager +*/ +#define COMPLETE_TERMINATOR L'\006' /** diff --git a/fish_pager.c b/fish_pager.c index ad64cdceb..291a16eb5 100644 --- a/fish_pager.c +++ b/fish_pager.c @@ -895,15 +895,29 @@ static void init() the resulting output back to the caller */ int out = dup( 1 ); + int in = dup( 0 ); close(1); - if( open( ttyname(0), O_WRONLY ) != 1 ) + close(0); + + if( (in = open( ttyname(2), O_RDWR )) != -1 ) { if( dup2( 2, 1 ) == -1 ) { - debug( 0, L"Could not set up 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 ); exit( 1 ); } } + else + { + debug( 0, L"Could not open tty for pager" ); + exit( 1 ); + } out_file = fdopen( out, "w" ); /** @@ -972,6 +986,41 @@ void destroy() fclose( out_file ); } +#define BUFSIZE 1024 +void read_array( FILE* file, array_list_t *comp ) +{ + char buffer[BUFSIZE]; + char c; + int i; + wchar_t *wcs; + + while( !feof( file ) ) + { + i = 0; + while( i < BUFSIZE-1 ) + { + c = getc( file ); + if( c == '\n' || c == PAGER_EOT ) + { + break; + } + + buffer[ i++ ] = c; + } + buffer[ i ] = '\0'; + + wcs = str2wcs( buffer ); + if( wcs ) + { + al_push( comp, wcs ); + } + if( c == PAGER_EOT ) + { + break; + } + } +} + int main( int argc, char **argv ) { int i; @@ -979,8 +1028,6 @@ int main( int argc, char **argv ) array_list_t *comp; wchar_t *prefix; - init(); - if( argc < 3 ) { debug( 0, L"Insufficient arguments" ); @@ -994,19 +1041,29 @@ int main( int argc, char **argv ) debug( 3, L"prefix is '%ls'", prefix ); - for( i=3; i 3 ) + { + for( i=3; i0; i-- ) { diff --git a/proc.h b/proc.h index 7dbe02ad0..626188f57 100644 --- a/proc.h +++ b/proc.h @@ -45,6 +45,11 @@ enum The exec builtin */ INTERNAL_EXEC, + /** + A buffer + */ + INTERNAL_BUFFER, + } ; @@ -66,7 +71,7 @@ enum be the result of an exec command. The role of this process_t is determined by the type field, which can be one of EXTERNAL, INTERNAL_BUILTIN, INTERNAL_FUNCTION, INTERNAL_BLOCK and - INTERNAL_EXEC. + INTERNAL_EXEC, INTERNAL_BUFFER The process_t contains information on how the process should be started, such as command name and arguments, as well as runtime @@ -79,13 +84,13 @@ enum argument array and actual_cmd is the absolute path of the command to execute. - If the process is of type ITERNAL_BUILTIN, argv is the argument + If the process is of type INTERNAL_BUILTIN, argv is the argument vector, and argv[0] is the name of the builtin command. - If the process is of type ITERNAL_FUNCTION, argv is the argument + If the process is of type INTERNAL_FUNCTION, argv is the argument vector, and argv[0] is the name of the shellscript function. - If the process is of type ITERNAL_BLOCK, argv has exactly one + If the process is of type INTERNAL_BLOCK, argv has exactly one element, which is the block of commands to execute. */ @@ -93,8 +98,8 @@ typedef struct process { /** Type of process. Can be one of \c EXTERNAL, \c - INTERNAL_BUILTIN, \c INTERNAL_FUNCTION, \c INTERNAL_BLOCK or - INTERNAL_EXEC + INTERNAL_BUILTIN, \c INTERNAL_FUNCTION, \c INTERNAL_BLOCK, + INTERNAL_EXEC, or INTERNAL_BUFFER */ int type; /** argv parameter for for execv, builtin_run, etc. */ diff --git a/reader.c b/reader.c index 388d9b284..28e6d1849 100644 --- a/reader.c +++ b/reader.c @@ -1485,10 +1485,10 @@ static void run_pager( wchar_t *prefix, int is_quoted, array_list_t *comp ) for( i=0; iparam2.out_buffer, foo, strlen(foo) );