(
content: string,
query: string,
options: StateSearchOptions = {}
)
| 143 | } |
| 144 | |
| 145 | export function searchTextContent( |
| 146 | content: string, |
| 147 | query: string, |
| 148 | options: StateSearchOptions = {} |
| 149 | ): StateTextMatch[] { |
| 150 | const matcher = createTextMatcher(query, options); |
| 151 | const matches: StateTextMatch[] = []; |
| 152 | const lines = content.split("\n"); |
| 153 | |
| 154 | for (let lineIndex = 0; lineIndex < lines.length; lineIndex++) { |
| 155 | const lineText = lines[lineIndex]; |
| 156 | matcher.lastIndex = 0; |
| 157 | |
| 158 | for (;;) { |
| 159 | const match = matcher.exec(lineText); |
| 160 | if (!match) { |
| 161 | break; |
| 162 | } |
| 163 | |
| 164 | matches.push({ |
| 165 | line: lineIndex + 1, |
| 166 | column: match.index + 1, |
| 167 | match: match[0], |
| 168 | lineText, |
| 169 | ...(options.contextBefore |
| 170 | ? { |
| 171 | beforeLines: lines.slice( |
| 172 | Math.max(0, lineIndex - options.contextBefore), |
| 173 | lineIndex |
| 174 | ) |
| 175 | } |
| 176 | : {}), |
| 177 | ...(options.contextAfter |
| 178 | ? { |
| 179 | afterLines: lines.slice( |
| 180 | lineIndex + 1, |
| 181 | lineIndex + 1 + options.contextAfter |
| 182 | ) |
| 183 | } |
| 184 | : {}) |
| 185 | }); |
| 186 | |
| 187 | if ( |
| 188 | options.maxMatches !== undefined && |
| 189 | matches.length >= options.maxMatches |
| 190 | ) { |
| 191 | return matches; |
| 192 | } |
| 193 | |
| 194 | if (match[0].length === 0) { |
| 195 | matcher.lastIndex++; |
| 196 | } |
| 197 | } |
| 198 | } |
| 199 | |
| 200 | return matches; |
| 201 | } |
| 202 |
no test coverage detected