This revision was automatically updated to reflect the committed changes.
Closed by commit rL337031: Replaced more boilerplate code with 
CompletionRequest (NFC) (authored by teemperor, committed by ).
Herald added a subscriber: llvm-commits.

Changed prior to commit:
  https://reviews.llvm.org/D48976?vs=154247&id=155441#toc

Repository:
  rL LLVM

https://reviews.llvm.org/D48976

Files:
  lldb/trunk/include/lldb/Core/FormatEntity.h
  lldb/trunk/include/lldb/Interpreter/CommandCompletions.h
  lldb/trunk/include/lldb/Interpreter/OptionValue.h
  lldb/trunk/include/lldb/Interpreter/OptionValueArch.h
  lldb/trunk/include/lldb/Interpreter/OptionValueBoolean.h
  lldb/trunk/include/lldb/Interpreter/OptionValueEnumeration.h
  lldb/trunk/include/lldb/Interpreter/OptionValueFileSpec.h
  lldb/trunk/include/lldb/Interpreter/OptionValueFormatEntity.h
  lldb/trunk/include/lldb/Interpreter/OptionValueUUID.h
  lldb/trunk/include/lldb/Interpreter/Options.h
  lldb/trunk/include/lldb/Symbol/Variable.h
  lldb/trunk/include/lldb/Utility/ArchSpec.h
  lldb/trunk/include/lldb/Utility/CompletionRequest.h
  lldb/trunk/source/Commands/CommandCompletions.cpp
  lldb/trunk/source/Commands/CommandObjectCommands.cpp
  lldb/trunk/source/Commands/CommandObjectFrame.cpp
  lldb/trunk/source/Commands/CommandObjectPlatform.cpp
  lldb/trunk/source/Commands/CommandObjectPlugin.cpp
  lldb/trunk/source/Commands/CommandObjectProcess.cpp
  lldb/trunk/source/Commands/CommandObjectSettings.cpp
  lldb/trunk/source/Commands/CommandObjectTarget.cpp
  lldb/trunk/source/Core/FormatEntity.cpp
  lldb/trunk/source/Core/IOHandler.cpp
  lldb/trunk/source/Interpreter/CommandInterpreter.cpp
  lldb/trunk/source/Interpreter/CommandObject.cpp
  lldb/trunk/source/Interpreter/CommandObjectRegexCommand.cpp
  lldb/trunk/source/Interpreter/OptionValue.cpp
  lldb/trunk/source/Interpreter/OptionValueArch.cpp
  lldb/trunk/source/Interpreter/OptionValueBoolean.cpp
  lldb/trunk/source/Interpreter/OptionValueEnumeration.cpp
  lldb/trunk/source/Interpreter/OptionValueFileSpec.cpp
  lldb/trunk/source/Interpreter/OptionValueFormatEntity.cpp
  lldb/trunk/source/Interpreter/OptionValueUUID.cpp
  lldb/trunk/source/Interpreter/Options.cpp
  lldb/trunk/source/Symbol/Variable.cpp
  lldb/trunk/source/Utility/ArchSpec.cpp
  lldb/trunk/source/Utility/CompletionRequest.cpp
  lldb/trunk/unittests/Utility/CompletionRequestTest.cpp

Index: lldb/trunk/include/lldb/Core/FormatEntity.h
===================================================================
--- lldb/trunk/include/lldb/Core/FormatEntity.h
+++ lldb/trunk/include/lldb/Core/FormatEntity.h
@@ -10,6 +10,7 @@
 #ifndef liblldb_FormatEntity_h_
 #define liblldb_FormatEntity_h_
 
+#include "lldb/Utility/CompletionRequest.h"
 #include "lldb/Utility/FileSpec.h" // for FileSpec
 #include "lldb/Utility/Status.h"
 #include "lldb/lldb-enumerations.h" // for Format::eFormatDefault, Format
@@ -211,9 +212,7 @@
                                     llvm::StringRef &variable_name,
                                     llvm::StringRef &variable_format);
 
-  static size_t AutoComplete(llvm::StringRef s, int match_start_point,
-                             int max_return_elements, bool &word_complete,
-                             StringList &matches);
+  static size_t AutoComplete(lldb_private::CompletionRequest &request);
 
   //----------------------------------------------------------------------
   // Format the current elements into the stream \a s.
Index: lldb/trunk/include/lldb/Symbol/Variable.h
===================================================================
--- lldb/trunk/include/lldb/Symbol/Variable.h
+++ lldb/trunk/include/lldb/Symbol/Variable.h
@@ -103,8 +103,7 @@
       ValueObjectList &valobj_list);
 
   static size_t AutoComplete(const ExecutionContext &exe_ctx,
-                             llvm::StringRef name, StringList &matches,
-                             bool &word_complete);
+                             CompletionRequest &request);
 
   CompilerDeclContext GetDeclContext();
 
Index: lldb/trunk/include/lldb/Interpreter/OptionValueFormatEntity.h
===================================================================
--- lldb/trunk/include/lldb/Interpreter/OptionValueFormatEntity.h
+++ lldb/trunk/include/lldb/Interpreter/OptionValueFormatEntity.h
@@ -45,9 +45,8 @@
 
   lldb::OptionValueSP DeepCopy() const override;
 
-  size_t AutoComplete(CommandInterpreter &interpreter, llvm::StringRef s,
-                      int match_start_point, int max_return_elements,
-                      bool &word_complete, StringList &matches) override;
+  size_t AutoComplete(CommandInterpreter &interpreter,
+                      CompletionRequest &request) override;
 
   //---------------------------------------------------------------------
   // Subclass specific functions
Index: lldb/trunk/include/lldb/Interpreter/OptionValueFileSpec.h
===================================================================
--- lldb/trunk/include/lldb/Interpreter/OptionValueFileSpec.h
+++ lldb/trunk/include/lldb/Interpreter/OptionValueFileSpec.h
@@ -54,9 +54,8 @@
 
   lldb::OptionValueSP DeepCopy() const override;
 
-  size_t AutoComplete(CommandInterpreter &interpreter, llvm::StringRef s,
-                      int match_start_point, int max_return_elements,
-                      bool &word_complete, StringList &matches) override;
+  size_t AutoComplete(CommandInterpreter &interpreter,
+                      CompletionRequest &request) override;
 
   //---------------------------------------------------------------------
   // Subclass specific functions
Index: lldb/trunk/include/lldb/Interpreter/OptionValueEnumeration.h
===================================================================
--- lldb/trunk/include/lldb/Interpreter/OptionValueEnumeration.h
+++ lldb/trunk/include/lldb/Interpreter/OptionValueEnumeration.h
@@ -59,9 +59,8 @@
 
   lldb::OptionValueSP DeepCopy() const override;
 
-  size_t AutoComplete(CommandInterpreter &interpreter, llvm::StringRef s,
-                      int match_start_point, int max_return_elements,
-                      bool &word_complete, StringList &matches) override;
+  size_t AutoComplete(CommandInterpreter &interpreter,
+                      CompletionRequest &request) override;
 
   //---------------------------------------------------------------------
   // Subclass specific functions
Index: lldb/trunk/include/lldb/Interpreter/OptionValueBoolean.h
===================================================================
--- lldb/trunk/include/lldb/Interpreter/OptionValueBoolean.h
+++ lldb/trunk/include/lldb/Interpreter/OptionValueBoolean.h
@@ -50,9 +50,8 @@
     return true;
   }
 
-  size_t AutoComplete(CommandInterpreter &interpreter, llvm::StringRef s,
-                      int match_start_point, int max_return_elements,
-                      bool &word_complete, StringList &matches) override;
+  size_t AutoComplete(CommandInterpreter &interpreter,
+                      CompletionRequest &request) override;
 
   //---------------------------------------------------------------------
   // Subclass specific functions
Index: lldb/trunk/include/lldb/Interpreter/OptionValue.h
===================================================================
--- lldb/trunk/include/lldb/Interpreter/OptionValue.h
+++ lldb/trunk/include/lldb/Interpreter/OptionValue.h
@@ -15,6 +15,7 @@
 // Other libraries and framework includes
 // Project includes
 #include "lldb/Core/FormatEntity.h"
+#include "lldb/Utility/CompletionRequest.h"
 #include "lldb/Utility/ConstString.h"
 #include "lldb/Utility/Status.h"
 #include "lldb/lldb-defines.h"
@@ -100,9 +101,7 @@
   virtual lldb::OptionValueSP DeepCopy() const = 0;
 
   virtual size_t AutoComplete(CommandInterpreter &interpreter,
-                              llvm::StringRef s, int match_start_point,
-                              int max_return_elements, bool &word_complete,
-                              StringList &matches);
+                              CompletionRequest &request);
 
   //-----------------------------------------------------------------
   // Subclasses can override these functions
Index: lldb/trunk/include/lldb/Interpreter/OptionValueArch.h
===================================================================
--- lldb/trunk/include/lldb/Interpreter/OptionValueArch.h
+++ lldb/trunk/include/lldb/Interpreter/OptionValueArch.h
@@ -57,9 +57,8 @@
 
   lldb::OptionValueSP DeepCopy() const override;
 
-  size_t AutoComplete(CommandInterpreter &interpreter, llvm::StringRef s,
-                      int match_start_point, int max_return_elements,
-                      bool &word_complete, StringList &matches) override;
+  size_t AutoComplete(CommandInterpreter &interpreter,
+                      lldb_private::CompletionRequest &request) override;
 
   //---------------------------------------------------------------------
   // Subclass specific functions
Index: lldb/trunk/include/lldb/Interpreter/OptionValueUUID.h
===================================================================
--- lldb/trunk/include/lldb/Interpreter/OptionValueUUID.h
+++ lldb/trunk/include/lldb/Interpreter/OptionValueUUID.h
@@ -61,9 +61,8 @@
 
   void SetCurrentValue(const UUID &value) { m_uuid = value; }
 
-  size_t AutoComplete(CommandInterpreter &interpreter, llvm::StringRef s,
-                      int match_start_point, int max_return_elements,
-                      bool &word_complete, StringList &matches) override;
+  size_t AutoComplete(CommandInterpreter &interpreter,
+                      CompletionRequest &request) override;
 
 protected:
   UUID m_uuid;
Index: lldb/trunk/include/lldb/Interpreter/Options.h
===================================================================
--- lldb/trunk/include/lldb/Interpreter/Options.h
+++ lldb/trunk/include/lldb/Interpreter/Options.h
@@ -176,81 +176,32 @@
   /// Handles the generic bits of figuring out whether we are in an option,
   /// and if so completing it.
   ///
-  /// @param[in] input
-  ///    The command line parsed into words
-  ///
-  /// @param[in] cursor_index
-  ///     The index in \ainput of the word in which the cursor lies.
-  ///
-  /// @param[in] char_pos
-  ///     The character position of the cursor in its argument word.
-  ///
-  /// @param[in] match_start_point
-  /// @param[in] match_return_elements
-  ///     See CommandObject::HandleCompletions for a description of
-  ///     how these work.
+  /// @param[in/out] request
+  ///    The completion request that we need to act upon.
   ///
   /// @param[in] interpreter
   ///     The interpreter that's doing the completing.
   ///
-  /// @param[out] word_complete
-  ///     \btrue if this is a complete option value (a space will be
-  ///     inserted after the completion.) \b false otherwise.
-  ///
-  /// @param[out] matches
-  ///     The array of matches returned.
-  ///
   /// FIXME: This is the wrong return value, since we also need to
   /// make a distinction between total number of matches, and the window the
   /// user wants returned.
   ///
   /// @return
   ///     \btrue if we were in an option, \bfalse otherwise.
   //------------------------------------------------------------------
-  bool HandleOptionCompletion(Args &input, OptionElementVector &option_map,
-                              int cursor_index, int char_pos,
-                              int match_start_point, int max_return_elements,
-                              CommandInterpreter &interpreter,
-                              bool &word_complete,
-                              lldb_private::StringList &matches);
+  bool HandleOptionCompletion(lldb_private::CompletionRequest &request,
+                              OptionElementVector &option_map,
+                              CommandInterpreter &interpreter);
 
   //------------------------------------------------------------------
   /// Handles the generic bits of figuring out whether we are in an option,
   /// and if so completing it.
   ///
