pub fn source_position_at(
read: impl Fn(usize) -> Option<String>,
cursor: usize,
cursor_byte: u32,
) -> Option<SourcePos>Expand description
MG.50: the SOURCE position the cursor is looking at, inside a diff.
<CR> in emacs magit opens the file at the code under the cursor,
not at the top. The diff already carries the answer: a hunk’s @@
header names where its body starts in the new file, so the target is
that start plus however many new-side rows precede the cursor within
the hunk.
Which rows count. Only those that exist on the NEW side — context
( ) and additions (+). A deletion (-) is not in the file being
opened, so it advances nothing; a cursor sitting on one resolves to
the position where the deleted text was, which is where a reader
looking at it wants to land. \ No newline at end of file belongs to
neither side.
The byte offset. Every hunk body row carries the one-character
diff marker ( / + / -) at byte 0, so source byte = cursor byte
− 1. Subtracting a BYTE rather than a column is what makes this
correct on rows containing multibyte text: the marker is always
exactly one byte, whatever follows it. saturating_sub handles a
cursor parked ON the marker, which resolves to the start of the
source line rather than wrapping. On the @@ row there is no code
under the cursor to align to, so the offset is 0.
Line and offset are answered together, by one walk, rather than
by a source_line_at plus a separate offset helper. The bug this
replaced was precisely a caller that had the line and defaulted the
offset to 0; a shape where you cannot obtain one without the other
cannot regress that way again.
None when the cursor is not inside a hunk (a file entry, a section
header, a diff --git line) — the caller then opens at the top,
which is what emacs does for a file entry too.