Skip to content

[lldb] Take a sledgehammer approach to resizing the statusline #146578

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 1 addition & 3 deletions lldb/include/lldb/Core/Statusline.h
Original file line number Diff line number Diff line change
Expand Up @@ -36,12 +36,10 @@ class Statusline {
/// Draw the statusline with the given text.
void Draw(std::string msg);

/// Update terminal dimensions.
void UpdateTerminalProperties();

enum ScrollWindowMode {
EnableStatusline,
DisableStatusline,
ResizeStatusline,
};

/// Set the scroll window for the given mode.
Expand Down
47 changes: 26 additions & 21 deletions lldb/source/Core/Statusline.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
#define ANSI_SAVE_CURSOR ESCAPE "7"
#define ANSI_RESTORE_CURSOR ESCAPE "8"
#define ANSI_CLEAR_BELOW ESCAPE "[J"
#define ANSI_CLEAR_SCREEN ESCAPE "[2J"
#define ANSI_SET_SCROLL_ROWS ESCAPE "[1;%ur"
#define ANSI_TO_START_OF_ROW ESCAPE "[%u;1f"
#define ANSI_REVERSE_VIDEO ESCAPE "[7m"
Expand All @@ -41,10 +42,12 @@ Statusline::Statusline(Debugger &debugger)
Statusline::~Statusline() { Disable(); }

void Statusline::TerminalSizeChanged() {
UpdateTerminalProperties();
m_terminal_width = m_debugger.GetTerminalWidth();
m_terminal_height = m_debugger.GetTerminalHeight();

// This definitely isn't signal safe, but the best we can do, until we
// have proper signal-catching thread.
UpdateScrollWindow(ResizeStatusline);

// Draw the old statusline.
Redraw(/*update=*/false);
}

Expand Down Expand Up @@ -85,38 +88,40 @@ void Statusline::Draw(std::string str) {
locked_stream << ANSI_RESTORE_CURSOR;
}

void Statusline::UpdateTerminalProperties() {
UpdateScrollWindow(DisableStatusline);
m_terminal_width = m_debugger.GetTerminalWidth();
m_terminal_height = m_debugger.GetTerminalHeight();
UpdateScrollWindow(EnableStatusline);
}

void Statusline::UpdateScrollWindow(ScrollWindowMode mode) {
assert(m_terminal_width != 0 && m_terminal_height != 0);

lldb::LockableStreamFileSP stream_sp = m_debugger.GetOutputStreamSP();
if (!stream_sp)
return;

const unsigned scroll_height =
(mode == DisableStatusline) ? m_terminal_height : m_terminal_height - 1;

const unsigned reduced_scroll_window = m_terminal_height - 1;
LockedStreamFile locked_stream = stream_sp->Lock();

if (mode == EnableStatusline) {
switch (mode) {
case 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;

if (mode == DisableStatusline) {
// Reduce the scroll window.
locked_stream << ANSI_SAVE_CURSOR;
locked_stream.Printf(ANSI_SET_SCROLL_ROWS, reduced_scroll_window);
locked_stream << ANSI_RESTORE_CURSOR;
break;
case DisableStatusline:
// Reset the scroll window.
locked_stream << ANSI_SAVE_CURSOR;
locked_stream.Printf(ANSI_SET_SCROLL_ROWS, 0);
locked_stream << ANSI_RESTORE_CURSOR;
// Clear the screen below to hide the old statusline.
locked_stream << ANSI_CLEAR_BELOW;
break;
case ResizeStatusline:
// Clear the screen and update the scroll window.
// FIXME: Find a better solution (#146919).
locked_stream << ANSI_CLEAR_SCREEN;
locked_stream.Printf(ANSI_SET_SCROLL_ROWS, reduced_scroll_window);
break;
}

m_debugger.RefreshIOHandler();
Expand Down
10 changes: 4 additions & 6 deletions lldb/test/API/functionalities/statusline/TestStatusline.py
Original file line number Diff line number Diff line change
Expand Up @@ -67,9 +67,7 @@ def test(self):
self.expect('set set separator "| "')

# Hide the statusline and check or the control character.
self.expect(
"set set show-statusline false", ["\x1b[1;{}r".format(self.TERMINAL_HEIGHT)]
)
self.expect("set set show-statusline false", ["\x1b[1;0r"])

def test_no_color(self):
"""Basic test for the statusline with colors disabled."""
Expand Down Expand Up @@ -114,6 +112,6 @@ def test_resize(self):
self.resize()
self.expect("set set show-statusline true", ["no target"])
self.resize(20, 60)
# Check for the escape code to resize the scroll window, followed by
# the prompt.
self.child.expect(re.escape("\x1b[1;19r\x1b8(lldb)"))
# Check for the escape code to resize the scroll window.
self.child.expect(re.escape("\x1b[1;19r"))
self.child.expect("(lldb)")
Loading