export interface LineMatch {
line: number;
start: number;
end: number;
}
export const MATCH_LIMIT = 10_000;
const escapeRegExp = (text: string): string => text.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
export const findMatches = (
lines: readonly string[],
query: string,
limit = MATCH_LIMIT
): LineMatch[] => {
const matches: LineMatch[] = [];
if (query === "") return matches;
const pattern = new RegExp(escapeRegExp(query), "giu");
for (let line = 0; line < lines.length; line++) {
for (const found of lines[line].matchAll(pattern)) {
matches.push({
line: line + 1,
start: found.index,
end: found.index + found[0].length
});
if (matches.length >= limit) return matches;
}
}
return matches;
};
export const wrapIndex = (index: number, length: number): number =>
length === 0 ? -1 : ((index % length) + length) % length;