From ebca4fc90117b986f20868f62474a91a5e07151c Mon Sep 17 00:00:00 2001 From: James Vecellio-Grant <159560811+Discountchubbs@users.noreply.github.com> Date: Sat, 29 Nov 2025 01:19:48 -0800 Subject: [PATCH] ui: fuzzy search helper (#1507) * ui: fuzzy search helper * final --------- Co-authored-by: Jason Wen --- .../widgets/helpers/fuzzy_search.py | 40 +++++++++++++++++++ 1 file changed, 40 insertions(+) create mode 100644 system/ui/sunnypilot/widgets/helpers/fuzzy_search.py diff --git a/system/ui/sunnypilot/widgets/helpers/fuzzy_search.py b/system/ui/sunnypilot/widgets/helpers/fuzzy_search.py new file mode 100644 index 000000000..8d0f6bd59 --- /dev/null +++ b/system/ui/sunnypilot/widgets/helpers/fuzzy_search.py @@ -0,0 +1,40 @@ +""" +Copyright (c) 2021-, Haibin Wen, sunnypilot, and a number of other contributors. + +This file is part of sunnypilot and is licensed under the MIT License. +See the LICENSE.md file in the root directory for more details. +""" +import re +import unicodedata + + +def normalize(text: str) -> str: + return unicodedata.normalize('NFKD', text).encode('ascii', 'ignore').decode('utf-8').lower() + + +def search_from_list(query: str, items: list[str]) -> list[str]: + if not query: + return items + + normalized_query = normalize(query) + search_terms = [re.sub(r'[^a-z0-9]', '', term) for term in normalized_query.split() if term.strip()] + + results = [] + for item in items: + normalized_item = normalize(item) + item_with_spaces = re.sub(r'[^a-z0-9\s]', ' ', normalized_item) + item_stripped = re.sub(r'[^a-z0-9]', '', normalized_item) + + all_terms_match = True + for term in search_terms: + if not term: + continue + + if term not in item_with_spaces and term not in item_stripped: + all_terms_match = False + break + + if all_terms_match: + results.append(item) + + return results