Skip to content

Commit c7207a2

Browse files
author
Roo
committed
fix: make @ file search respect VSCode search.useIgnoreFiles setting
- Modified executeRipgrepForFiles to accept respectIgnoreFiles parameter - Added --no-ignore-vcs flag when VSCode search.useIgnoreFiles is disabled - Updated searchWorkspaceFiles to read VSCode configuration - Added comprehensive tests to verify functionality - Fixes issue where @ file search could not find files in ignored directories when VSCode setting was disabled Fixes #5721
1 parent 8a3dcfb commit c7207a2

File tree

2 files changed

+148
-2
lines changed

2 files changed

+148
-2
lines changed
Lines changed: 136 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,136 @@
1+
import { describe, it, expect, vi, beforeEach } from "vitest"
2+
3+
// Mock getBinPath first - this needs to be hoisted
4+
vi.mock("../../ripgrep", () => ({
5+
getBinPath: vi.fn().mockResolvedValue("/usr/bin/rg"),
6+
}))
7+
8+
// Mock vscode
9+
vi.mock("vscode", () => ({
10+
workspace: {
11+
getConfiguration: vi.fn(),
12+
},
13+
env: {
14+
appRoot: "/mock/vscode/app",
15+
},
16+
}))
17+
18+
// Mock child_process
19+
vi.mock("child_process", () => ({
20+
spawn: vi.fn(),
21+
}))
22+
23+
// Mock readline
24+
vi.mock("readline", () => ({
25+
createInterface: vi.fn(),
26+
}))
27+
28+
// Import after mocks are set up
29+
import * as vscode from "vscode"
30+
import * as childProcess from "child_process"
31+
import * as readline from "readline"
32+
import { executeRipgrepForFiles, searchWorkspaceFiles } from "../file-search"
33+
34+
describe("file-search", () => {
35+
const mockSpawn = vi.mocked(childProcess.spawn)
36+
const mockGetConfiguration = vi.mocked(vscode.workspace.getConfiguration)
37+
const mockCreateInterface = vi.mocked(readline.createInterface)
38+
39+
beforeEach(() => {
40+
vi.clearAllMocks()
41+
42+
// Setup default mocks for each test
43+
const mockProcess = {
44+
stdout: {},
45+
stderr: {
46+
on: vi.fn(),
47+
},
48+
on: vi.fn(),
49+
kill: vi.fn(),
50+
}
51+
52+
const mockReadlineInterface = {
53+
on: vi.fn((event, callback) => {
54+
if (event === "line") {
55+
// Simulate some file output
56+
setTimeout(() => {
57+
callback("/test/workspace/src/file1.ts")
58+
callback("/test/workspace/src/file2.ts")
59+
}, 10)
60+
} else if (event === "close") {
61+
setTimeout(() => callback(), 20)
62+
}
63+
}),
64+
close: vi.fn(),
65+
}
66+
67+
mockSpawn.mockReturnValue(mockProcess as any)
68+
mockCreateInterface.mockReturnValue(mockReadlineInterface as any)
69+
})
70+
71+
describe("executeRipgrepForFiles", () => {
72+
it("should include --no-ignore-vcs flag when respectIgnoreFiles is false", async () => {
73+
const workspacePath = "/test/workspace"
74+
75+
// Test with respectIgnoreFiles = false
76+
await executeRipgrepForFiles(workspacePath, 5000, false)
77+
78+
// Verify that --no-ignore-vcs was included in the args
79+
expect(mockSpawn).toHaveBeenCalledWith("/usr/bin/rg", expect.arrayContaining(["--no-ignore-vcs"]))
80+
})
81+
82+
it("should not include --no-ignore-vcs flag when respectIgnoreFiles is true", async () => {
83+
const workspacePath = "/test/workspace"
84+
85+
// Test with respectIgnoreFiles = true (default)
86+
await executeRipgrepForFiles(workspacePath, 5000, true)
87+
88+
// Verify that --no-ignore-vcs was NOT included in the args
89+
expect(mockSpawn).toHaveBeenCalledWith("/usr/bin/rg", expect.not.arrayContaining(["--no-ignore-vcs"]))
90+
})
91+
})
92+
93+
describe("searchWorkspaceFiles", () => {
94+
it("should respect VSCode search.useIgnoreFiles setting when true", async () => {
95+
// Mock VSCode configuration to return useIgnoreFiles = true
96+
mockGetConfiguration.mockReturnValue({
97+
get: vi.fn().mockReturnValue(true),
98+
} as any)
99+
100+
await searchWorkspaceFiles("test", "/test/workspace", 20)
101+
102+
// Verify VSCode configuration was checked
103+
expect(mockGetConfiguration).toHaveBeenCalledWith("search")
104+
105+
// Verify that --no-ignore-vcs was NOT included (respecting .gitignore)
106+
expect(mockSpawn).toHaveBeenCalledWith("/usr/bin/rg", expect.not.arrayContaining(["--no-ignore-vcs"]))
107+
})
108+
109+
it("should respect VSCode search.useIgnoreFiles setting when false", async () => {
110+
// Mock VSCode configuration to return useIgnoreFiles = false
111+
mockGetConfiguration.mockReturnValue({
112+
get: vi.fn().mockReturnValue(false),
113+
} as any)
114+
115+
await searchWorkspaceFiles("test", "/test/workspace", 20)
116+
117+
// Verify VSCode configuration was checked
118+
expect(mockGetConfiguration).toHaveBeenCalledWith("search")
119+
120+
// Verify that --no-ignore-vcs was included (ignoring .gitignore)
121+
expect(mockSpawn).toHaveBeenCalledWith("/usr/bin/rg", expect.arrayContaining(["--no-ignore-vcs"]))
122+
})
123+
124+
it("should default to respecting ignore files when VSCode setting is not available", async () => {
125+
// Mock VSCode configuration to return undefined (use default)
126+
mockGetConfiguration.mockReturnValue({
127+
get: vi.fn().mockReturnValue(undefined),
128+
} as any)
129+
130+
await searchWorkspaceFiles("test", "/test/workspace", 20)
131+
132+
// Verify that the default behavior (respecting .gitignore) is used
133+
expect(mockSpawn).toHaveBeenCalledWith("/usr/bin/rg", expect.not.arrayContaining(["--no-ignore-vcs"]))
134+
})
135+
})
136+
})

