76 lines · 2.3 KB
import { Link } from "@tanstack/react-router";
import { EmptyState } from "./ui/Primitives";
import { SNIPPET_CLOSE, SNIPPET_OPEN } from "~/lib/code-intel";
import type { CodeSearchHit } from "~/lib/code-intel";

type Segment = { offset: number; text: string; marked: boolean };

function segments(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 Snippet({ text }: { text: string }) {
  return (
    <pre className="overflow-x-auto px-4 py-2 font-mono text-xs leading-5 whitespace-pre-wrap text-gray-400">
      {segments(text).map((segment) =>
        segment.marked ? (
          <mark key={segment.offset} className="rounded-sm bg-accent-500/25 text-accent-300">
            {segment.text}
          </mark>
        ) : (
          <span key={segment.offset}>{segment.text}</span>
        ),
      )}
    </pre>
  );
}

export function CodeSearchResults({
  hits,
  showRepo,