-
Notifications
You must be signed in to change notification settings - Fork 3
/
TodoCmd.hs
54 lines (49 loc) · 1.92 KB
/
TodoCmd.hs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
-- | "Todo"
--
-- A command line client for the todo app in Todo.hs. At every step, has
-- a primitive instruction parser that parses instructions/commands, sends
-- them into the 'Auto', and outputs the resulting Map of tasks in
-- a pretty-ish way.
--
-- In a GUI, you would have a thread waiting for inputs on a `Chan` queue
-- (using `runOnChan`, for example), and have your GUI elements dump
-- commands into the queue, and render outputs as they come out.
module Main (main) where
import Control.Auto
import Control.Monad
import Data.IntMap (IntMap)
import Data.Maybe
import Prelude hiding ((.), id)
import Text.Read
import Todo
import qualified Data.IntMap as IM
-- | Parse a string input.
parseInp :: String -> Maybe TodoInp
parseInp = p . words
where
p ("A":xs) = Just (IAdd (unwords xs))
p ("D":n:_) = onId n TEDelete
p ("C":n:_) = onId n (TEComplete True)
p ("U":n:_) = onId n (TEComplete False)
p ("P":n:_) = onId n TEPrune
p ("M":n:xs) = readMaybe n <&> \i -> ITask i (TEModify (unwords xs))
p _ = Nothing
onId :: String -> TaskCmd -> Maybe TodoInp
onId "*" te = Just (IAll te)
onId n te = readMaybe n <&> \i -> ITask i te
(<&>) :: Functor f => f a -> (a -> b) -> f b
x <&> f = fmap f x
-- | Just for command line testing use, turning the IntMap into a String.
formatTodo :: IntMap Task -> String
formatTodo = unlines . map format . IM.toList
where
format (n, Task desc compl) = concat [ show n
, ". ["
, if compl then "X" else " "
, "] "
, desc
]
main :: IO ()
main = void . interactAuto $ Just <$> fromBlips "" -- we need an Interval
. perBlip (fmap formatTodo todoApp)
. emitJusts parseInp