refactor: extract shared fuzzy filter utilities for list components

This commit is contained in:
CJ Winslow
2026-01-19 16:49:06 -08:00
committed by Peter Steinberger
parent a28c271488
commit f2666d2092
3 changed files with 118 additions and 90 deletions

View File

@@ -10,6 +10,7 @@ import {
truncateToWidth,
} from "@mariozechner/pi-tui";
import { visibleWidth } from "../../terminal/ansi.js";
import { findWordBoundaryIndex } from "./fuzzy-filter.js";
export interface SearchableSelectListTheme extends SelectListTheme {
searchPrompt: (text: string) => string;
@@ -81,7 +82,7 @@ export class SearchableSelectList implements Component {
continue;
}
// Tier 2: Word-boundary prefix in label (score 100-199)
const wordBoundaryIndex = this.findWordBoundaryIndex(label, q);
const wordBoundaryIndex = findWordBoundaryIndex(label, q);
if (wordBoundaryIndex !== null) {
wordBoundary.push({ item, score: wordBoundaryIndex });
continue;
@@ -112,20 +113,6 @@ export class SearchableSelectList implements Component {
];
}
private findWordBoundaryIndex(text: string, query: string): number | null {
if (!query) return null;
const maxIndex = text.length - query.length;
if (maxIndex < 0) return null;
for (let i = 0; i <= maxIndex; i++) {
if (text.startsWith(query, i)) {
if (i === 0 || /[\s\-_./:]/.test(text[i - 1] ?? "")) {
return i;
}
}
}
return null;
}
private escapeRegex(str: string): string {
return str.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
}