Problem
DiffPaneView.OnHunkNavigationRequested (DiffViewer/Views/DiffPaneView.xaml.cs:454-464) scrolls the inline editor to the wrong line when the user navigates via F7/F8 (or any code path that raises HunkNavigationRequested).
private void OnHunkNavigationRequested(object? sender, HunkNavigationEventArgs e)
{
ScrollEditorToLine(LeftEditor, e.LeftLine);
ScrollEditorToLine(RightEditor, e.RightLine);
// Inline mode: the line numbers above are blob-relative, but the
// inline editor's own line numbering is hunk-prefix-based. The
// simplest approximation: scroll to the new-side line + 1 (header).
ScrollEditorToLine(InlineEditor, e.RightLine); // ← bug
}
The comment correctly notes that the inline document interleaves hunk-header lines, so blob-relative line numbers don't translate 1:1. But the actual call passes e.RightLine (the new-side blob line) to the inline editor unchanged. The further down in the file, the larger the offset error.
Why this is fixable cleanly
MapNewLineToInline(int newLine) already exists in the same file (DiffViewer/Views/DiffPaneView.xaml.cs:501-509) and does exactly the inverse lookup needed:
private int MapNewLineToInline(int newLine)
{
if (_vm?.InlineLineToSourceLines is not { Count: > 0 } map) return newLine;
for (int i = 0; i < map.Count; i++)
{
if (map[i].NewLine is int n && n >= newLine) return i + 1;
}
...
}
It's already used by OnScrollRequested (DiffViewer/Views/DiffPaneView.xaml.cs:479+) for the overview-bar click path.
Suggested fix
- ScrollEditorToLine(InlineEditor, e.RightLine);
+ ScrollEditorToLine(InlineEditor, MapNewLineToInline(e.RightLine));
For deletions (a hunk where NewLine is null on the inline doc side because it's a pure removal), consider falling back to a MapOldLineToInline lookup or to the hunk-header line — e.RightLine will be 0 / the line after the deletion, which still won't be ideal.
Test coverage
Add a test that:
- Builds a diff with multiple hunks (e.g., a hunk near line 5 and another near line 50).
- Switches to inline mode.
- Calls
JumpToHunk(1) (the second hunk).
- Asserts the inline editor's current vertical scroll line corresponds to the inline-doc line that maps back to the hunk's
NewStartLine, not the raw NewStartLine.
This is harder to test because it requires WPF layout — but at minimum the helper math (MapNewLineToInline for known fixtures of InlineLineToSourceLines) can be unit-tested.
Citations
DiffViewer/Views/DiffPaneView.xaml.cs:454-464 — buggy handler
DiffViewer/Views/DiffPaneView.xaml.cs:479-492 — OnScrollRequested, the correct pattern
DiffViewer/Views/DiffPaneView.xaml.cs:501-509 — MapNewLineToInline helper that should be used
DiffViewer/Rendering/InlineDiffBuilder.cs — produces InlineLineToSourceLines
Severity
Medium-High. User-visible incorrectness in inline mode; the more interesting (further-down) hunks land off-screen.
Problem
DiffPaneView.OnHunkNavigationRequested(DiffViewer/Views/DiffPaneView.xaml.cs:454-464) scrolls the inline editor to the wrong line when the user navigates via F7/F8 (or any code path that raisesHunkNavigationRequested).The comment correctly notes that the inline document interleaves hunk-header lines, so blob-relative line numbers don't translate 1:1. But the actual call passes
e.RightLine(the new-side blob line) to the inline editor unchanged. The further down in the file, the larger the offset error.Why this is fixable cleanly
MapNewLineToInline(int newLine)already exists in the same file (DiffViewer/Views/DiffPaneView.xaml.cs:501-509) and does exactly the inverse lookup needed:It's already used by
OnScrollRequested(DiffViewer/Views/DiffPaneView.xaml.cs:479+) for the overview-bar click path.Suggested fix
For deletions (a hunk where
NewLineis null on the inline doc side because it's a pure removal), consider falling back to aMapOldLineToInlinelookup or to the hunk-header line —e.RightLinewill be 0 / the line after the deletion, which still won't be ideal.Test coverage
Add a test that:
JumpToHunk(1)(the second hunk).NewStartLine, not the rawNewStartLine.This is harder to test because it requires WPF layout — but at minimum the helper math (
MapNewLineToInlinefor known fixtures ofInlineLineToSourceLines) can be unit-tested.Citations
DiffViewer/Views/DiffPaneView.xaml.cs:454-464— buggy handlerDiffViewer/Views/DiffPaneView.xaml.cs:479-492—OnScrollRequested, the correct patternDiffViewer/Views/DiffPaneView.xaml.cs:501-509—MapNewLineToInlinehelper that should be usedDiffViewer/Rendering/InlineDiffBuilder.cs— producesInlineLineToSourceLinesSeverity
Medium-High. User-visible incorrectness in inline mode; the more interesting (further-down) hunks land off-screen.