nearestLine

tcmts.cli.main.nearestLine · #usryrqst · term · runs anywhere

Where in text the first line of old most likely is, said for a patch that didn't find it (or nothing, if no line is much like it): its line number (counting from from + 1) and text.

export function nearestLine(text: string, old: string, from = 0): string {
  const first =
    old
      .split("\n")
      .find((l) => l.trim())
      ?.trim() ?? "";
  const words = (s: string) => new Set(s.match(/[\w$]+|[^\s\w$]/g) ?? []);
  const want = words(first);
  if (!want.size) return "";
  // (how much of the line looked for a line has; of two that have as much, the shorter)
  let best = { score: 0, at: -1, line: "" };
  text.split("\n").forEach((line, i) => {
    const have = words(line);
    let common = 0;
    for (const w of want) if (have.has(w)) common++;
    const score = common / want.size;
    if (
      score > best.score ||
      (score === best.score && score > 0 && line.trim().length < best.line.length)
    )
      best = { score, at: i, line: line.trim() };
  });
  return best.score >= 0.6
    ? `; the nearest line is ${from + best.at + 1}: ${JSON.stringify(best.line.length > 100 ? `${best.line.slice(0, 99)}…` : best.line)}`
    : "";
}

used by