module Dustme where
import Control.Concurrent (newEmptyMVar, takeMVar)
import Control.Concurrent.Async (async, cancel, race)
import Control.DeepSeq (force)
import Control.Exception (bracket, evaluate)
import qualified Data.Text as T
import qualified Data.Text.IO as TIO
import Dustme.Renderer
import Dustme.Search
import Dustme.TTY (withTTY)
import Dustme.Types
import System.IO
dustme config = do
hSetBuffering stdout NoBuffering
input <- T.lines <$> TIO.getContents
let applyOp' = applyOp input
withTTY "/dev/tty0" (setup applyOp' (map mkTrivialMatch input))
mkTrivialMatch = Match 10000 1 0
setup applyOp' initMatch tty = go 0 initMatch (Search "") emptyCache
where
getCommand = takeMVar (ttyGetCommand tty)
go :: Int -> SearchResult -> Search -> SearchCache -> IO ()
go index matches' search cache = do
let matches = case search of
(Search "") -> initMatch
_ -> matches'
r <- race (evaluate $ force matches) getCommand
s <- case r of
Left matches' -> renderSearch tty index matches search >> getCommand
Right x -> return x
case s of
Accept -> TIO.putStrLn (matchText $ matches !! index)
Up -> go (clamp (length matches) (index1)) matches search cache
Down -> go (clamp (length matches) (index+1)) matches search cache
Edit op ->
let (newsearch,newcandidates) = applyOp' op search matches
(searchResult, newcache) =
getResults newcandidates cache newsearch
in go 0 searchResult newsearch newcache
clamp hi i
| i < 0 = 0
| i >= hi = hi 1
| otherwise = i