-  /// @param[in] interpreter
-  ///    The command interpreter doing the completion.
-  ///
-  /// @param[in] input
-  ///    The command line parsed into words
-  ///
-  /// @param[in] cursor_index
-  ///     The index in \ainput of the word in which the cursor lies.
-  ///
-  /// @param[in] char_pos
-  ///     The character position of the cursor in its argument word.
-  ///
-  /// @param[in] opt_element_vector
-  ///     The results of the options parse of \a input.
-  ///
-  /// @param[in] opt_element_index
-  ///     The position in \a opt_element_vector of the word in \a
-  ///     input containing the cursor.
-  ///
-  /// @param[in] match_start_point
-  /// @param[in] match_return_elements
-  ///     See CommandObject::HandleCompletions for a description of
-  ///     how these work.
+  /// @param[in/out] request
+  ///    The completion request that we need to act upon.
   ///
   /// @param[in] interpreter
-  ///     The command interpreter in which we're doing completion.
-  ///
-  /// @param[out] word_complete
-  ///     \btrue if this is a complete option value (a space will
-  ///     be inserted after the completion.) \bfalse otherwise.
-  ///
-  /// @param[out] matches
-  ///     The array of matches returned.
+  ///    The command interpreter doing the completion.
   ///
   /// FIXME: This is the wrong return value, since we also need to
   /// make a distinction between total number of matches, and the window the
@@ -260,12 +211,10 @@
   ///     \btrue if we were in an option, \bfalse otherwise.
   //------------------------------------------------------------------
   virtual bool
-  HandleOptionArgumentCompletion(Args &input, int cursor_index, int char_pos,
+  HandleOptionArgumentCompletion(lldb_private::CompletionRequest &request,
                                  OptionElementVector &opt_element_vector,
-                                 int opt_element_index, int match_start_point,
-                                 int max_return_elements,
-                                 CommandInterpreter &interpreter,
-                                 bool &word_complete, StringList &matches);
+                                 int opt_element_index,
+                                 CommandInterpreter &interpreter);
 
 protected:
   // This is a set of options expressed as indexes into the options table for
Index: lldb/trunk/include/lldb/Interpreter/CommandCompletions.h
===================================================================
--- lldb/trunk/include/lldb/Interpreter/CommandCompletions.h
+++ lldb/trunk/include/lldb/Interpreter/CommandCompletions.h
@@ -18,6 +18,7 @@
 // Project includes
 #include "lldb/Core/FileSpecList.h"
 #include "lldb/Core/SearchFilter.h"
+#include "lldb/Utility/CompletionRequest.h"
 #include "lldb/Utility/RegularExpression.h"
 #include "lldb/lldb-private.h"
 
@@ -32,16 +33,10 @@
   // argument of the option it is bound to (in the OptionDefinition table
   // below).  Return the total number of matches.
   //----------------------------------------------------------------------
-  typedef int (*CompletionCallback)(
-      CommandInterpreter &interpreter,
-      llvm::StringRef completion_str, // This is the argument we are completing
-      int match_start_point,   // This is the point in the list of matches that
-                               // you should start returning elements
-      int max_return_elements, // This is the number of matches requested.
-      lldb_private::SearchFilter
-          *searcher, // A search filter to limit the search...
-      bool &word_complete,
-      lldb_private::StringList &matches); // The array of matches we return.
+  typedef int (*CompletionCallback)(CommandInterpreter &interpreter,
+                                    CompletionRequest &request,
+                                    // A search filter to limit the search...
+                                    lldb_private::SearchFilter *searcher);
   typedef enum {
     eNoCompletion = 0u,
     eSourceFileCompletion = (1u << 0),
@@ -66,80 +61,55 @@
 
   static bool InvokeCommonCompletionCallbacks(
       CommandInterpreter &interpreter, uint32_t completion_mask,
-      llvm::StringRef completion_str, int match_start_point,
-      int max_return_elements, SearchFilter *searcher, bool &word_complete,
-      StringList &matches);
+      lldb_private::CompletionRequest &request, SearchFilter *searcher);
 
   //----------------------------------------------------------------------
   // These are the generic completer functions:
   //----------------------------------------------------------------------
   static int DiskFiles(CommandInterpreter &interpreter,
-                       llvm::StringRef partial_file_name, int match_start_point,
-                       int max_return_elements, SearchFilter *searcher,
-                       bool &word_complete, StringList &matches);
+                       CompletionRequest &request, SearchFilter *searcher);
 
   static int DiskFiles(const llvm::Twine &partial_file_name,
                        StringList &matches, TildeExpressionResolver &Resolver);
 
   static int DiskDirectories(CommandInterpreter &interpreter,
-                             llvm::StringRef partial_file_name,
-                             int match_start_point, int max_return_elements,
-                             SearchFilter *searcher, bool &word_complete,
-                             StringList &matches);
+                             CompletionRequest &request,
+                             SearchFilter *searcher);
 
   static int DiskDirectories(const llvm::Twine &partial_file_name,
                              StringList &matches,
                              TildeExpressionResolver &Resolver);
 
   static int SourceFiles(CommandInterpreter &interpreter,
-                         llvm::StringRef partial_file_name,
-                         int match_start_point, int max_return_elements,
-                         SearchFilter *searcher, bool &word_complete,
-                         StringList &matches);
+                         CompletionRequest &request, SearchFilter *searcher);
 
   static int Modules(CommandInterpreter &interpreter,
-                     llvm::StringRef partial_file_name, int match_start_point,
-                     int max_return_elements, SearchFilter *searcher,
-                     bool &word_complete, lldb_private::StringList &matches);
+                     CompletionRequest &request, SearchFilter *searcher);
 
   static int Symbols(CommandInterpreter &interpreter,
-                     llvm::StringRef partial_file_name, int match_start_point,
-                     int max_return_elements, SearchFilter *searcher,
-                     bool &word_complete, lldb_private::StringList &matches);
+                     CompletionRequest &request, SearchFilter *searcher);
 
   static int SettingsNames(CommandInterpreter &interpreter,
-                           llvm::StringRef partial_file_name,
-                           int match_start_point, int max_return_elements,
-                           SearchFilter *searcher, bool &word_complete,
-                           lldb_private::StringList &matches);
+                           CompletionRequest &request, SearchFilter *searcher);
 
   static int PlatformPluginNames(CommandInterpreter &interpreter,
-                                 llvm::StringRef partial_file_name,
-                                 int match_start_point, int max_return_elements,
-                                 SearchFilter *searcher, bool &word_complete,
-                                 lldb_private::StringList &matches);
+                                 CompletionRequest &request,
+                                 SearchFilter *searcher);
 
   static int ArchitectureNames(CommandInterpreter &interpreter,
-                               llvm::StringRef partial_file_name,
-                               int match_start_point, int max_return_elements,
-                               SearchFilter *searcher, bool &word_complete,
-                               lldb_private::StringList &matches);
+                               CompletionRequest &request,
+                               SearchFilter *searcher);
 
   static int VariablePath(CommandInterpreter &interpreter,
-                          llvm::StringRef partial_file_name,
-                          int match_start_point, int max_return_elements,
-                          SearchFilter *searcher, bool &word_complete,
-                          lldb_private::StringList &matches);
+                          CompletionRequest &request, SearchFilter *searcher);
 
   //----------------------------------------------------------------------
   // The Completer class is a convenient base class for building searchers that
   // go along with the SearchFilter passed to the standard Completer functions.
   //----------------------------------------------------------------------
   class Completer : public Searcher {
   public:
-    Completer(CommandInterpreter &interpreter, llvm::StringRef completion_str,
-              int match_start_point, int max_return_elements,
-              StringList &matches);
+    Completer(CommandInterpreter &interpreter, CompletionRequest &request);
 
     ~Completer() override;
 
@@ -152,10 +122,7 @@
 
   protected:
     CommandInterpreter &m_interpreter;
-    std::string m_completion_str;
-    int m_match_start_point;
-    int m_max_return_elements;
-    StringList &m_matches;
+    CompletionRequest &m_request;
 
   private:
     DISALLOW_COPY_AND_ASSIGN(Completer);
@@ -167,9 +134,7 @@
   class SourceFileCompleter : public Completer {
   public:
     SourceFileCompleter(CommandInterpreter &interpreter,
-                        bool include_support_files,
-                        llvm::StringRef completion_str, int match_start_point,
-                        int max_return_elements, StringList &matches);
+                        bool include_support_files, CompletionRequest &request);
 
     Searcher::Depth GetDepth() override;
 
@@ -195,8 +160,7 @@
   class ModuleCompleter : public Completer {
   public:
     ModuleCompleter(CommandInterpreter &interpreter,
-                    llvm::StringRef completion_str, int match_start_point,
-                    int max_return_elements, StringList &matches);
+                    CompletionRequest &request);
 
     Searcher::Depth GetDepth() override;
 
@@ -220,8 +184,7 @@
   class SymbolCompleter : public Completer {
   public:
     SymbolCompleter(CommandInterpreter &interpreter,
-                    llvm::StringRef completion_str, int match_start_point,
-                    int max_return_elements, StringList &matches);
+                    CompletionRequest &request);
 
     Searcher::Depth GetDepth() override;
 
Index: lldb/trunk/include/lldb/Utility/ArchSpec.h
===================================================================
--- lldb/trunk/include/lldb/Utility/ArchSpec.h
+++ lldb/trunk/include/lldb/Utility/ArchSpec.h
@@ -10,6 +10,7 @@
 #ifndef LLDB_UTILITY_ARCHSPEC_H
 #define LLDB_UTILITY_ARCHSPEC_H
 
+#include "lldb/Utility/CompletionRequest.h"
 #include "lldb/Utility/ConstString.h"
 #include "lldb/lldb-enumerations.h"
 #include "lldb/lldb-forward.h"
@@ -288,7 +289,8 @@
   //---------------------------------------------------------------------------
   static bool ContainsOnlyArch(const llvm::Triple &normalized_triple);
 
-  static size_t AutoComplete(llvm::StringRef name, StringList &matches);
+  static void ListSupportedArchNames(StringList &list);
+  static size_t AutoComplete(CompletionRequest &request);
 
   //------------------------------------------------------------------
   /// Returns a static string representing the current architecture.
Index: lldb/trunk/include/lldb/Utility/CompletionRequest.h
===================================================================
--- lldb/trunk/include/lldb/Utility/CompletionRequest.h
+++ lldb/trunk/include/lldb/Utility/CompletionRequest.h
@@ -27,26 +27,42 @@
 //----------------------------------------------------------------------
 class CompletionRequest {
 public:
-  //----------------------------------------------------------------------
+  //----------------------------------------------------------
   /// Constructs a completion request.
   ///
-  /// See the respective members of this class for documentation for the
-  /// parameters.
-  // TODO: Infer the parsed_line and the cursor positions from the other
-  // arguments.
-  //----------------------------------------------------------------------
-  CompletionRequest(llvm::StringRef command, unsigned raw_cursor_pos,
-                    Args &parsed_line, int cursor_index,
-                    int cursor_char_position, int match_start_point,
-                    int max_return_elements, bool word_complete,
+  /// @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 [in] match_start_point
+  /// @param [in] max_return_elements
+  ///     If there is a match that is expensive to compute, these are here to
+  ///     allow you to compute the completions in  batches.  Start the
+  ///     completion from match_start_point, and return match_return_elements
+  ///     elements.
+  ///
+  /// @param [out] matches
+  ///     A list of matches that will be filled by the different completion
+  ///     handlers.
+  //----------------------------------------------------------
+  CompletionRequest(llvm::StringRef command_line, unsigned raw_cursor_pos,
+                    int match_start_point, int max_return_elements,
                     StringList &matches);
 
   llvm::StringRef GetRawLine() 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 &GetPartialParsedLine() const { return m_partial_parsed_line; }
+
   void SetCursorIndex(int i) { m_cursor_index = i; }
   int GetCursorIndex() const { return m_cursor_index; }
 
@@ -64,13 +80,23 @@
   /// The array of matches returned.
   StringList &GetMatches() { return *m_matches; }
 
+  llvm::StringRef GetCursorArgument() const {
+    return GetParsedLine().GetArgumentAtIndex(GetCursorIndex());
+  }
+
+  llvm::StringRef GetCursorArgumentPrefix() const {
+    return GetCursorArgument().substr(0, GetCursorCharPosition());
+  }
+
 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 command line until the cursor position parsed as arguments.
+  Args m_partial_parsed_line;
   /// The index of the argument in which the completion cursor is.
   int m_cursor_index;
   /// The cursor position in the argument indexed by m_cursor_index.
@@ -84,7 +110,7 @@
   int m_max_return_elements;
   /// \btrue if this is a complete option value (a space will be inserted
   /// after the completion.)  \bfalse otherwise.
-  bool m_word_complete;
+  bool m_word_complete = false;
   // We don't own the list.
   StringList *m_matches;
 };
Index: lldb/trunk/unittests/Utility/CompletionRequestTest.cpp
===================================================================
--- lldb/trunk/unittests/Utility/CompletionRequestTest.cpp
+++ lldb/trunk/unittests/Utility/CompletionRequestTest.cpp
@@ -13,26 +13,28 @@
 using namespace lldb_private;
 
 TEST(CompletionRequest, Constructor) {
-  std::string command = "a b";
-  const unsigned cursor_pos = 2;
-  Args args(command);
+  std::string command = "a bad c";
+  const unsigned cursor_pos = 3;
   const int arg_index = 1;
-  const int arg_cursor_pos = 0;
+  const int arg_cursor_pos = 1;
   const int match_start = 2345;
   const int match_max_return = 12345;
-  bool word_complete = false;
   StringList matches;
-  CompletionRequest request(command, cursor_pos, args, arg_index,
-                            arg_cursor_pos, match_start, match_max_return,
-                            word_complete, matches);
+
+  CompletionRequest request(command, cursor_pos, match_start, match_max_return,
+                            matches);
 
   EXPECT_STREQ(request.GetRawLine().str().c_str(), command.c_str());
   EXPECT_EQ(request.GetRawCursorPos(), cursor_pos);
   EXPECT_EQ(request.GetCursorIndex(), arg_index);
   EXPECT_EQ(request.GetCursorCharPosition(), arg_cursor_pos);
   EXPECT_EQ(request.GetMatchStartPoint(), match_start);
   EXPECT_EQ(request.GetMaxReturnElements(), match_max_return);
-  EXPECT_EQ(request.GetWordComplete(), word_complete);
+  EXPECT_EQ(request.GetWordComplete(), false);
+
+  EXPECT_EQ(request.GetPartialParsedLine().GetArgumentCount(), 2u);
+  EXPECT_STREQ(request.GetPartialParsedLine().GetArgumentAtIndex(1), "b");
+
   // This is the generated matches should be equal to our passed string list.
   EXPECT_EQ(&request.GetMatches(), &matches);
 }
Index: lldb/trunk/source/Core/FormatEntity.cpp
===================================================================
--- lldb/trunk/source/Core/FormatEntity.cpp
+++ lldb/trunk/source/Core/FormatEntity.cpp
@@ -2344,12 +2344,12 @@
   }
 }
 
