feat: anchor review comments to precise text ranges

This commit is contained in:
Valdemar Lorenzen
2026-10-16 14:45:43 +02:00
parent 9a24302b4e
commit 2259d61633
11 changed files with 687 additions and 74 deletions
+38 -18
View File
@@ -341,14 +341,24 @@ impl Editor {
.filter(|_| self.diff_interacting())
.ok_or("Focus a diff text pane to add a comment")?;
if self.selection_count() != 1 {
return Err("Use one caret or one line range for a review comment".into());
return Err("Use one caret or one contiguous selection for a review comment".into());
}
let selection = self.selections().into_iter().next();
let (first, last) = selection.map_or((self.cursor().row, self.cursor().row), |selection| {
let last = selection.end.row.saturating_sub(usize::from(
selection.end.column == 0 && selection.end.row > selection.start.row,
));
(selection.start.row, last)
let range = self.selections().into_iter().next().unwrap_or_else(|| {
let row = self.cursor().row;
Selection {
start: Cursor { row, column: 0 },
end: if row + 1 < self.active.lines.len() {
Cursor {
row: row + 1,
column: 0,
}
} else {
Cursor {
row,
column: grapheme_count(&self.active.lines[row]),
}
},
}
});
let diff = self.diff.as_ref().unwrap();
let comparison = diff.comparison.as_ref().unwrap();
@@ -367,8 +377,14 @@ impl Editor {
}
.clone(),
side,
start_line: first + 1,
end_line: last + 1,
start: TextPosition {
row: range.start.row,
column: range.start.column,
},
end: TextPosition {
row: range.end.row,
column: range.end.column,
},
content: self.active.lines.join("\n"),
};
let id = diff
@@ -405,10 +421,12 @@ impl Editor {
let text = comment.body.clone();
let anchor = &comment.anchor;
let title = format!(
"Comment #{id} · {}:{}–{} · {:?} · :w saves review",
"Comment #{id} · {}:{}:{}–{}:{} · {:?} · :w saves review",
anchor.path.display(),
anchor.start_line,
anchor.end_line,
anchor.start.row + 1,
anchor.start.column + 1,
anchor.end.row + 1,
anchor.end.column + 1,
anchor.side
);
let target = diff.comparison.as_ref().and_then(|comparison| {
@@ -479,16 +497,16 @@ impl Editor {
self.set_message("Comment is stale; original snapshot anchor preserved");
return;
}
let row = comment.anchor.start_line - 1;
let position = comment.anchor.start;
let focus = if comment.anchor.side == Side::Before {
Focus::Before
} else {
Focus::After
};
diff.focus = focus;
diff.reveal_source_row(focus, row);
diff.reveal_source_row(focus, position.row);
self.bind_diff_buffer();
self.place_navigation(TextPosition { row, column: 0 });
self.place_navigation(position);
}
fn open_review_overview(&mut self) -> Result<(), String> {
@@ -529,11 +547,13 @@ impl Editor {
use std::fmt::Write as _;
write!(
text,
"\n## Comment #{} · {status}\n{}:{}–{} · {:?}\nRevision: {}\n{}\n",
"\n## Comment #{} · {status}\n{}:{}:{}–{}:{} · {:?}\nRevision: {}\n{}\n",
comment.id,
anchor.path.display(),
anchor.start_line,
anchor.end_line,
anchor.start.row + 1,
anchor.start.column + 1,
anchor.end.row + 1,
anchor.end.column + 1,
anchor.side,
anchor.revision,
comment.body