//===-- Editline.cpp ------------------------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//

#include <iomanip>
#include <limits.h>

#include "lldb/Host/ConnectionFileDescriptor.h"
#include "lldb/Host/Editline.h"
#include "lldb/Host/FileSystem.h"
#include "lldb/Host/Host.h"
#include "lldb/Utility/CompletionRequest.h"
#include "lldb/Utility/FileSpec.h"
#include "lldb/Utility/LLDBAssert.h"
#include "lldb/Utility/SelectHelper.h"
#include "lldb/Utility/Status.h"
#include "lldb/Utility/StreamString.h"
#include "lldb/Utility/StringList.h"
#include "lldb/Utility/Timeout.h"

#include "llvm/Support/FileSystem.h"
#include "llvm/Support/Threading.h"

using namespace lldb_private;
using namespace lldb_private::line_editor;

// Workaround for what looks like an OS X-specific issue, but other platforms
// may benefit from something similar if issues arise.  The libedit library
// doesn't explicitly initialize the curses termcap library, which it gets away
// with until TERM is set to VT100 where it stumbles over an implementation
// assumption that may not exist on other platforms.  The setupterm() function
// would normally require headers that don't work gracefully in this context,
// so the function declaration has been hoisted here.
#if defined(__APPLE__)
extern "C" {
int setupterm(char *term, int fildes, int *errret);
}
#define USE_SETUPTERM_WORKAROUND
#endif

// Editline uses careful cursor management to achieve the illusion of editing a
// multi-line block of text with a single line editor.  Preserving this
// illusion requires fairly careful management of cursor state.  Read and
// understand the relationship between DisplayInput(), MoveCursor(),
// SetCurrentLine(), and SaveEditedLine() before making changes.

/// https://www.ecma-international.org/publications/files/ECMA-ST/Ecma-048.pdf
#define ESCAPE "\x1b"
/// Faint, decreased intensity or second colour.
#define ANSI_FAINT ESCAPE "[2m"
/// Normal colour or normal intensity (neither bold nor faint).
#define ANSI_UNFAINT ESCAPE "[0m"
#define ANSI_CLEAR_BELOW ESCAPE "[J"
#define ANSI_CLEAR_RIGHT ESCAPE "[K"
#define ANSI_SET_COLUMN_N ESCAPE "[%dG"
#define ANSI_UP_N_ROWS ESCAPE "[%dA"
#define ANSI_DOWN_N_ROWS ESCAPE "[%dB"

#if LLDB_EDITLINE_USE_WCHAR

#define EditLineConstString(str) L##str
#define EditLineStringFormatSpec "%ls"

#else

#define EditLineConstString(str) str
#define EditLineStringFormatSpec "%s"

// use #defines so wide version functions and structs will resolve to old
// versions for case of libedit not built with wide char support
#define history_w history
#define history_winit history_init
#define history_wend history_end
#define HistoryW History
#define HistEventW HistEvent
#define LineInfoW LineInfo

#define el_wgets el_gets
#define el_wgetc el_getc
#define el_wpush el_push
#define el_wparse el_parse
#define el_wset el_set
#define el_wget el_get
#define el_wline el_line
#define el_winsertstr el_insertstr
#define el_wdeletestr el_deletestr

#endif // #if LLDB_EDITLINE_USE_WCHAR

bool IsOnlySpaces(const EditLineStringType &content) {
  for (wchar_t ch : content) {
    if (ch != EditLineCharType(' '))
      return false;
  }
  return true;
}

static int GetOperation(HistoryOperation op) {
  // The naming used by editline for the history operations is counter
  // intuitive to how it's used in LLDB's editline implementation.
  //
  //  - The H_LAST returns the oldest entry in the history.
  //
  //  - The H_PREV operation returns the previous element in the history, which
  //    is newer than the current one.
  //
  //  - The H_CURR returns the current entry in the history.
  //
  //  - The H_NEXT operation returns the next element in the history, which is
  //    older than the current one.
  //
  //  - The H_FIRST returns the most recent entry in the history.
  //
  // The naming of the enum entries match the semantic meaning.
  switch(op) {
    case HistoryOperation::Oldest:
      return H_LAST;
    case HistoryOperation::Older:
      return H_NEXT;
    case HistoryOperation::Current:
      return H_CURR;
    case HistoryOperation::Newer:
      return H_PREV;
    case HistoryOperation::Newest:
      return H_FIRST;
  }
  llvm_unreachable("Fully covered switch!");
}


EditLineStringType CombineLines(const std::vector<EditLineStringType> &lines) {
  EditLineStringStreamType combined_stream;
  for (EditLineStringType line : lines) {
    combined_stream << line.c_str() << "\n";
  }
  return combined_stream.str();
}

std::vector<EditLineStringType> SplitLines(const EditLineStringType &input) {
  std::vector<EditLineStringType> result;
  size_t start = 0;
  while (start < input.length()) {
    size_t end = input.find('\n', start);
    if (end == std::string::npos) {
      result.push_back(input.substr(start));
      break;
    }
    result.push_back(input.substr(start, end - start));
    start = end + 1;
  }
  return result;
}

EditLineStringType FixIndentation(const EditLineStringType &line,
                                  int indent_correction) {
  if (indent_correction == 0)
    return line;
  if (indent_correction < 0)
    return line.substr(-indent_correction);
  return EditLineStringType(indent_correction, EditLineCharType(' ')) + line;
}

int GetIndentation(const EditLineStringType &line) {
  int space_count = 0;
  for (EditLineCharType ch : line) {
    if (ch != EditLineCharType(' '))
      break;
    ++space_count;
  }
  return space_count;
}

bool IsInputPending(FILE *file) {
  // FIXME: This will be broken on Windows if we ever re-enable Editline.  You
  // can't use select
  // on something that isn't a socket.  This will have to be re-written to not
  // use a FILE*, but instead use some kind of yet-to-be-created abstraction
  // that select-like functionality on non-socket objects.
  const int fd = fileno(file);
  SelectHelper select_helper;
  select_helper.SetTimeout(std::chrono::microseconds(0));
  select_helper.FDSetRead(fd);
  return select_helper.Select().Success();
}

namespace lldb_private {
namespace line_editor {
typedef std::weak_ptr<EditlineHistory> EditlineHistoryWP;

// EditlineHistory objects are sometimes shared between multiple Editline
// instances with the same program name.

class EditlineHistory {
private:
  // Use static GetHistory() function to get a EditlineHistorySP to one of
  // these objects
  EditlineHistory(const std::string &prefix, uint32_t size, bool unique_entries)
      : m_history(nullptr), m_event(), m_prefix(prefix), m_path() {
    m_history = history_winit();
    history_w(m_history, &m_event, H_SETSIZE, size);
    if (unique_entries)
      history_w(m_history, &m_event, H_SETUNIQUE, 1);
  }