-size_t FormatEntity::AutoComplete(llvm::StringRef str, int match_start_point,
-                                  int max_return_elements, bool &word_complete,
-                                  StringList &matches) {
-  word_complete = false;
-  str = str.drop_front(match_start_point);
-  matches.Clear();
+size_t FormatEntity::AutoComplete(CompletionRequest &request) {
+  llvm::StringRef str = request.GetCursorArgumentPrefix().str();
+
+  request.SetWordComplete(false);
+  str = str.drop_front(request.GetMatchStartPoint());
+  request.GetMatches().Clear();
 
   const size_t dollar_pos = str.rfind('$');
   if (dollar_pos == llvm::StringRef::npos)
@@ -2359,7 +2359,7 @@
   if (dollar_pos == str.size() - 1) {
     std::string match = str.str();
     match.append("{");
-    matches.AppendString(match);
+    request.GetMatches().AppendString(match);
     return 1;
   }
 
@@ -2377,8 +2377,8 @@
   llvm::StringRef partial_variable(str.substr(dollar_pos + 2));
   if (partial_variable.empty()) {
     // Suggest all top level entites as we are just past "${"
-    AddMatches(&g_root, str, llvm::StringRef(), matches);
-    return matches.GetSize();
+    AddMatches(&g_root, str, llvm::StringRef(), request.GetMatches());
+    return request.GetMatches().GetSize();
   }
 
   // We have a partially specified variable, find it
@@ -2394,19 +2394,19 @@
     // Exact match
     if (n > 0) {
       // "${thread.info" <TAB>
-      matches.AppendString(MakeMatch(str, "."));
+      request.GetMatches().AppendString(MakeMatch(str, "."));
     } else {
       // "${thread.id" <TAB>
-      matches.AppendString(MakeMatch(str, "}"));
-      word_complete = true;
+      request.GetMatches().AppendString(MakeMatch(str, "}"));
+      request.SetWordComplete(true);
     }
   } else if (remainder.equals(".")) {
     // "${thread." <TAB>
-    AddMatches(entry_def, str, llvm::StringRef(), matches);
+    AddMatches(entry_def, str, llvm::StringRef(), request.GetMatches());
   } else {
     // We have a partial match
     // "${thre" <TAB>
-    AddMatches(entry_def, str, remainder, matches);
+    AddMatches(entry_def, str, remainder, request.GetMatches());
   }
-  return matches.GetSize();
+  return request.GetMatches().GetSize();
 }
Index: lldb/trunk/source/Core/IOHandler.cpp
===================================================================
--- lldb/trunk/source/Core/IOHandler.cpp
+++ lldb/trunk/source/Core/IOHandler.cpp
@@ -239,26 +239,21 @@
         matches);
 
   case Completion::Expression: {
-    bool word_complete = false;
-    const char *word_start = cursor;
-    if (cursor > current_line)
-      --word_start;
-    while (word_start > current_line && !isspace(*word_start))
-      --word_start;
+    CompletionRequest request(current_line, current_line - cursor,
+                              skip_first_n_matches, max_matches, matches);
     CommandCompletions::InvokeCommonCompletionCallbacks(
         io_handler.GetDebugger().GetCommandInterpreter(),
-        CommandCompletions::eVariablePathCompletion, word_start,
-        skip_first_n_matches, max_matches, nullptr, word_complete, matches);
+        CommandCompletions::eVariablePathCompletion, request, nullptr);
 
-    size_t num_matches = matches.GetSize();
+    size_t num_matches = request.GetMatches().GetSize();
     if (num_matches > 0) {
       std::string common_prefix;
-      matches.LongestCommonPrefix(common_prefix);
-      const size_t partial_name_len = strlen(word_start);
+      request.GetMatches().LongestCommonPrefix(common_prefix);
+      const size_t partial_name_len = request.GetCursorArgumentPrefix().size();
 
       // If we matched a unique single command, add a space... Only do this if
       // the completer told us this was a complete word, however...
-      if (num_matches == 1 && word_complete) {
+      if (num_matches == 1 && request.GetWordComplete()) {
         common_prefix.push_back(' ');
       }
       common_prefix.erase(0, partial_name_len);
Index: lldb/trunk/source/Symbol/Variable.cpp
===================================================================
--- lldb/trunk/source/Symbol/Variable.cpp
+++ lldb/trunk/source/Symbol/Variable.cpp
@@ -756,13 +756,13 @@
 }
 
 size_t Variable::AutoComplete(const ExecutionContext &exe_ctx,
-                              llvm::StringRef partial_path, StringList &matches,
-                              bool &word_complete) {
-  word_complete = false;
+                              CompletionRequest &request) {
   CompilerType compiler_type;
 
-  PrivateAutoComplete(exe_ctx.GetFramePtr(), partial_path, "", compiler_type,
-                      matches, word_complete);
+  bool word_complete = false;
+  PrivateAutoComplete(exe_ctx.GetFramePtr(), request.GetCursorArgumentPrefix(),
+                      "", compiler_type, request.GetMatches(), word_complete);
+  request.SetWordComplete(word_complete);
 
-  return matches.GetSize();
+  return request.GetMatches().GetSize();
 }
Index: lldb/trunk/source/Utility/CompletionRequest.cpp
===================================================================
--- lldb/trunk/source/Utility/CompletionRequest.cpp
+++ lldb/trunk/source/Utility/CompletionRequest.cpp
@@ -12,15 +12,48 @@
 using namespace lldb;
 using namespace lldb_private;
 
-CompletionRequest::CompletionRequest(llvm::StringRef command,
-                                     unsigned raw_cursor_pos, Args &parsed_line,
-                                     int cursor_index, int cursor_char_position,
+CompletionRequest::CompletionRequest(llvm::StringRef command_line,
+                                     unsigned raw_cursor_pos,
                                      int match_start_point,
                                      int max_return_elements,
-                                     bool word_complete, StringList &matches)
-    : m_command(command), m_raw_cursor_pos(raw_cursor_pos),
-      m_parsed_line(parsed_line), m_cursor_index(cursor_index),
-      m_cursor_char_position(cursor_char_position),
+                                     StringList &matches)
+    : m_command(command_line), m_raw_cursor_pos(raw_cursor_pos),
       m_match_start_point(match_start_point),
-      m_max_return_elements(max_return_elements),
-      m_word_complete(word_complete), m_matches(&matches) {}
+      m_max_return_elements(max_return_elements), m_matches(&matches) {
+
+  // We parse the argument up to the cursor, so the last argument in
+  // parsed_line is the one containing the cursor, and the cursor is after the
+  // last character.
+  m_parsed_line = Args(command_line);
+  m_partial_parsed_line = Args(command_line.substr(0, raw_cursor_pos));
+
+  m_cursor_index = m_partial_parsed_line.GetArgumentCount() - 1;
+
+  if (m_cursor_index == -1)
+    m_cursor_char_position = 0;
+  else
+    m_cursor_char_position =
+        strlen(m_partial_parsed_line.GetArgumentAtIndex(m_cursor_index));
+
+  matches.Clear();
+
+  const char *cursor = command_line.data() + raw_cursor_pos;
+  if (raw_cursor_pos > 0 && cursor[-1] == ' ') {
+    // We are just after a space.  If we are in an argument, then we will
+    // continue parsing, but if we are between arguments, then we have to
+    // complete whatever the next element would be. We can distinguish the two
+    // cases because if we are in an argument (e.g. because the space is
+    // protected by a quote) then the space will also be in the parsed
+    // argument...
+
+    const char *current_elem =
+        m_partial_parsed_line.GetArgumentAtIndex(m_cursor_index);
+    if (m_cursor_char_position == 0 ||
+        current_elem[m_cursor_char_position - 1] != ' ') {
+      m_parsed_line.InsertArgumentAtIndex(m_cursor_index + 1, llvm::StringRef(),
+                                          '\0');
+      m_cursor_index++;
+      m_cursor_char_position = 0;
+    }
+  }
+}
Index: lldb/trunk/source/Utility/ArchSpec.cpp
===================================================================
--- lldb/trunk/source/Utility/ArchSpec.cpp
+++ lldb/trunk/source/Utility/ArchSpec.cpp
@@ -245,17 +245,22 @@
   const char *name;
 };
 
