Number the lines of a patch in one pass when indexing its change lines

Several actions on the selected lines of a diff look up those lines in
the diff of their file by their line numbers: staging, unstaging and
discarding them, editing the hunk they are in, and adding them to a
custom patch. Showing which lines of a diff are in the custom patch
does the same lookup the other way round. For this, the change lines of
the file's diff are indexed by their line numbers.

The index asked the patch for the number of each change line separately,
and each of these calls counts the lines of the hunk before the line. So
for a new file of 100,000 lines, building the index took 2 seconds.
Number all lines of the patch in one pass instead. Building the index
for that file now takes 4 milliseconds.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
This commit is contained in:
Stefan Haller
2026-10-14 08:41:50 +02:00
co-authored by Claude Opus 5.5
parent 80dff3c2b9
commit 185f147db2
+3 -2
View File
@@ -416,12 +416,13 @@ type LineIdentity struct {
// old file keeps them apart.
func ChangeLineIndexByIdentity(parsed *Patch) map[LineIdentity]int {
byIdentity := map[LineIdentity]int{}
newLineNumbers, oldLineNumbers := parsed.LineNumbersOfLines()
for idx, line := range parsed.Lines() {
switch {
case line.IsAddition():
byIdentity[LineIdentity{parsed.LineNumberOfLine(idx), false}] = idx
byIdentity[LineIdentity{newLineNumbers[idx], false}] = idx
case line.IsDeletion():
byIdentity[LineIdentity{parsed.OldLineNumberOfLine(idx), true}] = idx
byIdentity[LineIdentity{oldLineNumbers[idx], true}] = idx
}
}
return byIdentity