( files: Map<string, string>, pattern: string, path?: string, opts?: GrepOptions )
| 131 | * but not in line modes. |
| 132 | */ |
| 133 | export function grep( |
| 134 | files: Map<string, string>, |
| 135 | pattern: string, |
| 136 | path?: string, |
| 137 | opts?: GrepOptions |
| 138 | ): GrepMatch[] | string[] | GrepCountEntry[] { |
| 139 | const maxResults = opts?.maxResults ?? 100 |
| 140 | const outputMode = opts?.outputMode ?? 'content' |
| 141 | const ignoreCase = opts?.ignoreCase ?? false |
| 142 | const showLineNumbers = opts?.lineNumbers ?? true |
| 143 | const contextLines = opts?.context ?? 0 |
| 144 | |
| 145 | const flags = ignoreCase ? 'gi' : 'g' |
| 146 | let regex: RegExp |
| 147 | try { |
| 148 | regex = new RegExp(pattern, flags) |
| 149 | } catch { |
| 150 | return [] |
| 151 | } |
| 152 | |
| 153 | if (outputMode === 'files_with_matches') { |
| 154 | const matchingFiles: string[] = [] |
| 155 | for (const [filePath, content] of files) { |
| 156 | if (path && !pathWithinGrepScope(filePath, path)) continue |
| 157 | regex.lastIndex = 0 |
| 158 | if (regex.test(content)) { |
| 159 | matchingFiles.push(filePath) |
| 160 | if (matchingFiles.length >= maxResults) break |
| 161 | } |
| 162 | } |
| 163 | return matchingFiles |
| 164 | } |
| 165 | |
| 166 | if (outputMode === 'count') { |
| 167 | const counts: GrepCountEntry[] = [] |
| 168 | for (const [filePath, content] of files) { |
| 169 | if (path && !pathWithinGrepScope(filePath, path)) continue |
| 170 | const lines = splitLinesForGrep(content) |
| 171 | let count = 0 |
| 172 | for (const line of lines) { |
| 173 | regex.lastIndex = 0 |
| 174 | if (regex.test(line)) count++ |
| 175 | } |
| 176 | if (count > 0) { |
| 177 | counts.push({ path: filePath, count }) |
| 178 | if (counts.length >= maxResults) break |
| 179 | } |
| 180 | } |
| 181 | return counts |
| 182 | } |
| 183 | |
| 184 | // Default: 'content' mode |
| 185 | const matches: GrepMatch[] = [] |
| 186 | for (const [filePath, content] of files) { |
| 187 | if (path && !pathWithinGrepScope(filePath, path)) continue |
| 188 | |
| 189 | const lines = splitLinesForGrep(content) |
| 190 | for (let i = 0; i < lines.length; i++) { |
no test coverage detected