-size_t ArchSpec::AutoComplete(llvm::StringRef name, StringList &matches) {
-  if (!name.empty()) {
+void ArchSpec::ListSupportedArchNames(StringList &list) {
+  for (uint32_t i = 0; i < llvm::array_lengthof(g_core_definitions); ++i)
+    list.AppendString(g_core_definitions[i].name);
+}
+
+size_t ArchSpec::AutoComplete(CompletionRequest &request) {
+  if (!request.GetCursorArgumentPrefix().empty()) {
     for (uint32_t i = 0; i < llvm::array_lengthof(g_core_definitions); ++i) {
-      if (NameMatches(g_core_definitions[i].name, NameMatch::StartsWith, name))
-        matches.AppendString(g_core_definitions[i].name);
+      if (NameMatches(g_core_definitions[i].name, NameMatch::StartsWith,
+                      request.GetCursorArgumentPrefix()))
+        request.GetMatches().AppendString(g_core_definitions[i].name);
     }
   } else {
-    for (uint32_t i = 0; i < llvm::array_lengthof(g_core_definitions); ++i)
-      matches.AppendString(g_core_definitions[i].name);
+    ListSupportedArchNames(request.GetMatches());
   }
-  return matches.GetSize();
+  return request.GetMatches().GetSize();
 }
 
 #define CPU_ANY (UINT32_MAX)
Index: lldb/trunk/source/Interpreter/OptionValueEnumeration.cpp
===================================================================
--- lldb/trunk/source/Interpreter/OptionValueEnumeration.cpp
+++ lldb/trunk/source/Interpreter/OptionValueEnumeration.cpp
@@ -109,23 +109,23 @@
   return OptionValueSP(new OptionValueEnumeration(*this));
 }
 
-size_t OptionValueEnumeration::AutoComplete(
-    CommandInterpreter &interpreter, llvm::StringRef s, int match_start_point,
-    int max_return_elements, bool &word_complete, StringList &matches) {
-  word_complete = false;
-  matches.Clear();
+size_t OptionValueEnumeration::AutoComplete(CommandInterpreter &interpreter,
+                                            CompletionRequest &request) {
+  request.SetWordComplete(false);
+  request.GetMatches().Clear();
 
   const uint32_t num_enumerators = m_enumerations.GetSize();
-  if (!s.empty()) {
+  if (!request.GetCursorArgumentPrefix().empty()) {
     for (size_t i = 0; i < num_enumerators; ++i) {
       llvm::StringRef name = m_enumerations.GetCStringAtIndex(i).GetStringRef();
-      if (name.startswith(s))
-        matches.AppendString(name);
+      if (name.startswith(request.GetCursorArgumentPrefix()))
+        request.GetMatches().AppendString(name);
     }
   } else {
     // only suggest "true" or "false" by default
     for (size_t i = 0; i < num_enumerators; ++i)
-      matches.AppendString(m_enumerations.GetCStringAtIndex(i).GetStringRef());
+      request.GetMatches().AppendString(
+          m_enumerations.GetCStringAtIndex(i).GetStringRef());
   }
-  return matches.GetSize();
+  return request.GetMatches().GetSize();
 }
Index: lldb/trunk/source/Interpreter/CommandObject.cpp
===================================================================
--- lldb/trunk/source/Interpreter/CommandObject.cpp
+++ lldb/trunk/source/Interpreter/CommandObject.cpp
@@ -279,14 +279,8 @@
       opt_element_vector = cur_options->ParseForCompletion(
           request.GetParsedLine(), request.GetCursorIndex());
 
-      bool handled_by_options;
-      bool word_complete = request.GetWordComplete();
-      handled_by_options = cur_options->HandleOptionCompletion(
-          request.GetParsedLine(), opt_element_vector, request.GetCursorIndex(),
-          request.GetCursorCharPosition(), request.GetMatchStartPoint(),
-          request.GetMaxReturnElements(), GetCommandInterpreter(),
-          word_complete, request.GetMatches());
-      request.SetWordComplete(word_complete);
+      bool handled_by_options = cur_options->HandleOptionCompletion(
+          request, opt_element_vector, GetCommandInterpreter());
       if (handled_by_options)
         return request.GetMatches().GetSize();
     }
@@ -1015,7 +1009,8 @@
   static StreamString g_archs_help;
   if (g_archs_help.Empty()) {
     StringList archs;
-    ArchSpec::AutoComplete(llvm::StringRef(), archs);
+
+    ArchSpec::ListSupportedArchNames(archs);
     g_archs_help.Printf("These are the supported architecture names:\n");
     archs.Join("\n", g_archs_help);
   }
Index: lldb/trunk/source/Interpreter/OptionValue.cpp
===================================================================
--- lldb/trunk/source/Interpreter/OptionValue.cpp
+++ lldb/trunk/source/Interpreter/OptionValue.cpp
@@ -573,12 +573,10 @@
 }
 
 size_t OptionValue::AutoComplete(CommandInterpreter &interpreter,
-                                 llvm::StringRef s, int match_start_point,
-                                 int max_return_elements, bool &word_complete,
-                                 StringList &matches) {
-  word_complete = false;
-  matches.Clear();
-  return matches.GetSize();
+                                 CompletionRequest &request) {
+  request.SetWordComplete(false);
+  request.GetMatches().Clear();
+  return request.GetMatches().GetSize();
 }
 
 Status OptionValue::SetValueFromString(llvm::StringRef value,
Index: lldb/trunk/source/Interpreter/OptionValueBoolean.cpp
===================================================================
--- lldb/trunk/source/Interpreter/OptionValueBoolean.cpp
+++ lldb/trunk/source/Interpreter/OptionValueBoolean.cpp
@@ -76,23 +76,22 @@
   return OptionValueSP(new OptionValueBoolean(*this));
 }
 
-size_t OptionValueBoolean::AutoComplete(
-    CommandInterpreter &interpreter, llvm::StringRef s, int match_start_point,
-    int max_return_elements, bool &word_complete, StringList &matches) {
-  word_complete = false;
-  matches.Clear();
+size_t OptionValueBoolean::AutoComplete(CommandInterpreter &interpreter,
+                                        CompletionRequest &request) {
+  request.SetWordComplete(false);
+  request.GetMatches().Clear();
   static const llvm::StringRef g_autocomplete_entries[] = {
       "true", "false", "on", "off", "yes", "no", "1", "0"};
 
   auto entries = llvm::makeArrayRef(g_autocomplete_entries);
 
   // only suggest "true" or "false" by default
-  if (s.empty())
+  if (request.GetCursorArgumentPrefix().empty())
     entries = entries.take_front(2);
 
   for (auto entry : entries) {
-    if (entry.startswith_lower(s))
-      matches.AppendString(entry);
+    if (entry.startswith_lower(request.GetCursorArgumentPrefix()))
+      request.GetMatches().AppendString(entry);
   }
-  return matches.GetSize();
+  return request.GetMatches().GetSize();
 }
Index: lldb/trunk/source/Interpreter/OptionValueArch.cpp
===================================================================
--- lldb/trunk/source/Interpreter/OptionValueArch.cpp
+++ lldb/trunk/source/Interpreter/OptionValueArch.cpp
@@ -74,13 +74,11 @@
 }
 
 size_t OptionValueArch::AutoComplete(CommandInterpreter &interpreter,
-                                     llvm::StringRef s, int match_start_point,
-                                     int max_return_elements,
-                                     bool &word_complete, StringList &matches) {
-  word_complete = false;
-  matches.Clear();
+                                     CompletionRequest &request) {
+  request.SetWordComplete(false);
+  request.GetMatches().Clear();
   CommandCompletions::InvokeCommonCompletionCallbacks(
-      interpreter, CommandCompletions::eArchitectureCompletion, s,
-      match_start_point, max_return_elements, nullptr, word_complete, matches);
-  return matches.GetSize();
+      interpreter, CommandCompletions::eArchitectureCompletion, request,
+      nullptr);
+  return request.GetMatches().GetSize();
 }
Index: lldb/trunk/source/Interpreter/CommandInterpreter.cpp
===================================================================
--- lldb/trunk/source/Interpreter/CommandInterpreter.cpp
+++ lldb/trunk/source/Interpreter/CommandInterpreter.cpp
@@ -1697,14 +1697,10 @@
     // We didn't find the first command object, so complete the first argument.
     Args command_args(command_string);
     StringList matches;
-    int cursor_index = 0;
-    int cursor_char_position = strlen(command_args.GetArgumentAtIndex(0));
-    bool word_complete = true;
-    CompletionRequest request(command_line, cursor_char_position, command_args,
-                              cursor_index, cursor_char_position, 0, -1,
-                              word_complete, matches);
+    unsigned cursor_char_position = strlen(command_args.GetArgumentAtIndex(0));
+    CompletionRequest request(command_line, cursor_char_position, 0, -1,
+                              matches);
     int num_matches = HandleCompletionMatches(request);
-    word_complete = request.GetWordComplete();
 
     if (num_matches > 0) {
       std::string error_msg;
@@ -1791,106 +1787,59 @@
 int CommandInterpreter::HandleCompletion(
     const char *current_line, const char *cursor, const char *last_char,
     int match_start_point, int max_return_elements, StringList &matches) {
-  // We parse the argument up to the cursor, so the last argument in
-  // parsed_line is the one containing the cursor, and the cursor is after the
-  // last character.
 
   llvm::StringRef command_line(current_line, last_char - current_line);
-  Args parsed_line(command_line);
-  Args partial_parsed_line(
-      llvm::StringRef(current_line, cursor - current_line));
+  CompletionRequest request(command_line, cursor - current_line,
+                            match_start_point, max_return_elements, matches);
 
   // Don't complete comments, and if the line we are completing is just the
   // history repeat character, substitute the appropriate history line.
-  const char *first_arg = parsed_line.GetArgumentAtIndex(0);
+  const char *first_arg = request.GetParsedLine().GetArgumentAtIndex(0);
   if (first_arg) {
     if (first_arg[0] == m_comment_char)
       return 0;
     else if (first_arg[0] == CommandHistory::g_repeat_char) {
       if (auto hist_str = m_command_history.FindString(first_arg)) {
-        matches.Clear();
-        matches.InsertStringAtIndex(0, *hist_str);
+        request.GetMatches().Clear();
+        request.GetMatches().InsertStringAtIndex(0, *hist_str);
         return -2;
       } else
         return 0;
     }
   }
 
-  int num_args = partial_parsed_line.GetArgumentCount();
-  int cursor_index = partial_parsed_line.GetArgumentCount() - 1;
-  int cursor_char_position;
-
-  if (cursor_index == -1)
-    cursor_char_position = 0;
-  else
-    cursor_char_position =
-        strlen(partial_parsed_line.GetArgumentAtIndex(cursor_index));
-
-  if (cursor > current_line && cursor[-1] == ' ') {
-    // We are just after a space.  If we are in an argument, then we will
-    // continue parsing, but if we are between arguments, then we have to
-    // complete whatever the next element would be. We can distinguish the two
-    // cases because if we are in an argument (e.g. because the space is
-    // protected by a quote) then the space will also be in the parsed
-    // argument...
-
-    const char *current_elem =
-        partial_parsed_line.GetArgumentAtIndex(cursor_index);
-    if (cursor_char_position == 0 ||
-        current_elem[cursor_char_position - 1] != ' ') {
-      parsed_line.InsertArgumentAtIndex(cursor_index + 1, llvm::StringRef(),
-                                        '\0');
-      cursor_index++;
-      cursor_char_position = 0;
-    }
-  }
-
-  int num_command_matches;
-
-  matches.Clear();
-
   // Only max_return_elements == -1 is supported at present:
   lldbassert(max_return_elements == -1);
-  bool word_complete = false;
-
-  CompletionRequest request(command_line, cursor - current_line, parsed_line,
-                            cursor_index, cursor_char_position,
-                            match_start_point, max_return_elements,
-                            word_complete, matches);
 
-  num_command_matches = HandleCompletionMatches(request);
-  word_complete = request.GetWordComplete();
+  int num_command_matches = HandleCompletionMatches(request);
 
   if (num_command_matches <= 0)
     return num_command_matches;
 
-  if (num_args == 0) {
+  if (request.GetParsedLine().GetArgumentCount() == 0) {
     // If we got an empty string, insert nothing.
     matches.InsertStringAtIndex(0, "");
   } else {
     // Now figure out if there is a common substring, and if so put that in
     // element 0, otherwise put an empty string in element 0.
-    std::string command_partial_str;
-    if (cursor_index >= 0)
-      command_partial_str =
-          parsed_line[cursor_index].ref.take_front(cursor_char_position);
+    std::string command_partial_str = request.GetCursorArgumentPrefix().str();
 
     std::string common_prefix;
     matches.LongestCommonPrefix(common_prefix);
     const size_t partial_name_len = command_partial_str.size();
     common_prefix.erase(0, partial_name_len);
 
     // If we matched a unique single command, add a space... Only do this if
     // the completer told us this was a complete word, however...
-    if (num_command_matches == 1 && word_complete) {
-      char quote_char = parsed_line[cursor_index].quote;
+    if (num_command_matches == 1 && request.GetWordComplete()) {
+      char quote_char = request.GetParsedLine()[request.GetCursorIndex()].quote;
       common_prefix =
           Args::EscapeLLDBCommandArgument(common_prefix, quote_char);
       if (quote_char != '\0')
         common_prefix.push_back(quote_char);
       common_prefix.push_back(' ');
     }
-    matches.InsertStringAtIndex(0, common_prefix.c_str());
+    request.GetMatches().InsertStringAtIndex(0, common_prefix.c_str());
   }
   return num_command_matches;
 }
Index: lldb/trunk/source/Interpreter/OptionValueUUID.cpp
===================================================================
--- lldb/trunk/source/Interpreter/OptionValueUUID.cpp
+++ lldb/trunk/source/Interpreter/OptionValueUUID.cpp
@@ -68,16 +68,15 @@
 }
 
 size_t OptionValueUUID::AutoComplete(CommandInterpreter &interpreter,
-                                     llvm::StringRef s, int match_start_point,
-                                     int max_return_elements,
-                                     bool &word_complete, StringList &matches) {
-  word_complete = false;
-  matches.Clear();
+                                     CompletionRequest &request) {
+  request.SetWordComplete(false);
+  request.GetMatches().Clear();
   ExecutionContext exe_ctx(interpreter.GetExecutionContext());
   Target *target = exe_ctx.GetTargetPtr();
   if (target) {
+    auto prefix = request.GetCursorArgumentPrefix();
     llvm::SmallVector<uint8_t, 20> uuid_bytes;
-    if (UUID::DecodeUUIDBytesFromString(s, uuid_bytes).empty()) {
+    if (UUID::DecodeUUIDBytesFromString(prefix, uuid_bytes).empty()) {
       const size_t num_modules = target->GetImages().GetSize();
       for (size_t i = 0; i < num_modules; ++i) {
         ModuleSP module_sp(target->GetImages().GetModuleAtIndex(i));
@@ -87,12 +86,12 @@
             llvm::ArrayRef<uint8_t> module_bytes = module_uuid.GetBytes();
             if (module_bytes.size() >= uuid_bytes.size() &&
                 module_bytes.take_front(uuid_bytes.size()).equals(uuid_bytes)) {
-              matches.AppendString(module_uuid.GetAsString());
+              request.GetMatches().AppendString(module_uuid.GetAsString());
             }
           }
         }
       }
     }
   }
-  return matches.GetSize();
+  return request.GetMatches().GetSize();
 }
Index: lldb/trunk/source/Interpreter/Options.cpp
===================================================================
--- lldb/trunk/source/Interpreter/Options.cpp
+++ lldb/trunk/source/Interpreter/Options.cpp
@@ -647,29 +647,26 @@
   return options_are_valid;
 }
 
