Add canse insensitive tilde completion

darcs-hash:20080113193221-75c98-169804fe128001f73eaee6fab28bfb99dca7c93e.gz
This commit is contained in:
liljencrantz 2008-01-14 05:32:21 +10:00
parent c2b28063e1
commit f5540ff958
3 changed files with 153 additions and 62 deletions

View file

@ -58,7 +58,7 @@ These functions are used for storing and retrieving tab-completion data, as well
/**
Description for ~USER completion
*/
#define COMPLETE_USER_DESC _( L"Home for %s" )
#define COMPLETE_USER_DESC _( L"Home for %ls" )
/**
Description for short variables. The value is concatenated to this description
@ -1613,8 +1613,8 @@ static void complete_param_expand( wchar_t *str,
Complete the specified string as an environment variable
*/
static int complete_variable( const wchar_t *whole_var,
int start_offset,
array_list_t *comp_list )
int start_offset,
array_list_t *comp_list )
{
int i;
const wchar_t *var = &whole_var[start_offset];
@ -1797,25 +1797,41 @@ static int try_complete_user( const wchar_t *cmd,
if( wcsncmp( user_name, pw_name, name_len )==0 )
{
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->pw_gecos );
pw_name );
completion_allocate( comp,
(wchar_t *)name.buff,
(wchar_t *)desc.buff,
0 );
&pw_name[name_len],
(wchar_t *)desc.buff,
COMPLETE_NO_SPACE );
res=1;
sb_destroy( &desc );
}
else if( wcsncasecmp( user_name, pw_name, name_len )==0 )
{
string_buffer_t name;
string_buffer_t desc;
sb_init( &name );
sb_init( &desc );
sb_printf( &name,
L"~%ls",
pw_name );
sb_printf( &desc,
COMPLETE_USER_DESC,
pw_name );
completion_allocate( comp,
(wchar_t *)name.buff,
(wchar_t *)desc.buff,
COMPLETE_NO_CASE | COMPLETE_DONT_ESCAPE | COMPLETE_NO_SPACE );
res=1;
sb_destroy( &desc );
sb_destroy( &name );

View file

@ -94,6 +94,13 @@
*/
#define COMPLETE_AUTO_SPACE 8
/**
This completion should be inserted as-is, without escaping.
*/
#define COMPLETE_DONT_ESCAPE 16
typedef struct
{

158
reader.c
View file

@ -998,7 +998,10 @@ static void completion_insert( const wchar_t *val, int flags )
wchar_t quote;
int add_space = !(flags & COMPLETE_NO_SPACE);
int do_replace = (flags&COMPLETE_NO_CASE);
int do_replace = (flags & COMPLETE_NO_CASE);
int do_escape = !(flags & COMPLETE_DONT_ESCAPE);
// debug( 0, L"Insert completion %ls with flags %d", val, flags);
if( do_replace )
{
@ -1017,10 +1020,17 @@ static void completion_insert( const wchar_t *val, int flags )
sb_init( &sb );
sb_append_substring( &sb, data->buff, begin - data->buff );
escaped = escape( val, ESCAPE_ALL | ESCAPE_NO_QUOTED );
if( do_escape )
{
escaped = escape( val, ESCAPE_ALL | ESCAPE_NO_QUOTED );
sb_append( &sb, escaped );
free( escaped );
}
else
{
sb_append( &sb, val );
}
sb_append( &sb, escaped );
free( escaped );
if( add_space )
{
@ -1039,50 +1049,58 @@ static void completion_insert( const wchar_t *val, int flags )
else
{
get_param( data->buff,
if( do_escape )
{
get_param( data->buff,
data->buff_pos,
&quote,
0, 0, 0 );
if( quote == L'\0' )
{
replaced = escape( val, ESCAPE_ALL | ESCAPE_NO_QUOTED );
if( quote == L'\0' )
{
replaced = escape( val, ESCAPE_ALL | ESCAPE_NO_QUOTED );
}
else
{
int unescapable=0;
const wchar_t *pin;
wchar_t *pout;
replaced = pout =
malloc( sizeof(wchar_t)*(wcslen(val) + 1) );
for( pin=val; *pin; pin++ )
{
switch( *pin )
{
case L'\n':
case L'\t':
case L'\b':
case L'\r':
unescapable=1;
break;
default:
*pout++ = *pin;
break;
}
}
if( unescapable )
{
free( replaced );
wchar_t *tmp = escape( val, ESCAPE_ALL | ESCAPE_NO_QUOTED );
replaced = wcsdupcat( L" ", tmp );
free( tmp);
replaced[0]=quote;
}
else
*pout = 0;
}
}
else
{
int unescapable=0;
const wchar_t *pin;
wchar_t *pout;
replaced = pout =
malloc( sizeof(wchar_t)*(wcslen(val) + 1) );
for( pin=val; *pin; pin++ )
{
switch( *pin )
{
case L'\n':
case L'\t':
case L'\b':
case L'\r':
unescapable=1;
break;
default:
*pout++ = *pin;
break;
}
}
if( unescapable )
{
free( replaced );
wchar_t *tmp = escape( val, ESCAPE_ALL | ESCAPE_NO_QUOTED );
replaced = wcsdupcat( L" ", tmp );
free( tmp);
replaced[0]=quote;
}
else
*pout = 0;
replaced = wcsdup(val);
}
if( insert_str( replaced ) )
@ -1292,6 +1310,27 @@ static void reader_flash()
}
#define UNCLEAN L"$*?({})"
int reader_can_replace( const wchar_t *in )
{
const wchar_t * str = in;
CHECK( in, 1 );
/*
Test characters that have a special meaning in any character position
*/
while( *str )
{
if( wcschr( UNCLEAN, *str ) )
return 0;
str++;
}
return 1;
}
/**
Handle the list of completions. This means the following:
@ -1327,8 +1366,14 @@ static int handle_completions( array_list_t *comp )
context = halloc( 0, 0 );
tok = halloc_wcsndup( context, begin, end-begin );
/*
Check trivial cases
*/
switch( al_get_count( comp ) )
{
/*
No suitable completions found, flash screen and retur
*/
case 0:
{
reader_flash();
@ -1336,15 +1381,24 @@ static int handle_completions( array_list_t *comp )
break;
}
/*
Exactly one suitable completion found - insert it
*/
case 1:
{
completion_t *c = (completion_t *)al_get( comp, 0 );
if( !(c->flags & COMPLETE_NO_CASE) || expand_is_clean( tok ) )
/*
If this is a replacement completion, check
that we know how to replace it, e.g. that
the token doesn't contain evil operators
like {}
*/
if( !(c->flags & COMPLETE_NO_CASE) || reader_can_replace( tok ) )
{
completion_insert( c->completion,
c->flags );
c->flags );
}
done = 1;
len = 1;
@ -1355,12 +1409,17 @@ static int handle_completions( array_list_t *comp )
if( !done )
{
/*
Try to find something to insert whith the correct case
*/
for( i=0; i<al_get_count( comp ); i++ )
{
completion_t *c = (completion_t *)al_get( comp, i );
int new_len;
/*
Ignore case insensitive completions for now
*/
if( c->flags & COMPLETE_NO_CASE )
continue;
@ -1379,6 +1438,9 @@ static int handle_completions( array_list_t *comp )
}
}
/*
If we found something to insert, do it.
*/
if( len > 0 )
{
if( count > 1 )
@ -1391,13 +1453,17 @@ static int handle_completions( array_list_t *comp )
}
if( !done && base == 0 )
{
/*
Try to find something to insert ignoring case
*/
if( begin )
{
if( expand_is_clean( tok ) )
if( reader_can_replace( tok ) )
{
int offset = wcslen( tok );
@ -2603,9 +2669,11 @@ wchar_t *reader_readline()
comp = al_halloc( 0 );
data->complete_func( buffcpy, comp );
sort_completion_list( comp );
remove_duplicates( comp );
free( buffcpy );
comp_empty = handle_completions( comp );