Skip to content

Commit 14406ca

Browse files
committed
[lldb][gui] use syntax highlighting also in gui mode
Use the same functionality as the non-gui mode, the colors just need translating to curses colors. Differential Revision: https://reviews.llvm.org/D85145
1 parent fc0e8fb commit 14406ca

File tree

1 file changed

+105
-26
lines changed

1 file changed

+105
-26
lines changed

lldb/source/Core/IOHandlerCursesGUI.cpp

Lines changed: 105 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -396,11 +396,11 @@ class Window {
396396
::wbkgd(m_window, COLOR_PAIR(color_pair_idx));
397397
}
398398

399-
void PutCStringTruncated(int right_pad, const char *s) {
399+
void PutCStringTruncated(int right_pad, const char *s, int len = -1) {
400400
int bytes_left = GetWidth() - GetCursorX();
401401
if (bytes_left > right_pad) {
402402
bytes_left -= right_pad;
403-
::waddnstr(m_window, s, bytes_left);
403+
::waddnstr(m_window, s, len < 0 ? bytes_left : std::min(bytes_left, len));
404404
}
405405
}
406406

@@ -452,6 +452,62 @@ class Window {
452452
return std::min<size_t>(length, std::max(0, GetWidth() - GetCursorX() - 1));
453453
}
454454

455+
// Curses doesn't allow direct output of color escape sequences, but that's
456+
// how we get source lines from the Highligher class. Read the line and
457+
// convert color escape sequences to curses color attributes.
458+
void OutputColoredStringTruncated(int right_pad, StringRef string,
459+
bool use_blue_background) {
460+
attr_t saved_attr;
461+
short saved_pair;
462+
int saved_opts;
463+
::wattr_get(m_window, &saved_attr, &saved_pair, &saved_opts);
464+
if (use_blue_background)
465+
::wattron(m_window, COLOR_PAIR(16));
466+
while (!string.empty()) {
467+
size_t esc_pos = string.find('\x1b');
468+
if (esc_pos == StringRef::npos) {
469+
PutCStringTruncated(right_pad, string.data(), string.size());
470+
break;
471+
}
472+
if (esc_pos > 0) {
473+
PutCStringTruncated(right_pad, string.data(), esc_pos);
474+
string = string.drop_front(esc_pos);
475+
}
476+
bool consumed = string.consume_front("\x1b");
477+
assert(consumed);
478+
UNUSED_IF_ASSERT_DISABLED(consumed);
479+
// This is written to match our Highlighter classes, which seem to
480+
// generate only foreground color escape sequences. If necessary, this
481+
// will need to be extended.
482+
if (!string.consume_front("[")) {
483+
llvm::errs() << "Missing '[' in color escape sequence.\n";
484+
continue;
485+
}
486+
// Only 8 basic foreground colors and reset, our Highlighter doesn't use
487+
// anything else.
488+
int value;
489+
if (!!string.consumeInteger(10, value) || // Returns false on success.
490+
!(value == 0 || (value >= 30 && value <= 37))) {
491+
llvm::errs() << "No valid color code in color escape sequence.\n";
492+
continue;
493+
}
494+
if (!string.consume_front("m")) {
495+
llvm::errs() << "Missing 'm' in color escape sequence.\n";
496+
continue;
497+
}
498+
if (value == 0) { // Reset.
499+
::wattr_set(m_window, saved_attr, saved_pair, &saved_opts);
500+
if (use_blue_background)
501+
::wattron(m_window, COLOR_PAIR(16));
502+
} else {
503+
// Mapped directly to first 16 color pairs (black/blue background).
504+
::wattron(m_window,
505+
COLOR_PAIR(value - 30 + 1 + (use_blue_background ? 8 : 0)));
506+
}
507+
}
508+
::wattr_set(m_window, saved_attr, saved_pair, &saved_opts);
509+
}
510+
455511
void Touch() {
456512
::touchwin(m_window);
457513
if (m_parent)
@@ -540,7 +596,7 @@ class Window {
540596
void DrawTitleBox(const char *title, const char *bottom_message = nullptr) {
541597
attr_t attr = 0;
542598
if (IsActive())
543-
attr = A_BOLD | COLOR_PAIR(2);
599+
attr = A_BOLD | COLOR_PAIR(18);
544600
else
545601
attr = 0;
546602
if (attr)
@@ -970,14 +1026,14 @@ void Menu::DrawMenuTitle(Window &window, bool highlight) {
9701026

9711027
if (m_key_name.empty()) {
9721028
if (!underlined_shortcut && llvm::isPrint(m_key_value)) {
973-
window.AttributeOn(COLOR_PAIR(3));
1029+
window.AttributeOn(COLOR_PAIR(19));
9741030
window.Printf(" (%c)", m_key_value);
975-
window.AttributeOff(COLOR_PAIR(3));
1031+
window.AttributeOff(COLOR_PAIR(19));
9761032
}
9771033
} else {
978-
window.AttributeOn(COLOR_PAIR(3));
1034+
window.AttributeOn(COLOR_PAIR(19));
9791035
window.Printf(" (%s)", m_key_name.c_str());
980-
window.AttributeOff(COLOR_PAIR(3));
1036+
window.AttributeOff(COLOR_PAIR(19));
9811037
}
9821038
}
9831039
}
@@ -989,7 +1045,7 @@ bool Menu::WindowDelegateDraw(Window &window, bool force) {
9891045
Menu::Type menu_type = GetType();
9901046
switch (menu_type) {
9911047
case Menu::Type::Bar: {
992-
window.SetBackground(2);
1048+
window.SetBackground(18);
9931049
window.MoveCursor(0, 0);
9941050
for (size_t i = 0; i < num_submenus; ++i) {
9951051
Menu *menu = submenus[i].get();
@@ -1009,7 +1065,7 @@ bool Menu::WindowDelegateDraw(Window &window, bool force) {
10091065
int cursor_x = 0;
10101066
int cursor_y = 0;
10111067
window.Erase();
1012-
window.SetBackground(2);
1068+
window.SetBackground(18);
10131069
window.Box();
10141070
for (size_t i = 0; i < num_submenus; ++i) {
10151071
const bool is_selected = (i == static_cast<size_t>(selected_idx));
@@ -2384,7 +2440,7 @@ class ValueObjectListDelegate : public WindowDelegate {
23842440

23852441
attr_t changd_attr = 0;
23862442
if (valobj->GetValueDidChange())
2387-
changd_attr = COLOR_PAIR(5) | A_BOLD;
2443+
changd_attr = COLOR_PAIR(2) | A_BOLD;
23882444

23892445
if (value && value[0]) {
23902446
window.PutCStringTruncated(1, " = ");
@@ -3253,7 +3309,7 @@ class StatusBarWindowDelegate : public WindowDelegate {
32533309
Thread *thread = exe_ctx.GetThreadPtr();
32543310
StackFrame *frame = exe_ctx.GetFramePtr();
32553311
window.Erase();
3256-
window.SetBackground(2);
3312+
window.SetBackground(18);
32573313
window.MoveCursor(0, 0);
32583314
if (process) {
32593315
const StateType state = process->GetState();
@@ -3525,7 +3581,7 @@ class SourceFileWindowDelegate : public WindowDelegate {
35253581
}
35263582

35273583
const attr_t selected_highlight_attr = A_REVERSE;
3528-
const attr_t pc_highlight_attr = COLOR_PAIR(1);
3584+
const attr_t pc_highlight_attr = COLOR_PAIR(9);
35293585

35303586
for (size_t i = 0; i < num_visible_lines; ++i) {
35313587
const uint32_t curr_line = m_first_visible_line + i;
@@ -3544,7 +3600,7 @@ class SourceFileWindowDelegate : public WindowDelegate {
35443600
highlight_attr = selected_highlight_attr;
35453601

35463602
if (bp_lines.find(curr_line + 1) != bp_lines.end())
3547-
bp_attr = COLOR_PAIR(2);
3603+
bp_attr = COLOR_PAIR(18);
35483604

35493605
if (bp_attr)
35503606
window.AttributeOn(bp_attr);
@@ -3563,10 +3619,13 @@ class SourceFileWindowDelegate : public WindowDelegate {
35633619

35643620
if (highlight_attr)
35653621
window.AttributeOn(highlight_attr);
3566-
const uint32_t line_len = window.LimitLengthToRestOfLine(
3567-
m_file_sp->GetLineLength(curr_line + 1, false));
3568-
if (line_len > 0)
3569-
window.PutCString(m_file_sp->PeekLineData(curr_line + 1), line_len);
3622+
3623+
StreamString lineStream;
3624+
m_file_sp->DisplaySourceLines(curr_line + 1, {}, 0, 0, &lineStream);
3625+
StringRef line = lineStream.GetString();
3626+
if (line.endswith("\n"))
3627+
line = line.drop_back();
3628+
window.OutputColoredStringTruncated(1, line, is_pc_line);
35703629

35713630
if (is_pc_line && frame_sp &&
35723631
frame_sp->GetConcreteFrameIndex() == 0) {
@@ -3580,10 +3639,13 @@ class SourceFileWindowDelegate : public WindowDelegate {
35803639
int desc_x = window_width - stop_description_len - 16;
35813640
if (desc_x - window.GetCursorX() > 0)
35823641
window.Printf("%*s", desc_x - window.GetCursorX(), "");
3583-
window.MoveCursor(window_width - stop_description_len - 15,
3642+
window.MoveCursor(window_width - stop_description_len - 16,
35843643
line_y);
3585-
window.PrintfTruncated(1, "<<< Thread %u: %s ",
3644+
const attr_t stop_reason_attr = COLOR_PAIR(17);
3645+
window.AttributeOn(stop_reason_attr);
3646+
window.PrintfTruncated(1, " <<< Thread %u: %s ",
35863647
thread->GetIndexID(), stop_description);
3648+
window.AttributeOff(stop_reason_attr);
35873649
}
35883650
} else {
35893651
window.Printf("%*s", window_width - window.GetCursorX() - 1, "");
@@ -3623,7 +3685,7 @@ class SourceFileWindowDelegate : public WindowDelegate {
36233685
}
36243686

36253687
const attr_t selected_highlight_attr = A_REVERSE;
3626-
const attr_t pc_highlight_attr = COLOR_PAIR(1);
3688+
const attr_t pc_highlight_attr = COLOR_PAIR(17);
36273689

36283690
StreamString strm;
36293691

@@ -3671,7 +3733,7 @@ class SourceFileWindowDelegate : public WindowDelegate {
36713733

36723734
if (bp_file_addrs.find(inst->GetAddress().GetFileAddress()) !=
36733735
bp_file_addrs.end())
3674-
bp_attr = COLOR_PAIR(2);
3736+
bp_attr = COLOR_PAIR(18);
36753737

36763738
if (bp_attr)
36773739
window.AttributeOn(bp_attr);
@@ -4190,11 +4252,28 @@ void IOHandlerCursesGUI::Activate() {
41904252
main_window_sp->CreateHelpSubwindow();
41914253
}
41924254

4193-
init_pair(1, COLOR_WHITE, COLOR_BLUE);
4194-
init_pair(2, COLOR_BLACK, COLOR_WHITE);
4195-
init_pair(3, COLOR_MAGENTA, COLOR_WHITE);
4196-
init_pair(4, COLOR_MAGENTA, COLOR_BLACK);
4197-
init_pair(5, COLOR_RED, COLOR_BLACK);
4255+
// All colors with black background.
4256+
init_pair(1, COLOR_BLACK, COLOR_BLACK);
4257+
init_pair(2, COLOR_RED, COLOR_BLACK);
4258+
init_pair(3, COLOR_GREEN, COLOR_BLACK);
4259+
init_pair(4, COLOR_YELLOW, COLOR_BLACK);
4260+
init_pair(5, COLOR_BLUE, COLOR_BLACK);
4261+
init_pair(6, COLOR_MAGENTA, COLOR_BLACK);
4262+
init_pair(7, COLOR_CYAN, COLOR_BLACK);
4263+
init_pair(8, COLOR_WHITE, COLOR_BLACK);
4264+
// All colors with blue background.
4265+
init_pair(9, COLOR_BLACK, COLOR_BLUE);
4266+
init_pair(10, COLOR_RED, COLOR_BLUE);
4267+
init_pair(11, COLOR_GREEN, COLOR_BLUE);
4268+
init_pair(12, COLOR_YELLOW, COLOR_BLUE);
4269+
init_pair(13, COLOR_BLUE, COLOR_BLUE);
4270+
init_pair(14, COLOR_MAGENTA, COLOR_BLUE);
4271+
init_pair(15, COLOR_CYAN, COLOR_BLUE);
4272+
init_pair(16, COLOR_WHITE, COLOR_BLUE);
4273+
4274+
init_pair(17, COLOR_WHITE, COLOR_BLUE);
4275+
init_pair(18, COLOR_BLACK, COLOR_WHITE);
4276+
init_pair(19, COLOR_MAGENTA, COLOR_WHITE);
41984277
}
41994278
}
42004279

0 commit comments

Comments
 (0)