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] ");
162 if (line.size() == 1) {
179 if (line ==
"yes" || line ==
"YES" || line ==
"Yes") {
182 }
else if (line ==
"no" || line ==
"NO" || line ==
"No") {
188std::optional<std::string>
190 llvm::StringRef line) {
214 const char *editline_name,
215 llvm::StringRef prompt, llvm::StringRef continuation_prompt,
216 bool multi_line,
bool color, uint32_t line_number_start,
225 prompt, continuation_prompt, multi_line, color, line_number_start,
232 const char *editline_name,
233 llvm::StringRef prompt, llvm::StringRef continuation_prompt,
234 bool multi_line,
bool color, uint32_t line_number_start,
236 :
IOHandler(debugger, type, input_sp, output_sp, error_sp, flags),
237#if LLDB_ENABLE_LIBEDIT
246#if LLDB_ENABLE_LIBEDIT
250 m_editline_up = std::make_unique<Editline>(
253 m_editline_up->SetIsInputCompleteCallback(
255 return this->IsInputCompleteCallback(editline, lines);
259 this->AutoCompleteCallback(request);
261 m_editline_up->SetRedrawCallback([
this]() { this->RedrawCallback(); });
264 m_editline_up->SetSuggestionCallback([
this](llvm::StringRef line) {
265 return this->SuggestionCallback(line);
279 int cursor_position) {
280 return this->FixIndentationCallback(editline, lines, cursor_position);
282 m_editline_up->SetFixIndentationCallback(std::move(f), indent_chars);
292#if LLDB_ENABLE_LIBEDIT
293 m_editline_up.reset();
308#if LLDB_ENABLE_LIBEDIT
310 m_editline_up->TerminalSizeChanged();
315static std::optional<std::string>
SplitLine(std::string &line_buffer) {
316 size_t pos = line_buffer.find(
'\n');
317 if (pos == std::string::npos)
320 std::string(StringRef(line_buffer.c_str(), pos).rtrim(
"\n\r"));
321 line_buffer = line_buffer.substr(pos + 1);
327static std::optional<std::string>
SplitLineEOF(std::string &line_buffer) {
328 if (llvm::all_of(line_buffer, llvm::isSpace))
330 std::string line = std::move(line_buffer);
336#if LLDB_ENABLE_LIBEDIT
338 return m_editline_up->GetLine(line, interrupted);
345 const char *prompt =
nullptr;
350 if (prompt ==
nullptr)
353 if (prompt && prompt[0]) {
356 locked_stream.
Printf(
"%s", prompt);
375 size_t bytes_read =
sizeof(buffer);
377 if (
error.Success() && !bytes_read) {
388 if (!got_line && in) {
390 char *r = fgets(buffer,
sizeof(buffer), in);
399 r = fgets(buffer,
sizeof(buffer), in);
401 if (r ==
nullptr && GetLastError() == ERROR_OPERATION_ABORTED)
405 if (ferror(in) && errno == EINTR)
420 return (
bool)got_line;
423#if LLDB_ENABLE_LIBEDIT
424bool IOHandlerEditline::IsInputCompleteCallback(
Editline *editline,
429int IOHandlerEditline::FixIndentationCallback(
Editline *editline,
431 int cursor_position) {
435std::optional<std::string>
436IOHandlerEditline::SuggestionCallback(llvm::StringRef line) {
437 return m_delegate.IOHandlerSuggestion(*
this, line);
444void IOHandlerEditline::RedrawCallback() {
451#if LLDB_ENABLE_LIBEDIT
453 return m_editline_up->GetPrompt();
458#if LLDB_ENABLE_LIBEDIT
467#if LLDB_ENABLE_LIBEDIT
470 m_editline_up->SetPromptAnsiPrefix(
472 m_editline_up->SetPromptAnsiSuffix(
482#if LLDB_ENABLE_LIBEDIT
484 m_editline_up->UseColor(use_color);
502#if LLDB_ENABLE_LIBEDIT
515#if LLDB_ENABLE_LIBEDIT
517 return m_editline_up->GetCurrentLine();
523#if LLDB_ENABLE_LIBEDIT
525 return m_editline_up->GetInputAsStringList();
540 bool success =
false;
541#if LLDB_ENABLE_LIBEDIT
555 locked_stream.
Printf(
"%u%s",
563 bool interrupted =
false;
564 if (
GetLine(line, interrupted) && !interrupted) {
566 done =
m_delegate.IOHandlerIsInputComplete(*
this, lines);
572#if LLDB_ENABLE_LIBEDIT
583 bool interrupted =
false;
589 m_delegate.IOHandlerInputInterrupted(*
this, line);
593 m_delegate.IOHandlerInputComplete(*
this, line);
599 if (
GetLine(line, interrupted)) {
601 m_delegate.IOHandlerInputInterrupted(*
this, line);
603 m_delegate.IOHandlerInputComplete(*
this, line);
612#if LLDB_ENABLE_LIBEDIT
614 m_editline_up->Cancel();
623#if LLDB_ENABLE_LIBEDIT
625 return m_editline_up->Interrupt();
631#if LLDB_ENABLE_LIBEDIT
633 m_editline_up->Interrupt();
638#if LLDB_ENABLE_LIBEDIT
641 m_editline_up->PrintAsync(stream_sp, s, len);
649 CONSOLE_SCREEN_BUFFER_INFO screen_buffer_info;
650 HANDLE console_handle = GetStdHandle(STD_OUTPUT_HANDLE);
651 GetConsoleScreenBufferInfo(console_handle, &screen_buffer_info);
652 COORD coord = screen_buffer_info.dwCursorPosition;
653 coord.X -= strlen(prompt);
656 SetConsoleCursorPosition(console_handle, coord);
668#if LLDB_ENABLE_LIBEDIT
670 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