  const char *GetHistoryFilePath() {
    // Compute the history path lazily.
    if (m_path.empty() && m_history && !m_prefix.empty()) {
      llvm::SmallString<128> lldb_history_file;
      llvm::sys::path::home_directory(lldb_history_file);
      llvm::sys::path::append(lldb_history_file, ".lldb");

      // LLDB stores its history in ~/.lldb/. If for some reason this directory
      // isn't writable or cannot be created, history won't be available.
      if (!llvm::sys::fs::create_directory(lldb_history_file)) {
#if LLDB_EDITLINE_USE_WCHAR
        std::string filename = m_prefix + "-widehistory";
#else
        std::string filename = m_prefix + "-history";
#endif
        llvm::sys::path::append(lldb_history_file, filename);
        m_path = std::string(lldb_history_file.str());
      }
    }

    if (m_path.empty())
      return nullptr;

    return m_path.c_str();
  }

public:
  ~EditlineHistory() {
    Save();

    if (m_history) {
      history_wend(m_history);
      m_history = nullptr;
    }
  }

  static EditlineHistorySP GetHistory(const std::string &prefix) {
    typedef std::map<std::string, EditlineHistoryWP> WeakHistoryMap;
    static std::recursive_mutex g_mutex;
    static WeakHistoryMap g_weak_map;
    std::lock_guard<std::recursive_mutex> guard(g_mutex);
    WeakHistoryMap::const_iterator pos = g_weak_map.find(prefix);
    EditlineHistorySP history_sp;
    if (pos != g_weak_map.end()) {
      history_sp = pos->second.lock();
      if (history_sp)
        return history_sp;
      g_weak_map.erase(pos);
    }
    history_sp.reset(new EditlineHistory(prefix, 800, true));
    g_weak_map[prefix] = history_sp;
    return history_sp;
  }

  bool IsValid() const { return m_history != nullptr; }

  HistoryW *GetHistoryPtr() { return m_history; }

  void Enter(const EditLineCharType *line_cstr) {
    if (m_history)
      history_w(m_history, &m_event, H_ENTER, line_cstr);
  }

  bool Load() {
    if (m_history) {
      const char *path = GetHistoryFilePath();
      if (path) {
        history_w(m_history, &m_event, H_LOAD, path);
        return true;
      }
    }
    return false;
  }

  bool Save() {
    if (m_history) {
      const char *path = GetHistoryFilePath();
      if (path) {
        history_w(m_history, &m_event, H_SAVE, path);
        return true;
      }
    }
    return false;
  }

protected:
  HistoryW *m_history; // The history object
  HistEventW m_event;  // The history event needed to contain all history events
  std::string m_prefix; // The prefix name (usually the editline program name)
                        // to use when loading/saving history
  std::string m_path;   // Path to the history file
};
}
}

// Editline private methods

void Editline::SetBaseLineNumber(int line_number) {
  m_base_line_number = line_number;
  m_line_number_digits =
      std::max<int>(3, std::to_string(line_number).length() + 1);
}

std::string Editline::PromptForIndex(int line_index) {
  bool use_line_numbers = m_multiline_enabled && m_base_line_number > 0;
  std::string prompt = m_set_prompt;
  if (use_line_numbers && prompt.length() == 0)
    prompt = ": ";
  std::string continuation_prompt = prompt;
  if (m_set_continuation_prompt.length() > 0) {
    continuation_prompt = m_set_continuation_prompt;

    // Ensure that both prompts are the same length through space padding
    while (continuation_prompt.length() < prompt.length()) {
      continuation_prompt += ' ';
    }
    while (prompt.length() < continuation_prompt.length()) {
      prompt += ' ';
    }
  }

  if (use_line_numbers) {
    StreamString prompt_stream;
    prompt_stream.Printf(
        "%*d%s", m_line_number_digits, m_base_line_number + line_index,
        (line_index == 0) ? prompt.c_str() : continuation_prompt.c_str());
    return std::string(std::move(prompt_stream.GetString()));
  }
  return (line_index == 0) ? prompt : continuation_prompt;
}

void Editline::SetCurrentLine(int line_index) {
  m_current_line_index = line_index;
  m_current_prompt = PromptForIndex(line_index);
}

int Editline::GetPromptWidth() { return (int)PromptForIndex(0).length(); }

bool Editline::IsEmacs() {
  const char *editor;
  el_get(m_editline, EL_EDITOR, &editor);
  return editor[0] == 'e';
}

bool Editline::IsOnlySpaces() {
  const LineInfoW *info = el_wline(m_editline);
  for (const EditLineCharType *character = info->buffer;
       character < info->lastchar; character++) {
    if (*character != ' ')
      return false;
  }
  return true;
}

int Editline::GetLineIndexForLocation(CursorLocation location, int cursor_row) {
  int line = 0;
  if (location == CursorLocation::EditingPrompt ||
      location == CursorLocation::BlockEnd ||
      location == CursorLocation::EditingCursor) {
    for (unsigned index = 0; index < m_current_line_index; index++) {
      line += CountRowsForLine(m_input_lines[index]);
    }
    if (location == CursorLocation::EditingCursor) {
      line += cursor_row;
    } else if (location == CursorLocation::BlockEnd) {
      for (unsigned index = m_current_line_index; index < m_input_lines.size();
           index++) {
        line += CountRowsForLine(m_input_lines[index]);
      }
      --line;
    }
  }
  return line;
}

void Editline::MoveCursor(CursorLocation from, CursorLocation to) {
  const LineInfoW *info = el_wline(m_editline);
  int editline_cursor_position =
      (int)((info->cursor - info->buffer) + GetPromptWidth());
  int editline_cursor_row = editline_cursor_position / m_terminal_width;

  // Determine relative starting and ending lines
  int fromLine = GetLineIndexForLocation(from, editline_cursor_row);
  int toLine = GetLineIndexForLocation(to, editline_cursor_row);
  if (toLine != fromLine) {
    fprintf(m_output_file,
            (toLine > fromLine) ? ANSI_DOWN_N_ROWS : ANSI_UP_N_ROWS,
            std::abs(toLine - fromLine));
  }

  // Determine target column
  int toColumn = 1;
  if (to == CursorLocation::EditingCursor) {
    toColumn =
        editline_cursor_position - (editline_cursor_row * m_terminal_width) + 1;
  } else if (to == CursorLocation::BlockEnd && !m_input_lines.empty()) {
    toColumn =
        ((m_input_lines[m_input_lines.size() - 1].length() + GetPromptWidth()) %
         80) +
        1;
  }
  fprintf(m_output_file, ANSI_SET_COLUMN_N, toColumn);
}

