Index: lldb/trunk/include/lldb/Core/FormatEntity.h =================================================================== --- lldb/trunk/include/lldb/Core/FormatEntity.h +++ lldb/trunk/include/lldb/Core/FormatEntity.h @@ -10,6 +10,7 @@ #ifndef liblldb_FormatEntity_h_ #define liblldb_FormatEntity_h_ +#include "lldb/Utility/CompletionRequest.h" #include "lldb/Utility/FileSpec.h" // for FileSpec #include "lldb/Utility/Status.h" #include "lldb/lldb-enumerations.h" // for Format::eFormatDefault, Format @@ -211,9 +212,7 @@ llvm::StringRef &variable_name, llvm::StringRef &variable_format); - static size_t AutoComplete(llvm::StringRef s, int match_start_point, - int max_return_elements, bool &word_complete, - StringList &matches); + static size_t AutoComplete(lldb_private::CompletionRequest &request); //---------------------------------------------------------------------- // Format the current elements into the stream \a s. Index: lldb/trunk/include/lldb/Interpreter/CommandCompletions.h =================================================================== --- lldb/trunk/include/lldb/Interpreter/CommandCompletions.h +++ lldb/trunk/include/lldb/Interpreter/CommandCompletions.h @@ -18,6 +18,7 @@ // Project includes #include "lldb/Core/FileSpecList.h" #include "lldb/Core/SearchFilter.h" +#include "lldb/Utility/CompletionRequest.h" #include "lldb/Utility/RegularExpression.h" #include "lldb/lldb-private.h" @@ -32,16 +33,10 @@ // argument of the option it is bound to (in the OptionDefinition table // below). Return the total number of matches. //---------------------------------------------------------------------- - typedef int (*CompletionCallback)( - CommandInterpreter &interpreter, - llvm::StringRef completion_str, // This is the argument we are completing - int match_start_point, // This is the point in the list of matches that - // you should start returning elements - int max_return_elements, // This is the number of matches requested. - lldb_private::SearchFilter - *searcher, // A search filter to limit the search... - bool &word_complete, - lldb_private::StringList &matches); // The array of matches we return. + typedef int (*CompletionCallback)(CommandInterpreter &interpreter, + CompletionRequest &request, + // A search filter to limit the search... + lldb_private::SearchFilter *searcher); typedef enum { eNoCompletion = 0u, eSourceFileCompletion = (1u << 0), @@ -66,70 +61,47 @@ static bool InvokeCommonCompletionCallbacks( CommandInterpreter &interpreter, uint32_t completion_mask, - llvm::StringRef completion_str, int match_start_point, - int max_return_elements, SearchFilter *searcher, bool &word_complete, - StringList &matches); + lldb_private::CompletionRequest &request, SearchFilter *searcher); //---------------------------------------------------------------------- // These are the generic completer functions: //---------------------------------------------------------------------- static int DiskFiles(CommandInterpreter &interpreter, - llvm::StringRef partial_file_name, int match_start_point, - int max_return_elements, SearchFilter *searcher, - bool &word_complete, StringList &matches); + CompletionRequest &request, SearchFilter *searcher); static int DiskFiles(const llvm::Twine &partial_file_name, StringList &matches, TildeExpressionResolver &Resolver); static int DiskDirectories(CommandInterpreter &interpreter, - llvm::StringRef partial_file_name, - int match_start_point, int max_return_elements, - SearchFilter *searcher, bool &word_complete, - StringList &matches); + CompletionRequest &request, + SearchFilter *searcher); static int DiskDirectories(const llvm::Twine &partial_file_name, StringList &matches, TildeExpressionResolver &Resolver); static int SourceFiles(CommandInterpreter &interpreter, - llvm::StringRef partial_file_name, - int match_start_point, int max_return_elements, - SearchFilter *searcher, bool &word_complete, - StringList &matches); + CompletionRequest &request, SearchFilter *searcher); static int Modules(CommandInterpreter &interpreter, - llvm::StringRef partial_file_name, int match_start_point, - int max_return_elements, SearchFilter *searcher, - bool &word_complete, lldb_private::StringList &matches); + CompletionRequest &request, SearchFilter *searcher); static int Symbols(CommandInterpreter &interpreter, - llvm::StringRef partial_file_name, int match_start_point, - int max_return_elements, SearchFilter *searcher, - bool &word_complete, lldb_private::StringList &matches); + CompletionRequest &request, SearchFilter *searcher); static int SettingsNames(CommandInterpreter &interpreter, - llvm::StringRef partial_file_name, - int match_start_point, int max_return_elements, - SearchFilter *searcher, bool &word_complete, - lldb_private::StringList &matches); + CompletionRequest &request, SearchFilter *searcher); static int PlatformPluginNames(CommandInterpreter &interpreter, - llvm::StringRef partial_file_name, - int match_start_point, int max_return_elements, - SearchFilter *searcher, bool &word_complete, - lldb_private::StringList &matches); + CompletionRequest &request, + SearchFilter *searcher); static int ArchitectureNames(CommandInterpreter &interpreter, - llvm::StringRef partial_file_name, - int match_start_point, int max_return_elements, - SearchFilter *searcher, bool &word_complete, - lldb_private::StringList &matches); + CompletionRequest &request, + SearchFilter *searcher); static int VariablePath(CommandInterpreter &interpreter, - llvm::StringRef partial_file_name, - int match_start_point, int max_return_elements, - SearchFilter *searcher, bool &word_complete, - lldb_private::StringList &matches); + CompletionRequest &request, SearchFilter *searcher); //---------------------------------------------------------------------- // The Completer class is a convenient base class for building searchers that @@ -137,9 +109,7 @@ //---------------------------------------------------------------------- class Completer : public Searcher { public: - Completer(CommandInterpreter &interpreter, llvm::StringRef completion_str, - int match_start_point, int max_return_elements, - StringList &matches); + Completer(CommandInterpreter &interpreter, CompletionRequest &request); ~Completer() override; @@ -152,10 +122,7 @@ protected: CommandInterpreter &m_interpreter; - std::string m_completion_str; - int m_match_start_point; - int m_max_return_elements; - StringList &m_matches; + CompletionRequest &m_request; private: DISALLOW_COPY_AND_ASSIGN(Completer); @@ -167,9 +134,7 @@ class SourceFileCompleter : public Completer { public: SourceFileCompleter(CommandInterpreter &interpreter, - bool include_support_files, - llvm::StringRef completion_str, int match_start_point, - int max_return_elements, StringList &matches); + bool include_support_files, CompletionRequest &request); Searcher::Depth GetDepth() override; @@ -195,8 +160,7 @@ class ModuleCompleter : public Completer { public: ModuleCompleter(CommandInterpreter &interpreter, - llvm::StringRef completion_str, int match_start_point, - int max_return_elements, StringList &matches); + CompletionRequest &request); Searcher::Depth GetDepth() override; @@ -220,8 +184,7 @@ class SymbolCompleter : public Completer { public: SymbolCompleter(CommandInterpreter &interpreter, - llvm::StringRef completion_str, int match_start_point, - int max_return_elements, StringList &matches); + CompletionRequest &request); Searcher::Depth GetDepth() override; Index: lldb/trunk/include/lldb/Interpreter/OptionValue.h =================================================================== --- lldb/trunk/include/lldb/Interpreter/OptionValue.h +++ lldb/trunk/include/lldb/Interpreter/OptionValue.h @@ -15,6 +15,7 @@ // Other libraries and framework includes // Project includes #include "lldb/Core/FormatEntity.h" +#include "lldb/Utility/CompletionRequest.h" #include "lldb/Utility/ConstString.h" #include "lldb/Utility/Status.h" #include "lldb/lldb-defines.h" @@ -100,9 +101,7 @@ virtual lldb::OptionValueSP DeepCopy() const = 0; virtual size_t AutoComplete(CommandInterpreter &interpreter, - llvm::StringRef s, int match_start_point, - int max_return_elements, bool &word_complete, - StringList &matches); + CompletionRequest &request); //----------------------------------------------------------------- // Subclasses can override these functions Index: lldb/trunk/include/lldb/Interpreter/OptionValueArch.h =================================================================== --- lldb/trunk/include/lldb/Interpreter/OptionValueArch.h +++ lldb/trunk/include/lldb/Interpreter/OptionValueArch.h @@ -57,9 +57,8 @@ lldb::OptionValueSP DeepCopy() const override; - size_t AutoComplete(CommandInterpreter &interpreter, llvm::StringRef s, - int match_start_point, int max_return_elements, - bool &word_complete, StringList &matches) override; + size_t AutoComplete(CommandInterpreter &interpreter, + lldb_private::CompletionRequest &request) override; //--------------------------------------------------------------------- // Subclass specific functions Index: lldb/trunk/include/lldb/Interpreter/OptionValueBoolean.h =================================================================== --- lldb/trunk/include/lldb/Interpreter/OptionValueBoolean.h +++ lldb/trunk/include/lldb/Interpreter/OptionValueBoolean.h @@ -50,9 +50,8 @@ return true; } - size_t AutoComplete(CommandInterpreter &interpreter, llvm::StringRef s, - int match_start_point, int max_return_elements, - bool &word_complete, StringList &matches) override; + size_t AutoComplete(CommandInterpreter &interpreter, + CompletionRequest &request) override; //--------------------------------------------------------------------- // Subclass specific functions Index: lldb/trunk/include/lldb/Interpreter/OptionValueEnumeration.h =================================================================== --- lldb/trunk/include/lldb/Interpreter/OptionValueEnumeration.h +++ lldb/trunk/include/lldb/Interpreter/OptionValueEnumeration.h @@ -59,9 +59,8 @@ lldb::OptionValueSP DeepCopy() const override; - size_t AutoComplete(CommandInterpreter &interpreter, llvm::StringRef s, - int match_start_point, int max_return_elements, - bool &word_complete, StringList &matches) override; + size_t AutoComplete(CommandInterpreter &interpreter, + CompletionRequest &request) override; //--------------------------------------------------------------------- // Subclass specific functions Index: lldb/trunk/include/lldb/Interpreter/OptionValueFileSpec.h =================================================================== --- lldb/trunk/include/lldb/Interpreter/OptionValueFileSpec.h +++ lldb/trunk/include/lldb/Interpreter/OptionValueFileSpec.h @@ -54,9 +54,8 @@ lldb::OptionValueSP DeepCopy() const override; - size_t AutoComplete(CommandInterpreter &interpreter, llvm::StringRef s, - int match_start_point, int max_return_elements, - bool &word_complete, StringList &matches) override; + size_t AutoComplete(CommandInterpreter &interpreter, + CompletionRequest &request) override; //--------------------------------------------------------------------- // Subclass specific functions Index: lldb/trunk/include/lldb/Interpreter/OptionValueFormatEntity.h =================================================================== --- lldb/trunk/include/lldb/Interpreter/OptionValueFormatEntity.h +++ lldb/trunk/include/lldb/Interpreter/OptionValueFormatEntity.h @@ -45,9 +45,8 @@ lldb::OptionValueSP DeepCopy() const override; - size_t AutoComplete(CommandInterpreter &interpreter, llvm::StringRef s, - int match_start_point, int max_return_elements, - bool &word_complete, StringList &matches) override; + size_t AutoComplete(CommandInterpreter &interpreter, + CompletionRequest &request) override; //--------------------------------------------------------------------- // Subclass specific functions Index: lldb/trunk/include/lldb/Interpreter/OptionValueUUID.h =================================================================== --- lldb/trunk/include/lldb/Interpreter/OptionValueUUID.h +++ lldb/trunk/include/lldb/Interpreter/OptionValueUUID.h @@ -61,9 +61,8 @@ void SetCurrentValue(const UUID &value) { m_uuid = value; } - size_t AutoComplete(CommandInterpreter &interpreter, llvm::StringRef s, - int match_start_point, int max_return_elements, - bool &word_complete, StringList &matches) override; + size_t AutoComplete(CommandInterpreter &interpreter, + CompletionRequest &request) override; protected: UUID m_uuid; Index: lldb/trunk/include/lldb/Interpreter/Options.h =================================================================== --- lldb/trunk/include/lldb/Interpreter/Options.h +++ lldb/trunk/include/lldb/Interpreter/Options.h @@ -176,30 +176,12 @@ /// Handles the generic bits of figuring out whether we are in an option, /// and if so completing it. /// - /// @param[in] input - /// The command line parsed into words - /// - /// @param[in] cursor_index - /// The index in \ainput of the word in which the cursor lies. - /// - /// @param[in] char_pos - /// The character position of the cursor in its argument word. - /// - /// @param[in] match_start_point - /// @param[in] match_return_elements - /// See CommandObject::HandleCompletions for a description of - /// how these work. + /// @param[in/out] request + /// The completion request that we need to act upon. /// /// @param[in] interpreter /// The interpreter that's doing the completing. /// - /// @param[out] word_complete - /// \btrue if this is a complete option value (a space will be - /// inserted after the completion.) \b false otherwise. - /// - /// @param[out] matches - /// The array of matches returned. - /// /// FIXME: This is the wrong return value, since we also need to /// make a distinction between total number of matches, and the window the /// user wants returned. @@ -207,50 +189,19 @@ /// @return /// \btrue if we were in an option, \bfalse otherwise. //------------------------------------------------------------------ - bool HandleOptionCompletion(Args &input, OptionElementVector &option_map, - int cursor_index, int char_pos, - int match_start_point, int max_return_elements, - CommandInterpreter &interpreter, - bool &word_complete, - lldb_private::StringList &matches); + bool HandleOptionCompletion(lldb_private::CompletionRequest &request, + OptionElementVector &option_map, + CommandInterpreter &interpreter); //------------------------------------------------------------------ /// Handles the generic bits of figuring out whether we are in an option, /// and if so completing it. /// - /// @param[in] interpreter - /// The command interpreter doing the completion. - /// - /// @param[in] input - /// The command line parsed into words - /// - /// @param[in] cursor_index - /// The index in \ainput of the word in which the cursor lies. - /// - /// @param[in] char_pos - /// The character position of the cursor in its argument word. - /// - /// @param[in] opt_element_vector - /// The results of the options parse of \a input. - /// - /// @param[in] opt_element_index - /// The position in \a opt_element_vector of the word in \a - /// input containing the cursor. - /// - /// @param[in] match_start_point - /// @param[in] match_return_elements - /// See CommandObject::HandleCompletions for a description of - /// how these work. + /// @param[in/out] request + /// The completion request that we need to act upon. /// /// @param[in] interpreter - /// The command interpreter in which we're doing completion. - /// - /// @param[out] word_complete - /// \btrue if this is a complete option value (a space will - /// be inserted after the completion.) \bfalse otherwise. - /// - /// @param[out] matches - /// The array of matches returned. + /// The command interpreter doing the completion. /// /// FIXME: This is the wrong return value, since we also need to /// make a distinction between total number of matches, and the window the @@ -260,12 +211,10 @@ /// \btrue if we were in an option, \bfalse otherwise. //------------------------------------------------------------------ virtual bool - HandleOptionArgumentCompletion(Args &input, int cursor_index, int char_pos, + HandleOptionArgumentCompletion(lldb_private::CompletionRequest &request, OptionElementVector &opt_element_vector, - int opt_element_index, int match_start_point, - int max_return_elements, - CommandInterpreter &interpreter, - bool &word_complete, StringList &matches); + int opt_element_index, + CommandInterpreter &interpreter); protected: // This is a set of options expressed as indexes into the options table for Index: lldb/trunk/include/lldb/Symbol/Variable.h =================================================================== --- lldb/trunk/include/lldb/Symbol/Variable.h +++ lldb/trunk/include/lldb/Symbol/Variable.h @@ -103,8 +103,7 @@ ValueObjectList &valobj_list); static size_t AutoComplete(const ExecutionContext &exe_ctx, - llvm::StringRef name, StringList &matches, - bool &word_complete); + CompletionRequest &request); CompilerDeclContext GetDeclContext(); Index: lldb/trunk/include/lldb/Utility/ArchSpec.h =================================================================== --- lldb/trunk/include/lldb/Utility/ArchSpec.h +++ lldb/trunk/include/lldb/Utility/ArchSpec.h @@ -10,6 +10,7 @@ #ifndef LLDB_UTILITY_ARCHSPEC_H #define LLDB_UTILITY_ARCHSPEC_H +#include "lldb/Utility/CompletionRequest.h" #include "lldb/Utility/ConstString.h" #include "lldb/lldb-enumerations.h" #include "lldb/lldb-forward.h" @@ -288,7 +289,8 @@ //--------------------------------------------------------------------------- static bool ContainsOnlyArch(const llvm::Triple &normalized_triple); - static size_t AutoComplete(llvm::StringRef name, StringList &matches); + static void ListSupportedArchNames(StringList &list); + static size_t AutoComplete(CompletionRequest &request); //------------------------------------------------------------------ /// Returns a static string representing the current architecture. Index: lldb/trunk/include/lldb/Utility/CompletionRequest.h =================================================================== --- lldb/trunk/include/lldb/Utility/CompletionRequest.h +++ lldb/trunk/include/lldb/Utility/CompletionRequest.h @@ -27,26 +27,42 @@ //---------------------------------------------------------------------- class CompletionRequest { public: - //---------------------------------------------------------------------- + //---------------------------------------------------------- /// Constructs a completion request. /// - /// See the respective members of this class for documentation for the - /// parameters. - // TODO: Infer the parsed_line and the cursor positions from the other - // arguments. - //---------------------------------------------------------------------- - CompletionRequest(llvm::StringRef command, unsigned raw_cursor_pos, - Args &parsed_line, int cursor_index, - int cursor_char_position, int match_start_point, - int max_return_elements, bool word_complete, + /// @param [in] command_line + /// The command line the user has typed at this point. + /// + /// @param [in] raw_cursor_pos + /// The position of the cursor in the command line string. Index 0 means + /// the cursor is at the start of the line. The completion starts from + /// this cursor position. + /// + /// @param [in] match_start_point + /// @param [in] max_return_elements + /// If there is a match that is expensive to compute, these are here to + /// allow you to compute the completions in batches. Start the + /// completion from match_start_point, and return match_return_elements + /// elements. + /// + /// @param [out] matches + /// A list of matches that will be filled by the different completion + /// handlers. + //---------------------------------------------------------- + CompletionRequest(llvm::StringRef command_line, unsigned raw_cursor_pos, + int match_start_point, int max_return_elements, StringList &matches); llvm::StringRef GetRawLine() const { return m_command; } unsigned GetRawCursorPos() const { return m_raw_cursor_pos; } + const Args &GetParsedLine() const { return m_parsed_line; } + Args &GetParsedLine() { return m_parsed_line; } + const Args &GetPartialParsedLine() const { return m_partial_parsed_line; } + void SetCursorIndex(int i) { m_cursor_index = i; } int GetCursorIndex() const { return m_cursor_index; } @@ -64,6 +80,14 @@ /// The array of matches returned. StringList &GetMatches() { return *m_matches; } + llvm::StringRef GetCursorArgument() const { + return GetParsedLine().GetArgumentAtIndex(GetCursorIndex()); + } + + llvm::StringRef GetCursorArgumentPrefix() const { + return GetCursorArgument().substr(0, GetCursorCharPosition()); + } + private: /// The raw command line we are supposed to complete. llvm::StringRef m_command; @@ -71,6 +95,8 @@ unsigned m_raw_cursor_pos; /// The command line parsed as arguments. Args m_parsed_line; + /// The command line until the cursor position parsed as arguments. + Args m_partial_parsed_line; /// The index of the argument in which the completion cursor is. int m_cursor_index; /// The cursor position in the argument indexed by m_cursor_index. @@ -84,7 +110,7 @@ int m_max_return_elements; /// \btrue if this is a complete option value (a space will be inserted /// after the completion.) \bfalse otherwise. - bool m_word_complete; + bool m_word_complete = false; // We don't own the list. StringList *m_matches; }; Index: lldb/trunk/source/Commands/CommandCompletions.cpp =================================================================== --- lldb/trunk/source/Commands/CommandCompletions.cpp +++ lldb/trunk/source/Commands/CommandCompletions.cpp @@ -57,9 +57,7 @@ bool CommandCompletions::InvokeCommonCompletionCallbacks( CommandInterpreter &interpreter, uint32_t completion_mask, - llvm::StringRef completion_str, int match_start_point, - int max_return_elements, SearchFilter *searcher, bool &word_complete, - StringList &matches) { + CompletionRequest &request, SearchFilter *searcher) { bool handled = false; if (completion_mask & eCustomCompletion) @@ -72,25 +70,18 @@ g_common_completions[i].type && g_common_completions[i].callback != nullptr) { handled = true; - g_common_completions[i].callback(interpreter, completion_str, - match_start_point, max_return_elements, - searcher, word_complete, matches); + g_common_completions[i].callback(interpreter, request, searcher); } } return handled; } int CommandCompletions::SourceFiles(CommandInterpreter &interpreter, - llvm::StringRef partial_file_name, - int match_start_point, - int max_return_elements, - SearchFilter *searcher, bool &word_complete, - StringList &matches) { - word_complete = true; + CompletionRequest &request, + SearchFilter *searcher) { + request.SetWordComplete(true); // Find some way to switch "include support files..." - SourceFileCompleter completer(interpreter, false, partial_file_name, - match_start_point, max_return_elements, - matches); + SourceFileCompleter completer(interpreter, false, request); if (searcher == nullptr) { lldb::TargetSP target_sp = interpreter.GetDebugger().GetSelectedTarget(); @@ -99,12 +90,11 @@ } else { completer.DoCompletion(searcher); } - return matches.GetSize(); + return request.GetMatches().GetSize(); } static int DiskFilesOrDirectories(const llvm::Twine &partial_name, - bool only_directories, bool &saw_directory, - StringList &matches, + bool only_directories, StringList &matches, TildeExpressionResolver &Resolver) { matches.Clear(); @@ -138,13 +128,12 @@ // but after that, we're done regardless of any matches. if (FirstSep == llvm::StringRef::npos) { llvm::StringSet<> MatchSet; - saw_directory = Resolver.ResolvePartial(Username, MatchSet); + Resolver.ResolvePartial(Username, MatchSet); for (const auto &S : MatchSet) { Resolved = S.getKey(); path::append(Resolved, path::get_separator()); matches.AppendString(Resolved); } - saw_directory = (matches.GetSize() > 0); } return matches.GetSize(); } @@ -155,7 +144,6 @@ if (FirstSep == llvm::StringRef::npos) { // Make sure it ends with a separator. path::append(CompletionBuffer, path::get_separator()); - saw_directory = true; matches.AppendString(CompletionBuffer); return 1; } @@ -227,7 +215,6 @@ CompletionBuffer.append(Name); if (is_dir) { - saw_directory = true; path::append(CompletionBuffer, path::get_separator()); } @@ -238,51 +225,40 @@ } int CommandCompletions::DiskFiles(CommandInterpreter &interpreter, - llvm::StringRef partial_file_name, - int match_start_point, - int max_return_elements, - SearchFilter *searcher, bool &word_complete, - StringList &matches) { - word_complete = false; + CompletionRequest &request, + SearchFilter *searcher) { + request.SetWordComplete(false); StandardTildeExpressionResolver Resolver; - return DiskFiles(partial_file_name, matches, Resolver); + return DiskFiles(request.GetCursorArgumentPrefix(), request.GetMatches(), + Resolver); } int CommandCompletions::DiskFiles(const llvm::Twine &partial_file_name, StringList &matches, TildeExpressionResolver &Resolver) { - bool word_complete; - int ret_val = DiskFilesOrDirectories(partial_file_name, false, word_complete, - matches, Resolver); - return ret_val; + return DiskFilesOrDirectories(partial_file_name, false, matches, Resolver); } -int CommandCompletions::DiskDirectories( - CommandInterpreter &interpreter, llvm::StringRef partial_file_name, - int match_start_point, int max_return_elements, SearchFilter *searcher, - bool &word_complete, StringList &matches) { - word_complete = false; +int CommandCompletions::DiskDirectories(CommandInterpreter &interpreter, + CompletionRequest &request, + SearchFilter *searcher) { + request.SetWordComplete(false); StandardTildeExpressionResolver Resolver; - return DiskDirectories(partial_file_name, matches, Resolver); + return DiskDirectories(request.GetCursorArgumentPrefix(), + request.GetMatches(), Resolver); } int CommandCompletions::DiskDirectories(const llvm::Twine &partial_file_name, StringList &matches, TildeExpressionResolver &Resolver) { - bool word_complete; - int ret_val = DiskFilesOrDirectories(partial_file_name, true, word_complete, - matches, Resolver); - return ret_val; + return DiskFilesOrDirectories(partial_file_name, true, matches, Resolver); } int CommandCompletions::Modules(CommandInterpreter &interpreter, - llvm::StringRef partial_file_name, - int match_start_point, int max_return_elements, - SearchFilter *searcher, bool &word_complete, - StringList &matches) { - word_complete = true; - ModuleCompleter completer(interpreter, partial_file_name, match_start_point, - max_return_elements, matches); + CompletionRequest &request, + SearchFilter *searcher) { + request.SetWordComplete(true); + ModuleCompleter completer(interpreter, request); if (searcher == nullptr) { lldb::TargetSP target_sp = interpreter.GetDebugger().GetSelectedTarget(); @@ -291,17 +267,14 @@ } else { completer.DoCompletion(searcher); } - return matches.GetSize(); + return request.GetMatches().GetSize(); } int CommandCompletions::Symbols(CommandInterpreter &interpreter, - llvm::StringRef partial_file_name, - int match_start_point, int max_return_elements, - SearchFilter *searcher, bool &word_complete, - StringList &matches) { - word_complete = true; - SymbolCompleter completer(interpreter, partial_file_name, match_start_point, - max_return_elements, matches); + CompletionRequest &request, + SearchFilter *searcher) { + request.SetWordComplete(true); + SymbolCompleter completer(interpreter, request); if (searcher == nullptr) { lldb::TargetSP target_sp = interpreter.GetDebugger().GetSelectedTarget(); @@ -310,13 +283,12 @@ } else { completer.DoCompletion(searcher); } - return matches.GetSize(); + return request.GetMatches().GetSize(); } -int CommandCompletions::SettingsNames( - CommandInterpreter &interpreter, llvm::StringRef partial_setting_name, - int match_start_point, int max_return_elements, SearchFilter *searcher, - bool &word_complete, StringList &matches) { +int CommandCompletions::SettingsNames(CommandInterpreter &interpreter, + CompletionRequest &request, + SearchFilter *searcher) { // Cache the full setting name list static StringList g_property_names; if (g_property_names.GetSize() == 0) { @@ -332,47 +304,39 @@ } size_t exact_matches_idx = SIZE_MAX; - const size_t num_matches = g_property_names.AutoComplete( - partial_setting_name, matches, exact_matches_idx); - word_complete = exact_matches_idx != SIZE_MAX; + const size_t num_matches = + g_property_names.AutoComplete(request.GetCursorArgumentPrefix(), + request.GetMatches(), exact_matches_idx); + request.SetWordComplete(exact_matches_idx != SIZE_MAX); return num_matches; } -int CommandCompletions::PlatformPluginNames( - CommandInterpreter &interpreter, llvm::StringRef partial_name, - int match_start_point, int max_return_elements, SearchFilter *searcher, - bool &word_complete, lldb_private::StringList &matches) { - const uint32_t num_matches = - PluginManager::AutoCompletePlatformName(partial_name, matches); - word_complete = num_matches == 1; +int CommandCompletions::PlatformPluginNames(CommandInterpreter &interpreter, + CompletionRequest &request, + SearchFilter *searcher) { + const uint32_t num_matches = PluginManager::AutoCompletePlatformName( + request.GetCursorArgumentPrefix(), request.GetMatches()); + request.SetWordComplete(num_matches == 1); return num_matches; } -int CommandCompletions::ArchitectureNames( - CommandInterpreter &interpreter, llvm::StringRef partial_name, - int match_start_point, int max_return_elements, SearchFilter *searcher, - bool &word_complete, lldb_private::StringList &matches) { - const uint32_t num_matches = ArchSpec::AutoComplete(partial_name, matches); - word_complete = num_matches == 1; +int CommandCompletions::ArchitectureNames(CommandInterpreter &interpreter, + CompletionRequest &request, + SearchFilter *searcher) { + const uint32_t num_matches = ArchSpec::AutoComplete(request); + request.SetWordComplete(num_matches == 1); return num_matches; } -int CommandCompletions::VariablePath( - CommandInterpreter &interpreter, llvm::StringRef partial_name, - int match_start_point, int max_return_elements, SearchFilter *searcher, - bool &word_complete, lldb_private::StringList &matches) { - return Variable::AutoComplete(interpreter.GetExecutionContext(), partial_name, - matches, word_complete); +int CommandCompletions::VariablePath(CommandInterpreter &interpreter, + CompletionRequest &request, + SearchFilter *searcher) { + return Variable::AutoComplete(interpreter.GetExecutionContext(), request); } CommandCompletions::Completer::Completer(CommandInterpreter &interpreter, - llvm::StringRef completion_str, - int match_start_point, - int max_return_elements, - StringList &matches) - : m_interpreter(interpreter), m_completion_str(completion_str), - m_match_start_point(match_start_point), - m_max_return_elements(max_return_elements), m_matches(matches) {} + CompletionRequest &request) + : m_interpreter(interpreter), m_request(request) {} CommandCompletions::Completer::~Completer() = default; @@ -382,13 +346,10 @@ CommandCompletions::SourceFileCompleter::SourceFileCompleter( CommandInterpreter &interpreter, bool include_support_files, - llvm::StringRef completion_str, int match_start_point, - int max_return_elements, StringList &matches) - : CommandCompletions::Completer(interpreter, completion_str, - match_start_point, max_return_elements, - matches), + CompletionRequest &request) + : CommandCompletions::Completer(interpreter, request), m_include_support_files(include_support_files), m_matching_files() { - FileSpec partial_spec(m_completion_str, false); + FileSpec partial_spec(m_request.GetCursorArgumentPrefix(), false); m_file_name = partial_spec.GetFilename().GetCString(); m_dir_name = partial_spec.GetDirectory().GetCString(); } @@ -448,10 +409,10 @@ filter->Search(*this); // Now convert the filelist to completions: for (size_t i = 0; i < m_matching_files.GetSize(); i++) { - m_matches.AppendString( + m_request.GetMatches().AppendString( m_matching_files.GetFileSpecAtIndex(i).GetFilename().GetCString()); } - return m_matches.GetSize(); + return m_request.GetMatches().GetSize(); } //---------------------------------------------------------------------- @@ -466,15 +427,12 @@ } CommandCompletions::SymbolCompleter::SymbolCompleter( - CommandInterpreter &interpreter, llvm::StringRef completion_str, - int match_start_point, int max_return_elements, StringList &matches) - : CommandCompletions::Completer(interpreter, completion_str, - match_start_point, max_return_elements, - matches) { + CommandInterpreter &interpreter, CompletionRequest &request) + : CommandCompletions::Completer(interpreter, request) { std::string regex_str; - if (!completion_str.empty()) { + if (!m_request.GetCursorArgumentPrefix().empty()) { regex_str.append("^"); - regex_str.append(completion_str); + regex_str.append(m_request.GetCursorArgumentPrefix()); } else { // Match anything since the completion string is empty regex_str.append("."); @@ -520,21 +478,18 @@ filter->Search(*this); collection::iterator pos = m_match_set.begin(), end = m_match_set.end(); for (pos = m_match_set.begin(); pos != end; pos++) - m_matches.AppendString((*pos).GetCString()); + m_request.GetMatches().AppendString((*pos).GetCString()); - return m_matches.GetSize(); + return m_request.GetMatches().GetSize(); } //---------------------------------------------------------------------- // ModuleCompleter //---------------------------------------------------------------------- CommandCompletions::ModuleCompleter::ModuleCompleter( - CommandInterpreter &interpreter, llvm::StringRef completion_str, - int match_start_point, int max_return_elements, StringList &matches) - : CommandCompletions::Completer(interpreter, completion_str, - match_start_point, max_return_elements, - matches) { - FileSpec partial_spec(m_completion_str, false); + CommandInterpreter &interpreter, CompletionRequest &request) + : CommandCompletions::Completer(interpreter, request) { + FileSpec partial_spec(m_request.GetCursorArgumentPrefix(), false); m_file_name = partial_spec.GetFilename().GetCString(); m_dir_name = partial_spec.GetDirectory().GetCString(); } @@ -562,7 +517,7 @@ match = false; if (match) { - m_matches.AppendString(cur_file_name); + m_request.GetMatches().AppendString(cur_file_name); } } return Searcher::eCallbackReturnContinue; @@ -570,5 +525,5 @@ size_t CommandCompletions::ModuleCompleter::DoCompletion(SearchFilter *filter) { filter->Search(*this); - return m_matches.GetSize(); + return m_request.GetMatches().GetSize(); } Index: lldb/trunk/source/Commands/CommandObjectCommands.cpp =================================================================== --- lldb/trunk/source/Commands/CommandObjectCommands.cpp +++ lldb/trunk/source/Commands/CommandObjectCommands.cpp @@ -238,16 +238,9 @@ int HandleArgumentCompletion( CompletionRequest &request, OptionElementVector &opt_element_vector) override { - auto completion_str = request.GetParsedLine()[request.GetCursorIndex()].ref; - completion_str = completion_str.take_front(request.GetCursorCharPosition()); - - bool word_complete = request.GetWordComplete(); CommandCompletions::InvokeCommonCompletionCallbacks( GetCommandInterpreter(), CommandCompletions::eDiskFileCompletion, - completion_str, request.GetMatchStartPoint(), - request.GetMaxReturnElements(), nullptr, word_complete, - request.GetMatches()); - request.SetWordComplete(word_complete); + request, nullptr); return request.GetMatches().GetSize(); } @@ -1433,17 +1426,9 @@ int HandleArgumentCompletion( CompletionRequest &request, OptionElementVector &opt_element_vector) override { - llvm::StringRef completion_str = - request.GetParsedLine()[request.GetCursorIndex()].ref; - completion_str = completion_str.take_front(request.GetCursorCharPosition()); - - bool word_complete = request.GetWordComplete(); CommandCompletions::InvokeCommonCompletionCallbacks( GetCommandInterpreter(), CommandCompletions::eDiskFileCompletion, - completion_str, request.GetMatchStartPoint(), - request.GetMaxReturnElements(), nullptr, word_complete, - request.GetMatches()); - request.SetWordComplete(word_complete); + request, nullptr); return request.GetMatches().GetSize(); } Index: lldb/trunk/source/Commands/CommandObjectFrame.cpp =================================================================== --- lldb/trunk/source/Commands/CommandObjectFrame.cpp +++ lldb/trunk/source/Commands/CommandObjectFrame.cpp @@ -467,16 +467,9 @@ CompletionRequest &request, OptionElementVector &opt_element_vector) override { // Arguments are the standard source file completer. - auto completion_str = request.GetParsedLine()[request.GetCursorIndex()].ref; - completion_str = completion_str.take_front(request.GetCursorCharPosition()); - - bool word_complete = request.GetWordComplete(); CommandCompletions::InvokeCommonCompletionCallbacks( GetCommandInterpreter(), CommandCompletions::eVariablePathCompletion, - completion_str, request.GetMatchStartPoint(), - request.GetMaxReturnElements(), nullptr, word_complete, - request.GetMatches()); - request.SetWordComplete(word_complete); + request, nullptr); return request.GetMatches().GetSize(); } Index: lldb/trunk/source/Commands/CommandObjectPlatform.cpp =================================================================== --- lldb/trunk/source/Commands/CommandObjectPlatform.cpp +++ lldb/trunk/source/Commands/CommandObjectPlatform.cpp @@ -179,16 +179,8 @@ ~CommandObjectPlatformSelect() override = default; int HandleCompletion(CompletionRequest &request) override { - std::string completion_str( - request.GetParsedLine().GetArgumentAtIndex(request.GetCursorIndex())); - completion_str.erase(request.GetCursorCharPosition()); - - bool word_complete = request.GetWordComplete(); - CommandCompletions::PlatformPluginNames( - GetCommandInterpreter(), completion_str.c_str(), - request.GetMatchStartPoint(), request.GetMaxReturnElements(), nullptr, - word_complete, request.GetMatches()); - request.SetWordComplete(word_complete); + CommandCompletions::PlatformPluginNames(GetCommandInterpreter(), request, + nullptr); return request.GetMatches().GetSize(); } @@ -1562,11 +1554,8 @@ } bool HandleOptionArgumentCompletion( - Args &input, int cursor_index, int char_pos, - OptionElementVector &opt_element_vector, int opt_element_index, - int match_start_point, int max_return_elements, - CommandInterpreter &interpreter, bool &word_complete, - StringList &matches) override { + CompletionRequest &request, OptionElementVector &opt_element_vector, + int opt_element_index, CommandInterpreter &interpreter) override { int opt_arg_pos = opt_element_vector[opt_element_index].opt_arg_pos; int opt_defs_index = opt_element_vector[opt_element_index].opt_defs_index; @@ -1579,7 +1568,7 @@ // plugin, otherwise use the default plugin. const char *partial_name = nullptr; - partial_name = input.GetArgumentAtIndex(opt_arg_pos); + partial_name = request.GetParsedLine().GetArgumentAtIndex(opt_arg_pos); PlatformSP platform_sp(interpreter.GetPlatform(true)); if (platform_sp) { @@ -1594,7 +1583,7 @@ const uint32_t num_matches = process_infos.GetSize(); if (num_matches > 0) { for (uint32_t i = 0; i < num_matches; ++i) { - matches.AppendString( + request.GetMatches().AppendString( process_infos.GetProcessNameAtIndex(i), process_infos.GetProcessNameLengthAtIndex(i)); } Index: lldb/trunk/source/Commands/CommandObjectPlugin.cpp =================================================================== --- lldb/trunk/source/Commands/CommandObjectPlugin.cpp +++ lldb/trunk/source/Commands/CommandObjectPlugin.cpp @@ -45,16 +45,9 @@ int HandleArgumentCompletion( CompletionRequest &request, OptionElementVector &opt_element_vector) override { - auto completion_str = request.GetParsedLine()[request.GetCursorIndex()].ref; - completion_str = completion_str.take_front(request.GetCursorCharPosition()); - - bool word_complete = request.GetWordComplete(); CommandCompletions::InvokeCommonCompletionCallbacks( GetCommandInterpreter(), CommandCompletions::eDiskFileCompletion, - completion_str, request.GetMatchStartPoint(), - request.GetMaxReturnElements(), nullptr, word_complete, - request.GetMatches()); - request.SetWordComplete(word_complete); + request, nullptr); return request.GetMatches().GetSize(); } Index: lldb/trunk/source/Commands/CommandObjectProcess.cpp =================================================================== --- lldb/trunk/source/Commands/CommandObjectProcess.cpp +++ lldb/trunk/source/Commands/CommandObjectProcess.cpp @@ -137,17 +137,10 @@ int HandleArgumentCompletion( CompletionRequest &request, OptionElementVector &opt_element_vector) override { - std::string completion_str( - request.GetParsedLine().GetArgumentAtIndex(request.GetCursorIndex())); - completion_str.erase(request.GetCursorCharPosition()); - bool word_complete = request.GetWordComplete(); CommandCompletions::InvokeCommonCompletionCallbacks( GetCommandInterpreter(), CommandCompletions::eDiskFileCompletion, - completion_str.c_str(), request.GetMatchStartPoint(), - request.GetMaxReturnElements(), nullptr, word_complete, - request.GetMatches()); - request.SetWordComplete(word_complete); + request, nullptr); return request.GetMatches().GetSize(); } @@ -388,11 +381,8 @@ } bool HandleOptionArgumentCompletion( - Args &input, int cursor_index, int char_pos, - OptionElementVector &opt_element_vector, int opt_element_index, - int match_start_point, int max_return_elements, - CommandInterpreter &interpreter, bool &word_complete, - StringList &matches) override { + CompletionRequest &request, OptionElementVector &opt_element_vector, + int opt_element_index, CommandInterpreter &interpreter) override { int opt_arg_pos = opt_element_vector[opt_element_index].opt_arg_pos; int opt_defs_index = opt_element_vector[opt_element_index].opt_defs_index; @@ -405,7 +395,7 @@ // plugin, otherwise use the default plugin. const char *partial_name = nullptr; - partial_name = input.GetArgumentAtIndex(opt_arg_pos); + partial_name = request.GetParsedLine().GetArgumentAtIndex(opt_arg_pos); PlatformSP platform_sp(interpreter.GetPlatform(true)); if (platform_sp) { @@ -420,7 +410,7 @@ const size_t num_matches = process_infos.GetSize(); if (num_matches > 0) { for (size_t i = 0; i < num_matches; ++i) { - matches.AppendString( + request.GetMatches().AppendString( process_infos.GetProcessNameAtIndex(i), process_infos.GetProcessNameLengthAtIndex(i)); } Index: lldb/trunk/source/Commands/CommandObjectSettings.cpp =================================================================== --- lldb/trunk/source/Commands/CommandObjectSettings.cpp +++ lldb/trunk/source/Commands/CommandObjectSettings.cpp @@ -136,9 +136,6 @@ int HandleArgumentCompletion( CompletionRequest &request, OptionElementVector &opt_element_vector) override { - std::string completion_str( - request.GetParsedLine().GetArgumentAtIndex(request.GetCursorIndex()), - request.GetCursorCharPosition()); const size_t argc = request.GetParsedLine().GetArgumentCount(); const char *arg = nullptr; @@ -151,13 +148,9 @@ } if (request.GetCursorIndex() == setting_var_idx) { // Attempting to complete setting variable name - bool word_complete = request.GetWordComplete(); CommandCompletions::InvokeCommonCompletionCallbacks( GetCommandInterpreter(), CommandCompletions::eSettingsNameCompletion, - completion_str.c_str(), request.GetMatchStartPoint(), - request.GetMaxReturnElements(), nullptr, word_complete, - request.GetMatches()); - request.SetWordComplete(word_complete); + request, nullptr); } else { arg = request.GetParsedLine().GetArgumentAtIndex(request.GetCursorIndex()); @@ -174,12 +167,7 @@ m_interpreter.GetDebugger().GetPropertyValue( &m_exe_ctx, setting_var_name, false, error)); if (value_sp) { - bool word_complete = request.GetWordComplete(); - value_sp->AutoComplete(m_interpreter, completion_str.c_str(), - request.GetMatchStartPoint(), - request.GetMaxReturnElements(), - word_complete, request.GetMatches()); - request.SetWordComplete(word_complete); + value_sp->AutoComplete(m_interpreter, request); } } } @@ -281,17 +269,9 @@ int HandleArgumentCompletion( CompletionRequest &request, OptionElementVector &opt_element_vector) override { - std::string completion_str( - request.GetParsedLine().GetArgumentAtIndex(request.GetCursorIndex()), - request.GetCursorCharPosition()); - - bool word_complete = request.GetWordComplete(); CommandCompletions::InvokeCommonCompletionCallbacks( GetCommandInterpreter(), CommandCompletions::eSettingsNameCompletion, - completion_str.c_str(), request.GetMatchStartPoint(), - request.GetMaxReturnElements(), nullptr, word_complete, - request.GetMatches()); - request.SetWordComplete(word_complete); + request, nullptr); return request.GetMatches().GetSize(); } @@ -355,17 +335,9 @@ int HandleArgumentCompletion( CompletionRequest &request, OptionElementVector &opt_element_vector) override { - std::string completion_str( - request.GetParsedLine().GetArgumentAtIndex(request.GetCursorIndex()), - request.GetCursorCharPosition()); - - bool word_complete = request.GetWordComplete(); CommandCompletions::InvokeCommonCompletionCallbacks( GetCommandInterpreter(), CommandCompletions::eSettingsNameCompletion, - completion_str.c_str(), request.GetMatchStartPoint(), - request.GetMaxReturnElements(), nullptr, word_complete, - request.GetMatches()); - request.SetWordComplete(word_complete); + request, nullptr); return request.GetMatches().GetSize(); } @@ -451,19 +423,10 @@ int HandleArgumentCompletion( CompletionRequest &request, OptionElementVector &opt_element_vector) override { - std::string completion_str( - request.GetParsedLine().GetArgumentAtIndex(request.GetCursorIndex()), - request.GetCursorCharPosition()); - - // Attempting to complete variable name - bool word_complete = request.GetWordComplete(); if (request.GetCursorIndex() < 2) CommandCompletions::InvokeCommonCompletionCallbacks( GetCommandInterpreter(), CommandCompletions::eSettingsNameCompletion, - completion_str.c_str(), request.GetMatchStartPoint(), - request.GetMaxReturnElements(), nullptr, word_complete, - request.GetMatches()); - request.SetWordComplete(word_complete); + request, nullptr); return request.GetMatches().GetSize(); } @@ -575,19 +538,11 @@ int HandleArgumentCompletion( CompletionRequest &request, OptionElementVector &opt_element_vector) override { - std::string completion_str( - request.GetParsedLine().GetArgumentAtIndex(request.GetCursorIndex()), - request.GetCursorCharPosition()); - - bool word_complete = request.GetWordComplete(); // Attempting to complete variable name if (request.GetCursorIndex() < 2) CommandCompletions::InvokeCommonCompletionCallbacks( GetCommandInterpreter(), CommandCompletions::eSettingsNameCompletion, - completion_str.c_str(), request.GetMatchStartPoint(), - request.GetMaxReturnElements(), nullptr, word_complete, - request.GetMatches()); - request.SetWordComplete(word_complete); + request, nullptr); return request.GetMatches().GetSize(); } @@ -683,19 +638,11 @@ int HandleArgumentCompletion( CompletionRequest &request, OptionElementVector &opt_element_vector) override { - std::string completion_str( - request.GetParsedLine().GetArgumentAtIndex(request.GetCursorIndex()), - request.GetCursorCharPosition()); - - bool word_complete = request.GetWordComplete(); // Attempting to complete variable name if (request.GetCursorIndex() < 2) CommandCompletions::InvokeCommonCompletionCallbacks( GetCommandInterpreter(), CommandCompletions::eSettingsNameCompletion, - completion_str.c_str(), request.GetMatchStartPoint(), - request.GetMaxReturnElements(), nullptr, word_complete, - request.GetMatches()); - request.SetWordComplete(word_complete); + request, nullptr); return request.GetMatches().GetSize(); } @@ -796,19 +743,11 @@ int HandleArgumentCompletion( CompletionRequest &request, OptionElementVector &opt_element_vector) override { - std::string completion_str( - request.GetParsedLine().GetArgumentAtIndex(request.GetCursorIndex()), - request.GetCursorCharPosition()); - - bool word_complete = request.GetWordComplete(); // Attempting to complete variable name if (request.GetCursorIndex() < 2) CommandCompletions::InvokeCommonCompletionCallbacks( GetCommandInterpreter(), CommandCompletions::eSettingsNameCompletion, - completion_str.c_str(), request.GetMatchStartPoint(), - request.GetMaxReturnElements(), nullptr, word_complete, - request.GetMatches()); - request.SetWordComplete(word_complete); + request, nullptr); return request.GetMatches().GetSize(); } @@ -898,19 +837,11 @@ int HandleArgumentCompletion( CompletionRequest &request, OptionElementVector &opt_element_vector) override { - std::string completion_str( - request.GetParsedLine().GetArgumentAtIndex(request.GetCursorIndex()), - request.GetCursorCharPosition()); - - bool word_complete = request.GetWordComplete(); // Attempting to complete variable name if (request.GetCursorIndex() < 2) CommandCompletions::InvokeCommonCompletionCallbacks( GetCommandInterpreter(), CommandCompletions::eSettingsNameCompletion, - completion_str.c_str(), request.GetMatchStartPoint(), - request.GetMaxReturnElements(), nullptr, word_complete, - request.GetMatches()); - request.SetWordComplete(word_complete); + request, nullptr); return request.GetMatches().GetSize(); } @@ -987,19 +918,11 @@ int HandleArgumentCompletion( CompletionRequest &request, OptionElementVector &opt_element_vector) override { - std::string completion_str( - request.GetParsedLine().GetArgumentAtIndex(request.GetCursorIndex()), - request.GetCursorCharPosition()); - - bool word_complete = request.GetWordComplete(); // Attempting to complete variable name if (request.GetCursorIndex() < 2) CommandCompletions::InvokeCommonCompletionCallbacks( GetCommandInterpreter(), CommandCompletions::eSettingsNameCompletion, - completion_str.c_str(), request.GetMatchStartPoint(), - request.GetMaxReturnElements(), nullptr, word_complete, - request.GetMatches()); - request.SetWordComplete(word_complete); + request, nullptr); return request.GetMatches().GetSize(); } Index: lldb/trunk/source/Commands/CommandObjectTarget.cpp =================================================================== --- lldb/trunk/source/Commands/CommandObjectTarget.cpp +++ lldb/trunk/source/Commands/CommandObjectTarget.cpp @@ -198,17 +198,9 @@ int HandleArgumentCompletion( CompletionRequest &request, OptionElementVector &opt_element_vector) override { - std::string completion_str( - request.GetParsedLine().GetArgumentAtIndex(request.GetCursorIndex())); - completion_str.erase(request.GetCursorCharPosition()); - - bool word_complete = request.GetWordComplete(); CommandCompletions::InvokeCommonCompletionCallbacks( GetCommandInterpreter(), CommandCompletions::eDiskFileCompletion, - completion_str.c_str(), request.GetMatchStartPoint(), - request.GetMaxReturnElements(), nullptr, word_complete, - request.GetMatches()); - request.SetWordComplete(word_complete); + request, nullptr); return request.GetMatches().GetSize(); } @@ -1815,18 +1807,9 @@ int HandleArgumentCompletion( CompletionRequest &request, OptionElementVector &opt_element_vector) override { - // Arguments are the standard module completer. - std::string completion_str( - request.GetParsedLine().GetArgumentAtIndex(request.GetCursorIndex())); - completion_str.erase(request.GetCursorCharPosition()); - - bool word_complete = request.GetWordComplete(); CommandCompletions::InvokeCommonCompletionCallbacks( - GetCommandInterpreter(), CommandCompletions::eModuleCompletion, - completion_str.c_str(), request.GetMatchStartPoint(), - request.GetMaxReturnElements(), nullptr, word_complete, - request.GetMatches()); - request.SetWordComplete(word_complete); + GetCommandInterpreter(), CommandCompletions::eModuleCompletion, request, + nullptr); return request.GetMatches().GetSize(); } }; @@ -1865,18 +1848,9 @@ int HandleArgumentCompletion( CompletionRequest &request, OptionElementVector &opt_element_vector) override { - // Arguments are the standard source file completer. - std::string completion_str( - request.GetParsedLine().GetArgumentAtIndex(request.GetCursorIndex())); - completion_str.erase(request.GetCursorCharPosition()); - - bool word_complete = request.GetWordComplete(); CommandCompletions::InvokeCommonCompletionCallbacks( GetCommandInterpreter(), CommandCompletions::eSourceFileCompletion, - completion_str.c_str(), request.GetMatchStartPoint(), - request.GetMaxReturnElements(), nullptr, word_complete, - request.GetMatches()); - request.SetWordComplete(word_complete); + request, nullptr); return request.GetMatches().GetSize(); } }; @@ -2416,17 +2390,9 @@ int HandleArgumentCompletion( CompletionRequest &request, OptionElementVector &opt_element_vector) override { - std::string completion_str( - request.GetParsedLine().GetArgumentAtIndex(request.GetCursorIndex())); - completion_str.erase(request.GetCursorCharPosition()); - - bool word_complete = request.GetWordComplete(); CommandCompletions::InvokeCommonCompletionCallbacks( GetCommandInterpreter(), CommandCompletions::eDiskFileCompletion, - completion_str.c_str(), request.GetMatchStartPoint(), - request.GetMaxReturnElements(), nullptr, word_complete, - request.GetMatches()); - request.SetWordComplete(word_complete); + request, nullptr); return request.GetMatches().GetSize(); } @@ -4018,17 +3984,9 @@ int HandleArgumentCompletion( CompletionRequest &request, OptionElementVector &opt_element_vector) override { - std::string completion_str( - request.GetParsedLine().GetArgumentAtIndex(request.GetCursorIndex())); - completion_str.erase(request.GetCursorCharPosition()); - - bool word_complete = request.GetWordComplete(); CommandCompletions::InvokeCommonCompletionCallbacks( GetCommandInterpreter(), CommandCompletions::eDiskFileCompletion, - completion_str.c_str(), request.GetMatchStartPoint(), - request.GetMaxReturnElements(), nullptr, word_complete, - request.GetMatches()); - request.SetWordComplete(word_complete); + request, nullptr); return request.GetMatches().GetSize(); } Index: lldb/trunk/source/Core/FormatEntity.cpp =================================================================== --- lldb/trunk/source/Core/FormatEntity.cpp +++ lldb/trunk/source/Core/FormatEntity.cpp @@ -2344,12 +2344,12 @@ } } -size_t FormatEntity::AutoComplete(llvm::StringRef str, int match_start_point, - int max_return_elements, bool &word_complete, - StringList &matches) { - word_complete = false; - str = str.drop_front(match_start_point); - matches.Clear(); +size_t FormatEntity::AutoComplete(CompletionRequest &request) { + llvm::StringRef str = request.GetCursorArgumentPrefix().str(); + + request.SetWordComplete(false); + str = str.drop_front(request.GetMatchStartPoint()); + request.GetMatches().Clear(); const size_t dollar_pos = str.rfind('$'); if (dollar_pos == llvm::StringRef::npos) @@ -2359,7 +2359,7 @@ if (dollar_pos == str.size() - 1) { std::string match = str.str(); match.append("{"); - matches.AppendString(match); + request.GetMatches().AppendString(match); return 1; } @@ -2377,8 +2377,8 @@ llvm::StringRef partial_variable(str.substr(dollar_pos + 2)); if (partial_variable.empty()) { // Suggest all top level entites as we are just past "${" - AddMatches(&g_root, str, llvm::StringRef(), matches); - return matches.GetSize(); + AddMatches(&g_root, str, llvm::StringRef(), request.GetMatches()); + return request.GetMatches().GetSize(); } // We have a partially specified variable, find it @@ -2394,19 +2394,19 @@ // Exact match if (n > 0) { // "${thread.info" - matches.AppendString(MakeMatch(str, ".")); + request.GetMatches().AppendString(MakeMatch(str, ".")); } else { // "${thread.id" - matches.AppendString(MakeMatch(str, "}")); - word_complete = true; + request.GetMatches().AppendString(MakeMatch(str, "}")); + request.SetWordComplete(true); } } else if (remainder.equals(".")) { // "${thread." - AddMatches(entry_def, str, llvm::StringRef(), matches); + AddMatches(entry_def, str, llvm::StringRef(), request.GetMatches()); } else { // We have a partial match // "${thre" - AddMatches(entry_def, str, remainder, matches); + AddMatches(entry_def, str, remainder, request.GetMatches()); } - return matches.GetSize(); + return request.GetMatches().GetSize(); } Index: lldb/trunk/source/Core/IOHandler.cpp =================================================================== --- lldb/trunk/source/Core/IOHandler.cpp +++ lldb/trunk/source/Core/IOHandler.cpp @@ -239,26 +239,21 @@ matches); case Completion::Expression: { - bool word_complete = false; - const char *word_start = cursor; - if (cursor > current_line) - --word_start; - while (word_start > current_line && !isspace(*word_start)) - --word_start; + CompletionRequest request(current_line, current_line - cursor, + skip_first_n_matches, max_matches, matches); CommandCompletions::InvokeCommonCompletionCallbacks( io_handler.GetDebugger().GetCommandInterpreter(), - CommandCompletions::eVariablePathCompletion, word_start, - skip_first_n_matches, max_matches, nullptr, word_complete, matches); + CommandCompletions::eVariablePathCompletion, request, nullptr); - size_t num_matches = matches.GetSize(); + size_t num_matches = request.GetMatches().GetSize(); if (num_matches > 0) { std::string common_prefix; - matches.LongestCommonPrefix(common_prefix); - const size_t partial_name_len = strlen(word_start); + request.GetMatches().LongestCommonPrefix(common_prefix); + const size_t partial_name_len = request.GetCursorArgumentPrefix().size(); // If we matched a unique single command, add a space... Only do this if // the completer told us this was a complete word, however... - if (num_matches == 1 && word_complete) { + if (num_matches == 1 && request.GetWordComplete()) { common_prefix.push_back(' '); } common_prefix.erase(0, partial_name_len); Index: lldb/trunk/source/Interpreter/CommandInterpreter.cpp =================================================================== --- lldb/trunk/source/Interpreter/CommandInterpreter.cpp +++ lldb/trunk/source/Interpreter/CommandInterpreter.cpp @@ -1697,14 +1697,10 @@ // We didn't find the first command object, so complete the first argument. Args command_args(command_string); StringList matches; - int cursor_index = 0; - int cursor_char_position = strlen(command_args.GetArgumentAtIndex(0)); - bool word_complete = true; - CompletionRequest request(command_line, cursor_char_position, command_args, - cursor_index, cursor_char_position, 0, -1, - word_complete, matches); + unsigned cursor_char_position = strlen(command_args.GetArgumentAtIndex(0)); + CompletionRequest request(command_line, cursor_char_position, 0, -1, + matches); int num_matches = HandleCompletionMatches(request); - word_complete = request.GetWordComplete(); if (num_matches > 0) { std::string error_msg; @@ -1791,89 +1787,42 @@ int CommandInterpreter::HandleCompletion( const char *current_line, const char *cursor, const char *last_char, int match_start_point, int max_return_elements, StringList &matches) { - // We parse the argument up to the cursor, so the last argument in - // parsed_line is the one containing the cursor, and the cursor is after the - // last character. llvm::StringRef command_line(current_line, last_char - current_line); - Args parsed_line(command_line); - Args partial_parsed_line( - llvm::StringRef(current_line, cursor - current_line)); + CompletionRequest request(command_line, cursor - current_line, + match_start_point, max_return_elements, matches); // Don't complete comments, and if the line we are completing is just the // history repeat character, substitute the appropriate history line. - const char *first_arg = parsed_line.GetArgumentAtIndex(0); + const char *first_arg = request.GetParsedLine().GetArgumentAtIndex(0); if (first_arg) { if (first_arg[0] == m_comment_char) return 0; else if (first_arg[0] == CommandHistory::g_repeat_char) { if (auto hist_str = m_command_history.FindString(first_arg)) { - matches.Clear(); - matches.InsertStringAtIndex(0, *hist_str); + request.GetMatches().Clear(); + request.GetMatches().InsertStringAtIndex(0, *hist_str); return -2; } else return 0; } } - int num_args = partial_parsed_line.GetArgumentCount(); - int cursor_index = partial_parsed_line.GetArgumentCount() - 1; - int cursor_char_position; - - if (cursor_index == -1) - cursor_char_position = 0; - else - cursor_char_position = - strlen(partial_parsed_line.GetArgumentAtIndex(cursor_index)); - - if (cursor > current_line && cursor[-1] == ' ') { - // We are just after a space. If we are in an argument, then we will - // continue parsing, but if we are between arguments, then we have to - // complete whatever the next element would be. We can distinguish the two - // cases because if we are in an argument (e.g. because the space is - // protected by a quote) then the space will also be in the parsed - // argument... - - const char *current_elem = - partial_parsed_line.GetArgumentAtIndex(cursor_index); - if (cursor_char_position == 0 || - current_elem[cursor_char_position - 1] != ' ') { - parsed_line.InsertArgumentAtIndex(cursor_index + 1, llvm::StringRef(), - '\0'); - cursor_index++; - cursor_char_position = 0; - } - } - - int num_command_matches; - - matches.Clear(); - // Only max_return_elements == -1 is supported at present: lldbassert(max_return_elements == -1); - bool word_complete = false; - - CompletionRequest request(command_line, cursor - current_line, parsed_line, - cursor_index, cursor_char_position, - match_start_point, max_return_elements, - word_complete, matches); - num_command_matches = HandleCompletionMatches(request); - word_complete = request.GetWordComplete(); + int num_command_matches = HandleCompletionMatches(request); if (num_command_matches <= 0) return num_command_matches; - if (num_args == 0) { + if (request.GetParsedLine().GetArgumentCount() == 0) { // If we got an empty string, insert nothing. matches.InsertStringAtIndex(0, ""); } else { // Now figure out if there is a common substring, and if so put that in // element 0, otherwise put an empty string in element 0. - std::string command_partial_str; - if (cursor_index >= 0) - command_partial_str = - parsed_line[cursor_index].ref.take_front(cursor_char_position); + std::string command_partial_str = request.GetCursorArgumentPrefix().str(); std::string common_prefix; matches.LongestCommonPrefix(common_prefix); @@ -1882,15 +1831,15 @@ // If we matched a unique single command, add a space... Only do this if // the completer told us this was a complete word, however... - if (num_command_matches == 1 && word_complete) { - char quote_char = parsed_line[cursor_index].quote; + if (num_command_matches == 1 && request.GetWordComplete()) { + char quote_char = request.GetParsedLine()[request.GetCursorIndex()].quote; common_prefix = Args::EscapeLLDBCommandArgument(common_prefix, quote_char); if (quote_char != '\0') common_prefix.push_back(quote_char); common_prefix.push_back(' '); } - matches.InsertStringAtIndex(0, common_prefix.c_str()); + request.GetMatches().InsertStringAtIndex(0, common_prefix.c_str()); } return num_command_matches; } Index: lldb/trunk/source/Interpreter/CommandObject.cpp =================================================================== --- lldb/trunk/source/Interpreter/CommandObject.cpp +++ lldb/trunk/source/Interpreter/CommandObject.cpp @@ -279,14 +279,8 @@ opt_element_vector = cur_options->ParseForCompletion( request.GetParsedLine(), request.GetCursorIndex()); - bool handled_by_options; - bool word_complete = request.GetWordComplete(); - handled_by_options = cur_options->HandleOptionCompletion( - request.GetParsedLine(), opt_element_vector, request.GetCursorIndex(), - request.GetCursorCharPosition(), request.GetMatchStartPoint(), - request.GetMaxReturnElements(), GetCommandInterpreter(), - word_complete, request.GetMatches()); - request.SetWordComplete(word_complete); + bool handled_by_options = cur_options->HandleOptionCompletion( + request, opt_element_vector, GetCommandInterpreter()); if (handled_by_options) return request.GetMatches().GetSize(); } @@ -1015,7 +1009,8 @@ static StreamString g_archs_help; if (g_archs_help.Empty()) { StringList archs; - ArchSpec::AutoComplete(llvm::StringRef(), archs); + + ArchSpec::ListSupportedArchNames(archs); g_archs_help.Printf("These are the supported architecture names:\n"); archs.Join("\n", g_archs_help); } Index: lldb/trunk/source/Interpreter/CommandObjectRegexCommand.cpp =================================================================== --- lldb/trunk/source/Interpreter/CommandObjectRegexCommand.cpp +++ lldb/trunk/source/Interpreter/CommandObjectRegexCommand.cpp @@ -95,15 +95,8 @@ int CommandObjectRegexCommand::HandleCompletion(CompletionRequest &request) { if (m_completion_type_mask) { - std::string completion_str( - request.GetParsedLine().GetArgumentAtIndex(request.GetCursorIndex()), - request.GetCursorCharPosition()); - bool word_complete = request.GetWordComplete(); CommandCompletions::InvokeCommonCompletionCallbacks( - GetCommandInterpreter(), m_completion_type_mask, completion_str.c_str(), - request.GetMatchStartPoint(), request.GetMaxReturnElements(), nullptr, - word_complete, request.GetMatches()); - request.SetWordComplete(word_complete); + GetCommandInterpreter(), m_completion_type_mask, request, nullptr); return request.GetMatches().GetSize(); } else { request.GetMatches().Clear(); Index: lldb/trunk/source/Interpreter/OptionValue.cpp =================================================================== --- lldb/trunk/source/Interpreter/OptionValue.cpp +++ lldb/trunk/source/Interpreter/OptionValue.cpp @@ -573,12 +573,10 @@ } size_t OptionValue::AutoComplete(CommandInterpreter &interpreter, - llvm::StringRef s, int match_start_point, - int max_return_elements, bool &word_complete, - StringList &matches) { - word_complete = false; - matches.Clear(); - return matches.GetSize(); + CompletionRequest &request) { + request.SetWordComplete(false); + request.GetMatches().Clear(); + return request.GetMatches().GetSize(); } Status OptionValue::SetValueFromString(llvm::StringRef value, Index: lldb/trunk/source/Interpreter/OptionValueArch.cpp =================================================================== --- lldb/trunk/source/Interpreter/OptionValueArch.cpp +++ lldb/trunk/source/Interpreter/OptionValueArch.cpp @@ -74,13 +74,11 @@ } size_t OptionValueArch::AutoComplete(CommandInterpreter &interpreter, - llvm::StringRef s, int match_start_point, - int max_return_elements, - bool &word_complete, StringList &matches) { - word_complete = false; - matches.Clear(); + CompletionRequest &request) { + request.SetWordComplete(false); + request.GetMatches().Clear(); CommandCompletions::InvokeCommonCompletionCallbacks( - interpreter, CommandCompletions::eArchitectureCompletion, s, - match_start_point, max_return_elements, nullptr, word_complete, matches); - return matches.GetSize(); + interpreter, CommandCompletions::eArchitectureCompletion, request, + nullptr); + return request.GetMatches().GetSize(); } Index: lldb/trunk/source/Interpreter/OptionValueBoolean.cpp =================================================================== --- lldb/trunk/source/Interpreter/OptionValueBoolean.cpp +++ lldb/trunk/source/Interpreter/OptionValueBoolean.cpp @@ -76,23 +76,22 @@ return OptionValueSP(new OptionValueBoolean(*this)); } -size_t OptionValueBoolean::AutoComplete( - CommandInterpreter &interpreter, llvm::StringRef s, int match_start_point, - int max_return_elements, bool &word_complete, StringList &matches) { - word_complete = false; - matches.Clear(); +size_t OptionValueBoolean::AutoComplete(CommandInterpreter &interpreter, + CompletionRequest &request) { + request.SetWordComplete(false); + request.GetMatches().Clear(); static const llvm::StringRef g_autocomplete_entries[] = { "true", "false", "on", "off", "yes", "no", "1", "0"}; auto entries = llvm::makeArrayRef(g_autocomplete_entries); // only suggest "true" or "false" by default - if (s.empty()) + if (request.GetCursorArgumentPrefix().empty()) entries = entries.take_front(2); for (auto entry : entries) { - if (entry.startswith_lower(s)) - matches.AppendString(entry); + if (entry.startswith_lower(request.GetCursorArgumentPrefix())) + request.GetMatches().AppendString(entry); } - return matches.GetSize(); + return request.GetMatches().GetSize(); } Index: lldb/trunk/source/Interpreter/OptionValueEnumeration.cpp =================================================================== --- lldb/trunk/source/Interpreter/OptionValueEnumeration.cpp +++ lldb/trunk/source/Interpreter/OptionValueEnumeration.cpp @@ -109,23 +109,23 @@ return OptionValueSP(new OptionValueEnumeration(*this)); } -size_t OptionValueEnumeration::AutoComplete( - CommandInterpreter &interpreter, llvm::StringRef s, int match_start_point, - int max_return_elements, bool &word_complete, StringList &matches) { - word_complete = false; - matches.Clear(); +size_t OptionValueEnumeration::AutoComplete(CommandInterpreter &interpreter, + CompletionRequest &request) { + request.SetWordComplete(false); + request.GetMatches().Clear(); const uint32_t num_enumerators = m_enumerations.GetSize(); - if (!s.empty()) { + if (!request.GetCursorArgumentPrefix().empty()) { for (size_t i = 0; i < num_enumerators; ++i) { llvm::StringRef name = m_enumerations.GetCStringAtIndex(i).GetStringRef(); - if (name.startswith(s)) - matches.AppendString(name); + if (name.startswith(request.GetCursorArgumentPrefix())) + request.GetMatches().AppendString(name); } } else { // only suggest "true" or "false" by default for (size_t i = 0; i < num_enumerators; ++i) - matches.AppendString(m_enumerations.GetCStringAtIndex(i).GetStringRef()); + request.GetMatches().AppendString( + m_enumerations.GetCStringAtIndex(i).GetStringRef()); } - return matches.GetSize(); + return request.GetMatches().GetSize(); } Index: lldb/trunk/source/Interpreter/OptionValueFileSpec.cpp =================================================================== --- lldb/trunk/source/Interpreter/OptionValueFileSpec.cpp +++ lldb/trunk/source/Interpreter/OptionValueFileSpec.cpp @@ -99,15 +99,13 @@ return OptionValueSP(new OptionValueFileSpec(*this)); } -size_t OptionValueFileSpec::AutoComplete( - CommandInterpreter &interpreter, llvm::StringRef s, int match_start_point, - int max_return_elements, bool &word_complete, StringList &matches) { - word_complete = false; - matches.Clear(); +size_t OptionValueFileSpec::AutoComplete(CommandInterpreter &interpreter, + CompletionRequest &request) { + request.SetWordComplete(false); + request.GetMatches().Clear(); CommandCompletions::InvokeCommonCompletionCallbacks( - interpreter, m_completion_mask, s, match_start_point, max_return_elements, - nullptr, word_complete, matches); - return matches.GetSize(); + interpreter, m_completion_mask, request, nullptr); + return request.GetMatches().GetSize(); } const lldb::DataBufferSP &OptionValueFileSpec::GetFileContents() { Index: lldb/trunk/source/Interpreter/OptionValueFormatEntity.cpp =================================================================== --- lldb/trunk/source/Interpreter/OptionValueFormatEntity.cpp +++ lldb/trunk/source/Interpreter/OptionValueFormatEntity.cpp @@ -105,9 +105,7 @@ return OptionValueSP(new OptionValueFormatEntity(*this)); } -size_t OptionValueFormatEntity::AutoComplete( - CommandInterpreter &interpreter, llvm::StringRef s, int match_start_point, - int max_return_elements, bool &word_complete, StringList &matches) { - return FormatEntity::AutoComplete(s, match_start_point, max_return_elements, - word_complete, matches); +size_t OptionValueFormatEntity::AutoComplete(CommandInterpreter &interpreter, + CompletionRequest &request) { + return FormatEntity::AutoComplete(request); } Index: lldb/trunk/source/Interpreter/OptionValueUUID.cpp =================================================================== --- lldb/trunk/source/Interpreter/OptionValueUUID.cpp +++ lldb/trunk/source/Interpreter/OptionValueUUID.cpp @@ -68,16 +68,15 @@ } size_t OptionValueUUID::AutoComplete(CommandInterpreter &interpreter, - llvm::StringRef s, int match_start_point, - int max_return_elements, - bool &word_complete, StringList &matches) { - word_complete = false; - matches.Clear(); + CompletionRequest &request) { + request.SetWordComplete(false); + request.GetMatches().Clear(); ExecutionContext exe_ctx(interpreter.GetExecutionContext()); Target *target = exe_ctx.GetTargetPtr(); if (target) { + auto prefix = request.GetCursorArgumentPrefix(); llvm::SmallVector uuid_bytes; - if (UUID::DecodeUUIDBytesFromString(s, uuid_bytes).empty()) { + if (UUID::DecodeUUIDBytesFromString(prefix, uuid_bytes).empty()) { const size_t num_modules = target->GetImages().GetSize(); for (size_t i = 0; i < num_modules; ++i) { ModuleSP module_sp(target->GetImages().GetModuleAtIndex(i)); @@ -87,12 +86,12 @@ llvm::ArrayRef module_bytes = module_uuid.GetBytes(); if (module_bytes.size() >= uuid_bytes.size() && module_bytes.take_front(uuid_bytes.size()).equals(uuid_bytes)) { - matches.AppendString(module_uuid.GetAsString()); + request.GetMatches().AppendString(module_uuid.GetAsString()); } } } } } } - return matches.GetSize(); + return request.GetMatches().GetSize(); } Index: lldb/trunk/source/Interpreter/Options.cpp =================================================================== --- lldb/trunk/source/Interpreter/Options.cpp +++ lldb/trunk/source/Interpreter/Options.cpp @@ -647,12 +647,10 @@ return options_are_valid; } -bool Options::HandleOptionCompletion( - Args &input, OptionElementVector &opt_element_vector, int cursor_index, - int char_pos, int match_start_point, int max_return_elements, - CommandInterpreter &interpreter, bool &word_complete, - lldb_private::StringList &matches) { - word_complete = true; +bool Options::HandleOptionCompletion(CompletionRequest &request, + OptionElementVector &opt_element_vector, + CommandInterpreter &interpreter) { + request.SetWordComplete(true); // For now we just scan the completions to see if the cursor position is in // an option or its argument. Otherwise we'll call HandleArgumentCompletion. @@ -661,15 +659,14 @@ auto opt_defs = GetDefinitions(); - std::string cur_opt_std_str(input.GetArgumentAtIndex(cursor_index)); - cur_opt_std_str.erase(char_pos); + std::string cur_opt_std_str = request.GetCursorArgumentPrefix().str(); const char *cur_opt_str = cur_opt_std_str.c_str(); for (size_t i = 0; i < opt_element_vector.size(); i++) { int opt_pos = opt_element_vector[i].opt_pos; int opt_arg_pos = opt_element_vector[i].opt_arg_pos; int opt_defs_index = opt_element_vector[i].opt_defs_index; - if (opt_pos == cursor_index) { + if (opt_pos == request.GetCursorIndex()) { // We're completing the option itself. if (opt_defs_index == OptionArgElement::eBareDash) { @@ -683,7 +680,7 @@ if (!def.short_option) continue; opt_str[1] = def.short_option; - matches.AppendString(opt_str); + request.GetMatches().AppendString(opt_str); } return true; @@ -695,7 +692,7 @@ full_name.erase(full_name.begin() + 2, full_name.end()); full_name.append(def.long_option); - matches.AppendString(full_name.c_str()); + request.GetMatches().AppendString(full_name.c_str()); } return true; } else if (opt_defs_index != OptionArgElement::eUnrecognizedArg) { @@ -708,10 +705,10 @@ strcmp(opt_defs[opt_defs_index].long_option, cur_opt_str) != 0) { std::string full_name("--"); full_name.append(opt_defs[opt_defs_index].long_option); - matches.AppendString(full_name.c_str()); + request.GetMatches().AppendString(full_name.c_str()); return true; } else { - matches.AppendString(input.GetArgumentAtIndex(cursor_index)); + request.GetMatches().AppendString(request.GetCursorArgument()); return true; } } else { @@ -734,29 +731,30 @@ // The options definitions table has duplicates because of the // way the grouping information is stored, so only add once. bool duplicate = false; - for (size_t k = 0; k < matches.GetSize(); k++) { - if (matches.GetStringAtIndex(k) == full_name) { + for (size_t k = 0; k < request.GetMatches().GetSize(); k++) { + if (request.GetMatches().GetStringAtIndex(k) == full_name) { duplicate = true; break; } } if (!duplicate) - matches.AppendString(full_name.c_str()); + request.GetMatches().AppendString(full_name.c_str()); } } } return true; } - } else if (opt_arg_pos == cursor_index) { + } else if (opt_arg_pos == request.GetCursorIndex()) { // Okay the cursor is on the completion of an argument. See if it has a // completion, otherwise return no matches. + CompletionRequest subrequest = request; + subrequest.SetCursorCharPosition(subrequest.GetCursorArgument().size()); if (opt_defs_index != -1) { - HandleOptionArgumentCompletion( - input, cursor_index, strlen(input.GetArgumentAtIndex(cursor_index)), - opt_element_vector, i, match_start_point, max_return_elements, - interpreter, word_complete, matches); + HandleOptionArgumentCompletion(subrequest, opt_element_vector, i, + interpreter); + request.SetWordComplete(subrequest.GetWordComplete()); return true; } else { // No completion callback means no completions... @@ -772,11 +770,8 @@ } bool Options::HandleOptionArgumentCompletion( - Args &input, int cursor_index, int char_pos, - OptionElementVector &opt_element_vector, int opt_element_index, - int match_start_point, int max_return_elements, - CommandInterpreter &interpreter, bool &word_complete, - lldb_private::StringList &matches) { + CompletionRequest &request, OptionElementVector &opt_element_vector, + int opt_element_index, CommandInterpreter &interpreter) { auto opt_defs = GetDefinitions(); std::unique_ptr filter_ap; @@ -788,12 +783,14 @@ OptionEnumValueElement *enum_values = opt_defs[opt_defs_index].enum_values; if (enum_values != nullptr) { bool return_value = false; - std::string match_string(input.GetArgumentAtIndex(opt_arg_pos), - input.GetArgumentAtIndex(opt_arg_pos) + char_pos); + std::string match_string( + request.GetParsedLine().GetArgumentAtIndex(opt_arg_pos), + request.GetParsedLine().GetArgumentAtIndex(opt_arg_pos) + + request.GetCursorCharPosition()); for (int i = 0; enum_values[i].string_value != nullptr; i++) { if (strstr(enum_values[i].string_value, match_string.c_str()) == enum_values[i].string_value) { - matches.AppendString(enum_values[i].string_value); + request.GetMatches().AppendString(enum_values[i].string_value); return_value = true; } } @@ -838,7 +835,8 @@ // restrict it to that shared library. if (cur_opt_name && strcmp(cur_opt_name, "shlib") == 0 && cur_arg_pos != -1) { - const char *module_name = input.GetArgumentAtIndex(cur_arg_pos); + const char *module_name = + request.GetParsedLine().GetArgumentAtIndex(cur_arg_pos); if (module_name) { FileSpec module_spec(module_name, false); lldb::TargetSP target_sp = @@ -853,9 +851,7 @@ } return CommandCompletions::InvokeCommonCompletionCallbacks( - interpreter, completion_mask, input.GetArgumentAtIndex(opt_arg_pos), - match_start_point, max_return_elements, filter_ap.get(), word_complete, - matches); + interpreter, completion_mask, request, filter_ap.get()); } void OptionGroupOptions::Append(OptionGroup *group) { Index: lldb/trunk/source/Symbol/Variable.cpp =================================================================== --- lldb/trunk/source/Symbol/Variable.cpp +++ lldb/trunk/source/Symbol/Variable.cpp @@ -756,13 +756,13 @@ } size_t Variable::AutoComplete(const ExecutionContext &exe_ctx, - llvm::StringRef partial_path, StringList &matches, - bool &word_complete) { - word_complete = false; + CompletionRequest &request) { CompilerType compiler_type; - PrivateAutoComplete(exe_ctx.GetFramePtr(), partial_path, "", compiler_type, - matches, word_complete); + bool word_complete = false; + PrivateAutoComplete(exe_ctx.GetFramePtr(), request.GetCursorArgumentPrefix(), + "", compiler_type, request.GetMatches(), word_complete); + request.SetWordComplete(word_complete); - return matches.GetSize(); + return request.GetMatches().GetSize(); } Index: lldb/trunk/source/Utility/ArchSpec.cpp =================================================================== --- lldb/trunk/source/Utility/ArchSpec.cpp +++ lldb/trunk/source/Utility/ArchSpec.cpp @@ -245,17 +245,22 @@ const char *name; }; -size_t ArchSpec::AutoComplete(llvm::StringRef name, StringList &matches) { - if (!name.empty()) { +void ArchSpec::ListSupportedArchNames(StringList &list) { + for (uint32_t i = 0; i < llvm::array_lengthof(g_core_definitions); ++i) + list.AppendString(g_core_definitions[i].name); +} + +size_t ArchSpec::AutoComplete(CompletionRequest &request) { + if (!request.GetCursorArgumentPrefix().empty()) { for (uint32_t i = 0; i < llvm::array_lengthof(g_core_definitions); ++i) { - if (NameMatches(g_core_definitions[i].name, NameMatch::StartsWith, name)) - matches.AppendString(g_core_definitions[i].name); + if (NameMatches(g_core_definitions[i].name, NameMatch::StartsWith, + request.GetCursorArgumentPrefix())) + request.GetMatches().AppendString(g_core_definitions[i].name); } } else { - for (uint32_t i = 0; i < llvm::array_lengthof(g_core_definitions); ++i) - matches.AppendString(g_core_definitions[i].name); + ListSupportedArchNames(request.GetMatches()); } - return matches.GetSize(); + return request.GetMatches().GetSize(); } #define CPU_ANY (UINT32_MAX) Index: lldb/trunk/source/Utility/CompletionRequest.cpp =================================================================== --- lldb/trunk/source/Utility/CompletionRequest.cpp +++ lldb/trunk/source/Utility/CompletionRequest.cpp @@ -12,15 +12,48 @@ using namespace lldb; using namespace lldb_private; -CompletionRequest::CompletionRequest(llvm::StringRef command, - unsigned raw_cursor_pos, Args &parsed_line, - int cursor_index, int cursor_char_position, +CompletionRequest::CompletionRequest(llvm::StringRef command_line, + unsigned raw_cursor_pos, int match_start_point, int max_return_elements, - bool word_complete, StringList &matches) - : m_command(command), m_raw_cursor_pos(raw_cursor_pos), - m_parsed_line(parsed_line), m_cursor_index(cursor_index), - m_cursor_char_position(cursor_char_position), + StringList &matches) + : m_command(command_line), m_raw_cursor_pos(raw_cursor_pos), m_match_start_point(match_start_point), - m_max_return_elements(max_return_elements), - m_word_complete(word_complete), m_matches(&matches) {} + m_max_return_elements(max_return_elements), m_matches(&matches) { + + // We parse the argument up to the cursor, so the last argument in + // parsed_line is the one containing the cursor, and the cursor is after the + // last character. + m_parsed_line = Args(command_line); + m_partial_parsed_line = Args(command_line.substr(0, raw_cursor_pos)); + + m_cursor_index = m_partial_parsed_line.GetArgumentCount() - 1; + + if (m_cursor_index == -1) + m_cursor_char_position = 0; + else + m_cursor_char_position = + strlen(m_partial_parsed_line.GetArgumentAtIndex(m_cursor_index)); + + matches.Clear(); + + const char *cursor = command_line.data() + raw_cursor_pos; + if (raw_cursor_pos > 0 && cursor[-1] == ' ') { + // We are just after a space. If we are in an argument, then we will + // continue parsing, but if we are between arguments, then we have to + // complete whatever the next element would be. We can distinguish the two + // cases because if we are in an argument (e.g. because the space is + // protected by a quote) then the space will also be in the parsed + // argument... + + const char *current_elem = + m_partial_parsed_line.GetArgumentAtIndex(m_cursor_index); + if (m_cursor_char_position == 0 || + current_elem[m_cursor_char_position - 1] != ' ') { + m_parsed_line.InsertArgumentAtIndex(m_cursor_index + 1, llvm::StringRef(), + '\0'); + m_cursor_index++; + m_cursor_char_position = 0; + } + } +} Index: lldb/trunk/unittests/Utility/CompletionRequestTest.cpp =================================================================== --- lldb/trunk/unittests/Utility/CompletionRequestTest.cpp +++ lldb/trunk/unittests/Utility/CompletionRequestTest.cpp @@ -13,18 +13,16 @@ using namespace lldb_private; TEST(CompletionRequest, Constructor) { - std::string command = "a b"; - const unsigned cursor_pos = 2; - Args args(command); + std::string command = "a bad c"; + const unsigned cursor_pos = 3; const int arg_index = 1; - const int arg_cursor_pos = 0; + const int arg_cursor_pos = 1; const int match_start = 2345; const int match_max_return = 12345; - bool word_complete = false; StringList matches; - CompletionRequest request(command, cursor_pos, args, arg_index, - arg_cursor_pos, match_start, match_max_return, - word_complete, matches); + + CompletionRequest request(command, cursor_pos, match_start, match_max_return, + matches); EXPECT_STREQ(request.GetRawLine().str().c_str(), command.c_str()); EXPECT_EQ(request.GetRawCursorPos(), cursor_pos); @@ -32,7 +30,11 @@ EXPECT_EQ(request.GetCursorCharPosition(), arg_cursor_pos); EXPECT_EQ(request.GetMatchStartPoint(), match_start); EXPECT_EQ(request.GetMaxReturnElements(), match_max_return); - EXPECT_EQ(request.GetWordComplete(), word_complete); + EXPECT_EQ(request.GetWordComplete(), false); + + EXPECT_EQ(request.GetPartialParsedLine().GetArgumentCount(), 2u); + EXPECT_STREQ(request.GetPartialParsedLine().GetArgumentAtIndex(1), "b"); + // This is the generated matches should be equal to our passed string list. EXPECT_EQ(&request.GetMatches(), &matches); }