From 104ec963c2d267ef44edc6509f3269babc0addf1 Mon Sep 17 00:00:00 2001 From: axel Date: Fri, 9 Feb 2007 19:33:50 +1000 Subject: [PATCH] First phase of using a real struct for passing around completions - only use it on things returned by complete(), e.g. use it in the reader darcs-hash:20070209093350-ac50b-d91fe87be4612a56bff2139349cefa28a504cbb7.gz --- complete.c | 46 +++++++++++++++++++++ complete.h | 38 ++++++++++++++++++ reader.c | 114 ++++++++++++++++++++++++++++++++++++----------------- 3 files changed, 161 insertions(+), 37 deletions(-) diff --git a/complete.c b/complete.c index 9a0f728f1..c559b0766 100644 --- a/complete.c +++ b/complete.c @@ -2069,6 +2069,49 @@ static int try_complete_user( const wchar_t *cmd, return res; } +static completion_t *completion_allocate( void *context, + const wchar_t *comp, + const wchar_t *desc, + int flags ) +{ + completion_t *res = halloc( context, sizeof( completion_t) ); + res->completion = halloc_wcsdup( context, comp ); + res->description = halloc_wcsdup( context, desc ); + res->flags = flags; + return res; +} + + +static void glorf( array_list_t *comp ) +{ + int i; + for( i=0; i 0 ) && ( wcschr( L"/=@:", next[wcslen(next)-1] ) != 0 ) ) + flags |= COMPLETE_NO_SPACE; + + item = completion_allocate( comp, next, desc, flags ); + free( next ); + al_set( comp, i, item ); + + } +} + + void complete( const wchar_t *cmd, array_list_t *comp ) { @@ -2337,6 +2380,9 @@ void complete( const wchar_t *cmd, condition_cache_clear(); + + glorf( comp ); + } /** diff --git a/complete.h b/complete.h index e04d0e5ff..181e54b52 100644 --- a/complete.h +++ b/complete.h @@ -66,6 +66,44 @@ */ #define PROG_COMPLETE_SEP L'\t' +/** + Do not insert space afterwards if this is the only completion. (The + default is to try insert a space) +*/ +#define COMPLETE_NO_SPACE 1 + +/** + This compeltion is case insensitive +*/ + +#define COMPLETE_NO_CASE 2 +/** + This compeltion is the whole argument, not just the remainder. This + flag must never be set on completions returned from the complete() + function. It is strictly for internal use in the completion code. +*/ +#define COMPLETE_WHOLE_ARGUMENT 4 + +typedef struct +{ + /** + The completion string + */ + const wchar_t *completion; + /** + The description for this completion + */ + const wchar_t *description; + /** + Determines whether a spece should be inserted after this + compeltion if it is the only possible completion. Can be one of + COMPLETE_SPACE_YES, COMPLETE_SPACE_NO and COMPLETE_SPACE_AUTO. + */ + int flags; +} + completion_t; + + /** Add a completion. diff --git a/reader.c b/reader.c index 1a1886ac1..589109879 100644 --- a/reader.c +++ b/reader.c @@ -99,6 +99,8 @@ commence. #include "output.h" #include "signal.h" #include "screen.h" +#include "halloc.h" +#include "halloc_util.h" #include "parse_util.h" @@ -980,12 +982,18 @@ static void run_pager( wchar_t *prefix, int is_quoted, array_list_t *comp ) string_buffer_t msg; wchar_t * prefix_esc; char *foo; + io_data_t *in; + wchar_t *escaped_separator; if( !prefix || (wcslen(prefix)==0)) + { prefix_esc = wcsdup(L"\"\""); + } else + { prefix_esc = escape( prefix,1); - + } + sb_init( &cmd ); sb_init( &msg ); sb_printf( &cmd, @@ -996,15 +1004,53 @@ static void run_pager( wchar_t *prefix, int is_quoted, array_list_t *comp ) free( prefix_esc ); - io_data_t *in= io_buffer_create( 1 ); + in= io_buffer_create( 1 ); in->fd = 3; + + escaped_separator = escape( COMPLETE_SEP_STR, 1); - for( i=0; icompletion ) + { + foo = escape( el->completion, 1 ); + } + + if( el && el->description ) + { + baz = escape( el->description, 1 ); + } + + if( !foo ) + { + debug( 0, L"Run pager called with bad argument." ); + bugreport(); + show_stackframe(); + } + else if( baz ) + { + sb_printf( &msg, L"%ls%ls%ls\n", + foo, + escaped_separator, + baz ); + } + else + { + sb_printf( &msg, L"%ls\n", + foo ); + } + + free( foo ); + free( baz ); } + + free( escaped_separator ); foo = wcs2str( (wchar_t *)msg.buff ); b_append( in->param2.out_buffer, foo, strlen(foo) ); @@ -1100,24 +1146,21 @@ static int handle_completions( array_list_t *comp ) } else if( al_get_count( comp ) == 1 ) { - wchar_t *comp_str = wcsdup((wchar_t *)al_get( comp, 0 )); - wchar_t *woot = wcschr( comp_str, COMPLETE_SEP ); - if( woot != 0 ) - *woot = L'\0'; - completion_insert( comp_str, - ( wcslen(comp_str) == 0 ) || - ( wcschr( L"/=@:", - comp_str[wcslen(comp_str)-1] ) == 0 ) ); - free( comp_str ); + completion_t *c = (completion_t *)al_get( comp, 0 ); + completion_insert( c->completion, + !(c->flags & COMPLETE_NO_SPACE) ); return 1; } else { - wchar_t *base = wcsdup( (wchar_t *)al_get( comp, 0 ) ); + completion_t *c = (completion_t *)al_get( comp, 0 ); + wchar_t *base = wcsdup( c->completion ); int len = wcslen( base ); + for( i=1; icompletion ); len = new_len < len ? new_len: len; } if( len > 0 ) @@ -2049,7 +2092,7 @@ wchar_t *reader_readline() int i; int last_char=0, yank=0; wchar_t *yank_str; - array_list_t comp; + array_list_t *comp=0; int comp_empty=1; int finished=0; struct termios old_modes; @@ -2057,9 +2100,6 @@ wchar_t *reader_readline() check_size(); data->search_buff[0]=data->buff[data->buff_len]='\0'; - - al_init( &comp ); - s_reset( &data->screen ); exec_prompt(); @@ -2131,14 +2171,13 @@ wchar_t *reader_readline() if( c != 0 ) break; } - +/* if( (last_char == R_COMPLETE) && (c != R_COMPLETE) && (!comp_empty) ) { - al_foreach( &comp, &free ); - al_truncate( &comp, 0 ); - comp_empty = 1; + halloc_destroy( comp ); + comp = 0; } - +*/ if( last_char != R_YANK && last_char != R_YANK_POP ) yank=0; @@ -2233,7 +2272,7 @@ wchar_t *reader_readline() wchar_t *buffcpy; int len; int cursor_steps; - + parse_util_cmdsubst_extent( data->buff, data->buff_pos, &begin, &end ); parse_util_token_extent( begin, data->buff_pos - (begin-data->buff), &token_begin, &token_end, 0, 0 ); @@ -2250,19 +2289,17 @@ wchar_t *reader_readline() len = data->buff_pos - (begin-data->buff); buffcpy = wcsndup( begin, len ); - data->complete_func( buffcpy, &comp ); + comp = al_halloc( 0 ); + data->complete_func( buffcpy, comp ); - sort_list( &comp ); - remove_duplicates( &comp ); +// sort_list( comp ); +// remove_duplicates( comp ); free( buffcpy ); + comp_empty = handle_completions( comp ); - } - if( (comp_empty = - handle_completions( &comp ) ) ) - { - al_foreach( &comp, &free ); - al_truncate( &comp, 0 ); + halloc_free( comp ); + comp = 0; } break; @@ -2661,7 +2698,10 @@ wchar_t *reader_readline() } writestr( L"\n" ); - al_destroy( &comp ); +/* + if( comp ) + halloc_free( comp ); +*/ if( !reader_exit_forced() ) { if( tcsetattr(0,TCSANOW,&old_modes)) /* return to previous mode */