[lldb][NFC] Remove WordComplete mode, make result array indexed from 0 and remove any undocumented/redundant return values

Summary:
We still have some leftovers of the old completion API in the internals of
LLDB that haven't been replaced by the new CompletionRequest. These leftovers
are:

* The return values (int/size_t) in all completion functions.
* Our result array that starts indexing at 1.
* `WordComplete` mode.

I didn't replace them back then because it's tricky to figure out what exactly they
are used for and the completion code is relatively untested. I finally got around
to writing more tests for the API and understanding the semantics, so I think it's
a good time to get rid of them.

A few words why those things should be removed/replaced:

* The return values are really cryptic, partly redundant and rarely documented.
  They are also completely ignored by Xcode, so whatever information they contain will end up
  breaking Xcode's completion mechanism. They are also partly impossible to even implement
  as we assign negative values special meaning and our completion API sometimes returns size_t.

  Completion functions are supposed to return -2 to rewrite the current line. We seem to use this
  in some untested code path to expand the history repeat character to the full command, but
  I haven't figured out why that doesn't work at the moment.
  Completion functions return -1 to 'insert the completion character', but that isn't implemented
  (even though we seem to activate this feature in LLDB sometimes).
  All positive values have to match the number of results. This is obviously just redundant information
  as the user can just look at the result list to get that information (which is what Xcode does).

* The result array that starts indexing at 1 is obviously unexpected. The first element of the array is
  reserved for the common prefix of all completions (e.g. "foobar" and "footar" -> "foo"). The idea is
  that we calculate this to make the life of the API caller easier, but obviously forcing people to have
  1-based indices is not helpful (or even worse, forces them to manually copy the results to make it
  0-based like Xcode has to do).

* The `WordComplete` mode indicates that LLDB should enter a space behind the completion. The
  idea is that we let the top-level API know that we just provided a full completion. Interestingly we
  `WordComplete` is just a single bool that somehow represents all N completions. And we always
  provide full completions in LLDB, so in theory it should always be true.
  The only use it currently serves is providing redundant information about whether we have a single
  definitive completion or not (which we already know from the number of results we get).

This patch essentially removes `WordComplete` mode and makes the result array indexed from 0.
It also removes all return values from all internal completion functions. The only non-redundant information
they contain is about rewriting the current line (which is broken), so that functionality was moved
to the CompletionRequest API. So you can now do `addCompletion("blub", "description", CompletionMode::RewriteLine)`
to do the same.

For the SB API we emulate the old behaviour by making the array indexed from 1 again with the common
prefix at index 0. I didn't keep the special negative return codes as we either never sent them before (e.g. -2) or we
didn't even implement them in the Editline handler (e.g. -1).

I tried to keep this patch minimal and I'm aware we can probably now even further simplify a bunch of related code,
but I would prefer doing this in follow-up NFC commits

Reviewers: JDevlieghere

Reviewed By: JDevlieghere

Subscribers: arphaman, abidh, lldb-commits

Tags: #lldb

Differential Revision: https://reviews.llvm.org/D66536

llvm-svn: 369624
This commit is contained in:
Raphael Isemann 2019-08-22 07:41:23 +00:00
parent 028b5499ff
commit ae34ed2c0d
57 changed files with 481 additions and 638 deletions

View File

@ -199,7 +199,7 @@ public:
llvm::StringRef &variable_name,
llvm::StringRef &variable_format);
static size_t AutoComplete(lldb_private::CompletionRequest &request);
static void AutoComplete(lldb_private::CompletionRequest &request);
// Format the current elements into the stream \a s.
//

View File

@ -199,8 +199,8 @@ public:
virtual void IOHandlerDeactivated(IOHandler &io_handler) {}
virtual int IOHandlerComplete(IOHandler &io_handler,
CompletionRequest &request);
virtual void IOHandlerComplete(IOHandler &io_handler,
CompletionRequest &request);
virtual const char *IOHandlerGetFixIndentationCharacters() { return nullptr; }
@ -414,7 +414,7 @@ private:
static int FixIndentationCallback(Editline *editline, const StringList &lines,
int cursor_position, void *baton);
static int AutoCompleteCallback(CompletionRequest &request, void *baton);
static void AutoCompleteCallback(CompletionRequest &request, void *baton);
#endif
protected:
@ -445,8 +445,8 @@ public:
bool GetResponse() const { return m_user_response; }
int IOHandlerComplete(IOHandler &io_handler,
CompletionRequest &request) override;
void IOHandlerComplete(IOHandler &io_handler,
CompletionRequest &request) override;
void IOHandlerInputComplete(IOHandler &io_handler,
std::string &data) override;

View File