void Editline::DisplayInput(int firstIndex) {
  fprintf(m_output_file, ANSI_SET_COLUMN_N ANSI_CLEAR_BELOW, 1);
  int line_count = (int)m_input_lines.size();
  const char *faint = m_color_prompts ? ANSI_FAINT : "";
  const char *unfaint = m_color_prompts ? ANSI_UNFAINT : "";

  for (int index = firstIndex; index < line_count; index++) {
    fprintf(m_output_file, "%s"
                           "%s"
                           "%s" EditLineStringFormatSpec " ",
            faint, PromptForIndex(index).c_str(), unfaint,
            m_input_lines[index].c_str());
    if (index < line_count - 1)
      fprintf(m_output_file, "\n");
  }
}

int Editline::CountRowsForLine(const EditLineStringType &content) {
  std::string prompt =
      PromptForIndex(0); // Prompt width is constant during an edit session
  int line_length = (int)(content.length() + prompt.length());
  return (line_length / m_terminal_width) + 1;
}

void Editline::SaveEditedLine() {
  const LineInfoW *info = el_wline(m_editline);
  m_input_lines[m_current_line_index] =
      EditLineStringType(info->buffer, info->lastchar - info->buffer);
}

StringList Editline::GetInputAsStringList(int line_count) {
  StringList lines;
  for (EditLineStringType line : m_input_lines) {
    if (line_count == 0)
      break;
#if LLDB_EDITLINE_USE_WCHAR
    lines.AppendString(m_utf8conv.to_bytes(line));
#else
    lines.AppendString(line);
#endif
    --line_count;
  }
  return lines;
}

unsigned char Editline::RecallHistory(HistoryOperation op) {
  assert(op == HistoryOperation::Older || op == HistoryOperation::Newer);
  if (!m_history_sp || !m_history_sp->IsValid())
    return CC_ERROR;

  HistoryW *pHistory = m_history_sp->GetHistoryPtr();
  HistEventW history_event;
  std::vector<EditLineStringType> new_input_lines;

  // Treat moving from the "live" entry differently
  if (!m_in_history) {
    switch (op) {
    case HistoryOperation::Newer:
      return CC_ERROR; // Can't go newer than the "live" entry
    case HistoryOperation::Older: {
      if (history_w(pHistory, &history_event,
                    GetOperation(HistoryOperation::Newest)) == -1)
        return CC_ERROR;
      // Save any edits to the "live" entry in case we return by moving forward
      // in history (it would be more bash-like to save over any current entry,
      // but libedit doesn't offer the ability to add entries anywhere except
      // the end.)
      SaveEditedLine();
      m_live_history_lines = m_input_lines;
      m_in_history = true;
    } break;
    default:
      llvm_unreachable("unsupported history direction");
    }
  } else {
    if (history_w(pHistory, &history_event, GetOperation(op)) == -1) {
      switch (op) {
      case HistoryOperation::Older:
        // Can't move earlier than the earliest entry.
        return CC_ERROR;
      case HistoryOperation::Newer:
        // Moving to newer-than-the-newest entry yields the "live" entry.
        new_input_lines = m_live_history_lines;
        m_in_history = false;
        break;
      default:
        llvm_unreachable("unsupported history direction");
      }
    }
  }

  // If we're pulling the lines from history, split them apart
  if (m_in_history)
    new_input_lines = SplitLines(history_event.str);

  // Erase the current edit session and replace it with a new one
  MoveCursor(CursorLocation::EditingCursor, CursorLocation::BlockStart);
  m_input_lines = new_input_lines;
  DisplayInput();

  // Prepare to edit the last line when moving to previous entry, or the first
  // line when moving to next entry
  switch (op) {
  case HistoryOperation::Older:
    m_current_line_index = (int)m_input_lines.size() - 1;
    break;
  case HistoryOperation::Newer:
    m_current_line_index = 0;
    break;
  default:
    llvm_unreachable("unsupported history direction");
  }
  SetCurrentLine(m_current_line_index);
  MoveCursor(CursorLocation::BlockEnd, CursorLocation::EditingPrompt);
  return CC_NEWLINE;
}

int Editline::GetCharacter(EditLineGetCharType *c) {
  const LineInfoW *info = el_wline(m_editline);

  // Paint a faint version of the desired prompt over the version libedit draws
  // (will only be requested if colors are supported)
  if (m_needs_prompt_repaint) {
    MoveCursor(CursorLocation::EditingCursor, CursorLocation::EditingPrompt);
    fprintf(m_output_file, "%s"
                           "%s"
                           "%s",
            ANSI_FAINT, Prompt(), ANSI_UNFAINT);
    MoveCursor(CursorLocation::EditingPrompt, CursorLocation::EditingCursor);
    m_needs_prompt_repaint = false;
  }

  if (m_multiline_enabled) {
    // Detect when the number of rows used for this input line changes due to
    // an edit
    int lineLength = (int)((info->lastchar - info->buffer) + GetPromptWidth());
    int new_line_rows = (lineLength / m_terminal_width) + 1;
    if (m_current_line_rows != -1 && new_line_rows != m_current_line_rows) {
      // Respond by repainting the current state from this line on
      MoveCursor(CursorLocation::EditingCursor, CursorLocation::EditingPrompt);
      SaveEditedLine();
      DisplayInput(m_current_line_index);
      MoveCursor(CursorLocation::BlockEnd, CursorLocation::EditingCursor);
    }
    m_current_line_rows = new_line_rows;
  }

  // Read an actual character
  while (true) {
    lldb::ConnectionStatus status = lldb::eConnectionStatusSuccess;
    char ch = 0;

    if (m_terminal_size_has_changed)
      ApplyTerminalSizeChange();

    // This mutex is locked by our caller (GetLine). Unlock it while we read a
    // character (blocking operation), so we do not hold the mutex
    // indefinitely. This gives a chance for someone to interrupt us. After
    // Read returns, immediately lock the mutex again and check if we were
    // interrupted.
    m_output_mutex.unlock();
    int read_count =
        m_input_connection.Read(&ch, 1, llvm::None, status, nullptr);
    m_output_mutex.lock();
    if (m_editor_status == EditorStatus::Interrupted) {
      while (read_count > 0 && status == lldb::eConnectionStatusSuccess)
        read_count =
            m_input_connection.Read(&ch, 1, llvm::None, status, nullptr);
      lldbassert(status == lldb::eConnectionStatusInterrupted);
      return 0;
    }

    if (read_count) {
      if (CompleteCharacter(ch, *c))
        return 1;
    } else {
      switch (status) {
      case lldb::eConnectionStatusSuccess: // Success
        break;

      case lldb::eConnectionStatusInterrupted:
        llvm_unreachable("Interrupts should have been handled above.");

      case lldb::eConnectionStatusError:        // Check GetError() for details
      case lldb::eConnectionStatusTimedOut:     // Request timed out
      case lldb::eConnectionStatusEndOfFile:    // End-of-file encountered
      case lldb::eConnectionStatusNoConnection: // No connection
      case lldb::eConnectionStatusLostConnection: // Lost connection while
                                                  // connected to a valid
                                                  // connection
        m_editor_status = EditorStatus::EndOfInput;
        return 0;
      }
    }
  }
}

