38 lines · 1.1 KB
const HUNK_HEADER = /^@@ -\d+(?:,\d+)? \+(\d+)(?:,\d+)? @@/;

/** New-side lines `start..end` of `path` as they appear in a unified patch (used to prefill suggestions). */
export function newSideLines(patch: string, path: string, start: number, end: number): string[] | null {
  const lines = patch.split("\n");
  const found = new Map<number, string>();
  let inFile = false;
  let next = 0;
  for (const line of lines) {
    if (line.startsWith("diff --git ")) {
      inFile = false;
      continue;
    }
    if (line.startsWith("+++ ")) {
      inFile = line === `+++ b/${path}`;
      continue;
    }
    if (!inFile) continue;
    const header = HUNK_HEADER.exec(line);
    if (header) {
      next = Number(header[1]);
      continue;
    }
    if (line.startsWith("-") || line.startsWith("\\")) continue;
    if (line.startsWith("+") || line.startsWith(" ")) {
      if (next >= start && next <= end) found.set(next, line.slice(1));
      next++;
    }
  }
  const out: string[] = [];
  for (let line = start; line <= end; line++) {
    const text = found.get(line);
    if (text === undefined) return null;
    out.push(text);
  }
  return out;
}