Something went wrong. Try again.
Something went wrong. Try again.
1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950import type { Hunk } from './types'
// Pure helpers turning -U0 hunks into per-line change marks for the head view.// Pure additions → "added"; replaced ranges → "modified"; pure deletions → a// marker on the line after which content was removed.
export type LineMark = 'added' | 'modified' | 'deleted'
export function lineMarks(hunks: Hunk[], lineCount: number): Map<number, LineMark> { const marks = new Map<number, LineMark>() for (const h of hunks) { if (h.newLines === 0) { // Deleted after line newStart (0 = top of file). marks.set(Math.min(Math.max(h.newStart, 1), lineCount), 'deleted') continue } const kind: LineMark = h.oldLines === 0 ? 'added' : 'modified' for (let l = h.newStart; l < h.newStart + h.newLines && l <= lineCount; l++) marks.set(l, kind) } return marks}
/** 1-based first line of each hunk, for next/previous-change navigation. */export function hunkAnchors(hunks: Hunk[]): number[] { return hunks.map((h) => Math.max(h.newStart, 1))}
/** Where a base line is in the head view: in a hunk's removed lines, or the head line it became. */export type BaseLinePlace = { removed: Hunk } | { headLine: number }
/** * Places a 1-based base line against -U0 hunks: the hunk whose removed lines * hold it, or, for a line the change kept, its head line number (0: above * line 1). */export function baseLinePlace(hunks: Hunk[], line: number): BaseLinePlace { let delta = 0 for (const h of [...hunks].sort((a, b) => a.oldStart - b.oldStart)) { if (h.oldLines > 0 && h.oldStart <= line && line < h.oldStart + h.oldLines) return { removed: h } // Before the line: removed lines ending above it, or lines added after an earlier base line. const before = h.oldLines > 0 ? h.oldStart + h.oldLines - 1 < line : h.oldStart < line if (before) delta += h.newLines - h.oldLines } return { headLine: Math.max(0, line + delta) }}
/** Whether base lines overlap lines the change removed (or replaced). */export const inRemoved = (hunks: Hunk[], lines: readonly [number, number]): boolean => hunks.some((h) => h.oldLines > 0 && h.oldStart <= lines[1] && h.oldStart + h.oldLines - 1 >= lines[0])