Index: lldb/source/Core/IOHandlerCursesGUI.cpp =================================================================== --- lldb/source/Core/IOHandlerCursesGUI.cpp +++ lldb/source/Core/IOHandlerCursesGUI.cpp @@ -391,11 +391,11 @@ ::wbkgd(m_window, COLOR_PAIR(color_pair_idx)); } - void PutCStringTruncated(int right_pad, const char *s) { + void PutCStringTruncated(int right_pad, const char *s, int len = -1) { int bytes_left = GetWidth() - GetCursorX(); if (bytes_left > right_pad) { bytes_left -= right_pad; - ::waddnstr(m_window, s, bytes_left); + ::waddnstr(m_window, s, len < 0 ? bytes_left : std::min(bytes_left, len)); } } @@ -455,6 +455,61 @@ return std::min(length, std::max(0, GetWidth() - GetCursorX() - 1)); } + // Curses doesn't allow direct output of color escape sequences, but that's + // how we get source lines from the Highligher class. Read the line and + // convert color escape sequences to curses color attributes. + void OutputColoredStringTruncated(int right_pad, const StringRef &string, + bool blue) { + int last_text = -1; // Last position in string that's been written. + int text_length = 0; // Size of normal characters to be written. + attr_t saved_attr; + short saved_pair; + int saved_opts; + ::wattr_get(m_window, &saved_attr, &saved_pair, &saved_opts); + if (blue) + ::wattron(m_window, COLOR_PAIR(16)); + for (size_t i = 0; i < string.size(); ++i) { + if (string[i] != '\x1b') { // esc + ++text_length; + continue; + } else { + if (text_length > 0) { + PutCStringTruncated(right_pad, string.data() + last_text + 1, + text_length); + text_length = 0; + } + ++i; + // Our Highlighter doesn't use any other escape sequences. + assert(string[i] == '['); + ++i; + const int esc_start = i; + while (string[i] != 'm') { + // No semicolons, our Highlighter doesn't use them. + assert(string[i] >= '0' && string[i] <= '9'); + ++i; + assert(i < string.size()); + } + const int value = atoi(string.data() + esc_start); + if (value == 0) { // Reset. + ::wattr_set(m_window, saved_attr, saved_pair, &saved_opts); + if (blue) + ::wattron(m_window, COLOR_PAIR(16)); + } else { + // Only 8 basic foreground colors, our Highlighter doesn't use + // anything else. + assert(value >= 30 && value <= 37); + // Mapped directly to first 16 color pairs (black/blue background). + ::wattron(m_window, COLOR_PAIR(value - 30 + 1 + (blue ? 8 : 0))); + } + last_text = i; + } + } + if (text_length > 0) + PutCStringTruncated(right_pad, string.data() + last_text + 1, + text_length); + ::wattr_set(m_window, saved_attr, saved_pair, &saved_opts); + } + void Touch() { ::touchwin(m_window); if (m_parent) @@ -543,7 +598,7 @@ void DrawTitleBox(const char *title, const char *bottom_message = nullptr) { attr_t attr = 0; if (IsActive()) - attr = A_BOLD | COLOR_PAIR(2); + attr = A_BOLD | COLOR_PAIR(18); else attr = 0; if (attr) @@ -944,9 +999,9 @@ } else { const int shortcut_key = m_key_value; bool underlined_shortcut = false; - const attr_t hilgight_attr = A_REVERSE; + const attr_t highlight_attr = A_REVERSE; if (highlight) - window.AttributeOn(hilgight_attr); + window.AttributeOn(highlight_attr); if (llvm::isPrint(shortcut_key)) { size_t lower_pos = m_name.find(tolower(shortcut_key)); size_t upper_pos = m_name.find(toupper(shortcut_key)); @@ -973,18 +1028,18 @@ } if (highlight) - window.AttributeOff(hilgight_attr); + window.AttributeOff(highlight_attr); if (m_key_name.empty()) { if (!underlined_shortcut && llvm::isPrint(m_key_value)) { - window.AttributeOn(COLOR_PAIR(3)); + window.AttributeOn(COLOR_PAIR(19)); window.Printf(" (%c)", m_key_value); - window.AttributeOff(COLOR_PAIR(3)); + window.AttributeOff(COLOR_PAIR(19)); } } else { - window.AttributeOn(COLOR_PAIR(3)); + window.AttributeOn(COLOR_PAIR(19)); window.Printf(" (%s)", m_key_name.c_str()); - window.AttributeOff(COLOR_PAIR(3)); + window.AttributeOff(COLOR_PAIR(19)); } } } @@ -996,7 +1051,7 @@ Menu::Type menu_type = GetType(); switch (menu_type) { case Menu::Type::Bar: { - window.SetBackground(2); + window.SetBackground(18); window.MoveCursor(0, 0); for (size_t i = 0; i < num_submenus; ++i) { Menu *menu = submenus[i].get(); @@ -1016,7 +1071,7 @@ int cursor_x = 0; int cursor_y = 0; window.Erase(); - window.SetBackground(2); + window.SetBackground(18); window.Box(); for (size_t i = 0; i < num_submenus; ++i) { const bool is_selected = (i == static_cast(selected_idx)); @@ -2391,7 +2446,7 @@ attr_t changd_attr = 0; if (valobj->GetValueDidChange()) - changd_attr = COLOR_PAIR(5) | A_BOLD; + changd_attr = COLOR_PAIR(2) | A_BOLD; if (value && value[0]) { window.PutCStringTruncated(1, " = "); @@ -3260,7 +3315,7 @@ Thread *thread = exe_ctx.GetThreadPtr(); StackFrame *frame = exe_ctx.GetFramePtr(); window.Erase(); - window.SetBackground(2); + window.SetBackground(18); window.MoveCursor(0, 0); if (process) { const StateType state = process->GetState(); @@ -3532,7 +3587,7 @@ } const attr_t selected_highlight_attr = A_REVERSE; - const attr_t pc_highlight_attr = COLOR_PAIR(1); + const attr_t pc_highlight_attr = COLOR_PAIR(9); for (size_t i = 0; i < num_visible_lines; ++i) { const uint32_t curr_line = m_first_visible_line + i; @@ -3551,7 +3606,7 @@ highlight_attr = selected_highlight_attr; if (bp_lines.find(curr_line + 1) != bp_lines.end()) - bp_attr = COLOR_PAIR(6); + bp_attr = COLOR_PAIR(20); if (bp_attr) window.AttributeOn(bp_attr); @@ -3570,10 +3625,13 @@ if (highlight_attr) window.AttributeOn(highlight_attr); - const uint32_t line_len = window.LimitLengthToRestOfLine( - m_file_sp->GetLineLength(curr_line + 1, false)); - if (line_len > 0) - window.PutCString(m_file_sp->PeekLineData(curr_line + 1), line_len); + + StreamString lineStream; + m_file_sp->DisplaySourceLines(curr_line + 1, {}, 0, 0, &lineStream); + StringRef line = lineStream.GetString(); + if (!line.empty() && line.back() == '\n') // remove trailing \n + line = StringRef(line.data(), line.size() - 1); + window.OutputColoredStringTruncated(1, line, is_pc_line); if (is_pc_line && frame_sp && frame_sp->GetConcreteFrameIndex() == 0) { @@ -3587,10 +3645,13 @@ int desc_x = window_width - stop_description_len - 16; if (desc_x - window.GetCursorX() > 0) window.Printf("%*s", desc_x - window.GetCursorX(), ""); - window.MoveCursor(window_width - stop_description_len - 15, + window.MoveCursor(window_width - stop_description_len - 16, line_y); - window.PrintfTruncated(1, "<<< Thread %u: %s ", + const attr_t stop_reason_attr = COLOR_PAIR(17); + window.AttributeOn(stop_reason_attr); + window.PrintfTruncated(1, " <<< Thread %u: %s ", thread->GetIndexID(), stop_description); + window.AttributeOff(stop_reason_attr); } } else { window.Printf("%*s", window_width - window.GetCursorX() - 1, ""); @@ -3630,7 +3691,7 @@ } const attr_t selected_highlight_attr = A_REVERSE; - const attr_t pc_highlight_attr = COLOR_PAIR(1); + const attr_t pc_highlight_attr = COLOR_PAIR(17); StreamString strm; @@ -3678,7 +3739,7 @@ if (bp_file_addrs.find(inst->GetAddress().GetFileAddress()) != bp_file_addrs.end()) - bp_attr = COLOR_PAIR(6); + bp_attr = COLOR_PAIR(20); if (bp_attr) window.AttributeOn(bp_attr); @@ -4190,12 +4251,28 @@ status_window_sp->SetDelegate( WindowDelegateSP(new StatusBarWindowDelegate(m_debugger))); - init_pair(1, COLOR_WHITE, COLOR_BLUE); - init_pair(2, COLOR_BLACK, COLOR_WHITE); - init_pair(3, COLOR_MAGENTA, COLOR_WHITE); - init_pair(4, COLOR_MAGENTA, COLOR_BLACK); - init_pair(5, COLOR_RED, COLOR_BLACK); - init_pair(6, COLOR_WHITE, COLOR_RED); + // All colors with black background. + init_pair(1, COLOR_BLACK, COLOR_BLACK); + init_pair(2, COLOR_RED, COLOR_BLACK); + init_pair(3, COLOR_GREEN, COLOR_BLACK); + init_pair(4, COLOR_YELLOW, COLOR_BLACK); + init_pair(5, COLOR_BLUE, COLOR_BLACK); + init_pair(6, COLOR_MAGENTA, COLOR_BLACK); + init_pair(7, COLOR_CYAN, COLOR_BLACK); + init_pair(8, COLOR_WHITE, COLOR_BLACK); + init_pair(9, COLOR_BLACK, COLOR_BLUE); + init_pair(10, COLOR_RED, COLOR_BLUE); + init_pair(11, COLOR_GREEN, COLOR_BLUE); + init_pair(12, COLOR_YELLOW, COLOR_BLUE); + init_pair(13, COLOR_BLUE, COLOR_BLUE); + init_pair(14, COLOR_MAGENTA, COLOR_BLUE); + init_pair(15, COLOR_CYAN, COLOR_BLUE); + init_pair(16, COLOR_WHITE, COLOR_BLUE); + + init_pair(17, COLOR_WHITE, COLOR_BLUE); + init_pair(18, COLOR_BLACK, COLOR_WHITE); + init_pair(19, COLOR_MAGENTA, COLOR_WHITE); + init_pair(20, COLOR_WHITE, COLOR_RED); } }