/Users/buildslave/jenkins/workspace/coverage/llvm-project/lldb/include/lldb/Utility/CompletionRequest.h
Line | Count | Source |
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" |
13 | | #include "lldb/Utility/LLDBAssert.h" |
14 | | #include "lldb/Utility/StringList.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". |
35 | | RewriteLine, |
36 | | }; |
37 | | |
38 | | class CompletionResult { |
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; |
50 | | CompletionMode m_mode; |
51 | | |
52 | | public: |
53 | | Completion(llvm::StringRef completion, llvm::StringRef description, |
54 | | CompletionMode mode) |
55 | 3.42k | : m_completion(completion.str()), m_descripton(description.str()), |
56 | 3.42k | m_mode(mode) {} |
57 | 3.26k | const std::string &GetCompletion() const { return m_completion; } |
58 | 3.20k | const std::string &GetDescription() const { return m_descripton; } |
59 | 459 | 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 | 4 | 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 | 339 | 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 | | /// |
100 | | class CompletionRequest { |
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 | 4 | llvm::StringRef GetRawLine() const { |
121 | 4 | return m_command.substr(0, GetRawCursorPos()); |
122 | 4 | } |
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 | 59 | llvm::StringRef GetRawLineWithUnusedSuffix() const { return m_command; } |
131 | | |
132 | 63 | unsigned GetRawCursorPos() const { return m_raw_cursor_pos; } |
133 | | |
134 | 6.35k | const Args &GetParsedLine() const { return m_parsed_line; } |
135 | | |
136 | 3.15k | Args &GetParsedLine() { return m_parsed_line; } |
137 | | |
138 | 306 | const Args::ArgEntry &GetParsedArg() { |
139 | 306 | return GetParsedLine()[GetCursorIndex()]; |
140 | 306 | } |
141 | | |
142 | | /// Drops the first argument from the argument list. |
143 | 587 | void ShiftArguments() { |
144 | 587 | m_cursor_index--; |
145 | 587 | m_parsed_line.Shift(); |
146 | 587 | } |
147 | | |
148 | | /// Adds an empty argument at the end of the argument list and moves |
149 | | /// the cursor to this new argument. |
150 | 152 | void AppendEmptyArgument() { |
151 | 152 | m_parsed_line.AppendArgument(llvm::StringRef()); |
152 | 152 | m_cursor_index++; |
153 | 152 | m_cursor_char_position = 0; |
154 | 152 | } |
155 | | |
156 | 7.93k | 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 = "", |
169 | 2.96k | CompletionMode mode = CompletionMode::Normal) { |
170 | 2.96k | m_result.AddResult(completion, description, mode); |
171 | 2.96k | } |
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 | 5.65k | 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 | 5.65k | static_assert(M != CompletionMode::RewriteLine, |
186 | 5.65k | "Shouldn't rewrite line with this function"); |
187 | 5.65k | if (completion.startswith(GetCursorArgumentPrefix())) |
188 | 2.12k | AddCompletion(completion, description, M); |
189 | 5.65k | } |
190 | | |
191 | | /// Adds multiple possible completion strings. |
192 | | /// |
193 | | /// \param completions The list of completions. |
194 | | /// |
195 | | /// \see AddCompletion |
196 | 288 | void AddCompletions(const StringList &completions) { |
197 | 288 | for (const std::string &completion : completions) |
198 | 1 | AddCompletion(completion); |
199 | 288 | } |
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 | 26 | const StringList &descriptions) { |
211 | 26 | lldbassert(completions.GetSize() == descriptions.GetSize()); |
212 | 162 | for (std::size_t i = 0; 26 i < completions.GetSize(); ++i136 ) |
213 | 136 | AddCompletion(completions.GetStringAtIndex(i), |
214 | 136 | descriptions.GetStringAtIndex(i)); |
215 | 26 | } |
216 | | |
217 | 6.35k | llvm::StringRef GetCursorArgumentPrefix() const { |
218 | 6.35k | return GetParsedLine().GetArgumentAtIndex(GetCursorIndex()); |
219 | 6.35k | } |
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. |
225 | | unsigned m_raw_cursor_pos; |
226 | | /// The command line parsed as arguments. |
227 | | Args m_parsed_line; |
228 | | /// The index of the argument in which the completion cursor is. |
229 | | size_t m_cursor_index; |
230 | | /// The cursor position in the argument indexed by m_cursor_index. |
231 | | size_t m_cursor_char_position; |
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). |
237 | | CompletionResult &m_result; |
238 | | }; |
239 | | |
240 | | } // namespace lldb_private |
241 | | |
242 | | #endif // LLDB_UTILITY_COMPLETIONREQUEST_H |