From a2e76c0bfc5bec8d50e8d13f71b72a66eaa0a386 Mon Sep 17 00:00:00 2001 From: Raphael Isemann Date: Fri, 13 Jul 2018 18:28:14 +0000 Subject: [PATCH] Replaced more boilerplate code with CompletionRequest (NFC) Summary: As suggested in D48796, this patch replaces even more internal calls that were using the old completion API style with a single CompletionRequest. In some cases we also pass an option vector/index, but as we don't always have this information, it currently is not part of the CompletionRequest class. The constructor of the CompletionRequest is now also more sensible. You only pass the user input, cursor position and your list of matches to the request and the rest will be inferred (using the same code we used before to calculate this). You also have to pass these match window parameters to it, even though they are unused right now. The patch shouldn't change any behavior. Reviewers: jingham Reviewed By: jingham Subscribers: lldb-commits Differential Revision: https://reviews.llvm.org/D48976 llvm-svn: 337031 --- lldb/include/lldb/Core/FormatEntity.h | 5 +- lldb/include/lldb/Interpreter/CommandCompletions.h | 83 +++------ lldb/include/lldb/Interpreter/OptionValue.h | 5 +- lldb/include/lldb/Interpreter/OptionValueArch.h | 5 +- lldb/include/lldb/Interpreter/OptionValueBoolean.h | 5 +- .../lldb/Interpreter/OptionValueEnumeration.h | 5 +- .../include/lldb/Interpreter/OptionValueFileSpec.h | 5 +- .../lldb/Interpreter/OptionValueFormatEntity.h | 5 +- lldb/include/lldb/Interpreter/OptionValueUUID.h | 5 +- lldb/include/lldb/Interpreter/Options.h | 73 ++------ lldb/include/lldb/Symbol/Variable.h | 3 +- lldb/include/lldb/Utility/ArchSpec.h | 4 +- lldb/include/lldb/Utility/CompletionRequest.h | 48 ++++-- lldb/source/Commands/CommandCompletions.cpp | 189 ++++++++------------- lldb/source/Commands/CommandObjectCommands.cpp | 19 +-- lldb/source/Commands/CommandObjectFrame.cpp | 9 +- lldb/source/Commands/CommandObjectPlatform.cpp | 23 +-- lldb/source/Commands/CommandObjectPlugin.cpp | 9 +- lldb/source/Commands/CommandObjectProcess.cpp | 20 +-- lldb/source/Commands/CommandObjectSettings.cpp | 97 ++--------- lldb/source/Commands/CommandObjectTarget.cpp | 54 +----- lldb/source/Core/FormatEntity.cpp | 30 ++-- lldb/source/Core/IOHandler.cpp | 19 +-- lldb/source/Interpreter/CommandInterpreter.cpp | 79 ++------- lldb/source/Interpreter/CommandObject.cpp | 13 +- .../Interpreter/CommandObjectRegexCommand.cpp | 9 +- lldb/source/Interpreter/OptionValue.cpp | 10 +- lldb/source/Interpreter/OptionValueArch.cpp | 14 +- lldb/source/Interpreter/OptionValueBoolean.cpp | 17 +- lldb/source/Interpreter/OptionValueEnumeration.cpp | 20 +-- lldb/source/Interpreter/OptionValueFileSpec.cpp | 14 +- .../source/Interpreter/OptionValueFormatEntity.cpp | 8 +- lldb/source/Interpreter/OptionValueUUID.cpp | 15 +- lldb/source/Interpreter/Options.cpp | 62 ++++--- lldb/source/Symbol/Variable.cpp | 12 +- lldb/source/Utility/ArchSpec.cpp | 19 ++- lldb/source/Utility/CompletionRequest.cpp | 51 +++++- lldb/unittests/Utility/CompletionRequestTest.cpp | 20 ++- 38 files changed, 379 insertions(+), 704 deletions(-) diff --git a/lldb/include/lldb/Core/FormatEntity.h b/lldb/include/lldb/Core/FormatEntity.h index 7b11112..93c7b3a 100644 --- a/lldb/include/lldb/Core/FormatEntity.h +++ b/lldb/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 @@ public: 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. diff --git a/lldb/include/lldb/Interpreter/CommandCompletions.h b/lldb/include/lldb/Interpreter/CommandCompletions.h index 4a8165b..d17864e 100644 --- a/lldb/include/lldb/Interpreter/CommandCompletions.h +++ b/lldb/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 @@ public: // 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 @@ public: 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 @@ public: //---------------------------------------------------------------------- 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 @@ public: 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 @@ public: 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 @@ public: 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 @@ public: 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; diff --git a/lldb/include/lldb/Interpreter/OptionValue.h b/lldb/include/lldb/Interpreter/OptionValue.h index 7694d68..4748e30 100644 --- a/lldb/include/lldb/Interpreter/OptionValue.h +++ b/lldb/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 @@ public: 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 diff --git a/lldb/include/lldb/Interpreter/OptionValueArch.h b/lldb/include/lldb/Interpreter/OptionValueArch.h index d66448a..edb6e24 100644 --- a/lldb/include/lldb/Interpreter/OptionValueArch.h +++ b/lldb/include/lldb/Interpreter/OptionValueArch.h @@ -57,9 +57,8 @@ public: 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 diff --git a/lldb/include/lldb/Interpreter/OptionValueBoolean.h b/lldb/include/lldb/Interpreter/OptionValueBoolean.h index 1ff84dd..6d2a16e 100644 --- a/lldb/include/lldb/Interpreter/OptionValueBoolean.h +++ b/lldb/include/lldb/Interpreter/OptionValueBoolean.h @@ -50,9 +50,8 @@ public: 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 diff --git a/lldb/include/lldb/Interpreter/OptionValueEnumeration.h b/lldb/include/lldb/Interpreter/OptionValueEnumeration.h index 4aa8823..08d6ac7 100644 --- a/lldb/include/lldb/Interpreter/OptionValueEnumeration.h +++ b/lldb/include/lldb/Interpreter/OptionValueEnumeration.h @@ -59,9 +59,8 @@ public: 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 diff --git a/lldb/include/lldb/Interpreter/OptionValueFileSpec.h b/lldb/include/lldb/Interpreter/OptionValueFileSpec.h index 293ecd0..41a479e 100644 --- a/lldb/include/lldb/Interpreter/OptionValueFileSpec.h +++ b/lldb/include/lldb/Interpreter/OptionValueFileSpec.h @@ -54,9 +54,8 @@ public: 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 diff --git a/lldb/include/lldb/Interpreter/OptionValueFormatEntity.h b/lldb/include/lldb/Interpreter/OptionValueFormatEntity.h index e5a65b7..880e434 100644 --- a/lldb/include/lldb/Interpreter/OptionValueFormatEntity.h +++ b/lldb/include/lldb/Interpreter/OptionValueFormatEntity.h @@ -45,9 +45,8 @@ public: 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 diff --git a/lldb/include/lldb/Interpreter/OptionValueUUID.h b/lldb/include/lldb/Interpreter/OptionValueUUID.h index 6e0aeeb..950efb5 100644 --- a/lldb/include/lldb/Interpreter/OptionValueUUID.h +++ b/lldb/include/lldb/Interpreter/OptionValueUUID.h @@ -61,9 +61,8 @@ public: 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; diff --git a/lldb/include/lldb/Interpreter/Options.h b/lldb/include/lldb/Interpreter/Options.h index ec611cc..0f0f983 100644 --- a/lldb/include/lldb/Interpreter/Options.h +++ b/lldb/include/lldb/Interpreter/Options.h @@ -176,30 +176,12 @@ public: /// 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 @@ public: /// @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 @@ public: /// \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 diff --git a/lldb/include/lldb/Symbol/Variable.h b/lldb/include/lldb/Symbol/Variable.h index 5c74d3c..1caec7e 100644 --- a/lldb/include/lldb/Symbol/Variable.h +++ b/lldb/include/lldb/Symbol/Variable.h @@ -103,8 +103,7 @@ public: ValueObjectList &valobj_list); static size_t AutoComplete(const ExecutionContext &exe_ctx, - llvm::StringRef name, StringList &matches, - bool &word_complete); + CompletionRequest &request); CompilerDeclContext GetDeclContext(); diff --git a/lldb/include/lldb/Utility/ArchSpec.h b/lldb/include/lldb/Utility/ArchSpec.h index ac847e1..680e9b1 100644 --- a/lldb/include/lldb/Utility/ArchSpec.h +++ b/lldb/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 @@ public: //--------------------------------------------------------------------------- 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. diff --git a/lldb/include/lldb/Utility/CompletionRequest.h b/lldb/include/lldb/Utility/CompletionRequest.h index 0ccadca..cfae16f 100644 --- a/lldb/include/lldb/Utility/CompletionRequest.h +++ b/lldb/include/lldb/Utility/CompletionRequest.h @@ -27,26 +27,42 @@ namespace lldb_private { //---------------------------------------------------------------------- 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 @@ public: /// 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 @@ private: 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 @@ private: 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; }; diff --git a/lldb/source/Commands/CommandCompletions.cpp b/lldb/source/Commands/CommandCompletions.cpp index f83a06d..bdfdbb8 100644 --- a/lldb/source/Commands/CommandCompletions.cpp +++ b/lldb/source/Commands/CommandCompletions.cpp @@ -57,9 +57,7 @@ CommandCompletions::CommonCompletionElement 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 @@ bool CommandCompletions::InvokeCommonCompletionCallbacks( 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 @@ int CommandCompletions::SourceFiles(CommandInterpreter &interpreter, } 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 @@ static int DiskFilesOrDirectories(const llvm::Twine &partial_name, // 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 @@ static int DiskFilesOrDirectories(const llvm::Twine &partial_name, 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 @@ static int DiskFilesOrDirectories(const llvm::Twine &partial_name, CompletionBuffer.append(Name); if (is_dir) { - saw_directory = true; path::append(CompletionBuffer, path::get_separator()); } @@ -238,51 +225,40 @@ static int DiskFilesOrDirectories(const llvm::Twine &partial_name, } 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 @@ int CommandCompletions::Modules(CommandInterpreter &interpreter, } 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 @@ int CommandCompletions::Symbols(CommandInterpreter &interpreter, } 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 @@ int CommandCompletions::SettingsNames( } 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::Completer::~Completer() = default; 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 @@ CommandCompletions::SourceFileCompleter::DoCompletion(SearchFilter *filter) { 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 @@ static bool regex_chars(const char comp) { } 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 @@ size_t CommandCompletions::SymbolCompleter::DoCompletion(SearchFilter *filter) { 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 @@ Searcher::CallbackReturn CommandCompletions::ModuleCompleter::SearchCallback( match = false; if (match) { - m_matches.AppendString(cur_file_name); + m_request.GetMatches().AppendString(cur_file_name); } } return Searcher::eCallbackReturnContinue; @@ -570,5 +525,5 @@ Searcher::CallbackReturn CommandCompletions::ModuleCompleter::SearchCallback( size_t CommandCompletions::ModuleCompleter::DoCompletion(SearchFilter *filter) { filter->Search(*this); - return m_matches.GetSize(); + return m_request.GetMatches().GetSize(); } diff --git a/lldb/source/Commands/CommandObjectCommands.cpp b/lldb/source/Commands/CommandObjectCommands.cpp index b7f439e..3012ee4 100644 --- a/lldb/source/Commands/CommandObjectCommands.cpp +++ b/lldb/source/Commands/CommandObjectCommands.cpp @@ -238,16 +238,9 @@ public: 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 @@ public: 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(); } diff --git a/lldb/source/Commands/CommandObjectFrame.cpp b/lldb/source/Commands/CommandObjectFrame.cpp index 6860021..0183c43 100644 --- a/lldb/source/Commands/CommandObjectFrame.cpp +++ b/lldb/source/Commands/CommandObjectFrame.cpp @@ -467,16 +467,9 @@ public: 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(); } diff --git a/lldb/source/Commands/CommandObjectPlatform.cpp b/lldb/source/Commands/CommandObjectPlatform.cpp index 3a27f34..f822a8b 100644 --- a/lldb/source/Commands/CommandObjectPlatform.cpp +++ b/lldb/source/Commands/CommandObjectPlatform.cpp @@ -179,16 +179,8 @@ public: ~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 @@ public: } 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 @@ public: // 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 @@ public: 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)); } diff --git a/lldb/source/Commands/CommandObjectPlugin.cpp b/lldb/source/Commands/CommandObjectPlugin.cpp index 36db0d1..1f379a2 100644 --- a/lldb/source/Commands/CommandObjectPlugin.cpp +++ b/lldb/source/Commands/CommandObjectPlugin.cpp @@ -45,16 +45,9 @@ public: 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(); } diff --git a/lldb/source/Commands/CommandObjectProcess.cpp b/lldb/source/Commands/CommandObjectProcess.cpp index 86d4777..3ac2791 100644 --- a/lldb/source/Commands/CommandObjectProcess.cpp +++ b/lldb/source/Commands/CommandObjectProcess.cpp @@ -137,17 +137,10 @@ public: 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 @@ public: } 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 @@ public: // 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 @@ public: 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)); } diff --git a/lldb/source/Commands/CommandObjectSettings.cpp b/lldb/source/Commands/CommandObjectSettings.cpp index ed58ca4..f259f2f 100644 --- a/lldb/source/Commands/CommandObjectSettings.cpp +++ b/lldb/source/Commands/CommandObjectSettings.cpp @@ -136,9 +136,6 @@ insert-before or insert-after."); 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 @@ insert-before or insert-after."); } 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 @@ insert-before or insert-after."); 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 @@ public: 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 @@ public: 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 @@ public: 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 @@ public: 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 @@ public: 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 @@ public: 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 @@ public: 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 @@ public: 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(); } diff --git a/lldb/source/Commands/CommandObjectTarget.cpp b/lldb/source/Commands/CommandObjectTarget.cpp index fc25fb3..a9062c1 100644 --- a/lldb/source/Commands/CommandObjectTarget.cpp +++ b/lldb/source/Commands/CommandObjectTarget.cpp @@ -198,17 +198,9 @@ public: 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 @@ public: 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 @@ public: 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 @@ public: 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 @@ public: 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(); } diff --git a/lldb/source/Core/FormatEntity.cpp b/lldb/source/Core/FormatEntity.cpp index f0b5b52..de9263f 100644 --- a/lldb/source/Core/FormatEntity.cpp +++ b/lldb/source/Core/FormatEntity.cpp @@ -2344,12 +2344,12 @@ static void AddMatches(const FormatEntity::Entry::Definition *def, } } -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 @@ size_t FormatEntity::AutoComplete(llvm::StringRef str, int match_start_point, 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 @@ size_t FormatEntity::AutoComplete(llvm::StringRef str, int match_start_point, 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 @@ size_t FormatEntity::AutoComplete(llvm::StringRef str, int match_start_point, // 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(); } diff --git a/lldb/source/Core/IOHandler.cpp b/lldb/source/Core/IOHandler.cpp index 82eccce..8474e4b 100644 --- a/lldb/source/Core/IOHandler.cpp +++ b/lldb/source/Core/IOHandler.cpp @@ -239,26 +239,21 @@ int IOHandlerDelegate::IOHandlerComplete(IOHandler &io_handler, 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); diff --git a/lldb/source/Interpreter/CommandInterpreter.cpp b/lldb/source/Interpreter/CommandInterpreter.cpp index d6d271a..df27eb2 100644 --- a/lldb/source/Interpreter/CommandInterpreter.cpp +++ b/lldb/source/Interpreter/CommandInterpreter.cpp @@ -1697,14 +1697,10 @@ bool CommandInterpreter::HandleCommand(const char *command_line, // 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::HandleCompletionMatches(CompletionRequest &request) { 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 @@ int CommandInterpreter::HandleCompletion( // 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; } diff --git a/lldb/source/Interpreter/CommandObject.cpp b/lldb/source/Interpreter/CommandObject.cpp index 004cdf0..07be913 100644 --- a/lldb/source/Interpreter/CommandObject.cpp +++ b/lldb/source/Interpreter/CommandObject.cpp @@ -279,14 +279,8 @@ int CommandObject::HandleCompletion(CompletionRequest &request) { 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 llvm::StringRef arch_helper() { 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); } diff --git a/lldb/source/Interpreter/CommandObjectRegexCommand.cpp b/lldb/source/Interpreter/CommandObjectRegexCommand.cpp index a5362c3..f975c0e 100644 --- a/lldb/source/Interpreter/CommandObjectRegexCommand.cpp +++ b/lldb/source/Interpreter/CommandObjectRegexCommand.cpp @@ -95,15 +95,8 @@ bool CommandObjectRegexCommand::AddRegexCommand(const char *re_cstr, 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(); diff --git a/lldb/source/Interpreter/OptionValue.cpp b/lldb/source/Interpreter/OptionValue.cpp index c02ffeb..2d7c69e 100644 --- a/lldb/source/Interpreter/OptionValue.cpp +++ b/lldb/source/Interpreter/OptionValue.cpp @@ -573,12 +573,10 @@ bool OptionValue::DumpQualifiedName(Stream &strm) const { } 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, diff --git a/lldb/source/Interpreter/OptionValueArch.cpp b/lldb/source/Interpreter/OptionValueArch.cpp index 12b8e603..3d08780 100644 --- a/lldb/source/Interpreter/OptionValueArch.cpp +++ b/lldb/source/Interpreter/OptionValueArch.cpp @@ -74,13 +74,11 @@ lldb::OptionValueSP OptionValueArch::DeepCopy() const { } 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(); } diff --git a/lldb/source/Interpreter/OptionValueBoolean.cpp b/lldb/source/Interpreter/OptionValueBoolean.cpp index 43c8233..8a34079 100644 --- a/lldb/source/Interpreter/OptionValueBoolean.cpp +++ b/lldb/source/Interpreter/OptionValueBoolean.cpp @@ -76,23 +76,22 @@ lldb::OptionValueSP OptionValueBoolean::DeepCopy() const { 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(); } diff --git a/lldb/source/Interpreter/OptionValueEnumeration.cpp b/lldb/source/Interpreter/OptionValueEnumeration.cpp index 9510f4a..e78618e 100644 --- a/lldb/source/Interpreter/OptionValueEnumeration.cpp +++ b/lldb/source/Interpreter/OptionValueEnumeration.cpp @@ -109,23 +109,23 @@ lldb::OptionValueSP OptionValueEnumeration::DeepCopy() const { 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(); } diff --git a/lldb/source/Interpreter/OptionValueFileSpec.cpp b/lldb/source/Interpreter/OptionValueFileSpec.cpp index d3abf3f..18bfcd6 100644 --- a/lldb/source/Interpreter/OptionValueFileSpec.cpp +++ b/lldb/source/Interpreter/OptionValueFileSpec.cpp @@ -99,15 +99,13 @@ lldb::OptionValueSP OptionValueFileSpec::DeepCopy() const { 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() { diff --git a/lldb/source/Interpreter/OptionValueFormatEntity.cpp b/lldb/source/Interpreter/OptionValueFormatEntity.cpp index dc9afea..ce1a84e 100644 --- a/lldb/source/Interpreter/OptionValueFormatEntity.cpp +++ b/lldb/source/Interpreter/OptionValueFormatEntity.cpp @@ -105,9 +105,7 @@ lldb::OptionValueSP OptionValueFormatEntity::DeepCopy() const { 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); } diff --git a/lldb/source/Interpreter/OptionValueUUID.cpp b/lldb/source/Interpreter/OptionValueUUID.cpp index b940584..7fa1552 100644 --- a/lldb/source/Interpreter/OptionValueUUID.cpp +++ b/lldb/source/Interpreter/OptionValueUUID.cpp @@ -68,16 +68,15 @@ lldb::OptionValueSP OptionValueUUID::DeepCopy() const { } 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 @@ size_t OptionValueUUID::AutoComplete(CommandInterpreter &interpreter, 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(); } diff --git a/lldb/source/Interpreter/Options.cpp b/lldb/source/Interpreter/Options.cpp index 1840598..f475897 100644 --- a/lldb/source/Interpreter/Options.cpp +++ b/lldb/source/Interpreter/Options.cpp @@ -647,12 +647,10 @@ bool Options::VerifyPartialOptions(CommandReturnObject &result) { 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 @@ bool Options::HandleOptionCompletion( 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 @@ bool Options::HandleOptionCompletion( 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 @@ bool Options::HandleOptionCompletion( 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 @@ bool Options::HandleOptionCompletion( 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 @@ bool Options::HandleOptionCompletion( // 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::HandleOptionCompletion( } 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 @@ bool Options::HandleOptionArgumentCompletion( 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 @@ bool Options::HandleOptionArgumentCompletion( // 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 @@ bool Options::HandleOptionArgumentCompletion( } 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) { diff --git a/lldb/source/Symbol/Variable.cpp b/lldb/source/Symbol/Variable.cpp index 4aa6a71..7eafef1 100644 --- a/lldb/source/Symbol/Variable.cpp +++ b/lldb/source/Symbol/Variable.cpp @@ -756,13 +756,13 @@ static void PrivateAutoComplete( } 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(); } diff --git a/lldb/source/Utility/ArchSpec.cpp b/lldb/source/Utility/ArchSpec.cpp index ac4330d..320f2d9 100644 --- a/lldb/source/Utility/ArchSpec.cpp +++ b/lldb/source/Utility/ArchSpec.cpp @@ -245,17 +245,22 @@ struct ArchDefinition { 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) diff --git a/lldb/source/Utility/CompletionRequest.cpp b/lldb/source/Utility/CompletionRequest.cpp index fbb0133..1b7697a 100644 --- a/lldb/source/Utility/CompletionRequest.cpp +++ b/lldb/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; + } + } +} diff --git a/lldb/unittests/Utility/CompletionRequestTest.cpp b/lldb/unittests/Utility/CompletionRequestTest.cpp index b5dff35..134bf51 100644 --- a/lldb/unittests/Utility/CompletionRequestTest.cpp +++ b/lldb/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 @@ TEST(CompletionRequest, Constructor) { 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); } -- 2.7.4