const char *Editline::Prompt() {
  if (m_color_prompts)
    m_needs_prompt_repaint = true;
  return m_current_prompt.c_str();
}

unsigned char Editline::BreakLineCommand(int ch) {
  // Preserve any content beyond the cursor, truncate and save the current line
  const LineInfoW *info = el_wline(m_editline);
  auto current_line =
      EditLineStringType(info->buffer, info->cursor - info->buffer);
  auto new_line_fragment =
      EditLineStringType(info->cursor, info->lastchar - info->cursor);
  m_input_lines[m_current_line_index] = current_line;

  // Ignore whitespace-only extra fragments when breaking a line
  if (::IsOnlySpaces(new_line_fragment))
    new_line_fragment = EditLineConstString("");

  // Establish the new cursor position at the start of a line when inserting a
  // line break
  m_revert_cursor_index = 0;

  // Don't perform automatic formatting when pasting
  if (!IsInputPending(m_input_file)) {
    // Apply smart indentation
    if (m_fix_indentation_callback) {
      StringList lines = GetInputAsStringList(m_current_line_index + 1);
#if LLDB_EDITLINE_USE_WCHAR
      lines.AppendString(m_utf8conv.to_bytes(new_line_fragment));
#else
      lines.AppendString(new_line_fragment);
#endif

      int indent_correction = m_fix_indentation_callback(
          this, lines, 0, m_fix_indentation_callback_baton);
      new_line_fragment = FixIndentation(new_line_fragment, indent_correction);
      m_revert_cursor_index = GetIndentation(new_line_fragment);
    }
  }

  // Insert the new line and repaint everything from the split line on down
  m_input_lines.insert(m_input_lines.begin() + m_current_line_index + 1,
                       new_line_fragment);
  MoveCursor(CursorLocation::EditingCursor, CursorLocation::EditingPrompt);
  DisplayInput(m_current_line_index);

  // Reposition the cursor to the right line and prepare to edit the new line
  SetCurrentLine(m_current_line_index + 1);
  MoveCursor(CursorLocation::BlockEnd, CursorLocation::EditingPrompt);
  return CC_NEWLINE;
}

unsigned char Editline::EndOrAddLineCommand(int ch) {
  // Don't perform end of input detection when pasting, always treat this as a
  // line break
  if (IsInputPending(m_input_file)) {
    return BreakLineCommand(ch);
  }

  // Save any edits to this line
  SaveEditedLine();

  // If this is the end of the last line, consider whether to add a line
  // instead
  const LineInfoW *info = el_wline(m_editline);
  if (m_current_line_index == m_input_lines.size() - 1 &&
      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)) {
        return BreakLineCommand(ch);
      }

      // The completion test is allowed to change the input lines when complete
      m_input_lines.clear();
      for (unsigned index = 0; index < lines.GetSize(); index++) {
#if LLDB_EDITLINE_USE_WCHAR
        m_input_lines.insert(m_input_lines.end(),
                             m_utf8conv.from_bytes(lines[index]));
#else
        m_input_lines.insert(m_input_lines.end(), lines[index]);
#endif
      }
    }
  }
  MoveCursor(CursorLocation::EditingCursor, CursorLocation::BlockEnd);
  fprintf(m_output_file, "\n");
  m_editor_status = EditorStatus::Complete;
  return CC_NEWLINE;
}

unsigned char Editline::DeleteNextCharCommand(int ch) {
  LineInfoW *info = const_cast<LineInfoW *>(el_wline(m_editline));

  // Just delete the next character normally if possible
  if (info->cursor < info->lastchar) {
    info->cursor++;
    el_deletestr(m_editline, 1);
    return CC_REFRESH;
  }

  // Fail when at the end of the last line, except when ^D is pressed on the
  // line is empty, in which case it is treated as EOF
  if (m_current_line_index == m_input_lines.size() - 1) {
    if (ch == 4 && info->buffer == info->lastchar) {
      fprintf(m_output_file, "^D\n");
      m_editor_status = EditorStatus::EndOfInput;
      return CC_EOF;
    }
    return CC_ERROR;
  }

  // Prepare to combine this line with the one below
  MoveCursor(CursorLocation::EditingCursor, CursorLocation::EditingPrompt);

  // Insert the next line of text at the cursor and restore the cursor position
  const EditLineCharType *cursor = info->cursor;
  el_winsertstr(m_editline, m_input_lines[m_current_line_index + 1].c_str());
  info->cursor = cursor;
  SaveEditedLine();

  // Delete the extra line
  m_input_lines.erase(m_input_lines.begin() + m_current_line_index + 1);

  // Clear and repaint from this line on down
  DisplayInput(m_current_line_index);
  MoveCursor(CursorLocation::BlockEnd, CursorLocation::EditingCursor);
  return CC_REFRESH;
}

unsigned char Editline::DeletePreviousCharCommand(int ch) {
  LineInfoW *info = const_cast<LineInfoW *>(el_wline(m_editline));

  // Just delete the previous character normally when not at the start of a
  // line
  if (info->cursor > info->buffer) {
    el_deletestr(m_editline, 1);
    return CC_REFRESH;
  }

  // No prior line and no prior character?  Let the user know
  if (m_current_line_index == 0)
    return CC_ERROR;

  // No prior character, but prior line?  Combine with the line above
  SaveEditedLine();
  SetCurrentLine(m_current_line_index - 1);
  auto priorLine = m_input_lines[m_current_line_index];
  m_input_lines.erase(m_input_lines.begin() + m_current_line_index);
  m_input_lines[m_current_line_index] =
      priorLine + m_input_lines[m_current_line_index];

  // Repaint from the new line down
  fprintf(m_output_file, ANSI_UP_N_ROWS ANSI_SET_COLUMN_N,
          CountRowsForLine(priorLine), 1);
  DisplayInput(m_current_line_index);

  // Put the cursor back where libedit expects it to be before returning to
  // editing by telling libedit about the newly inserted text
  MoveCursor(CursorLocation::BlockEnd, CursorLocation::EditingPrompt);
  el_winsertstr(m_editline, priorLine.c_str());
  return CC_REDISPLAY;
}

