hachem.wtf
aboutsummaryrefslogtreecommitdiff
path: root/src/ui/source_view.cpp
diff options
context:
space:
mode:
authorhachem <im@hachem.wtf>2026-03-14 19:30:33 +0100
committerhachem <im@hachem.wtf>2026-03-14 19:30:33 +0100
commitfadc56fa2952ad4031247e9e642a0fa2eab92ee0 (patch)
treec8d535fad584825cc0746fa20987eade349de743 /src/ui/source_view.cpp
parent75c96946c9ad945fadede7d16130966f601ccaa7 (diff)
refactor: overhaul the ui
Diffstat (limited to 'src/ui/source_view.cpp')
-rw-r--r--src/ui/source_view.cpp106
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;
+ }
+ }
}
}