Truncate results from search_files to 500 chars max

This commit is contained in:
Matt Rubens 2025-02-26 17:34:39 -05:00
parent 28cdf0e838
commit dfa019e7f4
3 changed files with 82 additions and 4 deletions

View file

@ -0,0 +1,5 @@
---
"roo-cline": patch
---
Truncate search_file output to avoid crashing the extension

View file

@ -0,0 +1,51 @@
// npx jest src/services/ripgrep/__tests__/index.test.ts
import { describe, expect, it } from "@jest/globals"
import { truncateLine } from "../index"
describe("Ripgrep line truncation", () => {
// The default MAX_LINE_LENGTH is 500 in the implementation
const MAX_LINE_LENGTH = 500
it("should truncate lines longer than MAX_LINE_LENGTH", () => {
const longLine = "a".repeat(600) // Line longer than MAX_LINE_LENGTH
const truncated = truncateLine(longLine)
expect(truncated).toContain("[truncated...]")
expect(truncated.length).toBeLessThan(longLine.length)
expect(truncated.length).toEqual(MAX_LINE_LENGTH + " [truncated...]".length)
})
it("should not truncate lines shorter than MAX_LINE_LENGTH", () => {
const shortLine = "Short line of text"
const truncated = truncateLine(shortLine)
expect(truncated).toEqual(shortLine)
expect(truncated).not.toContain("[truncated...]")
})
it("should correctly truncate a line at exactly MAX_LINE_LENGTH characters", () => {
const exactLine = "a".repeat(MAX_LINE_LENGTH)
const exactPlusOne = exactLine + "x"
// Should not truncate when exactly MAX_LINE_LENGTH
expect(truncateLine(exactLine)).toEqual(exactLine)
// Should truncate when exceeding MAX_LINE_LENGTH by even 1 character
expect(truncateLine(exactPlusOne)).toContain("[truncated...]")
})
it("should handle empty lines without errors", () => {
expect(truncateLine("")).toEqual("")
})
it("should allow custom maximum length", () => {
const customLength = 100
const line = "a".repeat(customLength + 50)
const truncated = truncateLine(line, customLength)
expect(truncated.length).toEqual(customLength + " [truncated...]".length)
expect(truncated).toContain("[truncated...]")
})
})

View file

@ -58,7 +58,19 @@ interface SearchResult {
afterContext: string[]
}
// Constants
const MAX_RESULTS = 300
const MAX_LINE_LENGTH = 500
/**
* Truncates a line if it exceeds the maximum length
* @param line The line to truncate
* @param maxLength The maximum allowed length (defaults to MAX_LINE_LENGTH)
* @returns The truncated line, or the original line if it's shorter than maxLength
*/
export function truncateLine(line: string, maxLength: number = MAX_LINE_LENGTH): string {
return line.length > maxLength ? line.substring(0, maxLength) + " [truncated...]" : line
}
async function getBinPath(vscodeAppRoot: string): Promise<string | undefined> {
const checkPath = async (pkgFolder: string) => {
@ -140,7 +152,8 @@ export async function regexSearchFiles(
let output: string
try {
output = await execRipgrep(rgPath, args)
} catch {
} catch (error) {
console.error("Error executing ripgrep:", error)
return "No results found"
}
const results: SearchResult[] = []
@ -154,19 +167,28 @@ export async function regexSearchFiles(
if (currentResult) {
results.push(currentResult as SearchResult)
}
// Safety check: truncate extremely long lines to prevent excessive output
const matchText = parsed.data.lines.text
const truncatedMatch = truncateLine(matchText)
currentResult = {
file: parsed.data.path.text,
line: parsed.data.line_number,
column: parsed.data.submatches[0].start,
match: parsed.data.lines.text,
match: truncatedMatch,
beforeContext: [],
afterContext: [],
}
} else if (parsed.type === "context" && currentResult) {
// Apply the same truncation logic to context lines
const contextText = parsed.data.lines.text
const truncatedContext = truncateLine(contextText)
if (parsed.data.line_number < currentResult.line!) {
currentResult.beforeContext!.push(parsed.data.lines.text)
currentResult.beforeContext!.push(truncatedContext)
} else {
currentResult.afterContext!.push(parsed.data.lines.text)
currentResult.afterContext!.push(truncatedContext)
}
}
} catch (error) {