LLDB  mainline
CompletionRequest.h
Go to the documentation of this file.
1 //===-- CompletionRequest.h -------------------------------------*- C++ -*-===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 
9 #ifndef LLDB_UTILITY_COMPLETIONREQUEST_H
10 #define LLDB_UTILITY_COMPLETIONREQUEST_H
11 
12 #include "lldb/Utility/Args.h"
15 #include "llvm/ADT/StringRef.h"
16 #include "llvm/ADT/StringSet.h"
17 
18 namespace lldb_private {
19 enum class CompletionMode {
20  /// The current token has been completed. The client should indicate this
21  /// to the user (usually this is done by adding a trailing space behind the
22  /// token).
23  /// Example: "command sub" -> "command subcommand " (note the trailing space).
24  Normal,
25  /// The current token has been partially completed. This means that we found
26  /// a completion, but that the token is still incomplete. Examples
27  /// for this are file paths, where we want to complete "/bi" to "/bin/", but
28  /// the file path token is still incomplete after the completion. Clients
29  /// should not indicate to the user that this is a full completion (e.g. by
30  /// not inserting the usual trailing space after a successful completion).
31  /// Example: "file /us" -> "file /usr/" (note the missing trailing space).
32  Partial,
33  /// The full line has been rewritten by the completion.
34  /// Example: "alias name" -> "other_command full_name".
36 };
37 
39 public:
40  /// A single completion and all associated data.
41  class Completion {
42 
43  /// The actual text that should be completed. The meaning of this text
44  /// is defined by the CompletionMode.
45  /// \see m_mode
46  std::string m_completion;
47  /// The description that should be displayed to the user alongside the
48  /// completion text.
49  std::string m_descripton;
51 
52  public:
53  Completion(llvm::StringRef completion, llvm::StringRef description,
54  CompletionMode mode)
55  : m_completion(completion.str()), m_descripton(description.str()),
56  m_mode(mode) {}
57  const std::string &GetCompletion() const { return m_completion; }
58  const std::string &GetDescription() const { return m_descripton; }
59  CompletionMode GetMode() const { return m_mode; }
60 
61  /// Generates a string that uniquely identifies this completion result.
62  std::string GetUniqueKey() const;
63  };
64 
65 private:
66  /// List of found completions.
67  std::vector<Completion> m_results;
68 
69  /// A set of the unique keys of all found completions so far. Used to filter
70  /// out duplicates.
71  /// \see CompletionResult::Completion::GetUniqueKey
72  llvm::StringSet<> m_added_values;
73 
74 public:
75  void AddResult(llvm::StringRef completion, llvm::StringRef description,
76  CompletionMode mode);
77 
78  llvm::ArrayRef<Completion> GetResults() const { return m_results; }
79 
80  /// Adds all collected completion matches to the given list.
81  /// The list will be cleared before the results are added. The number of
82  /// results here is guaranteed to be equal to GetNumberOfResults().
83  void GetMatches(StringList &matches) const;
84 
85  /// Adds all collected completion descriptions to the given list.
86  /// The list will be cleared before the results are added. The number of
87  /// results here is guaranteed to be equal to GetNumberOfResults().
88  void GetDescriptions(StringList &descriptions) const;
89 
90  std::size_t GetNumberOfResults() const { return m_results.size(); }
91 };
92 
93 /// \class CompletionRequest CompletionRequest.h
94 /// "lldb/Utility/ArgCompletionRequest.h"
95 ///
96 /// Contains all information necessary to complete an incomplete command
97 /// for the user. Will be filled with the generated completions by the different
98 /// completions functions.
99 ///
101 public:
102  /// Constructs a completion request.
103  ///
104  /// \param [in] command_line
105  /// The command line the user has typed at this point.
106  ///
107  /// \param [in] raw_cursor_pos
108  /// The position of the cursor in the command line string. Index 0 means
109  /// the cursor is at the start of the line. The completion starts from
110  /// this cursor position.
111  ///
112  /// \param [out] result
113  /// The CompletionResult that will be filled with the results after this
114  /// request has been handled.
115  CompletionRequest(llvm::StringRef command_line, unsigned raw_cursor_pos,
116  CompletionResult &result);
117 
118  /// Returns the raw user input used to create this CompletionRequest cut off
119  /// at the cursor position. The cursor will be at the end of the raw line.
120  llvm::StringRef GetRawLine() const {
121  return m_command.substr(0, GetRawCursorPos());
122  }
123 
124  /// Returns the full raw user input used to create this CompletionRequest.
125  /// This string is not cut off at the cursor position and will include
126  /// characters behind the cursor position.
127  ///
128  /// You should most likely *not* use this function unless the characters
129  /// behind the cursor position influence the completion.
130  llvm::StringRef GetRawLineWithUnusedSuffix() const { return m_command; }
131 
132  unsigned GetRawCursorPos() const { return m_raw_cursor_pos; }
133 
134  const Args &GetParsedLine() const { return m_parsed_line; }
135 
136  Args &GetParsedLine() { return m_parsed_line; }
137 
139  return GetParsedLine()[GetCursorIndex()];
140  }
141 
142  /// Drops the first argument from the argument list.
143  void ShiftArguments() {
144  m_cursor_index--;
145  m_parsed_line.Shift();
146  }
147 
148  /// Adds an empty argument at the end of the argument list and moves
149  /// the cursor to this new argument.
151  m_parsed_line.AppendArgument(llvm::StringRef());
152  m_cursor_index++;
153  m_cursor_char_position = 0;
154  }
155 
156  size_t GetCursorIndex() const { return m_cursor_index; }
157 
158  /// Adds a possible completion string. If the completion was already
159  /// suggested before, it will not be added to the list of results. A copy of
160  /// the suggested completion is stored, so the given string can be free'd
161  /// afterwards.
162  ///
163  /// \param completion The suggested completion.
164  /// \param description An optional description of the completion string. The
165  /// description will be displayed to the user alongside the completion.
166  /// \param mode The CompletionMode for this completion.
167  void AddCompletion(llvm::StringRef completion,
168  llvm::StringRef description = "",
170  m_result.AddResult(completion, description, mode);
171  }
172 
173  /// Adds a possible completion string if the completion would complete the
174  /// current argument.
175  ///
176  /// \param completion The suggested completion.
177  /// \param description An optional description of the completion string. The
178  /// description will be displayed to the user alongside the completion.
179  template <CompletionMode M = CompletionMode::Normal>
180  void TryCompleteCurrentArg(llvm::StringRef completion,
181  llvm::StringRef description = "") {
182  // Trying to rewrite the whole line while checking for the current
183  // argument never makes sense. Completion modes are always hardcoded, so
184  // this can be a static_assert.
185  static_assert(M != CompletionMode::RewriteLine,
186  "Shouldn't rewrite line with this function");
187  if (completion.startswith(GetCursorArgumentPrefix()))
188  AddCompletion(completion, description, M);
189  }
190 
191  /// Adds multiple possible completion strings.
192  ///
193  /// \param completions The list of completions.
194  ///
195  /// \see AddCompletion
196  void AddCompletions(const StringList &completions) {
197  for (const std::string &completion : completions)
198  AddCompletion(completion);
199  }
200 
201  /// Adds multiple possible completion strings alongside their descriptions.
202  ///
203  /// The number of completions and descriptions must be identical.
204  ///
205  /// \param completions The list of completions.
206  /// \param descriptions The list of descriptions.
207  ///
208  /// \see AddCompletion
209  void AddCompletions(const StringList &completions,
210  const StringList &descriptions) {
211  lldbassert(completions.GetSize() == descriptions.GetSize());
212  for (std::size_t i = 0; i < completions.GetSize(); ++i)
213  AddCompletion(completions.GetStringAtIndex(i),
214  descriptions.GetStringAtIndex(i));
215  }
216 
217  llvm::StringRef GetCursorArgumentPrefix() const {
218  return GetParsedLine().GetArgumentAtIndex(GetCursorIndex());
219  }
220 
221 private:
222  /// The raw command line we are supposed to complete.
223  llvm::StringRef m_command;
224  /// The cursor position in m_command.
226  /// The command line parsed as arguments.
228  /// The index of the argument in which the completion cursor is.
230  /// The cursor position in the argument indexed by m_cursor_index.
232 
233  /// The result this request is supposed to fill out.
234  /// We keep this object private to ensure that no backend can in any way
235  /// depend on already calculated completions (which would make debugging and
236  /// testing them much more complicated).
238 };
239 
240 } // namespace lldb_private
241 
242 #endif // LLDB_UTILITY_COMPLETIONREQUEST_H
unsigned m_raw_cursor_pos
The cursor position in m_command.
llvm::StringRef GetRawLine() const
Returns the raw user input used to create this CompletionRequest cut off at the cursor position...
A command line argument class.
Definition: Args.h:33
Completion(llvm::StringRef completion, llvm::StringRef description, CompletionMode mode)
A class that represents a running process on the host machine.
llvm::StringSet m_added_values
A set of the unique keys of all found completions so far.
void ShiftArguments()
Drops the first argument from the argument list.
#define lldbassert(x)
Definition: LLDBAssert.h:15
void AppendEmptyArgument()
Adds an empty argument at the end of the argument list and moves the cursor to this new argument...
std::size_t GetNumberOfResults() const
const Args::ArgEntry & GetParsedArg()
llvm::StringRef m_command
The raw command line we are supposed to complete.
void AddCompletion(llvm::StringRef completion, llvm::StringRef description="", CompletionMode mode=CompletionMode::Normal)
Adds a possible completion string.
size_t m_cursor_index
The index of the argument in which the completion cursor is.
CompletionResult & m_result
The result this request is supposed to fill out.
void AddCompletions(const StringList &completions)
Adds multiple possible completion strings.
std::string m_completion
The actual text that should be completed.
llvm::StringRef GetRawLineWithUnusedSuffix() const
Returns the full raw user input used to create this CompletionRequest.
"lldb/Utility/ArgCompletionRequest.h"
llvm::ArrayRef< Completion > GetResults() const
llvm::StringRef GetCursorArgumentPrefix() const
void AddCompletions(const StringList &completions, const StringList &descriptions)
Adds multiple possible completion strings alongside their descriptions.
const char * GetStringAtIndex(size_t idx) const
Definition: StringList.cpp:80
std::string m_descripton
The description that should be displayed to the user alongside the completion text.
The current token has been partially completed.
size_t GetSize() const
Definition: StringList.cpp:68
Args m_parsed_line
The command line parsed as arguments.
size_t m_cursor_char_position
The cursor position in the argument indexed by m_cursor_index.
std::vector< Completion > m_results
List of found completions.
The full line has been rewritten by the completion.
const std::string & GetCompletion() const
const std::string & GetDescription() const
void TryCompleteCurrentArg(llvm::StringRef completion, llvm::StringRef description="")
Adds a possible completion string if the completion would complete the current argument.
The current token has been completed.
const Args & GetParsedLine() const
A single completion and all associated data.