Merge pull request #506 from danmackinlay/fix-505-json-line-output

feat: Include line in --json search output

# Conflicts:
#	CHANGELOG.md
This commit is contained in:
Tobias Lütke 2026-04-05 17:16:05 -04:00
commit 76a2f0fb31
3 changed files with 21 additions and 1 deletions

View File

@ -25,6 +25,8 @@
(thanks @Mic92)
- Sync duplicated `handelize()` test expectations with the restored lowercase
behavior.
- Include `line` in `--json` search output so editor integrations can jump
directly to `file:line`. Closes #505 (thanks @danmackinlay)
## [2.0.1] - 2026-03-10

View File

@ -101,8 +101,11 @@ export function searchResultsToJson(
const query = opts.query || "";
const output = results.map(row => {
const bodyStr = row.body || "";
const snippetInfo = bodyStr
? extractSnippet(bodyStr, query, 300, row.chunkPos, undefined, opts.intent)
: undefined;
let body = opts.full ? bodyStr : undefined;
let snippet = !opts.full ? extractSnippet(bodyStr, query, 300, row.chunkPos, undefined, opts.intent).snippet : undefined;
let snippet = !opts.full ? snippetInfo?.snippet : undefined;
if (opts.lineNumbers) {
if (body) body = addLineNumbers(body);
@ -113,6 +116,7 @@ export function searchResultsToJson(
docid: `#${row.docid}`,
score: Math.round(row.score * 100) / 100,
file: row.displayPath,
...(snippetInfo && { line: snippetInfo.line }),
title: row.title,
...(row.context && { context: row.context }),
...(body && { body }),

View File

@ -95,6 +95,20 @@ describe("search results include context in all formats", () => {
expect(parsed[0].context).toBe(TEST_CONTEXT);
});
test("JSON format includes line", () => {
const output = searchResultsToJson(results, { query: "keynote" });
const parsed = JSON.parse(output);
expect(parsed[0].line).toBeTypeOf("number");
expect(parsed[0].line).toBeGreaterThan(0);
});
test("JSON format includes line with --full", () => {
const output = searchResultsToJson(results, { query: "keynote", full: true });
const parsed = JSON.parse(output);
expect(parsed[0].line).toBeTypeOf("number");
expect(parsed[0].line).toBeGreaterThan(0);
});
test("CSV format includes context", () => {
const output = searchResultsToCsv(results, { query: "keynote" });
// Header should have context column