unsigned char Editline::PreviousLineCommand(int ch) {
  SaveEditedLine();

  if (m_current_line_index == 0) {
    return RecallHistory(HistoryOperation::Older);
  }

  // Start from a known location
  MoveCursor(CursorLocation::EditingCursor, CursorLocation::EditingPrompt);

  // Treat moving up from a blank last line as a deletion of that line
  if (m_current_line_index == m_input_lines.size() - 1 && IsOnlySpaces()) {
    m_input_lines.erase(m_input_lines.begin() + m_current_line_index);
    fprintf(m_output_file, ANSI_CLEAR_BELOW);
  }

  SetCurrentLine(m_current_line_index - 1);
  fprintf(m_output_file, ANSI_UP_N_ROWS ANSI_SET_COLUMN_N,
          CountRowsForLine(m_input_lines[m_current_line_index]), 1);
  return CC_NEWLINE;
}

unsigned char Editline::NextLineCommand(int ch) {
  SaveEditedLine();

  // Handle attempts to move down from the last line
  if (m_current_line_index == m_input_lines.size() - 1) {
    // Don't add an extra line if the existing last line is blank, move through
    // history instead
    if (IsOnlySpaces()) {
      return RecallHistory(HistoryOperation::Newer);
    }

    // Determine indentation for the new line
    int indentation = 0;
    if (m_fix_indentation_callback) {
      StringList lines = GetInputAsStringList();
      lines.AppendString("");
      indentation = m_fix_indentation_callback(
          this, lines, 0, m_fix_indentation_callback_baton);
    }
    m_input_lines.insert(
        m_input_lines.end(),
        EditLineStringType(indentation, EditLineCharType(' ')));
  }

  // Move down past the current line using newlines to force scrolling if
  // needed
  SetCurrentLine(m_current_line_index + 1);
  const LineInfoW *info = el_wline(m_editline);
  int cursor_position = (int)((info->cursor - info->buffer) + GetPromptWidth());
  int cursor_row = cursor_position / m_terminal_width;
  for (int line_count = 0; line_count < m_current_line_rows - cursor_row;
       line_count++) {
    fprintf(m_output_file, "\n");
  }
  return CC_NEWLINE;
}

unsigned char Editline::PreviousHistoryCommand(int ch) {
  SaveEditedLine();

  return RecallHistory(HistoryOperation::Older);
}

unsigned char Editline::NextHistoryCommand(int ch) {
  SaveEditedLine();

  return RecallHistory(HistoryOperation::Newer);
}

unsigned char Editline::FixIndentationCommand(int ch) {
  if (!m_fix_indentation_callback)
    return CC_NORM;

  // Insert the character typed before proceeding
  EditLineCharType inserted[] = {(EditLineCharType)ch, 0};
  el_winsertstr(m_editline, inserted);
  LineInfoW *info = const_cast<LineInfoW *>(el_wline(m_editline));
  int cursor_position = info->cursor - info->buffer;

  // 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);

  // If it is already correct no special work is needed
  if (indent_correction == 0)
    return CC_REFRESH;

  // Change the indentation level of the line
  std::string currentLine = lines.GetStringAtIndex(m_current_line_index);
  if (indent_correction > 0) {
    currentLine = currentLine.insert(0, indent_correction, ' ');
  } else {
    currentLine = currentLine.erase(0, -indent_correction);
  }
#if LLDB_EDITLINE_USE_WCHAR
  m_input_lines[m_current_line_index] = m_utf8conv.from_bytes(currentLine);
#else
  m_input_lines[m_current_line_index] = currentLine;
#endif

  // Update the display to reflect the change
  MoveCursor(CursorLocation::EditingCursor, CursorLocation::EditingPrompt);
  DisplayInput(m_current_line_index);

  // Reposition the cursor back on the original line and prepare to restart
  // editing with a new cursor position
  SetCurrentLine(m_current_line_index);
  MoveCursor(CursorLocation::BlockEnd, CursorLocation::EditingPrompt);
  m_revert_cursor_index = cursor_position + indent_correction;
  return CC_NEWLINE;
}

unsigned char Editline::RevertLineCommand(int ch) {
  el_winsertstr(m_editline, m_input_lines[m_current_line_index].c_str());
  if (m_revert_cursor_index >= 0) {
    LineInfoW *info = const_cast<LineInfoW *>(el_wline(m_editline));
    info->cursor = info->buffer + m_revert_cursor_index;
    if (info->cursor > info->lastchar) {
      info->cursor = info->lastchar;
    }
    m_revert_cursor_index = -1;
  }
  return CC_REFRESH;
}

unsigned char Editline::BufferStartCommand(int ch) {
  SaveEditedLine();
  MoveCursor(CursorLocation::EditingCursor, CursorLocation::BlockStart);
  SetCurrentLine(0);
  m_revert_cursor_index = 0;
  return CC_NEWLINE;
}

unsigned char Editline::BufferEndCommand(int ch) {
  SaveEditedLine();
  MoveCursor(CursorLocation::EditingCursor, CursorLocation::BlockEnd);
  SetCurrentLine((int)m_input_lines.size() - 1);
  MoveCursor(CursorLocation::BlockEnd, CursorLocation::EditingPrompt);
  return CC_NEWLINE;
}

/// 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,
                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");
  }
}

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;
  }

  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);

    PrintCompletion(output_file, results.slice(cur_pos, next_size), max_len);

    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;
  }
}

unsigned char Editline::TabCommand(int ch) {
  if (m_completion_callback == nullptr)
    return CC_ERROR;

  const LineInfo *line_info = el_line(m_editline);

  llvm::StringRef line(line_info->buffer,
                       line_info->lastchar - line_info->buffer);
  unsigned cursor_index = line_info->cursor - line_info->buffer;
  CompletionResult result;
  CompletionRequest request(line, cursor_index, result);

  m_completion_callback(request, m_completion_callback_baton);

  llvm::ArrayRef<CompletionResult::Completion> results = result.GetResults();

  StringList completions;
  result.GetMatches(completions);

  if (results.size() == 0)
    return CC_ERROR;

  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().GetQuoteChar());
      to_add.push_back(' ');
      el_insertstr(m_editline, to_add.c_str());
      break;
    }
    case CompletionMode::Partial: {
      std::string to_add = completion.GetCompletion();
      to_add = to_add.substr(request.GetCursorArgumentPrefix().size());
      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.
  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;
  }

  DisplayCompletions(m_editline, m_output_file, results);

  DisplayInput();
  MoveCursor(CursorLocation::BlockEnd, CursorLocation::EditingCursor);
  return CC_REDISPLAY;
}

