diff --git a/shellhist/core/search.py b/shellhist/core/search.py index 1b1b43d..7093ada 100644 --- a/shellhist/core/search.py +++ b/shellhist/core/search.py @@ -1,96 +1 @@ -"""Search functionality for shell history.""" - -from datetime import datetime -from typing import Optional - -from fuzzywuzzy import fuzz, process - -from shellhist.core import HistoryEntry, HistoryStore - - -def fuzzy_search( - store: HistoryStore, - query: str, - threshold: int = 70, - limit: int = 20, - reverse: bool = False, - recent: bool = False, -) -> list[tuple[HistoryEntry, int]]: - """Search history with fuzzy matching. - - Args: - store: HistoryStore to search. - query: Search query string. - threshold: Minimum similarity score (0-100). - limit: Maximum number of results to return. - reverse: If True, sort by recency (newest first). - recent: If True, boost scores for recent commands. - - Returns: - List of (HistoryEntry, score) tuples sorted by score. - """ - commands = store.get_unique_commands() - - if not commands: - return [] - - results = [] - now = datetime.now() - - for command in commands: - score = fuzz.token_sort_ratio(query.lower(), command.lower()) - - if score >= threshold: - entry = _get_first_entry(store, command) - if entry: - if recent and entry.timestamp: - hours_old = (now - entry.timestamp).total_seconds() / 3600 - if hours_old < 24: - score = min(100, score + 10) - - results.append((entry, score)) - - results.sort(key=lambda x: x[1], reverse=not reverse) - - return results[:limit] - - -def _get_first_entry(store: HistoryStore, command: str) -> Optional[HistoryEntry]: - """Get the first entry for a command from the store.""" - for entry in store.entries: - if entry.command == command: - return entry - return None - - -def rank_by_frequency( - store: HistoryStore, - results: list[tuple[HistoryEntry, int]], - boost_recent: bool = False, -) -> list[tuple[HistoryEntry, int, int]]: - """Rank search results by frequency. - - Args: - store: HistoryStore for frequency lookups. - results: List of (HistoryEntry, score) tuples. - boost_recent: If True, boost scores for recent commands. - - Returns: - List of (HistoryEntry, score, frequency) tuples. - """ - ranked = [] - now = datetime.now() - - for entry, score in results: - freq = store.get_frequency(entry.command) - - if boost_recent and entry.timestamp: - hours_old = (now - entry.timestamp).total_seconds() / 3600 - if hours_old < 24: - freq = freq * 2 - - ranked.append((entry, score, freq)) - - ranked.sort(key=lambda x: (x[1], x[2]), reverse=True) - - return ranked +bmFtZTogQ0kKCm9uOgogIHB1c2g6CiAgICBicmFuY2hlczogW21haW5dCiAgcHVsbF9yZXF1ZXN0OgogICAgYnJhbmNoZXM6IFttYWluXQoKam9iczogCiAgdGVzdDoKICAgIHJ1bnMtb246IHVidW50dS1sYXRlc3QKICAgIHN0ZXBzOgogICAgICAtIHVzZXM6IGFjdGlvbnMvY2hlY2tvdXQdjNFgKICAgICAgdXNlczogYWN0aW9ucy9zZXR1cC1weXRob25fdjUKICAgICAgd2l0aDoKICAgICAgICBweXRob24tdmVyc2lvbjogJzMuMTEnCiAgICAtIHJ1bjogcGlwIGluc3RhbGwgLWUgIltcImRldlwiXSIKICAgIC0gcnVuOiBweXRlc3QgdGVzdHMvIC12CiAgICAtIHJ1bjogcnVmZiBjaGVjayAu \ No newline at end of file