Skip to main content

path_at_cursor

Function path_at_cursor 

Source
pub fn path_at_cursor(
    read: impl Fn(usize) -> Option<String>,
    cursor: usize,
) -> Option<PathBuf>
Expand description

Locate the hunk containing cursor, reading lines through read.

read(i) returns line i without its trailing newline, or None past the end. Lines are used verbatim — trailing whitespace is part of the diff’s content, and trimming it produces a patch whose context no longer matches the file.

Returns None when the cursor is not inside a hunk body — on a section header, a file entry, a commit message, a diff’s own ---/+++ header lines, or anywhere after the last body line of the hunk above. Callers fall back to file-level staging, which is what keeps every pre-MG.18 behaviour intact. MG.22: the file a diff line belongs to — the one diff-path parser.

Three modes had a copy of this (magit-diff, magit-commit, magit-revision), each scanning upward for diff --git a/<path>, and magit-revision additionally checking the cursor line for a git show --stat summary row (" src/main.rs | 12 +++++-----").

The order of those two checks is load-bearing, and the copy that had both got it wrong. magit-revision tried the stat row first, and parse_stat_line splits on " | " — so <CR> on any diff body line containing that sequence ( let x = a | b;, a markdown table, a doc comment) resolved to the text left of the pipe and opened a buffer named after it.

Scanning for the diff --git header first removes the ambiguity structurally rather than by tightening the stat pattern: a diff body line always has a header above it, and a stat row never does, because git show --stat -p prints the summary before the first diff. So reaching the stat check at all means the cursor is above every diff, which is exactly where stat rows live.

Reads through an accessor rather than a materialised buffer, for the reason hunk_at_with does: a large git show is tens of thousands of lines and resolving one path must not copy them.