#!/usr/bin/env stack
>
This is a command-line Pomodoro counter.
> module Pomodoro (session, countdown) where
> import Control.Concurrent (threadDelay)
> import System.Console.ANSI (clearLine,
> saveCursor,
> restoreCursor)
> import System.IO (hFlush,
> stdout)
> import Data.Time.Clock.POSIX (posixSecondsToUTCTime)
> import Data.Time.Format (formatTime, defaultTimeLocale)
>
> data Pomodoro = First | Second | Third | Fourth
> deriving (Pomodoro -> Pomodoro -> Bool
(Pomodoro -> Pomodoro -> Bool)
-> (Pomodoro -> Pomodoro -> Bool) -> Eq Pomodoro
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: Pomodoro -> Pomodoro -> Bool
$c/= :: Pomodoro -> Pomodoro -> Bool
== :: Pomodoro -> Pomodoro -> Bool
$c== :: Pomodoro -> Pomodoro -> Bool
Eq, Eq Pomodoro
Eq Pomodoro
-> (Pomodoro -> Pomodoro -> Ordering)
-> (Pomodoro -> Pomodoro -> Bool)
-> (Pomodoro -> Pomodoro -> Bool)
-> (Pomodoro -> Pomodoro -> Bool)
-> (Pomodoro -> Pomodoro -> Bool)
-> (Pomodoro -> Pomodoro -> Pomodoro)
-> (Pomodoro -> Pomodoro -> Pomodoro)
-> Ord Pomodoro
Pomodoro -> Pomodoro -> Bool
Pomodoro -> Pomodoro -> Ordering
Pomodoro -> Pomodoro -> Pomodoro
forall a.
Eq a
-> (a -> a -> Ordering)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> a)
-> (a -> a -> a)
-> Ord a
min :: Pomodoro -> Pomodoro -> Pomodoro
$cmin :: Pomodoro -> Pomodoro -> Pomodoro
max :: Pomodoro -> Pomodoro -> Pomodoro
$cmax :: Pomodoro -> Pomodoro -> Pomodoro
>= :: Pomodoro -> Pomodoro -> Bool
$c>= :: Pomodoro -> Pomodoro -> Bool
> :: Pomodoro -> Pomodoro -> Bool
$c> :: Pomodoro -> Pomodoro -> Bool
<= :: Pomodoro -> Pomodoro -> Bool
$c<= :: Pomodoro -> Pomodoro -> Bool
< :: Pomodoro -> Pomodoro -> Bool
$c< :: Pomodoro -> Pomodoro -> Bool
compare :: Pomodoro -> Pomodoro -> Ordering
$ccompare :: Pomodoro -> Pomodoro -> Ordering
$cp1Ord :: Eq Pomodoro
Ord, Int -> Pomodoro -> ShowS
[Pomodoro] -> ShowS
Pomodoro -> String
(Int -> Pomodoro -> ShowS)
-> (Pomodoro -> String) -> ([Pomodoro] -> ShowS) -> Show Pomodoro
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [Pomodoro] -> ShowS
$cshowList :: [Pomodoro] -> ShowS
show :: Pomodoro -> String
$cshow :: Pomodoro -> String
showsPrec :: Int -> Pomodoro -> ShowS
$cshowsPrec :: Int -> Pomodoro -> ShowS
Show, ReadPrec [Pomodoro]
ReadPrec Pomodoro
Int -> ReadS Pomodoro
ReadS [Pomodoro]
(Int -> ReadS Pomodoro)
-> ReadS [Pomodoro]
-> ReadPrec Pomodoro
-> ReadPrec [Pomodoro]
-> Read Pomodoro
forall a.
(Int -> ReadS a)
-> ReadS [a] -> ReadPrec a -> ReadPrec [a] -> Read a
readListPrec :: ReadPrec [Pomodoro]
$creadListPrec :: ReadPrec [Pomodoro]
readPrec :: ReadPrec Pomodoro
$creadPrec :: ReadPrec Pomodoro
readList :: ReadS [Pomodoro]
$creadList :: ReadS [Pomodoro]
readsPrec :: Int -> ReadS Pomodoro
$creadsPrec :: Int -> ReadS Pomodoro
Read, Pomodoro
Pomodoro -> Pomodoro -> Bounded Pomodoro
forall a. a -> a -> Bounded a
maxBound :: Pomodoro
$cmaxBound :: Pomodoro
minBound :: Pomodoro
$cminBound :: Pomodoro
Bounded, Int -> Pomodoro
Pomodoro -> Int
Pomodoro -> [Pomodoro]
Pomodoro -> Pomodoro
Pomodoro -> Pomodoro -> [Pomodoro]
Pomodoro -> Pomodoro -> Pomodoro -> [Pomodoro]
(Pomodoro -> Pomodoro)
-> (Pomodoro -> Pomodoro)
-> (Int -> Pomodoro)
-> (Pomodoro -> Int)
-> (Pomodoro -> [Pomodoro])
-> (Pomodoro -> Pomodoro -> [Pomodoro])
-> (Pomodoro -> Pomodoro -> [Pomodoro])
-> (Pomodoro -> Pomodoro -> Pomodoro -> [Pomodoro])
-> Enum Pomodoro
forall a.
(a -> a)
-> (a -> a)
-> (Int -> a)
-> (a -> Int)
-> (a -> [a])
-> (a -> a -> [a])
-> (a -> a -> [a])
-> (a -> a -> a -> [a])
-> Enum a
enumFromThenTo :: Pomodoro -> Pomodoro -> Pomodoro -> [Pomodoro]
$cenumFromThenTo :: Pomodoro -> Pomodoro -> Pomodoro -> [Pomodoro]
enumFromTo :: Pomodoro -> Pomodoro -> [Pomodoro]
$cenumFromTo :: Pomodoro -> Pomodoro -> [Pomodoro]
enumFromThen :: Pomodoro -> Pomodoro -> [Pomodoro]
$cenumFromThen :: Pomodoro -> Pomodoro -> [Pomodoro]
enumFrom :: Pomodoro -> [Pomodoro]
$cenumFrom :: Pomodoro -> [Pomodoro]
fromEnum :: Pomodoro -> Int
$cfromEnum :: Pomodoro -> Int
toEnum :: Int -> Pomodoro
$ctoEnum :: Int -> Pomodoro
pred :: Pomodoro -> Pomodoro
$cpred :: Pomodoro -> Pomodoro
succ :: Pomodoro -> Pomodoro
$csucc :: Pomodoro -> Pomodoro
Enum)
>
>
> secToTimestamp :: Int -> String
> secToTimestamp :: Int -> String
secToTimestamp = TimeLocale -> String -> UTCTime -> String
forall t. FormatTime t => TimeLocale -> String -> t -> String
formatTime TimeLocale
defaultTimeLocale String
"%M:%S" (UTCTime -> String) -> (Int -> UTCTime) -> Int -> String
forall b c a. (b -> c) -> (a -> b) -> a -> c
. POSIXTime -> UTCTime
posixSecondsToUTCTime (POSIXTime -> UTCTime) -> (Int -> POSIXTime) -> Int -> UTCTime
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Int -> POSIXTime
forall a b. (Integral a, Num b) => a -> b
fromIntegral
>
>
>
>
>
>
>
>
>
> countdown :: IO()
> countdown :: IO ()
countdown = do
> Int -> IO ()
wait_seconds (Int -> IO ()) -> Int -> IO ()
forall a b. (a -> b) -> a -> b
$ Int
25 Int -> Int -> Int
forall a. Num a => a -> a -> a
* Int
60 Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
1
>
> no_del :: Int -> IO()
> no_del :: Int -> IO ()
no_del Int
_ = do
> () -> IO ()
forall (m :: * -> *) a. Monad m => a -> m a
return ()
> pom :: Show a => a -> IO ()
> pom :: a -> IO ()
pom a
m = do
> String -> IO ()
putStr (String -> IO ()) -> String -> IO ()
forall a b. (a -> b) -> a -> b
$ a -> String
forall a. Show a => a -> String
show a
m String -> ShowS
forall a. [a] -> [a] -> [a]
++ String
" pomodoro" String -> ShowS
forall a. [a] -> [a] -> [a]
++ String
" | "
> IO ()
saveCursor
> Int -> IO ()
wait_seconds (Int -> IO ()) -> Int -> IO ()
forall a b. (a -> b) -> a -> b
$ Int
25 Int -> Int -> Int
forall a. Num a => a -> a -> a
* Int
60 Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
1
> IO ()
restoreCursor
> String -> IO ()
putStrLn String
"Finished, take a 5 minute rest."
> to_work :: IO ()
> to_work :: IO ()
to_work = do
> IO ()
saveCursor
> String -> IO ()
putStr String
"Get back to work"
> Int -> IO ()
delay Int
2
> IO ()
restoreCursor
> IO ()
clearLine
> pomodoro :: Pomodoro -> IO ()
> pomodoro :: Pomodoro -> IO ()
pomodoro Pomodoro
Fourth = do
> Pomodoro -> IO ()
forall a. Show a => a -> IO ()
pom Pomodoro
Fourth
> String -> IO ()
putStrLn String
"Take a 30-minute rest now. You just completed 4 pomodoros."
> String -> IO ()
putStrLn String
"Congratulations on 4 pomodoros finished in a row!"
> pomodoro Pomodoro
m = do
> Pomodoro -> IO ()
forall a. Show a => a -> IO ()
pom Pomodoro
m
> Int -> IO ()
delay (Int -> IO ()) -> Int -> IO ()
forall a b. (a -> b) -> a -> b
$ Int
5 Int -> Int -> Int
forall a. Num a => a -> a -> a
* Int
60
> IO ()
to_work
> Pomodoro -> IO ()
pomodoro (Pomodoro -> IO ()) -> Pomodoro -> IO ()
forall a b. (a -> b) -> a -> b
$ Pomodoro -> Pomodoro
forall a. Enum a => a -> a
succ Pomodoro
m
>
> wait_seconds :: Int -> IO()
> wait_seconds :: Int -> IO ()
wait_seconds Int
0 = String -> IO ()
putStr String
""
> wait_seconds Int
n = do
> IO ()
saveCursor
> String -> IO ()
putStr (String -> IO ()) -> String -> IO ()
forall a b. (a -> b) -> a -> b
$ Int -> String
secToTimestamp (Int -> String) -> Int -> String
forall a b. (a -> b) -> a -> b
$ Int
n Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
1
> Handle -> IO ()
hFlush Handle
stdout
> IO ()
restoreCursor
> Int -> IO ()
delay Int
1
> Int -> IO ()
wait_seconds (Int -> IO ()) -> Int -> IO ()
forall a b. (a -> b) -> a -> b
$ Int
n Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
1
>
>
>
>
>
> delay :: Int -> IO()
> delay :: Int -> IO ()
delay Int
n = Int -> IO ()
threadDelay (Int -> IO ()) -> Int -> IO ()
forall a b. (a -> b) -> a -> b
$ Int
n Int -> Int -> Int
forall a. Num a => a -> a -> a
* Int
1000 Int -> Int -> Int
forall a. Num a => a -> a -> a
* Int
1000
> session :: IO()
> session :: IO ()
session = Pomodoro -> IO ()
pomodoro Pomodoro
First
> main :: IO()
> main :: IO ()
main = IO ()
session