Improve autosuggesting of cd command

This commit is contained in:
ridiculousfish 2012-03-30 11:16:24 -07:00
parent 0f63e1f988
commit c10b3017d6
2 changed files with 26 additions and 13 deletions

View File

@ -533,15 +533,15 @@ static int has_expand_reserved( const wchar_t *str )
return 0;
}
/* Attempts to suggest a completion for a command we handle specially, like 'cd'. Returns true if we recognized the command (even if we couldn't think of a suggestion for it) */
bool autosuggest_suggest_special(const wcstring &str, const wcstring &working_directory, wcstring &outString) {
if (str.empty())
return false;
wcstring cmd;
bool had_cmd = false;
bool had_cmd = false, recognized_cmd = false;
wcstring suggestion;
bool suggestionOK = false;
tokenizer tok;
for( tok_init( &tok, str.c_str(), TOK_SQUASH_ERRORS );
@ -556,12 +556,22 @@ bool autosuggest_suggest_special(const wcstring &str, const wcstring &working_di
{
if( had_cmd )
{
if( cmd == L"cd" )
recognized_cmd = (cmd == L"cd");
if( recognized_cmd )
{
wcstring dir = tok_last( &tok );
wcstring suggested_path;
if (is_potential_path(dir, &suggested_path, true /* require directory */)) {
suggestionOK = true;
/* suggested_path needs to actually have dir as a prefix (perhaps with different case). Handle stuff like ./ */
bool wants_dot_slash = string_prefixes_string(L"./", dir);
bool has_dot_slash = string_prefixes_string(L"./", suggested_path);
if (wants_dot_slash && ! has_dot_slash) {
suggested_path.insert(0, L"./");
} else if (! wants_dot_slash && has_dot_slash) {
suggested_path.erase(0, 2);
}
suggestion = str;
suggestion.erase(tok_get_pos(&tok));
suggestion.append(suggested_path);
@ -668,9 +678,11 @@ bool autosuggest_suggest_special(const wcstring &str, const wcstring &working_di
}
tok_destroy( &tok );
if (suggestionOK)
if (recognized_cmd) {
outString.swap(suggestion);
return suggestionOK;
}
return recognized_cmd;
}
bool autosuggest_handle_special(const wcstring &str, const wcstring &working_directory, bool *outSuggestionOK) {

View File

@ -1249,6 +1249,7 @@ struct autosuggestion_context_t {
int threaded_autosuggest(void) {
ASSERT_IS_BACKGROUND_THREAD();
/* If the main thread has moved on, skip all the work */
if (generation_count != s_generation_count) {
return 0;
}
@ -1279,6 +1280,13 @@ struct autosuggestion_context_t {
}
}
/* Try handling a special command like cd */
wcstring special_suggestion;
if (autosuggest_suggest_special(search_string, working_directory, special_suggestion)) {
this->autosuggestion = special_suggestion;
return 1;
}
/* Try normal completions */
std::vector<completion_t> completions;
complete(search_string, completions, COMPLETE_AUTOSUGGEST, &this->commands_to_load);
@ -1303,13 +1311,6 @@ struct autosuggestion_context_t {
return 1;
}
/* Since we didn't find a suggestion from history, try other means */
wcstring special_suggestion;
if (autosuggest_suggest_special(search_string, working_directory, special_suggestion)) {
this->autosuggestion = special_suggestion;
return 1;
}
return 0;
}
};