-bool Options::HandleOptionCompletion(
-    Args &input, OptionElementVector &opt_element_vector, int cursor_index,
-    int char_pos, int match_start_point, int max_return_elements,
-    CommandInterpreter &interpreter, bool &word_complete,
-    lldb_private::StringList &matches) {
-  word_complete = true;
+bool Options::HandleOptionCompletion(CompletionRequest &request,
+                                     OptionElementVector &opt_element_vector,
+                                     CommandInterpreter &interpreter) {
+  request.SetWordComplete(true);
 
   // For now we just scan the completions to see if the cursor position is in
   // an option or its argument.  Otherwise we'll call HandleArgumentCompletion.
   // In the future we can use completion to validate options as well if we
   // want.
 
   auto opt_defs = GetDefinitions();
 
-  std::string cur_opt_std_str(input.GetArgumentAtIndex(cursor_index));
-  cur_opt_std_str.erase(char_pos);
+  std::string cur_opt_std_str = request.GetCursorArgumentPrefix().str();
   const char *cur_opt_str = cur_opt_std_str.c_str();
 
   for (size_t i = 0; i < opt_element_vector.size(); i++) {
     int opt_pos = opt_element_vector[i].opt_pos;
     int opt_arg_pos = opt_element_vector[i].opt_arg_pos;
     int opt_defs_index = opt_element_vector[i].opt_defs_index;
-    if (opt_pos == cursor_index) {
+    if (opt_pos == request.GetCursorIndex()) {
       // We're completing the option itself.
 
       if (opt_defs_index == OptionArgElement::eBareDash) {
@@ -683,7 +680,7 @@
           if (!def.short_option)
             continue;
           opt_str[1] = def.short_option;
-          matches.AppendString(opt_str);
+          request.GetMatches().AppendString(opt_str);
         }
 
         return true;
@@ -695,7 +692,7 @@
 
           full_name.erase(full_name.begin() + 2, full_name.end());
           full_name.append(def.long_option);
-          matches.AppendString(full_name.c_str());
+          request.GetMatches().AppendString(full_name.c_str());
         }
         return true;
       } else if (opt_defs_index != OptionArgElement::eUnrecognizedArg) {
@@ -708,10 +705,10 @@
             strcmp(opt_defs[opt_defs_index].long_option, cur_opt_str) != 0) {
           std::string full_name("--");
           full_name.append(opt_defs[opt_defs_index].long_option);
-          matches.AppendString(full_name.c_str());
+          request.GetMatches().AppendString(full_name.c_str());
           return true;
         } else {
-          matches.AppendString(input.GetArgumentAtIndex(cursor_index));
+          request.GetMatches().AppendString(request.GetCursorArgument());
           return true;
         }
       } else {
@@ -734,29 +731,30 @@
               // The options definitions table has duplicates because of the
               // way the grouping information is stored, so only add once.
               bool duplicate = false;
-              for (size_t k = 0; k < matches.GetSize(); k++) {
-                if (matches.GetStringAtIndex(k) == full_name) {
+              for (size_t k = 0; k < request.GetMatches().GetSize(); k++) {
+                if (request.GetMatches().GetStringAtIndex(k) == full_name) {
                   duplicate = true;
                   break;
                 }
               }
               if (!duplicate)
-                matches.AppendString(full_name.c_str());
+                request.GetMatches().AppendString(full_name.c_str());
             }
           }
         }
         return true;
       }
 
-    } else if (opt_arg_pos == cursor_index) {
+    } else if (opt_arg_pos == request.GetCursorIndex()) {
       // Okay the cursor is on the completion of an argument. See if it has a
       // completion, otherwise return no matches.
 
+      CompletionRequest subrequest = request;
+      subrequest.SetCursorCharPosition(subrequest.GetCursorArgument().size());
       if (opt_defs_index != -1) {
-        HandleOptionArgumentCompletion(
-            input, cursor_index, strlen(input.GetArgumentAtIndex(cursor_index)),
-            opt_element_vector, i, match_start_point, max_return_elements,
-            interpreter, word_complete, matches);
+        HandleOptionArgumentCompletion(subrequest, opt_element_vector, i,
+                                       interpreter);
+        request.SetWordComplete(subrequest.GetWordComplete());
         return true;
       } else {
         // No completion callback means no completions...
@@ -772,11 +770,8 @@
 }
 
 bool Options::HandleOptionArgumentCompletion(
-    Args &input, int cursor_index, int char_pos,
-    OptionElementVector &opt_element_vector, int opt_element_index,
-    int match_start_point, int max_return_elements,
-    CommandInterpreter &interpreter, bool &word_complete,
-    lldb_private::StringList &matches) {
+    CompletionRequest &request, OptionElementVector &opt_element_vector,
+    int opt_element_index, CommandInterpreter &interpreter) {
   auto opt_defs = GetDefinitions();
   std::unique_ptr<SearchFilter> filter_ap;
 
@@ -788,12 +783,14 @@
   OptionEnumValueElement *enum_values = opt_defs[opt_defs_index].enum_values;
   if (enum_values != nullptr) {
     bool return_value = false;
-    std::string match_string(input.GetArgumentAtIndex(opt_arg_pos),
-                             input.GetArgumentAtIndex(opt_arg_pos) + char_pos);
+    std::string match_string(
+        request.GetParsedLine().GetArgumentAtIndex(opt_arg_pos),
+        request.GetParsedLine().GetArgumentAtIndex(opt_arg_pos) +
+            request.GetCursorCharPosition());
     for (int i = 0; enum_values[i].string_value != nullptr; i++) {
       if (strstr(enum_values[i].string_value, match_string.c_str()) ==
           enum_values[i].string_value) {
-        matches.AppendString(enum_values[i].string_value);
+        request.GetMatches().AppendString(enum_values[i].string_value);
         return_value = true;
       }
     }
@@ -838,7 +835,8 @@
       // restrict it to that shared library.
       if (cur_opt_name && strcmp(cur_opt_name, "shlib") == 0 &&
           cur_arg_pos != -1) {
-        const char *module_name = input.GetArgumentAtIndex(cur_arg_pos);
+        const char *module_name =
+            request.GetParsedLine().GetArgumentAtIndex(cur_arg_pos);
         if (module_name) {
           FileSpec module_spec(module_name, false);
           lldb::TargetSP target_sp =
@@ -853,9 +851,7 @@
   }
 
   return CommandCompletions::InvokeCommonCompletionCallbacks(
-      interpreter, completion_mask, input.GetArgumentAtIndex(opt_arg_pos),
-      match_start_point, max_return_elements, filter_ap.get(), word_complete,
-      matches);
+      interpreter, completion_mask, request, filter_ap.get());
 }
 
 void OptionGroupOptions::Append(OptionGroup *group) {
Index: lldb/trunk/source/Interpreter/OptionValueFormatEntity.cpp
===================================================================
--- lldb/trunk/source/Interpreter/OptionValueFormatEntity.cpp
+++ lldb/trunk/source/Interpreter/OptionValueFormatEntity.cpp
@@ -105,9 +105,7 @@
   return OptionValueSP(new OptionValueFormatEntity(*this));
 }
 
-size_t OptionValueFormatEntity::AutoComplete(
-    CommandInterpreter &interpreter, llvm::StringRef s, int match_start_point,
-    int max_return_elements, bool &word_complete, StringList &matches) {
-  return FormatEntity::AutoComplete(s, match_start_point, max_return_elements,
-                                    word_complete, matches);
+size_t OptionValueFormatEntity::AutoComplete(CommandInterpreter &interpreter,
+                                             CompletionRequest &request) {
+  return FormatEntity::AutoComplete(request);
 }
Index: lldb/trunk/source/Interpreter/CommandObjectRegexCommand.cpp
===================================================================
--- lldb/trunk/source/Interpreter/CommandObjectRegexCommand.cpp
+++ lldb/trunk/source/Interpreter/CommandObjectRegexCommand.cpp
@@ -95,15 +95,8 @@
 
 int CommandObjectRegexCommand::HandleCompletion(CompletionRequest &request) {
   if (m_completion_type_mask) {
-    std::string completion_str(
-        request.GetParsedLine().GetArgumentAtIndex(request.GetCursorIndex()),
-        request.GetCursorCharPosition());
-    bool word_complete = request.GetWordComplete();
     CommandCompletions::InvokeCommonCompletionCallbacks(
-        GetCommandInterpreter(), m_completion_type_mask, completion_str.c_str(),
-        request.GetMatchStartPoint(), request.GetMaxReturnElements(), nullptr,
-        word_complete, request.GetMatches());
-    request.SetWordComplete(word_complete);
+        GetCommandInterpreter(), m_completion_type_mask, request, nullptr);
     return request.GetMatches().GetSize();
   } else {
     request.GetMatches().Clear();
Index: lldb/trunk/source/Interpreter/OptionValueFileSpec.cpp
===================================================================
--- lldb/trunk/source/Interpreter/OptionValueFileSpec.cpp
+++ lldb/trunk/source/Interpreter/OptionValueFileSpec.cpp
@@ -99,15 +99,13 @@
   return OptionValueSP(new OptionValueFileSpec(*this));
 }
 
-size_t OptionValueFileSpec::AutoComplete(
-    CommandInterpreter &interpreter, llvm::StringRef s, int match_start_point,
-    int max_return_elements, bool &word_complete, StringList &matches) {
-  word_complete = false;
-  matches.Clear();
+size_t OptionValueFileSpec::AutoComplete(CommandInterpreter &interpreter,
+                                         CompletionRequest &request) {
+  request.SetWordComplete(false);
+  request.GetMatches().Clear();
   CommandCompletions::InvokeCommonCompletionCallbacks(
-      interpreter, m_completion_mask, s, match_start_point, max_return_elements,
-      nullptr, word_complete, matches);
-  return matches.GetSize();
+      interpreter, m_completion_mask, request, nullptr);
+  return request.GetMatches().GetSize();
 }
 
 const lldb::DataBufferSP &OptionValueFileSpec::GetFileContents() {
Index: lldb/trunk/source/Commands/CommandObjectCommands.cpp
===================================================================
--- lldb/trunk/source/Commands/CommandObjectCommands.cpp
+++ lldb/trunk/source/Commands/CommandObjectCommands.cpp
@@ -238,16 +238,9 @@
   int HandleArgumentCompletion(
       CompletionRequest &request,
       OptionElementVector &opt_element_vector) override {
-    auto completion_str = request.GetParsedLine()[request.GetCursorIndex()].ref;
-    completion_str = completion_str.take_front(request.GetCursorCharPosition());
-
-    bool word_complete = request.GetWordComplete();
     CommandCompletions::InvokeCommonCompletionCallbacks(
         GetCommandInterpreter(), CommandCompletions::eDiskFileCompletion,
-        completion_str, request.GetMatchStartPoint(),
-        request.GetMaxReturnElements(), nullptr, word_complete,
-        request.GetMatches());
-    request.SetWordComplete(word_complete);
+        request, nullptr);
     return request.GetMatches().GetSize();
   }
 
@@ -1433,17 +1426,9 @@
   int HandleArgumentCompletion(
       CompletionRequest &request,
       OptionElementVector &opt_element_vector) override {
-    llvm::StringRef completion_str =
-        request.GetParsedLine()[request.GetCursorIndex()].ref;
-    completion_str = completion_str.take_front(request.GetCursorCharPosition());
-
-    bool word_complete = request.GetWordComplete();
     CommandCompletions::InvokeCommonCompletionCallbacks(
         GetCommandInterpreter(), CommandCompletions::eDiskFileCompletion,
-        completion_str, request.GetMatchStartPoint(),
-        request.GetMaxReturnElements(), nullptr, word_complete,
-        request.GetMatches());
-    request.SetWordComplete(word_complete);
+        request, nullptr);
     return request.GetMatches().GetSize();
   }
 
Index: lldb/trunk/source/Commands/CommandObjectFrame.cpp
===================================================================
--- lldb/trunk/source/Commands/CommandObjectFrame.cpp
+++ lldb/trunk/source/Commands/CommandObjectFrame.cpp
@@ -467,16 +467,9 @@
       CompletionRequest &request,
       OptionElementVector &opt_element_vector) override {
     // Arguments are the standard source file completer.
-    auto completion_str = request.GetParsedLine()[request.GetCursorIndex()].ref;
-    completion_str = completion_str.take_front(request.GetCursorCharPosition());
-
-    bool word_complete = request.GetWordComplete();
     CommandCompletions::InvokeCommonCompletionCallbacks(
         GetCommandInterpreter(), CommandCompletions::eVariablePathCompletion,
-        completion_str, request.GetMatchStartPoint(),
-        request.GetMaxReturnElements(), nullptr, word_complete,
-        request.GetMatches());
-    request.SetWordComplete(word_complete);
+        request, nullptr);
     return request.GetMatches().GetSize();
   }
 
