import { Link } from "@tanstack/react-router"; import { SNIPPET_CLOSE, SNIPPET_OPEN } from "~/lib/code-intel"; import type { CodeSearchHit, CodeSearchLine } from "~/lib/code-intel"; import { EmptyState } from "~/ui/EmptyState"; import { TextLink } from "~/ui/TextLink"; type Segment = { offset: number; text: string; marked: boolean }; function snippetSegments(text: string): Segment[] { const out: Segment[] = []; let offset = 0; for (const [position, part] of text.split(SNIPPET_OPEN).entries()) { const [marked, rest] = position === 0 ? ["", part] : [part.split(SNIPPET_CLOSE)[0] ?? "", part.split(SNIPPET_CLOSE)[1] ?? ""]; if (marked) out.push({ offset, text: marked, marked: true }); offset += marked.length + 1; if (rest) out.push({ offset, text: rest, marked: false }); offset += rest.length + 1; } return out; } function lineSegments(line: CodeSearchLine): Segment[] { const out: Segment[] = []; let cursor = 0; for (const { start, end } of line.ranges) { if (start > cursor) out.push({ offset: cursor, text: line.text.slice(cursor, start), marked: false }); out.push({ offset: start, text: line.text.slice(start, end), marked: true }); cursor = end; } if (cursor < line.text.length) out.push({ offset: cursor, text: line.text.slice(cursor), marked: false }); return out; } function Highlighted({ segments }: { segments: Segment[] }) { return segments.map((segment) => segment.marked ? ( {segment.text} ) : ( {segment.text} ), ); } function blobParams(hit: CodeSearchHit) { return { owner: hit.owner, repo: hit.repo, _splat: `${hit.ref}/${hit.path}` }; } /** Path with the directory dimmed, so the file name is what the eye lands on. */ function FilePath({ path }: { path: string }) { const slash = path.lastIndexOf("/"); return ( <> {slash >= 0 && {path.slice(0, slash + 1)}} {path.slice(slash + 1)} > ); } function MatchLines({ hit }: { hit: CodeSearchHit }) { if (hit.lines.length === 0) { return (
);
}
return (
{line.clippedStart && …}
{line.clippedEnd && …}