Skip to content

Commit aa889ed

Browse files
committed
[lldb] Fix statusline terminal resizing
Simplify and fix the logic to clear the old statusline when the terminal window dimensions have changed. I accidentally broke the terminal resizing behavior when addressing code review feedback. I'd really like to figure out a way to test this. PExpect isn't a good fit for this, because I really need to check the result, rather than the control characters, as the latter doesn't tell me whether any part of the old statusline is still visible.
1 parent fe3e9c2 commit aa889ed

File tree

2 files changed

+23
-56
lines changed

2 files changed

+23
-56
lines changed

lldb/include/lldb/Core/Statusline.h

Lines changed: 2 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,6 @@
1010
#define LLDB_CORE_STATUSLINE_H
1111

1212
#include "lldb/lldb-forward.h"
13-
#include "llvm/ADT/StringRef.h"
14-
#include <csignal>
1513
#include <cstdint>
1614
#include <string>
1715

@@ -34,10 +32,6 @@ class Statusline {
3432
/// Inform the statusline that the terminal dimensions have changed.
3533
void TerminalSizeChanged();
3634

37-
protected:
38-
/// Pad and trim the given string to fit to the given width.
39-
static std::string TrimAndPad(std::string str, size_t width);
40-
4135
private:
4236
/// Draw the statusline with the given text.
4337
void Draw(std::string msg);
@@ -46,20 +40,15 @@ class Statusline {
4640
void UpdateTerminalProperties();
4741

4842
enum ScrollWindowMode {
49-
ScrollWindowExtend,
50-
ScrollWindowShrink,
43+
EnableStatusline,
44+
DisableStatusline,
5145
};
5246

5347
/// Set the scroll window for the given mode.
5448
void UpdateScrollWindow(ScrollWindowMode mode);
5549

56-
/// Clear the statusline (without redrawing the background).
57-
void Reset();
58-
5950
Debugger &m_debugger;
6051
std::string m_last_str;
61-
62-
volatile std::sig_atomic_t m_terminal_size_has_changed = 1;
6352
uint64_t m_terminal_width = 0;
6453
uint64_t m_terminal_height = 0;
6554
};

lldb/source/Core/Statusline.cpp

Lines changed: 21 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -23,50 +23,49 @@
2323
#define ANSI_SAVE_CURSOR ESCAPE "7"
2424
#define ANSI_RESTORE_CURSOR ESCAPE "8"
2525
#define ANSI_CLEAR_BELOW ESCAPE "[J"
26-
#define ANSI_CLEAR_LINE "\r\x1B[2K"
26+
#define ANSI_CURSOR_DOWN ESCAPE "[B"
27+
#define ANSI_CLEAR_LINE ESCAPE "[2K"
2728
#define ANSI_SET_SCROLL_ROWS ESCAPE "[0;%ur"
2829
#define ANSI_TO_START_OF_ROW ESCAPE "[%u;0f"
2930
#define ANSI_UP_ROWS ESCAPE "[%dA"
3031

3132
using namespace lldb;
3233
using namespace lldb_private;
3334

34-
Statusline::Statusline(Debugger &debugger) : m_debugger(debugger) { Enable(); }
35+
Statusline::Statusline(Debugger &debugger)
36+
: m_debugger(debugger), m_terminal_width(m_debugger.GetTerminalWidth()),
37+
m_terminal_height(m_debugger.GetTerminalHeight()) {
38+
Enable();
39+
}
3540

3641
Statusline::~Statusline() { Disable(); }
3742

3843
void Statusline::TerminalSizeChanged() {
39-
m_terminal_size_has_changed = 1;
44+
UpdateTerminalProperties();
4045

4146
// This definitely isn't signal safe, but the best we can do, until we
4247
// have proper signal-catching thread.
4348
Redraw(/*update=*/false);
4449
}
4550

4651
void Statusline::Enable() {
47-
UpdateTerminalProperties();
48-
4952
// Reduce the scroll window to make space for the status bar below.
50-
UpdateScrollWindow(ScrollWindowShrink);
53+
UpdateScrollWindow(EnableStatusline);
5154

5255
// Draw the statusline.
53-
Redraw();
56+
Redraw(/*update=*/true);
5457
}
5558

5659
void Statusline::Disable() {
57-
UpdateTerminalProperties();
58-
5960
// Extend the scroll window to cover the status bar.
60-
UpdateScrollWindow(ScrollWindowExtend);
61+
UpdateScrollWindow(DisableStatusline);
6162
}
6263

6364
void Statusline::Draw(std::string str) {
6465
lldb::LockableStreamFileSP stream_sp = m_debugger.GetOutputStreamSP();
6566
if (!stream_sp)
6667
return;
6768

68-
UpdateTerminalProperties();
69-
7069
m_last_str = str;
7170

7271
str = ansi::TrimAndPad(str, m_terminal_width);
@@ -80,58 +79,37 @@ void Statusline::Draw(std::string str) {
8079
locked_stream << ANSI_RESTORE_CURSOR;
8180
}
8281

83-
void Statusline::Reset() {
84-
lldb::LockableStreamFileSP stream_sp = m_debugger.GetOutputStreamSP();
85-
if (!stream_sp)
86-
return;
87-
88-
LockedStreamFile locked_stream = stream_sp->Lock();
89-
locked_stream << ANSI_SAVE_CURSOR;
90-
locked_stream.Printf(ANSI_TO_START_OF_ROW,
91-
static_cast<unsigned>(m_terminal_height));
92-
locked_stream << ANSI_CLEAR_LINE;
93-
locked_stream << ANSI_RESTORE_CURSOR;
94-
}
95-
9682
void Statusline::UpdateTerminalProperties() {
97-
if (m_terminal_size_has_changed == 0)
98-
return;
99-
100-
// Clear the previous statusline using the previous dimensions.
101-
Reset();
102-
83+
UpdateScrollWindow(DisableStatusline);
10384
m_terminal_width = m_debugger.GetTerminalWidth();
10485
m_terminal_height = m_debugger.GetTerminalHeight();
105-
106-
// Set the scroll window based on the new terminal height.
107-
UpdateScrollWindow(ScrollWindowShrink);
108-
109-
// Clear the flag.
110-
m_terminal_size_has_changed = 0;
86+
UpdateScrollWindow(EnableStatusline);
11187
}
11288

11389
void Statusline::UpdateScrollWindow(ScrollWindowMode mode) {
90+
assert(m_terminal_width != 0 && m_terminal_height != 0);
91+
11492
lldb::LockableStreamFileSP stream_sp = m_debugger.GetOutputStreamSP();
11593
if (!stream_sp)
11694
return;
11795

11896
const unsigned scroll_height =
119-
(mode == ScrollWindowExtend) ? m_terminal_height : m_terminal_height - 1;
97+
(mode == DisableStatusline) ? m_terminal_height : m_terminal_height - 1;
12098

12199
LockedStreamFile locked_stream = stream_sp->Lock();
122100
locked_stream << ANSI_SAVE_CURSOR;
123101
locked_stream.Printf(ANSI_SET_SCROLL_ROWS, scroll_height);
124102
locked_stream << ANSI_RESTORE_CURSOR;
125103
switch (mode) {
126-
case ScrollWindowExtend:
127-
// Clear the screen below to hide the old statusline.
128-
locked_stream << ANSI_CLEAR_BELOW;
129-
break;
130-
case ScrollWindowShrink:
104+
case EnableStatusline:
131105
// Move everything on the screen up.
132106
locked_stream.Printf(ANSI_UP_ROWS, 1);
133107
locked_stream << '\n';
134108
break;
109+
case DisableStatusline:
110+
// Clear the screen below to hide the old statusline.
111+
locked_stream << ANSI_CLEAR_BELOW;
112+
break;
135113
}
136114
}
137115

0 commit comments

Comments
 (0)