| 358 | } |
| 359 | |
| 360 | export async function search(input: { cwd: string; pattern: string; glob?: string[]; limit?: number }) { |
| 361 | const args = [`${await filepath()}`, "--json", "--hidden", "--glob='!.git/*'"] |
| 362 | |
| 363 | if (input.glob) { |
| 364 | for (const g of input.glob) { |
| 365 | args.push(`--glob=${g}`) |
| 366 | } |
| 367 | } |
| 368 | |
| 369 | if (input.limit) { |
| 370 | args.push(`--max-count=${input.limit}`) |
| 371 | } |
| 372 | |
| 373 | args.push("--") |
| 374 | args.push(input.pattern) |
| 375 | |
| 376 | const command = args.join(" ") |
| 377 | const result = await $`${{ raw: command }}`.cwd(input.cwd).quiet().nothrow() |
| 378 | if (result.exitCode !== 0) { |
| 379 | return [] |
| 380 | } |
| 381 | |
| 382 | const lines = result.text().trim().split("\n").filter(Boolean) |
| 383 | // Parse JSON lines from ripgrep output |
| 384 | |
| 385 | return lines |
| 386 | .map((line) => JSON.parse(line)) |
| 387 | .map((parsed) => Result.parse(parsed)) |
| 388 | .filter((r) => r.type === "match") |
| 389 | .map((r) => r.data) |
| 390 | } |
| 391 | } |