diff options
Diffstat (limited to 'include/lldb/Utility/CompletionRequest.h')
-rw-r--r-- | include/lldb/Utility/CompletionRequest.h | 128 |
1 files changed, 76 insertions, 52 deletions
diff --git a/include/lldb/Utility/CompletionRequest.h b/include/lldb/Utility/CompletionRequest.h index f5ccb01ca16f9..570f626ac54e8 100644 --- a/include/lldb/Utility/CompletionRequest.h +++ b/include/lldb/Utility/CompletionRequest.h @@ -16,25 +16,53 @@ #include "llvm/ADT/StringSet.h" namespace lldb_private { +enum class CompletionMode { + // The current token has been completed. + Normal, + // The current token has been partially completed. This means that we found + // a completion, but that the completed token is still incomplete. Examples + // for this are file paths, where we want to complete "/bi" to "/bin/", but + // the file path token is still incomplete after the completion. Clients + // should not indicate to the user that this is a full completion (e.g. by + // not inserting the usual trailing space after a successful completion). + Partial, + // The full line has been rewritten by the completion. + RewriteLine, +}; + class CompletionResult { +public: /// A single completion and all associated data. - struct Completion { - Completion(llvm::StringRef completion, llvm::StringRef description) - : m_completion(completion.str()), m_descripton(description.str()) {} + class Completion { std::string m_completion; std::string m_descripton; + CompletionMode m_mode; + + public: + Completion(llvm::StringRef completion, llvm::StringRef description, + CompletionMode mode) + : m_completion(completion.str()), m_descripton(description.str()), + m_mode(mode) {} + const std::string &GetCompletion() const { return m_completion; } + const std::string &GetDescription() const { return m_descripton; } + CompletionMode GetMode() const { return m_mode; } /// Generates a string that uniquely identifies this completion result. std::string GetUniqueKey() const; }; + +private: std::vector<Completion> m_results; /// List of added completions so far. Used to filter out duplicates. llvm::StringSet<> m_added_values; public: - void AddResult(llvm::StringRef completion, llvm::StringRef description); + void AddResult(llvm::StringRef completion, llvm::StringRef description, + CompletionMode mode); + + llvm::ArrayRef<Completion> GetResults() const { return m_results; } /// Adds all collected completion matches to the given list. /// The list will be cleared before the results are added. The number of @@ -68,18 +96,10 @@ public: /// 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] result /// The CompletionResult that will be filled with the results after this /// request has been handled. CompletionRequest(llvm::StringRef command_line, unsigned raw_cursor_pos, - int match_start_point, int max_return_elements, CompletionResult &result); llvm::StringRef GetRawLine() const { return m_command; } @@ -90,21 +110,25 @@ public: 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; } - - void SetCursorCharPosition(int pos) { m_cursor_char_position = pos; } - int GetCursorCharPosition() const { return m_cursor_char_position; } - - int GetMatchStartPoint() const { return m_match_start_point; } + const Args::ArgEntry &GetParsedArg() { + return GetParsedLine()[GetCursorIndex()]; + } - int GetMaxReturnElements() const { return m_max_return_elements; } + /// Drops the first argument from the argument list. + void ShiftArguments() { + m_cursor_index--; + m_parsed_line.Shift(); + } - bool GetWordComplete() { return m_word_complete; } + /// Adds an empty argument at the end of the argument list and moves + /// the cursor to this new argument. + void AppendEmptyArgument() { + m_parsed_line.AppendArgument(llvm::StringRef()); + m_cursor_index++; + m_cursor_char_position = 0; + } - void SetWordComplete(bool v) { m_word_complete = v; } + size_t GetCursorIndex() const { return m_cursor_index; } /// Adds a possible completion string. If the completion was already /// suggested before, it will not be added to the list of results. A copy of @@ -112,11 +136,31 @@ public: /// afterwards. /// /// \param match The suggested completion. - /// \param match An optional description of the completion string. The + /// \param completion An optional description of the completion string. The /// description will be displayed to the user alongside the completion. + /// \param mode The CompletionMode for this completion. void AddCompletion(llvm::StringRef completion, - llvm::StringRef description = "") { - m_result.AddResult(completion, description); + llvm::StringRef description = "", + CompletionMode mode = CompletionMode::Normal) { + m_result.AddResult(completion, description, mode); + } + + /// Adds a possible completion string if the completion would complete the + /// current argument. + /// + /// \param match The suggested completion. + /// \param description An optional description of the completion string. The + /// description will be displayed to the user alongside the completion. + template <CompletionMode M = CompletionMode::Normal> + void TryCompleteCurrentArg(llvm::StringRef completion, + llvm::StringRef description = "") { + // Trying to rewrite the whole line while checking for the current + // argument never makes sense. Completion modes are always hardcoded, so + // this can be a static_assert. + static_assert(M != CompletionMode::RewriteLine, + "Shouldn't rewrite line with this function"); + if (completion.startswith(GetCursorArgumentPrefix())) + AddCompletion(completion, description, M); } /// Adds multiple possible completion strings. @@ -125,8 +169,8 @@ public: /// /// \see AddCompletion void AddCompletions(const StringList &completions) { - for (std::size_t i = 0; i < completions.GetSize(); ++i) - AddCompletion(completions.GetStringAtIndex(i)); + for (const std::string &completion : completions) + AddCompletion(completion); } /// Adds multiple possible completion strings alongside their descriptions. @@ -145,16 +189,8 @@ public: descriptions.GetStringAtIndex(i)); } - std::size_t GetNumberOfMatches() const { - return m_result.GetNumberOfResults(); - } - - llvm::StringRef GetCursorArgument() const { - return GetParsedLine().GetArgumentAtIndex(GetCursorIndex()); - } - llvm::StringRef GetCursorArgumentPrefix() const { - return GetCursorArgument().substr(0, GetCursorCharPosition()); + return GetParsedLine().GetArgumentAtIndex(GetCursorIndex()); } private: @@ -164,22 +200,10 @@ 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; + size_t m_cursor_index; /// The cursor position in the argument indexed by m_cursor_index. - int m_cursor_char_position; - /// 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 \amatch_start_point, and return - /// \amatch_return_elements elements. - // FIXME: These two values are not implemented. - int m_match_start_point; - 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 = false; + size_t m_cursor_char_position; /// The result this request is supposed to fill out. /// We keep this object private to ensure that no backend can in any way |