void Editline::ConfigureEditor(bool multiline) {
  if (m_editline && m_multiline_enabled == multiline)
    return;
  m_multiline_enabled = multiline;

  if (m_editline) {
    // Disable edit mode to stop the terminal from flushing all input during
    // the call to el_end() since we expect to have multiple editline instances
    // in this program.
    el_set(m_editline, EL_EDITMODE, 0);
    el_end(m_editline);
  }

  m_editline =
      el_init(m_editor_name.c_str(), m_input_file, m_output_file, m_error_file);
  ApplyTerminalSizeChange();

  if (m_history_sp && m_history_sp->IsValid()) {
    if (!m_history_sp->Load()) {
        fputs("Could not load history file\n.", m_output_file);
    }
    el_wset(m_editline, EL_HIST, history, m_history_sp->GetHistoryPtr());
  }
  el_set(m_editline, EL_CLIENTDATA, this);
  el_set(m_editline, EL_SIGNAL, 0);
  el_set(m_editline, EL_EDITOR, "emacs");
  el_set(m_editline, EL_PROMPT,
         (EditlinePromptCallbackType)([](EditLine *editline) {
           return Editline::InstanceFor(editline)->Prompt();
         }));

  el_wset(m_editline, EL_GETCFN, (EditlineGetCharCallbackType)([](
                                     EditLine *editline, EditLineGetCharType *c) {
            return Editline::InstanceFor(editline)->GetCharacter(c);
          }));

  // Commands used for multiline support, registered whether or not they're
  // used
  el_wset(m_editline, EL_ADDFN, EditLineConstString("lldb-break-line"),
          EditLineConstString("Insert a line break"),
          (EditlineCommandCallbackType)([](EditLine *editline, int ch) {
            return Editline::InstanceFor(editline)->BreakLineCommand(ch);
          }));
  el_wset(m_editline, EL_ADDFN, EditLineConstString("lldb-end-or-add-line"),
          EditLineConstString("End editing or continue when incomplete"),
          (EditlineCommandCallbackType)([](EditLine *editline, int ch) {
            return Editline::InstanceFor(editline)->EndOrAddLineCommand(ch);
          }));
  el_wset(m_editline, EL_ADDFN, EditLineConstString("lldb-delete-next-char"),
          EditLineConstString("Delete next character"),
          (EditlineCommandCallbackType)([](EditLine *editline, int ch) {
            return Editline::InstanceFor(editline)->DeleteNextCharCommand(ch);
          }));
  el_wset(
      m_editline, EL_ADDFN, EditLineConstString("lldb-delete-previous-char"),
      EditLineConstString("Delete previous character"),
      (EditlineCommandCallbackType)([](EditLine *editline, int ch) {
        return Editline::InstanceFor(editline)->DeletePreviousCharCommand(ch);
      }));
  el_wset(m_editline, EL_ADDFN, EditLineConstString("lldb-previous-line"),
          EditLineConstString("Move to previous line"),
          (EditlineCommandCallbackType)([](EditLine *editline, int ch) {
            return Editline::InstanceFor(editline)->PreviousLineCommand(ch);
          }));
  el_wset(m_editline, EL_ADDFN, EditLineConstString("lldb-next-line"),
          EditLineConstString("Move to next line"),
          (EditlineCommandCallbackType)([](EditLine *editline, int ch) {
            return Editline::InstanceFor(editline)->NextLineCommand(ch);
          }));
  el_wset(m_editline, EL_ADDFN, EditLineConstString("lldb-previous-history"),
          EditLineConstString("Move to previous history"),
          (EditlineCommandCallbackType)([](EditLine *editline, int ch) {
            return Editline::InstanceFor(editline)->PreviousHistoryCommand(ch);
          }));
  el_wset(m_editline, EL_ADDFN, EditLineConstString("lldb-next-history"),
          EditLineConstString("Move to next history"),
          (EditlineCommandCallbackType)([](EditLine *editline, int ch) {
            return Editline::InstanceFor(editline)->NextHistoryCommand(ch);
          }));
  el_wset(m_editline, EL_ADDFN, EditLineConstString("lldb-buffer-start"),
          EditLineConstString("Move to start of buffer"),
          (EditlineCommandCallbackType)([](EditLine *editline, int ch) {
            return Editline::InstanceFor(editline)->BufferStartCommand(ch);
          }));
  el_wset(m_editline, EL_ADDFN, EditLineConstString("lldb-buffer-end"),
          EditLineConstString("Move to end of buffer"),
          (EditlineCommandCallbackType)([](EditLine *editline, int ch) {
            return Editline::InstanceFor(editline)->BufferEndCommand(ch);
          }));
  el_wset(m_editline, EL_ADDFN, EditLineConstString("lldb-fix-indentation"),
          EditLineConstString("Fix line indentation"),
          (EditlineCommandCallbackType)([](EditLine *editline, int ch) {
            return Editline::InstanceFor(editline)->FixIndentationCommand(ch);
          }));

  // Register the complete callback under two names for compatibility with
  // older clients using custom .editrc files (largely because libedit has a
  // bad bug where if you have a bind command that tries to bind to a function
  // name that doesn't exist, it can corrupt the heap and crash your process
  // later.)
  EditlineCommandCallbackType complete_callback = [](EditLine *editline,
                                                     int ch) {
    return Editline::InstanceFor(editline)->TabCommand(ch);
  };
  el_wset(m_editline, EL_ADDFN, EditLineConstString("lldb-complete"),
          EditLineConstString("Invoke completion"), complete_callback);
  el_wset(m_editline, EL_ADDFN, EditLineConstString("lldb_complete"),
          EditLineConstString("Invoke completion"), complete_callback);

  // General bindings we don't mind being overridden
  if (!multiline) {
    el_set(m_editline, EL_BIND, "^r", "em-inc-search-prev",
           NULL); // Cycle through backwards search, entering string
  }
  el_set(m_editline, EL_BIND, "^w", "ed-delete-prev-word",
         NULL); // Delete previous word, behave like bash in emacs mode
  el_set(m_editline, EL_BIND, "\t", "lldb-complete",
         NULL); // Bind TAB to auto complete

  // Allow ctrl-left-arrow and ctrl-right-arrow for navigation, behave like
  // bash in emacs mode.
  el_set(m_editline, EL_BIND, ESCAPE "[1;5C", "em-next-word", NULL);
  el_set(m_editline, EL_BIND, ESCAPE "[1;5D", "ed-prev-word", NULL);
  el_set(m_editline, EL_BIND, ESCAPE "[5C", "em-next-word", NULL);
  el_set(m_editline, EL_BIND, ESCAPE "[5D", "ed-prev-word", NULL);
  el_set(m_editline, EL_BIND, ESCAPE ESCAPE "[C", "em-next-word", NULL);
  el_set(m_editline, EL_BIND, ESCAPE ESCAPE "[D", "ed-prev-word", NULL);

  // Allow user-specific customization prior to registering bindings we
  // absolutely require
  el_source(m_editline, nullptr);

  // Register an internal binding that external developers shouldn't use
  el_wset(m_editline, EL_ADDFN, EditLineConstString("lldb-revert-line"),
          EditLineConstString("Revert line to saved state"),
          (EditlineCommandCallbackType)([](EditLine *editline, int ch) {
            return Editline::InstanceFor(editline)->RevertLineCommand(ch);
          }));

  // Register keys that perform auto-indent correction
  if (m_fix_indentation_callback && m_fix_indentation_callback_chars) {
    char bind_key[2] = {0, 0};
    const char *indent_chars = m_fix_indentation_callback_chars;
    while (*indent_chars) {
      bind_key[0] = *indent_chars;
      el_set(m_editline, EL_BIND, bind_key, "lldb-fix-indentation", NULL);
      ++indent_chars;
    }
  }

  // Multi-line editor bindings
  if (multiline) {
    el_set(m_editline, EL_BIND, "\n", "lldb-end-or-add-line", NULL);
    el_set(m_editline, EL_BIND, "\r", "lldb-end-or-add-line", NULL);
    el_set(m_editline, EL_BIND, ESCAPE "\n", "lldb-break-line", NULL);
    el_set(m_editline, EL_BIND, ESCAPE "\r", "lldb-break-line", NULL);
    el_set(m_editline, EL_BIND, "^p", "lldb-previous-line", NULL);
    el_set(m_editline, EL_BIND, "^n", "lldb-next-line", NULL);
    el_set(m_editline, EL_BIND, "^?", "lldb-delete-previous-char", NULL);
    el_set(m_editline, EL_BIND, "^d", "lldb-delete-next-char", NULL);
    el_set(m_editline, EL_BIND, ESCAPE "[3~", "lldb-delete-next-char", NULL);
    el_set(m_editline, EL_BIND, ESCAPE "[\\^", "lldb-revert-line", NULL);

    // Editor-specific bindings
    if (IsEmacs()) {
      el_set(m_editline, EL_BIND, ESCAPE "<", "lldb-buffer-start", NULL);
      el_set(m_editline, EL_BIND, ESCAPE ">", "lldb-buffer-end", NULL);
      el_set(m_editline, EL_BIND, ESCAPE "[A", "lldb-previous-line", NULL);
      el_set(m_editline, EL_BIND, ESCAPE "[B", "lldb-next-line", NULL);
      el_set(m_editline, EL_BIND, ESCAPE ESCAPE "[A", "lldb-previous-history",
             NULL);
      el_set(m_editline, EL_BIND, ESCAPE ESCAPE "[B", "lldb-next-history",
             NULL);
      el_set(m_editline, EL_BIND, ESCAPE "[1;3A", "lldb-previous-history",
             NULL);
      el_set(m_editline, EL_BIND, ESCAPE "[1;3B", "lldb-next-history", NULL);
    } else {
      el_set(m_editline, EL_BIND, "^H", "lldb-delete-previous-char", NULL);

      el_set(m_editline, EL_BIND, "-a", ESCAPE "[A", "lldb-previous-line",
             NULL);
      el_set(m_editline, EL_BIND, "-a", ESCAPE "[B", "lldb-next-line", NULL);
      el_set(m_editline, EL_BIND, "-a", "x", "lldb-delete-next-char", NULL);
      el_set(m_editline, EL_BIND, "-a", "^H", "lldb-delete-previous-char",
             NULL);
      el_set(m_editline, EL_BIND, "-a", "^?", "lldb-delete-previous-char",
             NULL);

      // Escape is absorbed exiting edit mode, so re-register important
      // sequences without the prefix
      el_set(m_editline, EL_BIND, "-a", "[A", "lldb-previous-line", NULL);
      el_set(m_editline, EL_BIND, "-a", "[B", "lldb-next-line", NULL);
      el_set(m_editline, EL_BIND, "-a", "[\\^", "lldb-revert-line", NULL);
    }
  }
}

