CompletionRequest.h revision 360784
140090Smsmith//===-- CompletionRequest.h -------------------------------------*- C++ -*-===//
240090Smsmith//
340090Smsmith// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
440090Smsmith// See https://llvm.org/LICENSE.txt for license information.
540090Smsmith// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
640090Smsmith//
740090Smsmith//===----------------------------------------------------------------------===//
840090Smsmith
940090Smsmith#ifndef LLDB_UTILITY_COMPLETIONREQUEST_H
1040090Smsmith#define LLDB_UTILITY_COMPLETIONREQUEST_H
1140090Smsmith
1240090Smsmith#include "lldb/Utility/Args.h"
1340090Smsmith#include "lldb/Utility/LLDBAssert.h"
1440090Smsmith#include "lldb/Utility/StringList.h"
1540090Smsmith#include "llvm/ADT/StringRef.h"
1640090Smsmith#include "llvm/ADT/StringSet.h"
1740090Smsmith
1840090Smsmithnamespace lldb_private {
1940090Smsmithenum class CompletionMode {
2040090Smsmith  // The current token has been completed.
2140090Smsmith  Normal,
2240090Smsmith  // The current token has been partially completed. This means that we found
2340090Smsmith  // a completion, but that the completed token is still incomplete. Examples
2440090Smsmith  // for this are file paths, where we want to complete "/bi" to "/bin/", but
2540116Sjkh  // the file path token is still incomplete after the completion. Clients
2640090Smsmith  // should not indicate to the user that this is a full completion (e.g. by
2740090Smsmith  // not inserting the usual trailing space after a successful completion).
2840090Smsmith  Partial,
2994936Smux  // The full line has been rewritten by the completion.
3094936Smux  RewriteLine,
3140090Smsmith};
3294936Smux
3394936Smuxclass CompletionResult {
3494936Smuxpublic:
3540090Smsmith  /// A single completion and all associated data.
3640090Smsmith  class Completion {
37116182Sobrien
38116182Sobrien    std::string m_completion;
39116182Sobrien    std::string m_descripton;
4094936Smux    CompletionMode m_mode;
4140090Smsmith
4294936Smux  public:
4394936Smux    Completion(llvm::StringRef completion, llvm::StringRef description,
4494936Smux               CompletionMode mode)
4594936Smux        : m_completion(completion.str()), m_descripton(description.str()),
4694936Smux          m_mode(mode) {}
47164033Srwatson    const std::string &GetCompletion() const { return m_completion; }
4840090Smsmith    const std::string &GetDescription() const { return m_descripton; }
4940090Smsmith    CompletionMode GetMode() const { return m_mode; }
5094936Smux
5194936Smux    /// Generates a string that uniquely identifies this completion result.
5240090Smsmith    std::string GetUniqueKey() const;
5394936Smux  };
5440090Smsmith
55163606Srwatsonprivate:
56163606Srwatson  std::vector<Completion> m_results;
57141616Sphk
5840090Smsmith  /// List of added completions so far. Used to filter out duplicates.
5994936Smux  llvm::StringSet<> m_added_values;
6040090Smsmith
6194936Smuxpublic:
6294936Smux  void AddResult(llvm::StringRef completion, llvm::StringRef description,
63202050Simp                 CompletionMode mode);
64202050Simp
6594936Smux  llvm::ArrayRef<Completion> GetResults() const { return m_results; }
6694936Smux
6794936Smux  /// Adds all collected completion matches to the given list.
6894936Smux  /// The list will be cleared before the results are added. The number of
69160217Sscottl  /// results here is guaranteed to be equal to GetNumberOfResults().
7094936Smux  void GetMatches(StringList &matches) const;
7185385Sjhb
72167232Srwatson  /// Adds all collected completion descriptions to the given list.
7394936Smux  /// The list will be cleared before the results are added. The number of
7494936Smux  /// results here is guaranteed to be equal to GetNumberOfResults().
7594936Smux  void GetDescriptions(StringList &descriptions) const;
7694936Smux
7794936Smux  std::size_t GetNumberOfResults() const { return m_results.size(); }
7894936Smux};
7994936Smux
8094936Smux/// \class CompletionRequest CompletionRequest.h
8194936Smux///   "lldb/Utility/ArgCompletionRequest.h"
8294936Smux///
83107850Salfred/// Contains all information necessary to complete an incomplete command
84107850Salfred/// for the user. Will be filled with the generated completions by the different
85107850Salfred/// completions functions.
86107850Salfred///
8794936Smuxclass CompletionRequest {
8894936Smuxpublic:
89160217Sscottl  /// Constructs a completion request.
90190301Scperciva  ///
9194936Smux  /// \param [in] command_line
9295839Speter  ///     The command line the user has typed at this point.
9394936Smux  ///
9494936Smux  /// \param [in] raw_cursor_pos
9594936Smux  ///     The position of the cursor in the command line string. Index 0 means
96107849Salfred  ///     the cursor is at the start of the line. The completion starts from
97106308Srwatson  ///     this cursor position.
98172930Srwatson  ///
99106308Srwatson  /// \param [out] result
100106308Srwatson  ///     The CompletionResult that will be filled with the results after this
101106308Srwatson  ///     request has been handled.
102128697Sdas  CompletionRequest(llvm::StringRef command_line, unsigned raw_cursor_pos,
103190301Scperciva                    CompletionResult &result);
104190301Scperciva
105190301Scperciva  llvm::StringRef GetRawLine() const { return m_command; }
106190301Scperciva
107160217Sscottl  unsigned GetRawCursorPos() const { return m_raw_cursor_pos; }
108190301Scperciva
109160217Sscottl  const Args &GetParsedLine() const { return m_parsed_line; }
110128697Sdas
111128697Sdas  Args &GetParsedLine() { return m_parsed_line; }
112128697Sdas
113190301Scperciva  const Args::ArgEntry &GetParsedArg() {
114128697Sdas    return GetParsedLine()[GetCursorIndex()];
115128697Sdas  }
116128697Sdas
117128697Sdas  /// Drops the first argument from the argument list.
118160217Sscottl  void ShiftArguments() {
119160217Sscottl    m_cursor_index--;
120128697Sdas    m_parsed_line.Shift();
12194936Smux  }
12294936Smux
123160217Sscottl  /// Adds an empty argument at the end of the argument list and moves
124160217Sscottl  /// the cursor to this new argument.
125160217Sscottl  void AppendEmptyArgument() {
126160217Sscottl    m_parsed_line.AppendArgument(llvm::StringRef());
127160217Sscottl    m_cursor_index++;
128128697Sdas    m_cursor_char_position = 0;
129128697Sdas  }
13094936Smux
13194936Smux  size_t GetCursorIndex() const { return m_cursor_index; }
132164033Srwatson
133164033Srwatson  /// Adds a possible completion string. If the completion was already
134164033Srwatson  /// suggested before, it will not be added to the list of results. A copy of
13594936Smux  /// the suggested completion is stored, so the given string can be free'd
13694936Smux  /// afterwards.
137164033Srwatson  ///
138164033Srwatson  /// \param match The suggested completion.
139164033Srwatson  /// \param completion An optional description of the completion string. The
140164033Srwatson  ///     description will be displayed to the user alongside the completion.
141164033Srwatson  /// \param mode The CompletionMode for this completion.
142164033Srwatson  void AddCompletion(llvm::StringRef completion,
143164033Srwatson                     llvm::StringRef description = "",
14494936Smux                     CompletionMode mode = CompletionMode::Normal) {
14594936Smux    m_result.AddResult(completion, description, mode);
146111119Simp  }
14794936Smux
148107849Salfred  /// Adds a possible completion string if the completion would complete the
14994936Smux  /// current argument.
15094936Smux  ///
15194936Smux  /// \param match The suggested completion.
152107849Salfred  /// \param description An optional description of the completion string. The
15394936Smux  ///     description will be displayed to the user alongside the completion.
154106308Srwatson  template <CompletionMode M = CompletionMode::Normal>
155172930Srwatson  void TryCompleteCurrentArg(llvm::StringRef completion,
156106308Srwatson                             llvm::StringRef description = "") {
157106308Srwatson    // Trying to rewrite the whole line while checking for the current
158106308Srwatson    // argument never makes sense. Completion modes are always hardcoded, so
15994936Smux    // this can be a static_assert.
16094936Smux    static_assert(M != CompletionMode::RewriteLine,
16194936Smux                  "Shouldn't rewrite line with this function");
16294936Smux    if (completion.startswith(GetCursorArgumentPrefix()))
16394936Smux      AddCompletion(completion, description, M);
16494936Smux  }
165107849Salfred
166107849Salfred  /// Adds multiple possible completion strings.
167107849Salfred  ///
16894936Smux  /// \param completions The list of completions.
16994936Smux  ///
17094936Smux  /// \see AddCompletion
17194936Smux  void AddCompletions(const StringList &completions) {
17294936Smux    for (const std::string &completion : completions)
17394936Smux      AddCompletion(completion);
174107849Salfred  }
17594936Smux
17694936Smux  /// Adds multiple possible completion strings alongside their descriptions.
17794936Smux  ///
17894936Smux  /// The number of completions and descriptions must be identical.
17994936Smux  ///
18094936Smux  /// \param completions The list of completions.
181111119Simp  /// \param completions The list of descriptions.
182107849Salfred  ///
18394936Smux  /// \see AddCompletion
18494936Smux  void AddCompletions(const StringList &completions,
18594936Smux                      const StringList &descriptions) {
18694936Smux    lldbassert(completions.GetSize() == descriptions.GetSize());
187106308Srwatson    for (std::size_t i = 0; i < completions.GetSize(); ++i)
188172930Srwatson      AddCompletion(completions.GetStringAtIndex(i),
189106308Srwatson                    descriptions.GetStringAtIndex(i));
190106308Srwatson  }
191106308Srwatson
19294936Smux  llvm::StringRef GetCursorArgumentPrefix() const {
19394936Smux    return GetParsedLine().GetArgumentAtIndex(GetCursorIndex());
19494936Smux  }
195106308Srwatson
196172930Srwatsonprivate:
197106308Srwatson  /// The raw command line we are supposed to complete.
198106308Srwatson  llvm::StringRef m_command;
199106308Srwatson  /// The cursor position in m_command.
20094936Smux  unsigned m_raw_cursor_pos;
20194936Smux  /// The command line parsed as arguments.
20294936Smux  Args m_parsed_line;
20394936Smux  /// The index of the argument in which the completion cursor is.
20494936Smux  size_t m_cursor_index;
20594936Smux  /// The cursor position in the argument indexed by m_cursor_index.
20694936Smux  size_t m_cursor_char_position;
20794936Smux
20894936Smux  /// The result this request is supposed to fill out.
20994936Smux  /// We keep this object private to ensure that no backend can in any way
21094936Smux  /// depend on already calculated completions (which would make debugging and
21194936Smux  /// testing them much more complicated).
21294936Smux  CompletionResult &m_result;
213202050Simp};
214202050Simp
215202050Simp} // namespace lldb_private
216202050Simp
217202050Simp#endif // LLDB_UTILITY_COMPLETIONREQUEST_H
218202050Simp