From c10b3017d6479bbfeceb3a466b6b2c04aa24d9b8 Mon Sep 17 00:00:00 2001 From: ridiculousfish Date: Fri, 30 Mar 2012 11:16:24 -0700 Subject: [PATCH] Improve autosuggesting of cd command --- highlight.cpp | 24 ++++++++++++++++++------ reader.cpp | 15 ++++++++------- 2 files changed, 26 insertions(+), 13 deletions(-) diff --git a/highlight.cpp b/highlight.cpp index 02b084ec1..3f4cde855 100644 --- a/highlight.cpp +++ b/highlight.cpp @@ -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) { diff --git a/reader.cpp b/reader.cpp index bde0bcb1e..5bf7cebb4 100644 --- a/reader.cpp +++ b/reader.cpp @@ -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 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; } };