aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorGravatar stew <stew@vireo.org>2006-08-22 11:24:51 +1000
committerGravatar stew <stew@vireo.org>2006-08-22 11:24:51 +1000
commitdfe3dc142982cf8c7ca0b9041a91d04cc88a714a (patch)
treeb3e3ce70096c8915c0a492a8469ee9a1f0b05469
parent2ea00ce444d326d11ef64bff3c81636aff624855 (diff)
fish_pager_via_stdin
darcs-hash:20060822012451-2edb7-d8939fab708d8c605d2c7d0683c71f11db659bc9.gz
-rw-r--r--complete.h15
-rw-r--r--fish_pager.c85
-rw-r--r--proc.h17
-rw-r--r--reader.c4
4 files changed, 99 insertions, 22 deletions
diff --git a/complete.h b/complete.h
index ef507745..5abd4453 100644
--- a/complete.h
+++ b/complete.h
@@ -54,6 +54,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
descriptions on the same line.
@@ -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 ad64cdce..291a16eb 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<argc; i++ )
- {
- wchar_t *wcs = str2wcs( argv[i] );
- if( wcs )
+ if( argc > 3 )
+ {
+ for( i=3; i<argc; i++ )
{
- al_push( comp, wcs );
+ wchar_t *wcs = str2wcs( argv[i] );
+ if( wcs )
+ {
+ al_push( comp, wcs );
+ }
}
}
-
- mangle_descriptions( comp );
- if( wcscmp( prefix, L"-" ) == 0 )
- join_completions( comp );
- mangle_completions( comp, prefix );
+ else
+ {
+ read_array( stdin, comp );
+ }
+
+
+ init();
+
+ mangle_descriptions( comp );
+ if( wcscmp( prefix, L"-" ) == 0 )
+ join_completions( comp );
+ mangle_completions( comp, prefix );
for( i = 6; i>0; i-- )
{
diff --git a/proc.h b/proc.h
index 7dbe02ad..626188f5 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 388d9b28..28e6d184 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; i<al_get_count( comp); i++ )
{
- wchar_t *el = escape( (wchar_t*)al_get( comp, i ),1);
+ wchar_t *el = (wchar_t*)al_get( comp, i );
sb_printf( &msg, L"%ls\n", el );
- free(el);
}
+ sb_printf( &msg, PAGER_EOT_STR );
foo = wcs2str( (wchar_t *)msg.buff );
b_append( in->param2.out_buffer, foo, strlen(foo) );