Index: lldb/trunk/source/Commands/CommandObjectTarget.cpp
===================================================================
--- lldb/trunk/source/Commands/CommandObjectTarget.cpp
+++ lldb/trunk/source/Commands/CommandObjectTarget.cpp
@@ -198,17 +198,9 @@
   int HandleArgumentCompletion(
       CompletionRequest &request,
       OptionElementVector &opt_element_vector) override {
-    std::string completion_str(
-        request.GetParsedLine().GetArgumentAtIndex(request.GetCursorIndex()));
-    completion_str.erase(request.GetCursorCharPosition());
-
-    bool word_complete = request.GetWordComplete();
     CommandCompletions::InvokeCommonCompletionCallbacks(
         GetCommandInterpreter(), CommandCompletions::eDiskFileCompletion,
-        completion_str.c_str(), request.GetMatchStartPoint(),
-        request.GetMaxReturnElements(), nullptr, word_complete,
-        request.GetMatches());
-    request.SetWordComplete(word_complete);
+        request, nullptr);
     return request.GetMatches().GetSize();
   }
 
@@ -1815,18 +1807,9 @@
   int HandleArgumentCompletion(
       CompletionRequest &request,
       OptionElementVector &opt_element_vector) override {
-    // Arguments are the standard module completer.
-    std::string completion_str(
-        request.GetParsedLine().GetArgumentAtIndex(request.GetCursorIndex()));
-    completion_str.erase(request.GetCursorCharPosition());
-
-    bool word_complete = request.GetWordComplete();
     CommandCompletions::InvokeCommonCompletionCallbacks(
-        GetCommandInterpreter(), CommandCompletions::eModuleCompletion,
-        completion_str.c_str(), request.GetMatchStartPoint(),
-        request.GetMaxReturnElements(), nullptr, word_complete,
-        request.GetMatches());
-    request.SetWordComplete(word_complete);
+        GetCommandInterpreter(), CommandCompletions::eModuleCompletion, request,
+        nullptr);
     return request.GetMatches().GetSize();
   }
 };
@@ -1865,18 +1848,9 @@
   int HandleArgumentCompletion(
       CompletionRequest &request,
       OptionElementVector &opt_element_vector) override {
-    // Arguments are the standard source file completer.
-    std::string completion_str(
-        request.GetParsedLine().GetArgumentAtIndex(request.GetCursorIndex()));
-    completion_str.erase(request.GetCursorCharPosition());
-
-    bool word_complete = request.GetWordComplete();
     CommandCompletions::InvokeCommonCompletionCallbacks(
         GetCommandInterpreter(), CommandCompletions::eSourceFileCompletion,
-        completion_str.c_str(), request.GetMatchStartPoint(),
-        request.GetMaxReturnElements(), nullptr, word_complete,
-        request.GetMatches());
-    request.SetWordComplete(word_complete);
+        request, nullptr);
     return request.GetMatches().GetSize();
   }
 };
@@ -2416,17 +2390,9 @@
   int HandleArgumentCompletion(
       CompletionRequest &request,
       OptionElementVector &opt_element_vector) override {
-    std::string completion_str(
-        request.GetParsedLine().GetArgumentAtIndex(request.GetCursorIndex()));
-    completion_str.erase(request.GetCursorCharPosition());
-
-    bool word_complete = request.GetWordComplete();
     CommandCompletions::InvokeCommonCompletionCallbacks(
         GetCommandInterpreter(), CommandCompletions::eDiskFileCompletion,
-        completion_str.c_str(), request.GetMatchStartPoint(),
-        request.GetMaxReturnElements(), nullptr, word_complete,
-        request.GetMatches());
-    request.SetWordComplete(word_complete);
+        request, nullptr);
     return request.GetMatches().GetSize();
   }
 
@@ -4018,17 +3984,9 @@
   int HandleArgumentCompletion(
       CompletionRequest &request,
       OptionElementVector &opt_element_vector) override {
-    std::string completion_str(
-        request.GetParsedLine().GetArgumentAtIndex(request.GetCursorIndex()));
-    completion_str.erase(request.GetCursorCharPosition());
-
-    bool word_complete = request.GetWordComplete();
     CommandCompletions::InvokeCommonCompletionCallbacks(
         GetCommandInterpreter(), CommandCompletions::eDiskFileCompletion,
-        completion_str.c_str(), request.GetMatchStartPoint(),
-        request.GetMaxReturnElements(), nullptr, word_complete,
-        request.GetMatches());
-    request.SetWordComplete(word_complete);
+        request, nullptr);
     return request.GetMatches().GetSize();
   }
 
Index: lldb/trunk/source/Commands/CommandCompletions.cpp
===================================================================
--- lldb/trunk/source/Commands/CommandCompletions.cpp
+++ lldb/trunk/source/Commands/CommandCompletions.cpp
@@ -57,9 +57,7 @@
 
 bool CommandCompletions::InvokeCommonCompletionCallbacks(
     CommandInterpreter &interpreter, uint32_t completion_mask,
-    llvm::StringRef completion_str, int match_start_point,
-    int max_return_elements, SearchFilter *searcher, bool &word_complete,
-    StringList &matches) {
+    CompletionRequest &request, SearchFilter *searcher) {
   bool handled = false;
 
   if (completion_mask & eCustomCompletion)
@@ -72,39 +70,31 @@
                  g_common_completions[i].type &&
              g_common_completions[i].callback != nullptr) {
       handled = true;
-      g_common_completions[i].callback(interpreter, completion_str,
-                                       match_start_point, max_return_elements,
-                                       searcher, word_complete, matches);
+      g_common_completions[i].callback(interpreter, request, searcher);
     }
   }
   return handled;
 }
 
 int CommandCompletions::SourceFiles(CommandInterpreter &interpreter,
-                                    llvm::StringRef partial_file_name,
-                                    int match_start_point,
-                                    int max_return_elements,
-                                    SearchFilter *searcher, bool &word_complete,
-                                    StringList &matches) {
-  word_complete = true;
+                                    CompletionRequest &request,
+                                    SearchFilter *searcher) {
+  request.SetWordComplete(true);
   // Find some way to switch "include support files..."
-  SourceFileCompleter completer(interpreter, false, partial_file_name,
-                                match_start_point, max_return_elements,
-                                matches);
+  SourceFileCompleter completer(interpreter, false, request);
 
   if (searcher == nullptr) {
     lldb::TargetSP target_sp = interpreter.GetDebugger().GetSelectedTarget();
     SearchFilterForUnconstrainedSearches null_searcher(target_sp);
     completer.DoCompletion(&null_searcher);
   } else {
     completer.DoCompletion(searcher);
   }
-  return matches.GetSize();
+  return request.GetMatches().GetSize();
 }
 
 static int DiskFilesOrDirectories(const llvm::Twine &partial_name,
-                                  bool only_directories, bool &saw_directory,
-                                  StringList &matches,
+                                  bool only_directories, StringList &matches,
                                   TildeExpressionResolver &Resolver) {
   matches.Clear();
 
@@ -138,13 +128,12 @@
       // but after that, we're done regardless of any matches.
       if (FirstSep == llvm::StringRef::npos) {
         llvm::StringSet<> MatchSet;
-        saw_directory = Resolver.ResolvePartial(Username, MatchSet);
+        Resolver.ResolvePartial(Username, MatchSet);
         for (const auto &S : MatchSet) {
           Resolved = S.getKey();
           path::append(Resolved, path::get_separator());
           matches.AppendString(Resolved);
         }
-        saw_directory = (matches.GetSize() > 0);
       }
       return matches.GetSize();
     }
@@ -155,7 +144,6 @@
     if (FirstSep == llvm::StringRef::npos) {
       // Make sure it ends with a separator.
       path::append(CompletionBuffer, path::get_separator());
-      saw_directory = true;
       matches.AppendString(CompletionBuffer);
       return 1;
     }
@@ -227,7 +215,6 @@
     CompletionBuffer.append(Name);
 
     if (is_dir) {
-      saw_directory = true;
       path::append(CompletionBuffer, path::get_separator());
     }
 
@@ -238,85 +225,70 @@
 }
 
 int CommandCompletions::DiskFiles(CommandInterpreter &interpreter,
-                                  llvm::StringRef partial_file_name,
-                                  int match_start_point,
-                                  int max_return_elements,
-                                  SearchFilter *searcher, bool &word_complete,
-                                  StringList &matches) {
-  word_complete = false;
+                                  CompletionRequest &request,
+                                  SearchFilter *searcher) {
+  request.SetWordComplete(false);
   StandardTildeExpressionResolver Resolver;
-  return DiskFiles(partial_file_name, matches, Resolver);
+  return DiskFiles(request.GetCursorArgumentPrefix(), request.GetMatches(),
+                   Resolver);
 }
 
 int CommandCompletions::DiskFiles(const llvm::Twine &partial_file_name,
                                   StringList &matches,
                                   TildeExpressionResolver &Resolver) {
-  bool word_complete;
-  int ret_val = DiskFilesOrDirectories(partial_file_name, false, word_complete,
-                                       matches, Resolver);
-  return ret_val;
+  return DiskFilesOrDirectories(partial_file_name, false, matches, Resolver);
 }
 
