Step 101: annotation conflict highlighting

This commit is contained in:
Bill
2026-02-09 10:39:48 -07:00
parent 865cb3efa6
commit 7738c3d6b4
6 changed files with 208 additions and 0 deletions

View File

@@ -28,6 +28,7 @@ struct CodeEditorOptions {
const std::vector<struct DiagnosticRange>* diagnostics = nullptr;
const std::vector<struct AnnotationMarker>* annotations = nullptr;
const std::vector<struct SuggestionMarker>* suggestions = nullptr;
const std::vector<struct AnnotationConflictMarker>* conflicts = nullptr;
};
struct CodeEditorResult {
@@ -71,6 +72,15 @@ struct SuggestionMarker {
std::string nodeId;
};
struct AnnotationConflictMarker {
int childLine = -1;
int parentLine = -1;
std::string message;
std::string childAnnoId;
std::string parentAnnoId;
std::string parentStrategy;
};
struct FoldRegion {
int startLine = 0;
int endLine = 0;
@@ -311,6 +321,30 @@ public:
}
}
// Conflict markers: highlight and connecting line
if (options.conflicts) {
AnnotationConflictMarker conflict;
if (conflictAtLine(*options.conflicts, ln, conflict)) {
ImVec2 center(origin.x + 12.0f, y + lineHeight * 0.5f);
drawList->AddCircle(center, 5.0f, IM_COL32(220, 80, 80, 255), 12, 1.5f);
if (ln == std::min(conflict.childLine, conflict.parentLine) &&
conflict.childLine >= 0 && conflict.parentLine >= 0) {
float y1 = textBase.y + conflict.childLine * lineHeight + lineHeight * 0.5f;
float y2 = textBase.y + conflict.parentLine * lineHeight + lineHeight * 0.5f;
drawList->AddLine(ImVec2(origin.x + 12.0f, y1),
ImVec2(origin.x + 12.0f, y2),
IM_COL32(220, 80, 80, 180), 1.0f);
}
ImVec2 a(center.x - 5.0f, center.y - 5.0f);
ImVec2 b(center.x + 5.0f, center.y + 5.0f);
if (ImGui::IsMouseHoveringRect(a, b)) {
ImGui::BeginTooltip();
ImGui::TextUnformatted(conflict.message.c_str());
ImGui::EndTooltip();
}
}
}
// Fold indicator
const FoldRegion* fold = findFoldAtLine(ln);
if (fold) {
@@ -623,6 +657,18 @@ private:
return false;
}
static bool conflictAtLine(const std::vector<AnnotationConflictMarker>& markers,
int line,
AnnotationConflictMarker& out) {
for (const auto& m : markers) {
if (m.childLine == line || m.parentLine == line) {
out = m;
return true;
}
}
return false;
}
static std::string diagnosticMessageAtLine(const std::vector<DiagnosticRange>& diags, int line) {
for (const auto& d : diags) {
if (line >= d.startLine && line <= d.endLine) return d.message;