"""Recherche floue minimale (sans dependance externe) : `query` doit apparaitre comme sous-sequence de `text` (caracteres dans l'ordre, pas necessairement contigus), avec un score favorisant les correspondances contigues et les debuts de mot - le meme principe que fzf/Sublime Text en plus simple.""" from __future__ import annotations _WORD_BOUNDARY = " -_./@:\\" def fuzzy_score(query: str, text: str) -> int | None: """None si `query` n'est pas une sous-sequence de `text`. Sinon un score ou plus haut = meilleure correspondance.""" if not query: return 0 q = query.lower() t = text.lower() score = 0 pos = 0 streak = 0 for ch in q: idx = t.find(ch, pos) if idx == -1: return None if idx == pos: streak += 1 score += 3 + streak # caracteres consecutifs : bonus croissant else: streak = 0 score += 1 if idx == 0 or t[idx - 1] in _WORD_BOUNDARY: score += 5 # debut de mot/segment pos = idx + 1 # penalise legerement les correspondances trop etalees dans un texte long score += max(0, 20 - (pos - len(q))) return score