-int CommandCompletions::DiskDirectories(
-    CommandInterpreter &interpreter, llvm::StringRef partial_file_name,
-    int match_start_point, int max_return_elements, SearchFilter *searcher,
-    bool &word_complete, StringList &matches) {
-  word_complete = false;
+int CommandCompletions::DiskDirectories(CommandInterpreter &interpreter,
+                                        CompletionRequest &request,
+                                        SearchFilter *searcher) {
+  request.SetWordComplete(false);
   StandardTildeExpressionResolver Resolver;
-  return DiskDirectories(partial_file_name, matches, Resolver);
+  return DiskDirectories(request.GetCursorArgumentPrefix(),
+                         request.GetMatches(), Resolver);
 }
 
 int CommandCompletions::DiskDirectories(const llvm::Twine &partial_file_name,
                                         StringList &matches,
                                         TildeExpressionResolver &Resolver) {
-  bool word_complete;
-  int ret_val = DiskFilesOrDirectories(partial_file_name, true, word_complete,
-                                       matches, Resolver);
-  return ret_val;
+  return DiskFilesOrDirectories(partial_file_name, true, matches, Resolver);
 }
 
 int CommandCompletions::Modules(CommandInterpreter &interpreter,
-                                llvm::StringRef partial_file_name,
-                                int match_start_point, int max_return_elements,
-                                SearchFilter *searcher, bool &word_complete,
-                                StringList &matches) {
-  word_complete = true;
-  ModuleCompleter completer(interpreter, partial_file_name, match_start_point,
-                            max_return_elements, matches);
+                                CompletionRequest &request,
+                                SearchFilter *searcher) {
+  request.SetWordComplete(true);
+  ModuleCompleter completer(interpreter, request);
 
   if (searcher == nullptr) {
     lldb::TargetSP target_sp = interpreter.GetDebugger().GetSelectedTarget();
     SearchFilterForUnconstrainedSearches null_searcher(target_sp);
     completer.DoCompletion(&null_searcher);
   } else {
     completer.DoCompletion(searcher);
   }
-  return matches.GetSize();
+  return request.GetMatches().GetSize();
 }
 
 int CommandCompletions::Symbols(CommandInterpreter &interpreter,
-                                llvm::StringRef partial_file_name,
-                                int match_start_point, int max_return_elements,
-                                SearchFilter *searcher, bool &word_complete,
-                                StringList &matches) {
-  word_complete = true;
-  SymbolCompleter completer(interpreter, partial_file_name, match_start_point,
-                            max_return_elements, matches);
+                                CompletionRequest &request,
+                                SearchFilter *searcher) {
+  request.SetWordComplete(true);
+  SymbolCompleter completer(interpreter, request);
 
   if (searcher == nullptr) {
     lldb::TargetSP target_sp = interpreter.GetDebugger().GetSelectedTarget();
     SearchFilterForUnconstrainedSearches null_searcher(target_sp);
     completer.DoCompletion(&null_searcher);
   } else {
     completer.DoCompletion(searcher);
   }
-  return matches.GetSize();
+  return request.GetMatches().GetSize();
 }
 
-int CommandCompletions::SettingsNames(
-    CommandInterpreter &interpreter, llvm::StringRef partial_setting_name,
-    int match_start_point, int max_return_elements, SearchFilter *searcher,
-    bool &word_complete, StringList &matches) {
+int CommandCompletions::SettingsNames(CommandInterpreter &interpreter,
+                                      CompletionRequest &request,
+                                      SearchFilter *searcher) {
   // Cache the full setting name list
   static StringList g_property_names;
   if (g_property_names.GetSize() == 0) {
@@ -332,47 +304,39 @@
   }
 
   size_t exact_matches_idx = SIZE_MAX;
-  const size_t num_matches = g_property_names.AutoComplete(
-      partial_setting_name, matches, exact_matches_idx);
-  word_complete = exact_matches_idx != SIZE_MAX;
+  const size_t num_matches =
+      g_property_names.AutoComplete(request.GetCursorArgumentPrefix(),
+                                    request.GetMatches(), exact_matches_idx);
+  request.SetWordComplete(exact_matches_idx != SIZE_MAX);
   return num_matches;
 }
 
-int CommandCompletions::PlatformPluginNames(
-    CommandInterpreter &interpreter, llvm::StringRef partial_name,
-    int match_start_point, int max_return_elements, SearchFilter *searcher,
-    bool &word_complete, lldb_private::StringList &matches) {
-  const uint32_t num_matches =
-      PluginManager::AutoCompletePlatformName(partial_name, matches);
-  word_complete = num_matches == 1;
+int CommandCompletions::PlatformPluginNames(CommandInterpreter &interpreter,
+                                            CompletionRequest &request,
+                                            SearchFilter *searcher) {
+  const uint32_t num_matches = PluginManager::AutoCompletePlatformName(
+      request.GetCursorArgumentPrefix(), request.GetMatches());
+  request.SetWordComplete(num_matches == 1);
   return num_matches;
 }
 
-int CommandCompletions::ArchitectureNames(
-    CommandInterpreter &interpreter, llvm::StringRef partial_name,
-    int match_start_point, int max_return_elements, SearchFilter *searcher,
-    bool &word_complete, lldb_private::StringList &matches) {
-  const uint32_t num_matches = ArchSpec::AutoComplete(partial_name, matches);
-  word_complete = num_matches == 1;
+int CommandCompletions::ArchitectureNames(CommandInterpreter &interpreter,
+                                          CompletionRequest &request,
+                                          SearchFilter *searcher) {
+  const uint32_t num_matches = ArchSpec::AutoComplete(request);
+  request.SetWordComplete(num_matches == 1);
   return num_matches;
 }
 
-int CommandCompletions::VariablePath(
-    CommandInterpreter &interpreter, llvm::StringRef partial_name,
-    int match_start_point, int max_return_elements, SearchFilter *searcher,
-    bool &word_complete, lldb_private::StringList &matches) {
-  return Variable::AutoComplete(interpreter.GetExecutionContext(), partial_name,
-                                matches, word_complete);
+int CommandCompletions::VariablePath(CommandInterpreter &interpreter,
+                                     CompletionRequest &request,
+                                     SearchFilter *searcher) {
+  return Variable::AutoComplete(interpreter.GetExecutionContext(), request);
 }
 
 CommandCompletions::Completer::Completer(CommandInterpreter &interpreter,
-                                         llvm::StringRef completion_str,
-                                         int match_start_point,
-                                         int max_return_elements,
-                                         StringList &matches)
-    : m_interpreter(interpreter), m_completion_str(completion_str),
-      m_match_start_point(match_start_point),
-      m_max_return_elements(max_return_elements), m_matches(matches) {}
+                                         CompletionRequest &request)
+    : m_interpreter(interpreter), m_request(request) {}
 
 CommandCompletions::Completer::~Completer() = default;
 
@@ -382,13 +346,10 @@
 
 CommandCompletions::SourceFileCompleter::SourceFileCompleter(
     CommandInterpreter &interpreter, bool include_support_files,
-    llvm::StringRef completion_str, int match_start_point,
-    int max_return_elements, StringList &matches)
-    : CommandCompletions::Completer(interpreter, completion_str,
-                                    match_start_point, max_return_elements,
-                                    matches),
+    CompletionRequest &request)
+    : CommandCompletions::Completer(interpreter, request),
       m_include_support_files(include_support_files), m_matching_files() {
-  FileSpec partial_spec(m_completion_str, false);
+  FileSpec partial_spec(m_request.GetCursorArgumentPrefix(), false);
   m_file_name = partial_spec.GetFilename().GetCString();
   m_dir_name = partial_spec.GetDirectory().GetCString();
 }
@@ -448,10 +409,10 @@
   filter->Search(*this);
   // Now convert the filelist to completions:
   for (size_t i = 0; i < m_matching_files.GetSize(); i++) {
-    m_matches.AppendString(
+    m_request.GetMatches().AppendString(
         m_matching_files.GetFileSpecAtIndex(i).GetFilename().GetCString());
   }
-  return m_matches.GetSize();
+  return m_request.GetMatches().GetSize();
 }
 
 //----------------------------------------------------------------------
@@ -466,15 +427,12 @@
 }
 
 CommandCompletions::SymbolCompleter::SymbolCompleter(
-    CommandInterpreter &interpreter, llvm::StringRef completion_str,
-    int match_start_point, int max_return_elements, StringList &matches)
-    : CommandCompletions::Completer(interpreter, completion_str,
-                                    match_start_point, max_return_elements,
-                                    matches) {
+    CommandInterpreter &interpreter, CompletionRequest &request)
+    : CommandCompletions::Completer(interpreter, request) {
   std::string regex_str;
-  if (!completion_str.empty()) {
+  if (!m_request.GetCursorArgumentPrefix().empty()) {
     regex_str.append("^");
-    regex_str.append(completion_str);
+    regex_str.append(m_request.GetCursorArgumentPrefix());
   } else {
     // Match anything since the completion string is empty
     regex_str.append(".");
@@ -520,21 +478,18 @@
   filter->Search(*this);
   collection::iterator pos = m_match_set.begin(), end = m_match_set.end();
   for (pos = m_match_set.begin(); pos != end; pos++)
-    m_matches.AppendString((*pos).GetCString());
+    m_request.GetMatches().AppendString((*pos).GetCString());
 
-  return m_matches.GetSize();
+  return m_request.GetMatches().GetSize();
 }
 
 //----------------------------------------------------------------------
 // ModuleCompleter
 //----------------------------------------------------------------------
 CommandCompletions::ModuleCompleter::ModuleCompleter(
-    CommandInterpreter &interpreter, llvm::StringRef completion_str,
-    int match_start_point, int max_return_elements, StringList &matches)
-    : CommandCompletions::Completer(interpreter, completion_str,
-                                    match_start_point, max_return_elements,
-                                    matches) {
-  FileSpec partial_spec(m_completion_str, false);
+    CommandInterpreter &interpreter, CompletionRequest &request)
+    : CommandCompletions::Completer(interpreter, request) {
+  FileSpec partial_spec(m_request.GetCursorArgumentPrefix(), false);
   m_file_name = partial_spec.GetFilename().GetCString();
   m_dir_name = partial_spec.GetDirectory().GetCString();
 }
@@ -562,13 +517,13 @@
       match = false;
 
     if (match) {
-      m_matches.AppendString(cur_file_name);
+      m_request.GetMatches().AppendString(cur_file_name);
     }
   }
   return Searcher::eCallbackReturnContinue;
 }
 
 size_t CommandCompletions::ModuleCompleter::DoCompletion(SearchFilter *filter) {
   filter->Search(*this);
-  return m_matches.GetSize();
+  return m_request.GetMatches().GetSize();
 }
Index: lldb/trunk/source/Commands/CommandObjectSettings.cpp
===================================================================
--- lldb/trunk/source/Commands/CommandObjectSettings.cpp
+++ lldb/trunk/source/Commands/CommandObjectSettings.cpp
@@ -136,9 +136,6 @@
   int HandleArgumentCompletion(
       CompletionRequest &request,
       OptionElementVector &opt_element_vector) override {
-    std::string completion_str(
-        request.GetParsedLine().GetArgumentAtIndex(request.GetCursorIndex()),
-        request.GetCursorCharPosition());
 
     const size_t argc = request.GetParsedLine().GetArgumentCount();
     const char *arg = nullptr;
@@ -151,13 +148,9 @@
     }
     if (request.GetCursorIndex() == setting_var_idx) {
       // Attempting to complete setting variable name
-      bool word_complete = request.GetWordComplete();
       CommandCompletions::InvokeCommonCompletionCallbacks(
           GetCommandInterpreter(), CommandCompletions::eSettingsNameCompletion,
-          completion_str.c_str(), request.GetMatchStartPoint(),
-          request.GetMaxReturnElements(), nullptr, word_complete,
-          request.GetMatches());
-      request.SetWordComplete(word_complete);
+          request, nullptr);
     } else {
       arg =
           request.GetParsedLine().GetArgumentAtIndex(request.GetCursorIndex());
@@ -174,12 +167,7 @@
               m_interpreter.GetDebugger().GetPropertyValue(
                   &m_exe_ctx, setting_var_name, false, error));
           if (value_sp) {
-            bool word_complete = request.GetWordComplete();
-            value_sp->AutoComplete(m_interpreter, completion_str.c_str(),
-                                   request.GetMatchStartPoint(),
-                                   request.GetMaxReturnElements(),
-                                   word_complete, request.GetMatches());
-            request.SetWordComplete(word_complete);
+            value_sp->AutoComplete(m_interpreter, request);
           }
         }
       }
@@ -281,17 +269,9 @@
   int HandleArgumentCompletion(
       CompletionRequest &request,
       OptionElementVector &opt_element_vector) override {
-    std::string completion_str(
-        request.GetParsedLine().GetArgumentAtIndex(request.GetCursorIndex()),
-        request.GetCursorCharPosition());
-
-    bool word_complete = request.GetWordComplete();
     CommandCompletions::InvokeCommonCompletionCallbacks(
         GetCommandInterpreter(), CommandCompletions::eSettingsNameCompletion,
-        completion_str.c_str(), request.GetMatchStartPoint(),
-        request.GetMaxReturnElements(), nullptr, word_complete,
-        request.GetMatches());
-    request.SetWordComplete(word_complete);
+        request, nullptr);
     return request.GetMatches().GetSize();
   }
 
