Fix to make completions non-authoritative by default, which is why unknown options were always colored like errors (e.g. --rebase)

This commit is contained in:
ridiculousfish 2012-08-06 23:34:55 -07:00
parent 84729c4dfa
commit 6eb66770a4
3 changed files with 66 additions and 83 deletions

View file

@ -432,7 +432,7 @@ bool completer_t::condition_test( const wcstring &condition )
/** Search for an exactly matching completion entry. Must be called while locked. */
static completion_entry_t *complete_find_exact_entry( const wchar_t *cmd, const bool cmd_is_path )
static completion_entry_t *complete_find_exact_entry( const wcstring &cmd, const bool cmd_is_path )
{
ASSERT_IS_LOCKED(completion_lock);
completion_entry_t *result = NULL;
@ -445,7 +445,7 @@ static completion_entry_t *complete_find_exact_entry( const wchar_t *cmd, const
}
/** Locate the specified entry. Create it if it doesn't exist. Must be called while locked. */
static completion_entry_t *complete_get_exact_entry( const wchar_t *cmd, bool cmd_is_path )
static completion_entry_t *complete_get_exact_entry( const wcstring &cmd, bool cmd_is_path )
{
ASSERT_IS_LOCKED(completion_lock);
completion_entry_t *c;
@ -454,7 +454,7 @@ static completion_entry_t *complete_get_exact_entry( const wchar_t *cmd, bool cm
if( c == NULL )
{
c = new completion_entry_t(cmd, cmd_is_path, L"", true);
c = new completion_entry_t(cmd, cmd_is_path, L"", false);
completion_set.insert(c);
}
@ -623,71 +623,69 @@ static void parse_cmd_string(const wcstring &str, wcstring &path, wcstring &cmd)
}
}
int complete_is_valid_option( const wchar_t *str,
const wchar_t *opt,
int complete_is_valid_option( const wcstring &str,
const wcstring &opt,
wcstring_list_t *errors,
bool allow_autoload )
{
wcstring cmd, path;
int found_match = 0;
int authoritative = 1;
bool found_match = false;
bool authoritative = true;
int opt_found=0;
std::set<wcstring> gnu_match_set;
int is_gnu_opt=0;
int is_old_opt=0;
int is_short_opt=0;
int is_gnu_exact=0;
bool is_gnu_opt=false;
bool is_old_opt=false;
bool is_short_opt=false;
bool is_gnu_exact=false;
size_t gnu_opt_len=0;
std::vector<char> short_validated;
CHECK( str, 0 );
CHECK( opt, 0 );
if (opt.empty())
return false;
std::vector<bool> short_validated;
/*
Check some generic things like -- and - options.
*/
switch( wcslen(opt ) )
switch( opt.size() )
{
case 0:
case 1:
{
return 1;
return true;
}
case 2:
{
if( wcscmp( L"--", opt ) == 0 )
if( opt == L"--" )
{
return 1;
return true;
}
break;
}
}
if( opt[0] != L'-' )
if( opt.at(0) != L'-' )
{
if( errors )
errors->push_back(L"Option does not begin with a '-'");
return 0;
return false;
}
short_validated.resize(wcslen(opt), 0);
short_validated.resize(opt.size(), 0);
is_gnu_opt = opt[1]==L'-';
is_gnu_opt = opt.at(1) == L'-';
if( is_gnu_opt )
{
const wchar_t *opt_end = wcschr(opt, L'=' );
if( opt_end )
size_t opt_end = opt.find(L'=');
if( opt_end != wcstring::npos )
{
gnu_opt_len = (opt_end-opt)-2;
gnu_opt_len = opt_end-2;
}
else
{
gnu_opt_len = wcslen(opt)-2;
gnu_opt_len = opt.size() - 2;
}
}
@ -706,18 +704,17 @@ int complete_is_valid_option( const wchar_t *str,
{
const completion_entry_t *i = *iter;
const wcstring &match = i->cmd_is_path ? path : cmd;
const wchar_t *a;
if( !wildcard_match( match, i->cmd ) )
{
continue;
}
found_match = 1;
found_match = true;
if( !i->authoritative )
if (! i->authoritative)
{
authoritative = 0;
authoritative = false;
break;
}
@ -732,14 +729,12 @@ int complete_is_valid_option( const wchar_t *str,
continue;
}
if (wcsncmp(&opt[2], o.long_opt.c_str(), gnu_opt_len) == 0)
if (opt.compare(2, gnu_opt_len, o.long_opt) == 0)
{
gnu_match_set.insert(o.long_opt);
if( (wcsncmp( &opt[2],
o.long_opt.c_str(),
o.long_opt.size())==0) )
if (opt.compare(2, o.long_opt.size(), o.long_opt))
{
is_gnu_exact=1;
is_gnu_exact = true;
}
}
}
@ -755,10 +750,10 @@ int complete_is_valid_option( const wchar_t *str,
continue;
if( wcscmp( &opt[1], o.long_opt.c_str() )==0)
if( opt.compare(1, wcstring::npos, o.long_opt )==0)
{
opt_found = 1;
is_old_opt = 1;
opt_found = true;
is_old_opt = true;
break;
}
@ -767,12 +762,10 @@ int complete_is_valid_option( const wchar_t *str,
if( is_old_opt )
break;
for( a = &opt[1]; *a; a++ )
for (size_t opt_idx = 1; opt_idx < opt.size(); opt_idx++)
{
const wcstring &short_opt_str = i->get_short_opt_str();
size_t str_idx = short_opt_str.find(*a);
size_t str_idx = short_opt_str.find(opt.at(opt_idx));
if (str_idx != wcstring::npos )
{
if (str_idx + 1 < short_opt_str.size() && short_opt_str.at(str_idx + 1) == L':' )
@ -781,17 +774,13 @@ int complete_is_valid_option( const wchar_t *str,
This is a short option with an embedded argument,
call complete_is_valid_argument on the argument.
*/
wchar_t nopt[3];
nopt[0]=L'-';
nopt[1]=opt[1];
nopt[2]=L'\0';
short_validated.at(a-opt) =
complete_is_valid_argument( str, nopt, &opt[2]);
const wcstring nopt = L"-" + opt.substr(1, 1);
short_validated.at(opt_idx) =
complete_is_valid_argument( str, nopt, opt.substr(2));
}
else
{
short_validated.at(a-opt)=1;
short_validated.at(opt_idx) = true;
}
}
}
@ -807,19 +796,15 @@ int complete_is_valid_option( const wchar_t *str,
if( is_short_opt )
{
size_t j;
opt_found=1;
for( j=1; j<wcslen(opt); j++)
for( size_t j=1; j<opt.size(); j++)
{
if ( !short_validated.at(j))
{
if( errors )
{
wchar_t str[2];
str[0] = opt[j];
str[1]=0;
errors->push_back(format_error(_(L"Unknown option: "), str));
const wcstring str = opt.substr(j, 1);
errors->push_back(format_error(_(L"Unknown option: "), str.c_str()));
}
opt_found = 0;
@ -848,14 +833,12 @@ int complete_is_valid_option( const wchar_t *str,
}
}
return (authoritative && found_match)?opt_found:1;
return (authoritative && found_match)?opt_found:true;
}
int complete_is_valid_argument( const wchar_t *str,
const wchar_t *opt,
const wchar_t *arg )
bool complete_is_valid_argument( const wcstring &str, const wcstring &opt, const wcstring &arg )
{
return 1;
return true;
}

View file

@ -199,15 +199,15 @@ void sort_completions( std::vector<completion_t> &completions);
\param flags A set of completion flags
*/
void complete_add( const wchar_t *cmd,
bool cmd_is_path,
wchar_t short_opt,
const wchar_t *long_opt,
int long_mode,
int result_mode,
const wchar_t *condition,
const wchar_t *comp,
const wchar_t *desc,
int flags );
bool cmd_is_path,
wchar_t short_opt,
const wchar_t *long_opt,
int long_mode,
int result_mode,
const wchar_t *condition,
const wchar_t *comp,
const wchar_t *desc,
int flags );
/**
Sets whether the completion list for this command is complete. If
true, any options not matching one of the provided options will be
@ -219,9 +219,9 @@ void complete_set_authoritative( const wchar_t *cmd, bool cmd_type, bool authori
Remove a previously defined completion
*/
void complete_remove( const wchar_t *cmd,
bool cmd_is_path,
wchar_t short_opt,
const wchar_t *long_opt );
bool cmd_is_path,
wchar_t short_opt,
const wchar_t *long_opt );
/** Find all completions of the command cmd, insert them into out. If to_load is not NULL, append all commands that we would autoload, but did not (presumably because this is not the main thread) */
@ -237,8 +237,8 @@ void complete_print( wcstring &out );
/**
Tests if the specified option is defined for the specified command
*/
int complete_is_valid_option( const wchar_t *str,
const wchar_t *opt,
int complete_is_valid_option( const wcstring &str,
const wcstring &opt,
wcstring_list_t *inErrorsOrNull,
bool allow_autoload );
@ -246,9 +246,9 @@ int complete_is_valid_option( const wchar_t *str,
Tests if the specified argument is valid for the specified option
and command
*/
int complete_is_valid_argument( const wchar_t *str,
const wchar_t *opt,
const wchar_t *arg );
bool complete_is_valid_argument( const wcstring &str,
const wcstring &opt,
const wcstring &arg );
/**

View file

@ -935,7 +935,7 @@ static void tokenize( const wchar_t * const buff, std::vector<int> &color, const
}
else if( accept_switches )
{
if( complete_is_valid_option( last_cmd.c_str(), param, error, false /* no autoload */ ) )
if( complete_is_valid_option( last_cmd, param, error, false /* no autoload */ ) )
color.at(tok_get_pos( &tok )) = HIGHLIGHT_PARAM;
else
color.at(tok_get_pos( &tok )) = HIGHLIGHT_ERROR;