Second phase of using a real struct for passing around completions - make variable, user and command completion use the completion_t struct

darcs-hash:20070217110555-ac50b-8f08ade57885bc2ee17a07f5e789368e7dad9421.gz
This commit is contained in:
axel 2007-02-17 21:05:55 +10:00
parent 104ec963c2
commit 854c4aee9a

View file

@ -58,12 +58,12 @@ These functions are used for storing and retrieving tab-completion data, as well
/** /**
Description for ~USER completion Description for ~USER completion
*/ */
#define COMPLETE_USER_DESC _( L"%ls/%lcHome for %s" ) #define COMPLETE_USER_DESC _( L"Home for %s" )
/** /**
Description for short variables. The value is concatenated to this description Description for short variables. The value is concatenated to this description
*/ */
#define COMPLETE_VAR_DESC_VAL _( L"Variable: " ) #define COMPLETE_VAR_DESC_VAL _( L"Variable: %ls" )
/** /**
Description for generic executable Description for generic executable
@ -234,6 +234,45 @@ static void complete_free_entry( complete_entry_t *c );
static void clear_hash_entry( void *key, void *data ); static void clear_hash_entry( void *key, void *data );
/**
Create a new completion entry
*/
static void completion_allocate( array_list_t *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;
al_push( context, res );
}
static void completion_allocate2( array_list_t *context,
wchar_t *comp,
wchar_t sep )
{
completion_t *res = halloc( context, sizeof( completion_t) );
wchar_t *sep_pos = wcschr( comp, sep );
int flags = 0;
if( sep_pos )
{
*sep_pos = 0;
res->description = halloc_wcsdup( context, sep_pos+1 );
}
res->completion = halloc_wcsdup( context, comp );
if( ( wcslen(comp) > 0 ) && ( wcschr( L"/=@:", comp[wcslen(comp)-1] ) != 0 ) )
flags |= COMPLETE_NO_SPACE;
res->flags = flags;
al_push( context, res );
}
/** /**
Destroys various structures used for tab-completion and free()s the memory used by them. Destroys various structures used for tab-completion and free()s the memory used by them.
*/ */
@ -1141,6 +1180,53 @@ static void copy_strings_with_prefix( array_list_t *comp_out,
} }
static void completion_convert_list( array_list_t *src, array_list_t *dest )
{
int i;
for( i=0; i<al_get_count( src ); i++ )
{
wchar_t *next = (wchar_t *)al_get( src, i );
completion_allocate2( dest, next, COMPLETE_SEP );
free( next );
}
}
static void complete_strings( array_list_t *comp_out,
const wchar_t *wc_escaped,
const wchar_t *desc,
const wchar_t *(*desc_func)(const wchar_t *),
array_list_t *possible_comp )
{
int i;
wchar_t *wc, *tmp;
array_list_t lst;
al_init( &lst );
tmp = expand_one( 0,
wcsdup(wc_escaped), EXPAND_SKIP_CMDSUBST | EXPAND_SKIP_WILDCARDS);
if(!tmp)
return;
wc = parse_util_unescape_wildcards( tmp );
free(tmp);
for( i=0; i<al_get_count( possible_comp ); i++ )
{
wchar_t *next_str = (wchar_t *)al_get( possible_comp, i );
if( next_str )
wildcard_complete( next_str, wc, desc, desc_func, &lst );
}
completion_convert_list( &lst, comp_out );
al_destroy( &lst );
free( wc );
}
/** /**
If command to complete is short enough, substitute If command to complete is short enough, substitute
the description with the whatis information for the executable. the description with the whatis information for the executable.
@ -1348,7 +1434,6 @@ static void complete_cmd( const wchar_t *cmd,
wchar_t *cdpath = env_get(L"CDPATH"); wchar_t *cdpath = env_get(L"CDPATH");
wchar_t *cdpath_cpy = wcsdup( cdpath?cdpath:L"." ); wchar_t *cdpath_cpy = wcsdup( cdpath?cdpath:L"." );
int prev_count = al_get_count( comp );
if( (wcschr( cmd, L'/') != 0) || (cmd[0] == L'~' ) ) if( (wcschr( cmd, L'/') != 0) || (cmd[0] == L'~' ) )
{ {
@ -1361,10 +1446,11 @@ static void complete_cmd( const wchar_t *cmd,
if( expand_string( 0, if( expand_string( 0,
wcsdup(cmd), wcsdup(cmd),
comp, &tmp,
ACCEPT_INCOMPLETE | EXECUTABLES_ONLY ) != EXPAND_ERROR ) ACCEPT_INCOMPLETE | EXECUTABLES_ONLY ) != EXPAND_ERROR )
{ {
complete_cmd_desc( cmd, comp ); complete_cmd_desc( cmd, &tmp );
completion_convert_list( &tmp, comp );
} }
al_destroy( &tmp ); al_destroy( &tmp );
} }
@ -1399,10 +1485,8 @@ static void complete_cmd( const wchar_t *cmd,
ACCEPT_INCOMPLETE | ACCEPT_INCOMPLETE |
EXECUTABLES_ONLY ) != EXPAND_ERROR ) EXECUTABLES_ONLY ) != EXPAND_ERROR )
{ {
for( i=0; i<al_get_count(&tmp); i++ ) complete_cmd_desc( cmd, &tmp );
{ completion_convert_list( &tmp, comp );
al_push( comp, al_get( &tmp, i ) );
}
} }
al_destroy( &tmp ); al_destroy( &tmp );
@ -1410,10 +1494,6 @@ static void complete_cmd( const wchar_t *cmd,
} }
free( path_cpy ); free( path_cpy );
if( al_get_count( comp ) > prev_count )
{
complete_cmd_desc( cmd, comp );
}
} }
} }
@ -1426,7 +1506,7 @@ static void complete_cmd( const wchar_t *cmd,
if( use_function ) if( use_function )
{ {
function_get_names( &possible_comp, cmd[0] == L'_' ); function_get_names( &possible_comp, cmd[0] == L'_' );
copy_strings_with_prefix( comp, cmd, 0, &complete_function_desc, &possible_comp ); complete_strings( comp, cmd, 0, &complete_function_desc, &possible_comp );
} }
al_truncate( &possible_comp, 0 ); al_truncate( &possible_comp, 0 );
@ -1434,7 +1514,7 @@ static void complete_cmd( const wchar_t *cmd,
if( use_builtin ) if( use_builtin )
{ {
builtin_get_names( &possible_comp ); builtin_get_names( &possible_comp );
copy_strings_with_prefix( comp, cmd, 0, &builtin_get_desc, &possible_comp ); complete_strings( comp, cmd, 0, &builtin_get_desc, &possible_comp );
} }
al_destroy( &possible_comp ); al_destroy( &possible_comp );
@ -1461,15 +1541,18 @@ static void complete_cmd( const wchar_t *cmd,
continue; continue;
} }
al_init( &tmp );
if( expand_string( 0, if( expand_string( 0,
nxt_completion, nxt_completion,
comp, &tmp,
ACCEPT_INCOMPLETE | DIRECTORIES_ONLY ) != EXPAND_ERROR ) ACCEPT_INCOMPLETE | DIRECTORIES_ONLY ) != EXPAND_ERROR )
{ {
/* /*
Don't care if we fail - completions are just hints Don't care if we fail - completions are just hints
*/ */
completion_convert_list( &tmp, comp );
} }
al_destroy( &tmp );
} }
} }
} }
@ -1887,6 +1970,7 @@ static void complete_param_expand( wchar_t *str,
} }
/** /**
Complete the specified string as an environment variable Complete the specified string as an environment variable
*/ */
@ -1916,20 +2000,21 @@ static int complete_variable( const wchar_t *var,
value_unescaped = env_get( name ); value_unescaped = env_get( name );
if( value_unescaped ) if( value_unescaped )
{ {
wchar_t *desc; string_buffer_t desc;
value = expand_escape_variable( value_unescaped ); value = expand_escape_variable( value_unescaped );
/*
Variable description is 'Variable: VALUE
*/
desc = wcsdupcat2( &name[varlen], COMPLETE_SEP_STR, COMPLETE_VAR_DESC_VAL, value, (void *)0 );
if( desc ) sb_init( &desc );
{ sb_printf( &desc, COMPLETE_VAR_DESC_VAL, value );
res =1;
al_push( comp, desc ); completion_allocate( comp,
} &name[varlen],
(wchar_t *)desc.buff,
0 );
res =1;
free( value ); free( value );
sb_destroy( &desc );
} }
} }
@ -2047,16 +2132,29 @@ static int try_complete_user( const wchar_t *cmd,
{ {
if( wcsncmp( user_name, pw_name, name_len )==0 ) if( wcsncmp( user_name, pw_name, name_len )==0 )
{ {
string_buffer_t sb; string_buffer_t desc;
sb_init( &sb ); string_buffer_t name;
sb_printf( &sb,
sb_init( &name );
sb_printf( &name,
L"%ls/",
&pw_name[name_len] );
sb_init( &desc );
sb_printf( &desc,
COMPLETE_USER_DESC, COMPLETE_USER_DESC,
&pw_name[name_len],
COMPLETE_SEP,
pw->pw_gecos ); pw->pw_gecos );
al_push( comp, (wchar_t *)sb.buff ); completion_allocate( comp,
(wchar_t *)name.buff,
(wchar_t *)desc.buff,
0 );
res=1; res=1;
sb_destroy( &desc );
sb_destroy( &name );
} }
free( pw_name ); free( pw_name );
} }
@ -2069,18 +2167,6 @@ static int try_complete_user( const wchar_t *cmd,
return res; 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 ) static void glorf( array_list_t *comp )
{ {
@ -2089,7 +2175,7 @@ static void glorf( array_list_t *comp )
{ {
wchar_t *next = (wchar_t *)al_get( comp, i ); wchar_t *next = (wchar_t *)al_get( comp, i );
wchar_t *desc; wchar_t *desc;
completion_t *item; void *item;
int flags = 0; int flags = 0;
@ -2104,9 +2190,10 @@ static void glorf( array_list_t *comp )
if( ( wcslen(next) > 0 ) && ( wcschr( L"/=@:", next[wcslen(next)-1] ) != 0 ) ) if( ( wcslen(next) > 0 ) && ( wcschr( L"/=@:", next[wcslen(next)-1] ) != 0 ) )
flags |= COMPLETE_NO_SPACE; flags |= COMPLETE_NO_SPACE;
item = completion_allocate( comp, next, desc, flags ); completion_allocate( comp, next, desc, flags );
free( next ); item = al_pop( comp );
al_set( comp, i, item ); al_set( comp, i, item );
free( next );
} }
} }
@ -2369,9 +2456,9 @@ void complete( const wchar_t *cmd,
This function wants the unescaped string This function wants the unescaped string
*/ */
complete_param_expand( current_token, comp, do_file ); complete_param_expand( current_token, comp, do_file );
glorf( comp );
} }
} }
} }
free( current_token ); free( current_token );
@ -2381,7 +2468,6 @@ void complete( const wchar_t *cmd,
condition_cache_clear(); condition_cache_clear();
glorf( comp );
} }