mirror of
https://github.com/fish-shell/fish-shell
synced 2024-12-25 20:33:08 +00:00
Fifth phase of using a real struct for passing around completions - make expand.c and wildcard.c use the struct internally. This makes all completion code use the new struct.
darcs-hash:20070224081131-ac50b-aba4ff255c6dc1ce9ad375d6cd1acde919c7cbd6.gz
This commit is contained in:
parent
6859e012d9
commit
73a67c2a43
3 changed files with 122 additions and 161 deletions
31
complete.c
31
complete.c
|
@ -245,7 +245,8 @@ void completion_allocate( array_list_t *context,
|
|||
{
|
||||
completion_t *res = halloc( context, sizeof( completion_t) );
|
||||
res->completion = halloc_wcsdup( context, comp );
|
||||
res->description = halloc_wcsdup( context, desc );
|
||||
if( desc )
|
||||
res->description = halloc_wcsdup( context, desc );
|
||||
res->flags = flags;
|
||||
al_push( context, res );
|
||||
}
|
||||
|
@ -1135,24 +1136,6 @@ const wchar_t *complete_get_desc( const wchar_t *filename )
|
|||
return (wchar_t *)get_desc_buff->buff;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
Convert all string completions in src into completion_t structs in
|
||||
dest. All source strings will be free'd.
|
||||
*/
|
||||
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 );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
Copy any strings in possible_comp which have the specified prefix
|
||||
to the list comp_out. The prefix may contain wildcards. The output
|
||||
|
@ -1180,10 +1163,6 @@ static void complete_strings( array_list_t *comp_out,
|
|||
{
|
||||
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);
|
||||
|
@ -1197,11 +1176,11 @@ static void complete_strings( array_list_t *comp_out,
|
|||
{
|
||||
wchar_t *next_str = (wchar_t *)al_get( possible_comp, i );
|
||||
if( next_str )
|
||||
wildcard_complete( next_str, wc, desc, desc_func, &lst );
|
||||
{
|
||||
wildcard_complete( next_str, wc, desc, desc_func, comp_out );
|
||||
}
|
||||
}
|
||||
|
||||
completion_convert_list( &lst, comp_out );
|
||||
al_destroy( &lst );
|
||||
free( wc );
|
||||
}
|
||||
|
||||
|
|
202
expand.c
202
expand.c
|
@ -85,7 +85,7 @@ parameter expansion.
|
|||
/**
|
||||
Description for short job. The job command is concatenated
|
||||
*/
|
||||
#define COMPLETE_JOB_DESC_VAL _( L"Job: ")
|
||||
#define COMPLETE_JOB_DESC_VAL _( L"Job: %ls")
|
||||
|
||||
/**
|
||||
Description for the shells own pid
|
||||
|
@ -329,14 +329,14 @@ static int match_pid( const wchar_t *cmd,
|
|||
Searches for a job with the specified job id, or a job or process
|
||||
which has the string \c proc as a prefix of its commandline.
|
||||
|
||||
If accept_incomplete is true, the remaining string for any matches
|
||||
If the ACCEPT_INCOMPLETE flag is set, the remaining string for any matches
|
||||
are inserted.
|
||||
|
||||
If accept_incomplete is false, any job matching the specified
|
||||
string is matched, and the job pgid is returned. If no job
|
||||
matches, all child processes are searched. If no child processes
|
||||
match, and <tt>fish</tt> can understand the contents of the /proc
|
||||
filesystem, all the users processes are searched for matches.
|
||||
Otherwise, any job matching the specified string is matched, and
|
||||
the job pgid is returned. If no job matches, all child processes
|
||||
are searched. If no child processes match, and <tt>fish</tt> can
|
||||
understand the contents of the /proc filesystem, all the users
|
||||
processes are searched for matches.
|
||||
*/
|
||||
|
||||
static int find_process( const wchar_t *proc,
|
||||
|
@ -372,14 +372,20 @@ static int find_process( const wchar_t *proc,
|
|||
|
||||
if( wcsncmp( proc, jid, wcslen(proc ) )==0 )
|
||||
{
|
||||
al_push( out,
|
||||
wcsdupcat2( jid+wcslen(proc),
|
||||
COMPLETE_SEP_STR,
|
||||
COMPLETE_JOB_DESC_VAL,
|
||||
j->command,
|
||||
(void *)0 ) );
|
||||
|
||||
string_buffer_t desc_buff;
|
||||
|
||||
sb_init( &desc_buff );
|
||||
|
||||
sb_printf( &desc_buff,
|
||||
COMPLETE_JOB_DESC_VAL,
|
||||
j->command );
|
||||
|
||||
completion_allocate( out,
|
||||
jid+wcslen(proc),
|
||||
(wchar_t *)desc_buff.buff,
|
||||
0 );
|
||||
|
||||
sb_destroy( &desc_buff );
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -422,11 +428,10 @@ static int find_process( const wchar_t *proc,
|
|||
{
|
||||
if( flags & ACCEPT_INCOMPLETE )
|
||||
{
|
||||
wchar_t *res = wcsdupcat2( j->command + offset + wcslen(proc),
|
||||
COMPLETE_SEP_STR,
|
||||
COMPLETE_JOB_DESC,
|
||||
(void *)0 );
|
||||
al_push( out, res );
|
||||
completion_allocate( out,
|
||||
j->command + offset + wcslen(proc),
|
||||
COMPLETE_JOB_DESC,
|
||||
0 );
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -459,11 +464,10 @@ static int find_process( const wchar_t *proc,
|
|||
{
|
||||
if( flags & ACCEPT_INCOMPLETE )
|
||||
{
|
||||
wchar_t *res = wcsdupcat2( p->actual_cmd + offset + wcslen(proc),
|
||||
COMPLETE_SEP_STR,
|
||||
COMPLETE_CHILD_PROCESS_DESC,
|
||||
(void *)0);
|
||||
al_push( out, res );
|
||||
completion_allocate( out,
|
||||
p->actual_cmd + offset + wcslen(proc),
|
||||
COMPLETE_CHILD_PROCESS_DESC,
|
||||
0 );
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -575,13 +579,10 @@ static int find_process( const wchar_t *proc,
|
|||
{
|
||||
if( flags & ACCEPT_INCOMPLETE )
|
||||
{
|
||||
wchar_t *res = wcsdupcat2( cmd + offset + wcslen(proc),
|
||||
COMPLETE_SEP_STR,
|
||||
COMPLETE_PROCESS_DESC,
|
||||
(void *)0);
|
||||
if( res )
|
||||
al_push( out, res );
|
||||
|
||||
completion_allocate( out,
|
||||
cmd + offset + wcslen(proc),
|
||||
COMPLETE_PROCESS_DESC,
|
||||
0 );
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -625,13 +626,17 @@ static int expand_pid( wchar_t *in,
|
|||
{
|
||||
if( wcsncmp( in+1, SELF_STR, wcslen(in+1) )==0 )
|
||||
{
|
||||
wchar_t *res = wcsdupcat2( SELF_STR+wcslen(in+1), COMPLETE_SEP_STR, COMPLETE_SELF_DESC, (void *)0 );
|
||||
al_push( out, res );
|
||||
completion_allocate( out,
|
||||
SELF_STR+wcslen(in+1),
|
||||
COMPLETE_SELF_DESC,
|
||||
0 );
|
||||
}
|
||||
else if( wcsncmp( in+1, LAST_STR, wcslen(in+1) )==0 )
|
||||
{
|
||||
wchar_t *res = wcsdupcat2( LAST_STR+wcslen(in+1), COMPLETE_SEP_STR, COMPLETE_LAST_DESC, (void *)0 );
|
||||
al_push( out, res );
|
||||
completion_allocate( out,
|
||||
LAST_STR+wcslen(in+1),
|
||||
COMPLETE_LAST_DESC,
|
||||
0 );
|
||||
}
|
||||
}
|
||||
else
|
||||
|
@ -1519,36 +1524,6 @@ static void remove_internal_separator( const void *s, int conv )
|
|||
*out=0;
|
||||
}
|
||||
|
||||
static void glorf( array_list_t *comp, int from )
|
||||
{
|
||||
int i;
|
||||
for( i=from; i<al_get_count( comp ); i++ )
|
||||
{
|
||||
wchar_t *next = (wchar_t *)al_get( comp, i );
|
||||
wchar_t *desc;
|
||||
void *item;
|
||||
int flags = 0;
|
||||
|
||||
|
||||
desc = wcschr( next, COMPLETE_SEP );
|
||||
|
||||
if( desc )
|
||||
{
|
||||
*desc = 0;
|
||||
desc++;
|
||||
}
|
||||
|
||||
if( ( wcslen(next) > 0 ) && ( wcschr( L"/=@:", next[wcslen(next)-1] ) != 0 ) )
|
||||
flags |= COMPLETE_NO_SPACE;
|
||||
|
||||
completion_allocate( comp, next, desc, flags );
|
||||
item = al_pop( comp );
|
||||
al_set( comp, i, item );
|
||||
free( next );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
The real expansion function. expand_one is just a wrapper around this one.
|
||||
|
@ -1566,8 +1541,6 @@ int expand_string( void *context,
|
|||
int res = EXPAND_OK;
|
||||
int start_count = al_get_count( end_out );
|
||||
|
||||
int end_out_count = al_get_count( end_out );
|
||||
|
||||
CHECK( str, EXPAND_ERROR );
|
||||
CHECK( end_out, EXPAND_ERROR );
|
||||
|
||||
|
@ -1712,7 +1685,9 @@ int expand_string( void *context,
|
|||
return EXPAND_OK;
|
||||
}
|
||||
else
|
||||
{
|
||||
al_push( out, next );
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -1745,57 +1720,75 @@ int expand_string( void *context,
|
|||
if( ((flags & ACCEPT_INCOMPLETE) && (!(flags & EXPAND_SKIP_WILDCARDS))) ||
|
||||
wildcard_has( next, 1 ) )
|
||||
{
|
||||
wchar_t *start, *rest;
|
||||
array_list_t *list = out;
|
||||
|
||||
if( next[0] == '/' )
|
||||
{
|
||||
wc_res = wildcard_expand( &next[1], L"/",flags, out );
|
||||
start = L"/";
|
||||
rest = &next[1];
|
||||
}
|
||||
else
|
||||
{
|
||||
wc_res = wildcard_expand( next, L"", flags, out );
|
||||
start = L"";
|
||||
rest = next;
|
||||
}
|
||||
free( next );
|
||||
switch( wc_res )
|
||||
|
||||
if( flags & ACCEPT_INCOMPLETE )
|
||||
{
|
||||
case 0:
|
||||
list = end_out;
|
||||
}
|
||||
|
||||
wc_res = wildcard_expand( rest, start, flags, list );
|
||||
|
||||
free( next );
|
||||
|
||||
if( !(flags & ACCEPT_INCOMPLETE) )
|
||||
{
|
||||
|
||||
switch( wc_res )
|
||||
{
|
||||
if( !(flags & ACCEPT_INCOMPLETE) )
|
||||
case 0:
|
||||
{
|
||||
if( res == EXPAND_OK )
|
||||
res = EXPAND_WILDCARD_NO_MATCH;
|
||||
if( !(flags & ACCEPT_INCOMPLETE) )
|
||||
{
|
||||
if( res == EXPAND_OK )
|
||||
res = EXPAND_WILDCARD_NO_MATCH;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
case 1:
|
||||
{
|
||||
int j;
|
||||
res = EXPAND_WILDCARD_MATCH;
|
||||
sort_list( out );
|
||||
|
||||
for( j=0; j<al_get_count( out ); j++ )
|
||||
{
|
||||
wchar_t *next = (wchar_t *)al_get( out, j );
|
||||
if( !next )
|
||||
{
|
||||
debug( 2, L"Got null string on line %d of file %s", __LINE__, __FILE__ );
|
||||
continue;
|
||||
}
|
||||
al_push( end_out, next );
|
||||
}
|
||||
al_truncate( out, 0 );
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
case 1:
|
||||
{
|
||||
int j;
|
||||
res = EXPAND_WILDCARD_MATCH;
|
||||
sort_list( out );
|
||||
|
||||
for( j=0; j<al_get_count( out ); j++ )
|
||||
case -1:
|
||||
{
|
||||
wchar_t *next = (wchar_t *)al_get( out, j );
|
||||
if( !next )
|
||||
{
|
||||
debug( 2, L"Got null string on line %d of file %s", __LINE__, __FILE__ );
|
||||
continue;
|
||||
}
|
||||
al_push( end_out, next );
|
||||
al_foreach( out, &free );
|
||||
al_destroy( in );
|
||||
al_destroy( out );
|
||||
return EXPAND_ERROR;
|
||||
}
|
||||
al_truncate( out, 0 );
|
||||
break;
|
||||
}
|
||||
|
||||
case -1:
|
||||
{
|
||||
al_foreach( out, &free );
|
||||
al_destroy( in );
|
||||
al_destroy( out );
|
||||
return EXPAND_ERROR;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -1808,6 +1801,7 @@ int expand_string( void *context,
|
|||
al_push( end_out, next );
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
al_destroy( in );
|
||||
al_destroy( out );
|
||||
|
@ -1821,12 +1815,6 @@ int expand_string( void *context,
|
|||
}
|
||||
}
|
||||
|
||||
if( flags & ACCEPT_INCOMPLETE)
|
||||
{
|
||||
glorf( end_out, end_out_count );
|
||||
}
|
||||
|
||||
|
||||
|
||||
return res;
|
||||
|
||||
|
|
50
wildcard.c
50
wildcard.c
|
@ -177,7 +177,9 @@ static int wildcard_complete_internal( const wchar_t *orig,
|
|||
if( *wc == 0 &&
|
||||
( ( *str != L'.') || (!is_first)) )
|
||||
{
|
||||
wchar_t *new;
|
||||
wchar_t *out_completion = 0;
|
||||
const wchar_t *out_desc = desc;
|
||||
|
||||
if( !out )
|
||||
{
|
||||
return 1;
|
||||
|
@ -190,14 +192,13 @@ static int wildcard_complete_internal( const wchar_t *orig,
|
|||
*/
|
||||
wchar_t *sep;
|
||||
|
||||
new = wcsdup( str );
|
||||
sep = wcschr(new, PROG_COMPLETE_SEP );
|
||||
*sep = COMPLETE_SEP;
|
||||
out_completion = wcsdup( str );
|
||||
sep = wcschr(out_completion, PROG_COMPLETE_SEP );
|
||||
*sep = 0;
|
||||
out_desc = sep + 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
const wchar_t *this_desc = desc;
|
||||
|
||||
if( desc_func )
|
||||
{
|
||||
/*
|
||||
|
@ -207,30 +208,25 @@ static int wildcard_complete_internal( const wchar_t *orig,
|
|||
*/
|
||||
const wchar_t *func_desc = desc_func( orig );
|
||||
if( func_desc )
|
||||
this_desc = func_desc;
|
||||
out_desc = func_desc;
|
||||
}
|
||||
|
||||
/*
|
||||
Append description to item, if a description exists
|
||||
*/
|
||||
if( this_desc && wcslen(this_desc) )
|
||||
{
|
||||
/*
|
||||
Check if the description already contains a separator character, if not, prepend it
|
||||
*/
|
||||
if( wcschr( this_desc, COMPLETE_SEP ) )
|
||||
new = wcsdupcat2( str, this_desc, (void *)0 );
|
||||
else
|
||||
new = wcsdupcat2( str, COMPLETE_SEP_STR, this_desc, (void *)0 );
|
||||
}
|
||||
else
|
||||
new = wcsdup( str );
|
||||
out_completion = wcsdup( str );
|
||||
}
|
||||
|
||||
if( new )
|
||||
if( out_completion )
|
||||
{
|
||||
al_push( out, new );
|
||||
completion_allocate( out,
|
||||
out_completion,
|
||||
out_desc,
|
||||
0 );
|
||||
}
|
||||
|
||||
free ( out_completion );
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
@ -336,11 +332,6 @@ static void get_desc( wchar_t *fn, string_buffer_t *sb, int is_cmd )
|
|||
|
||||
desc = complete_get_desc( fn );
|
||||
|
||||
if( wcschr( desc, COMPLETE_SEP )==0 )
|
||||
{
|
||||
sb_append( sb, COMPLETE_SEP_STR );
|
||||
}
|
||||
|
||||
if( sz >= 0 && S_ISDIR(buf.st_mode) )
|
||||
{
|
||||
sb_append( sb, desc );
|
||||
|
@ -527,8 +518,11 @@ int wildcard_expand( const wchar_t *wc,
|
|||
get_desc( long_name,
|
||||
&sb_desc,
|
||||
flags & EXECUTABLES_ONLY );
|
||||
al_push( out,
|
||||
wcsdupcat(name, (wchar_t *)sb_desc.buff) );
|
||||
completion_allocate( out,
|
||||
name,
|
||||
(wchar_t *)sb_desc.buff,
|
||||
0 );
|
||||
|
||||
}
|
||||
|
||||
free( long_name );
|
||||
|
|
Loading…
Reference in a new issue