diff options
Diffstat (limited to 'src/ui/source_view.cpp')
| -rw-r--r-- | src/ui/source_view.cpp | 106 |
1 files changed, 100 insertions, 6 deletions
diff --git a/src/ui/source_view.cpp b/src/ui/source_view.cpp index dfd0bfb..a98594c 100644 --- a/src/ui/source_view.cpp +++ b/src/ui/source_view.cpp @@ -267,12 +267,9 @@ namespace Hsdbg macros.find(word) != nullptr) kind = SyntaxKind::Macro; - if (kind != SyntaxKind::Default) - { - flush_default(start); - emit(start, at - start, kind); - run = at; - } + flush_default(start); + emit(start, at - start, kind); + run = at; continue; } @@ -315,11 +312,57 @@ namespace Hsdbg const ImU32 BREAKPOINT_DISABLED_COLOR = IM_COL32(120, 90, 90, 255); const ImU32 BREAKPOINT_HOVER_COLOR = IM_COL32(226, 84, 84, 90); + const ImU32 INLINE_VALUE_COLOR = IM_COL32(122, 140, 170, 235); + auto line_number_width(size_t line_count) -> float { return ImGui::CalcTextSize(std::to_string(line_count).c_str()).x; } + auto find_local(std::span<const Variable> locals, std::string_view word) -> const Variable* + { + const auto match = std::ranges::find_if(locals, [&](const Variable& local) + { + return !local.value.empty() && local.name == word; + }); + + return match != locals.end() ? &*match : nullptr; + } + + auto contains_word(const std::string& line, const std::string& name) -> bool + { + if (name.empty()) + return false; + + for (size_t at = line.find(name); at != std::string::npos; at = line.find(name, at + 1)) + { + const bool left = at > 0 && is_word(line[at - 1]); + const bool right = at + name.size() < line.size() && is_word(line[at + name.size()]); + + if (!left && !right) + return true; + } + + return false; + } + + auto inline_value(const Variable& local) -> std::string + { + std::string text = local.name + " = " + local.value; + + if (const auto newline = text.find('\n'); newline != std::string::npos) + text.resize(newline); + + constexpr size_t cap = 48; + if (text.size() > cap) + { + text.resize(cap - 3); + text += "..."; + } + + return text; + } + auto capture_invocation(const std::string& line, uint32_t start) -> std::string { const size_t size = line.size(); @@ -415,6 +458,13 @@ namespace Hsdbg return request; } + auto SourceView::take_watch_request() -> std::optional<std::string> + { + std::optional<std::string> request = std::move(m_watch_request); + m_watch_request.reset(); + return request; + } + auto SourceView::set_highlighted_line(uint32_t line) -> void { m_highlighted_line = line; @@ -480,6 +530,10 @@ namespace Hsdbg m_scroll_to_highlight = false; } + const std::span<const Variable> locals = + (debugger.is_stopped() && m_highlighted_line != 0) ? debugger.locals() + : std::span<const Variable>{}; + ImGuiListClipper clipper; clipper.Begin(static_cast<int>(m_lines.size()), text_height); @@ -580,6 +634,21 @@ namespace Hsdbg if (span.kind == SyntaxKind::Default) { ImGui::TextUnformatted(begin, end); + + const std::string_view word(begin, static_cast<size_t>(end - begin)); + const bool is_name = !word.empty() && is_word_start(word.front()); + + if (!locals.empty() && ImGui::IsItemHovered()) + { + if (const Variable* local = find_local(locals, word)) + ImGui::SetTooltip("%s = %s%s%s", local->name.c_str(), + local->value.c_str(), + local->type.empty() ? "" : "\n", + local->type.c_str()); + } + + if (is_name && ImGui::IsItemClicked(ImGuiMouseButton_Right)) + m_watch_request = std::string(word); } else if (span.kind == SyntaxKind::Macro) { @@ -594,6 +663,31 @@ namespace Hsdbg } } } + + if (!locals.empty() && line_number <= m_highlighted_line) + { + int shown = 0; + + for (const Variable& local : locals) + { + if (shown >= 4) + break; + + if (local.value.empty() || !contains_word(text, local.name)) + continue; + + ImGui::SameLine(0.0f, shown == 0 ? GUTTER_MARGIN * 3.0f : GUTTER_MARGIN); + ImGui::PushStyleColor(ImGuiCol_Text, INLINE_VALUE_COLOR); + ImGui::TextUnformatted(inline_value(local).c_str()); + ImGui::PopStyleColor(); + + if (ImGui::IsItemHovered()) + ImGui::SetTooltip("%s = %s%s%s", local.name.c_str(), local.value.c_str(), + local.type.empty() ? "" : "\n", local.type.c_str()); + + ++shown; + } + } } } |