// Editline public methods

Editline *Editline::InstanceFor(EditLine *editline) {
  Editline *editor;
  el_get(editline, EL_CLIENTDATA, &editor);
  return editor;
}

Editline::Editline(const char *editline_name, FILE *input_file,
                   FILE *output_file, FILE *error_file, bool color_prompts)
    : m_editor_status(EditorStatus::Complete), m_color_prompts(color_prompts),
      m_input_file(input_file), m_output_file(output_file),
      m_error_file(error_file), m_input_connection(fileno(input_file), false) {
  // Get a shared history instance
  m_editor_name = (editline_name == nullptr) ? "lldb-tmp" : editline_name;
  m_history_sp = EditlineHistory::GetHistory(m_editor_name);

#ifdef USE_SETUPTERM_WORKAROUND
  if (m_output_file) {
    const int term_fd = fileno(m_output_file);
    if (term_fd != -1) {
      static std::mutex *g_init_terminal_fds_mutex_ptr = nullptr;
      static std::set<int> *g_init_terminal_fds_ptr = nullptr;
      static llvm::once_flag g_once_flag;
      llvm::call_once(g_once_flag, [&]() {
        g_init_terminal_fds_mutex_ptr =
            new std::mutex(); // NOTE: Leak to avoid C++ destructor chain issues
        g_init_terminal_fds_ptr = new std::set<int>(); // NOTE: Leak to avoid
                                                       // C++ destructor chain
                                                       // issues
      });

      // We must make sure to initialize the terminal a given file descriptor
      // only once. If we do this multiple times, we start leaking memory.
      std::lock_guard<std::mutex> guard(*g_init_terminal_fds_mutex_ptr);
      if (g_init_terminal_fds_ptr->find(term_fd) ==
          g_init_terminal_fds_ptr->end()) {
        g_init_terminal_fds_ptr->insert(term_fd);
        setupterm((char *)0, term_fd, (int *)0);
      }
    }
  }
#endif
}

Editline::~Editline() {
  if (m_editline) {
    // Disable edit mode to stop the terminal from flushing all input during
    // the call to el_end() since we expect to have multiple editline instances
    // in this program.
    el_set(m_editline, EL_EDITMODE, 0);
    el_end(m_editline);
    m_editline = nullptr;
  }

  // EditlineHistory objects are sometimes shared between multiple Editline
  // instances with the same program name. So just release our shared pointer
  // and if we are the last owner, it will save the history to the history save
  // file automatically.
  m_history_sp.reset();
}

