fix: preserve review comments across unrelated edits

This commit is contained in:
Valdemar Lorenzen
2026-10-20 14:58:56 +02:00
parent 2727425518
commit 31203889bb
10 changed files with 422 additions and 147 deletions
+34 -19
View File
@@ -4366,16 +4366,18 @@ fn draw_diff_pane(
.document
.comments
.iter()
.filter(|comment| {
.filter_map(|comment| {
let before = comment.anchor.side == crate::review::Side::Before;
let path = if before {
file.old_path.as_ref().unwrap_or(&file.path)
} else {
&file.path
};
(unified || before == (focus == Focus::Before))
&& comment.anchor.path == *path
&& diff.review_anchor_current(&comment.anchor)
if !(unified || before == (focus == Focus::Before)) || comment.anchor.path != *path {
return None;
}
diff.review_anchor_range(&comment.anchor)
.map(|range| (comment, range))
});
paint_diff_content(
frame,
@@ -4407,7 +4409,12 @@ fn paint_diff_content<'a>(
highlight_trailing_whitespace: bool,
whitespace_characters: Option<&BTreeMap<char, char>>,
whitespace_scope: WhitespaceScope,
review_comments: impl Iterator<Item = &'a crate::review::Comment> + Clone,
review_comments: impl Iterator<
Item = (
&'a crate::review::Comment,
std::ops::Range<crate::plugin::TextPosition>,
),
> + Clone,
selected_review: Option<u64>,
) -> Rect {
if view.info.display_len == 0 {
@@ -4430,8 +4437,7 @@ fn paint_diff_content<'a>(
let width = usize::from(content.width).saturating_sub(gutter);
let selected_anchor = review_comments
.clone()
.find(|comment| selected_review == Some(comment.id))
.map(|comment| &comment.anchor);
.find(|(comment, _)| selected_review == Some(comment.id));
for (screen, display_row, segments) in
diff_screen_rows(view.info.display_len, top, content.height, wrapped)
{
@@ -4584,22 +4590,24 @@ fn paint_diff_content<'a>(
};
paint_trailing_whitespace(frame, &text, text_area, left);
}
if let Some(anchor) = selected_anchor {
let side = match anchor.side {
if let Some((comment, range)) = &selected_anchor {
let side = match comment.anchor.side {
crate::review::Side::Before => Focus::Before,
crate::review::Side::After => Focus::After,
};
if let Some(source_row) = view
.review_row(side, display_row)
.filter(|source_row| anchor.rows().contains(source_row))
{
let start = if source_row == anchor.start.row {
anchor.start.column
if let Some(source_row) = view.review_row(side, display_row).filter(|source_row| {
(range.start.row
..=range.end.row
- usize::from(range.end.column == 0 && range.end.row > range.start.row))
.contains(source_row)
}) {
let start = if source_row == range.start.row {
range.start.column
} else {
0
};
let end = if source_row == anchor.end.row {
anchor.end.column
let end = if source_row == range.end.row {
range.end.column
} else {
usize::MAX
};
@@ -4615,7 +4623,7 @@ fn paint_diff_content<'a>(
}
}
if gutter > 0 {
for comment in review_comments {
for (comment, range) in review_comments {
let side = match comment.anchor.side {
crate::review::Side::Before => Focus::Before,
crate::review::Side::After => Focus::After,
@@ -4626,7 +4634,14 @@ fn paint_diff_content<'a>(
{
let source = view.review_row(side, display);
if wrapped.is_some_and(|rows| rows[screen].position.continuation != 0)
|| !source.is_some_and(|row| comment.anchor.rows().contains(&row))
|| !source.is_some_and(|row| {
(range.start.row
..=range.end.row
- usize::from(
range.end.column == 0 && range.end.row > range.start.row,
))
.contains(&row)
})
{
continue;
}