Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2026-05-10 08:42:57

0001 //===-- CompletionRequest.h -------------------------------------*- C++ -*-===//
0002 //
0003 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
0004 // See https://llvm.org/LICENSE.txt for license information.
0005 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
0006 //
0007 //===----------------------------------------------------------------------===//
0008 
0009 #ifndef LLDB_UTILITY_COMPLETIONREQUEST_H
0010 #define LLDB_UTILITY_COMPLETIONREQUEST_H
0011 
0012 #include "lldb/Utility/Args.h"
0013 #include "lldb/Utility/LLDBAssert.h"
0014 #include "lldb/Utility/StringList.h"
0015 #include "llvm/ADT/StringRef.h"
0016 #include "llvm/ADT/StringSet.h"
0017 
0018 namespace lldb_private {
0019 enum class CompletionMode {
0020   /// The current token has been completed. The client should indicate this
0021   /// to the user (usually this is done by adding a trailing space behind the
0022   /// token).
0023   /// Example: "command sub" -> "command subcommand " (note the trailing space).
0024   Normal,
0025   /// The current token has been partially completed. This means that we found
0026   /// a completion, but that the token is still incomplete. Examples
0027   /// for this are file paths, where we want to complete "/bi" to "/bin/", but
0028   /// the file path token is still incomplete after the completion. Clients
0029   /// should not indicate to the user that this is a full completion (e.g. by
0030   /// not inserting the usual trailing space after a successful completion).
0031   /// Example: "file /us" -> "file /usr/" (note the missing trailing space).
0032   Partial,
0033   /// The full line has been rewritten by the completion.
0034   /// Example: "alias name" -> "other_command full_name".
0035   RewriteLine,
0036 };
0037 
0038 class CompletionResult {
0039 public:
0040   /// A single completion and all associated data.
0041   class Completion {
0042 
0043     /// The actual text that should be completed. The meaning of this text
0044     /// is defined by the CompletionMode.
0045     /// \see m_mode
0046     std::string m_completion;
0047     /// The description that should be displayed to the user alongside the
0048     /// completion text.
0049     std::string m_descripton;
0050     CompletionMode m_mode;
0051 
0052   public:
0053     Completion(llvm::StringRef completion, llvm::StringRef description,
0054                CompletionMode mode)
0055         : m_completion(completion.rtrim().str()),
0056           m_descripton(description.rtrim().str()), m_mode(mode) {}
0057     const std::string &GetCompletion() const { return m_completion; }
0058     const std::string &GetDescription() const { return m_descripton; }
0059     CompletionMode GetMode() const { return m_mode; }
0060 
0061     /// Generates a string that uniquely identifies this completion result.
0062     std::string GetUniqueKey() const;
0063   };
0064 
0065 private:
0066   /// List of found completions.
0067   std::vector<Completion> m_results;
0068 
0069   /// A set of the unique keys of all found completions so far. Used to filter
0070   /// out duplicates.
0071   /// \see CompletionResult::Completion::GetUniqueKey
0072   llvm::StringSet<> m_added_values;
0073 
0074 public:
0075   void AddResult(llvm::StringRef completion, llvm::StringRef description,
0076                  CompletionMode mode);
0077 
0078   llvm::ArrayRef<Completion> GetResults() const { return m_results; }
0079 
0080   /// Adds all collected completion matches to the given list.
0081   /// The list will be cleared before the results are added. The number of
0082   /// results here is guaranteed to be equal to GetNumberOfResults().
0083   void GetMatches(StringList &matches) const;
0084 
0085   /// Adds all collected completion descriptions to the given list.
0086   /// The list will be cleared before the results are added. The number of
0087   /// results here is guaranteed to be equal to GetNumberOfResults().
0088   void GetDescriptions(StringList &descriptions) const;
0089 
0090   std::size_t GetNumberOfResults() const { return m_results.size(); }
0091 };
0092 
0093 /// \class CompletionRequest CompletionRequest.h
0094 ///   "lldb/Utility/ArgCompletionRequest.h"
0095 ///
0096 /// Contains all information necessary to complete an incomplete command
0097 /// for the user. Will be filled with the generated completions by the different
0098 /// completions functions.
0099 ///
0100 class CompletionRequest {
0101 public:
0102   /// Constructs a completion request.
0103   ///
0104   /// \param [in] command_line
0105   ///     The command line the user has typed at this point.
0106   ///
0107   /// \param [in] raw_cursor_pos
0108   ///     The position of the cursor in the command line string. Index 0 means
0109   ///     the cursor is at the start of the line. The completion starts from
0110   ///     this cursor position.
0111   ///
0112   /// \param [out] result
0113   ///     The CompletionResult that will be filled with the results after this
0114   ///     request has been handled.
0115   CompletionRequest(llvm::StringRef command_line, unsigned raw_cursor_pos,
0116                     CompletionResult &result);
0117 
0118   /// Returns the raw user input used to create this CompletionRequest cut off
0119   /// at the cursor position. The cursor will be at the end of the raw line.
0120   llvm::StringRef GetRawLine() const {
0121     return m_command.substr(0, GetRawCursorPos());
0122   }
0123 
0124   /// Returns the full raw user input used to create this CompletionRequest.
0125   /// This string is not cut off at the cursor position and will include
0126   /// characters behind the cursor position.
0127   ///
0128   /// You should most likely *not* use this function unless the characters
0129   /// behind the cursor position influence the completion.
0130   llvm::StringRef GetRawLineWithUnusedSuffix() const { return m_command; }
0131 
0132   unsigned GetRawCursorPos() const { return m_raw_cursor_pos; }
0133 
0134   const Args &GetParsedLine() const { return m_parsed_line; }
0135 
0136   Args &GetParsedLine() { return m_parsed_line; }
0137 
0138   const Args::ArgEntry &GetParsedArg() {
0139     return GetParsedLine()[GetCursorIndex()];
0140   }
0141 
0142   size_t GetCursorCharPos() const { return m_cursor_char_position; }
0143 
0144   /// Drops the first argument from the argument list.
0145   void ShiftArguments() {
0146     m_cursor_index--;
0147     m_parsed_line.Shift();
0148   }
0149 
0150   /// Adds an empty argument at the end of the argument list and moves
0151   /// the cursor to this new argument.
0152   void AppendEmptyArgument() {
0153     m_parsed_line.AppendArgument(llvm::StringRef());
0154     m_cursor_index++;
0155     m_cursor_char_position = 0;
0156   }
0157 
0158   size_t GetCursorIndex() const { return m_cursor_index; }
0159 
0160   /// Adds a possible completion string. If the completion was already
0161   /// suggested before, it will not be added to the list of results. A copy of
0162   /// the suggested completion is stored, so the given string can be free'd
0163   /// afterwards.
0164   ///
0165   /// \param completion The suggested completion.
0166   /// \param description An optional description of the completion string. The
0167   ///     description will be displayed to the user alongside the completion.
0168   /// \param mode The CompletionMode for this completion.
0169   void AddCompletion(llvm::StringRef completion,
0170                      llvm::StringRef description = "",
0171                      CompletionMode mode = CompletionMode::Normal) {
0172     m_result.AddResult(completion, description, mode);
0173   }
0174 
0175   /// Adds a possible completion string if the completion would complete the
0176   /// current argument.
0177   ///
0178   /// \param completion The suggested completion.
0179   /// \param description An optional description of the completion string. The
0180   ///     description will be displayed to the user alongside the completion.
0181   template <CompletionMode M = CompletionMode::Normal>
0182   void TryCompleteCurrentArg(llvm::StringRef completion,
0183                              llvm::StringRef description = "") {
0184     // Trying to rewrite the whole line while checking for the current
0185     // argument never makes sense. Completion modes are always hardcoded, so
0186     // this can be a static_assert.
0187     static_assert(M != CompletionMode::RewriteLine,
0188                   "Shouldn't rewrite line with this function");
0189     if (completion.starts_with(GetCursorArgumentPrefix()))
0190       AddCompletion(completion, description, M);
0191   }
0192 
0193   /// Adds multiple possible completion strings.
0194   ///
0195   /// \param completions The list of completions.
0196   ///
0197   /// \see AddCompletion
0198   void AddCompletions(const StringList &completions) {
0199     for (const std::string &completion : completions)
0200       AddCompletion(completion);
0201   }
0202 
0203   /// Adds multiple possible completion strings alongside their descriptions.
0204   ///
0205   /// The number of completions and descriptions must be identical.
0206   ///
0207   /// \param completions The list of completions.
0208   /// \param descriptions The list of descriptions.
0209   ///
0210   /// \see AddCompletion
0211   void AddCompletions(const StringList &completions,
0212                       const StringList &descriptions) {
0213     lldbassert(completions.GetSize() == descriptions.GetSize());
0214     for (std::size_t i = 0; i < completions.GetSize(); ++i)
0215       AddCompletion(completions.GetStringAtIndex(i),
0216                     descriptions.GetStringAtIndex(i));
0217   }
0218 
0219   llvm::StringRef GetCursorArgumentPrefix() const {
0220     return GetParsedLine().GetArgumentAtIndex(GetCursorIndex());
0221   }
0222 
0223 private:
0224   /// The raw command line we are supposed to complete.
0225   llvm::StringRef m_command;
0226   /// The cursor position in m_command.
0227   unsigned m_raw_cursor_pos;
0228   /// The command line parsed as arguments.
0229   Args m_parsed_line;
0230   /// The index of the argument in which the completion cursor is.
0231   size_t m_cursor_index;
0232   /// The cursor position in the argument indexed by m_cursor_index.
0233   size_t m_cursor_char_position;
0234 
0235   /// The result this request is supposed to fill out.
0236   /// We keep this object private to ensure that no backend can in any way
0237   /// depend on already calculated completions (which would make debugging and
0238   /// testing them much more complicated).
0239   CompletionResult &m_result;
0240 };
0241 
0242 } // namespace lldb_private
0243 
0244 #endif // LLDB_UTILITY_COMPLETIONREQUEST_H