17#include "lldb/Host/Config.h"
27#if LLDB_ENABLE_LIBEDIT
32#include "llvm/ADT/StringRef.h"
112 locked_Stream.
Write(s, len);
116 std::lock_guard<std::recursive_mutex> guard(
m_mutex);
119 m_top->PrintAsync(s, len, is_stdout);
124 bool default_response)
137 prompt_stream.
Printf(
": [Y/n] ");
139 prompt_stream.
Printf(
": [y/N] ");
155 const llvm::StringRef input = llvm::StringRef(line).rtrim();
163 if (input.size() == 1) {
180 if (input.equals_insensitive(
"yes")) {
183 }
else if (input.equals_insensitive(
"no")) {
189std::optional<std::string>
191 llvm::StringRef line) {
215 const char *editline_name,
216 llvm::StringRef prompt, llvm::StringRef continuation_prompt,
217 bool multi_line,
bool color, uint32_t line_number_start,
226 prompt, continuation_prompt, multi_line, color, line_number_start,
233 const char *editline_name,
234 llvm::StringRef prompt, llvm::StringRef continuation_prompt,
235 bool multi_line,
bool color, uint32_t line_number_start,
237 :
IOHandler(debugger, type, input_sp, output_sp, error_sp, flags),
238#if LLDB_ENABLE_LIBEDIT
247#if LLDB_ENABLE_LIBEDIT
251 const bool use_editline =
256 m_editline_up = std::make_unique<Editline>(
259 m_editline_up->SetIsInputCompleteCallback(
261 return this->IsInputCompleteCallback(editline, lines);
265 this->AutoCompleteCallback(request);
267 m_editline_up->SetRedrawCallback([
this]() { this->RedrawCallback(); });
270 m_editline_up->SetSuggestionCallback([
this](llvm::StringRef line) {
271 return this->SuggestionCallback(line);
285 int cursor_position) {
286 return this->FixIndentationCallback(editline, lines, cursor_position);
288 m_editline_up->SetFixIndentationCallback(std::move(f), indent_chars);
298#if LLDB_ENABLE_LIBEDIT
299 m_editline_up.reset();
314#if LLDB_ENABLE_LIBEDIT
316 m_editline_up->TerminalSizeChanged();
321static std::optional<std::string>
SplitLine(std::string &line_buffer) {
322 size_t pos = line_buffer.find(
'\n');
323 if (pos == std::string::npos)
326 std::string(StringRef(line_buffer.c_str(), pos).rtrim(
"\n\r"));
327 line_buffer = line_buffer.substr(pos + 1);
333static std::optional<std::string>
SplitLineEOF(std::string &line_buffer) {
334 if (llvm::all_of(line_buffer, llvm::isSpace))
336 std::string line = std::move(line_buffer);
342#if LLDB_ENABLE_LIBEDIT
344 return m_editline_up->GetLine(line, interrupted);
351 const char *prompt =
nullptr;
356 if (prompt ==
nullptr)
359 if (prompt && prompt[0]) {
362 locked_stream.
Printf(
"%s", prompt);
381 size_t bytes_read =
sizeof(buffer);
383 if (
error.Success() && !bytes_read) {
394 if (!got_line && in) {
396 char *r = fgets(buffer,
sizeof(buffer), in);
405 r = fgets(buffer,
sizeof(buffer), in);
407 if (r ==
nullptr && GetLastError() == ERROR_OPERATION_ABORTED)
411 if (ferror(in) && errno == EINTR)
426 return (
bool)got_line;
429#if LLDB_ENABLE_LIBEDIT
430bool IOHandlerEditline::IsInputCompleteCallback(
Editline *editline,
435int IOHandlerEditline::FixIndentationCallback(
Editline *editline,
437 int cursor_position) {
441std::optional<std::string>
442IOHandlerEditline::SuggestionCallback(llvm::StringRef line) {
443 return m_delegate.IOHandlerSuggestion(*
this, line);
450void IOHandlerEditline::RedrawCallback() {
457#if LLDB_ENABLE_LIBEDIT
459 return m_editline_up->GetPrompt();
464#if LLDB_ENABLE_LIBEDIT
473#if LLDB_ENABLE_LIBEDIT
476 m_editline_up->SetPromptAnsiPrefix(
478 m_editline_up->SetPromptAnsiSuffix(
488#if LLDB_ENABLE_LIBEDIT
490 m_editline_up->UseColor(use_color);
508#if LLDB_ENABLE_LIBEDIT
521#if LLDB_ENABLE_LIBEDIT
523 return m_editline_up->GetCurrentLine();
529#if LLDB_ENABLE_LIBEDIT
531 return m_editline_up->GetInputAsStringList();
546 bool success =
false;
547#if LLDB_ENABLE_LIBEDIT
561 locked_stream.
Printf(
"%u%s",
569 bool interrupted =
false;
570 if (
GetLine(line, interrupted) && !interrupted) {
572 done =
m_delegate.IOHandlerIsInputComplete(*
this, lines);
578#if LLDB_ENABLE_LIBEDIT
589 bool interrupted =
false;
595 m_delegate.IOHandlerInputInterrupted(*
this, line);
599 m_delegate.IOHandlerInputComplete(*
this, line);
605 if (
GetLine(line, interrupted)) {
607 m_delegate.IOHandlerInputInterrupted(*
this, line);
609 m_delegate.IOHandlerInputComplete(*
this, line);
618#if LLDB_ENABLE_LIBEDIT
620 m_editline_up->Cancel();
629#if LLDB_ENABLE_LIBEDIT
631 return m_editline_up->Interrupt();
637#if LLDB_ENABLE_LIBEDIT
639 m_editline_up->Interrupt();
644#if LLDB_ENABLE_LIBEDIT
647 m_editline_up->PrintAsync(stream_sp, s, len);
655 CONSOLE_SCREEN_BUFFER_INFO screen_buffer_info;
656 HANDLE console_handle = GetStdHandle(STD_OUTPUT_HANDLE);
657 GetConsoleScreenBufferInfo(console_handle, &screen_buffer_info);
658 COORD coord = screen_buffer_info.dwCursorPosition;
659 coord.X -= strlen(prompt);
662 SetConsoleCursorPosition(console_handle, coord);
674#if LLDB_ENABLE_LIBEDIT
676 m_editline_up->Refresh();
static llvm::raw_ostream & error(Stream &strm)
static std::optional< std::string > SplitLine(std::string &line_buffer)
static std::optional< std::string > SplitLineEOF(std::string &line_buffer)
static bool InvokeCommonCompletionCallbacks(CommandInterpreter &interpreter, uint32_t completion_mask, lldb_private::CompletionRequest &request, SearchFilter *searcher)
std::optional< std::string > GetAutoSuggestionForCommand(llvm::StringRef line)
Returns the auto-suggestion string that should be added to the given command line.
void HandleCompletion(CompletionRequest &request)
"lldb/Utility/ArgCompletionRequest.h"
void AddCompletion(llvm::StringRef completion, llvm::StringRef description="", CompletionMode mode=CompletionMode::Normal)
Adds a possible completion string.
unsigned GetRawCursorPos() const
A class to manage flag bits.
llvm::StringRef GetAutosuggestionAnsiPrefix() const
CommandInterpreter & GetCommandInterpreter()
llvm::StringRef GetAutosuggestionAnsiSuffix() const
bool GetUseAutosuggestion() const
void AdoptTopIOHandlerFilesIfInvalid(lldb::FileSP &in, lldb::LockableStreamFileSP &out, lldb::LockableStreamFileSP &err)
Instances of Editline provide an abstraction over libedit's EditLine facility.
const bool m_default_response
IOHandlerConfirm(Debugger &debugger, llvm::StringRef prompt, bool default_response)
void IOHandlerInputComplete(IOHandler &io_handler, std::string &data) override
Called when a line or lines have been retrieved.
void IOHandlerComplete(IOHandler &io_handler, CompletionRequest &request) override
~IOHandlerConfirm() override
A delegate class for use with IOHandler subclasses.
virtual void IOHandlerComplete(IOHandler &io_handler, CompletionRequest &request)
virtual const char * IOHandlerGetFixIndentationCharacters()
virtual bool IOHandlerIsInputComplete(IOHandler &io_handler, StringList &lines)
Called to determine whether typing enter after the last line in lines should end input.
virtual std::optional< std::string > IOHandlerSuggestion(IOHandler &io_handler, llvm::StringRef line)
virtual int IOHandlerFixIndentation(IOHandler &io_handler, const StringList &lines, int cursor_position)
Called when a new line is created or one of an identified set of indentation characters is typed.
void PrintAsync(const char *s, size_t len, bool is_stdout) override
bool SetPrompt(llvm::StringRef prompt) override
bool Interrupt() override
bool GetLine(std::string &line, bool &interrupted)
void TerminalSizeChanged() override
~IOHandlerEditline() override
uint32_t m_base_line_number
bool GetLines(StringList &lines, bool &interrupted)
std::string m_continuation_prompt
const char * GetContinuationPrompt()
void SetBaseLineNumber(uint32_t line)
IOHandlerEditline(Debugger &debugger, IOHandler::Type type, const char *editline_name, llvm::StringRef prompt, llvm::StringRef continuation_prompt, bool multi_line, bool color, uint32_t line_number_start, IOHandlerDelegate &delegate)
void SetContinuationPrompt(llvm::StringRef prompt)
StringList * m_current_lines_ptr
IOHandlerDelegate & m_delegate
bool SetUseColor(bool use_color) override
std::string m_line_buffer
const char * GetPrompt() override
uint32_t GetCurrentLineIndex() const
void Deactivate() override
StringList GetCurrentLines() const
bool PrintAsync(const char *s, size_t len, bool is_stdout)
std::recursive_mutex m_mutex
virtual void PrintAsync(const char *s, size_t len, bool is_stdout)
Predicate< bool > m_popped
bool GetIsRealTerminal()
Check if the input is coming from a real terminal.
lldb::FileSP GetInputFileSP()
virtual void Deactivate()
lldb::LockableStreamFileSP m_output_sp
lldb::LockableStreamFileSP m_error_sp
IOHandler(Debugger &debugger, IOHandler::Type type)
bool GetIsInteractive()
Check if the input is being supplied interactively by a user.
lldb::LockableStreamFileSP GetErrorStreamFileSP()
lldb::LockableStreamFileSP GetOutputStreamFileSP()
llvm::StringRef GetString() const
size_t Write(const void *src, size_t src_len)
Output character bytes to the stream.
size_t Printf(const char *format,...) __attribute__((format(printf
Output printf formatted output to the stream.
size_t PutCString(llvm::StringRef cstr)
Output a C string to the stream.
std::string CopyList(const char *item_preamble=nullptr, const char *items_sep="\n") const
void AppendString(const std::string &s)
std::string FormatAnsiTerminalCodes(llvm::StringRef format, bool do_color=true)
llvm::unique_function< int(Editline *, StringList &, int)> FixIndentationCallbackType
A class that represents a running process on the host machine.
@ eBroadcastOnChange
Only broadcast if the value changes when the value is modified.
@ eVariablePathCompletion
std::shared_ptr< lldb_private::LockableStreamFile > LockableStreamFileSP
std::shared_ptr< lldb_private::File > FileSP