Skip to content

Commit 75ecca9

Browse files
authored
Merge pull request RooCodeInc#1224 from RooVetGit/fix_search_files
Truncate results from search_files to 500 chars max
2 parents 4fac3da + dfa019e commit 75ecca9

File tree

3 files changed

+82
-4
lines changed

3 files changed

+82
-4
lines changed

.changeset/stale-cooks-help.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
"roo-cline": patch
3+
---
4+
5+
Truncate search_file output to avoid crashing the extension
Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
// npx jest src/services/ripgrep/__tests__/index.test.ts
2+
3+
import { describe, expect, it } from "@jest/globals"
4+
import { truncateLine } from "../index"
5+
6+
describe("Ripgrep line truncation", () => {
7+
// The default MAX_LINE_LENGTH is 500 in the implementation
8+
const MAX_LINE_LENGTH = 500
9+
10+
it("should truncate lines longer than MAX_LINE_LENGTH", () => {
11+
const longLine = "a".repeat(600) // Line longer than MAX_LINE_LENGTH
12+
const truncated = truncateLine(longLine)
13+
14+
expect(truncated).toContain("[truncated...]")
15+
expect(truncated.length).toBeLessThan(longLine.length)
16+
expect(truncated.length).toEqual(MAX_LINE_LENGTH + " [truncated...]".length)
17+
})
18+
19+
it("should not truncate lines shorter than MAX_LINE_LENGTH", () => {
20+
const shortLine = "Short line of text"
21+
const truncated = truncateLine(shortLine)
22+
23+
expect(truncated).toEqual(shortLine)
24+
expect(truncated).not.toContain("[truncated...]")
25+
})
26+
27+
it("should correctly truncate a line at exactly MAX_LINE_LENGTH characters", () => {
28+
const exactLine = "a".repeat(MAX_LINE_LENGTH)
29+
const exactPlusOne = exactLine + "x"
30+
31+
// Should not truncate when exactly MAX_LINE_LENGTH
32+
expect(truncateLine(exactLine)).toEqual(exactLine)
33+
34+
// Should truncate when exceeding MAX_LINE_LENGTH by even 1 character
35+
expect(truncateLine(exactPlusOne)).toContain("[truncated...]")
36+
})
37+
38+
it("should handle empty lines without errors", () => {
39+
expect(truncateLine("")).toEqual("")
40+
})
41+
42+
it("should allow custom maximum length", () => {
43+
const customLength = 100
44+
const line = "a".repeat(customLength + 50)
45+
46+
const truncated = truncateLine(line, customLength)
47+
48+
expect(truncated.length).toEqual(customLength + " [truncated...]".length)
49+
expect(truncated).toContain("[truncated...]")
50+
})
51+
})

src/services/ripgrep/index.ts

Lines changed: 26 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,19 @@ interface SearchResult {
5858
afterContext: string[]
5959
}
6060

61+
// Constants
6162
const MAX_RESULTS = 300
63+
const MAX_LINE_LENGTH = 500
64+
65+
/**
66+
* Truncates a line if it exceeds the maximum length
67+
* @param line The line to truncate
68+
* @param maxLength The maximum allowed length (defaults to MAX_LINE_LENGTH)
69+
* @returns The truncated line, or the original line if it's shorter than maxLength
70+
*/
71+
export function truncateLine(line: string, maxLength: number = MAX_LINE_LENGTH): string {
72+
return line.length > maxLength ? line.substring(0, maxLength) + " [truncated...]" : line
73+
}
6274

6375
async function getBinPath(vscodeAppRoot: string): Promise<string | undefined> {
6476
const checkPath = async (pkgFolder: string) => {
@@ -140,7 +152,8 @@ export async function regexSearchFiles(
140152
let output: string
141153
try {
142154
output = await execRipgrep(rgPath, args)
143-
} catch {
155+
} catch (error) {
156+
console.error("Error executing ripgrep:", error)
144157
return "No results found"
145158
}
146159
const results: SearchResult[] = []
@@ -154,19 +167,28 @@ export async function regexSearchFiles(
154167
if (currentResult) {
155168
results.push(currentResult as SearchResult)
156169
}
170+
171+
// Safety check: truncate extremely long lines to prevent excessive output
172+
const matchText = parsed.data.lines.text
173+
const truncatedMatch = truncateLine(matchText)
174+
157175
currentResult = {
158176
file: parsed.data.path.text,
159177
line: parsed.data.line_number,
160178
column: parsed.data.submatches[0].start,
161-
match: parsed.data.lines.text,
179+
match: truncatedMatch,
162180
beforeContext: [],
163181
afterContext: [],
164182
}
165183
} else if (parsed.type === "context" && currentResult) {
184+
// Apply the same truncation logic to context lines
185+
const contextText = parsed.data.lines.text
186+
const truncatedContext = truncateLine(contextText)
187+
166188
if (parsed.data.line_number < currentResult.line!) {
167-
currentResult.beforeContext!.push(parsed.data.lines.text)
189+
currentResult.beforeContext!.push(truncatedContext)
168190
} else {
169-
currentResult.afterContext!.push(parsed.data.lines.text)
191+
currentResult.afterContext!.push(truncatedContext)
170192
}
171193
}
172194
} catch (error) {

0 commit comments

Comments
 (0)