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 m_editline_up = std::make_unique<Editline>(
254 m_editline_up->SetIsInputCompleteCallback(
256 return this->IsInputCompleteCallback(editline, lines);
260 this->AutoCompleteCallback(request);
262 m_editline_up->SetRedrawCallback([
this]() { this->RedrawCallback(); });
265 m_editline_up->SetSuggestionCallback([
this](llvm::StringRef line) {
266 return this->SuggestionCallback(line);
280 int cursor_position) {
281 return this->FixIndentationCallback(editline, lines, cursor_position);
283 m_editline_up->SetFixIndentationCallback(std::move(f), indent_chars);
293#if LLDB_ENABLE_LIBEDIT
294 m_editline_up.reset();
309#if LLDB_ENABLE_LIBEDIT
311 m_editline_up->TerminalSizeChanged();
316static std::optional<std::string>
SplitLine(std::string &line_buffer) {
317 size_t pos = line_buffer.find(
'\n');
318 if (pos == std::string::npos)
321 std::string(StringRef(line_buffer.c_str(), pos).rtrim(
"\n\r"));
322 line_buffer = line_buffer.substr(pos + 1);
328static std::optional<std::string>
SplitLineEOF(std::string &line_buffer) {
329 if (llvm::all_of(line_buffer, llvm::isSpace))
331 std::string line = std::move(line_buffer);
337#if LLDB_ENABLE_LIBEDIT
339 return m_editline_up->GetLine(line, interrupted);
346 const char *prompt =
nullptr;
351 if (prompt ==
nullptr)
354 if (prompt && prompt[0]) {
357 locked_stream.
Printf(
"%s", prompt);
376 size_t bytes_read =
sizeof(buffer);
378 if (
error.Success() && !bytes_read) {
389 if (!got_line && in) {
391 char *r = fgets(buffer,
sizeof(buffer), in);
400 r = fgets(buffer,
sizeof(buffer), in);
402 if (r ==
nullptr && GetLastError() == ERROR_OPERATION_ABORTED)
406 if (ferror(in) && errno == EINTR)
421 return (
bool)got_line;
424#if LLDB_ENABLE_LIBEDIT
425bool IOHandlerEditline::IsInputCompleteCallback(
Editline *editline,
430int IOHandlerEditline::FixIndentationCallback(
Editline *editline,
432 int cursor_position) {
436std::optional<std::string>
437IOHandlerEditline::SuggestionCallback(llvm::StringRef line) {
438 return m_delegate.IOHandlerSuggestion(*
this, line);
445void IOHandlerEditline::RedrawCallback() {
452#if LLDB_ENABLE_LIBEDIT
454 return m_editline_up->GetPrompt();
459#if LLDB_ENABLE_LIBEDIT
468#if LLDB_ENABLE_LIBEDIT
471 m_editline_up->SetPromptAnsiPrefix(
473 m_editline_up->SetPromptAnsiSuffix(
483#if LLDB_ENABLE_LIBEDIT
485 m_editline_up->UseColor(use_color);
503#if LLDB_ENABLE_LIBEDIT
516#if LLDB_ENABLE_LIBEDIT
518 return m_editline_up->GetCurrentLine();
524#if LLDB_ENABLE_LIBEDIT
526 return m_editline_up->GetInputAsStringList();
541 bool success =
false;
542#if LLDB_ENABLE_LIBEDIT
556 locked_stream.
Printf(
"%u%s",
564 bool interrupted =
false;
565 if (
GetLine(line, interrupted) && !interrupted) {
567 done =
m_delegate.IOHandlerIsInputComplete(*
this, lines);
573#if LLDB_ENABLE_LIBEDIT
584 bool interrupted =
false;
590 m_delegate.IOHandlerInputInterrupted(*
this, line);
594 m_delegate.IOHandlerInputComplete(*
this, line);
600 if (
GetLine(line, interrupted)) {
602 m_delegate.IOHandlerInputInterrupted(*
this, line);
604 m_delegate.IOHandlerInputComplete(*
this, line);
613#if LLDB_ENABLE_LIBEDIT
615 m_editline_up->Cancel();
624#if LLDB_ENABLE_LIBEDIT
626 return m_editline_up->Interrupt();
632#if LLDB_ENABLE_LIBEDIT
634 m_editline_up->Interrupt();
639#if LLDB_ENABLE_LIBEDIT
642 m_editline_up->PrintAsync(stream_sp, s, len);
650 CONSOLE_SCREEN_BUFFER_INFO screen_buffer_info;
651 HANDLE console_handle = GetStdHandle(STD_OUTPUT_HANDLE);
652 GetConsoleScreenBufferInfo(console_handle, &screen_buffer_info);
653 COORD coord = screen_buffer_info.dwCursorPosition;
654 coord.X -= strlen(prompt);
657 SetConsoleCursorPosition(console_handle, coord);
669#if LLDB_ENABLE_LIBEDIT
671 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