mirror of
https://github.com/fish-shell/fish-shell.git
synced 2025-02-21 02:04:54 +08:00
Improve the status builtin
darcs-hash:20060130195310-ac50b-5da6881a847170242be56555646bbf037218d545.gz
This commit is contained in:
parent
f59e9baab9
commit
028e1f36a1
328
complete.c
328
complete.c
@ -141,7 +141,7 @@
|
||||
#define CC_FALSE L"false"
|
||||
|
||||
/**
|
||||
Struct describing a completion option entry.
|
||||
Struct describing a completion option entry.
|
||||
|
||||
If short_opt and long_opt are both zero, the comp field must not be
|
||||
empty and contains a list of arguments to the command.
|
||||
@ -149,7 +149,7 @@
|
||||
If either short_opt or long_opt are non-zero, they specify a switch
|
||||
for the command. If \c comp is also not empty, it contains a list
|
||||
of arguments that may only follow after the specified switch.
|
||||
|
||||
|
||||
*/
|
||||
typedef struct complete_entry_opt
|
||||
{
|
||||
@ -228,9 +228,9 @@ static void condition_cache_clear()
|
||||
if( condition_cache )
|
||||
{
|
||||
hash_destroy( condition_cache );
|
||||
free( condition_cache );
|
||||
free( condition_cache );
|
||||
condition_cache = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@ -242,38 +242,38 @@ static void condition_cache_clear()
|
||||
static int condition_test( const wchar_t *condition )
|
||||
{
|
||||
const void *test_res;
|
||||
|
||||
|
||||
if( !condition || !wcslen(condition) )
|
||||
{
|
||||
// fwprintf( stderr, L"No condition specified\n" );
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
if( !condition_cache )
|
||||
{
|
||||
condition_cache = malloc( sizeof( hash_table_t ) );
|
||||
if( !condition_cache )
|
||||
{
|
||||
die_mem();
|
||||
|
||||
|
||||
}
|
||||
|
||||
hash_init( condition_cache,
|
||||
|
||||
hash_init( condition_cache,
|
||||
&hash_wcs_func,
|
||||
&hash_wcs_cmp );
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
test_res = hash_get( condition_cache, condition );
|
||||
|
||||
|
||||
if (test_res == CC_NOT_TESTED )
|
||||
{
|
||||
test_res = exec_subshell( condition, 0 )?CC_FALSE:CC_TRUE;
|
||||
// debug( 1, L"Eval returns %ls for '%ls'", test_res, condition );
|
||||
// debug( 1, L"Eval returns %ls for '%ls'", test_res, condition );
|
||||
|
||||
hash_put( condition_cache, condition, test_res );
|
||||
|
||||
|
||||
/*
|
||||
Restore previous status information
|
||||
*/
|
||||
@ -281,13 +281,13 @@ static int condition_test( const wchar_t *condition )
|
||||
|
||||
if( test_res == CC_TRUE )
|
||||
{
|
||||
// debug( 1, L"Use conditional completion on condition %ls", condition );
|
||||
return 1;
|
||||
// debug( 1, L"Use conditional completion on condition %ls", condition );
|
||||
return 1;
|
||||
}
|
||||
|
||||
// debug( 1, L"Skip conditional completion on condition %ls", condition );
|
||||
return 0;
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
@ -341,15 +341,15 @@ void complete_destroy()
|
||||
complete_free_entry( prev );
|
||||
}
|
||||
first_entry = 0;
|
||||
|
||||
|
||||
if( suffix_hash )
|
||||
{
|
||||
hash_foreach( suffix_hash, &clear_hash_entry );
|
||||
hash_destroy( suffix_hash );
|
||||
free( suffix_hash );
|
||||
free( suffix_hash );
|
||||
suffix_hash=0;
|
||||
}
|
||||
|
||||
|
||||
if( loaded_completions )
|
||||
{
|
||||
hash_foreach( loaded_completions,
|
||||
@ -404,8 +404,8 @@ void complete_add( const wchar_t *cmd,
|
||||
{
|
||||
if( !(c = malloc( sizeof(complete_entry) )))
|
||||
die_mem();
|
||||
|
||||
|
||||
|
||||
|
||||
c->next = first_entry;
|
||||
first_entry = c;
|
||||
|
||||
@ -419,7 +419,7 @@ void complete_add( const wchar_t *cmd,
|
||||
/* wprintf( L"Add completion to option (short %lc, long %ls)\n", short_opt, long_opt );*/
|
||||
if( !(opt = malloc( sizeof( complete_entry_opt ) )))
|
||||
die_mem();
|
||||
|
||||
|
||||
opt->next = c->first_option;
|
||||
c->first_option = opt;
|
||||
c->authorative = authorative;
|
||||
@ -526,12 +526,12 @@ void complete_remove( const wchar_t *cmd,
|
||||
}
|
||||
else
|
||||
{
|
||||
eprev->next = e->next;
|
||||
eprev->next = e->next;
|
||||
}
|
||||
|
||||
|
||||
free( e->short_opt_str );
|
||||
free( e );
|
||||
e=0;
|
||||
e=0;
|
||||
}
|
||||
|
||||
}
|
||||
@ -615,12 +615,12 @@ int complete_is_valid_option( const wchar_t *str,
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
if( !(short_validated = malloc( wcslen( opt ) )))
|
||||
die_mem();
|
||||
|
||||
|
||||
memset( short_validated, 0, wcslen( opt ) );
|
||||
|
||||
hash_init( &gnu_match_hash,
|
||||
@ -899,7 +899,7 @@ static const wchar_t *complete_get_desc_suffix( const wchar_t *suff_orig )
|
||||
const wchar_t *complete_get_desc( const wchar_t *filename )
|
||||
{
|
||||
struct stat buf;
|
||||
|
||||
|
||||
if( !get_desc_buff )
|
||||
{
|
||||
get_desc_buff = malloc(sizeof(string_buffer_t) );
|
||||
@ -909,17 +909,17 @@ const wchar_t *complete_get_desc( const wchar_t *filename )
|
||||
{
|
||||
sb_clear( get_desc_buff );
|
||||
}
|
||||
|
||||
|
||||
if( lwstat( filename, &buf )==0)
|
||||
{
|
||||
{
|
||||
if( S_ISCHR(buf.st_mode) )
|
||||
{
|
||||
sb_printf( get_desc_buff, L"%lc%ls", COMPLETE_SEP, COMPLETE_CHAR_DESC );
|
||||
sb_printf( get_desc_buff, L"%lc%ls", COMPLETE_SEP, COMPLETE_CHAR_DESC );
|
||||
}
|
||||
else if( S_ISBLK(buf.st_mode) )
|
||||
sb_printf( get_desc_buff, L"%lc%ls", COMPLETE_SEP, COMPLETE_BLOCK_DESC );
|
||||
sb_printf( get_desc_buff, L"%lc%ls", COMPLETE_SEP, COMPLETE_BLOCK_DESC );
|
||||
else if( S_ISFIFO(buf.st_mode) )
|
||||
sb_printf( get_desc_buff, L"%lc%ls", COMPLETE_SEP, COMPLETE_FIFO_DESC );
|
||||
sb_printf( get_desc_buff, L"%lc%ls", COMPLETE_SEP, COMPLETE_FIFO_DESC );
|
||||
else if( S_ISLNK(buf.st_mode))
|
||||
{
|
||||
struct stat buf2;
|
||||
@ -931,7 +931,7 @@ const wchar_t *complete_get_desc( const wchar_t *filename )
|
||||
sb_printf( get_desc_buff, L"/%lc%ls", COMPLETE_SEP, COMPLETE_SYMLINK_DESC );
|
||||
}
|
||||
else if( waccess( filename, X_OK ) == 0 )
|
||||
sb_printf( get_desc_buff, L"%lc%ls", COMPLETE_SEP, COMPLETE_EXEC_LINK_DESC );
|
||||
sb_printf( get_desc_buff, L"%lc%ls", COMPLETE_SEP, COMPLETE_EXEC_LINK_DESC );
|
||||
else
|
||||
sb_printf( get_desc_buff, L"%lc%ls", COMPLETE_SEP, COMPLETE_SYMLINK_DESC );
|
||||
}
|
||||
@ -951,7 +951,7 @@ const wchar_t *complete_get_desc( const wchar_t *filename )
|
||||
{
|
||||
sb_printf( get_desc_buff, L"%lc%ls", COMPLETE_SEP, COMPLETE_LOOP_SYMLINK_DESC );
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
Some kind of broken symlink. We ignore it
|
||||
here, and it will get a 'file' description,
|
||||
@ -981,16 +981,16 @@ const wchar_t *complete_get_desc( const wchar_t *filename )
|
||||
sb_printf( get_desc_buff,
|
||||
L"%lc%ls",
|
||||
COMPLETE_SEP,
|
||||
complete_get_desc_suffix( suffix ) );
|
||||
complete_get_desc_suffix( suffix ) );
|
||||
}
|
||||
else
|
||||
{
|
||||
{
|
||||
sb_printf( get_desc_buff,
|
||||
L"%lc%ls",
|
||||
COMPLETE_SEP,
|
||||
L"%lc%ls",
|
||||
COMPLETE_SEP,
|
||||
COMPLETE_FILE_DESC );
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
return (wchar_t *)get_desc_buff->buff;
|
||||
@ -998,7 +998,7 @@ const wchar_t *complete_get_desc( const wchar_t *filename )
|
||||
|
||||
/**
|
||||
Copy any strings in possible_comp which have the specified prefix
|
||||
to the list comp_out. The prefix may contain wildcards.
|
||||
to the list comp_out. The prefix may contain wildcards.
|
||||
|
||||
There are three ways to specify descriptions for each
|
||||
completion. Firstly, if a description has already been added to the
|
||||
@ -1068,7 +1068,7 @@ static void complete_cmd_desc( const wchar_t *cmd, array_list_t *comp )
|
||||
cmd_start++;
|
||||
else
|
||||
cmd_start = cmd;
|
||||
|
||||
|
||||
cmd_len = wcslen(cmd_start);
|
||||
|
||||
/*
|
||||
@ -1083,9 +1083,9 @@ static void complete_cmd_desc( const wchar_t *cmd, array_list_t *comp )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
esc = expand_escape( cmd_start, 1 );
|
||||
|
||||
|
||||
esc = expand_escape( cmd_start, 1 );
|
||||
|
||||
if( whatis_path )
|
||||
{
|
||||
apropos_cmd =wcsdupcat2( L"grep ^/dev/null -F <", whatis_path, L" ", esc, 0 );
|
||||
@ -1094,8 +1094,8 @@ static void complete_cmd_desc( const wchar_t *cmd, array_list_t *comp )
|
||||
{
|
||||
apropos_cmd = wcsdupcat( L"apropos ^/dev/null ", esc );
|
||||
}
|
||||
free(esc);
|
||||
|
||||
free(esc);
|
||||
|
||||
al_init( &list );
|
||||
hash_init( &lookup, &hash_wcs_func, &hash_wcs_cmp );
|
||||
|
||||
@ -1111,23 +1111,23 @@ static void complete_cmd_desc( const wchar_t *cmd, array_list_t *comp )
|
||||
Then discard anything that is not a possible completion and put
|
||||
the result into a hashtable with the completion as key and the
|
||||
description as value.
|
||||
|
||||
|
||||
Should be reasonably fast, since no memory allocations are needed.
|
||||
*/
|
||||
for( i=0; i<al_get_count( &list); i++ )
|
||||
{
|
||||
wchar_t *el = (wchar_t *)al_get( &list, i );
|
||||
wchar_t *key, *key_end, *val_begin;
|
||||
|
||||
|
||||
if( !el )
|
||||
continue;
|
||||
|
||||
|
||||
//fwprintf( stderr, L"%ls\n", el );
|
||||
if( wcsncmp( el, cmd_start, cmd_len ) != 0 )
|
||||
continue;
|
||||
//fwprintf( stderr, L"%ls\n", el );
|
||||
key = el + cmd_len;
|
||||
|
||||
|
||||
key_end = wcschr( el, L' ' );
|
||||
if( !key_end )
|
||||
{
|
||||
@ -1137,71 +1137,71 @@ static void complete_cmd_desc( const wchar_t *cmd, array_list_t *comp )
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
*key_end = 0;
|
||||
val_begin=key_end+1;
|
||||
|
||||
|
||||
//fwprintf( stderr, L"Key %ls\n", el );
|
||||
|
||||
|
||||
while( *val_begin != L'-' && *val_begin)
|
||||
{
|
||||
val_begin++;
|
||||
}
|
||||
|
||||
|
||||
if( !*val_begin )
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
|
||||
val_begin++;
|
||||
|
||||
|
||||
while( *val_begin == L' ' || *val_begin == L'\t' )
|
||||
{
|
||||
val_begin++;
|
||||
}
|
||||
|
||||
|
||||
if( !*val_begin )
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
And once again I make sure the first character is uppercased
|
||||
because I like it that way, and I get to decide these
|
||||
things.
|
||||
*/
|
||||
val_begin[0]=towupper(val_begin[0]);
|
||||
hash_put( &lookup, key, val_begin );
|
||||
hash_put( &lookup, key, val_begin );
|
||||
}
|
||||
|
||||
/*
|
||||
Then do a lookup on every completion and if a match is found,
|
||||
change to the new description.
|
||||
|
||||
change to the new description.
|
||||
|
||||
This needs to do a reallocation for every description added, but
|
||||
there shouldn't be that many completions, so it should be ok.
|
||||
*/
|
||||
for( i=0; i<al_get_count(comp); i++ )
|
||||
{
|
||||
wchar_t *el = (wchar_t *)al_get( comp, i );
|
||||
wchar_t *cmd_end = wcschr( el,
|
||||
wchar_t *cmd_end = wcschr( el,
|
||||
COMPLETE_SEP );
|
||||
wchar_t *new_desc;
|
||||
|
||||
|
||||
if( cmd_end )
|
||||
*cmd_end = 0;
|
||||
|
||||
new_desc = (wchar_t *)hash_get( &lookup,
|
||||
el );
|
||||
|
||||
|
||||
if( new_desc )
|
||||
{
|
||||
wchar_t *new_el = wcsdupcat2( el,
|
||||
COMPLETE_SEP_STR,
|
||||
new_desc,
|
||||
new_desc,
|
||||
0 );
|
||||
al_set( comp, i, new_el );
|
||||
free( el );
|
||||
free( el );
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -1209,11 +1209,11 @@ static void complete_cmd_desc( const wchar_t *cmd, array_list_t *comp )
|
||||
*cmd_end = COMPLETE_SEP;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
hash_destroy( &lookup );
|
||||
al_foreach( &list,
|
||||
al_foreach( &list,
|
||||
(void(*)(const void *))&free );
|
||||
al_destroy( &list );
|
||||
al_destroy( &list );
|
||||
free( apropos_cmd );
|
||||
}
|
||||
|
||||
@ -1248,16 +1248,16 @@ static void complete_cmd( const wchar_t *cmd,
|
||||
int i;
|
||||
array_list_t tmp;
|
||||
wchar_t *nxt_completion;
|
||||
|
||||
|
||||
wchar_t *cdpath = env_get(L"CDPATH");
|
||||
wchar_t *cdpath_cpy = wcsdup( cdpath?cdpath:L"." );
|
||||
|
||||
|
||||
if( (wcschr( cmd, L'/') != 0) || (cmd[0] == L'~' ) )
|
||||
{
|
||||
array_list_t tmp;
|
||||
al_init( &tmp );
|
||||
|
||||
if( expand_string( wcsdup(cmd),
|
||||
|
||||
if( expand_string( wcsdup(cmd),
|
||||
comp,
|
||||
ACCEPT_INCOMPLETE | EXECUTABLES_ONLY ) != EXPAND_ERROR )
|
||||
{
|
||||
@ -1269,7 +1269,7 @@ static void complete_cmd( const wchar_t *cmd,
|
||||
{
|
||||
path = env_get(L"PATH");
|
||||
path_cpy = wcsdup( path );
|
||||
|
||||
|
||||
for( nxt_path = wcstok( path_cpy, ARRAY_SEP_STR, &state );
|
||||
nxt_path != 0;
|
||||
nxt_path = wcstok( 0, ARRAY_SEP_STR, &state) )
|
||||
@ -1280,12 +1280,12 @@ static void complete_cmd( const wchar_t *cmd,
|
||||
0 );
|
||||
if( ! nxt_completion )
|
||||
continue;
|
||||
|
||||
|
||||
al_init( &tmp );
|
||||
|
||||
if( expand_string( nxt_completion,
|
||||
&tmp,
|
||||
ACCEPT_INCOMPLETE |
|
||||
if( expand_string( nxt_completion,
|
||||
&tmp,
|
||||
ACCEPT_INCOMPLETE |
|
||||
EXECUTABLES_ONLY ) != EXPAND_ERROR )
|
||||
{
|
||||
for( i=0; i<al_get_count(&tmp); i++ )
|
||||
@ -1293,7 +1293,7 @@ static void complete_cmd( const wchar_t *cmd,
|
||||
al_push( comp, al_get( &tmp, i ) );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
al_destroy( &tmp );
|
||||
|
||||
}
|
||||
@ -1337,19 +1337,19 @@ static void complete_cmd( const wchar_t *cmd,
|
||||
|
||||
al_init( &tmp );
|
||||
|
||||
if( expand_string( nxt_completion,
|
||||
if( expand_string( nxt_completion,
|
||||
&tmp,
|
||||
ACCEPT_INCOMPLETE | DIRECTORIES_ONLY ) != EXPAND_ERROR )
|
||||
{
|
||||
|
||||
|
||||
for( i=0; i<al_get_count(&tmp); i++ )
|
||||
{
|
||||
wchar_t *nxt = (wchar_t *)al_get( &tmp, i );
|
||||
|
||||
|
||||
wchar_t *desc = wcsrchr( nxt, COMPLETE_SEP );
|
||||
if( desc )
|
||||
{
|
||||
int is_valid = desc && (wcscmp(desc+1,
|
||||
int is_valid = desc && (wcscmp(desc+1,
|
||||
COMPLETE_DIRECTORY_DESC)==0);
|
||||
if( is_valid )
|
||||
{
|
||||
@ -1376,7 +1376,7 @@ static void complete_cmd( const wchar_t *cmd,
|
||||
copy_strings_with_prefix, meaning the completion may contain
|
||||
wildcards. Logically, this is not always the right thing to do, but
|
||||
I have yet to come up with a case where this matters.
|
||||
|
||||
|
||||
\param str The string to complete.
|
||||
\param args The list of option arguments to be evaluated.
|
||||
\param desc Description of the completion
|
||||
@ -1388,16 +1388,16 @@ static void complete_from_args( const wchar_t *str,
|
||||
array_list_t *comp_out )
|
||||
{
|
||||
int was_interactive = is_interactive;
|
||||
|
||||
|
||||
array_list_t possible_comp;
|
||||
int i;
|
||||
|
||||
|
||||
al_init( &possible_comp );
|
||||
|
||||
is_interactive=0;
|
||||
eval_args( args, &possible_comp );
|
||||
is_interactive=was_interactive;
|
||||
|
||||
|
||||
/* We need to unescape these strings before matching them */
|
||||
for( i=0; i< al_get_count( &possible_comp ); i++ )
|
||||
{
|
||||
@ -1502,15 +1502,15 @@ static int short_ok( wchar_t *arg,
|
||||
return 1;
|
||||
}
|
||||
|
||||
void complete_load( wchar_t *cmd,
|
||||
void complete_load( wchar_t *cmd,
|
||||
int reload )
|
||||
{
|
||||
const wchar_t *path_var;
|
||||
const wchar_t *path_var;
|
||||
array_list_t path_list;
|
||||
int i;
|
||||
string_buffer_t path;
|
||||
time_t *tm;
|
||||
|
||||
|
||||
/*
|
||||
First check that the specified completion hasn't already been loaded
|
||||
*/
|
||||
@ -1534,7 +1534,7 @@ void complete_load( wchar_t *cmd,
|
||||
*/
|
||||
if( !reload && tm )
|
||||
return;
|
||||
|
||||
|
||||
/*
|
||||
Do we know where to look for completions?
|
||||
*/
|
||||
@ -1545,7 +1545,7 @@ void complete_load( wchar_t *cmd,
|
||||
al_init( &path_list );
|
||||
|
||||
sb_init( &path );
|
||||
|
||||
|
||||
expand_variable_array( path_var, &path_list );
|
||||
|
||||
/*
|
||||
@ -1553,18 +1553,18 @@ void complete_load( wchar_t *cmd,
|
||||
*/
|
||||
for( i=0; i<al_get_count( &path_list ); i++ )
|
||||
{
|
||||
struct stat buf;
|
||||
wchar_t *next = (wchar_t *)al_get( &path_list, i );
|
||||
struct stat buf;
|
||||
wchar_t *next = (wchar_t *)al_get( &path_list, i );
|
||||
sb_clear( &path );
|
||||
sb_append2( &path, next, L"/", cmd, L".fish", (void *)0 );
|
||||
if( (wstat( (wchar_t *)path.buff, &buf )== 0) &&
|
||||
if( (wstat( (wchar_t *)path.buff, &buf )== 0) &&
|
||||
(waccess( (wchar_t *)path.buff, R_OK ) == 0) )
|
||||
{
|
||||
if( !tm || (*tm != buf.st_mtime ) )
|
||||
{
|
||||
wchar_t *esc = expand_escape( (wchar_t *)path.buff, 1 );
|
||||
wchar_t *src_cmd = wcsdupcat( L". ", esc );
|
||||
|
||||
|
||||
if( !tm )
|
||||
{
|
||||
tm = malloc(sizeof(time_t));
|
||||
@ -1572,15 +1572,15 @@ void complete_load( wchar_t *cmd,
|
||||
die_mem();
|
||||
}
|
||||
|
||||
*tm = buf.st_mtime;
|
||||
*tm = buf.st_mtime;
|
||||
hash_put( loaded_completions,
|
||||
intern( cmd ),
|
||||
tm );
|
||||
|
||||
|
||||
free( esc );
|
||||
|
||||
|
||||
complete_remove( cmd, COMMAND, 0, 0 );
|
||||
|
||||
|
||||
/*
|
||||
Source the completion file for the specified completion
|
||||
*/
|
||||
@ -1588,7 +1588,7 @@ void complete_load( wchar_t *cmd,
|
||||
free(src_cmd);
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -1599,17 +1599,17 @@ void complete_load( wchar_t *cmd,
|
||||
*/
|
||||
if( !tm )
|
||||
{
|
||||
tm = malloc(sizeof(time_t));
|
||||
tm = malloc(sizeof(time_t));
|
||||
if( !tm )
|
||||
die_mem();
|
||||
|
||||
|
||||
*tm = 0;
|
||||
hash_put( loaded_completions, intern( cmd ), tm );
|
||||
}
|
||||
|
||||
sb_destroy( &path );
|
||||
al_foreach( &path_list, (void (*)(const void *))&free );
|
||||
|
||||
|
||||
al_destroy( &path_list );
|
||||
}
|
||||
|
||||
@ -1634,7 +1634,7 @@ static int complete_param( wchar_t *cmd_orig,
|
||||
parse_cmd_string( cmd_orig, &path, &cmd );
|
||||
|
||||
complete_load( cmd, 1 );
|
||||
|
||||
|
||||
al_init( &matches );
|
||||
|
||||
|
||||
@ -1657,7 +1657,7 @@ static int complete_param( wchar_t *cmd_orig,
|
||||
wchar_t *arg;
|
||||
if( (arg=param_match2( o, str ))!=0 && condition_test( o->condition ))
|
||||
{
|
||||
|
||||
|
||||
/* wprintf( L"Use option with desc %ls\n", o->desc ); */
|
||||
use_common &= ((o->result_mode & NO_COMMON )==0);
|
||||
use_files &= ((o->result_mode & NO_FILES )==0);
|
||||
@ -1706,13 +1706,13 @@ static int complete_param( wchar_t *cmd_orig,
|
||||
*/
|
||||
if( !o->old_mode && wcslen(o->long_opt) && !(o->result_mode & NO_COMMON) )
|
||||
continue;
|
||||
|
||||
|
||||
if( param_match( o, popt ) && condition_test( o->condition ))
|
||||
{
|
||||
use_common &= ((o->result_mode & NO_COMMON )==0);
|
||||
use_files &= ((o->result_mode & NO_FILES )==0);
|
||||
complete_from_args( str, o->comp, o->desc, comp_out );
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1727,15 +1727,15 @@ static int complete_param( wchar_t *cmd_orig,
|
||||
If this entry is for the base command,
|
||||
check if any of the arguments match
|
||||
*/
|
||||
|
||||
|
||||
if( !condition_test( o->condition ))
|
||||
continue;
|
||||
|
||||
|
||||
|
||||
if( (o->short_opt == L'\0' ) && (o->long_opt[0]==L'\0'))
|
||||
{
|
||||
use_files &= ((o->result_mode & NO_FILES )==0);
|
||||
// debug( 0, L"Running argument command %ls", o->comp );
|
||||
// debug( 0, L"Running argument command %ls", o->comp );
|
||||
complete_from_args( str, o->comp, o->desc, comp_out );
|
||||
}
|
||||
|
||||
@ -1751,10 +1751,10 @@ static int complete_param( wchar_t *cmd_orig,
|
||||
malloc( sizeof(wchar_t)*(3 + wcslen(o->desc)));
|
||||
if( !next_opt )
|
||||
die_mem();
|
||||
|
||||
|
||||
next_opt[0]=o->short_opt;
|
||||
next_opt[1]=COMPLETE_SEP;
|
||||
next_opt[2]=L'\0';
|
||||
next_opt[1]=COMPLETE_SEP;
|
||||
next_opt[2]=L'\0';
|
||||
wcscat( next_opt, o->desc );
|
||||
al_push( comp_out, next_opt );
|
||||
}
|
||||
@ -1767,9 +1767,9 @@ static int complete_param( wchar_t *cmd_orig,
|
||||
string_buffer_t whole_opt;
|
||||
sb_init( &whole_opt );
|
||||
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)
|
||||
{
|
||||
{
|
||||
/*
|
||||
If the option requires arguments, add
|
||||
option with an appended '=' . If the
|
||||
@ -1784,14 +1784,14 @@ static int complete_param( wchar_t *cmd_orig,
|
||||
wcsdupcat2(&((wchar_t *)whole_opt.buff)[wcslen(str)], COMPLETE_SEP_STR, o->desc, (void *)0) );
|
||||
// fwprintf( stderr, L"Add without param %ls\n", o->long_opt );
|
||||
}
|
||||
|
||||
|
||||
if( !o->old_mode && ( wcslen(o->comp) || (o->result_mode & NO_COMMON ) ) )
|
||||
{
|
||||
al_push( comp_out,
|
||||
wcsdupcat2(&((wchar_t *)whole_opt.buff)[wcslen(str)], L"=", COMPLETE_SEP_STR, o->desc, (void *)0) );
|
||||
// fwprintf( stderr, L"Add with param %ls\n", o->long_opt );
|
||||
}
|
||||
|
||||
|
||||
// fwprintf( stderr, L"Matching long option %ls\n", o->long_opt );
|
||||
}
|
||||
sb_destroy( &whole_opt );
|
||||
@ -1808,8 +1808,8 @@ static int complete_param( wchar_t *cmd_orig,
|
||||
/**
|
||||
Perform file completion on the specified string
|
||||
*/
|
||||
static void complete_param_expand( wchar_t *str,
|
||||
array_list_t *comp_out,
|
||||
static void complete_param_expand( wchar_t *str,
|
||||
array_list_t *comp_out,
|
||||
int do_file )
|
||||
{
|
||||
wchar_t *comp_str;
|
||||
@ -1819,19 +1819,19 @@ static void complete_param_expand( wchar_t *str,
|
||||
}
|
||||
else
|
||||
comp_str = str;
|
||||
|
||||
debug( 2,
|
||||
L"expand_string( \"%ls\", comp_out, EXPAND_SKIP_SUBSHELL | ACCEPT_INCOMPLETE | %ls );",
|
||||
comp_str,
|
||||
|
||||
debug( 2,
|
||||
L"expand_string( \"%ls\", comp_out, EXPAND_SKIP_SUBSHELL | ACCEPT_INCOMPLETE | %ls );",
|
||||
comp_str,
|
||||
do_file?L"0":L"EXPAND_SKIP_WILDCARDS" );
|
||||
|
||||
|
||||
expand_string( wcsdup(comp_str), comp_out, EXPAND_SKIP_SUBSHELL | ACCEPT_INCOMPLETE | (do_file?0:EXPAND_SKIP_WILDCARDS) );
|
||||
}
|
||||
|
||||
/**
|
||||
Complete the specified string as an environment variable
|
||||
*/
|
||||
static int complete_variable( const wchar_t *var,
|
||||
static int complete_variable( const wchar_t *var,
|
||||
array_list_t *comp )
|
||||
{
|
||||
int i;
|
||||
@ -1877,7 +1877,7 @@ static int complete_variable( const wchar_t *var,
|
||||
/**
|
||||
Search the specified string for the \$ sign, try to complete as an environment variable
|
||||
*/
|
||||
static int try_complete_variable( const wchar_t *cmd,
|
||||
static int try_complete_variable( const wchar_t *cmd,
|
||||
array_list_t *comp )
|
||||
{
|
||||
int len = wcslen( cmd );
|
||||
@ -1904,7 +1904,7 @@ static int try_complete_variable( const wchar_t *cmd,
|
||||
Try to complete the specified string as a username. This is used by ~USER type expansion.
|
||||
*/
|
||||
|
||||
static int try_complete_user( const wchar_t *cmd,
|
||||
static int try_complete_user( const wchar_t *cmd,
|
||||
array_list_t *comp )
|
||||
{
|
||||
const wchar_t *first_char=0;
|
||||
@ -1983,8 +1983,8 @@ static int try_complete_user( const wchar_t *cmd,
|
||||
{
|
||||
if( wcsncmp( user_name, pw_name, name_len )==0 )
|
||||
{
|
||||
wchar_t *blarg = wcsdupcat2( &pw_name[name_len],
|
||||
L"/",
|
||||
wchar_t *blarg = wcsdupcat2( &pw_name[name_len],
|
||||
L"/",
|
||||
COMPLETE_SEP_STR,
|
||||
COMPLETE_USER_DESC,
|
||||
0 );
|
||||
@ -2015,12 +2015,12 @@ void complete( const wchar_t *cmd,
|
||||
|
||||
int on_command=0;
|
||||
int pos;
|
||||
|
||||
|
||||
int old_error_max = error_max;
|
||||
int done=0;
|
||||
|
||||
int cursor_pos = wcslen(cmd );
|
||||
|
||||
|
||||
error_max=0;
|
||||
|
||||
/**
|
||||
@ -2031,11 +2031,11 @@ void complete( const wchar_t *cmd,
|
||||
if( try_complete_variable( cmd, comp ))
|
||||
{
|
||||
done=1;
|
||||
|
||||
|
||||
}
|
||||
else if( try_complete_user( cmd, comp ))
|
||||
{
|
||||
done=1;
|
||||
done=1;
|
||||
}
|
||||
|
||||
/*
|
||||
@ -2051,10 +2051,10 @@ void complete( const wchar_t *cmd,
|
||||
if( !begin )
|
||||
done=1;
|
||||
}
|
||||
|
||||
|
||||
if( !done )
|
||||
{
|
||||
|
||||
|
||||
pos = cursor_pos-(begin-cmd);
|
||||
|
||||
buff = wcsndup( begin, end-begin );
|
||||
@ -2062,14 +2062,14 @@ void complete( const wchar_t *cmd,
|
||||
if( !buff )
|
||||
done=1;
|
||||
}
|
||||
|
||||
|
||||
if( !done )
|
||||
{
|
||||
int had_cmd=0;
|
||||
int end_loop=0;
|
||||
|
||||
|
||||
tok_init( &tok, buff, TOK_ACCEPT_UNFINISHED );
|
||||
|
||||
|
||||
while( tok_has_next( &tok) && !end_loop )
|
||||
{
|
||||
switch( tok_last_type( &tok ) )
|
||||
@ -2079,31 +2079,31 @@ void complete( const wchar_t *cmd,
|
||||
{
|
||||
if( parser_is_subcommand( tok_last( &tok ) ) )
|
||||
break;
|
||||
|
||||
|
||||
current_command = wcsdup( tok_last( &tok ) );
|
||||
|
||||
|
||||
on_command = (pos <= tok_get_pos( &tok) + wcslen( tok_last( &tok ) ) );
|
||||
had_cmd=1;
|
||||
}
|
||||
break;
|
||||
|
||||
|
||||
case TOK_END:
|
||||
case TOK_PIPE:
|
||||
case TOK_BACKGROUND:
|
||||
had_cmd=0;
|
||||
break;
|
||||
|
||||
|
||||
|
||||
|
||||
case TOK_ERROR:
|
||||
end_loop=1;
|
||||
break;
|
||||
|
||||
|
||||
}
|
||||
if( tok_get_pos( &tok ) >= pos )
|
||||
end_loop=1;
|
||||
|
||||
|
||||
tok_next( &tok );
|
||||
|
||||
|
||||
}
|
||||
|
||||
tok_destroy( &tok );
|
||||
@ -2120,10 +2120,10 @@ void complete( const wchar_t *cmd,
|
||||
prev_token = prev_begin ? wcsndup( prev_begin, prev_end - prev_begin ): wcsdup(L"");
|
||||
|
||||
// fwprintf( stderr, L"on_command: %d, %ls %ls\n", on_command, current_compmand, current_token );
|
||||
|
||||
|
||||
if( current_token && current_command && prev_token )
|
||||
{
|
||||
|
||||
|
||||
if( on_command )
|
||||
{
|
||||
/* Complete command filename */
|
||||
@ -2164,11 +2164,11 @@ void complete( const wchar_t *cmd,
|
||||
non-null and longer than 0 characters.
|
||||
*/
|
||||
static void append_switch( string_buffer_t *out,
|
||||
const wchar_t *opt,
|
||||
const wchar_t *opt,
|
||||
const wchar_t *argument )
|
||||
{
|
||||
wchar_t *esc;
|
||||
|
||||
|
||||
if( !argument || argument==L"" )
|
||||
return;
|
||||
|
||||
@ -2180,7 +2180,7 @@ static void append_switch( string_buffer_t *out,
|
||||
void complete_print( string_buffer_t *out )
|
||||
{
|
||||
complete_entry *e;
|
||||
|
||||
|
||||
for( e = first_entry; e; e=e->next )
|
||||
{
|
||||
complete_entry_opt *o;
|
||||
@ -2198,11 +2198,11 @@ void complete_print( string_buffer_t *out )
|
||||
sb_printf( out,
|
||||
L"complete%ls",
|
||||
modestr[o->result_mode] );
|
||||
|
||||
|
||||
append_switch( out,
|
||||
e->cmd_type?L"path":L"command",
|
||||
e->cmd );
|
||||
|
||||
|
||||
|
||||
if( o->short_opt != 0 )
|
||||
{
|
||||
@ -2210,24 +2210,24 @@ void complete_print( string_buffer_t *out )
|
||||
L" --short-option '%lc'",
|
||||
o->short_opt );
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
append_switch( out,
|
||||
o->old_mode?L"old-option":L"long-option",
|
||||
o->long_opt );
|
||||
|
||||
|
||||
append_switch( out,
|
||||
L"description",
|
||||
o->desc );
|
||||
|
||||
|
||||
append_switch( out,
|
||||
L"arguments",
|
||||
o->comp );
|
||||
|
||||
|
||||
append_switch( out,
|
||||
L"condition",
|
||||
o->condition );
|
||||
|
||||
|
||||
sb_printf( out, L"\n" );
|
||||
}
|
||||
}
|
||||
|
256
reader.c
256
reader.c
@ -321,14 +321,14 @@ static void term_donate()
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
Grab control of terminal
|
||||
*/
|
||||
static void term_steal()
|
||||
{
|
||||
{
|
||||
|
||||
while( 1 )
|
||||
{
|
||||
@ -345,7 +345,7 @@ static void term_steal()
|
||||
break;
|
||||
}
|
||||
|
||||
common_handle_winch(0 );
|
||||
common_handle_winch(0 );
|
||||
|
||||
if( tcsetattr(0,TCSANOW,&old_modes))/* return to previous mode */
|
||||
{
|
||||
@ -431,7 +431,7 @@ static int check_size()
|
||||
data->new_color == 0 )
|
||||
{
|
||||
die_mem();
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
return 1;
|
||||
@ -510,7 +510,7 @@ static int calc_output()
|
||||
{
|
||||
data->output[0]=ellipsis_char;
|
||||
data->output[1]=0;
|
||||
|
||||
|
||||
}
|
||||
|
||||
wcsncat( data->output,
|
||||
@ -520,7 +520,7 @@ static int calc_output()
|
||||
if( offset_end<data->buff_len )
|
||||
{
|
||||
int l = wcslen(data->output);
|
||||
|
||||
|
||||
data->output[l]=ellipsis_char;
|
||||
data->output[l+1]=0;
|
||||
|
||||
@ -537,7 +537,7 @@ static int calc_output()
|
||||
|
||||
|
||||
/**
|
||||
Compare two completions, ignoring their description.
|
||||
Compare two completions, ignoring their description.
|
||||
*/
|
||||
static int fldcmp( wchar_t *a, wchar_t *b )
|
||||
{
|
||||
@ -606,7 +606,7 @@ void reader_write_title()
|
||||
wchar_t *title;
|
||||
array_list_t l;
|
||||
wchar_t *term = env_get( L"TERM" );
|
||||
|
||||
|
||||
/*
|
||||
This is a pretty lame heuristic for detecting terminals that do
|
||||
not support setting the title. If we recognise the terminal name
|
||||
@ -650,16 +650,16 @@ void reader_write_title()
|
||||
static int try_sequence( char *seq, wchar_t *str )
|
||||
{
|
||||
int i;
|
||||
|
||||
|
||||
for( i=0;; i++ )
|
||||
{
|
||||
if( !seq[i] )
|
||||
return i;
|
||||
|
||||
|
||||
if( seq[i] != str[i] )
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -672,11 +672,11 @@ static int calc_prompt_width( array_list_t *arr )
|
||||
{
|
||||
int res = 0;
|
||||
int i, j, k;
|
||||
|
||||
|
||||
for( i=0; i<al_get_count( arr ); i++ )
|
||||
{
|
||||
wchar_t *next = (wchar_t *)al_get( arr, i );
|
||||
|
||||
|
||||
for( j=0; next[j]; j++ )
|
||||
{
|
||||
if( next[j] == L'\e' )
|
||||
@ -687,11 +687,11 @@ static int calc_prompt_width( array_list_t *arr )
|
||||
int l;
|
||||
int len=0;
|
||||
int found = 0;
|
||||
|
||||
|
||||
/*
|
||||
Test these color escapes with parameter value 0..7
|
||||
*/
|
||||
char * esc[] =
|
||||
char * esc[] =
|
||||
{
|
||||
set_a_foreground,
|
||||
set_a_background,
|
||||
@ -714,12 +714,12 @@ static int calc_prompt_width( array_list_t *arr )
|
||||
flash_screen
|
||||
}
|
||||
;
|
||||
|
||||
|
||||
for( l=0; l < (sizeof(esc)/sizeof(char *)) && !found; l++ )
|
||||
{
|
||||
if( !esc[l] )
|
||||
continue;
|
||||
|
||||
|
||||
for( k=0; k<8; k++ )
|
||||
{
|
||||
len = try_sequence( tparm(esc[l],k), &next[j] );
|
||||
@ -729,9 +729,9 @@ static int calc_prompt_width( array_list_t *arr )
|
||||
found = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
for( l=0; l < (sizeof(esc2)/sizeof(char *)) && !found; l++ )
|
||||
{
|
||||
if( !esc2[l] )
|
||||
@ -743,7 +743,7 @@ static int calc_prompt_width( array_list_t *arr )
|
||||
*/
|
||||
len = maxi( try_sequence( tparm(esc2[l]), &next[j] ),
|
||||
try_sequence( esc2[l], &next[j] ));
|
||||
|
||||
|
||||
if( len )
|
||||
{
|
||||
j += (len-1);
|
||||
@ -751,14 +751,14 @@ static int calc_prompt_width( array_list_t *arr )
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
else
|
||||
{
|
||||
/*
|
||||
Ordinary decent character. Just add width.
|
||||
*/
|
||||
res += wcwidth( next[j] );
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
return res;
|
||||
@ -1152,10 +1152,10 @@ static int insert_str(wchar_t *str)
|
||||
else
|
||||
{
|
||||
int old_len = data->buff_len;
|
||||
|
||||
|
||||
data->buff_len += len;
|
||||
check_size();
|
||||
|
||||
|
||||
/* Insert space for extra characters at the right position */
|
||||
if( data->buff_pos < old_len )
|
||||
{
|
||||
@ -1168,17 +1168,17 @@ static int insert_str(wchar_t *str)
|
||||
data->buff[data->buff_len]='\0';
|
||||
|
||||
/* Syntax highlight */
|
||||
|
||||
|
||||
reader_super_highlight_me_plenty( data->buff,
|
||||
data->new_color,
|
||||
data->buff_pos-1,
|
||||
0 );
|
||||
memcpy( data->color, data->new_color, sizeof(int) * data->buff_len );
|
||||
|
||||
|
||||
/* repaint */
|
||||
|
||||
repaint();
|
||||
|
||||
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
@ -1409,49 +1409,49 @@ static void run_pager( wchar_t *prefix, int is_quoted, array_list_t *comp )
|
||||
prefix_esc = escape( prefix,1);
|
||||
|
||||
sb_init( &cmd );
|
||||
sb_printf( &cmd,
|
||||
L"fish_pager %d %ls",
|
||||
is_quoted,
|
||||
sb_printf( &cmd,
|
||||
L"fish_pager %d %ls",
|
||||
is_quoted,
|
||||
prefix_esc );
|
||||
|
||||
|
||||
free( prefix_esc );
|
||||
|
||||
|
||||
for( i=0; i<al_get_count( comp); i++ )
|
||||
{
|
||||
wchar_t *el = escape( (wchar_t*)al_get( comp, i ),1);
|
||||
wchar_t *el = escape( (wchar_t*)al_get( comp, i ),1);
|
||||
sb_printf( &cmd, L" %ls", el );
|
||||
free(el);
|
||||
}
|
||||
|
||||
term_donate();
|
||||
|
||||
|
||||
term_donate();
|
||||
|
||||
io_data_t *out = io_buffer_create();
|
||||
|
||||
|
||||
eval( (wchar_t *)cmd.buff, out, TOP);
|
||||
term_steal();
|
||||
term_steal();
|
||||
|
||||
io_buffer_read( out );
|
||||
|
||||
sb_destroy( &cmd );
|
||||
|
||||
|
||||
int nil=0;
|
||||
sb_destroy( &cmd );
|
||||
|
||||
|
||||
int nil=0;
|
||||
b_append( out->param2.out_buffer, &nil, 1 );
|
||||
|
||||
|
||||
wchar_t *tmp;
|
||||
wchar_t *str = str2wcs((char *)out->param2.out_buffer->buff);
|
||||
|
||||
|
||||
if( str )
|
||||
{
|
||||
for( tmp = str + wcslen(str)-1; tmp >= str; tmp-- )
|
||||
{
|
||||
input_unreadch( *tmp );
|
||||
}
|
||||
}
|
||||
free( str );
|
||||
}
|
||||
|
||||
|
||||
io_buffer_destroy( out);
|
||||
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
@ -1527,7 +1527,7 @@ static int handle_completions( array_list_t *comp )
|
||||
0 );
|
||||
|
||||
len = &data->buff[data->buff_pos]-prefix_start+1;
|
||||
|
||||
|
||||
if( len <= PREFIX_MAX_LEN )
|
||||
{
|
||||
prefix = malloc( sizeof(wchar_t)*(len+1) );
|
||||
@ -1542,11 +1542,11 @@ static int handle_completions( array_list_t *comp )
|
||||
0
|
||||
}
|
||||
;
|
||||
|
||||
|
||||
prefix = wcsdupcat( tmp,
|
||||
prefix_start + (len - PREFIX_MAX_LEN) );
|
||||
prefix[PREFIX_MAX_LEN] = 0;
|
||||
|
||||
|
||||
}
|
||||
|
||||
{
|
||||
@ -1559,7 +1559,7 @@ static int handle_completions( array_list_t *comp )
|
||||
writech(L'\n');
|
||||
|
||||
run_pager( prefix, is_quoted, comp );
|
||||
|
||||
|
||||
|
||||
/*
|
||||
Try to print a list of completions. First try with five
|
||||
@ -1638,8 +1638,8 @@ static void reader_interactive_init()
|
||||
history_init();
|
||||
|
||||
|
||||
common_handle_winch(0);
|
||||
|
||||
common_handle_winch(0);
|
||||
|
||||
tcgetattr(0,&shell_modes); /* get the current terminal modes */
|
||||
memcpy( &saved_modes,
|
||||
&shell_modes,
|
||||
@ -1744,7 +1744,7 @@ static void handle_history( const wchar_t *new_str )
|
||||
Check if the specified string is contained in the list, using
|
||||
wcscmp as a comparison function
|
||||
*/
|
||||
static int contains( const wchar_t *needle,
|
||||
static int contains( const wchar_t *needle,
|
||||
array_list_t *haystack )
|
||||
{
|
||||
int i;
|
||||
@ -1754,7 +1754,7 @@ static int contains( const wchar_t *needle,
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
@ -1771,7 +1771,7 @@ static void reset_token_history()
|
||||
}
|
||||
else
|
||||
data->search_buff[0]=0;
|
||||
|
||||
|
||||
data->token_history_pos = -1;
|
||||
data->search_pos=0;
|
||||
al_foreach( &data->search_prev, (void (*)(const void *))&free );
|
||||
@ -1798,7 +1798,7 @@ static void handle_token_history( int forward, int reset )
|
||||
Start a new token search using the current token
|
||||
*/
|
||||
reset_token_history();
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
@ -1851,13 +1851,13 @@ static void handle_token_history( int forward, int reset )
|
||||
}
|
||||
else
|
||||
{
|
||||
return;
|
||||
}
|
||||
return;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
debug( 3, L"new '%ls'", data->token_history_buff );
|
||||
debug( 3, L"new '%ls'", data->token_history_buff );
|
||||
|
||||
for( tok_init( &tok, data->token_history_buff, TOK_ACCEPT_UNFINISHED );
|
||||
tok_has_next( &tok);
|
||||
@ -1882,7 +1882,7 @@ static void handle_token_history( int forward, int reset )
|
||||
data->token_history_pos = tok_get_pos( &tok );
|
||||
str = wcsdup(tok_last( &tok ));
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1890,7 +1890,7 @@ static void handle_token_history( int forward, int reset )
|
||||
|
||||
tok_destroy( &tok );
|
||||
}
|
||||
|
||||
|
||||
if( str )
|
||||
{
|
||||
reader_replace_current_token( str );
|
||||
@ -1912,10 +1912,10 @@ static void handle_token_history( int forward, int reset )
|
||||
Move buffer position one word or erase one word. This function
|
||||
updates both the internal buffer and the screen. It is used by
|
||||
M-left, M-right and ^W to do block movement or block erase.
|
||||
|
||||
|
||||
\param dir Direction to move/erase. 0 means move left, 1 means move right.
|
||||
\param erase Whether to erase the characters along the way or only move past them.
|
||||
|
||||
|
||||
*/
|
||||
static void move_word( int dir, int erase )
|
||||
{
|
||||
@ -1952,7 +1952,7 @@ static void move_word( int dir, int erase )
|
||||
if( !dir )
|
||||
end_buff_pos -= step;
|
||||
mode++;
|
||||
}
|
||||
}
|
||||
break;
|
||||
/*
|
||||
case 2:
|
||||
@ -1985,9 +1985,9 @@ static void move_word( int dir, int erase )
|
||||
data->buff_len -= remove_count;
|
||||
data->buff_pos = first_char;
|
||||
data->buff[data->buff_len]=0;
|
||||
|
||||
|
||||
reader_super_highlight_me_plenty( data->buff, data->color, data->buff_pos, 0 );
|
||||
|
||||
|
||||
repaint();
|
||||
}
|
||||
else
|
||||
@ -2063,7 +2063,7 @@ int reader_get_cursor_pos()
|
||||
|
||||
void reader_run_command( wchar_t *cmd )
|
||||
{
|
||||
|
||||
|
||||
wchar_t *ft;
|
||||
|
||||
ft= tok_first( cmd );
|
||||
@ -2073,12 +2073,12 @@ void reader_run_command( wchar_t *cmd )
|
||||
free(ft);
|
||||
|
||||
reader_write_title();
|
||||
|
||||
|
||||
term_donate();
|
||||
|
||||
|
||||
eval( cmd, 0, TOP );
|
||||
job_reap( 1 );
|
||||
|
||||
|
||||
term_steal();
|
||||
|
||||
env_set( L"_", L"fish", ENV_GLOBAL );
|
||||
@ -2087,7 +2087,7 @@ void reader_run_command( wchar_t *cmd )
|
||||
proc_update_jiffies();
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
@ -2161,11 +2161,11 @@ void reader_pop()
|
||||
Clean up after history search
|
||||
*/
|
||||
al_foreach( &n->search_prev, (void (*)(const void *))&free );
|
||||
al_destroy( &n->search_prev );
|
||||
al_destroy( &n->search_prev );
|
||||
free( (void *)n->token_history_buff);
|
||||
|
||||
|
||||
free(n);
|
||||
|
||||
|
||||
if( data == 0 )
|
||||
{
|
||||
reader_interactive_destroy();
|
||||
@ -2271,9 +2271,9 @@ static int read_i()
|
||||
that we can handle a call to reader_set_buffer
|
||||
during evaluation.
|
||||
*/
|
||||
|
||||
|
||||
tmp = wcsdup( reader_readline() );
|
||||
|
||||
|
||||
data->buff_pos=data->buff_len=0;
|
||||
data->buff[data->buff_len]=L'\0';
|
||||
reader_run_command( tmp );
|
||||
@ -2308,7 +2308,7 @@ static int can_read( int fd )
|
||||
{
|
||||
struct timeval can_read_timeout = { 0, 0 };
|
||||
fd_set fds;
|
||||
|
||||
|
||||
FD_ZERO(&fds);
|
||||
FD_SET(fd, &fds);
|
||||
return select(fd + 1, &fds, 0, 0, &can_read_timeout) == 1;
|
||||
@ -2378,13 +2378,13 @@ wchar_t *reader_readline()
|
||||
|
||||
wchar_t arr[READAHEAD_MAX+1];
|
||||
int i;
|
||||
|
||||
|
||||
memset( arr, 0, sizeof( arr ) );
|
||||
arr[0] = c;
|
||||
|
||||
|
||||
for( i=1; i<READAHEAD_MAX; i++ )
|
||||
{
|
||||
|
||||
|
||||
if( !can_read( 0 ) )
|
||||
{
|
||||
c = 0;
|
||||
@ -2399,12 +2399,12 @@ wchar_t *reader_readline()
|
||||
else
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
insert_str( arr );
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if( c != 0 )
|
||||
break;
|
||||
}
|
||||
@ -2448,11 +2448,11 @@ wchar_t *reader_readline()
|
||||
repaint();
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
/* complete */
|
||||
case R_COMPLETE:
|
||||
{
|
||||
|
||||
|
||||
// fwprintf( stderr, L"aaa\n" );
|
||||
if( !data->complete_func )
|
||||
break;
|
||||
@ -2509,10 +2509,10 @@ wchar_t *reader_readline()
|
||||
wchar_t *str = wcsndup( data->buff, data->buff_pos );
|
||||
if( !str )
|
||||
die_mem();
|
||||
|
||||
|
||||
kill_add( str );
|
||||
free( str );
|
||||
|
||||
|
||||
data->buff_len = wcslen(data->buff +data->buff_pos);
|
||||
memmove( data->buff, data->buff +data->buff_pos, sizeof(wchar_t)*data->buff_len );
|
||||
data->buff[data->buff_len]=L'\0';
|
||||
@ -2544,7 +2544,7 @@ wchar_t *reader_readline()
|
||||
// wcscpy(data->search_buff,data->buff);
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
/* rotate killring*/
|
||||
case R_YANK_POP:
|
||||
{
|
||||
@ -2559,16 +2559,16 @@ wchar_t *reader_readline()
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
/* Escape was pressed */
|
||||
case L'\e':
|
||||
{
|
||||
if( *data->search_buff )
|
||||
{
|
||||
if( data->token_history_pos==-1 )
|
||||
{
|
||||
{
|
||||
history_reset();
|
||||
reader_set_buffer( data->search_buff,
|
||||
reader_set_buffer( data->search_buff,
|
||||
wcslen(data->search_buff ) );
|
||||
}
|
||||
else
|
||||
@ -2577,26 +2577,26 @@ wchar_t *reader_readline()
|
||||
}
|
||||
*data->search_buff=0;
|
||||
check_colors();
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
/* delete backward*/
|
||||
case R_BACKWARD_DELETE_CHAR:
|
||||
{
|
||||
remove_backward();
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
/* delete forward*/
|
||||
case R_DELETE_CHAR:
|
||||
{
|
||||
remove_forward();
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
/* exit, but only if line is empty */
|
||||
case R_EXIT:
|
||||
{
|
||||
@ -2607,7 +2607,7 @@ wchar_t *reader_readline()
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
/* Newline, evaluate*/
|
||||
case L'\n':
|
||||
{
|
||||
@ -2633,7 +2633,7 @@ wchar_t *reader_readline()
|
||||
writech('\n');
|
||||
repaint();
|
||||
}
|
||||
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
@ -2650,7 +2650,7 @@ wchar_t *reader_readline()
|
||||
handle_history(history_prev_match(data->search_buff));
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
/* History down */
|
||||
case R_HISTORY_SEARCH_FORWARD:
|
||||
{
|
||||
@ -2664,7 +2664,7 @@ wchar_t *reader_readline()
|
||||
handle_history(history_next_match(data->search_buff));
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
/* Token search for a earlier match */
|
||||
case R_HISTORY_TOKEN_SEARCH_BACKWARD:
|
||||
{
|
||||
@ -2697,7 +2697,7 @@ wchar_t *reader_readline()
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* Move left*/
|
||||
case R_BACKWARD_CHAR:
|
||||
if( data->buff_pos > 0 )
|
||||
@ -2735,7 +2735,7 @@ wchar_t *reader_readline()
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
case R_DELETE_LINE:
|
||||
{
|
||||
data->buff[0]=0;
|
||||
@ -2744,35 +2744,35 @@ wchar_t *reader_readline()
|
||||
repaint();
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
/* kill one word left */
|
||||
case R_BACKWARD_KILL_WORD:
|
||||
{
|
||||
move_word(0,1);
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
/* kill one word right */
|
||||
case R_KILL_WORD:
|
||||
{
|
||||
move_word(1,1);
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
/* move one word left*/
|
||||
case R_BACKWARD_WORD:
|
||||
{
|
||||
move_word(0,0);
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
/* move one word right*/
|
||||
case R_FORWARD_WORD:
|
||||
{
|
||||
move_word( 1,0);
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
case R_CLEAR_SCREEN:
|
||||
{
|
||||
writembs( clear_screen );
|
||||
@ -2813,7 +2813,7 @@ wchar_t *reader_readline()
|
||||
data->search_buff[0]=0;
|
||||
history_reset();
|
||||
data->token_history_pos=-1;
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
@ -2845,21 +2845,21 @@ static int read_ni( int fd )
|
||||
|
||||
int des = fd == 0 ? dup(0) : fd;
|
||||
int res=0;
|
||||
|
||||
|
||||
if (des == -1)
|
||||
{
|
||||
wperror( L"dup" );
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
b_init( &acc );
|
||||
|
||||
|
||||
in_stream = fdopen( des, "r" );
|
||||
if( in_stream != 0 )
|
||||
{
|
||||
wchar_t *str;
|
||||
int acc_used;
|
||||
|
||||
|
||||
while(!feof( in_stream ))
|
||||
{
|
||||
char buff[4096];
|
||||
@ -2868,7 +2868,7 @@ static int read_ni( int fd )
|
||||
c = fread(buff, 1, 4096, in_stream);
|
||||
if( ferror( in_stream ) )
|
||||
{
|
||||
debug( 1,
|
||||
debug( 1,
|
||||
_( L"Error while reading commands" ) );
|
||||
|
||||
/*
|
||||
@ -2877,7 +2877,7 @@ static int read_ni( int fd )
|
||||
acc.used=0;
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
b_append( &acc, buff, c );
|
||||
}
|
||||
b_append( &acc, "\0", 1 );
|
||||
@ -2887,16 +2887,16 @@ static int read_ni( int fd )
|
||||
|
||||
if( fclose( in_stream ))
|
||||
{
|
||||
debug( 1,
|
||||
debug( 1,
|
||||
_( L"Error while closing input stream" ) );
|
||||
wperror( L"fclose" );
|
||||
res = 1;
|
||||
}
|
||||
|
||||
|
||||
// fwprintf( stderr, L"Woot is %d chars\n", wcslen( acc.buff ) );
|
||||
|
||||
|
||||
if( str )
|
||||
{
|
||||
{
|
||||
if( !parser_test( str, 1 ) )
|
||||
{
|
||||
//fwprintf( stderr, L"We parse it\n" );
|
||||
@ -2916,21 +2916,21 @@ static int read_ni( int fd )
|
||||
if( acc_used > 1 )
|
||||
{
|
||||
debug( 1,
|
||||
_( L"Could not convert input. Read %d bytes." ),
|
||||
_( L"Could not convert input. Read %d bytes." ),
|
||||
acc_used-1 );
|
||||
}
|
||||
else
|
||||
{
|
||||
debug( 1,
|
||||
debug( 1,
|
||||
_( L"Could not read input stream" ) );
|
||||
}
|
||||
res=1;
|
||||
}
|
||||
res=1;
|
||||
}
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
debug( 1,
|
||||
debug( 1,
|
||||
_( L"Error while opening input stream" ) );
|
||||
wperror( L"fdopen" );
|
||||
free( buff );
|
||||
@ -2949,18 +2949,18 @@ int reader_read( int fd )
|
||||
original state. We also update the signal handlers.
|
||||
*/
|
||||
int shell_was_interactive = is_interactive;
|
||||
|
||||
|
||||
is_interactive = ((fd == 0) && isatty(STDIN_FILENO));
|
||||
signal_set_handlers();
|
||||
|
||||
|
||||
res= is_interactive?read_i():read_ni( fd );
|
||||
|
||||
|
||||
/*
|
||||
If the exit command was called in a script, only exit the
|
||||
script, not the program
|
||||
*/
|
||||
end_loop = 0;
|
||||
|
||||
|
||||
is_interactive = shell_was_interactive;
|
||||
signal_set_handlers();
|
||||
return res;
|
||||
|
56
tokenizer.c
56
tokenizer.c
@ -116,15 +116,15 @@ static void tok_error( tokenizer *tok, const wchar_t *err )
|
||||
void tok_init( tokenizer *tok, const wchar_t *b, int flags )
|
||||
{
|
||||
// fwprintf( stderr, L"CREATE: \'%ls\'\n", b );
|
||||
|
||||
|
||||
|
||||
memset( tok, 0, sizeof( tokenizer) );
|
||||
|
||||
|
||||
tok->accept_unfinished = flags & TOK_ACCEPT_UNFINISHED;
|
||||
tok->show_comments = flags & TOK_SHOW_COMMENTS;
|
||||
tok->has_next=1;
|
||||
tok->has_next=1;
|
||||
|
||||
/*
|
||||
/*
|
||||
Before we copy the buffer we need to check that it is not
|
||||
null. But before that, we need to init the tokenizer far enough
|
||||
so that errors can be properly flagged
|
||||
@ -137,7 +137,7 @@ void tok_init( tokenizer *tok, const wchar_t *b, int flags )
|
||||
|
||||
tok->has_next = (*b != L'\0');
|
||||
tok->orig_buff = tok->buff = (wchar_t *)(b);
|
||||
|
||||
|
||||
if( tok->accept_unfinished )
|
||||
{
|
||||
int l = wcslen( tok->orig_buff );
|
||||
@ -149,7 +149,7 @@ void tok_init( tokenizer *tok, const wchar_t *b, int flags )
|
||||
tok->orig_buff = tok->buff = wcsdup( tok->orig_buff );
|
||||
if( !tok->orig_buff )
|
||||
{
|
||||
die_mem();
|
||||
die_mem();
|
||||
}
|
||||
tok->orig_buff[l-1] = L'\0';
|
||||
}
|
||||
@ -223,7 +223,7 @@ static void read_string( tokenizer *tok )
|
||||
|
||||
while( 1 )
|
||||
{
|
||||
|
||||
|
||||
if( !myal( *tok->buff ) )
|
||||
{
|
||||
// debug(1, L"%lc", *tok->buff );
|
||||
@ -260,7 +260,7 @@ static void read_string( tokenizer *tok )
|
||||
mode = 1;
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
case L'[':
|
||||
{
|
||||
if( tok->buff != start )
|
||||
@ -271,7 +271,7 @@ static void read_string( tokenizer *tok )
|
||||
case L'\'':
|
||||
case L'"':
|
||||
{
|
||||
|
||||
|
||||
wchar_t *end = quote_end( tok->buff );
|
||||
tok->last_quote = *tok->buff;
|
||||
if( end )
|
||||
@ -281,14 +281,14 @@ static void read_string( tokenizer *tok )
|
||||
else
|
||||
{
|
||||
tok->buff += wcslen( tok->buff );
|
||||
|
||||
|
||||
if( (!tok->accept_unfinished) )
|
||||
{
|
||||
tok_error( tok, EOL_ERROR );
|
||||
return;
|
||||
}
|
||||
do_loop = 0;
|
||||
|
||||
|
||||
}
|
||||
break;
|
||||
}
|
||||
@ -303,7 +303,7 @@ static void read_string( tokenizer *tok )
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
case 3:
|
||||
case 1:
|
||||
switch( *tok->buff )
|
||||
@ -355,7 +355,7 @@ static void read_string( tokenizer *tok )
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
if( !do_loop )
|
||||
break;
|
||||
@ -408,7 +408,7 @@ static void read_comment( tokenizer *tok )
|
||||
static void read_redirect( tokenizer *tok, int fd )
|
||||
{
|
||||
int mode = -1;
|
||||
|
||||
|
||||
if( (*tok->buff == L'>') ||
|
||||
(*tok->buff == L'^') )
|
||||
{
|
||||
@ -430,7 +430,7 @@ static void read_redirect( tokenizer *tok, int fd )
|
||||
tok_error( tok, PIPE_ERROR );
|
||||
return;
|
||||
}
|
||||
check_size( tok, FD_STR_MAX_LEN );
|
||||
check_size( tok, FD_STR_MAX_LEN );
|
||||
tok->buff++;
|
||||
swprintf( tok->last, FD_STR_MAX_LEN, L"%d", fd );
|
||||
tok->last_type = TOK_PIPE;
|
||||
@ -446,14 +446,14 @@ static void read_redirect( tokenizer *tok, int fd )
|
||||
{
|
||||
tok_error( tok, REDIRECT_ERROR);
|
||||
}
|
||||
|
||||
|
||||
if( !check_size( tok, 2 ))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
swprintf( tok->last, tok->last_len, L"%d", fd );
|
||||
|
||||
|
||||
if( *tok->buff == L'&' )
|
||||
{
|
||||
tok->buff++;
|
||||
@ -496,10 +496,10 @@ void tok_next( tokenizer *tok )
|
||||
|
||||
if( tok_last_type( tok ) == TOK_ERROR )
|
||||
{
|
||||
tok->has_next=0;
|
||||
return;
|
||||
tok->has_next=0;
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
if( !tok->has_next )
|
||||
{
|
||||
/* wprintf( L"EOL\n" );*/
|
||||
@ -551,9 +551,9 @@ void tok_next( tokenizer *tok )
|
||||
|
||||
case L'|':
|
||||
check_size( tok, 2 );
|
||||
|
||||
|
||||
tok->last[0]=L'1';
|
||||
tok->last[1]=L'\0';
|
||||
tok->last[1]=L'\0';
|
||||
tok->last_type = TOK_PIPE;
|
||||
tok->buff++;
|
||||
break;
|
||||
@ -567,9 +567,9 @@ void tok_next( tokenizer *tok )
|
||||
|
||||
default:
|
||||
{
|
||||
|
||||
|
||||
if( iswdigit( *tok->buff ) )
|
||||
{
|
||||
{
|
||||
wchar_t *orig = tok->buff;
|
||||
int fd = 0;
|
||||
while( iswdigit( *tok->buff ) )
|
||||
@ -583,11 +583,11 @@ void tok_next( tokenizer *tok )
|
||||
read_redirect( tok, fd );
|
||||
return;
|
||||
}
|
||||
tok->buff = orig;
|
||||
tok->buff = orig;
|
||||
}
|
||||
read_string( tok );
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@ -603,7 +603,7 @@ wchar_t *tok_first( const wchar_t *str )
|
||||
wchar_t *res=0;
|
||||
|
||||
tok_init( &t, str, 0 );
|
||||
|
||||
|
||||
switch( tok_last_type( &t ) )
|
||||
{
|
||||
case TOK_STRING:
|
||||
|
Loading…
x
Reference in New Issue
Block a user