mirror of
https://github.com/fish-shell/fish-shell
synced 2024-12-26 04:43:10 +00:00
Lots of modernization changed
Removed wcsdupcat
This commit is contained in:
parent
4bd63020ca
commit
9bcc7df96f
15 changed files with 177 additions and 348 deletions
|
@ -231,7 +231,7 @@
|
||||||
/* Begin PBXLegacyTarget section */
|
/* Begin PBXLegacyTarget section */
|
||||||
D0A084F713B3AC130099B651 /* FishsFish */ = {
|
D0A084F713B3AC130099B651 /* FishsFish */ = {
|
||||||
isa = PBXLegacyTarget;
|
isa = PBXLegacyTarget;
|
||||||
buildArgumentsString = "-k ${ACTION} -j 3";
|
buildArgumentsString = "-k ${ACTION}";
|
||||||
buildConfigurationList = D0A084FA13B3AC130099B651 /* Build configuration list for PBXLegacyTarget "FishsFish" */;
|
buildConfigurationList = D0A084FA13B3AC130099B651 /* Build configuration list for PBXLegacyTarget "FishsFish" */;
|
||||||
buildPhases = (
|
buildPhases = (
|
||||||
);
|
);
|
||||||
|
|
|
@ -2569,7 +2569,7 @@ static int builtin_exit( parser_t &parser, wchar_t **argv )
|
||||||
static int builtin_cd( parser_t &parser, wchar_t **argv )
|
static int builtin_cd( parser_t &parser, wchar_t **argv )
|
||||||
{
|
{
|
||||||
env_var_t dir_in;
|
env_var_t dir_in;
|
||||||
wchar_t *dir;
|
wchar_t *dir = NULL;
|
||||||
int res=STATUS_BUILTIN_OK;
|
int res=STATUS_BUILTIN_OK;
|
||||||
|
|
||||||
|
|
||||||
|
@ -2583,10 +2583,13 @@ static int builtin_cd( parser_t &parser, wchar_t **argv )
|
||||||
argv[0] );
|
argv[0] );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else {
|
||||||
dir_in = argv[1];
|
dir_in = argv[1];
|
||||||
|
}
|
||||||
|
|
||||||
dir = path_allocate_cdpath( dir_in.missing() ? NULL : dir_in.c_str() );
|
if (! dir_in.missing()) {
|
||||||
|
dir = path_allocate_cdpath(dir_in);
|
||||||
|
}
|
||||||
|
|
||||||
if( !dir )
|
if( !dir )
|
||||||
{
|
{
|
||||||
|
|
81
common.cpp
81
common.cpp
|
@ -401,61 +401,6 @@ char **wcsv2strv( const wchar_t * const *in )
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
wchar_t *wcsdupcat_internal( const wchar_t *a, ... )
|
|
||||||
{
|
|
||||||
int len=wcslen(a);
|
|
||||||
int pos;
|
|
||||||
va_list va, va2;
|
|
||||||
wchar_t *arg;
|
|
||||||
|
|
||||||
va_start( va, a );
|
|
||||||
va_copy( va2, va );
|
|
||||||
while( (arg=va_arg(va, wchar_t *) )!= 0 )
|
|
||||||
{
|
|
||||||
len += wcslen( arg );
|
|
||||||
}
|
|
||||||
va_end( va );
|
|
||||||
|
|
||||||
wchar_t *res = (wchar_t *)malloc( sizeof(wchar_t)*(len +1 ));
|
|
||||||
if( res == 0 )
|
|
||||||
{
|
|
||||||
DIE_MEM();
|
|
||||||
}
|
|
||||||
|
|
||||||
wcscpy( res, a );
|
|
||||||
pos = wcslen(a);
|
|
||||||
while( (arg=va_arg(va2, wchar_t *) )!= 0 )
|
|
||||||
{
|
|
||||||
wcscpy( res+pos, arg );
|
|
||||||
pos += wcslen(arg);
|
|
||||||
}
|
|
||||||
va_end( va2 );
|
|
||||||
return res;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
wchar_t **strv2wcsv( const char **in )
|
|
||||||
{
|
|
||||||
int count =0;
|
|
||||||
int i;
|
|
||||||
|
|
||||||
while( in[count] != 0 )
|
|
||||||
count++;
|
|
||||||
wchar_t **res = (wchar_t **)malloc( sizeof( wchar_t *)*(count+1));
|
|
||||||
if( res == 0 )
|
|
||||||
{
|
|
||||||
DIE_MEM();
|
|
||||||
}
|
|
||||||
|
|
||||||
for( i=0; i<count; i++ )
|
|
||||||
{
|
|
||||||
res[i]=str2wcs(in[i]);
|
|
||||||
}
|
|
||||||
res[count]=0;
|
|
||||||
return res;
|
|
||||||
|
|
||||||
}
|
|
||||||
wcstring format_string(const wchar_t *format, ...)
|
wcstring format_string(const wchar_t *format, ...)
|
||||||
{
|
{
|
||||||
va_list va;
|
va_list va;
|
||||||
|
@ -1723,6 +1668,13 @@ void tokenize_variable_array( const wcstring &val, std::vector<wcstring> &out)
|
||||||
out.push_back(val.substr(pos, end - pos));
|
out.push_back(val.substr(pos, end - pos));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool string_prefixes_string(const wchar_t *proposed_prefix, const wcstring &value)
|
||||||
|
{
|
||||||
|
size_t prefix_size = wcslen(proposed_prefix);
|
||||||
|
return prefix_size <= value.size() && value.compare(0, prefix_size, proposed_prefix) == 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
bool string_prefixes_string(const wcstring &proposed_prefix, const wcstring &value)
|
bool string_prefixes_string(const wcstring &proposed_prefix, const wcstring &value)
|
||||||
{
|
{
|
||||||
size_t prefix_size = proposed_prefix.size();
|
size_t prefix_size = proposed_prefix.size();
|
||||||
|
@ -1948,14 +1900,19 @@ null_terminated_array_t<char> convert_wide_array_to_narrow(const null_terminated
|
||||||
|
|
||||||
void append_path_component(wcstring &path, const wcstring &component)
|
void append_path_component(wcstring &path, const wcstring &component)
|
||||||
{
|
{
|
||||||
size_t len = path.size();
|
if (path.empty() || component.empty()) {
|
||||||
if (len == 0)
|
path.append(component);
|
||||||
{
|
} else {
|
||||||
path = component;
|
size_t path_len = path.size();
|
||||||
|
bool path_slash = path.at(path_len-1) == L'/';
|
||||||
|
bool comp_slash = component.at(0) == L'/';
|
||||||
|
if (! path_slash && ! comp_slash) {
|
||||||
|
// Need a slash
|
||||||
|
path.push_back(L'/');
|
||||||
|
} else if (path_slash && comp_slash) {
|
||||||
|
// Too many slashes
|
||||||
|
path.erase(path_len - 1, 1);
|
||||||
}
|
}
|
||||||
else
|
|
||||||
{
|
|
||||||
if (path[len-1] != L'/') path.push_back(L'/');
|
|
||||||
path.append(component);
|
path.append(component);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
22
common.h
22
common.h
|
@ -180,10 +180,6 @@ extern const wchar_t *program_name;
|
||||||
Check if the specified stringelement is a part of the specified string list
|
Check if the specified stringelement is a part of the specified string list
|
||||||
*/
|
*/
|
||||||
#define contains( str,... ) contains_internal( str, __VA_ARGS__, NULL )
|
#define contains( str,... ) contains_internal( str, __VA_ARGS__, NULL )
|
||||||
/**
|
|
||||||
Concatenate all the specified strings into a single newly allocated one
|
|
||||||
*/
|
|
||||||
#define wcsdupcat( str,... ) wcsdupcat_internal( str, __VA_ARGS__, NULL )
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Print a stack trace to stderr
|
Print a stack trace to stderr
|
||||||
|
@ -251,6 +247,7 @@ std::string wcs2string(const wcstring &input);
|
||||||
|
|
||||||
/** Test if a string prefixes another. Returns true if a is a prefix of b */
|
/** Test if a string prefixes another. Returns true if a is a prefix of b */
|
||||||
bool string_prefixes_string(const wcstring &proposed_prefix, const wcstring &value);
|
bool string_prefixes_string(const wcstring &proposed_prefix, const wcstring &value);
|
||||||
|
bool string_prefixes_string(const wchar_t *proposed_prefix, const wcstring &value);
|
||||||
|
|
||||||
/** Test if a string prefixes another without regard to case. Returns true if a is a prefix of b */
|
/** Test if a string prefixes another without regard to case. Returns true if a is a prefix of b */
|
||||||
bool string_prefixes_string_case_insensitive(const wcstring &proposed_prefix, const wcstring &value);
|
bool string_prefixes_string_case_insensitive(const wcstring &proposed_prefix, const wcstring &value);
|
||||||
|
@ -520,23 +517,6 @@ void append_format(wcstring &str, const wchar_t *format, ...);
|
||||||
*/
|
*/
|
||||||
char **wcsv2strv( const wchar_t * const *in );
|
char **wcsv2strv( const wchar_t * const *in );
|
||||||
|
|
||||||
/**
|
|
||||||
Returns a newly allocated multibyte character string array equivalent of the specified wide character string array
|
|
||||||
*/
|
|
||||||
wchar_t **strv2wcsv( const char **in );
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
Returns a newly allocated concatenation of the specified wide
|
|
||||||
character strings. The last argument must be a null pointer.
|
|
||||||
*/
|
|
||||||
__sentinel wchar_t *wcsdupcat_internal( const wchar_t *a, ... );
|
|
||||||
|
|
||||||
/**
|
|
||||||
Test if the given string is a valid variable name
|
|
||||||
*/
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Test if the given string is a valid variable name.
|
Test if the given string is a valid variable name.
|
||||||
|
|
||||||
|
|
95
complete.cpp
95
complete.cpp
|
@ -828,7 +828,7 @@ int complete_is_valid_argument( const wchar_t *str,
|
||||||
*/
|
*/
|
||||||
|
|
||||||
static void complete_strings( std::vector<completion_t> &comp_out,
|
static void complete_strings( std::vector<completion_t> &comp_out,
|
||||||
const wchar_t *wc_escaped,
|
const wcstring &wc_escaped,
|
||||||
const wchar_t *desc,
|
const wchar_t *desc,
|
||||||
const wchar_t *(*desc_func)(const wcstring &),
|
const wchar_t *(*desc_func)(const wcstring &),
|
||||||
std::vector<completion_t> &possible_comp,
|
std::vector<completion_t> &possible_comp,
|
||||||
|
@ -1001,9 +1001,12 @@ static const wchar_t *complete_function_desc( const wcstring &fn )
|
||||||
|
|
||||||
\param comp the list to add all completions to
|
\param comp the list to add all completions to
|
||||||
*/
|
*/
|
||||||
void completer_t::complete_cmd( const wcstring &str, bool use_function, bool use_builtin, bool use_command)
|
void completer_t::complete_cmd( const wcstring &str_cmd, bool use_function, bool use_builtin, bool use_command)
|
||||||
{
|
{
|
||||||
const wchar_t * const cmd = str.c_str();
|
/* Paranoia */
|
||||||
|
if (str_cmd.empty())
|
||||||
|
return;
|
||||||
|
|
||||||
wchar_t *path_cpy;
|
wchar_t *path_cpy;
|
||||||
wchar_t *nxt_path;
|
wchar_t *nxt_path;
|
||||||
wchar_t *state;
|
wchar_t *state;
|
||||||
|
@ -1013,20 +1016,19 @@ void completer_t::complete_cmd( const wcstring &str, bool use_function, bool use
|
||||||
env_var_t cdpath = env_get_string(L"CDPATH");
|
env_var_t cdpath = env_get_string(L"CDPATH");
|
||||||
if (cdpath.missing_or_empty())
|
if (cdpath.missing_or_empty())
|
||||||
cdpath = L".";
|
cdpath = L".";
|
||||||
wchar_t *cdpath_cpy = wcsdup(cdpath.c_str());
|
|
||||||
|
|
||||||
const bool wants_description = (type == COMPLETE_DEFAULT);
|
const bool wants_description = (type == COMPLETE_DEFAULT);
|
||||||
|
|
||||||
if( (wcschr( cmd, L'/') != 0) || (cmd[0] == L'~' ) )
|
if (str_cmd.find(L'/') != wcstring::npos || str_cmd.at(0) == L'~')
|
||||||
{
|
{
|
||||||
|
|
||||||
if( use_command )
|
if( use_command )
|
||||||
{
|
{
|
||||||
|
|
||||||
if( expand_string(str, this->completions, ACCEPT_INCOMPLETE | EXECUTABLES_ONLY | this->expand_flags() ) != EXPAND_ERROR )
|
if( expand_string(str_cmd, this->completions, ACCEPT_INCOMPLETE | EXECUTABLES_ONLY | this->expand_flags() ) != EXPAND_ERROR )
|
||||||
{
|
{
|
||||||
if (wants_description) {
|
if (wants_description) {
|
||||||
this->complete_cmd_desc( str );
|
this->complete_cmd_desc( str_cmd );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1046,43 +1048,37 @@ void completer_t::complete_cmd( const wcstring &str, bool use_function, bool use
|
||||||
nxt_path != 0;
|
nxt_path != 0;
|
||||||
nxt_path = wcstok( 0, ARRAY_SEP_STR, &state) )
|
nxt_path = wcstok( 0, ARRAY_SEP_STR, &state) )
|
||||||
{
|
{
|
||||||
size_t prev_count;
|
wcstring base_path = nxt_path;
|
||||||
int path_len = wcslen(nxt_path);
|
if (base_path.empty())
|
||||||
int add_slash;
|
|
||||||
|
|
||||||
if( !path_len )
|
|
||||||
{
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
add_slash = nxt_path[path_len-1]!=L'/';
|
|
||||||
wchar_t *nxt_completion = wcsdupcat( nxt_path,
|
|
||||||
add_slash?L"/":L"",
|
|
||||||
cmd );
|
|
||||||
if( ! nxt_completion )
|
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
prev_count = this->completions.size() ;
|
/* Make sure the base path ends with a slash */
|
||||||
|
if (base_path.at(base_path.size() - 1) != L'/')
|
||||||
|
base_path.push_back(L'/');
|
||||||
|
|
||||||
|
wcstring nxt_completion = base_path;
|
||||||
|
nxt_completion.append(str_cmd);
|
||||||
|
|
||||||
|
size_t prev_count = this->completions.size();
|
||||||
if( expand_string( nxt_completion,
|
if( expand_string( nxt_completion,
|
||||||
this->completions,
|
this->completions,
|
||||||
ACCEPT_INCOMPLETE | EXECUTABLES_ONLY | this->expand_flags() ) != EXPAND_ERROR )
|
ACCEPT_INCOMPLETE | EXECUTABLES_ONLY | this->expand_flags() ) != EXPAND_ERROR )
|
||||||
{
|
{
|
||||||
|
/* For all new completions, if COMPLETE_NO_CASE is set, then use only the last path component */
|
||||||
for( size_t i=prev_count; i< this->completions.size(); i++ )
|
for( size_t i=prev_count; i< this->completions.size(); i++ )
|
||||||
{
|
{
|
||||||
completion_t &c = this->completions.at( i );
|
completion_t &c = this->completions.at( i );
|
||||||
if(c.flags & COMPLETE_NO_CASE )
|
if(c.flags & COMPLETE_NO_CASE )
|
||||||
{
|
{
|
||||||
c.completion += add_slash ;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
free(nxt_completion);
|
c.completion.erase(0, base_path.size());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
free( path_cpy );
|
free( path_cpy );
|
||||||
if (wants_description)
|
if (wants_description)
|
||||||
this->complete_cmd_desc( str );
|
this->complete_cmd_desc( str_cmd );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1093,12 +1089,12 @@ void completer_t::complete_cmd( const wcstring &str, bool use_function, bool use
|
||||||
if( use_function )
|
if( use_function )
|
||||||
{
|
{
|
||||||
//function_get_names( &possible_comp, cmd[0] == L'_' );
|
//function_get_names( &possible_comp, cmd[0] == L'_' );
|
||||||
wcstring_list_t names = function_get_names(cmd[0] == L'_' );
|
wcstring_list_t names = function_get_names(str_cmd.at(0) == L'_' );
|
||||||
for (size_t i=0; i < names.size(); i++) {
|
for (size_t i=0; i < names.size(); i++) {
|
||||||
possible_comp.push_back(completion_t(names.at(i)));
|
possible_comp.push_back(completion_t(names.at(i)));
|
||||||
}
|
}
|
||||||
|
|
||||||
complete_strings( this->completions, cmd, 0, &complete_function_desc, possible_comp, 0 );
|
complete_strings( this->completions, str_cmd, 0, &complete_function_desc, possible_comp, 0 );
|
||||||
}
|
}
|
||||||
|
|
||||||
possible_comp.clear();
|
possible_comp.clear();
|
||||||
|
@ -1106,43 +1102,10 @@ void completer_t::complete_cmd( const wcstring &str, bool use_function, bool use
|
||||||
if( use_builtin )
|
if( use_builtin )
|
||||||
{
|
{
|
||||||
builtin_get_names( possible_comp );
|
builtin_get_names( possible_comp );
|
||||||
complete_strings( this->completions, cmd, 0, &builtin_get_desc, possible_comp, 0 );
|
complete_strings( this->completions, str_cmd, 0, &builtin_get_desc, possible_comp, 0 );
|
||||||
}
|
|
||||||
// al_destroy( &possible_comp );
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if( use_builtin || (use_function && function_exists( L"cd") ) )
|
|
||||||
{
|
|
||||||
/*
|
|
||||||
Tab complete implicit cd for directories in CDPATH
|
|
||||||
*/
|
|
||||||
if( cmd[0] != L'/' && ( wcsncmp( cmd, L"./", 2 )!=0) )
|
|
||||||
{
|
|
||||||
for( nxt_path = wcstok( cdpath_cpy, ARRAY_SEP_STR, &state );
|
|
||||||
nxt_path != 0;
|
|
||||||
nxt_path = wcstok( 0, ARRAY_SEP_STR, &state) )
|
|
||||||
{
|
|
||||||
wchar_t *nxt_completion=
|
|
||||||
wcsdupcat( nxt_path,
|
|
||||||
(nxt_path[wcslen(nxt_path)-1]==L'/'?L"":L"/"),
|
|
||||||
cmd );
|
|
||||||
if( ! nxt_completion )
|
|
||||||
{
|
|
||||||
continue;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if( expand_string( nxt_completion,
|
|
||||||
this->completions,
|
|
||||||
ACCEPT_INCOMPLETE | DIRECTORIES_ONLY | this->expand_flags() ) != EXPAND_ERROR )
|
|
||||||
{
|
|
||||||
}
|
|
||||||
free(nxt_completion);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
free( cdpath_cpy );
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -1178,7 +1141,7 @@ void completer_t::complete_from_args( const wcstring &str,
|
||||||
if (! is_autosuggest)
|
if (! is_autosuggest)
|
||||||
proc_pop_interactive();
|
proc_pop_interactive();
|
||||||
|
|
||||||
complete_strings( this->completions, str.c_str(), desc.c_str(), 0, possible_comp, flags );
|
complete_strings( this->completions, str, desc.c_str(), 0, possible_comp, flags );
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -1507,7 +1470,7 @@ void completer_t::complete_param_expand( const wcstring &sstr, bool do_file)
|
||||||
const wchar_t * const str = sstr.c_str();
|
const wchar_t * const str = sstr.c_str();
|
||||||
const wchar_t *comp_str;
|
const wchar_t *comp_str;
|
||||||
|
|
||||||
if( (wcsncmp( str, L"--", 2 )) == 0 && (comp_str = wcschr(str, L'=' ) ) )
|
if (string_prefixes_string( L"--", sstr) && (comp_str = wcschr(str, L'=' ) ) )
|
||||||
{
|
{
|
||||||
comp_str++;
|
comp_str++;
|
||||||
}
|
}
|
||||||
|
|
6
expand.h
6
expand.h
|
@ -105,8 +105,7 @@ enum
|
||||||
EXPAND_WILDCARD_NO_MATCH,
|
EXPAND_WILDCARD_NO_MATCH,
|
||||||
/* Ok, a wildcard in the string matched a file */
|
/* Ok, a wildcard in the string matched a file */
|
||||||
EXPAND_WILDCARD_MATCH
|
EXPAND_WILDCARD_MATCH
|
||||||
}
|
};
|
||||||
;
|
|
||||||
|
|
||||||
/** Character for separating two array elements. We use 30, i.e. the ascii record separator since that seems logical. */
|
/** Character for separating two array elements. We use 30, i.e. the ascii record separator since that seems logical. */
|
||||||
#define ARRAY_SEP 0x1e
|
#define ARRAY_SEP 0x1e
|
||||||
|
@ -129,8 +128,7 @@ class parser_t;
|
||||||
into the list out.
|
into the list out.
|
||||||
|
|
||||||
If the parameter does not need expansion, it is copied into the list
|
If the parameter does not need expansion, it is copied into the list
|
||||||
out. If expansion is performed, the original parameter is freed and
|
out.
|
||||||
newly allocated strings are inserted into the list out.
|
|
||||||
|
|
||||||
\param input The parameter to expand
|
\param input The parameter to expand
|
||||||
\param output The list to which the result will be appended.
|
\param output The list to which the result will be appended.
|
||||||
|
|
72
fishd.cpp
72
fishd.cpp
|
@ -670,54 +670,45 @@ static wchar_t *fishd_env_get( const wchar_t *key )
|
||||||
to be rewritten to avoid dragging in additional library
|
to be rewritten to avoid dragging in additional library
|
||||||
dependencies.
|
dependencies.
|
||||||
*/
|
*/
|
||||||
static wchar_t *fishd_get_config()
|
static wcstring fishd_get_config()
|
||||||
{
|
{
|
||||||
wchar_t *xdg_dir, *home;
|
wchar_t *xdg_dir, *home;
|
||||||
int done = 0;
|
bool done = false;
|
||||||
wchar_t *res = 0;
|
wcstring result;
|
||||||
|
|
||||||
xdg_dir = fishd_env_get( L"XDG_CONFIG_HOME" );
|
xdg_dir = fishd_env_get( L"XDG_CONFIG_HOME" );
|
||||||
if( xdg_dir )
|
if (xdg_dir)
|
||||||
{
|
{
|
||||||
res = wcsdupcat( xdg_dir, L"/fish" );
|
result = xdg_dir;
|
||||||
if( !create_directory( res ) )
|
append_path_component(result, L"/fish");
|
||||||
|
if (!create_directory(result))
|
||||||
{
|
{
|
||||||
done = 1;
|
done = true;
|
||||||
}
|
}
|
||||||
else
|
free(xdg_dir);
|
||||||
{
|
|
||||||
free( res );
|
|
||||||
}
|
|
||||||
free( xdg_dir );
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
home = fishd_env_get( L"HOME" );
|
home = fishd_env_get( L"HOME" );
|
||||||
if( home )
|
if( home )
|
||||||
{
|
{
|
||||||
res = wcsdupcat( home, L"/.config/fish" );
|
result = home;
|
||||||
if( !create_directory( res ) )
|
append_path_component(result, L"/.config/fish");
|
||||||
|
if (!create_directory(result))
|
||||||
{
|
{
|
||||||
done = 1;
|
done = 1;
|
||||||
}
|
}
|
||||||
else
|
|
||||||
{
|
|
||||||
free( res );
|
|
||||||
}
|
|
||||||
free( home );
|
free( home );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if( done )
|
if (! done) {
|
||||||
{
|
/* Bad juju */
|
||||||
return res;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
debug( 0, _(L"Unable to create a configuration directory for fish. Your personal settings will not be saved. Please set the $XDG_CONFIG_HOME variable to a directory where the current user has write access." ));
|
debug( 0, _(L"Unable to create a configuration directory for fish. Your personal settings will not be saved. Please set the $XDG_CONFIG_HOME variable to a directory where the current user has write access." ));
|
||||||
return 0;
|
result.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -725,41 +716,30 @@ static wchar_t *fishd_get_config()
|
||||||
*/
|
*/
|
||||||
static void load_or_save( int save)
|
static void load_or_save( int save)
|
||||||
{
|
{
|
||||||
char *name;
|
const wcstring wdir = fishd_get_config();
|
||||||
wchar_t *wdir = fishd_get_config();
|
|
||||||
char *dir;
|
|
||||||
char hostname[HOSTNAME_LEN];
|
char hostname[HOSTNAME_LEN];
|
||||||
connection_t c;
|
connection_t c;
|
||||||
int fd;
|
int fd;
|
||||||
|
|
||||||
if( !wdir )
|
if (wdir.empty())
|
||||||
{
|
|
||||||
return;
|
return;
|
||||||
}
|
|
||||||
|
|
||||||
dir = wcs2str( wdir );
|
std::string dir = wcs2string( wdir );
|
||||||
|
|
||||||
free( wdir );
|
|
||||||
|
|
||||||
gethostname( hostname, HOSTNAME_LEN );
|
gethostname( hostname, HOSTNAME_LEN );
|
||||||
|
|
||||||
name = (char *)malloc( strlen(dir)+ strlen(FILE)+ strlen(hostname) + 2 );
|
std::string name;
|
||||||
strcpy( name, dir );
|
name.append(dir);
|
||||||
strcat( name, "/" );
|
name.append("/");
|
||||||
strcat( name, FILE );
|
name.append(FILE);
|
||||||
strcat( name, hostname );
|
name.append(hostname);
|
||||||
|
|
||||||
free( dir );
|
|
||||||
|
|
||||||
|
|
||||||
debug( 4, L"Open file for %s: '%s'",
|
debug( 4, L"Open file for %s: '%s'",
|
||||||
save?"saving":"loading",
|
save?"saving":"loading",
|
||||||
name );
|
name.c_str() );
|
||||||
|
|
||||||
/* OK to not use CLO_EXEC here because fishd is single threaded */
|
/* OK to not use CLO_EXEC here because fishd is single threaded */
|
||||||
fd = open( name, save?(O_CREAT | O_TRUNC | O_WRONLY):O_RDONLY, 0600);
|
fd = open(name.c_str(), save?(O_CREAT | O_TRUNC | O_WRONLY):O_RDONLY, 0600);
|
||||||
|
|
||||||
free( name );
|
|
||||||
|
|
||||||
if( fd == -1 )
|
if( fd == -1 )
|
||||||
{
|
{
|
||||||
|
|
|
@ -807,7 +807,7 @@ bool autosuggest_special_validate_from_history(const wcstring &str, const wcstri
|
||||||
if (is_help) {
|
if (is_help) {
|
||||||
suggestionOK = false;
|
suggestionOK = false;
|
||||||
} else {
|
} else {
|
||||||
wchar_t *path = path_allocate_cdpath(dir.c_str(), working_directory.c_str());
|
wchar_t *path = path_allocate_cdpath(dir, working_directory.c_str());
|
||||||
if (path == NULL) {
|
if (path == NULL) {
|
||||||
suggestionOK = false;
|
suggestionOK = false;
|
||||||
} else if (paths_are_same_file(working_directory, path)) {
|
} else if (paths_are_same_file(working_directory, path)) {
|
||||||
|
@ -1237,8 +1237,7 @@ void highlight_shell( const wcstring &buff, std::vector<int> &color, int pos, wc
|
||||||
|
|
||||||
//our subcolors start at color + (begin-subbuff)+1
|
//our subcolors start at color + (begin-subbuff)+1
|
||||||
size_t start = begin - subbuff + 1, len = wcslen(begin + 1);
|
size_t start = begin - subbuff + 1, len = wcslen(begin + 1);
|
||||||
std::vector<int> subcolors;
|
std::vector<int> subcolors(len, -1);
|
||||||
subcolors.resize(len, -1);
|
|
||||||
|
|
||||||
highlight_shell( begin+1, subcolors, -1, error, vars );
|
highlight_shell( begin+1, subcolors, -1, error, vars );
|
||||||
|
|
||||||
|
|
17
kill.cpp
17
kill.cpp
|
@ -76,8 +76,8 @@ void kill_add( const wcstring &str )
|
||||||
if (str.empty())
|
if (str.empty())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
wchar_t *cmd = NULL;
|
wcstring cmd;
|
||||||
wchar_t *escaped_str;
|
wchar_t *escaped_str = NULL;
|
||||||
kill_list.push_front(str);
|
kill_list.push_front(str);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -92,7 +92,9 @@ void kill_add( const wcstring &str )
|
||||||
if( !clipboard_wstr.missing() )
|
if( !clipboard_wstr.missing() )
|
||||||
{
|
{
|
||||||
escaped_str = escape( str.c_str(), 1 );
|
escaped_str = escape( str.c_str(), 1 );
|
||||||
cmd = wcsdupcat(L"echo -n ", escaped_str, clipboard_wstr.c_str());
|
cmd.assign(L"echo -n ");
|
||||||
|
cmd.append(escaped_str);
|
||||||
|
cmd.append(clipboard_wstr);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -105,13 +107,15 @@ void kill_add( const wcstring &str )
|
||||||
if( !disp_wstr.missing() )
|
if( !disp_wstr.missing() )
|
||||||
{
|
{
|
||||||
escaped_str = escape( str.c_str(), 1 );
|
escaped_str = escape( str.c_str(), 1 );
|
||||||
cmd = wcsdupcat(L"echo ", escaped_str, L"|xsel -b" );
|
cmd.assign(L"echo ");
|
||||||
|
cmd.append(escaped_str);
|
||||||
|
cmd.append(L"|xsel -b" );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (cmd != NULL)
|
if (! cmd.empty())
|
||||||
{
|
{
|
||||||
if( exec_subshell( cmd) == -1 )
|
if( exec_subshell(cmd) == -1 )
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
Do nothing on failiure
|
Do nothing on failiure
|
||||||
|
@ -119,7 +123,6 @@ void kill_add( const wcstring &str )
|
||||||
}
|
}
|
||||||
|
|
||||||
free( cut_buffer );
|
free( cut_buffer );
|
||||||
free( cmd );
|
|
||||||
|
|
||||||
cut_buffer = escaped_str;
|
cut_buffer = escaped_str;
|
||||||
}
|
}
|
||||||
|
|
10
parser.cpp
10
parser.cpp
|
@ -798,14 +798,8 @@ int parser_t::eval_args( const wchar_t *line, std::vector<completion_t> &args )
|
||||||
{
|
{
|
||||||
case TOK_STRING:
|
case TOK_STRING:
|
||||||
{
|
{
|
||||||
wchar_t *tmp = wcsdup(tok_last( &tok ));
|
const wcstring tmp = tok_last(&tok);
|
||||||
|
if( expand_string(tmp, args, eflags) == EXPAND_ERROR )
|
||||||
if( !tmp )
|
|
||||||
{
|
|
||||||
DIE_MEM();
|
|
||||||
}
|
|
||||||
|
|
||||||
if( expand_string( tmp, args, eflags ) == EXPAND_ERROR )
|
|
||||||
{
|
{
|
||||||
err_pos=tok_get_pos( &tok );
|
err_pos=tok_get_pos( &tok );
|
||||||
do_loop=0;
|
do_loop=0;
|
||||||
|
|
38
path.cpp
38
path.cpp
|
@ -343,12 +343,12 @@ bool path_get_cdpath_string(const wcstring &dir_str, wcstring &result, const env
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
wchar_t *path_allocate_cdpath( const wchar_t *dir, const wchar_t *wd )
|
wchar_t *path_allocate_cdpath( const wcstring &dir, const wchar_t *wd )
|
||||||
{
|
{
|
||||||
wchar_t *res = NULL;
|
wchar_t *res = NULL;
|
||||||
int err = ENOENT;
|
int err = ENOENT;
|
||||||
if( !dir )
|
if (dir.empty())
|
||||||
return 0;
|
return NULL;
|
||||||
|
|
||||||
if (wd) {
|
if (wd) {
|
||||||
size_t len = wcslen(wd);
|
size_t len = wcslen(wd);
|
||||||
|
@ -357,13 +357,12 @@ wchar_t *path_allocate_cdpath( const wchar_t *dir, const wchar_t *wd )
|
||||||
|
|
||||||
wcstring_list_t paths;
|
wcstring_list_t paths;
|
||||||
|
|
||||||
if (dir[0] == L'/') {
|
if (dir.at(0) == L'/') {
|
||||||
/* Absolute path */
|
/* Absolute path */
|
||||||
paths.push_back(dir);
|
paths.push_back(dir);
|
||||||
} else if (wcsncmp(dir, L"./", 2) == 0 ||
|
} else if (string_prefixes_string(L"./", dir) ||
|
||||||
wcsncmp(dir, L"../", 3) == 0 ||
|
string_prefixes_string(L"../", dir) ||
|
||||||
wcscmp(dir, L".") == 0 ||
|
dir == L"." || dir == L"..") {
|
||||||
wcscmp(dir, L"..") == 0) {
|
|
||||||
/* Path is relative to the working directory */
|
/* Path is relative to the working directory */
|
||||||
wcstring path;
|
wcstring path;
|
||||||
if (wd)
|
if (wd)
|
||||||
|
@ -373,7 +372,6 @@ wchar_t *path_allocate_cdpath( const wchar_t *dir, const wchar_t *wd )
|
||||||
} else {
|
} else {
|
||||||
wchar_t *path_cpy;
|
wchar_t *path_cpy;
|
||||||
wchar_t *state;
|
wchar_t *state;
|
||||||
wchar_t *whole_path;
|
|
||||||
|
|
||||||
// Respect CDPATH
|
// Respect CDPATH
|
||||||
env_var_t path = env_get_string(L"CDPATH");
|
env_var_t path = env_get_string(L"CDPATH");
|
||||||
|
@ -392,25 +390,17 @@ wchar_t *path_allocate_cdpath( const wchar_t *dir, const wchar_t *wd )
|
||||||
nxt_path = wd;
|
nxt_path = wd;
|
||||||
}
|
}
|
||||||
|
|
||||||
wchar_t *expanded_path = expand_tilde_compat( wcsdup(nxt_path) );
|
wcstring expanded_path = nxt_path;
|
||||||
|
expand_tilde(expanded_path);
|
||||||
|
|
||||||
// debug( 2, L"woot %ls\n", expanded_path );
|
// debug( 2, L"woot %ls\n", expanded_path.c_str() );
|
||||||
|
|
||||||
int path_len = wcslen( expanded_path );
|
if (expanded_path.empty())
|
||||||
if( path_len == 0 )
|
|
||||||
{
|
|
||||||
free(expanded_path );
|
|
||||||
continue;
|
continue;
|
||||||
}
|
|
||||||
|
|
||||||
whole_path =
|
wcstring whole_path = expanded_path;
|
||||||
wcsdupcat( expanded_path,
|
append_path_component(whole_path, dir);
|
||||||
( expanded_path[path_len-1] != L'/' )?L"/":L"",
|
|
||||||
dir );
|
|
||||||
|
|
||||||
free(expanded_path );
|
|
||||||
paths.push_back(whole_path);
|
paths.push_back(whole_path);
|
||||||
free( whole_path );
|
|
||||||
}
|
}
|
||||||
free( path_cpy );
|
free( path_cpy );
|
||||||
}
|
}
|
||||||
|
@ -442,7 +432,7 @@ wchar_t *path_allocate_cdpath( const wchar_t *dir, const wchar_t *wd )
|
||||||
|
|
||||||
|
|
||||||
bool path_can_get_cdpath(const wcstring &in, const wchar_t *wd) {
|
bool path_can_get_cdpath(const wcstring &in, const wchar_t *wd) {
|
||||||
wchar_t *tmp = path_allocate_cdpath(in.c_str(), wd);
|
wchar_t *tmp = path_allocate_cdpath(in, wd);
|
||||||
bool result = (tmp != NULL);
|
bool result = (tmp != NULL);
|
||||||
free(tmp);
|
free(tmp);
|
||||||
return result;
|
return result;
|
||||||
|
|
2
path.h
2
path.h
|
@ -53,7 +53,7 @@ bool path_get_path_string(const wcstring &cmd, wcstring &output, const env_vars
|
||||||
\return 0 if the command can not be found, the path of the command otherwise. The path should be free'd with free().
|
\return 0 if the command can not be found, the path of the command otherwise. The path should be free'd with free().
|
||||||
*/
|
*/
|
||||||
|
|
||||||
wchar_t *path_allocate_cdpath( const wchar_t *in, const wchar_t *wd = NULL);
|
wchar_t *path_allocate_cdpath( const wcstring &in, const wchar_t *wd = NULL);
|
||||||
bool path_can_get_cdpath(const wcstring &in, const wchar_t *wd = NULL);
|
bool path_can_get_cdpath(const wcstring &in, const wchar_t *wd = NULL);
|
||||||
bool path_get_cdpath_string(const wcstring &in, wcstring &out, const env_vars &vars);
|
bool path_get_cdpath_string(const wcstring &in, wcstring &out, const env_vars &vars);
|
||||||
|
|
||||||
|
|
65
reader.cpp
65
reader.cpp
|
@ -938,7 +938,6 @@ static void get_param( const wchar_t *cmd,
|
||||||
*/
|
*/
|
||||||
static wcstring completion_apply_to_command_line(const wcstring &val_str, int flags, const wcstring &command_line, size_t *inout_cursor_pos)
|
static wcstring completion_apply_to_command_line(const wcstring &val_str, int flags, const wcstring &command_line, size_t *inout_cursor_pos)
|
||||||
{
|
{
|
||||||
wchar_t *replaced;
|
|
||||||
const wchar_t *val = val_str.c_str();
|
const wchar_t *val = val_str.c_str();
|
||||||
bool add_space = !(flags & COMPLETE_NO_SPACE);
|
bool add_space = !(flags & COMPLETE_NO_SPACE);
|
||||||
bool do_replace = !!(flags & COMPLETE_NO_CASE);
|
bool do_replace = !!(flags & COMPLETE_NO_CASE);
|
||||||
|
@ -988,25 +987,20 @@ static wcstring completion_apply_to_command_line(const wcstring &val_str, int fl
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
wchar_t quote = L'\0';
|
wchar_t quote = L'\0';
|
||||||
|
wcstring replaced;
|
||||||
if( do_escape )
|
if( do_escape )
|
||||||
{
|
{
|
||||||
get_param(command_line.c_str(), cursor_pos, "e, 0, 0, 0);
|
get_param(command_line.c_str(), cursor_pos, "e, 0, 0, 0);
|
||||||
if( quote == L'\0' )
|
if( quote == L'\0' )
|
||||||
{
|
{
|
||||||
replaced = escape( val, ESCAPE_ALL | ESCAPE_NO_QUOTED );
|
replaced = escape_string( val, ESCAPE_ALL | ESCAPE_NO_QUOTED );
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
bool unescapable = false;
|
bool unescapable = false;
|
||||||
|
for (const wchar_t *pin = val; *pin; pin++)
|
||||||
const wchar_t *pin;
|
|
||||||
wchar_t *pout;
|
|
||||||
|
|
||||||
replaced = pout = (wchar_t *)malloc( sizeof(wchar_t)*(wcslen(val) + 1) );
|
|
||||||
|
|
||||||
for( pin=val; *pin; pin++ )
|
|
||||||
{
|
{
|
||||||
switch( *pin )
|
switch (*pin )
|
||||||
{
|
{
|
||||||
case L'\n':
|
case L'\n':
|
||||||
case L'\t':
|
case L'\t':
|
||||||
|
@ -1015,31 +1009,26 @@ static wcstring completion_apply_to_command_line(const wcstring &val_str, int fl
|
||||||
unescapable = true;
|
unescapable = true;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
*pout++ = *pin;
|
replaced.push_back(*pin);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (unescapable)
|
if (unescapable)
|
||||||
{
|
{
|
||||||
free( replaced );
|
replaced = escape_string(val, ESCAPE_ALL | ESCAPE_NO_QUOTED);
|
||||||
wchar_t *tmp = escape( val, ESCAPE_ALL | ESCAPE_NO_QUOTED );
|
replaced.insert(0, "e, 1);
|
||||||
replaced = wcsdupcat( L" ", tmp );
|
|
||||||
free( tmp);
|
|
||||||
replaced[0]=quote;
|
|
||||||
}
|
}
|
||||||
else
|
|
||||||
*pout = 0;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
replaced = wcsdup(val);
|
replaced = val;
|
||||||
}
|
}
|
||||||
|
|
||||||
wcstring result = command_line;
|
wcstring result = command_line;
|
||||||
result.insert(cursor_pos, replaced);
|
result.insert(cursor_pos, replaced);
|
||||||
size_t new_cursor_pos = cursor_pos + wcslen(replaced);
|
size_t new_cursor_pos = cursor_pos + replaced.size();
|
||||||
if (add_space)
|
if (add_space)
|
||||||
{
|
{
|
||||||
if (quote && (command_line.c_str()[cursor_pos] != quote))
|
if (quote && (command_line.c_str()[cursor_pos] != quote))
|
||||||
|
@ -1049,7 +1038,6 @@ static wcstring completion_apply_to_command_line(const wcstring &val_str, int fl
|
||||||
}
|
}
|
||||||
result.insert(new_cursor_pos++, L" ");
|
result.insert(new_cursor_pos++, L" ");
|
||||||
}
|
}
|
||||||
free(replaced);
|
|
||||||
*inout_cursor_pos = new_cursor_pos;
|
*inout_cursor_pos = new_cursor_pos;
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
@ -1084,30 +1072,28 @@ static void completion_insert( const wchar_t *val, int flags )
|
||||||
\param comp the list of completions to display
|
\param comp the list of completions to display
|
||||||
*/
|
*/
|
||||||
|
|
||||||
static void run_pager( wchar_t *prefix, int is_quoted, const std::vector<completion_t> &comp )
|
static void run_pager( const wcstring &prefix, int is_quoted, const std::vector<completion_t> &comp )
|
||||||
{
|
{
|
||||||
wcstring msg;
|
wcstring msg;
|
||||||
wchar_t * prefix_esc;
|
wcstring prefix_esc;
|
||||||
char *foo;
|
char *foo;
|
||||||
io_data_t *in;
|
io_data_t *in;
|
||||||
wchar_t *escaped_separator;
|
wchar_t *escaped_separator;
|
||||||
int has_case_sensitive=0;
|
int has_case_sensitive=0;
|
||||||
|
|
||||||
if( !prefix || (wcslen(prefix)==0))
|
if (prefix.empty())
|
||||||
{
|
{
|
||||||
prefix_esc = wcsdup(L"\"\"");
|
prefix_esc = L"\"\"";
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
prefix_esc = escape( prefix,1);
|
prefix_esc = escape_string(prefix, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
wcstring cmd = format_string(L"fish_pager -c 3 -r 4 %ls -p %ls",
|
wcstring cmd = format_string(L"fish_pager -c 3 -r 4 %ls -p %ls",
|
||||||
// L"valgrind --track-fds=yes --log-file=pager.txt --leak-check=full ./fish_pager %d %ls",
|
// L"valgrind --track-fds=yes --log-file=pager.txt --leak-check=full ./fish_pager %d %ls",
|
||||||
is_quoted?L"-q":L"",
|
is_quoted?L"-q":L"",
|
||||||
prefix_esc );
|
prefix_esc.c_str() );
|
||||||
|
|
||||||
free(prefix_esc);
|
|
||||||
|
|
||||||
in= io_buffer_create( 1 );
|
in= io_buffer_create( 1 );
|
||||||
in->fd = 3;
|
in->fd = 3;
|
||||||
|
@ -1611,7 +1597,7 @@ static int handle_completions( const std::vector<completion_t> &comp )
|
||||||
is true, so we print the list
|
is true, so we print the list
|
||||||
*/
|
*/
|
||||||
int len;
|
int len;
|
||||||
wchar_t * prefix;
|
wcstring prefix;
|
||||||
const wchar_t * prefix_start;
|
const wchar_t * prefix_start;
|
||||||
const wchar_t *buff = data->command_line.c_str();
|
const wchar_t *buff = data->command_line.c_str();
|
||||||
get_param( buff,
|
get_param( buff,
|
||||||
|
@ -1625,23 +1611,12 @@ static int handle_completions( const std::vector<completion_t> &comp )
|
||||||
|
|
||||||
if( len <= PREFIX_MAX_LEN )
|
if( len <= PREFIX_MAX_LEN )
|
||||||
{
|
{
|
||||||
prefix = (wchar_t *)malloc( sizeof(wchar_t)*(len+1) );
|
prefix.append(prefix_start, len);
|
||||||
wcslcpy( prefix, prefix_start, len );
|
|
||||||
prefix[len]=L'\0';
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
wchar_t tmp[2]=
|
prefix = wcstring(&ellipsis_char, 1);
|
||||||
{
|
prefix.append(prefix_start + (len - PREFIX_MAX_LEN));
|
||||||
ellipsis_char,
|
|
||||||
0
|
|
||||||
}
|
|
||||||
;
|
|
||||||
|
|
||||||
prefix = wcsdupcat( tmp,
|
|
||||||
prefix_start + (len - PREFIX_MAX_LEN) );
|
|
||||||
prefix[PREFIX_MAX_LEN] = 0;
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
|
@ -1656,8 +1631,6 @@ static int handle_completions( const std::vector<completion_t> &comp )
|
||||||
|
|
||||||
run_pager( prefix, is_quoted, comp );
|
run_pager( prefix, is_quoted, comp );
|
||||||
}
|
}
|
||||||
|
|
||||||
free( prefix );
|
|
||||||
s_reset( &data->screen, true);
|
s_reset( &data->screen, true);
|
||||||
reader_repaint();
|
reader_repaint();
|
||||||
|
|
||||||
|
|
83
wildcard.cpp
83
wildcard.cpp
|
@ -199,54 +199,49 @@ static int wildcard_match2( const wcstring &str_str,
|
||||||
possible completion of the string, the remainder of the string is
|
possible completion of the string, the remainder of the string is
|
||||||
inserted into the out vector.
|
inserted into the out vector.
|
||||||
*/
|
*/
|
||||||
static int wildcard_complete_internal( const wchar_t *orig,
|
static bool wildcard_complete_internal(const wcstring &orig,
|
||||||
const wchar_t *str,
|
const wchar_t *str,
|
||||||
const wchar_t *wc,
|
const wchar_t *wc,
|
||||||
int is_first,
|
bool is_first,
|
||||||
const wchar_t *desc,
|
const wchar_t *desc,
|
||||||
const wchar_t *(*desc_func)(const wcstring &),
|
const wchar_t *(*desc_func)(const wcstring &),
|
||||||
std::vector<completion_t> &out,
|
std::vector<completion_t> &out,
|
||||||
int flags )
|
int flags )
|
||||||
{
|
{
|
||||||
if( !wc || !str || !orig)
|
if( !wc || ! str || orig.empty())
|
||||||
{
|
{
|
||||||
debug( 2, L"Got null string on line %d of file %s", __LINE__, __FILE__ );
|
debug( 2, L"Got null string on line %d of file %s", __LINE__, __FILE__ );
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if( *wc == 0 &&
|
if( *wc == 0 &&
|
||||||
( ( *str != L'.') || (!is_first)) )
|
( (str[0] != L'.') || (!is_first)) )
|
||||||
{
|
{
|
||||||
wchar_t *out_completion = 0;
|
wcstring out_completion;
|
||||||
const wchar_t *out_desc = desc;
|
wcstring out_desc = (desc ? desc : L"");
|
||||||
|
|
||||||
if( flags & COMPLETE_NO_CASE )
|
if( flags & COMPLETE_NO_CASE )
|
||||||
{
|
{
|
||||||
out_completion = wcsdup( orig );
|
out_completion = orig;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
out_completion = wcsdup( str );
|
out_completion = str;
|
||||||
}
|
}
|
||||||
|
|
||||||
if( wcschr( str, PROG_COMPLETE_SEP ) )
|
size_t complete_sep_loc = out_completion.find(PROG_COMPLETE_SEP);
|
||||||
|
if (complete_sep_loc != wcstring::npos)
|
||||||
{
|
{
|
||||||
/*
|
/* This completion has an embedded description, do not use the generic description */
|
||||||
This completion has an embedded description, du not use the generic description
|
out_desc.assign(out_completion, complete_sep_loc + 1, out_completion.size() - complete_sep_loc - 1);
|
||||||
*/
|
out_completion.resize(complete_sep_loc);
|
||||||
wchar_t *sep;
|
|
||||||
|
|
||||||
sep = wcschr(out_completion, PROG_COMPLETE_SEP );
|
|
||||||
*sep = 0;
|
|
||||||
out_desc = sep + 1;
|
|
||||||
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if( desc_func )
|
if( desc_func )
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
A descripton generating function is specified, call
|
A description generating function is specified, call
|
||||||
it. If it returns something, use that as the
|
it. If it returns something, use that as the
|
||||||
description.
|
description.
|
||||||
*/
|
*/
|
||||||
|
@ -257,36 +252,33 @@ static int wildcard_complete_internal( const wchar_t *orig,
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if(out_completion)
|
if (! out_completion.empty())
|
||||||
{
|
{
|
||||||
completion_allocate( out,
|
completion_allocate( out,
|
||||||
out_completion,
|
out_completion,
|
||||||
out_desc ? out_desc : L"",
|
out_desc,
|
||||||
flags );
|
flags );
|
||||||
}
|
}
|
||||||
|
return true;
|
||||||
free ( out_completion );
|
|
||||||
|
|
||||||
return 1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
if( *wc == ANY_STRING )
|
if( *wc == ANY_STRING )
|
||||||
{
|
{
|
||||||
int res=0;
|
bool res=false;
|
||||||
|
|
||||||
/* Ignore hidden file */
|
/* Ignore hidden file */
|
||||||
if( is_first && str[0] == L'.' )
|
if( is_first && str[0] == L'.' )
|
||||||
return 0;
|
return false;
|
||||||
|
|
||||||
/* Try all submatches */
|
/* Try all submatches */
|
||||||
do
|
do
|
||||||
{
|
{
|
||||||
res |= wildcard_complete_internal( orig, str, wc+1, 0, desc, desc_func, out, flags );
|
res = wildcard_complete_internal( orig, str, wc+1, 0, desc, desc_func, out, flags );
|
||||||
if( res )
|
if (res)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
while( *str++ != 0 );
|
while (*str++ != 0);
|
||||||
return res;
|
return res;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -302,20 +294,18 @@ static int wildcard_complete_internal( const wchar_t *orig,
|
||||||
{
|
{
|
||||||
return wildcard_complete_internal( orig, str+1, wc+1, 0, desc, desc_func, out, flags | COMPLETE_NO_CASE );
|
return wildcard_complete_internal( orig, str+1, wc+1, 0, desc, desc_func, out, flags | COMPLETE_NO_CASE );
|
||||||
}
|
}
|
||||||
return 0;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
int wildcard_complete( const wchar_t *str,
|
bool wildcard_complete(const wcstring &str,
|
||||||
const wchar_t *wc,
|
const wchar_t *wc,
|
||||||
const wchar_t *desc,
|
const wchar_t *desc,
|
||||||
const wchar_t *(*desc_func)(const wcstring &),
|
const wchar_t *(*desc_func)(const wcstring &),
|
||||||
std::vector<completion_t> &out,
|
std::vector<completion_t> &out,
|
||||||
int flags )
|
int flags )
|
||||||
{
|
{
|
||||||
int res;
|
bool res;
|
||||||
|
res = wildcard_complete_internal( str, str.c_str(), wc, true, desc, desc_func, out, flags );
|
||||||
res = wildcard_complete_internal( str, str, wc, 1, desc, desc_func, out, flags );
|
|
||||||
|
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -570,14 +560,13 @@ static wcstring file_get_desc( const wchar_t *filename,
|
||||||
*/
|
*/
|
||||||
static void wildcard_completion_allocate( std::vector<completion_t> &list,
|
static void wildcard_completion_allocate( std::vector<completion_t> &list,
|
||||||
const wcstring &fullname,
|
const wcstring &fullname,
|
||||||
const wchar_t *completion,
|
const wcstring &completion,
|
||||||
const wchar_t *wc,
|
const wchar_t *wc,
|
||||||
expand_flags_t expand_flags)
|
expand_flags_t expand_flags)
|
||||||
{
|
{
|
||||||
struct stat buf, lbuf;
|
struct stat buf, lbuf;
|
||||||
wcstring sb;
|
wcstring sb;
|
||||||
|
wcstring munged_completion;
|
||||||
int free_completion = 0;
|
|
||||||
|
|
||||||
int flags = 0;
|
int flags = 0;
|
||||||
int stat_res, lstat_res;
|
int stat_res, lstat_res;
|
||||||
|
@ -593,12 +582,13 @@ static void wildcard_completion_allocate( std::vector<completion_t> &list,
|
||||||
*/
|
*/
|
||||||
if( ( lstat_res = lwstat( fullname, &lbuf ) ) )
|
if( ( lstat_res = lwstat( fullname, &lbuf ) ) )
|
||||||
{
|
{
|
||||||
|
/* lstat failed! */
|
||||||
sz=-1;
|
sz=-1;
|
||||||
stat_res = lstat_res;
|
stat_res = lstat_res;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if( S_ISLNK(lbuf.st_mode))
|
if (S_ISLNK(lbuf.st_mode))
|
||||||
{
|
{
|
||||||
|
|
||||||
if( ( stat_res = wstat( fullname, &buf ) ) )
|
if( ( stat_res = wstat( fullname, &buf ) ) )
|
||||||
|
@ -630,9 +620,9 @@ static void wildcard_completion_allocate( std::vector<completion_t> &list,
|
||||||
|
|
||||||
if( sz >= 0 && S_ISDIR(buf.st_mode) )
|
if( sz >= 0 && S_ISDIR(buf.st_mode) )
|
||||||
{
|
{
|
||||||
free_completion = 1;
|
|
||||||
flags = flags | COMPLETE_NO_SPACE;
|
flags = flags | COMPLETE_NO_SPACE;
|
||||||
completion = wcsdupcat( completion, L"/" );
|
munged_completion = completion;
|
||||||
|
munged_completion.push_back(L'/');
|
||||||
sb.append(desc);
|
sb.append(desc);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -642,9 +632,8 @@ static void wildcard_completion_allocate( std::vector<completion_t> &list,
|
||||||
sb.append(format_size(sz));
|
sb.append(format_size(sz));
|
||||||
}
|
}
|
||||||
|
|
||||||
wildcard_complete( completion, wc, sb.c_str(), NULL, list, flags );
|
const wcstring &completion_to_use = munged_completion.empty() ? completion : munged_completion;
|
||||||
if( free_completion )
|
wildcard_complete(completion_to_use, wc, sb.c_str(), NULL, list, flags);
|
||||||
free( (void *)completion );
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -790,7 +779,7 @@ static int wildcard_expand_internal( const wchar_t *wc,
|
||||||
{
|
{
|
||||||
wildcard_completion_allocate( out,
|
wildcard_completion_allocate( out,
|
||||||
long_name,
|
long_name,
|
||||||
next.c_str(),
|
next,
|
||||||
L"",
|
L"",
|
||||||
flags);
|
flags);
|
||||||
}
|
}
|
||||||
|
@ -812,7 +801,7 @@ static int wildcard_expand_internal( const wchar_t *wc,
|
||||||
This is the last wildcard segment, and it is not empty. Match files/directories.
|
This is the last wildcard segment, and it is not empty. Match files/directories.
|
||||||
*/
|
*/
|
||||||
wcstring next;
|
wcstring next;
|
||||||
while(wreaddir(dir, next))
|
while (wreaddir(dir, next))
|
||||||
{
|
{
|
||||||
const wchar_t * const name = next.c_str();
|
const wchar_t * const name = next.c_str();
|
||||||
if( flags & ACCEPT_INCOMPLETE )
|
if( flags & ACCEPT_INCOMPLETE )
|
||||||
|
|
|
@ -86,7 +86,7 @@ int wildcard_has( const wchar_t *str, int internal );
|
||||||
/**
|
/**
|
||||||
Test wildcard completion
|
Test wildcard completion
|
||||||
*/
|
*/
|
||||||
int wildcard_complete( const wchar_t *str,
|
bool wildcard_complete(const wcstring &str,
|
||||||
const wchar_t *wc,
|
const wchar_t *wc,
|
||||||
const wchar_t *desc,
|
const wchar_t *desc,
|
||||||
const wchar_t *(*desc_func)(const wcstring &),
|
const wchar_t *(*desc_func)(const wcstring &),
|
||||||
|
|
Loading…
Reference in a new issue