diff --git a/highlight.cpp b/highlight.cpp index 09a7666a3..549159c5c 100644 --- a/highlight.cpp +++ b/highlight.cpp @@ -33,6 +33,7 @@ #include "output.h" #include "wildcard.h" #include "path.h" +#include "history.h" /** Number of elements in the highlight_var array @@ -810,17 +811,16 @@ bool autosuggest_suggest_special(const wcstring &str, const wcstring &working_di return result; } -bool autosuggest_special_validate_from_history(const wcstring &str, const wcstring &working_directory, bool *outSuggestionOK) { +bool autosuggest_validate_from_history(const history_item_t &item, file_detection_context_t &detector, const wcstring &working_directory, const env_vars &vars) { ASSERT_IS_BACKGROUND_THREAD(); - assert(outSuggestionOK != NULL); - + bool handled = false, suggestionOK = false; /* Parse the string */ wcstring parsed_command; wcstring_list_t parsed_arguments; int parsed_last_arg_pos = -1; - if (! autosuggest_parse_command(str, &parsed_command, &parsed_arguments, &parsed_last_arg_pos)) + if (! autosuggest_parse_command(item.str(), &parsed_command, &parsed_arguments, &parsed_last_arg_pos)) return false; if (parsed_command == L"cd" && ! parsed_arguments.empty()) { @@ -845,11 +845,34 @@ bool autosuggest_special_validate_from_history(const wcstring &str, const wcstri free(path); } } - } else { - /* Either an error or some other command, so we don't handle it specially */ + } + + /* If not handled specially, handle it here */ + if (! handled) { + bool cmd_ok = false; + + wchar_t *full_path = path_get_path(parsed_command.c_str()); + if (full_path) { + cmd_ok = true; + free(full_path); + } + else if (builtin_exists(parsed_command) || function_exists_no_autoload(parsed_command, vars)) { + cmd_ok = true; + } + + if (cmd_ok) { + const path_list_t &paths = item.get_required_paths(); + if (paths.empty()) { + suggestionOK= true; + } + else { + detector.potential_paths = paths; + suggestionOK = detector.paths_are_valid(paths); + } + } } - *outSuggestionOK = suggestionOK; - return handled; + + return suggestionOK; } // This function does I/O diff --git a/highlight.h b/highlight.h index 11ed9e4f5..3d4a4fe8e 100644 --- a/highlight.h +++ b/highlight.h @@ -70,6 +70,9 @@ */ #define HIGHLIGHT_AUTOSUGGESTION 0x2000 +class history_item_t; +class file_detection_context_t; + /** Perform syntax highlighting for the shell commands in buff. The result is stored in the color array as a color_code from the HIGHLIGHT_ enum @@ -109,7 +112,7 @@ rgb_color_t highlight_get_color( int highlight, bool is_background ); /** Given a command 'str' from the history, try to determine whether we ought to suggest it by specially recognizing the command. Returns true if we validated the command. If so, returns by reference whether the suggestion is valid or not. */ -bool autosuggest_special_validate_from_history(const wcstring &str, const wcstring &working_directory, bool *outSuggestionOK); +bool autosuggest_validate_from_history(const history_item_t &item, file_detection_context_t &detector, const wcstring &working_directory, const env_vars &vars); /** Given the command line contents 'str', return via reference a suggestion by specially recognizing the command. Returns true if we recognized the command (even if we couldn't think of a suggestion for it). */ diff --git a/reader.cpp b/reader.cpp index d7f5235da..9b2960cc9 100644 --- a/reader.cpp +++ b/reader.cpp @@ -1255,23 +1255,12 @@ struct autosuggestion_context_t { if (item.str().find('\n') != wcstring::npos) continue; - bool item_ok = false; - if (autosuggest_special_validate_from_history(item.str(), working_directory, &item_ok)) { + if (autosuggest_validate_from_history(item, detector, working_directory, vars)) { /* The command autosuggestion was handled specially, so we're done */ - } else { - /* See if the item has any required paths */ - const path_list_t &paths = item.get_required_paths(); - if (paths.empty()) { - item_ok = true; - } else { - detector.potential_paths = paths; - item_ok = detector.paths_are_valid(paths); - } - } - if (item_ok) { this->autosuggestion = searcher.current_string(); return 1; } + } /* Try handling a special command like cd */