From 6eb66770a499444edf15810e4f1fcf7694b71430 Mon Sep 17 00:00:00 2001 From: ridiculousfish Date: Mon, 6 Aug 2012 23:34:55 -0700 Subject: [PATCH] Fix to make completions non-authoritative by default, which is why unknown options were always colored like errors (e.g. --rebase) --- complete.cpp | 113 +++++++++++++++++++++----------------------------- complete.h | 34 +++++++-------- highlight.cpp | 2 +- 3 files changed, 66 insertions(+), 83 deletions(-) diff --git a/complete.cpp b/complete.cpp index e2bb336bb..14d372c19 100644 --- a/complete.cpp +++ b/complete.cpp @@ -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 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 short_validated; - - - CHECK( str, 0 ); - CHECK( opt, 0 ); - + if (opt.empty()) + return false; + + std::vector 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; jpush_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; } diff --git a/complete.h b/complete.h index ddf601719..3b5bc619e 100644 --- a/complete.h +++ b/complete.h @@ -199,15 +199,15 @@ void sort_completions( std::vector &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 ); /** diff --git a/highlight.cpp b/highlight.cpp index e0c99778d..c232c4007 100644 --- a/highlight.cpp +++ b/highlight.cpp @@ -935,7 +935,7 @@ static void tokenize( const wchar_t * const buff, std::vector &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;