@ -10,6 +10,7 @@
#define liblldb_PluginManager_h_
#include "lldb/Core/Architecture.h"
#include "lldb/Utility/CompletionRequest.h"
#include "lldb/Utility/FileSpec.h"
#include "lldb/Utility/Status.h"
#include "lldb/lldb-enumerations.h"
@ -228,8 +229,8 @@ public:
static const char *GetPlatformPluginDescriptionAtIndex(uint32_t idx);
static size_t AutoCompletePlatformName(llvm::StringRef partial_name,
StringList &matches);
static void AutoCompletePlatformName(llvm::StringRef partial_name,
CompletionRequest &request);
// Process
static bool
RegisterPlugin(ConstString name, const char *description,

View File

@ -103,8 +103,8 @@ public:
void IOHandlerInputComplete(IOHandler &io_handler,
std::string &line) override;
int IOHandlerComplete(IOHandler &io_handler,
CompletionRequest &request) override;
void IOHandlerComplete(IOHandler &io_handler,
CompletionRequest &request) override;
protected:
static int CalculateActualIndentation(const StringList &lines);

View File

@ -98,7 +98,7 @@ typedef int (*FixIndentationCallbackType)(Editline *editline,
const StringList &lines,
int cursor_position, void *baton);
typedef int (*CompleteCallbackType)(CompletionRequest &request, void *baton);
typedef void (*CompleteCallbackType)(CompletionRequest &request, void *baton);
/// Status used to decide when and how to start editing another line in
/// multi-line sessions

View File

@ -36,11 +36,11 @@ public:
bool WantsCompletion() override;
int HandleCompletion(CompletionRequest &request) override;
void HandleCompletion(CompletionRequest &request) override;
int HandleArgumentCompletion(
CompletionRequest &request,
OptionElementVector &opt_element_vector) override;
void
HandleArgumentCompletion(CompletionRequest &request,
OptionElementVector &opt_element_vector) override;
Options *GetOptions() override;

View File

@ -26,10 +26,10 @@ public:
// This is the command completion callback that is used to complete the
// argument of the option it is bound to (in the OptionDefinition table
// below). Return the total number of matches.
typedef int (*CompletionCallback)(CommandInterpreter &interpreter,
CompletionRequest &request,
// A search filter to limit the search...
lldb_private::SearchFilter *searcher);
typedef void (*CompletionCallback)(CommandInterpreter &interpreter,
CompletionRequest &request,
// A search filter to limit the search...
lldb_private::SearchFilter *searcher);
enum CommonCompletionTypes {
eNoCompletion = 0u,
eSourceFileCompletion = (1u << 0),
@ -57,43 +57,43 @@ public:
lldb_private::CompletionRequest &request, SearchFilter *searcher);
// These are the generic completer functions:
static int DiskFiles(CommandInterpreter &interpreter,
CompletionRequest &request, SearchFilter *searcher);
static void DiskFiles(CommandInterpreter &interpreter,
CompletionRequest &request, SearchFilter *searcher);
static int DiskFiles(const llvm::Twine &partial_file_name,
StringList &matches, TildeExpressionResolver &Resolver);
static void DiskFiles(const llvm::Twine &partial_file_name,
StringList &matches, TildeExpressionResolver &Resolver);
static int DiskDirectories(CommandInterpreter &interpreter,
CompletionRequest &request,
SearchFilter *searcher);
static void DiskDirectories(CommandInterpreter &interpreter,
CompletionRequest &request,
SearchFilter *searcher);
static int DiskDirectories(const llvm::Twine &partial_file_name,
StringList &matches,
TildeExpressionResolver &Resolver);
static void DiskDirectories(const llvm::Twine &partial_file_name,
StringList &matches,
TildeExpressionResolver &Resolver);
static int SourceFiles(CommandInterpreter &interpreter,
CompletionRequest &request, SearchFilter *searcher);
static int Modules(CommandInterpreter &interpreter,
CompletionRequest &request, SearchFilter *searcher);
static int Symbols(CommandInterpreter &interpreter,
CompletionRequest &request, SearchFilter *searcher);
static int SettingsNames(CommandInterpreter &interpreter,
CompletionRequest &request, SearchFilter *searcher);
static int PlatformPluginNames(CommandInterpreter &interpreter,
CompletionRequest &request,
SearchFilter *searcher);
static int ArchitectureNames(CommandInterpreter &interpreter,
CompletionRequest &request,
SearchFilter *searcher);
static int VariablePath(CommandInterpreter &interpreter,
static void SourceFiles(CommandInterpreter &interpreter,
CompletionRequest &request, SearchFilter *searcher);
static void Modules(CommandInterpreter &interpreter,
CompletionRequest &request, SearchFilter *searcher);
static void Symbols(CommandInterpreter &interpreter,
CompletionRequest &request, SearchFilter *searcher);
static void SettingsNames(CommandInterpreter &interpreter,
CompletionRequest &request, SearchFilter *searcher);
static void PlatformPluginNames(CommandInterpreter &interpreter,
CompletionRequest &request,
SearchFilter *searcher);
static void ArchitectureNames(CommandInterpreter &interpreter,
CompletionRequest &request,
SearchFilter *searcher);
static void VariablePath(CommandInterpreter &interpreter,
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 {
@ -107,7 +107,7 @@ public:
lldb::SearchDepth GetDepth() override = 0;
virtual size_t DoCompletion(SearchFilter *filter) = 0;
virtual void DoCompletion(SearchFilter *filter) = 0;
protected:
CommandInterpreter &m_interpreter;
@ -130,7 +130,7 @@ public:
Address *addr,
bool complete) override;
size_t DoCompletion(SearchFilter *filter) override;
void DoCompletion(SearchFilter *filter) override;
private:
bool m_include_support_files;
@ -154,7 +154,7 @@ public:
Address *addr,
bool complete) override;
size_t DoCompletion(SearchFilter *filter) override;
void DoCompletion(SearchFilter *filter) override;
private:
const char *m_file_name;
@ -176,7 +176,7 @@ public:
Address *addr,
bool complete) override;
size_t DoCompletion(SearchFilter *filter) override;
void DoCompletion(SearchFilter *filter) override;
private:
RegularExpression m_regex;

View File

@ -308,18 +308,12 @@ public:
CommandObject *GetCommandObjectForCommand(llvm::StringRef &command_line);
// This handles command line completion. Returns: -1
// if the completion character should be inserted -2 if the entire command
// line should be deleted and replaced with matches.GetStringAtIndex(0)
// INT_MAX if the number of matches is > max_return_elements, but it is
// expensive to compute. Otherwise, returns the number of matches.
//
// FIXME: Only max_return_elements == -1 is supported at present.
int HandleCompletion(CompletionRequest &request);
// This handles command line completion.
void HandleCompletion(CompletionRequest &request);
// This version just returns matches, and doesn't compute the substring. It
// is here so the Help command can call it for the first argument.
int HandleCompletionMatches(CompletionRequest &request);
void HandleCompletionMatches(CompletionRequest &request);
int GetCommandNamesMatchingPartialString(const char *cmd_cstr,
bool include_aliases,

View File

@ -232,10 +232,7 @@ public:
/// 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.
virtual int HandleCompletion(CompletionRequest &request);
virtual void HandleCompletion(CompletionRequest &request);
/// The input array contains a parsed version of the line. The insertion
/// point is given by cursor_index (the index in input of the word containing
@ -250,14 +247,9 @@ public:
/// 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
/// The number of completions.
virtual int
virtual void
HandleArgumentCompletion(CompletionRequest &request,
OptionElementVector &opt_element_vector) {
return 0;
}
OptionElementVector &opt_element_vector) {}
bool HelpTextContainsWord(llvm::StringRef search_word,
bool search_short_help = true,

View File

@ -50,7 +50,7 @@ public:
bool WantsRawCommandString() override { return false; }
int HandleCompletion(CompletionRequest &request) override;
void HandleCompletion(CompletionRequest &request) override;
const char *GetRepeatCommand(Args &current_command_args,
uint32_t index) override;
@ -112,11 +112,11 @@ public:
Options *GetOptions() override;
int HandleCompletion(CompletionRequest &request) override;
void HandleCompletion(CompletionRequest &request) override;
int HandleArgumentCompletion(
CompletionRequest &request,
OptionElementVector &opt_element_vector) override;
void
HandleArgumentCompletion(CompletionRequest &request,
OptionElementVector &opt_element_vector) override;
const char *GetRepeatCommand(Args &current_command_args,
uint32_t index) override;

View File

@ -34,7 +34,7 @@ public:
bool HasRegexEntries() const { return !m_entries.empty(); }
int HandleCompletion(CompletionRequest &request) override;
void HandleCompletion(CompletionRequest &request) override;
protected:
bool DoExecute(llvm::StringRef command, CommandReturnObject &result) override;

View File

@ -93,8 +93,8 @@ public:
virtual lldb::OptionValueSP DeepCopy() const = 0;
virtual size_t AutoComplete(CommandInterpreter &interpreter,
CompletionRequest &request);
virtual void AutoComplete(CommandInterpreter &interpreter,
CompletionRequest &request);
// Subclasses can override these functions
virtual lldb::OptionValueSP GetSubValue(const ExecutionContext *exe_ctx,

View File

@ -55,8 +55,8 @@ public:
lldb::OptionValueSP DeepCopy() const override;
size_t AutoComplete(CommandInterpreter &interpreter,
lldb_private::CompletionRequest &request) override;
void AutoComplete(CommandInterpreter &interpreter,
lldb_private::CompletionRequest &request) override;
// Subclass specific functions

View File

@ -43,8 +43,8 @@ public:
return true;
}
size_t AutoComplete(CommandInterpreter &interpreter,
CompletionRequest &request) override;
void AutoComplete(CommandInterpreter &interpreter,
CompletionRequest &request) override;
// Subclass specific functions

View File

@ -55,8 +55,8 @@ public:
lldb::OptionValueSP DeepCopy() const override;
size_t AutoComplete(CommandInterpreter &interpreter,
CompletionRequest &request) override;
void AutoComplete(CommandInterpreter &interpreter,
CompletionRequest &request) override;
// Subclass specific functions

View File

@ -51,8 +51,8 @@ public:
lldb::OptionValueSP DeepCopy() const override;
size_t AutoComplete(CommandInterpreter &interpreter,
CompletionRequest &request) override;
void AutoComplete(CommandInterpreter &interpreter,
CompletionRequest &request) override;
// Subclass specific functions

View File

@ -38,8 +38,8 @@ public:
lldb::OptionValueSP DeepCopy() const override;
size_t AutoComplete(CommandInterpreter &interpreter,
CompletionRequest &request) override;
void AutoComplete(CommandInterpreter &interpreter,
CompletionRequest &request) override;
// Subclass specific functions

View File

@ -52,8 +52,8 @@ public:
void SetCurrentValue(const UUID &value) { m_uuid = value; }
size_t AutoComplete(CommandInterpreter &interpreter,
CompletionRequest &request) override;
void AutoComplete(CommandInterpreter &interpreter,
CompletionRequest &request) override;
protected:
UUID m_uuid;

View File

@ -99,8 +99,8 @@ public:
GetVariableCallback callback, void *baton, VariableList &variable_list,
ValueObjectList &valobj_list);
static size_t AutoComplete(const ExecutionContext &exe_ctx,
CompletionRequest &request);
static void AutoComplete(const ExecutionContext &exe_ctx,
CompletionRequest &request);
CompilerDeclContext GetDeclContext();

View File

@ -268,7 +268,7 @@ public:
static bool ContainsOnlyArch(const llvm::Triple &normalized_triple);
static void ListSupportedArchNames(StringList &list);
static size_t AutoComplete(CompletionRequest &request);
static void AutoComplete(CompletionRequest &request);
/// Returns a static string representing the current architecture.
///

View File

@ -16,25 +16,45 @@
#include "llvm/ADT/StringSet.h"
namespace lldb_private {
enum class CompletionMode {
Normal,
// The full line has been rewritten by the completion.
RewriteLine,
};
class CompletionResult {
public:
/// A single completion and all associated data.
struct Completion {
Completion(llvm::StringRef completion, llvm::StringRef description)
: m_completion(completion.str()), m_descripton(description.str()) {}
class Completion {
std::string m_completion;
std::string m_descripton;
CompletionMode m_mode;
public:
Completion(llvm::StringRef completion, llvm::StringRef description,
CompletionMode mode)
: m_completion(completion.str()), m_descripton(description.str()),
m_mode(mode) {}
const std::string &GetCompletion() const { return m_completion; }
const std::string &GetDescription() const { return m_descripton; }
CompletionMode GetMode() const { return m_mode; }
/// Generates a string that uniquely identifies this completion result.
std::string GetUniqueKey() const;
};
private:
std::vector<Completion> m_results;
/// List of added completions so far. Used to filter out duplicates.
llvm::StringSet<> m_added_values;
public:
void AddResult(llvm::StringRef completion, llvm::StringRef description);
void AddResult(llvm::StringRef completion, llvm::StringRef description,
CompletionMode mode);
llvm::ArrayRef<Completion> GetResults() const { return m_results; }
/// Adds all collected completion matches to the given list.
/// The list will be cleared before the results are added. The number of
@ -87,16 +107,16 @@ public:
const Args &GetPartialParsedLine() const { return m_partial_parsed_line; }
const Args::ArgEntry &GetParsedArg() {
return GetParsedLine()[GetCursorIndex()];
}
void SetCursorIndex(int i) { m_cursor_index = i; }
int GetCursorIndex() const { return m_cursor_index; }
void SetCursorCharPosition(int pos) { m_cursor_char_position = pos; }
int GetCursorCharPosition() const { return m_cursor_char_position; }
bool GetWordComplete() { return m_word_complete; }
void SetWordComplete(bool v) { m_word_complete = v; }
/// Adds a possible completion string. If the completion was already
/// suggested before, it will not be added to the list of results. A copy of
/// the suggested completion is stored, so the given string can be free'd
@ -106,8 +126,9 @@ public:
/// \param match An optional description of the completion string. The
/// description will be displayed to the user alongside the completion.
void AddCompletion(llvm::StringRef completion,
llvm::StringRef description = "") {
m_result.AddResult(completion, description);
llvm::StringRef description = "",
CompletionMode mode = CompletionMode::Normal) {
m_result.AddResult(completion, description, mode);
}
/// Adds multiple possible completion strings.
@ -136,10 +157,6 @@ public:
descriptions.GetStringAtIndex(i));
}
std::size_t GetNumberOfMatches() const {
return m_result.GetNumberOfResults();
}
llvm::StringRef GetCursorArgument() const {
return GetParsedLine().GetArgumentAtIndex(GetCursorIndex());
}
@ -161,9 +178,6 @@ private:
int m_cursor_index;
/// The cursor position in the argument indexed by m_cursor_index.
int m_cursor_char_position;
/// \btrue if this is a complete option value (a space will be inserted
/// after the completion.) \bfalse otherwise.
bool m_word_complete = false;
/// The result this request is supposed to fill out.
/// We keep this object private to ensure that no backend can in any way

View File

@ -353,8 +353,6 @@ int SBCommandInterpreter::HandleCompletionWithDescriptions(
current_line, cursor, last_char, match_start_point,
max_return_elements, matches, descriptions);
int num_completions = 0;
// Sanity check the arguments that are passed in: cursor & last_char have to
// be within the current_line.
if (current_line == nullptr || cursor == nullptr || last_char == nullptr)
@ -368,22 +366,50 @@ int SBCommandInterpreter::HandleCompletionWithDescriptions(
last_char - current_line > static_cast<ptrdiff_t>(current_line_size))
return 0;
if (!IsValid())
return 0;
if (IsValid()) {
lldb_private::StringList lldb_matches, lldb_descriptions;
CompletionResult result;
CompletionRequest request(current_line, cursor - current_line, result);
num_completions = m_opaque_ptr->HandleCompletion(request);
result.GetMatches(lldb_matches);
result.GetDescriptions(lldb_descriptions);
lldb_private::StringList lldb_matches, lldb_descriptions;
CompletionResult result;
CompletionRequest request(current_line, cursor - current_line, result);
m_opaque_ptr->HandleCompletion(request);
result.GetMatches(lldb_matches);
result.GetDescriptions(lldb_descriptions);
SBStringList temp_matches_list(&lldb_matches);
matches.AppendList(temp_matches_list);
SBStringList temp_descriptions_list(&lldb_descriptions);
descriptions.AppendList(temp_descriptions_list);
// Make the result array indexed from 1 again by adding the 'common prefix'
// of all completions as element 0. This is done to emulate the old API.
if (request.GetParsedLine().GetArgumentCount() == 0) {
// If we got an empty string, insert nothing.
lldb_matches.InsertStringAtIndex(0, "");
lldb_descriptions.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 = request.GetCursorArgumentPrefix().str();
std::string common_prefix = lldb_matches.LongestCommonPrefix();
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 (lldb_matches.GetSize() == 1) {
char quote_char = request.GetParsedArg().quote;
common_prefix =
Args::EscapeLLDBCommandArgument(common_prefix, quote_char);
if (request.GetParsedArg().IsQuoted())
common_prefix.push_back(quote_char);
common_prefix.push_back(' ');
}
lldb_matches.InsertStringAtIndex(0, common_prefix.c_str());
lldb_descriptions.InsertStringAtIndex(0, "");
}
return num_completions;
SBStringList temp_matches_list(&lldb_matches);
matches.AppendList(temp_matches_list);
SBStringList temp_descriptions_list(&lldb_descriptions);
descriptions.AppendList(temp_descriptions_list);
return result.GetNumberOfResults();
}
int SBCommandInterpreter::HandleCompletionWithDescriptions(

View File

@ -71,10 +71,9 @@ bool CommandCompletions::InvokeCommonCompletionCallbacks(
return handled;
}
int CommandCompletions::SourceFiles(CommandInterpreter &interpreter,
CompletionRequest &request,
SearchFilter *searcher) {
request.SetWordComplete(true);
void CommandCompletions::SourceFiles(CommandInterpreter &interpreter,
CompletionRequest &request,
SearchFilter *searcher) {
// Find some way to switch "include support files..."
SourceFileCompleter completer(interpreter, false, request);
@ -85,12 +84,11 @@ int CommandCompletions::SourceFiles(CommandInterpreter &interpreter,
} else {
completer.DoCompletion(searcher);
}
return request.GetNumberOfMatches();
}
static int DiskFilesOrDirectories(const llvm::Twine &partial_name,
bool only_directories, StringList &matches,
TildeExpressionResolver &Resolver) {
static void DiskFilesOrDirectories(const llvm::Twine &partial_name,
bool only_directories, StringList &matches,
TildeExpressionResolver &Resolver) {
matches.Clear();
llvm::SmallString<256> CompletionBuffer;
@ -98,7 +96,7 @@ static int DiskFilesOrDirectories(const llvm::Twine &partial_name,
partial_name.toVector(CompletionBuffer);
if (CompletionBuffer.size() >= PATH_MAX)
return matches.GetSize();
return;
namespace path = llvm::sys::path;
@ -129,7 +127,7 @@ static int DiskFilesOrDirectories(const llvm::Twine &partial_name,
matches.AppendString(Resolved);
}
}
return matches.GetSize();
return;
}
// If there was no trailing slash, then we're done as soon as we resolve
@ -139,7 +137,7 @@ static int DiskFilesOrDirectories(const llvm::Twine &partial_name,
// Make sure it ends with a separator.
path::append(CompletionBuffer, path::get_separator());
matches.AppendString(CompletionBuffer);
return matches.GetSize();
return;
}
// We want to keep the form the user typed, so we special case this to
@ -221,49 +219,44 @@ static int DiskFilesOrDirectories(const llvm::Twine &partial_name,
matches.AppendString(CompletionBuffer);
}
return matches.GetSize();
}
static int DiskFilesOrDirectories(CompletionRequest &request,
bool only_directories) {
request.SetWordComplete(false);
static void DiskFilesOrDirectories(CompletionRequest &request,
bool only_directories) {
StandardTildeExpressionResolver resolver;
StringList matches;
DiskFilesOrDirectories(request.GetCursorArgumentPrefix(), only_directories,
matches, resolver);
request.AddCompletions(matches);
return request.GetNumberOfMatches();
}
int CommandCompletions::DiskFiles(CommandInterpreter &interpreter,
CompletionRequest &request,
SearchFilter *searcher) {
return DiskFilesOrDirectories(request, /*only_dirs*/ false);
void CommandCompletions::DiskFiles(CommandInterpreter &interpreter,
CompletionRequest &request,
SearchFilter *searcher) {
DiskFilesOrDirectories(request, /*only_dirs*/ false);
}
int CommandCompletions::DiskFiles(const llvm::Twine &partial_file_name,
StringList &matches,
TildeExpressionResolver &Resolver) {
return DiskFilesOrDirectories(partial_file_name, false, matches, Resolver);
void CommandCompletions::DiskFiles(const llvm::Twine &partial_file_name,
StringList &matches,
TildeExpressionResolver &Resolver) {
DiskFilesOrDirectories(partial_file_name, false, matches, Resolver);
}
int CommandCompletions::DiskDirectories(CommandInterpreter &interpreter,
CompletionRequest &request,
SearchFilter *searcher) {
return DiskFilesOrDirectories(request, /*only_dirs*/ true);
void CommandCompletions::DiskDirectories(CommandInterpreter &interpreter,
CompletionRequest &request,
SearchFilter *searcher) {
DiskFilesOrDirectories(request, /*only_dirs*/ true);
}
int CommandCompletions::DiskDirectories(const llvm::Twine &partial_file_name,
StringList &matches,
TildeExpressionResolver &Resolver) {
return DiskFilesOrDirectories(partial_file_name, true, matches, Resolver);
void CommandCompletions::DiskDirectories(const llvm::Twine &partial_file_name,
StringList &matches,
TildeExpressionResolver &Resolver) {
DiskFilesOrDirectories(partial_file_name, true, matches, Resolver);
}
int CommandCompletions::Modules(CommandInterpreter &interpreter,
CompletionRequest &request,
SearchFilter *searcher) {
request.SetWordComplete(true);
void CommandCompletions::Modules(CommandInterpreter &interpreter,
CompletionRequest &request,
SearchFilter *searcher) {
ModuleCompleter completer(interpreter, request);
if (searcher == nullptr) {
@ -273,13 +266,11 @@ int CommandCompletions::Modules(CommandInterpreter &interpreter,
} else {
completer.DoCompletion(searcher);
}
return request.GetNumberOfMatches();
}
int CommandCompletions::Symbols(CommandInterpreter &interpreter,
CompletionRequest &request,
SearchFilter *searcher) {
request.SetWordComplete(true);
void CommandCompletions::Symbols(CommandInterpreter &interpreter,
CompletionRequest &request,
SearchFilter *searcher) {
SymbolCompleter completer(interpreter, request);
if (searcher == nullptr) {
@ -289,12 +280,11 @@ int CommandCompletions::Symbols(CommandInterpreter &interpreter,
} else {
completer.DoCompletion(searcher);
}
return request.GetNumberOfMatches();
}
int CommandCompletions::SettingsNames(CommandInterpreter &interpreter,
CompletionRequest &request,
SearchFilter *searcher) {
void 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) {
@ -309,44 +299,29 @@ int CommandCompletions::SettingsNames(CommandInterpreter &interpreter,
}
}
bool exact_match = false;
for (const std::string &s : g_property_names) {
if (llvm::StringRef(s).startswith(request.GetCursorArgumentPrefix())) {
if (request.GetCursorArgumentPrefix() == s)
exact_match = true;
if (llvm::StringRef(s).startswith(request.GetCursorArgumentPrefix()))
request.AddCompletion(s);
}
}
request.SetWordComplete(exact_match);
return request.GetNumberOfMatches();
}
int CommandCompletions::PlatformPluginNames(CommandInterpreter &interpreter,
CompletionRequest &request,
SearchFilter *searcher) {
StringList new_matches;
std::size_t num_matches = PluginManager::AutoCompletePlatformName(
request.GetCursorArgumentPrefix(), new_matches);
request.SetWordComplete(num_matches == 1);
request.AddCompletions(new_matches);
return request.GetNumberOfMatches();
void CommandCompletions::PlatformPluginNames(CommandInterpreter &interpreter,
CompletionRequest &request,
SearchFilter *searcher) {
PluginManager::AutoCompletePlatformName(request.GetCursorArgumentPrefix(),
request);
}
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;
void CommandCompletions::ArchitectureNames(CommandInterpreter &interpreter,
CompletionRequest &request,
SearchFilter *searcher) {
ArchSpec::AutoComplete(request);
}
int CommandCompletions::VariablePath(CommandInterpreter &interpreter,
CompletionRequest &request,
SearchFilter *searcher) {
return Variable::AutoComplete(interpreter.GetExecutionContext(), request);
void CommandCompletions::VariablePath(CommandInterpreter &interpreter,
CompletionRequest &request,
SearchFilter *searcher) {
Variable::AutoComplete(interpreter.GetExecutionContext(), request);
}
CommandCompletions::Completer::Completer(CommandInterpreter &interpreter,
@ -417,15 +392,14 @@ CommandCompletions::SourceFileCompleter::SearchCallback(SearchFilter &filter,
return Searcher::eCallbackReturnContinue;
}
size_t
CommandCompletions::SourceFileCompleter::DoCompletion(SearchFilter *filter) {
void CommandCompletions::SourceFileCompleter::DoCompletion(
SearchFilter *filter) {
filter->Search(*this);
// Now convert the filelist to completions:
for (size_t i = 0; i < m_matching_files.GetSize(); i++) {
m_request.AddCompletion(
m_matching_files.GetFileSpecAtIndex(i).GetFilename().GetCString());
}
return m_request.GetNumberOfMatches();
}
// SymbolCompleter
@ -489,13 +463,11 @@ Searcher::CallbackReturn CommandCompletions::SymbolCompleter::SearchCallback(
return Searcher::eCallbackReturnContinue;
}
size_t CommandCompletions::SymbolCompleter::DoCompletion(SearchFilter *filter) {
void CommandCompletions::SymbolCompleter::DoCompletion(SearchFilter *filter) {
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_request.AddCompletion((*pos).GetCString());
return m_request.GetNumberOfMatches();
}
// ModuleCompleter
@ -536,7 +508,6 @@ Searcher::CallbackReturn CommandCompletions::ModuleCompleter::SearchCallback(
return Searcher::eCallbackReturnContinue;
}
size_t CommandCompletions::ModuleCompleter::DoCompletion(SearchFilter *filter) {
void CommandCompletions::ModuleCompleter::DoCompletion(SearchFilter *filter) {
filter->Search(*this);
return m_request.GetNumberOfMatches();
}

View File

@ -215,13 +215,12 @@ public:
return "";
}
int HandleArgumentCompletion(
CompletionRequest &request,
OptionElementVector &opt_element_vector) override {
void
HandleArgumentCompletion(CompletionRequest &request,
OptionElementVector &opt_element_vector) override {
CommandCompletions::InvokeCommonCompletionCallbacks(
GetCommandInterpreter(), CommandCompletions::eDiskFileCompletion,
request, nullptr);
return request.GetNumberOfMatches();
}
Options *GetOptions() override { return &m_options; }
@ -1388,13 +1387,12 @@ public:
~CommandObjectCommandsScriptImport() override = default;
int HandleArgumentCompletion(
CompletionRequest &request,
OptionElementVector &opt_element_vector) override {
void
HandleArgumentCompletion(CompletionRequest &request,
OptionElementVector &opt_element_vector) override {
CommandCompletions::InvokeCommonCompletionCallbacks(
GetCommandInterpreter(), CommandCompletions::eDiskFileCompletion,
request, nullptr);
return request.GetNumberOfMatches();
}
Options *GetOptions() override { return &m_options; }

View File

@ -294,7 +294,7 @@ CommandObjectExpression::~CommandObjectExpression() = default;
Options *CommandObjectExpression::GetOptions() { return &m_option_group; }
int CommandObjectExpression::HandleCompletion(CompletionRequest &request) {
void CommandObjectExpression::HandleCompletion(CompletionRequest &request) {
EvaluateExpressionOptions options;
options.SetCoerceToId(m_varobj_options.use_objc);
options.SetLanguage(m_command_options.language);
@ -311,7 +311,7 @@ int CommandObjectExpression::HandleCompletion(CompletionRequest &request) {
// This didn't work, so let's get out before we start doing things that
// expect a valid frame pointer.
if (m_interpreter.GetExecutionContext().GetFramePtr() == nullptr)
return 0;
return;
ExecutionContext exe_ctx(m_interpreter.GetExecutionContext());
@ -321,7 +321,7 @@ int CommandObjectExpression::HandleCompletion(CompletionRequest &request) {
target = GetDummyTarget();
if (!target)
return 0;
return;
unsigned cursor_pos = request.GetRawCursorPos();
llvm::StringRef code = request.GetRawLine();
@ -341,7 +341,7 @@ int CommandObjectExpression::HandleCompletion(CompletionRequest &request) {
// exit.
// FIXME: We should complete the options here.
if (cursor_pos < raw_start)
return 0;
return;
// Make the cursor_pos again relative to the start of the code string.
assert(cursor_pos >= raw_start);
@ -354,10 +354,9 @@ int CommandObjectExpression::HandleCompletion(CompletionRequest &request) {
code, llvm::StringRef(), language, UserExpression::eResultTypeAny,
options, nullptr, error));
if (error.Fail())
return 0;
return;
expr->Complete(exe_ctx, request, cursor_pos);
return request.GetNumberOfMatches();
}
static lldb_private::Status

View File

@ -54,7 +54,7 @@ public:
Options *GetOptions() override;
int HandleCompletion(CompletionRequest &request) override;
void HandleCompletion(CompletionRequest &request) override;
protected:
// IOHandler::Delegate functions

View File

@ -451,14 +451,13 @@ public:
Options *GetOptions() override { return &m_option_group; }
int HandleArgumentCompletion(
CompletionRequest &request,
OptionElementVector &opt_element_vector) override {
void
HandleArgumentCompletion(CompletionRequest &request,
OptionElementVector &opt_element_vector) override {
// Arguments are the standard source file completer.
CommandCompletions::InvokeCommonCompletionCallbacks(
GetCommandInterpreter(), CommandCompletions::eVariablePathCompletion,
request, nullptr);
return request.GetNumberOfMatches();
}
protected:

View File

@ -201,10 +201,10 @@ bool CommandObjectHelp::DoExecute(Args &command, CommandReturnObject &result) {
return result.Succeeded();
}
int CommandObjectHelp::HandleCompletion(CompletionRequest &request) {
void CommandObjectHelp::HandleCompletion(CompletionRequest &request) {
// Return the completions of the commands in the help system:
if (request.GetCursorIndex() == 0) {
return m_interpreter.HandleCompletionMatches(request);
m_interpreter.HandleCompletionMatches(request);
} else {
CommandObject *cmd_obj =
m_interpreter.GetCommandObject(request.GetParsedLine()[0].ref);
@ -216,9 +216,9 @@ int CommandObjectHelp::HandleCompletion(CompletionRequest &request) {
if (cmd_obj) {
request.GetParsedLine().Shift();
request.SetCursorIndex(request.GetCursorIndex() - 1);
return cmd_obj->HandleCompletion(request);
cmd_obj->HandleCompletion(request);
} else {
return m_interpreter.HandleCompletionMatches(request);
m_interpreter.HandleCompletionMatches(request);
}
}
}

View File

@ -23,7 +23,7 @@ public:
~CommandObjectHelp() override;
int HandleCompletion(CompletionRequest &request) override;
void HandleCompletion(CompletionRequest &request) override;
static void GenerateAdditionalHelpAvenuesMessage(
Stream *s, llvm::StringRef command, llvm::StringRef prefix,

View File

@ -179,11 +179,7 @@ void CommandObjectMultiword::GenerateHelpText(Stream &output_stream) {
"'help <command> <subcommand>'.\n");
}
int CommandObjectMultiword::HandleCompletion(CompletionRequest &request) {
// Any of the command matches will provide a complete word, otherwise the
// individual completers will override this.
request.SetWordComplete(true);
void CommandObjectMultiword::HandleCompletion(CompletionRequest &request) {
auto arg0 = request.GetParsedLine()[0].ref;
if (request.GetCursorIndex() == 0) {
StringList new_matches, descriptions;
@ -197,23 +193,19 @@ int CommandObjectMultiword::HandleCompletion(CompletionRequest &request) {
StringList temp_matches;
CommandObject *cmd_obj = GetSubcommandObject(arg0, &temp_matches);
if (cmd_obj != nullptr) {
if (request.GetParsedLine().GetArgumentCount() == 1) {
request.SetWordComplete(true);
} else {
if (request.GetParsedLine().GetArgumentCount() != 1) {
request.GetParsedLine().Shift();
request.SetCursorCharPosition(0);
request.GetParsedLine().AppendArgument(llvm::StringRef());
return cmd_obj->HandleCompletion(request);
cmd_obj->HandleCompletion(request);
}
}
}
return new_matches.GetSize();
} else {
StringList new_matches;
CommandObject *sub_command_object = GetSubcommandObject(arg0, &new_matches);
if (sub_command_object == nullptr) {
request.AddCompletions(new_matches);
return request.GetNumberOfMatches();
} else {
// Remove the one match that we got from calling GetSubcommandObject.
new_matches.DeleteStringAtIndex(0);
@ -360,19 +352,17 @@ Options *CommandObjectProxy::GetOptions() {
return nullptr;
}
int CommandObjectProxy::HandleCompletion(CompletionRequest &request) {
void CommandObjectProxy::HandleCompletion(CompletionRequest &request) {
CommandObject *proxy_command = GetProxyCommandObject();
if (proxy_command)
return proxy_command->HandleCompletion(request);
return 0;
proxy_command->HandleCompletion(request);
}
int CommandObjectProxy::HandleArgumentCompletion(
void CommandObjectProxy::HandleArgumentCompletion(
CompletionRequest &request, OptionElementVector &opt_element_vector) {
CommandObject *proxy_command = GetProxyCommandObject();
if (proxy_command)
return proxy_command->HandleArgumentCompletion(request, opt_element_vector);
return 0;
proxy_command->HandleArgumentCompletion(request, opt_element_vector);
}
const char *CommandObjectProxy::GetRepeatCommand(Args &current_command_args,

View File

@ -158,10 +158,9 @@ public:
~CommandObjectPlatformSelect() override = default;
int HandleCompletion(CompletionRequest &request) override {
void HandleCompletion(CompletionRequest &request) override {
CommandCompletions::PlatformPluginNames(GetCommandInterpreter(), request,
nullptr);
return request.GetNumberOfMatches();
}
Options *GetOptions() override { return &m_option_group; }

View File

@ -37,13 +37,12 @@ public:
~CommandObjectPluginLoad() override = default;
int HandleArgumentCompletion(
CompletionRequest &request,
OptionElementVector &opt_element_vector) override {
void
HandleArgumentCompletion(CompletionRequest &request,
OptionElementVector &opt_element_vector) override {
CommandCompletions::InvokeCommonCompletionCallbacks(
GetCommandInterpreter(), CommandCompletions::eDiskFileCompletion,
request, nullptr);
return request.GetNumberOfMatches();
}
protected:

View File

@ -127,14 +127,13 @@ public:
~CommandObjectProcessLaunch() override = default;
int HandleArgumentCompletion(
CompletionRequest &request,
OptionElementVector &opt_element_vector) override {
void
HandleArgumentCompletion(CompletionRequest &request,
OptionElementVector &opt_element_vector) override {
CommandCompletions::InvokeCommonCompletionCallbacks(
GetCommandInterpreter(), CommandCompletions::eDiskFileCompletion,
request, nullptr);
return request.GetNumberOfMatches();
}
Options *GetOptions() override { return &m_options; }

View File

@ -126,9 +126,9 @@ insert-before or insert-after.");
bool m_force;
};
int HandleArgumentCompletion(
CompletionRequest &request,
OptionElementVector &opt_element_vector) override {
void
HandleArgumentCompletion(CompletionRequest &request,
OptionElementVector &opt_element_vector) override {
const size_t argc = request.GetParsedLine().GetArgumentCount();
const char *arg = nullptr;
@ -164,7 +164,6 @@ insert-before or insert-after.");
}
}
}
return request.GetNumberOfMatches();
}
protected:
@ -271,13 +270,12 @@ public:
~CommandObjectSettingsShow() override = default;
int HandleArgumentCompletion(
CompletionRequest &request,
OptionElementVector &opt_element_vector) override {
void
HandleArgumentCompletion(CompletionRequest &request,
OptionElementVector &opt_element_vector) override {
CommandCompletions::InvokeCommonCompletionCallbacks(
GetCommandInterpreter(), CommandCompletions::eSettingsNameCompletion,
request, nullptr);
return request.GetNumberOfMatches();
}
protected:
@ -527,13 +525,12 @@ public:
~CommandObjectSettingsList() override = default;
int HandleArgumentCompletion(
CompletionRequest &request,
OptionElementVector &opt_element_vector) override {
void
HandleArgumentCompletion(CompletionRequest &request,
OptionElementVector &opt_element_vector) override {
CommandCompletions::InvokeCommonCompletionCallbacks(
GetCommandInterpreter(), CommandCompletions::eSettingsNameCompletion,
request, nullptr);
return request.GetNumberOfMatches();
}
protected:
@ -615,14 +612,13 @@ public:
bool WantsCompletion() override { return true; }
int HandleArgumentCompletion(
CompletionRequest &request,
OptionElementVector &opt_element_vector) override {
void
HandleArgumentCompletion(CompletionRequest &request,
OptionElementVector &opt_element_vector) override {
if (request.GetCursorIndex() < 2)
CommandCompletions::InvokeCommonCompletionCallbacks(
GetCommandInterpreter(), CommandCompletions::eSettingsNameCompletion,
request, nullptr);
return request.GetNumberOfMatches();
}
protected:
@ -728,16 +724,14 @@ public:
// !WantsRawCommandString.
bool WantsCompletion() override { return true; }
int HandleArgumentCompletion(
CompletionRequest &request,
OptionElementVector &opt_element_vector) override {
void
HandleArgumentCompletion(CompletionRequest &request,
OptionElementVector &opt_element_vector) override {
// Attempting to complete variable name
if (request.GetCursorIndex() < 2)
CommandCompletions::InvokeCommonCompletionCallbacks(
GetCommandInterpreter(), CommandCompletions::eSettingsNameCompletion,
request, nullptr);
return request.GetNumberOfMatches();
}
protected:
@ -826,16 +820,14 @@ public:
// !WantsRawCommandString.
bool WantsCompletion() override { return true; }
int HandleArgumentCompletion(
CompletionRequest &request,
OptionElementVector &opt_element_vector) override {
void
HandleArgumentCompletion(CompletionRequest &request,
OptionElementVector &opt_element_vector) override {
// Attempting to complete variable name
if (request.GetCursorIndex() < 2)
CommandCompletions::InvokeCommonCompletionCallbacks(
GetCommandInterpreter(), CommandCompletions::eSettingsNameCompletion,
request, nullptr);
return request.GetNumberOfMatches();
}
protected:
@ -929,16 +921,14 @@ public:
// !WantsRawCommandString.
bool WantsCompletion() override { return true; }
int HandleArgumentCompletion(
CompletionRequest &request,
OptionElementVector &opt_element_vector) override {
void
HandleArgumentCompletion(CompletionRequest &request,
OptionElementVector &opt_element_vector) override {
// Attempting to complete variable name
if (request.GetCursorIndex() < 2)
CommandCompletions::InvokeCommonCompletionCallbacks(
GetCommandInterpreter(), CommandCompletions::eSettingsNameCompletion,
request, nullptr);
return request.GetNumberOfMatches();
}
protected:
@ -1021,16 +1011,14 @@ public:
// !WantsRawCommandString.
bool WantsCompletion() override { return true; }
int HandleArgumentCompletion(
CompletionRequest &request,
OptionElementVector &opt_element_vector) override {
void
HandleArgumentCompletion(CompletionRequest &request,
OptionElementVector &opt_element_vector) override {
// Attempting to complete variable name
if (request.GetCursorIndex() < 2)
CommandCompletions::InvokeCommonCompletionCallbacks(
GetCommandInterpreter(), CommandCompletions::eSettingsNameCompletion,
request, nullptr);
return request.GetNumberOfMatches();
}
protected:
@ -1100,16 +1088,14 @@ public:
~CommandObjectSettingsClear() override = default;
int HandleArgumentCompletion(
CompletionRequest &request,
OptionElementVector &opt_element_vector) override {
void
HandleArgumentCompletion(CompletionRequest &request,
OptionElementVector &opt_element_vector) override {
// Attempting to complete variable name
if (request.GetCursorIndex() < 2)
CommandCompletions::InvokeCommonCompletionCallbacks(
GetCommandInterpreter(), CommandCompletions::eSettingsNameCompletion,
request, nullptr);
return request.GetNumberOfMatches();
}
protected:

View File

@ -258,13 +258,12 @@ public:
Options *GetOptions() override { return &m_option_group; }
int HandleArgumentCompletion(
CompletionRequest &request,
OptionElementVector &opt_element_vector) override {
void
HandleArgumentCompletion(CompletionRequest &request,
OptionElementVector &opt_element_vector) override {
CommandCompletions::InvokeCommonCompletionCallbacks(
GetCommandInterpreter(), CommandCompletions::eDiskFileCompletion,
request, nullptr);
return request.GetNumberOfMatches();
}
protected:
@ -1844,13 +1843,12 @@ public:
~CommandObjectTargetModulesModuleAutoComplete() override = default;
int HandleArgumentCompletion(
CompletionRequest &request,
OptionElementVector &opt_element_vector) override {
void
HandleArgumentCompletion(CompletionRequest &request,
OptionElementVector &opt_element_vector) override {
CommandCompletions::InvokeCommonCompletionCallbacks(
GetCommandInterpreter(), CommandCompletions::eModuleCompletion, request,
nullptr);
return request.GetNumberOfMatches();
}
};
@ -1883,13 +1881,12 @@ public:
~CommandObjectTargetModulesSourceFileAutoComplete() override = default;
int HandleArgumentCompletion(
CompletionRequest &request,
OptionElementVector &opt_element_vector) override {
void
HandleArgumentCompletion(CompletionRequest &request,
OptionElementVector &opt_element_vector) override {
CommandCompletions::InvokeCommonCompletionCallbacks(
GetCommandInterpreter(), CommandCompletions::eSourceFileCompletion,
request, nullptr);
return request.GetNumberOfMatches();
}
};
@ -2534,13 +2531,12 @@ public:
Options *GetOptions() override { return &m_option_group; }
int HandleArgumentCompletion(
CompletionRequest &request,
OptionElementVector &opt_element_vector) override {
void
HandleArgumentCompletion(CompletionRequest &request,
OptionElementVector &opt_element_vector) override {
CommandCompletions::InvokeCommonCompletionCallbacks(
GetCommandInterpreter(), CommandCompletions::eDiskFileCompletion,
request, nullptr);
return request.GetNumberOfMatches();
}
protected:
@ -4090,13 +4086,12 @@ public:
~CommandObjectTargetSymbolsAdd() override = default;
int HandleArgumentCompletion(
CompletionRequest &request,
OptionElementVector &opt_element_vector) override {
void
HandleArgumentCompletion(CompletionRequest &request,
OptionElementVector &opt_element_vector) override {
CommandCompletions::InvokeCommonCompletionCallbacks(
GetCommandInterpreter(), CommandCompletions::eDiskFileCompletion,
request, nullptr);
return request.GetNumberOfMatches();
}
Options *GetOptions() override { return &m_option_group; }

View File

@ -2346,33 +2346,31 @@ static void AddMatches(const FormatEntity::Entry::Definition *def,
}
}
size_t FormatEntity::AutoComplete(CompletionRequest &request) {
void FormatEntity::AutoComplete(CompletionRequest &request) {
llvm::StringRef str = request.GetCursorArgumentPrefix();
request.SetWordComplete(false);
const size_t dollar_pos = str.rfind('$');
if (dollar_pos == llvm::StringRef::npos)
return 0;
return;
// Hitting TAB after $ at the end of the string add a "{"
if (dollar_pos == str.size() - 1) {
std::string match = str.str();
match.append("{");
request.AddCompletion(match);
return 1;
return;
}
if (str[dollar_pos + 1] != '{')
return 0;
return;
const size_t close_pos = str.find('}', dollar_pos + 2);
if (close_pos != llvm::StringRef::npos)
return 0;
return;
const size_t format_pos = str.find('%', dollar_pos + 2);
if (format_pos != llvm::StringRef::npos)
return 0;
return;
llvm::StringRef partial_variable(str.substr(dollar_pos + 2));
if (partial_variable.empty()) {
@ -2380,7 +2378,7 @@ size_t FormatEntity::AutoComplete(CompletionRequest &request) {
StringList new_matches;
AddMatches(&g_root, str, llvm::StringRef(), new_matches);
request.AddCompletions(new_matches);
return request.GetNumberOfMatches();
return;
}
// We have a partially specified variable, find it
@ -2388,7 +2386,7 @@ size_t FormatEntity::AutoComplete(CompletionRequest &request) {
const FormatEntity::Entry::Definition *entry_def =
FindEntry(partial_variable, &g_root, remainder);
if (!entry_def)
return 0;
return;
const size_t n = entry_def->num_children;
@ -2400,7 +2398,6 @@ size_t FormatEntity::AutoComplete(CompletionRequest &request) {
} else {
// "${thread.id" <TAB>
request.AddCompletion(MakeMatch(str, "}"));
request.SetWordComplete(true);
}
} else if (remainder.equals(".")) {
// "${thread." <TAB>
@ -2414,5 +2411,4 @@ size_t FormatEntity::AutoComplete(CompletionRequest &request) {
AddMatches(entry_def, str, remainder, new_matches);
request.AddCompletions(new_matches);
}
return request.GetNumberOfMatches();
}

View File

@ -170,15 +170,14 @@ IOHandlerConfirm::IOHandlerConfirm(Debugger &debugger, llvm::StringRef prompt,
IOHandlerConfirm::~IOHandlerConfirm() = default;
int IOHandlerConfirm::IOHandlerComplete(IOHandler &io_handler,
CompletionRequest &request) {
void IOHandlerConfirm::IOHandlerComplete(IOHandler &io_handler,
CompletionRequest &request) {
if (request.GetRawCursorPos() == 0) {
if (m_default_response)
request.AddCompletion("y");
else
request.AddCompletion("n");
}
return request.GetNumberOfMatches();
}
void IOHandlerConfirm::IOHandlerInputComplete(IOHandler &io_handler,
@ -216,47 +215,20 @@ void IOHandlerConfirm::IOHandlerInputComplete(IOHandler &io_handler,
}
}
int IOHandlerDelegate::IOHandlerComplete(IOHandler &io_handler,
CompletionRequest &request) {
void IOHandlerDelegate::IOHandlerComplete(IOHandler &io_handler,
CompletionRequest &request) {
switch (m_completion) {
case Completion::None:
break;
case Completion::LLDBCommand:
return io_handler.GetDebugger().GetCommandInterpreter().HandleCompletion(
request);
case Completion::Expression: {
CompletionResult result;
CompletionRequest subrequest(request.GetRawLine(),
request.GetRawCursorPos(), result);
io_handler.GetDebugger().GetCommandInterpreter().HandleCompletion(request);
break;
case Completion::Expression:
CommandCompletions::InvokeCommonCompletionCallbacks(
io_handler.GetDebugger().GetCommandInterpreter(),
CommandCompletions::eVariablePathCompletion, subrequest, nullptr);
StringList matches;
StringList descriptions;
result.GetMatches(matches);
result.GetDescriptions(descriptions);
size_t num_matches = subrequest.GetNumberOfMatches();
if (num_matches > 0) {
std::string common_prefix = matches.LongestCommonPrefix();
const size_t partial_name_len =
subrequest.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 && subrequest.GetWordComplete()) {
common_prefix.push_back(' ');
}
common_prefix.erase(0, partial_name_len);
request.AddCompletion(common_prefix);
}
request.AddCompletions(matches, descriptions);
return request.GetNumberOfMatches();
} break;
CommandCompletions::eVariablePathCompletion, request, nullptr);
break;
}
return 0;
}
IOHandlerEditline::IOHandlerEditline(
@ -445,13 +417,11 @@ int IOHandlerEditline::FixIndentationCallback(Editline *editline,
*editline_reader, lines, cursor_position);
}
int IOHandlerEditline::AutoCompleteCallback(CompletionRequest &request,
void *baton) {
void IOHandlerEditline::AutoCompleteCallback(CompletionRequest &request,
void *baton) {
IOHandlerEditline *editline_reader = (IOHandlerEditline *)baton;
if (editline_reader)
return editline_reader->m_delegate.IOHandlerComplete(*editline_reader,
request);
return 0;
editline_reader->m_delegate.IOHandlerComplete(*editline_reader, request);
}
#endif

View File

@ -1341,10 +1341,10 @@ PluginManager::GetPlatformCreateCallbackForPluginName(ConstString name) {
return nullptr;
}
size_t PluginManager::AutoCompletePlatformName(llvm::StringRef name,
StringList &matches) {
void PluginManager::AutoCompletePlatformName(llvm::StringRef name,
CompletionRequest &request) {
if (name.empty())
return matches.GetSize();
return;
std::lock_guard<std::recursive_mutex> guard(GetPlatformInstancesMutex());
PlatformInstances &instances = GetPlatformInstances();
@ -1354,9 +1354,8 @@ size_t PluginManager::AutoCompletePlatformName(llvm::StringRef name,
for (pos = instances.begin(); pos != end; ++pos) {
llvm::StringRef plugin_name(pos->name.GetCString());
if (plugin_name.startswith(name_sref))
matches.AppendString(plugin_name.data());
request.AddCompletion(plugin_name.data());
}
return matches.GetSize();
}
#pragma mark Process

View File

@ -433,7 +433,8 @@ void REPL::IOHandlerInputComplete(IOHandler &io_handler, std::string &code) {
}
}
int REPL::IOHandlerComplete(IOHandler &io_handler, CompletionRequest &request) {
void REPL::IOHandlerComplete(IOHandler &io_handler,
CompletionRequest &request) {
// Complete an LLDB command if the first character is a colon...
if (request.GetRawLine().startswith(":")) {
Debugger &debugger = m_target.GetDebugger();
@ -443,19 +444,19 @@ int REPL::IOHandlerComplete(IOHandler &io_handler, CompletionRequest &request) {
CompletionResult sub_result;
CompletionRequest sub_request(new_line, request.GetRawCursorPos() - 1,
sub_result);
int result = debugger.GetCommandInterpreter().HandleCompletion(sub_request);
debugger.GetCommandInterpreter().HandleCompletion(sub_request);
StringList matches, descriptions;
sub_result.GetMatches(matches);
sub_result.GetDescriptions(descriptions);
request.AddCompletions(matches, descriptions);
return result;
return;
}
// Strip spaces from the line and see if we had only spaces
if (request.GetRawLineUntilCursor().trim().empty()) {
// Only spaces on this line, so just indent
request.AddCompletion(m_indent_str);
return 1;
return;
}
std::string current_code;
@ -482,8 +483,12 @@ int REPL::IOHandlerComplete(IOHandler &io_handler, CompletionRequest &request) {
StringList matches;
int result = CompleteCode(current_code, matches);
request.AddCompletions(matches);
return result;
if (result == -2) {
assert(matches.GetSize() == 1);
request.AddCompletion(matches.GetStringAtIndex(0), "",
CompletionMode::RewriteLine);
} else
request.AddCompletions(matches);
}
bool QuitCommandOverrideCallback(void *baton, const char **argv) {

View File

@ -864,26 +864,59 @@ unsigned char Editline::BufferEndCommand(int ch) {
/// Prints completions and their descriptions to the given file. Only the
/// completions in the interval [start, end) are printed.
static void PrintCompletion(FILE *output_file, size_t start, size_t end,
StringList &completions, StringList &descriptions) {
// This is an 'int' because of printf.
int max_len = 0;
static void
PrintCompletion(FILE *output_file,
llvm::ArrayRef<CompletionResult::Completion> results,
size_t max_len) {
for (const CompletionResult::Completion &c : results) {
fprintf(output_file, "\t%-*s", (int)max_len, c.GetCompletion().c_str());
if (!c.GetDescription().empty())
fprintf(output_file, " -- %s", c.GetDescription().c_str());
fprintf(output_file, "\n");
}
}
for (size_t i = start; i < end; i++) {
const char *completion_str = completions.GetStringAtIndex(i);
max_len = std::max((int)strlen(completion_str), max_len);
static void
DisplayCompletions(::EditLine *editline, FILE *output_file,
llvm::ArrayRef<CompletionResult::Completion> results) {
assert(!results.empty());
fprintf(output_file, "\n" ANSI_CLEAR_BELOW "Available completions:\n");
const size_t page_size = 40;
bool all = false;
auto longest =
std::max_element(results.begin(), results.end(), [](auto &c1, auto &c2) {
return c1.GetCompletion().size() < c2.GetCompletion().size();
});
const size_t max_len = longest->GetCompletion().size();
if (results.size() < page_size) {
PrintCompletion(output_file, results, max_len);
return;
}
for (size_t i = start; i < end; i++) {
const char *completion_str = completions.GetStringAtIndex(i);
const char *description_str = descriptions.GetStringAtIndex(i);
size_t cur_pos = 0;
while (cur_pos < results.size()) {
size_t remaining = results.size() - cur_pos;
size_t next_size = all ? remaining : std::min(page_size, remaining);
if (completion_str)
fprintf(output_file, "\n\t%-*s", max_len, completion_str);
PrintCompletion(output_file, results.slice(cur_pos, next_size), max_len);
// Print the description if we got one.
if (description_str && strlen(description_str))
fprintf(output_file, " -- %s", description_str);
cur_pos += next_size;
if (cur_pos >= results.size())
break;
fprintf(output_file, "More (Y/n/a): ");
char reply = 'n';
int got_char = el_getc(editline, &reply);
fprintf(output_file, "\n");
if (got_char == -1 || reply == 'n')
break;
if (reply == 'a')
all = true;
}
}
@ -892,8 +925,6 @@ unsigned char Editline::TabCommand(int ch) {
return CC_ERROR;
const LineInfo *line_info = el_line(m_editline);
StringList completions, descriptions;
int page_size = 40;
llvm::StringRef line(line_info->buffer,
line_info->lastchar - line_info->buffer);
@ -901,71 +932,51 @@ unsigned char Editline::TabCommand(int ch) {
CompletionResult result;
CompletionRequest request(line, cursor_index, result);
const int num_completions =
m_completion_callback(request, m_completion_callback_baton);
m_completion_callback(request, m_completion_callback_baton);
llvm::ArrayRef<CompletionResult::Completion> results = result.GetResults();
StringList completions;
result.GetMatches(completions);
result.GetDescriptions(descriptions);
if (num_completions == 0)
if (results.size() == 0)
return CC_ERROR;
// if (num_completions == -1)
// {
// el_insertstr (m_editline, m_completion_key);
// return CC_REDISPLAY;
// }
// else
if (num_completions == -2) {
// Replace the entire line with the first string...
el_deletestr(m_editline, line_info->cursor - line_info->buffer);
el_insertstr(m_editline, completions.GetStringAtIndex(0));
if (results.size() == 1) {
CompletionResult::Completion completion = results.front();
switch (completion.GetMode()) {
case CompletionMode::Normal: {
std::string to_add = completion.GetCompletion();
to_add = to_add.substr(request.GetCursorArgumentPrefix().size());
if (request.GetParsedArg().IsQuoted())
to_add.push_back(request.GetParsedArg().quote);
to_add.push_back(' ');
el_insertstr(m_editline, to_add.c_str());
break;
}
case CompletionMode::RewriteLine: {
el_deletestr(m_editline, line_info->cursor - line_info->buffer);
el_insertstr(m_editline, completion.GetCompletion().c_str());
break;
}
}
return CC_REDISPLAY;
}
// If we get a longer match display that first.
const char *completion_str = completions.GetStringAtIndex(0);
if (completion_str != nullptr && *completion_str != '\0') {
el_insertstr(m_editline, completion_str);
std::string longest_prefix = completions.LongestCommonPrefix();
if (!longest_prefix.empty())
longest_prefix =
longest_prefix.substr(request.GetCursorArgumentPrefix().size());
if (!longest_prefix.empty()) {
el_insertstr(m_editline, longest_prefix.c_str());
return CC_REDISPLAY;
}
if (num_completions > 1) {
int num_elements = num_completions + 1;
fprintf(m_output_file, "\n" ANSI_CLEAR_BELOW "Available completions:");
if (num_completions < page_size) {
PrintCompletion(m_output_file, 1, num_elements, completions,
descriptions);
fprintf(m_output_file, "\n");
} else {
int cur_pos = 1;
char reply;
int got_char;
while (cur_pos < num_elements) {
int endpoint = cur_pos + page_size;
if (endpoint > num_elements)
endpoint = num_elements;
DisplayCompletions(m_editline, m_output_file, results);
PrintCompletion(m_output_file, cur_pos, endpoint, completions,
descriptions);
cur_pos = endpoint;
if (cur_pos >= num_elements) {
fprintf(m_output_file, "\n");
break;
}
fprintf(m_output_file, "\nMore (Y/n/a): ");
reply = 'n';
got_char = el_getc(m_editline, &reply);
if (got_char == -1 || reply == 'n')
break;
if (reply == 'a')
page_size = num_elements - cur_pos;
}
}
DisplayInput();
MoveCursor(CursorLocation::BlockEnd, CursorLocation::EditingCursor);
}
DisplayInput();
MoveCursor(CursorLocation::BlockEnd, CursorLocation::EditingCursor);
return CC_REDISPLAY;
}

View File

@ -115,18 +115,16 @@ bool CommandAlias::WantsCompletion() {
return false;
}
int CommandAlias::HandleCompletion(CompletionRequest &request) {
void CommandAlias::HandleCompletion(CompletionRequest &request) {
if (IsValid())
return m_underlying_command_sp->HandleCompletion(request);
return -1;
m_underlying_command_sp->HandleCompletion(request);
}
int CommandAlias::HandleArgumentCompletion(
void CommandAlias::HandleArgumentCompletion(
CompletionRequest &request, OptionElementVector &opt_element_vector) {
if (IsValid())
return m_underlying_command_sp->HandleArgumentCompletion(
request, opt_element_vector);
return -1;
m_underlying_command_sp->HandleArgumentCompletion(request,
opt_element_vector);
}
Options *CommandAlias::GetOptions() {

View File

@ -1754,19 +1754,17 @@ bool CommandInterpreter::HandleCommand(const char *command_line,
return result.Succeeded();
}
int CommandInterpreter::HandleCompletionMatches(CompletionRequest &request) {
int num_command_matches = 0;
void CommandInterpreter::HandleCompletionMatches(CompletionRequest &request) {
bool look_for_subcommand = false;
// For any of the command completions a unique match will be a complete word.
request.SetWordComplete(true);
if (request.GetCursorIndex() == -1) {
// We got nothing on the command line, so return the list of commands
bool include_aliases = true;
StringList new_matches, descriptions;
num_command_matches = GetCommandNamesMatchingPartialString(
"", include_aliases, new_matches, descriptions);
GetCommandNamesMatchingPartialString("", include_aliases, new_matches,
descriptions);
request.AddCompletions(new_matches, descriptions);
} else if (request.GetCursorIndex() == 0) {
// The cursor is in the first argument, so just do a lookup in the
@ -1776,15 +1774,12 @@ int CommandInterpreter::HandleCompletionMatches(CompletionRequest &request) {
GetCommandObject(request.GetParsedLine().GetArgumentAtIndex(0),
&new_matches, &new_descriptions);
if (num_command_matches == 1 && cmd_obj && cmd_obj->IsMultiwordObject() &&
if (new_matches.GetSize() && cmd_obj && cmd_obj->IsMultiwordObject() &&
new_matches.GetStringAtIndex(0) != nullptr &&
strcmp(request.GetParsedLine().GetArgumentAtIndex(0),
new_matches.GetStringAtIndex(0)) == 0) {
if (request.GetParsedLine().GetArgumentCount() == 1) {
request.SetWordComplete(true);
} else {
if (request.GetParsedLine().GetArgumentCount() != 1) {
look_for_subcommand = true;
num_command_matches = 0;
new_matches.DeleteStringAtIndex(0);
new_descriptions.DeleteStringAtIndex(0);
request.GetParsedLine().AppendArgument(llvm::StringRef());
@ -1793,7 +1788,6 @@ int CommandInterpreter::HandleCompletionMatches(CompletionRequest &request) {
}
}
request.AddCompletions(new_matches, new_descriptions);
num_command_matches = request.GetNumberOfMatches();
}
if (request.GetCursorIndex() > 0 || look_for_subcommand) {
@ -1802,77 +1796,32 @@ int CommandInterpreter::HandleCompletionMatches(CompletionRequest &request) {
// matching initial command:
CommandObject *command_object =
GetCommandObject(request.GetParsedLine().GetArgumentAtIndex(0));
if (command_object == nullptr) {
return 0;
} else {
if (command_object) {
request.GetParsedLine().Shift();
request.SetCursorIndex(request.GetCursorIndex() - 1);
num_command_matches = command_object->HandleCompletion(request);
command_object->HandleCompletion(request);
}
}
return num_command_matches;
}
int CommandInterpreter::HandleCompletion(CompletionRequest &orig_request) {
// Start a new subrequest we can modify.
CompletionResult result;
CompletionRequest request(orig_request.GetRawLine(),
orig_request.GetRawCursorPos(), result);
void CommandInterpreter::HandleCompletion(CompletionRequest &request) {
// 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 = request.GetParsedLine().GetArgumentAtIndex(0);
StringList matches, descriptions;
llvm::StringRef 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.InsertStringAtIndex(0, *hist_str);
descriptions.InsertStringAtIndex(0, "Previous command history event");
return -2;
} else
return 0;
if (!first_arg.empty()) {
if (first_arg.front() == m_comment_char)
return;
if (first_arg.front() == CommandHistory::g_repeat_char) {
if (auto hist_str = m_command_history.FindString(first_arg))
request.AddCompletion(*hist_str, "Previous command history event",
CompletionMode::RewriteLine);
return;
}
}
int num_command_matches = HandleCompletionMatches(request);
result.GetMatches(matches);
result.GetDescriptions(descriptions);
if (num_command_matches <= 0)
return num_command_matches;
if (request.GetParsedLine().GetArgumentCount() == 0) {
// If we got an empty string, insert nothing.
matches.InsertStringAtIndex(0, "");
descriptions.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 = request.GetCursorArgumentPrefix().str();
std::string common_prefix = matches.LongestCommonPrefix();
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 && 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());
descriptions.InsertStringAtIndex(0, "");
}
// Add completion to original request.
orig_request.AddCompletions(matches, descriptions);
return num_command_matches;
HandleCompletionMatches(request);
}
CommandInterpreter::~CommandInterpreter() {}

View File

@ -257,14 +257,14 @@ void CommandObject::Cleanup() {
m_api_locker.unlock();
}
int CommandObject::HandleCompletion(CompletionRequest &request) {
void CommandObject::HandleCompletion(CompletionRequest &request) {
// Default implementation of WantsCompletion() is !WantsRawCommandString().
// Subclasses who want raw command string but desire, for example, argument
// completion should override WantsCompletion() to return true, instead.
if (WantsRawCommandString() && !WantsCompletion()) {
// FIXME: Abstract telling the completion to insert the completion
// character.
return -1;
return;
} else {
// Can we do anything generic with the options?
Options *cur_options = GetOptions();
@ -278,11 +278,11 @@ int CommandObject::HandleCompletion(CompletionRequest &request) {
bool handled_by_options = cur_options->HandleOptionCompletion(
request, opt_element_vector, GetCommandInterpreter());
if (handled_by_options)
return request.GetNumberOfMatches();
return;
}
// If we got here, the last word is not an option or an option argument.
return HandleArgumentCompletion(request, opt_element_vector);
HandleArgumentCompletion(request, opt_element_vector);
}
}

View File

@ -84,13 +84,9 @@ bool CommandObjectRegexCommand::AddRegexCommand(const char *re_cstr,
return false;
}
int CommandObjectRegexCommand::HandleCompletion(CompletionRequest &request) {
void CommandObjectRegexCommand::HandleCompletion(CompletionRequest &request) {
if (m_completion_type_mask) {
CommandCompletions::InvokeCommonCompletionCallbacks(
GetCommandInterpreter(), m_completion_type_mask, request, nullptr);
return request.GetNumberOfMatches();
} else {
request.SetWordComplete(false);
}
return 0;
}

View File

@ -565,11 +565,8 @@ bool OptionValue::DumpQualifiedName(Stream &strm) const {
return dumped_something;
}
size_t OptionValue::AutoComplete(CommandInterpreter &interpreter,
CompletionRequest &request) {
request.SetWordComplete(false);
return request.GetNumberOfMatches();
}
void OptionValue::AutoComplete(CommandInterpreter &interpreter,
CompletionRequest &request) {}
Status OptionValue::SetValueFromString(llvm::StringRef value,
VarSetOperationType op) {

View File

@ -68,11 +68,9 @@ lldb::OptionValueSP OptionValueArch::DeepCopy() const {
return OptionValueSP(new OptionValueArch(*this));
}
size_t OptionValueArch::AutoComplete(CommandInterpreter &interpreter,
CompletionRequest &request) {
request.SetWordComplete(false);
void OptionValueArch::AutoComplete(CommandInterpreter &interpreter,
CompletionRequest &request) {
CommandCompletions::InvokeCommonCompletionCallbacks(
interpreter, CommandCompletions::eArchitectureCompletion, request,
nullptr);
return request.GetNumberOfMatches();
}

View File

@ -71,9 +71,8 @@ lldb::OptionValueSP OptionValueBoolean::DeepCopy() const {
return OptionValueSP(new OptionValueBoolean(*this));
}
size_t OptionValueBoolean::AutoComplete(CommandInterpreter &interpreter,
CompletionRequest &request) {
request.SetWordComplete(false);
void OptionValueBoolean::AutoComplete(CommandInterpreter &interpreter,
CompletionRequest &request) {
static const llvm::StringRef g_autocomplete_entries[] = {
"true", "false", "on", "off", "yes", "no", "1", "0"};
@ -87,5 +86,4 @@ size_t OptionValueBoolean::AutoComplete(CommandInterpreter &interpreter,
if (entry.startswith_lower(request.GetCursorArgumentPrefix()))
request.AddCompletion(entry);
}
return request.GetNumberOfMatches();
}

View File

@ -102,10 +102,8 @@ lldb::OptionValueSP OptionValueEnumeration::DeepCopy() const {
return OptionValueSP(new OptionValueEnumeration(*this));
}
size_t OptionValueEnumeration::AutoComplete(CommandInterpreter &interpreter,
CompletionRequest &request) {
request.SetWordComplete(false);
void OptionValueEnumeration::AutoComplete(CommandInterpreter &interpreter,
CompletionRequest &request) {
const uint32_t num_enumerators = m_enumerations.GetSize();
if (!request.GetCursorArgumentPrefix().empty()) {
for (size_t i = 0; i < num_enumerators; ++i) {
@ -118,5 +116,4 @@ size_t OptionValueEnumeration::AutoComplete(CommandInterpreter &interpreter,
for (size_t i = 0; i < num_enumerators; ++i)
request.AddCompletion(m_enumerations.GetCStringAtIndex(i).GetStringRef());
}
return request.GetNumberOfMatches();
}

View File

@ -99,12 +99,10 @@ lldb::OptionValueSP OptionValueFileSpec::DeepCopy() const {
return OptionValueSP(new OptionValueFileSpec(*this));
}
size_t OptionValueFileSpec::AutoComplete(CommandInterpreter &interpreter,
CompletionRequest &request) {
request.SetWordComplete(false);
void OptionValueFileSpec::AutoComplete(CommandInterpreter &interpreter,
CompletionRequest &request) {
CommandCompletions::InvokeCommonCompletionCallbacks(
interpreter, m_completion_mask, request, nullptr);
return request.GetNumberOfMatches();
}
const lldb::DataBufferSP &OptionValueFileSpec::GetFileContents() {

View File

@ -116,7 +116,7 @@ lldb::OptionValueSP OptionValueFormatEntity::DeepCopy() const {
return OptionValueSP(new OptionValueFormatEntity(*this));
}
size_t OptionValueFormatEntity::AutoComplete(CommandInterpreter &interpreter,
CompletionRequest &request) {
return FormatEntity::AutoComplete(request);
void OptionValueFormatEntity::AutoComplete(CommandInterpreter &interpreter,
CompletionRequest &request) {
FormatEntity::AutoComplete(request);
}

View File

@ -62,9 +62,8 @@ lldb::OptionValueSP OptionValueUUID::DeepCopy() const {
return OptionValueSP(new OptionValueUUID(*this));
}
size_t OptionValueUUID::AutoComplete(CommandInterpreter &interpreter,
CompletionRequest &request) {
request.SetWordComplete(false);
void OptionValueUUID::AutoComplete(CommandInterpreter &interpreter,
CompletionRequest &request) {
ExecutionContext exe_ctx(interpreter.GetExecutionContext());
Target *target = exe_ctx.GetTargetPtr();
if (target) {
@ -87,5 +86,4 @@ size_t OptionValueUUID::AutoComplete(CommandInterpreter &interpreter,
}
}
}
return request.GetNumberOfMatches();
}

View File

@ -645,8 +645,6 @@ bool Options::VerifyPartialOptions(CommandReturnObject &result) {
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
@ -739,7 +737,6 @@ bool Options::HandleOptionCompletion(CompletionRequest &request,
if (opt_defs_index != -1) {
HandleOptionArgumentCompletion(subrequest, opt_element_vector, i,
interpreter);
request.SetWordComplete(subrequest.GetWordComplete());
return true;
} else {
// No completion callback means no completions...

View File

@ -583,7 +583,6 @@ static void PrivateAutoComplete(
case eTypeClassTypedef:
case eTypeClassVector: {
request.AddCompletion(prefix_path.str());
request.SetWordComplete(true);
} break;
case eTypeClassClass:
@ -603,7 +602,6 @@ static void PrivateAutoComplete(
request.AddCompletion((prefix_path + "->").str());
else {
request.AddCompletion(prefix_path.str());
request.SetWordComplete(true);
}
} break;
}
@ -749,12 +747,10 @@ static void PrivateAutoComplete(
}
}
size_t Variable::AutoComplete(const ExecutionContext &exe_ctx,
CompletionRequest &request) {
void Variable::AutoComplete(const ExecutionContext &exe_ctx,
CompletionRequest &request) {
CompilerType compiler_type;
PrivateAutoComplete(exe_ctx.GetFramePtr(), request.GetCursorArgumentPrefix(),
"", compiler_type, request);
return request.GetNumberOfMatches();
}

View File

@ -243,7 +243,7 @@ void ArchSpec::ListSupportedArchNames(StringList &list) {
list.AppendString(g_core_definitions[i].name);
}
size_t ArchSpec::AutoComplete(CompletionRequest &request) {
void 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,
@ -255,7 +255,6 @@ size_t ArchSpec::AutoComplete(CompletionRequest &request) {
ListSupportedArchNames(matches);
request.AddCompletions(matches);
}
return request.GetNumberOfMatches();
}
#define CPU_ANY (UINT32_MAX)

View File

@ -64,13 +64,16 @@ std::string CompletionResult::Completion::GetUniqueKey() const {
std::string result;
result.append(std::to_string(m_completion.size()));
result.append(m_completion);
result.append(std::to_string(static_cast<int>(m_mode)));
result.append(":");
result.append(m_descripton);
return result;
}
void CompletionResult::AddResult(llvm::StringRef completion,
llvm::StringRef description) {
Completion r(completion, description);
llvm::StringRef description,
CompletionMode mode) {
Completion r(completion, description, mode);
// Add the completion if we haven't seen the same value before.
if (m_added_values.insert(r.GetUniqueKey()).second)
@ -80,11 +83,11 @@ void CompletionResult::AddResult(llvm::StringRef completion,
void CompletionResult::GetMatches(StringList &matches) const {
matches.Clear();
for (const Completion &completion : m_results)
matches.AppendString(completion.m_completion);
matches.AppendString(completion.GetCompletion());
}
void CompletionResult::GetDescriptions(StringList &descriptions) const {
descriptions.Clear();
for (const Completion &completion : m_results)
descriptions.AppendString(completion.m_descripton);
descriptions.AppendString(completion.GetDescription());
}

View File

@ -116,20 +116,16 @@ protected:
StringList &Results) {
// When a partial name matches, it returns all matches. If it matches both
// a full name AND some partial names, it returns all of them.
uint32_t Count =
CommandCompletions::DiskDirectories(Prefix + "foo", Results, Resolver);
ASSERT_EQ(4u, Count);
ASSERT_EQ(Count, Results.GetSize());
CommandCompletions::DiskDirectories(Prefix + "foo", Results, Resolver);
ASSERT_EQ(4u, Results.GetSize());
EXPECT_TRUE(HasEquivalentFile(DirFoo, Results));
EXPECT_TRUE(HasEquivalentFile(DirFooA, Results));
EXPECT_TRUE(HasEquivalentFile(DirFooB, Results));
EXPECT_TRUE(HasEquivalentFile(DirFooC, Results));
// If it matches only partial names, it still works as expected.
Count = CommandCompletions::DiskDirectories(Twine(Prefix) + "b", Results,
Resolver);
ASSERT_EQ(2u, Count);
ASSERT_EQ(Count, Results.GetSize());
CommandCompletions::DiskDirectories(Twine(Prefix) + "b", Results, Resolver);
ASSERT_EQ(2u, Results.GetSize());
EXPECT_TRUE(HasEquivalentFile(DirBar, Results));
EXPECT_TRUE(HasEquivalentFile(DirBaz, Results));
}
@ -160,21 +156,17 @@ TEST_F(CompletionTest, DirCompletionAbsolute) {
// When a directory is specified that doesn't end in a slash, it searches
// for that directory, not items under it.
// Sanity check that the path we complete on exists and isn't too long.
size_t Count = CommandCompletions::DiskDirectories(Twine(BaseDir) + "/fooa",
Results, Resolver);
ASSERT_EQ(1u, Count);
ASSERT_EQ(Count, Results.GetSize());
CommandCompletions::DiskDirectories(Twine(BaseDir) + "/fooa", Results,
Resolver);
ASSERT_EQ(1u, Results.GetSize());
EXPECT_TRUE(HasEquivalentFile(DirFooA, Results));
Count = CommandCompletions::DiskDirectories(Twine(BaseDir) + "/.", Results,
Resolver);
ASSERT_EQ(0u, Count);
ASSERT_EQ(Count, Results.GetSize());
CommandCompletions::DiskDirectories(Twine(BaseDir) + "/.", Results, Resolver);
ASSERT_EQ(0u, Results.GetSize());
// When the same directory ends with a slash, it finds all children.
Count = CommandCompletions::DiskDirectories(Prefixes[0], Results, Resolver);
ASSERT_EQ(7u, Count);
ASSERT_EQ(Count, Results.GetSize());
CommandCompletions::DiskDirectories(Prefixes[0], Results, Resolver);
ASSERT_EQ(7u, Results.GetSize());
EXPECT_TRUE(HasEquivalentFile(DirFoo, Results));
EXPECT_TRUE(HasEquivalentFile(DirFooA, Results));
EXPECT_TRUE(HasEquivalentFile(DirFooB, Results));
@ -197,25 +189,19 @@ TEST_F(CompletionTest, FileCompletionAbsolute) {
StringList Results;
// When an item is specified that doesn't end in a slash but exactly matches
// one item, it returns that item.
size_t Count = CommandCompletions::DiskFiles(Twine(BaseDir) + "/fooa",
Results, Resolver);
ASSERT_EQ(1u, Count);
ASSERT_EQ(Count, Results.GetSize());
CommandCompletions::DiskFiles(Twine(BaseDir) + "/fooa", Results, Resolver);
ASSERT_EQ(1u, Results.GetSize());
EXPECT_TRUE(HasEquivalentFile(DirFooA, Results));
// The previous check verified a directory match. But it should work for
// files too.
Count =
CommandCompletions::DiskFiles(Twine(BaseDir) + "/aa", Results, Resolver);
ASSERT_EQ(1u, Count);
ASSERT_EQ(Count, Results.GetSize());
CommandCompletions::DiskFiles(Twine(BaseDir) + "/aa", Results, Resolver);
ASSERT_EQ(1u, Results.GetSize());
EXPECT_TRUE(HasEquivalentFile(FileAA, Results));
// When it ends with a slash, it should find all files and directories.
Count =
CommandCompletions::DiskFiles(Twine(BaseDir) + "/", Results, Resolver);
ASSERT_EQ(13u, Count);
ASSERT_EQ(Count, Results.GetSize());
CommandCompletions::DiskFiles(Twine(BaseDir) + "/", Results, Resolver);
ASSERT_EQ(13u, Results.GetSize());
EXPECT_TRUE(HasEquivalentFile(DirFoo, Results));
EXPECT_TRUE(HasEquivalentFile(DirFooA, Results));
EXPECT_TRUE(HasEquivalentFile(DirFooB, Results));
@ -232,10 +218,8 @@ TEST_F(CompletionTest, FileCompletionAbsolute) {
EXPECT_TRUE(HasEquivalentFile(FileBaz, Results));
// When a partial name matches, it returns all file & directory matches.
Count =
CommandCompletions::DiskFiles(Twine(BaseDir) + "/foo", Results, Resolver);
ASSERT_EQ(5u, Count);
ASSERT_EQ(Count, Results.GetSize());
CommandCompletions::DiskFiles(Twine(BaseDir) + "/foo", Results, Resolver);
ASSERT_EQ(5u, Results.GetSize());
EXPECT_TRUE(HasEquivalentFile(DirFoo, Results));
EXPECT_TRUE(HasEquivalentFile(DirFooA, Results));
EXPECT_TRUE(HasEquivalentFile(DirFooB, Results));
@ -254,42 +238,35 @@ TEST_F(CompletionTest, DirCompletionUsername) {
// Just resolving current user's home directory by itself should return the
// directory.
StringList Results;
size_t Count = CommandCompletions::DiskDirectories("~", Results, Resolver);
EXPECT_EQ(Count, Results.GetSize());
CommandCompletions::DiskDirectories("~", Results, Resolver);
EXPECT_THAT(toVector(Results), UnorderedElementsAre("~" + sep));
// With a slash appended, it should return all items in the directory.
Count = CommandCompletions::DiskDirectories("~/", Results, Resolver);
CommandCompletions::DiskDirectories("~/", Results, Resolver);
EXPECT_THAT(toVector(Results),
UnorderedElementsAre(
"~/foo" + sep, "~/fooa" + sep, "~/foob" + sep, "~/fooc" + sep,
"~/bar" + sep, "~/baz" + sep, "~/test_folder" + sep));
EXPECT_EQ(Count, Results.GetSize());
// Check that we can complete directories in nested paths
Count = CommandCompletions::DiskDirectories("~/foo/", Results, Resolver);
EXPECT_EQ(Count, Results.GetSize());
CommandCompletions::DiskDirectories("~/foo/", Results, Resolver);
EXPECT_THAT(toVector(Results), UnorderedElementsAre("~/foo/nested" + sep));
Count = CommandCompletions::DiskDirectories("~/foo/nes", Results, Resolver);
EXPECT_EQ(Count, Results.GetSize());
CommandCompletions::DiskDirectories("~/foo/nes", Results, Resolver);
EXPECT_THAT(toVector(Results), UnorderedElementsAre("~/foo/nested" + sep));
// With ~username syntax it should return one match if there is an exact
// match. It shouldn't translate to the actual directory, it should keep the
// form the user typed.
Count = CommandCompletions::DiskDirectories("~Lars", Results, Resolver);
EXPECT_EQ(Count, Results.GetSize());
CommandCompletions::DiskDirectories("~Lars", Results, Resolver);
EXPECT_THAT(toVector(Results), UnorderedElementsAre("~Lars" + sep));
// But with a username that is not found, no results are returned.
Count = CommandCompletions::DiskDirectories("~Dave", Results, Resolver);
EXPECT_EQ(Count, Results.GetSize());
CommandCompletions::DiskDirectories("~Dave", Results, Resolver);
EXPECT_THAT(toVector(Results), UnorderedElementsAre());
// And if there are multiple matches, it should return all of them.
Count = CommandCompletions::DiskDirectories("~La", Results, Resolver);
EXPECT_EQ(Count, Results.GetSize());
CommandCompletions::DiskDirectories("~La", Results, Resolver);
EXPECT_THAT(toVector(Results),
UnorderedElementsAre("~Lars" + sep, "~Larry" + sep));
}

View File

@ -26,7 +26,6 @@ TEST(CompletionRequest, Constructor) {
EXPECT_EQ(request.GetRawCursorPos(), cursor_pos);
EXPECT_EQ(request.GetCursorIndex(), arg_index);
EXPECT_EQ(request.GetCursorCharPosition(), arg_cursor_pos);
EXPECT_EQ(request.GetWordComplete(), false);
EXPECT_EQ(request.GetPartialParsedLine().GetArgumentCount(), 2u);
EXPECT_STREQ(request.GetPartialParsedLine().GetArgumentAtIndex(1), "b");