module Dustme.Search where
import Control.Monad (guard)
import Data.Char (isSpace)
import Data.HashMap.Strict (HashMap)
import qualified Data.HashMap.Strict as HM
import Data.List (sortBy)
import Data.Maybe (mapMaybe)
import Data.Monoid ((<>))
import Data.Ord (comparing)
import Data.Text (Text)
import qualified Data.Text as T
import Dustme.Score (bestMatches, getIndices, matchComparison)
import Dustme.Types
import Safe (headMay)
isBoundaryChar = isSpace
emptyCache = HM.empty
getResults :: [Text]
-> SearchCache
-> Search
-> (SearchResult, SearchCache)
getResults candidates cache search = case HM.lookup search cache of
Nothing -> let result = runSearch search candidates in
(result, HM.insert search result cache)
Just cached -> (cached, cache)
runSearch :: Search -> [Text] -> SearchResult
runSearch (Search st) candidates =
sortBy matchComparison $
mapMaybe (headMay . bestMatches st) candidates
applyOp :: [Text] -> SearchOp -> Search -> SearchResult -> (Search,[Text])
applyOp candidates op (Search st) matches =
case op of
AddText t -> ( Search (st <> t)
, map matchText matches)
Backspace -> ( Search (T.dropEnd 1 st)
, candidates)
DeleteWord -> ( Search $ T.dropWhileEnd (not . isBoundaryChar) st
, candidates)