src/services/search/file-search.ts

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,7 @@ export async function executeRipgrep({
8888
export async function executeRipgrepForFiles(
8989
workspacePath: string,
9090
limit: number = 5000,
91+
respectIgnoreFiles: boolean = true,
9192
): Promise<{ path: string; type: "file" | "folder"; label?: string }[]> {
9293
const args = [
9394
"--files",
@@ -101,9 +102,15 @@ export async function executeRipgrepForFiles(
101102
"!**/out/**",
102103
"-g",
103104
"!**/dist/**",
104-
workspacePath,
105105
]
106106

107+
// If VSCode's search.useIgnoreFiles is disabled, add --no-ignore-vcs to ignore .gitignore files
108+
if (!respectIgnoreFiles) {
109+
args.push("--no-ignore-vcs")
110+
}
111+
112+
args.push(workspacePath)
113+
107114
return executeRipgrep({ args, workspacePath, limit })
108115
}
109116

@@ -113,8 +120,11 @@ export async function searchWorkspaceFiles(
113120
limit: number = 20,
114121
): Promise<{ path: string; type: "file" | "folder"; label?: string }[]> {
115122
try {
123+
// Check VSCode's search.useIgnoreFiles setting
124+
const useIgnoreFiles = vscode.workspace.getConfiguration("search").get<boolean>("useIgnoreFiles", true)
125+
116126
// Get all files and directories (from our modified function)
117-
const allItems = await executeRipgrepForFiles(workspacePath, 5000)
127+
const allItems = await executeRipgrepForFiles(workspacePath, 5000, useIgnoreFiles)
118128

119129
// If no query, just return the top items
120130
if (!query.trim()) {

0 commit comments

Comments
 (0)