[lldb] Correctly restore the cursor column after resizing the statusline (#146132)
This PR ensures we correctly restore the cursor column after resizing the statusline. To ensure we have space for the statusline, we have to emit a newline to move up everything on screen. The newline causes the cursor to move to the start of the next line, which needs to be undone. Normally, we would use escape codes to save & restore the cursor position, but that doesn't work here, as the cursor position may have (purposely) changed. Instead, we move the cursor up one line using an escape code, but we weren't restoring the column. Interestingly, Editline was able to recover from this issue through the LineInfo struct which contains the buffer and the cursor location, which allows us to compute the column. This PR addresses the bug by having Editline "refresh" the cursor position. Fixes #134064
This commit is contained in:
committed by
GitHub
parent
0d1392e979
commit
1eb795413d
@@ -1445,6 +1445,13 @@ bool Debugger::PopIOHandler(const IOHandlerSP &pop_reader_sp) {
|
||||
return true;
|
||||
}
|
||||
|
||||
void Debugger::RefreshIOHandler() {
|
||||
std::lock_guard<std::recursive_mutex> guard(m_io_handler_stack.GetMutex());
|
||||
IOHandlerSP reader_sp(m_io_handler_stack.Top());
|
||||
if (reader_sp)
|
||||
reader_sp->Refresh();
|
||||
}
|
||||
|
||||
StreamUP Debugger::GetAsyncOutputStream() {
|
||||
return std::make_unique<StreamAsynchronousIO>(*this,
|
||||
StreamAsynchronousIO::STDOUT);
|
||||
|
||||
@@ -663,3 +663,10 @@ void IOHandlerEditline::PrintAsync(const char *s, size_t len, bool is_stdout) {
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
void IOHandlerEditline::Refresh() {
|
||||
#if LLDB_ENABLE_LIBEDIT
|
||||
if (m_editline_up)
|
||||
m_editline_up->Refresh();
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -103,20 +103,23 @@ void Statusline::UpdateScrollWindow(ScrollWindowMode mode) {
|
||||
(mode == DisableStatusline) ? m_terminal_height : m_terminal_height - 1;
|
||||
|
||||
LockedStreamFile locked_stream = stream_sp->Lock();
|
||||
|
||||
if (mode == EnableStatusline) {
|
||||
// Move everything on the screen up.
|
||||
locked_stream << '\n';
|
||||
locked_stream.Printf(ANSI_UP_ROWS, 1);
|
||||
}
|
||||
|
||||
locked_stream << ANSI_SAVE_CURSOR;
|
||||
locked_stream.Printf(ANSI_SET_SCROLL_ROWS, scroll_height);
|
||||
locked_stream << ANSI_RESTORE_CURSOR;
|
||||
switch (mode) {
|
||||
case EnableStatusline:
|
||||
// Move everything on the screen up.
|
||||
locked_stream.Printf(ANSI_UP_ROWS, 1);
|
||||
locked_stream << '\n';
|
||||
break;
|
||||
case DisableStatusline:
|
||||
|
||||
if (mode == DisableStatusline) {
|
||||
// Clear the screen below to hide the old statusline.
|
||||
locked_stream << ANSI_CLEAR_BELOW;
|
||||
break;
|
||||
}
|
||||
|
||||
m_debugger.RefreshIOHandler();
|
||||
}
|
||||
|
||||
void Statusline::Redraw(bool update) {
|
||||
|
||||
@@ -1709,6 +1709,13 @@ void Editline::PrintAsync(lldb::LockableStreamFileSP stream_sp, const char *s,
|
||||
}
|
||||
}
|
||||
|
||||
void Editline::Refresh() {
|
||||
if (!m_editline || !m_output_stream_sp)
|
||||
return;
|
||||
LockedStreamFile locked_stream = m_output_stream_sp->Lock();
|
||||
MoveCursor(CursorLocation::EditingCursor, CursorLocation::EditingCursor);
|
||||
}
|
||||
|
||||
bool Editline::CompleteCharacter(char ch, EditLineGetCharType &out) {
|
||||
#if !LLDB_EDITLINE_USE_WCHAR
|
||||
if (ch == (char)EOF)
|
||||
|
||||
Reference in New Issue
Block a user