aboutsummaryrefslogtreecommitdiffhomepage
path: root/complete.c
diff options
context:
space:
mode:
authorGravatar axel <axel@liljencrantz.se>2007-02-17 21:05:55 +1000
committerGravatar axel <axel@liljencrantz.se>2007-02-17 21:05:55 +1000
commit854c4aee9a9a3cc5f219dd05e2e691a2e0c8309e (patch)
tree35f69c87c1f4452dffe4fe97fb4d83edc0b38cd0 /complete.c
parent104ec963c2d267ef44edc6509f3269babc0addf1 (diff)
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
Diffstat (limited to 'complete.c')
-rw-r--r--complete.c184
1 files changed, 135 insertions, 49 deletions
diff --git a/complete.c b/complete.c
index c559b076..60864b73 100644
--- a/complete.c
+++ b/complete.c
@@ -58,12 +58,12 @@ These functions are used for storing and retrieving tab-completion data, as well
/**
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
*/
-#define COMPLETE_VAR_DESC_VAL _( L"Variable: " )
+#define COMPLETE_VAR_DESC_VAL _( L"Variable: %ls" )
/**
Description for generic executable
@@ -235,6 +235,45 @@ 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.
*/
static void complete_destroy()
@@ -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
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_cpy = wcsdup( cdpath?cdpath:L"." );
- int prev_count = al_get_count( comp );
if( (wcschr( cmd, L'/') != 0) || (cmd[0] == L'~' ) )
{
@@ -1361,10 +1446,11 @@ static void complete_cmd( const wchar_t *cmd,
if( expand_string( 0,
wcsdup(cmd),
- comp,
+ &tmp,
ACCEPT_INCOMPLETE | EXECUTABLES_ONLY ) != EXPAND_ERROR )
{
- complete_cmd_desc( cmd, comp );
+ complete_cmd_desc( cmd, &tmp );
+ completion_convert_list( &tmp, comp );
}
al_destroy( &tmp );
}
@@ -1399,10 +1485,8 @@ static void complete_cmd( const wchar_t *cmd,
ACCEPT_INCOMPLETE |
EXECUTABLES_ONLY ) != EXPAND_ERROR )
{
- for( i=0; i<al_get_count(&tmp); i++ )
- {
- al_push( comp, al_get( &tmp, i ) );
- }
+ complete_cmd_desc( cmd, &tmp );
+ completion_convert_list( &tmp, comp );
}
al_destroy( &tmp );
@@ -1410,10 +1494,6 @@ static void complete_cmd( const wchar_t *cmd,
}
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 )
{
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 );
@@ -1434,7 +1514,7 @@ static void complete_cmd( const wchar_t *cmd,
if( use_builtin )
{
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 );
@@ -1461,15 +1541,18 @@ static void complete_cmd( const wchar_t *cmd,
continue;
}
+ al_init( &tmp );
if( expand_string( 0,
nxt_completion,
- comp,
+ &tmp,
ACCEPT_INCOMPLETE | DIRECTORIES_ONLY ) != EXPAND_ERROR )
{
/*
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
*/
@@ -1916,20 +2000,21 @@ static int complete_variable( const wchar_t *var,
value_unescaped = env_get( name );
if( value_unescaped )
{
- wchar_t *desc;
+ string_buffer_t desc;
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 );
+
+ sb_init( &desc );
+ sb_printf( &desc, COMPLETE_VAR_DESC_VAL, value );
+
+ completion_allocate( comp,
+ &name[varlen],
+ (wchar_t *)desc.buff,
+ 0 );
+ res =1;
- if( desc )
- {
- res =1;
- al_push( comp, desc );
- }
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 )
{
- string_buffer_t sb;
- sb_init( &sb );
- sb_printf( &sb,
+ string_buffer_t desc;
+ string_buffer_t name;
+
+ sb_init( &name );
+ sb_printf( &name,
+ L"%ls/",
+ &pw_name[name_len] );
+
+ sb_init( &desc );
+ sb_printf( &desc,
COMPLETE_USER_DESC,
- &pw_name[name_len],
- COMPLETE_SEP,
pw->pw_gecos );
+
+ completion_allocate( comp,
+ (wchar_t *)name.buff,
+ (wchar_t *)desc.buff,
+ 0 );
- al_push( comp, (wchar_t *)sb.buff );
res=1;
+
+ sb_destroy( &desc );
+ sb_destroy( &name );
+
}
free( pw_name );
}
@@ -2069,18 +2167,6 @@ 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 )
{
@@ -2089,7 +2175,7 @@ static void glorf( array_list_t *comp )
{
wchar_t *next = (wchar_t *)al_get( comp, i );
wchar_t *desc;
- completion_t *item;
+ void *item;
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 ) )
flags |= COMPLETE_NO_SPACE;
- item = completion_allocate( comp, next, desc, flags );
- free( next );
+ completion_allocate( comp, next, desc, flags );
+ item = al_pop( comp );
al_set( comp, i, item );
+ free( next );
}
}
@@ -2369,9 +2456,9 @@ void complete( const wchar_t *cmd,
This function wants the unescaped string
*/
complete_param_expand( current_token, comp, do_file );
+ glorf( comp );
}
}
-
}
free( current_token );
@@ -2381,7 +2468,6 @@ void complete( const wchar_t *cmd,
condition_cache_clear();
- glorf( comp );
}