void Editline::SetPrompt(const char *prompt) {
  m_set_prompt = prompt == nullptr ? "" : prompt;
}

void Editline::SetContinuationPrompt(const char *continuation_prompt) {
  m_set_continuation_prompt =
      continuation_prompt == nullptr ? "" : continuation_prompt;
}

void Editline::TerminalSizeChanged() { m_terminal_size_has_changed = 1; }

void Editline::ApplyTerminalSizeChange() {
  if (!m_editline)
    return;

  m_terminal_size_has_changed = 0;
  el_resize(m_editline);
  int columns;
  // This function is documenting as taking (const char *, void *) for the
  // vararg part, but in reality in was consuming arguments until the first
  // null pointer. This was fixed in libedit in April 2019
  // <http://mail-index.netbsd.org/source-changes/2019/04/26/msg105454.html>,
  // but we're keeping the workaround until a version with that fix is more
  // widely available.
  if (el_get(m_editline, EL_GETTC, "co", &columns, nullptr) == 0) {
    m_terminal_width = columns;
    if (m_current_line_rows != -1) {
      const LineInfoW *info = el_wline(m_editline);
      int lineLength =
          (int)((info->lastchar - info->buffer) + GetPromptWidth());
      m_current_line_rows = (lineLength / columns) + 1;
    }
  } else {
    m_terminal_width = INT_MAX;
    m_current_line_rows = 1;
  }
}

const char *Editline::GetPrompt() { return m_set_prompt.c_str(); }

uint32_t Editline::GetCurrentLine() { return m_current_line_index; }

bool Editline::Interrupt() {
  bool result = true;
  std::lock_guard<std::mutex> guard(m_output_mutex);
  if (m_editor_status == EditorStatus::Editing) {
    fprintf(m_output_file, "^C\n");
    result = m_input_connection.InterruptRead();
  }
  m_editor_status = EditorStatus::Interrupted;
  return result;
}

bool Editline::Cancel() {
  bool result = true;
  std::lock_guard<std::mutex> guard(m_output_mutex);
  if (m_editor_status == EditorStatus::Editing) {
    MoveCursor(CursorLocation::EditingCursor, CursorLocation::BlockStart);
    fprintf(m_output_file, ANSI_CLEAR_BELOW);
    result = m_input_connection.InterruptRead();
  }
  m_editor_status = EditorStatus::Interrupted;
  return result;
}

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>();
  m_input_lines.insert(m_input_lines.begin(), EditLineConstString(""));

  std::lock_guard<std::mutex> guard(m_output_mutex);

  lldbassert(m_editor_status != EditorStatus::Editing);
  if (m_editor_status == EditorStatus::Interrupted) {
    m_editor_status = EditorStatus::Complete;
    interrupted = true;
    return true;
  }

  SetCurrentLine(0);
  m_in_history = false;
  m_editor_status = EditorStatus::Editing;
  m_revert_cursor_index = -1;

  int count;
  auto input = el_wgets(m_editline, &count);

  interrupted = m_editor_status == EditorStatus::Interrupted;
  if (!interrupted) {
    if (input == nullptr) {
      fprintf(m_output_file, "\n");
      m_editor_status = EditorStatus::EndOfInput;
    } else {
      m_history_sp->Enter(input);
#if LLDB_EDITLINE_USE_WCHAR
      line = m_utf8conv.to_bytes(SplitLines(input)[0]);
#else
      line = SplitLines(input)[0];
#endif
      m_editor_status = EditorStatus::Complete;
    }
  }
  return m_editor_status != EditorStatus::EndOfInput;
}

bool Editline::GetLines(int first_line_number, StringList &lines,
                        bool &interrupted) {
  ConfigureEditor(true);

  // Print the initial input lines, then move the cursor back up to the start
  // of input
  SetBaseLineNumber(first_line_number);
  m_input_lines = std::vector<EditLineStringType>();
  m_input_lines.insert(m_input_lines.begin(), EditLineConstString(""));

  std::lock_guard<std::mutex> guard(m_output_mutex);
  // Begin the line editing loop
  DisplayInput();
  SetCurrentLine(0);
  MoveCursor(CursorLocation::BlockEnd, CursorLocation::BlockStart);
  m_editor_status = EditorStatus::Editing;
  m_in_history = false;

  m_revert_cursor_index = -1;
  while (m_editor_status == EditorStatus::Editing) {
    int count;
    m_current_line_rows = -1;
    el_wpush(m_editline, EditLineConstString(
                             "\x1b[^")); // Revert to the existing line content
    el_wgets(m_editline, &count);
  }

  interrupted = m_editor_status == EditorStatus::Interrupted;
  if (!interrupted) {
    // Save the completed entry in history before returning
    m_history_sp->Enter(CombineLines(m_input_lines).c_str());

    lines = GetInputAsStringList();
  }
  return m_editor_status != EditorStatus::EndOfInput;
}

void Editline::PrintAsync(Stream *stream, const char *s, size_t len) {
  std::lock_guard<std::mutex> guard(m_output_mutex);
  if (m_editor_status == EditorStatus::Editing) {
    MoveCursor(CursorLocation::EditingCursor, CursorLocation::BlockStart);
    fprintf(m_output_file, ANSI_CLEAR_BELOW);
  }
  stream->Write(s, len);
  stream->Flush();
  if (m_editor_status == EditorStatus::Editing) {
    DisplayInput();
    MoveCursor(CursorLocation::BlockEnd, CursorLocation::EditingCursor);
  }
}

bool Editline::CompleteCharacter(char ch, EditLineGetCharType &out) {
#if !LLDB_EDITLINE_USE_WCHAR
  if (ch == (char)EOF)
    return false;

  out = (unsigned char)ch;
  return true;
#else
  std::codecvt_utf8<wchar_t> cvt;
  llvm::SmallString<4> input;
  for (;;) {
    const char *from_next;
    wchar_t *to_next;
    std::mbstate_t state = std::mbstate_t();
    input.push_back(ch);
    switch (cvt.in(state, input.begin(), input.end(), from_next, &out, &out + 1,
                   to_next)) {
    case std::codecvt_base::ok:
      return out != (int)WEOF;

    case std::codecvt_base::error:
    case std::codecvt_base::noconv:
      return false;

    case std::codecvt_base::partial:
      lldb::ConnectionStatus status;
      size_t read_count = m_input_connection.Read(
          &ch, 1, std::chrono::seconds(0), status, nullptr);
      if (read_count == 0)
        return false;
      break;
    }
  }
#endif
}
