mirror of
https://github.com/fish-shell/fish-shell.git
synced 2026-06-02 05:41:16 -03:00
Initial checkin of code for using case insensitive completion as a fallback for regular completion. Some types of completions don't yet support the feature.
darcs-hash:20070228214327-ac50b-9b5c69a1c3e0c11b560f8c61be0441d2ee9d6404.gz
This commit is contained in:
@@ -50,7 +50,8 @@ static void builtin_complete_add2( const wchar_t *cmd,
|
||||
int result_mode,
|
||||
const wchar_t *condition,
|
||||
const wchar_t *comp,
|
||||
const wchar_t *desc )
|
||||
const wchar_t *desc,
|
||||
int flags )
|
||||
{
|
||||
int i;
|
||||
const wchar_t *s;
|
||||
@@ -65,7 +66,8 @@ static void builtin_complete_add2( const wchar_t *cmd,
|
||||
result_mode,
|
||||
condition,
|
||||
comp,
|
||||
desc );
|
||||
desc,
|
||||
flags );
|
||||
}
|
||||
|
||||
for( i=0; i<al_get_count( gnu_opt ); i++ )
|
||||
@@ -78,7 +80,8 @@ static void builtin_complete_add2( const wchar_t *cmd,
|
||||
result_mode,
|
||||
condition,
|
||||
comp,
|
||||
desc );
|
||||
desc,
|
||||
flags );
|
||||
}
|
||||
|
||||
for( i=0; i<al_get_count( old_opt ); i++ )
|
||||
@@ -91,7 +94,8 @@ static void builtin_complete_add2( const wchar_t *cmd,
|
||||
result_mode,
|
||||
condition,
|
||||
comp,
|
||||
desc );
|
||||
desc,
|
||||
flags );
|
||||
}
|
||||
|
||||
if( al_get_count( old_opt )+al_get_count( gnu_opt )+wcslen(short_opt) == 0 )
|
||||
@@ -104,7 +108,8 @@ static void builtin_complete_add2( const wchar_t *cmd,
|
||||
result_mode,
|
||||
condition,
|
||||
comp,
|
||||
desc );
|
||||
desc,
|
||||
flags );
|
||||
}
|
||||
}
|
||||
|
||||
@@ -120,7 +125,8 @@ static void builtin_complete_add( array_list_t *cmd,
|
||||
int authorative,
|
||||
const wchar_t *condition,
|
||||
const wchar_t *comp,
|
||||
const wchar_t *desc )
|
||||
const wchar_t *desc,
|
||||
int flags )
|
||||
{
|
||||
int i;
|
||||
|
||||
@@ -134,7 +140,8 @@ static void builtin_complete_add( array_list_t *cmd,
|
||||
result_mode,
|
||||
condition,
|
||||
comp,
|
||||
desc );
|
||||
desc,
|
||||
flags );
|
||||
|
||||
if( authorative != -1 )
|
||||
{
|
||||
@@ -155,7 +162,8 @@ static void builtin_complete_add( array_list_t *cmd,
|
||||
result_mode,
|
||||
condition,
|
||||
comp,
|
||||
desc );
|
||||
desc,
|
||||
flags );
|
||||
|
||||
if( authorative != -1 )
|
||||
{
|
||||
@@ -287,6 +295,7 @@ static int builtin_complete( wchar_t **argv )
|
||||
int result_mode=SHARED;
|
||||
int remove = 0;
|
||||
int authorative = -1;
|
||||
int flags = COMPLETE_AUTO_SPACE;
|
||||
|
||||
string_buffer_t short_opt;
|
||||
array_list_t gnu_opt, old_opt;
|
||||
@@ -602,7 +611,8 @@ static int builtin_complete( wchar_t **argv )
|
||||
authorative,
|
||||
condition,
|
||||
comp,
|
||||
desc );
|
||||
desc,
|
||||
flags );
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
51
complete.c
51
complete.c
@@ -138,6 +138,8 @@ typedef struct complete_entry_opt
|
||||
int old_mode;
|
||||
/** Next option in the linked list */
|
||||
struct complete_entry_opt *next;
|
||||
/** Completion flags */
|
||||
int flags;
|
||||
}
|
||||
complete_entry_opt_t;
|
||||
|
||||
@@ -395,7 +397,8 @@ void complete_add( const wchar_t *cmd,
|
||||
int result_mode,
|
||||
const wchar_t *condition,
|
||||
const wchar_t *comp,
|
||||
const wchar_t *desc )
|
||||
const wchar_t *desc,
|
||||
int flags )
|
||||
{
|
||||
complete_entry_t *c;
|
||||
complete_entry_opt_t *opt;
|
||||
@@ -429,6 +432,7 @@ void complete_add( const wchar_t *cmd,
|
||||
opt->comp = comp?halloc_wcsdup(opt, comp):L"";
|
||||
opt->condition = condition?halloc_wcsdup(opt, condition):L"";
|
||||
opt->long_opt = long_opt?halloc_wcsdup(opt, long_opt):L"" ;
|
||||
opt->flags = flags;
|
||||
|
||||
if( desc && wcslen( desc ) )
|
||||
{
|
||||
@@ -1205,7 +1209,8 @@ static void complete_cmd( const wchar_t *cmd,
|
||||
static void complete_from_args( const wchar_t *str,
|
||||
const wchar_t *args,
|
||||
const wchar_t *desc,
|
||||
array_list_t *comp_out )
|
||||
array_list_t *comp_out,
|
||||
int flags )
|
||||
{
|
||||
|
||||
array_list_t possible_comp;
|
||||
@@ -1216,7 +1221,7 @@ static void complete_from_args( const wchar_t *str,
|
||||
eval_args( args, &possible_comp );
|
||||
proc_pop_interactive();
|
||||
|
||||
complete_strings( comp_out, str, desc, 0, &possible_comp, COMPLETE_AUTO_SPACE );
|
||||
complete_strings( comp_out, str, desc, 0, &possible_comp, flags );
|
||||
|
||||
al_foreach( &possible_comp, &free );
|
||||
al_destroy( &possible_comp );
|
||||
@@ -1384,7 +1389,7 @@ static int complete_param( const wchar_t *cmd_orig,
|
||||
{
|
||||
use_common &= ((o->result_mode & NO_COMMON )==0);
|
||||
use_files &= ((o->result_mode & NO_FILES )==0);
|
||||
complete_from_args( arg, o->comp, C_(o->desc), comp_out );
|
||||
complete_from_args( arg, o->comp, C_(o->desc), comp_out, o->flags );
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1407,7 +1412,7 @@ static int complete_param( const wchar_t *cmd_orig,
|
||||
old_style_match = 1;
|
||||
use_common &= ((o->result_mode & NO_COMMON )==0);
|
||||
use_files &= ((o->result_mode & NO_FILES )==0);
|
||||
complete_from_args( str, o->comp, C_(o->desc), comp_out );
|
||||
complete_from_args( str, o->comp, C_(o->desc), comp_out, o->flags );
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1433,7 +1438,7 @@ static int complete_param( const wchar_t *cmd_orig,
|
||||
{
|
||||
use_common &= ((o->result_mode & NO_COMMON )==0);
|
||||
use_files &= ((o->result_mode & NO_FILES )==0);
|
||||
complete_from_args( str, o->comp, C_(o->desc), comp_out );
|
||||
complete_from_args( str, o->comp, C_(o->desc), comp_out, o->flags );
|
||||
|
||||
}
|
||||
}
|
||||
@@ -1458,7 +1463,7 @@ static int complete_param( const wchar_t *cmd_orig,
|
||||
if( (o->short_opt == L'\0' ) && (o->long_opt[0]==L'\0'))
|
||||
{
|
||||
use_files &= ((o->result_mode & NO_FILES )==0);
|
||||
complete_from_args( str, o->comp, C_(o->desc), comp_out );
|
||||
complete_from_args( str, o->comp, C_(o->desc), comp_out, o->flags );
|
||||
}
|
||||
|
||||
if( wcslen(str) > 0 && use_switches )
|
||||
@@ -1483,19 +1488,38 @@ static int complete_param( const wchar_t *cmd_orig,
|
||||
*/
|
||||
if( o->long_opt[0] != L'\0' )
|
||||
{
|
||||
int match=0, match_no_case=0;
|
||||
|
||||
string_buffer_t *whole_opt = sb_halloc( context );
|
||||
sb_append2( whole_opt, o->old_mode?L"-":L"--", o->long_opt, (void *)0 );
|
||||
|
||||
if( wcsncmp( str, (wchar_t *)whole_opt->buff, wcslen(str) )==0)
|
||||
match = wcsncmp( str, (wchar_t *)whole_opt->buff, wcslen(str) )==0;
|
||||
|
||||
if( !match )
|
||||
{
|
||||
match_no_case = wcsncasecmp( str, (wchar_t *)whole_opt->buff, wcslen(str) )==0;
|
||||
}
|
||||
|
||||
if( match || match_no_case )
|
||||
{
|
||||
int has_arg=0; /* Does this switch have any known arguments */
|
||||
int req_arg=0; /* Does this switch _require_ an argument */
|
||||
|
||||
int offset = 0;
|
||||
int flags = 0;
|
||||
|
||||
|
||||
if( match )
|
||||
offset = wcslen( str );
|
||||
else
|
||||
flags = COMPLETE_NO_CASE;
|
||||
|
||||
has_arg = !!wcslen( o->comp );
|
||||
req_arg = (o->result_mode & NO_COMMON );
|
||||
|
||||
if( !o->old_mode && ( has_arg && !req_arg ) )
|
||||
{
|
||||
|
||||
/*
|
||||
Optional arguments to a switch can
|
||||
only be handled using the '=', so we
|
||||
@@ -1507,23 +1531,24 @@ static int complete_param( const wchar_t *cmd_orig,
|
||||
*/
|
||||
string_buffer_t completion;
|
||||
sb_init( &completion );
|
||||
|
||||
sb_printf( &completion,
|
||||
L"%ls=",
|
||||
((wchar_t *)whole_opt->buff)+wcslen(str) );
|
||||
((wchar_t *)whole_opt->buff)+offset );
|
||||
|
||||
completion_allocate( comp_out,
|
||||
(wchar_t *)completion.buff,
|
||||
C_(o->desc),
|
||||
0 );
|
||||
flags );
|
||||
|
||||
sb_destroy( &completion );
|
||||
|
||||
}
|
||||
|
||||
completion_allocate( comp_out,
|
||||
((wchar_t *)whole_opt->buff) + wcslen(str),
|
||||
((wchar_t *)whole_opt->buff) + offset,
|
||||
C_(o->desc),
|
||||
0 );
|
||||
|
||||
flags );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -75,8 +75,8 @@
|
||||
/**
|
||||
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()
|
||||
@@ -169,7 +169,8 @@ void complete_add( const wchar_t *cmd,
|
||||
int result_mode,
|
||||
const wchar_t *condition,
|
||||
const wchar_t *comp,
|
||||
const wchar_t *desc );
|
||||
const wchar_t *desc,
|
||||
int flags );
|
||||
/**
|
||||
Sets whether the completion list for this command is complete. If
|
||||
true, any options not matching one of the provided options will be
|
||||
|
||||
186
reader.c
186
reader.c
@@ -751,6 +751,19 @@ static int comp_len( const wchar_t *a, const wchar_t *b )
|
||||
return i;
|
||||
}
|
||||
|
||||
/**
|
||||
Calculate the case insensitive length of the common prefix substring of two strings.
|
||||
*/
|
||||
static int comp_ilen( const wchar_t *a, const wchar_t *b )
|
||||
{
|
||||
int i;
|
||||
for( i=0;
|
||||
a[i] != '\0' && b[i] != '\0' && towlower(a[i])==towlower(b[i]);
|
||||
i++ )
|
||||
;
|
||||
return i;
|
||||
}
|
||||
|
||||
/**
|
||||
Find the outermost quoting style of current token. Returns 0 if
|
||||
token is not quoted.
|
||||
@@ -887,11 +900,46 @@ static void get_param( wchar_t *cmd,
|
||||
just the common prefix of several completions. If the former, end by
|
||||
printing a space (and an end quote if the parameter is quoted).
|
||||
*/
|
||||
static void completion_insert( const wchar_t *val, int is_complete )
|
||||
static void completion_insert( const wchar_t *val, int flags )
|
||||
{
|
||||
wchar_t *replaced;
|
||||
|
||||
wchar_t quote;
|
||||
int add_space = !(flags & COMPLETE_NO_SPACE);
|
||||
int do_replace = (flags&COMPLETE_NO_CASE);
|
||||
|
||||
if( do_replace )
|
||||
{
|
||||
|
||||
int tok_start, tok_len;
|
||||
wchar_t *begin, *end;
|
||||
string_buffer_t sb;
|
||||
|
||||
parse_util_token_extent( data->buff, data->buff_pos, &begin, 0, 0, 0 );
|
||||
end = data->buff+data->buff_pos;
|
||||
|
||||
tok_start = begin - data->buff;
|
||||
tok_len = end-begin;
|
||||
|
||||
sb_init( &sb );
|
||||
sb_append_substring( &sb, data->buff, begin - data->buff );
|
||||
sb_append( &sb, val );
|
||||
if( add_space )
|
||||
{
|
||||
sb_append( &sb, L" " );
|
||||
}
|
||||
|
||||
sb_append( &sb, end );
|
||||
|
||||
reader_set_buffer( (wchar_t *)sb.buff, (begin-data->buff)+wcslen(val)+!!add_space );
|
||||
sb_destroy( &sb );
|
||||
|
||||
reader_super_highlight_me_plenty( data->buff_pos, 0 );
|
||||
repaint();
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
get_param( data->buff,
|
||||
data->buff_pos,
|
||||
@@ -944,7 +992,7 @@ static void completion_insert( const wchar_t *val, int is_complete )
|
||||
/*
|
||||
Print trailing space since this is the only completion
|
||||
*/
|
||||
if( is_complete )
|
||||
if( add_space )
|
||||
{
|
||||
|
||||
if( (quote) &&
|
||||
@@ -960,6 +1008,9 @@ static void completion_insert( const wchar_t *val, int is_complete )
|
||||
}
|
||||
|
||||
free(replaced);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1009,15 +1060,34 @@ static void run_pager( wchar_t *prefix, int is_quoted, array_list_t *comp )
|
||||
for( i=0; i<al_get_count( comp ); i++ )
|
||||
{
|
||||
|
||||
int base_len=-1;
|
||||
completion_t *el = (completion_t *)al_get( comp, i );
|
||||
|
||||
wchar_t *foo=0;
|
||||
wchar_t *baz=0;
|
||||
|
||||
if( el && el->completion )
|
||||
{
|
||||
if( el->flags & COMPLETE_NO_CASE )
|
||||
{
|
||||
if( base_len == -1 )
|
||||
{
|
||||
wchar_t *begin;
|
||||
|
||||
parse_util_token_extent( data->buff, data->buff_pos, &begin, 0, 0, 0 );
|
||||
base_len = data->buff_pos - (begin-data->buff);
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
foo = escape( el->completion + base_len, 1 );
|
||||
}
|
||||
else
|
||||
{
|
||||
foo = escape( el->completion, 1 );
|
||||
}
|
||||
}
|
||||
|
||||
if( el && el->description )
|
||||
{
|
||||
@@ -1135,40 +1205,119 @@ static void reader_flash()
|
||||
static int handle_completions( array_list_t *comp )
|
||||
{
|
||||
int i;
|
||||
void *context = 0;
|
||||
wchar_t *base = 0;
|
||||
int len = 0;
|
||||
int done = 0;
|
||||
int count = 0;
|
||||
int flags=0;
|
||||
|
||||
if( al_get_count( comp ) == 0 )
|
||||
{
|
||||
reader_flash();
|
||||
return 0;
|
||||
}
|
||||
else if( al_get_count( comp ) == 1 )
|
||||
|
||||
if( al_get_count( comp ) == 1 )
|
||||
{
|
||||
completion_t *c = (completion_t *)al_get( comp, 0 );
|
||||
completion_insert( c->completion,
|
||||
!(c->flags & COMPLETE_NO_SPACE) );
|
||||
c->flags );
|
||||
return 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
completion_t *c = (completion_t *)al_get( comp, 0 );
|
||||
wchar_t *base = wcsdup( c->completion );
|
||||
int len = wcslen( base );
|
||||
|
||||
for( i=1; i<al_get_count( comp ); i++ )
|
||||
context = halloc( 0, 0 );
|
||||
|
||||
for( i=0; i<al_get_count( comp ); i++ )
|
||||
{
|
||||
completion_t *c = (completion_t *)al_get( comp, i );
|
||||
int new_len = comp_len( base, c->completion );
|
||||
int new_len;
|
||||
|
||||
if( c->flags & COMPLETE_NO_CASE )
|
||||
continue;
|
||||
|
||||
count++;
|
||||
|
||||
if( base )
|
||||
{
|
||||
new_len = comp_len( base, c->completion );
|
||||
len = new_len < len ? new_len: len;
|
||||
}
|
||||
else
|
||||
{
|
||||
base = wcsdup( c->completion );
|
||||
len = wcslen( base );
|
||||
flags = c->flags;
|
||||
}
|
||||
}
|
||||
|
||||
if( len > 0 )
|
||||
{
|
||||
if( count > 1 )
|
||||
flags = flags | COMPLETE_NO_SPACE;
|
||||
|
||||
base[len]=L'\0';
|
||||
wchar_t *woot = wcschr( base, COMPLETE_SEP );
|
||||
if( woot != 0 )
|
||||
*woot = L'\0';
|
||||
completion_insert(base, 0);
|
||||
completion_insert(base, flags);
|
||||
done = 1;
|
||||
}
|
||||
|
||||
if( base == 0 )
|
||||
{
|
||||
wchar_t *begin, *end;
|
||||
|
||||
parse_util_token_extent( data->buff, data->buff_pos, &begin, 0, 0, 0 );
|
||||
|
||||
if( begin )
|
||||
{
|
||||
end = data->buff+data->buff_pos;
|
||||
wchar_t *tok = halloc_wcsndup( context, begin, end-begin );
|
||||
|
||||
if( expand_is_clean( tok ) )
|
||||
{
|
||||
int offset = wcslen( tok );
|
||||
|
||||
count = 0;
|
||||
|
||||
for( i=0; i<al_get_count( comp ); i++ )
|
||||
{
|
||||
completion_t *c = (completion_t *)al_get( comp, i );
|
||||
int new_len;
|
||||
|
||||
if( !(c->flags & COMPLETE_NO_CASE) )
|
||||
continue;
|
||||
|
||||
count++;
|
||||
|
||||
if( base )
|
||||
{
|
||||
new_len = offset + comp_ilen( base+offset, c->completion+offset );
|
||||
len = new_len < len ? new_len: len;
|
||||
}
|
||||
else
|
||||
{
|
||||
base = wcsdup( c->completion );
|
||||
len = wcslen( base );
|
||||
flags = c->flags;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
if( len > offset )
|
||||
{
|
||||
if( count > 1 )
|
||||
flags = flags | COMPLETE_NO_SPACE;
|
||||
|
||||
base[len]=L'\0';
|
||||
completion_insert( base, flags );
|
||||
done = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
free( base );
|
||||
|
||||
if( !done )
|
||||
{
|
||||
/*
|
||||
There is no common prefix in the completions, and show_list
|
||||
@@ -1225,9 +1374,12 @@ static int handle_completions( array_list_t *comp )
|
||||
|
||||
}
|
||||
|
||||
free( base );
|
||||
|
||||
halloc_free( context );
|
||||
|
||||
return len;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
16
wildcard.c
16
wildcard.c
@@ -288,6 +288,12 @@ static int wildcard_complete_internal( const wchar_t *orig,
|
||||
out_completion = wcsdup( str );
|
||||
}
|
||||
|
||||
if( flags & COMPLETE_NO_CASE )
|
||||
{
|
||||
free( out_completion );
|
||||
out_completion = wcsdup( orig );
|
||||
}
|
||||
|
||||
if( out_completion )
|
||||
{
|
||||
completion_allocate( out,
|
||||
@@ -329,6 +335,10 @@ static int wildcard_complete_internal( const wchar_t *orig,
|
||||
{
|
||||
return wildcard_complete_internal( orig, str+1, wc+1, 0, desc, desc_func, out, flags );
|
||||
}
|
||||
else if( towlower(*wc) == towlower(*str) )
|
||||
{
|
||||
return wildcard_complete_internal( orig, str+1, wc+1, 0, desc, desc_func, out, flags | COMPLETE_NO_CASE );
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -339,7 +349,11 @@ int wildcard_complete( const wchar_t *str,
|
||||
array_list_t *out,
|
||||
int flags )
|
||||
{
|
||||
return wildcard_complete_internal( str, str, wc, 1, desc, desc_func, out, flags );
|
||||
int res;
|
||||
|
||||
res = wildcard_complete_internal( str, str, wc, 1, desc, desc_func, out, flags );
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user