@@ -355,17 +335,9 @@
   int HandleArgumentCompletion(
       CompletionRequest &request,
       OptionElementVector &opt_element_vector) override {
-    std::string completion_str(
-        request.GetParsedLine().GetArgumentAtIndex(request.GetCursorIndex()),
-        request.GetCursorCharPosition());
-
-    bool word_complete = request.GetWordComplete();
     CommandCompletions::InvokeCommonCompletionCallbacks(
         GetCommandInterpreter(), CommandCompletions::eSettingsNameCompletion,
-        completion_str.c_str(), request.GetMatchStartPoint(),
-        request.GetMaxReturnElements(), nullptr, word_complete,
-        request.GetMatches());
-    request.SetWordComplete(word_complete);
+        request, nullptr);
     return request.GetMatches().GetSize();
   }
 
@@ -451,19 +423,10 @@
   int HandleArgumentCompletion(
       CompletionRequest &request,
       OptionElementVector &opt_element_vector) override {
-    std::string completion_str(
-        request.GetParsedLine().GetArgumentAtIndex(request.GetCursorIndex()),
-        request.GetCursorCharPosition());
-
-    // Attempting to complete variable name
-    bool word_complete = request.GetWordComplete();
     if (request.GetCursorIndex() < 2)
       CommandCompletions::InvokeCommonCompletionCallbacks(
           GetCommandInterpreter(), CommandCompletions::eSettingsNameCompletion,
-          completion_str.c_str(), request.GetMatchStartPoint(),
-          request.GetMaxReturnElements(), nullptr, word_complete,
-          request.GetMatches());
-    request.SetWordComplete(word_complete);
+          request, nullptr);
     return request.GetMatches().GetSize();
   }
 
@@ -575,19 +538,11 @@
   int HandleArgumentCompletion(
       CompletionRequest &request,
       OptionElementVector &opt_element_vector) override {
-    std::string completion_str(
-        request.GetParsedLine().GetArgumentAtIndex(request.GetCursorIndex()),
-        request.GetCursorCharPosition());
-
-    bool word_complete = request.GetWordComplete();
     // Attempting to complete variable name
     if (request.GetCursorIndex() < 2)
       CommandCompletions::InvokeCommonCompletionCallbacks(
           GetCommandInterpreter(), CommandCompletions::eSettingsNameCompletion,
-          completion_str.c_str(), request.GetMatchStartPoint(),
-          request.GetMaxReturnElements(), nullptr, word_complete,
-          request.GetMatches());
-    request.SetWordComplete(word_complete);
+          request, nullptr);
 
     return request.GetMatches().GetSize();
   }
@@ -683,19 +638,11 @@
   int HandleArgumentCompletion(
       CompletionRequest &request,
       OptionElementVector &opt_element_vector) override {
-    std::string completion_str(
-        request.GetParsedLine().GetArgumentAtIndex(request.GetCursorIndex()),
-        request.GetCursorCharPosition());
-
-    bool word_complete = request.GetWordComplete();
     // Attempting to complete variable name
     if (request.GetCursorIndex() < 2)
       CommandCompletions::InvokeCommonCompletionCallbacks(
           GetCommandInterpreter(), CommandCompletions::eSettingsNameCompletion,
-          completion_str.c_str(), request.GetMatchStartPoint(),
-          request.GetMaxReturnElements(), nullptr, word_complete,
-          request.GetMatches());
-    request.SetWordComplete(word_complete);
+          request, nullptr);
 
     return request.GetMatches().GetSize();
   }
@@ -796,19 +743,11 @@
   int HandleArgumentCompletion(
       CompletionRequest &request,
       OptionElementVector &opt_element_vector) override {
-    std::string completion_str(
-        request.GetParsedLine().GetArgumentAtIndex(request.GetCursorIndex()),
-        request.GetCursorCharPosition());
-
-    bool word_complete = request.GetWordComplete();
     // Attempting to complete variable name
     if (request.GetCursorIndex() < 2)
       CommandCompletions::InvokeCommonCompletionCallbacks(
           GetCommandInterpreter(), CommandCompletions::eSettingsNameCompletion,
-          completion_str.c_str(), request.GetMatchStartPoint(),
-          request.GetMaxReturnElements(), nullptr, word_complete,
-          request.GetMatches());
-    request.SetWordComplete(word_complete);
+          request, nullptr);
 
     return request.GetMatches().GetSize();
   }
@@ -898,19 +837,11 @@
   int HandleArgumentCompletion(
       CompletionRequest &request,
       OptionElementVector &opt_element_vector) override {
-    std::string completion_str(
-        request.GetParsedLine().GetArgumentAtIndex(request.GetCursorIndex()),
-        request.GetCursorCharPosition());
-
-    bool word_complete = request.GetWordComplete();
     // Attempting to complete variable name
     if (request.GetCursorIndex() < 2)
       CommandCompletions::InvokeCommonCompletionCallbacks(
           GetCommandInterpreter(), CommandCompletions::eSettingsNameCompletion,
-          completion_str.c_str(), request.GetMatchStartPoint(),
-          request.GetMaxReturnElements(), nullptr, word_complete,
-          request.GetMatches());
-    request.SetWordComplete(word_complete);
+          request, nullptr);
 
     return request.GetMatches().GetSize();
   }
@@ -987,19 +918,11 @@
   int HandleArgumentCompletion(
       CompletionRequest &request,
       OptionElementVector &opt_element_vector) override {
-    std::string completion_str(
-        request.GetParsedLine().GetArgumentAtIndex(request.GetCursorIndex()),
-        request.GetCursorCharPosition());
-
-    bool word_complete = request.GetWordComplete();
     // Attempting to complete variable name
     if (request.GetCursorIndex() < 2)
       CommandCompletions::InvokeCommonCompletionCallbacks(
           GetCommandInterpreter(), CommandCompletions::eSettingsNameCompletion,
-          completion_str.c_str(), request.GetMatchStartPoint(),
-          request.GetMaxReturnElements(), nullptr, word_complete,
-          request.GetMatches());
-    request.SetWordComplete(word_complete);
+          request, nullptr);
 
     return request.GetMatches().GetSize();
   }
Index: lldb/trunk/source/Commands/CommandObjectPlugin.cpp
===================================================================
--- lldb/trunk/source/Commands/CommandObjectPlugin.cpp
+++ lldb/trunk/source/Commands/CommandObjectPlugin.cpp
@@ -45,16 +45,9 @@
   int HandleArgumentCompletion(
       CompletionRequest &request,
       OptionElementVector &opt_element_vector) override {
-    auto completion_str = request.GetParsedLine()[request.GetCursorIndex()].ref;
-    completion_str = completion_str.take_front(request.GetCursorCharPosition());
-
-    bool word_complete = request.GetWordComplete();
     CommandCompletions::InvokeCommonCompletionCallbacks(
         GetCommandInterpreter(), CommandCompletions::eDiskFileCompletion,
-        completion_str, request.GetMatchStartPoint(),
-        request.GetMaxReturnElements(), nullptr, word_complete,
-        request.GetMatches());
-    request.SetWordComplete(word_complete);
+        request, nullptr);
     return request.GetMatches().GetSize();
   }
 
Index: lldb/trunk/source/Commands/CommandObjectPlatform.cpp
===================================================================
--- lldb/trunk/source/Commands/CommandObjectPlatform.cpp
+++ lldb/trunk/source/Commands/CommandObjectPlatform.cpp
@@ -179,16 +179,8 @@
   ~CommandObjectPlatformSelect() override = default;
 
   int HandleCompletion(CompletionRequest &request) override {
-    std::string completion_str(
-        request.GetParsedLine().GetArgumentAtIndex(request.GetCursorIndex()));
-    completion_str.erase(request.GetCursorCharPosition());
-
-    bool word_complete = request.GetWordComplete();
-    CommandCompletions::PlatformPluginNames(
-        GetCommandInterpreter(), completion_str.c_str(),
-        request.GetMatchStartPoint(), request.GetMaxReturnElements(), nullptr,
-        word_complete, request.GetMatches());
-    request.SetWordComplete(word_complete);
+    CommandCompletions::PlatformPluginNames(GetCommandInterpreter(), request,
+                                            nullptr);
     return request.GetMatches().GetSize();
   }
 
@@ -1562,11 +1554,8 @@
     }
 
     bool HandleOptionArgumentCompletion(
-        Args &input, int cursor_index, int char_pos,
-        OptionElementVector &opt_element_vector, int opt_element_index,
-        int match_start_point, int max_return_elements,
-        CommandInterpreter &interpreter, bool &word_complete,
-        StringList &matches) override {
+        CompletionRequest &request, OptionElementVector &opt_element_vector,
+        int opt_element_index, CommandInterpreter &interpreter) override {
       int opt_arg_pos = opt_element_vector[opt_element_index].opt_arg_pos;
       int opt_defs_index = opt_element_vector[opt_element_index].opt_defs_index;
 
@@ -1579,7 +1568,7 @@
         // plugin, otherwise use the default plugin.
 
         const char *partial_name = nullptr;
-        partial_name = input.GetArgumentAtIndex(opt_arg_pos);
+        partial_name = request.GetParsedLine().GetArgumentAtIndex(opt_arg_pos);
 
         PlatformSP platform_sp(interpreter.GetPlatform(true));
         if (platform_sp) {
@@ -1594,7 +1583,7 @@
           const uint32_t num_matches = process_infos.GetSize();
           if (num_matches > 0) {
             for (uint32_t i = 0; i < num_matches; ++i) {
-              matches.AppendString(
+              request.GetMatches().AppendString(
                   process_infos.GetProcessNameAtIndex(i),
                   process_infos.GetProcessNameLengthAtIndex(i));
             }
Index: lldb/trunk/source/Commands/CommandObjectProcess.cpp
===================================================================
--- lldb/trunk/source/Commands/CommandObjectProcess.cpp
+++ lldb/trunk/source/Commands/CommandObjectProcess.cpp
@@ -137,17 +137,10 @@
   int HandleArgumentCompletion(
       CompletionRequest &request,
       OptionElementVector &opt_element_vector) override {
-    std::string completion_str(
-        request.GetParsedLine().GetArgumentAtIndex(request.GetCursorIndex()));
-    completion_str.erase(request.GetCursorCharPosition());
 
-    bool word_complete = request.GetWordComplete();
     CommandCompletions::InvokeCommonCompletionCallbacks(
         GetCommandInterpreter(), CommandCompletions::eDiskFileCompletion,
-        completion_str.c_str(), request.GetMatchStartPoint(),
-        request.GetMaxReturnElements(), nullptr, word_complete,
-        request.GetMatches());
-    request.SetWordComplete(word_complete);
+        request, nullptr);
     return request.GetMatches().GetSize();
   }
 
@@ -388,11 +381,8 @@
     }
 
     bool HandleOptionArgumentCompletion(
-        Args &input, int cursor_index, int char_pos,
-        OptionElementVector &opt_element_vector, int opt_element_index,
-        int match_start_point, int max_return_elements,
-        CommandInterpreter &interpreter, bool &word_complete,
-        StringList &matches) override {
+        CompletionRequest &request, OptionElementVector &opt_element_vector,
+        int opt_element_index, CommandInterpreter &interpreter) override {
       int opt_arg_pos = opt_element_vector[opt_element_index].opt_arg_pos;
       int opt_defs_index = opt_element_vector[opt_element_index].opt_defs_index;
 
@@ -405,7 +395,7 @@
         // plugin, otherwise use the default plugin.
 
         const char *partial_name = nullptr;
-        partial_name = input.GetArgumentAtIndex(opt_arg_pos);
+        partial_name = request.GetParsedLine().GetArgumentAtIndex(opt_arg_pos);
 
         PlatformSP platform_sp(interpreter.GetPlatform(true));
         if (platform_sp) {
@@ -420,7 +410,7 @@
           const size_t num_matches = process_infos.GetSize();
           if (num_matches > 0) {
             for (size_t i = 0; i < num_matches; ++i) {
-              matches.AppendString(
+              request.GetMatches().AppendString(
                   process_infos.GetProcessNameAtIndex(i),
                   process_infos.GetProcessNameLengthAtIndex(i));
             }
_______________________________________________
lldb-commits mailing list
lldb-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits

Reply via email to