private:
#if LLDB_ENABLE_LIBEDIT
- static bool IsInputCompleteCallback(Editline *editline, StringList &lines,
- void *baton);
+ bool IsInputCompleteCallback(Editline *editline, StringList &lines);
- static int FixIndentationCallback(Editline *editline, const StringList &lines,
- int cursor_position, void *baton);
+ int FixIndentationCallback(Editline *editline, const StringList &lines,
+ int cursor_position);
- static llvm::Optional<std::string> SuggestionCallback(llvm::StringRef line,
- void *baton);
+ llvm::Optional<std::string> SuggestionCallback(llvm::StringRef line);
- static void AutoCompleteCallback(CompletionRequest &request, void *baton);
+ void AutoCompleteCallback(CompletionRequest &request);
#endif
protected:
#include <sstream>
#include <vector>
-#include "lldb/Host/ConnectionFileDescriptor.h"
#include "lldb/lldb-private.h"
#if defined(_WIN32)
#include "lldb/Utility/CompletionRequest.h"
#include "lldb/Utility/FileSpec.h"
#include "lldb/Utility/Predicate.h"
+#include "lldb/Utility/StringList.h"
+
+#include "llvm/ADT/FunctionExtras.h"
namespace lldb_private {
namespace line_editor {
using EditLineGetCharType = char;
#endif
-typedef int (*EditlineGetCharCallbackType)(::EditLine *editline,
- EditLineGetCharType *c);
-typedef unsigned char (*EditlineCommandCallbackType)(::EditLine *editline,
- int ch);
-typedef const char *(*EditlinePromptCallbackType)(::EditLine *editline);
+using EditlineGetCharCallbackType = int (*)(::EditLine *editline,
+ EditLineGetCharType *c);
+using EditlineCommandCallbackType = unsigned char (*)(::EditLine *editline,
+ int ch);
+using EditlinePromptCallbackType = const char *(*)(::EditLine *editline);
class EditlineHistory;
-typedef std::shared_ptr<EditlineHistory> EditlineHistorySP;
+using EditlineHistorySP = std::shared_ptr<EditlineHistory>;
-typedef bool (*IsInputCompleteCallbackType)(Editline *editline,
- StringList &lines, void *baton);
+using IsInputCompleteCallbackType =
+ llvm::unique_function<bool(Editline *, StringList &)>;
-typedef int (*FixIndentationCallbackType)(Editline *editline,
- const StringList &lines,
- int cursor_position, void *baton);
+using FixIndentationCallbackType =
+ llvm::unique_function<int(Editline *, StringList &, int)>;
-typedef llvm::Optional<std::string> (*SuggestionCallbackType)(
- llvm::StringRef line, void *baton);
+using SuggestionCallbackType =
+ llvm::unique_function<llvm::Optional<std::string>(llvm::StringRef)>;
-typedef void (*CompleteCallbackType)(CompletionRequest &request, void *baton);
+using CompleteCallbackType = llvm::unique_function<void(CompletionRequest &)>;
/// Status used to decide when and how to start editing another line in
/// multi-line sessions
bool Cancel();
/// Register a callback for autosuggestion.
- void SetSuggestionCallback(SuggestionCallbackType callback, void *baton);
+ void SetSuggestionCallback(SuggestionCallbackType callback) {
+ m_suggestion_callback = std::move(callback);
+ }
/// Register a callback for the tab key
- void SetAutoCompleteCallback(CompleteCallbackType callback, void *baton);
+ void SetAutoCompleteCallback(CompleteCallbackType callback) {
+ m_completion_callback = std::move(callback);
+ }
/// Register a callback for testing whether multi-line input is complete
- void SetIsInputCompleteCallback(IsInputCompleteCallbackType callback,
- void *baton);
+ void SetIsInputCompleteCallback(IsInputCompleteCallbackType callback) {
+ m_is_input_complete_callback = std::move(callback);
+ }
/// Register a callback for determining the appropriate indentation for a line
/// when creating a newline. An optional set of insertable characters can
- /// also
- /// trigger the callback.
- bool SetFixIndentationCallback(FixIndentationCallbackType callback,
- void *baton, const char *indent_chars);
+ /// also trigger the callback.
+ void SetFixIndentationCallback(FixIndentationCallbackType callback,
+ const char *indent_chars) {
+ m_fix_indentation_callback = std::move(callback);
+ m_fix_indentation_callback_chars = indent_chars;
+ }
/// Prompts for and reads a single line of user input.
bool GetLine(std::string &line, bool &interrupted);
FILE *m_output_file;
FILE *m_error_file;
ConnectionFileDescriptor m_input_connection;
- IsInputCompleteCallbackType m_is_input_complete_callback = nullptr;
- void *m_is_input_complete_callback_baton = nullptr;
- FixIndentationCallbackType m_fix_indentation_callback = nullptr;
- void *m_fix_indentation_callback_baton = nullptr;
+
+ IsInputCompleteCallbackType m_is_input_complete_callback;
+
+ FixIndentationCallbackType m_fix_indentation_callback;
const char *m_fix_indentation_callback_chars = nullptr;
- CompleteCallbackType m_completion_callback = nullptr;
- void *m_completion_callback_baton = nullptr;
- SuggestionCallbackType m_suggestion_callback = nullptr;
- void *m_suggestion_callback_baton = nullptr;
+
+ CompleteCallbackType m_completion_callback;
+
+ SuggestionCallbackType m_suggestion_callback;
+
std::size_t m_previous_autosuggestion_size = 0;
std::mutex m_output_mutex;
};
m_editline_up = std::make_unique<Editline>(editline_name, GetInputFILE(),
GetOutputFILE(), GetErrorFILE(),
m_color_prompts);
- m_editline_up->SetIsInputCompleteCallback(IsInputCompleteCallback, this);
- m_editline_up->SetAutoCompleteCallback(AutoCompleteCallback, this);
- if (debugger.GetUseAutosuggestion() && debugger.GetUseColor())
- m_editline_up->SetSuggestionCallback(SuggestionCallback, this);
+ m_editline_up->SetIsInputCompleteCallback(
+ [this](Editline *editline, StringList &lines) {
+ return this->IsInputCompleteCallback(editline, lines);
+ });
+
+ m_editline_up->SetAutoCompleteCallback([this](CompletionRequest &request) {
+ this->AutoCompleteCallback(request);
+ });
+
+ if (debugger.GetUseAutosuggestion() && debugger.GetUseColor()) {
+ m_editline_up->SetSuggestionCallback([this](llvm::StringRef line) {
+ return this->SuggestionCallback(line);
+ });
+ }
// See if the delegate supports fixing indentation
const char *indent_chars = delegate.IOHandlerGetFixIndentationCharacters();
if (indent_chars) {
// The delegate does support indentation, hook it up so when any
// indentation character is typed, the delegate gets a chance to fix it
- m_editline_up->SetFixIndentationCallback(FixIndentationCallback, this,
- indent_chars);
+ FixIndentationCallbackType f = [this](Editline *editline,
+ const StringList &lines,
+ int cursor_position) {
+ return this->FixIndentationCallback(editline, lines, cursor_position);
+ };
+ m_editline_up->SetFixIndentationCallback(std::move(f), indent_chars);
}
}
#endif
#if LLDB_ENABLE_LIBEDIT
bool IOHandlerEditline::IsInputCompleteCallback(Editline *editline,
- StringList &lines,
- void *baton) {
- IOHandlerEditline *editline_reader = (IOHandlerEditline *)baton;
- return editline_reader->m_delegate.IOHandlerIsInputComplete(*editline_reader,
- lines);
+ StringList &lines) {
+ return m_delegate.IOHandlerIsInputComplete(*this, lines);
}
int IOHandlerEditline::FixIndentationCallback(Editline *editline,
const StringList &lines,
- int cursor_position,
- void *baton) {
- IOHandlerEditline *editline_reader = (IOHandlerEditline *)baton;
- return editline_reader->m_delegate.IOHandlerFixIndentation(
- *editline_reader, lines, cursor_position);
+ int cursor_position) {
+ return m_delegate.IOHandlerFixIndentation(*this, lines, cursor_position);
}
llvm::Optional<std::string>
-IOHandlerEditline::SuggestionCallback(llvm::StringRef line, void *baton) {
- IOHandlerEditline *editline_reader = static_cast<IOHandlerEditline *>(baton);
- if (editline_reader)
- return editline_reader->m_delegate.IOHandlerSuggestion(*editline_reader,
- line);
-
- return llvm::None;
+IOHandlerEditline::SuggestionCallback(llvm::StringRef line) {
+ return m_delegate.IOHandlerSuggestion(*this, line);
}
-void IOHandlerEditline::AutoCompleteCallback(CompletionRequest &request,
- void *baton) {
- IOHandlerEditline *editline_reader = (IOHandlerEditline *)baton;
- if (editline_reader)
- editline_reader->m_delegate.IOHandlerComplete(*editline_reader, request);
+void IOHandlerEditline::AutoCompleteCallback(CompletionRequest &request) {
+ m_delegate.IOHandlerComplete(*this, request);
}
#endif
#include <iomanip>
#include <limits.h>
-#include "lldb/Host/ConnectionFileDescriptor.h"
#include "lldb/Host/Editline.h"
+
+#include "lldb/Host/ConnectionFileDescriptor.h"
#include "lldb/Host/FileSystem.h"
#include "lldb/Host/Host.h"
#include "lldb/Utility/CompletionRequest.h"
lines.AppendString(new_line_fragment);
#endif
- int indent_correction = m_fix_indentation_callback(
- this, lines, 0, m_fix_indentation_callback_baton);
+ int indent_correction = m_fix_indentation_callback(this, lines, 0);
new_line_fragment = FixIndentation(new_line_fragment, indent_correction);
m_revert_cursor_index = GetIndentation(new_line_fragment);
}
info->cursor == info->lastchar) {
if (m_is_input_complete_callback) {
auto lines = GetInputAsStringList();
- if (!m_is_input_complete_callback(this, lines,
- m_is_input_complete_callback_baton)) {
+ if (!m_is_input_complete_callback(this, lines)) {
return BreakLineCommand(ch);
}
if (m_fix_indentation_callback) {
StringList lines = GetInputAsStringList();
lines.AppendString("");
- indentation = m_fix_indentation_callback(
- this, lines, 0, m_fix_indentation_callback_baton);
+ indentation = m_fix_indentation_callback(this, lines, 0);
}
m_input_lines.insert(
m_input_lines.end(),
// Save the edits and determine the correct indentation level
SaveEditedLine();
StringList lines = GetInputAsStringList(m_current_line_index + 1);
- int indent_correction = m_fix_indentation_callback(
- this, lines, cursor_position, m_fix_indentation_callback_baton);
+ int indent_correction =
+ m_fix_indentation_callback(this, lines, cursor_position);
// If it is already correct no special work is needed
if (indent_correction == 0)
}
unsigned char Editline::TabCommand(int ch) {
- if (m_completion_callback == nullptr)
+ if (!m_completion_callback)
return CC_ERROR;
const LineInfo *line_info = el_line(m_editline);
CompletionResult result;
CompletionRequest request(line, cursor_index, result);
- m_completion_callback(request, m_completion_callback_baton);
+ m_completion_callback(request);
llvm::ArrayRef<CompletionResult::Completion> results = result.GetResults();
}
unsigned char Editline::ApplyAutosuggestCommand(int ch) {
+ if (!m_suggestion_callback) {
+ return CC_REDISPLAY;
+ }
+
const LineInfo *line_info = el_line(m_editline);
llvm::StringRef line(line_info->buffer,
line_info->lastchar - line_info->buffer);
- if (llvm::Optional<std::string> to_add =
- m_suggestion_callback(line, m_suggestion_callback_baton))
+ if (llvm::Optional<std::string> to_add = m_suggestion_callback(line))
el_insertstr(m_editline, to_add->c_str());
return CC_REDISPLAY;
unsigned char Editline::TypedCharacter(int ch) {
std::string typed = std::string(1, ch);
el_insertstr(m_editline, typed.c_str());
+
+ if (!m_suggestion_callback) {
+ return CC_REDISPLAY;
+ }
+
const LineInfo *line_info = el_line(m_editline);
llvm::StringRef line(line_info->buffer,
line_info->lastchar - line_info->buffer);
- if (llvm::Optional<std::string> to_add =
- m_suggestion_callback(line, m_suggestion_callback_baton)) {
+ if (llvm::Optional<std::string> to_add = m_suggestion_callback(line)) {
std::string to_add_color = ANSI_FAINT + to_add.getValue() + ANSI_UNFAINT;
fputs(typed.c_str(), m_output_file);
fputs(to_add_color.c_str(), m_output_file);
return result;
}
-void Editline::SetSuggestionCallback(SuggestionCallbackType callback,
- void *baton) {
- m_suggestion_callback = callback;
- m_suggestion_callback_baton = baton;
-}
-
-void Editline::SetAutoCompleteCallback(CompleteCallbackType callback,
- void *baton) {
- m_completion_callback = callback;
- m_completion_callback_baton = baton;
-}
-
-void Editline::SetIsInputCompleteCallback(IsInputCompleteCallbackType callback,
- void *baton) {
- m_is_input_complete_callback = callback;
- m_is_input_complete_callback_baton = baton;
-}
-
-bool Editline::SetFixIndentationCallback(FixIndentationCallbackType callback,
- void *baton,
- const char *indent_chars) {
- m_fix_indentation_callback = callback;
- m_fix_indentation_callback_baton = baton;
- m_fix_indentation_callback_chars = indent_chars;
- return false;
-}
-
bool Editline::GetLine(std::string &line, bool &interrupted) {
ConfigureEditor(false);
m_input_lines = std::vector<EditLineStringType>();
void ConsumeAllOutput();
private:
- static bool IsInputComplete(lldb_private::Editline *editline,
- lldb_private::StringList &lines, void *baton);
+ bool IsInputComplete(lldb_private::Editline *editline,
+ lldb_private::StringList &lines);
std::unique_ptr<lldb_private::Editline> _editline_sp;
_editline_sp->SetPrompt("> ");
// Hookup our input complete callback.
- _editline_sp->SetIsInputCompleteCallback(IsInputComplete, this);
+ auto input_complete_cb = [this](Editline *editline, StringList &lines) {
+ return this->IsInputComplete(editline, lines);
+ };
+ _editline_sp->SetIsInputCompleteCallback(input_complete_cb);
}
void EditlineAdapter::CloseInput() {
}
bool EditlineAdapter::IsInputComplete(lldb_private::Editline *editline,
- lldb_private::StringList &lines,
- void *baton) {
+ lldb_private::StringList &lines) {
// We'll call ourselves complete if we've received a balanced set of braces.
int start_block_count = 0;
int brace_balance = 0;