| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242 |
- //===-- CompletionRequest.h -------------------------------------*- C++ -*-===//
- //
- // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
- // See https://llvm.org/LICENSE.txt for license information.
- // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
- //
- //===----------------------------------------------------------------------===//
- #ifndef LLDB_UTILITY_COMPLETIONREQUEST_H
- #define LLDB_UTILITY_COMPLETIONREQUEST_H
- #include "lldb/Utility/Args.h"
- #include "lldb/Utility/LLDBAssert.h"
- #include "lldb/Utility/StringList.h"
- #include "llvm/ADT/StringRef.h"
- #include "llvm/ADT/StringSet.h"
- namespace lldb_private {
- enum class CompletionMode {
- /// The current token has been completed. The client should indicate this
- /// to the user (usually this is done by adding a trailing space behind the
- /// token).
- /// Example: "command sub" -> "command subcommand " (note the trailing space).
- Normal,
- /// The current token has been partially completed. This means that we found
- /// a completion, but that the 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).
- /// Example: "file /us" -> "file /usr/" (note the missing trailing space).
- Partial,
- /// The full line has been rewritten by the completion.
- /// Example: "alias name" -> "other_command full_name".
- RewriteLine,
- };
- class CompletionResult {
- public:
- /// A single completion and all associated data.
- class Completion {
- /// The actual text that should be completed. The meaning of this text
- /// is defined by the CompletionMode.
- /// \see m_mode
- std::string m_completion;
- /// The description that should be displayed to the user alongside the
- /// completion text.
- 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:
- /// List of found completions.
- std::vector<Completion> m_results;
- /// A set of the unique keys of all found completions so far. Used to filter
- /// out duplicates.
- /// \see CompletionResult::Completion::GetUniqueKey
- llvm::StringSet<> m_added_values;
- public:
- 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
- /// results here is guaranteed to be equal to GetNumberOfResults().
- void GetMatches(StringList &matches) const;
- /// Adds all collected completion descriptions to the given list.
- /// The list will be cleared before the results are added. The number of
- /// results here is guaranteed to be equal to GetNumberOfResults().
- void GetDescriptions(StringList &descriptions) const;
- std::size_t GetNumberOfResults() const { return m_results.size(); }
- };
- /// \class CompletionRequest CompletionRequest.h
- /// "lldb/Utility/ArgCompletionRequest.h"
- ///
- /// Contains all information necessary to complete an incomplete command
- /// for the user. Will be filled with the generated completions by the different
- /// completions functions.
- ///
- class CompletionRequest {
- public:
- /// Constructs a completion request.
- ///
- /// \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 [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,
- CompletionResult &result);
- /// Returns the raw user input used to create this CompletionRequest cut off
- /// at the cursor position. The cursor will be at the end of the raw line.
- llvm::StringRef GetRawLine() const {
- return m_command.substr(0, GetRawCursorPos());
- }
- /// Returns the full raw user input used to create this CompletionRequest.
- /// This string is not cut off at the cursor position and will include
- /// characters behind the cursor position.
- ///
- /// You should most likely *not* use this function unless the characters
- /// behind the cursor position influence the completion.
- llvm::StringRef GetRawLineWithUnusedSuffix() 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::ArgEntry &GetParsedArg() {
- return GetParsedLine()[GetCursorIndex()];
- }
- /// Drops the first argument from the argument list.
- void ShiftArguments() {
- m_cursor_index--;
- m_parsed_line.Shift();
- }
- /// 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;
- }
- 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
- /// the suggested completion is stored, so the given string can be free'd
- /// afterwards.
- ///
- /// \param completion The suggested completion.
- /// \param description 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 = "",
- CompletionMode mode = CompletionMode::Normal) {
- m_result.AddResult(completion, description, mode);
- }
- /// Adds a possible completion string if the completion would complete the
- /// current argument.
- ///
- /// \param completion 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.
- ///
- /// \param completions The list of completions.
- ///
- /// \see AddCompletion
- void AddCompletions(const StringList &completions) {
- for (const std::string &completion : completions)
- AddCompletion(completion);
- }
- /// Adds multiple possible completion strings alongside their descriptions.
- ///
- /// The number of completions and descriptions must be identical.
- ///
- /// \param completions The list of completions.
- /// \param descriptions The list of descriptions.
- ///
- /// \see AddCompletion
- void AddCompletions(const StringList &completions,
- const StringList &descriptions) {
- lldbassert(completions.GetSize() == descriptions.GetSize());
- for (std::size_t i = 0; i < completions.GetSize(); ++i)
- AddCompletion(completions.GetStringAtIndex(i),
- descriptions.GetStringAtIndex(i));
- }
- llvm::StringRef GetCursorArgumentPrefix() const {
- return GetParsedLine().GetArgumentAtIndex(GetCursorIndex());
- }
- private:
- /// The raw command line we are supposed to complete.
- llvm::StringRef m_command;
- /// The cursor position in m_command.
- unsigned m_raw_cursor_pos;
- /// The command line parsed as arguments.
- Args m_parsed_line;
- /// The index of the argument in which the completion cursor is.
- size_t m_cursor_index;
- /// The cursor position in the argument indexed by m_cursor_index.
- 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
- /// depend on already calculated completions (which would make debugging and
- /// testing them much more complicated).
- CompletionResult &m_result;
- };
- } // namespace lldb_private
- #endif // LLDB_UTILITY_COMPLETIONREQUEST_H
|