{-# LANGUAGE CPP #-}
{-# LANGUAGE InstanceSigs #-}
{-# LANGUAGE LambdaCase #-}
{-# LANGUAGE NamedFieldPuns #-}
{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE ScopedTypeVariables #-}
{-# LANGUAGE StrictData #-}
module XMonad.Prompt.OrgMode (
orgPrompt,
orgPromptPrimary,
ClipboardSupport (..),
OrgMode,
#ifdef TESTING
pInput,
Note (..),
Priority (..),
Date (..),
Time (..),
TimeOfDay (..),
DayOfWeek (..),
#endif
) where
import XMonad.Prelude
import XMonad (X, io)
import XMonad.Prompt (XPConfig, XPrompt (showXPrompt), mkXPrompt)
import XMonad.Util.Parser
import XMonad.Util.XSelection (getSelection)
import Data.Time (Day (ModifiedJulianDay), NominalDiffTime, UTCTime (utctDay), addUTCTime, defaultTimeLocale, formatTime, fromGregorian, getCurrentTime, iso8601DateFormat, nominalDay, toGregorian)
import System.IO (IOMode (AppendMode), hPutStrLn, withFile)
data OrgMode = OrgMode
{ OrgMode -> ClipboardSupport
clpSupport :: ClipboardSupport
, :: String
, OrgMode -> String
orgFile :: FilePath
}
data ClipboardSupport
= PrimarySelection
| NoClpSupport
data Clp
= String
| Body String
instance XPrompt OrgMode where
showXPrompt :: OrgMode -> String
showXPrompt :: OrgMode -> String
showXPrompt OrgMode{ String
todoHeader :: String
todoHeader :: OrgMode -> String
todoHeader, String
orgFile :: String
orgFile :: OrgMode -> String
orgFile, ClipboardSupport
clpSupport :: ClipboardSupport
clpSupport :: OrgMode -> ClipboardSupport
clpSupport } =
[String] -> String
forall a. Monoid a => [a] -> a
mconcat [String
"Add ", String
todoHeader, String
clp, String
" to ", String
orgFile, String
": "]
where
String
clp :: String = case ClipboardSupport
clpSupport of
ClipboardSupport
NoClpSupport -> String
""
ClipboardSupport
PrimarySelection -> String
" + PS"
orgPrompt
:: XPConfig
-> String
-> FilePath
-> X ()
orgPrompt :: XPConfig -> String -> String -> X ()
orgPrompt XPConfig
xpc = XPConfig -> OrgMode -> X ()
mkOrgPrompt XPConfig
xpc (OrgMode -> X ())
-> (String -> String -> OrgMode) -> String -> String -> X ()
forall a b c d. (a -> b) -> (c -> d -> a) -> c -> d -> b
.: ClipboardSupport -> String -> String -> OrgMode
OrgMode ClipboardSupport
NoClpSupport
orgPromptPrimary :: XPConfig -> String -> FilePath -> X ()
orgPromptPrimary :: XPConfig -> String -> String -> X ()
orgPromptPrimary XPConfig
xpc = XPConfig -> OrgMode -> X ()
mkOrgPrompt XPConfig
xpc (OrgMode -> X ())
-> (String -> String -> OrgMode) -> String -> String -> X ()
forall a b c d. (a -> b) -> (c -> d -> a) -> c -> d -> b
.: ClipboardSupport -> String -> String -> OrgMode
OrgMode ClipboardSupport
PrimarySelection
mkOrgPrompt :: XPConfig -> OrgMode -> X ()
mkOrgPrompt :: XPConfig -> OrgMode -> X ()
mkOrgPrompt XPConfig
xpc oc :: OrgMode
oc@OrgMode{ String
todoHeader :: String
todoHeader :: OrgMode -> String
todoHeader, String
orgFile :: String
orgFile :: OrgMode -> String
orgFile, ClipboardSupport
clpSupport :: ClipboardSupport
clpSupport :: OrgMode -> ClipboardSupport
clpSupport } =
OrgMode -> XPConfig -> ComplFunction -> (String -> X ()) -> X ()
forall p.
XPrompt p =>
p -> XPConfig -> ComplFunction -> (String -> X ()) -> X ()
mkXPrompt OrgMode
oc XPConfig
xpc (IO [String] -> ComplFunction
forall a b. a -> b -> a
const ([String] -> IO [String]
forall (f :: * -> *) a. Applicative f => a -> f a
pure [])) String -> X ()
appendNote
where
appendNote :: String -> X ()
appendNote :: String -> X ()
appendNote String
input = IO () -> X ()
forall (m :: * -> *) a. MonadIO m => IO a -> m a
io (IO () -> X ()) -> IO () -> X ()
forall a b. (a -> b) -> a -> b
$ do
Clp
clpStr <- case ClipboardSupport
clpSupport of
ClipboardSupport
NoClpSupport -> Clp -> IO Clp
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Clp -> IO Clp) -> Clp -> IO Clp
forall a b. (a -> b) -> a -> b
$ String -> Clp
Body String
""
ClipboardSupport
PrimarySelection -> do
String
sel <- IO String
forall (m :: * -> *). MonadIO m => m String
getSelection
Clp -> IO Clp
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Clp -> IO Clp) -> Clp -> IO Clp
forall a b. (a -> b) -> a -> b
$ if (String -> Bool) -> [String] -> Bool
forall (t :: * -> *) a. Foldable t => (a -> Bool) -> t a -> Bool
any (String -> String -> Bool
forall a. Eq a => [a] -> [a] -> Bool
`isPrefixOf` String
sel) [String
"http://", String
"https://"]
then String -> Clp
Header String
sel
else String -> Clp
Body (String -> Clp) -> String -> Clp
forall a b. (a -> b) -> a -> b
$ String
"\n " String -> String -> String
forall a. Semigroup a => a -> a -> a
<> String
sel
String
fp <- String -> IO String
forall (m :: * -> *). MonadIO m => String -> m String
mkAbsolutePath String
orgFile
String -> IOMode -> (Handle -> IO ()) -> IO ()
forall r. String -> IOMode -> (Handle -> IO r) -> IO r
withFile String
fp IOMode
AppendMode ((Handle -> IO ()) -> IO ())
-> (String -> Handle -> IO ()) -> String -> IO ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Handle -> String -> IO ()) -> String -> Handle -> IO ()
forall a b c. (a -> b -> c) -> b -> a -> c
flip Handle -> String -> IO ()
hPutStrLn
(String -> IO ()) -> (String -> IO String) -> String -> IO ()
forall (m :: * -> *) b c a.
Monad m =>
(b -> m c) -> (a -> m b) -> a -> m c
<=< IO String -> (Note -> IO String) -> Maybe Note -> IO String
forall b a. b -> (a -> b) -> Maybe a -> b
maybe (String -> IO String
forall (f :: * -> *) a. Applicative f => a -> f a
pure String
"") (Clp -> String -> Note -> IO String
ppNote Clp
clpStr String
todoHeader) (Maybe Note -> IO String)
-> (String -> Maybe Note) -> String -> IO String
forall b c a. (b -> c) -> (a -> b) -> a -> c
. String -> Maybe Note
pInput
(String -> IO ()) -> String -> IO ()
forall a b. (a -> b) -> a -> b
$ String
input
data Time = Time
{ Time -> Date
date :: Date
, Time -> Maybe TimeOfDay
tod :: Maybe TimeOfDay
}
deriving (Time -> Time -> Bool
(Time -> Time -> Bool) -> (Time -> Time -> Bool) -> Eq Time
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: Time -> Time -> Bool
$c/= :: Time -> Time -> Bool
== :: Time -> Time -> Bool
$c== :: Time -> Time -> Bool
Eq, Int -> Time -> String -> String
[Time] -> String -> String
Time -> String
(Int -> Time -> String -> String)
-> (Time -> String) -> ([Time] -> String -> String) -> Show Time
forall a.
(Int -> a -> String -> String)
-> (a -> String) -> ([a] -> String -> String) -> Show a
showList :: [Time] -> String -> String
$cshowList :: [Time] -> String -> String
show :: Time -> String
$cshow :: Time -> String
showsPrec :: Int -> Time -> String -> String
$cshowsPrec :: Int -> Time -> String -> String
Show)
data TimeOfDay = TimeOfDay Int Int
deriving (TimeOfDay -> TimeOfDay -> Bool
(TimeOfDay -> TimeOfDay -> Bool)
-> (TimeOfDay -> TimeOfDay -> Bool) -> Eq TimeOfDay
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: TimeOfDay -> TimeOfDay -> Bool
$c/= :: TimeOfDay -> TimeOfDay -> Bool
== :: TimeOfDay -> TimeOfDay -> Bool
$c== :: TimeOfDay -> TimeOfDay -> Bool
Eq)
instance Show TimeOfDay where
show :: TimeOfDay -> String
show :: TimeOfDay -> String
show (TimeOfDay Int
h Int
m) = Int -> String
pad Int
h String -> String -> String
forall a. Semigroup a => a -> a -> a
<> String
":" String -> String -> String
forall a. Semigroup a => a -> a -> a
<> Int -> String
pad Int
m
where
pad :: Int -> String
pad :: Int -> String
pad Int
n = (if Int
n Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
<= Int
9 then String
"0" else String
"") String -> String -> String
forall a. Semigroup a => a -> a -> a
<> Int -> String
forall a. Show a => a -> String
show Int
n
data Date
= Today
| Tomorrow
| Next DayOfWeek
| Date (Int, Maybe Int, Maybe Integer)
deriving (Date -> Date -> Bool
(Date -> Date -> Bool) -> (Date -> Date -> Bool) -> Eq Date
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: Date -> Date -> Bool
$c/= :: Date -> Date -> Bool
== :: Date -> Date -> Bool
$c== :: Date -> Date -> Bool
Eq, Eq Date
Eq Date
-> (Date -> Date -> Ordering)
-> (Date -> Date -> Bool)
-> (Date -> Date -> Bool)
-> (Date -> Date -> Bool)
-> (Date -> Date -> Bool)
-> (Date -> Date -> Date)
-> (Date -> Date -> Date)
-> Ord Date
Date -> Date -> Bool
Date -> Date -> Ordering
Date -> Date -> Date
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 :: Date -> Date -> Date
$cmin :: Date -> Date -> Date
max :: Date -> Date -> Date
$cmax :: Date -> Date -> Date
>= :: Date -> Date -> Bool
$c>= :: Date -> Date -> Bool
> :: Date -> Date -> Bool
$c> :: Date -> Date -> Bool
<= :: Date -> Date -> Bool
$c<= :: Date -> Date -> Bool
< :: Date -> Date -> Bool
$c< :: Date -> Date -> Bool
compare :: Date -> Date -> Ordering
$ccompare :: Date -> Date -> Ordering
Ord, Int -> Date -> String -> String
[Date] -> String -> String
Date -> String
(Int -> Date -> String -> String)
-> (Date -> String) -> ([Date] -> String -> String) -> Show Date
forall a.
(Int -> a -> String -> String)
-> (a -> String) -> ([a] -> String -> String) -> Show a
showList :: [Date] -> String -> String
$cshowList :: [Date] -> String -> String
show :: Date -> String
$cshow :: Date -> String
showsPrec :: Int -> Date -> String -> String
$cshowsPrec :: Int -> Date -> String -> String
Show)
toOrgFmt :: Maybe TimeOfDay -> Day -> String
toOrgFmt :: Maybe TimeOfDay -> Day -> String
toOrgFmt Maybe TimeOfDay
tod Day
day =
[String] -> String
forall a. Monoid a => [a] -> a
mconcat [String
"<", String
isoDay, String
" ", Int -> String -> String
forall a. Int -> [a] -> [a]
take Int
3 (String -> String) -> String -> String
forall a b. (a -> b) -> a -> b
$ DayOfWeek -> String
forall a. Show a => a -> String
show (Day -> DayOfWeek
dayOfWeek Day
day), String
time, String
">"]
where
String
time :: String = String -> (TimeOfDay -> String) -> Maybe TimeOfDay -> String
forall b a. b -> (a -> b) -> Maybe a -> b
maybe String
"" ((Char
' ' Char -> String -> String
forall a. a -> [a] -> [a]
:) (String -> String) -> (TimeOfDay -> String) -> TimeOfDay -> String
forall b c a. (b -> c) -> (a -> b) -> a -> c
. TimeOfDay -> String
forall a. Show a => a -> String
show) Maybe TimeOfDay
tod
String
isoDay :: String = TimeLocale -> String -> Day -> String
forall t. FormatTime t => TimeLocale -> String -> t -> String
formatTime TimeLocale
defaultTimeLocale (Maybe String -> String
iso8601DateFormat Maybe String
forall a. Maybe a
Nothing) Day
day
ppDate :: Time -> IO String
ppDate :: Time -> IO String
ppDate Time{ Date
date :: Date
date :: Time -> Date
date, Maybe TimeOfDay
tod :: Maybe TimeOfDay
tod :: Time -> Maybe TimeOfDay
tod } = do
UTCTime
curTime <- IO UTCTime
getCurrentTime
let curDay :: Day
curDay = UTCTime -> Day
utctDay UTCTime
curTime
(Integer
y, Int
m, Int
_) = Day -> (Integer, Int, Int)
toGregorian Day
curDay
diffToDay :: DayOfWeek -> NominalDiffTime
diffToDay DayOfWeek
d = DayOfWeek -> DayOfWeek -> NominalDiffTime
diffBetween DayOfWeek
d (Day -> DayOfWeek
dayOfWeek Day
curDay)
String -> IO String
forall (f :: * -> *) a. Applicative f => a -> f a
pure (String -> IO String) -> (Day -> String) -> Day -> IO String
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Maybe TimeOfDay -> Day -> String
toOrgFmt Maybe TimeOfDay
tod (Day -> IO String) -> Day -> IO String
forall a b. (a -> b) -> a -> b
$ case Date
date of
Date
Today -> Day
curDay
Date
Tomorrow -> UTCTime -> Day
utctDay (UTCTime -> Day) -> UTCTime -> Day
forall a b. (a -> b) -> a -> b
$ NominalDiffTime -> UTCTime -> UTCTime
addDays NominalDiffTime
1 UTCTime
curTime
Next DayOfWeek
wday -> UTCTime -> Day
utctDay (UTCTime -> Day) -> UTCTime -> Day
forall a b. (a -> b) -> a -> b
$ NominalDiffTime -> UTCTime -> UTCTime
addDays (DayOfWeek -> NominalDiffTime
diffToDay DayOfWeek
wday) UTCTime
curTime
Date (Int
d, Maybe Int
mbM, Maybe Integer
mbY) -> Integer -> Int -> Int -> Day
fromGregorian (Integer -> Maybe Integer -> Integer
forall a. a -> Maybe a -> a
fromMaybe Integer
y Maybe Integer
mbY) (Int -> Maybe Int -> Int
forall a. a -> Maybe a -> a
fromMaybe Int
m Maybe Int
mbM) Int
d
where
NominalDiffTime -> UTCTime -> UTCTime
addDays :: NominalDiffTime -> UTCTime -> UTCTime
= NominalDiffTime -> UTCTime -> UTCTime
addUTCTime (NominalDiffTime -> UTCTime -> UTCTime)
-> (NominalDiffTime -> NominalDiffTime)
-> NominalDiffTime
-> UTCTime
-> UTCTime
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (NominalDiffTime -> NominalDiffTime -> NominalDiffTime
forall a. Num a => a -> a -> a
* NominalDiffTime
nominalDay)
diffBetween :: DayOfWeek -> DayOfWeek -> NominalDiffTime
diffBetween :: DayOfWeek -> DayOfWeek -> NominalDiffTime
diffBetween DayOfWeek
d DayOfWeek
cur
| DayOfWeek
d DayOfWeek -> DayOfWeek -> Bool
forall a. Eq a => a -> a -> Bool
== DayOfWeek
cur = NominalDiffTime
7
| Bool
otherwise = Int -> NominalDiffTime
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Int -> NominalDiffTime) -> (Int -> Int) -> Int -> NominalDiffTime
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Int -> Int
forall a. Num a => a -> a
abs (Int -> NominalDiffTime) -> Int -> NominalDiffTime
forall a b. (a -> b) -> a -> b
$ (DayOfWeek -> Int
forall a. Enum a => a -> Int
fromEnum DayOfWeek
d Int -> Int -> Int
forall a. Num a => a -> a -> a
- DayOfWeek -> Int
forall a. Enum a => a -> Int
fromEnum DayOfWeek
cur) Int -> Int -> Int
forall a. Integral a => a -> a -> a
`mod` Int
7
dayOfWeek :: Day -> DayOfWeek
dayOfWeek :: Day -> DayOfWeek
dayOfWeek (ModifiedJulianDay Integer
d) = Int -> DayOfWeek
forall a. Enum a => Int -> a
toEnum (Int -> DayOfWeek) -> Int -> DayOfWeek
forall a b. (a -> b) -> a -> b
$ Integer -> Int
forall a. Num a => Integer -> a
fromInteger (Integer -> Int) -> Integer -> Int
forall a b. (a -> b) -> a -> b
$ Integer
d Integer -> Integer -> Integer
forall a. Num a => a -> a -> a
+ Integer
3
data DayOfWeek
= Monday | Tuesday | Wednesday | Thursday | Friday | Saturday | Sunday
deriving (DayOfWeek -> DayOfWeek -> Bool
(DayOfWeek -> DayOfWeek -> Bool)
-> (DayOfWeek -> DayOfWeek -> Bool) -> Eq DayOfWeek
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: DayOfWeek -> DayOfWeek -> Bool
$c/= :: DayOfWeek -> DayOfWeek -> Bool
== :: DayOfWeek -> DayOfWeek -> Bool
$c== :: DayOfWeek -> DayOfWeek -> Bool
Eq, Eq DayOfWeek
Eq DayOfWeek
-> (DayOfWeek -> DayOfWeek -> Ordering)
-> (DayOfWeek -> DayOfWeek -> Bool)
-> (DayOfWeek -> DayOfWeek -> Bool)
-> (DayOfWeek -> DayOfWeek -> Bool)
-> (DayOfWeek -> DayOfWeek -> Bool)
-> (DayOfWeek -> DayOfWeek -> DayOfWeek)
-> (DayOfWeek -> DayOfWeek -> DayOfWeek)
-> Ord DayOfWeek
DayOfWeek -> DayOfWeek -> Bool
DayOfWeek -> DayOfWeek -> Ordering
DayOfWeek -> DayOfWeek -> DayOfWeek
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 :: DayOfWeek -> DayOfWeek -> DayOfWeek
$cmin :: DayOfWeek -> DayOfWeek -> DayOfWeek
max :: DayOfWeek -> DayOfWeek -> DayOfWeek
$cmax :: DayOfWeek -> DayOfWeek -> DayOfWeek
>= :: DayOfWeek -> DayOfWeek -> Bool
$c>= :: DayOfWeek -> DayOfWeek -> Bool
> :: DayOfWeek -> DayOfWeek -> Bool
$c> :: DayOfWeek -> DayOfWeek -> Bool
<= :: DayOfWeek -> DayOfWeek -> Bool
$c<= :: DayOfWeek -> DayOfWeek -> Bool
< :: DayOfWeek -> DayOfWeek -> Bool
$c< :: DayOfWeek -> DayOfWeek -> Bool
compare :: DayOfWeek -> DayOfWeek -> Ordering
$ccompare :: DayOfWeek -> DayOfWeek -> Ordering
Ord, Int -> DayOfWeek -> String -> String
[DayOfWeek] -> String -> String
DayOfWeek -> String
(Int -> DayOfWeek -> String -> String)
-> (DayOfWeek -> String)
-> ([DayOfWeek] -> String -> String)
-> Show DayOfWeek
forall a.
(Int -> a -> String -> String)
-> (a -> String) -> ([a] -> String -> String) -> Show a
showList :: [DayOfWeek] -> String -> String
$cshowList :: [DayOfWeek] -> String -> String
show :: DayOfWeek -> String
$cshow :: DayOfWeek -> String
showsPrec :: Int -> DayOfWeek -> String -> String
$cshowsPrec :: Int -> DayOfWeek -> String -> String
Show)
instance Enum DayOfWeek where
toEnum :: Int -> DayOfWeek
toEnum :: Int -> DayOfWeek
toEnum Int
i = case Int -> Int -> Int
forall a. Integral a => a -> a -> a
mod Int
i Int
7 of
Int
0 -> DayOfWeek
Sunday
Int
1 -> DayOfWeek
Monday
Int
2 -> DayOfWeek
Tuesday
Int
3 -> DayOfWeek
Wednesday
Int
4 -> DayOfWeek
Thursday
Int
5 -> DayOfWeek
Friday
Int
_ -> DayOfWeek
Saturday
fromEnum :: DayOfWeek -> Int
fromEnum :: DayOfWeek -> Int
fromEnum = \case
DayOfWeek
Monday -> Int
1
DayOfWeek
Tuesday -> Int
2
DayOfWeek
Wednesday -> Int
3
DayOfWeek
Thursday -> Int
4
DayOfWeek
Friday -> Int
5
DayOfWeek
Saturday -> Int
6
DayOfWeek
Sunday -> Int
7
data Note
= Scheduled String Time Priority
| Deadline String Time Priority
| NormalMsg String Priority
deriving (Note -> Note -> Bool
(Note -> Note -> Bool) -> (Note -> Note -> Bool) -> Eq Note
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: Note -> Note -> Bool
$c/= :: Note -> Note -> Bool
== :: Note -> Note -> Bool
$c== :: Note -> Note -> Bool
Eq, Int -> Note -> String -> String
[Note] -> String -> String
Note -> String
(Int -> Note -> String -> String)
-> (Note -> String) -> ([Note] -> String -> String) -> Show Note
forall a.
(Int -> a -> String -> String)
-> (a -> String) -> ([a] -> String -> String) -> Show a
showList :: [Note] -> String -> String
$cshowList :: [Note] -> String -> String
show :: Note -> String
$cshow :: Note -> String
showsPrec :: Int -> Note -> String -> String
$cshowsPrec :: Int -> Note -> String -> String
Show)
data Priority = A | B | C | NoPriority
deriving (Priority -> Priority -> Bool
(Priority -> Priority -> Bool)
-> (Priority -> Priority -> Bool) -> Eq Priority
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: Priority -> Priority -> Bool
$c/= :: Priority -> Priority -> Bool
== :: Priority -> Priority -> Bool
$c== :: Priority -> Priority -> Bool
Eq, Int -> Priority -> String -> String
[Priority] -> String -> String
Priority -> String
(Int -> Priority -> String -> String)
-> (Priority -> String)
-> ([Priority] -> String -> String)
-> Show Priority
forall a.
(Int -> a -> String -> String)
-> (a -> String) -> ([a] -> String -> String) -> Show a
showList :: [Priority] -> String -> String
$cshowList :: [Priority] -> String -> String
show :: Priority -> String
$cshow :: Priority -> String
showsPrec :: Int -> Priority -> String -> String
$cshowsPrec :: Int -> Priority -> String -> String
Show)
ppNote :: Clp -> String -> Note -> IO String
ppNote :: Clp -> String -> Note -> IO String
ppNote Clp
clp String
todo = \case
Scheduled String
str Time
time Priority
prio -> String -> String -> Maybe Time -> Priority -> IO String
mkLine String
str String
"SCHEDULED: " (Time -> Maybe Time
forall a. a -> Maybe a
Just Time
time) Priority
prio
Deadline String
str Time
time Priority
prio -> String -> String -> Maybe Time -> Priority -> IO String
mkLine String
str String
"DEADLINE: " (Time -> Maybe Time
forall a. a -> Maybe a
Just Time
time) Priority
prio
NormalMsg String
str Priority
prio -> String -> String -> Maybe Time -> Priority -> IO String
mkLine String
str String
"" Maybe Time
forall a. Maybe a
Nothing Priority
prio
where
mkLine :: String -> String -> Maybe Time -> Priority -> IO String
mkLine :: String -> String -> Maybe Time -> Priority -> IO String
mkLine String
str String
sched Maybe Time
time Priority
prio = do
String
t <- case Maybe Time
time of
Maybe Time
Nothing -> String -> IO String
forall (f :: * -> *) a. Applicative f => a -> f a
pure String
""
Just Time
ti -> ((String
"\n " String -> String -> String
forall a. Semigroup a => a -> a -> a
<> String
sched) String -> String -> String
forall a. Semigroup a => a -> a -> a
<>) (String -> String) -> IO String -> IO String
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Time -> IO String
ppDate Time
ti
String -> IO String
forall (f :: * -> *) a. Applicative f => a -> f a
pure (String -> IO String) -> String -> IO String
forall a b. (a -> b) -> a -> b
$ String
"* " String -> String -> String
forall a. Semigroup a => a -> a -> a
<> String
todo String -> String -> String
forall a. Semigroup a => a -> a -> a
<> String
priority String -> String -> String
forall a. Semigroup a => a -> a -> a
<> case Clp
clp of
Body String
c -> [String] -> String
forall a. Monoid a => [a] -> a
mconcat [String
str, String
t, String
c]
Header String
c -> [String] -> String
forall a. Monoid a => [a] -> a
mconcat [String
"[[", String
c, String
"][", String
str,String
"]]", String
t]
where
priority :: String
priority = case Priority
prio of
Priority
NoPriority -> String
" "
Priority
otherPrio -> String
" [#" String -> String -> String
forall a. Semigroup a => a -> a -> a
<> Priority -> String
forall a. Show a => a -> String
show Priority
otherPrio String -> String -> String
forall a. Semigroup a => a -> a -> a
<> String
"] "
pInput :: String -> Maybe Note
pInput :: String -> Maybe Note
pInput String
inp = (Parser Note -> String -> Maybe Note
forall a. Parser a -> String -> Maybe a
`runParser` String
inp) (Parser Note -> Maybe Note)
-> ([Parser Note] -> Parser Note) -> [Parser Note] -> Maybe Note
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [Parser Note] -> Parser Note
forall a. [Parser a] -> Parser a
choice ([Parser Note] -> Maybe Note) -> [Parser Note] -> Maybe Note
forall a b. (a -> b) -> a -> b
$
[ String -> Time -> Priority -> Note
Scheduled (String -> Time -> Priority -> Note)
-> Parser String -> Parser (Time -> Priority -> Note)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> String -> Parser String
getLast String
"+s" Parser (Time -> Priority -> Note)
-> Parser Time -> Parser (Priority -> Note)
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> (Date -> Maybe TimeOfDay -> Time
Time (Date -> Maybe TimeOfDay -> Time)
-> Parser Date -> Parser (Maybe TimeOfDay -> Time)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Parser Date
pDate Parser (Maybe TimeOfDay -> Time)
-> Parser (Maybe TimeOfDay) -> Parser Time
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Parser (Maybe TimeOfDay)
pTimeOfDay) Parser (Priority -> Note) -> Parser Priority -> Parser Note
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Parser Priority
pPriority
, String -> Time -> Priority -> Note
Deadline (String -> Time -> Priority -> Note)
-> Parser String -> Parser (Time -> Priority -> Note)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> String -> Parser String
getLast String
"+d" Parser (Time -> Priority -> Note)
-> Parser Time -> Parser (Priority -> Note)
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> (Date -> Maybe TimeOfDay -> Time
Time (Date -> Maybe TimeOfDay -> Time)
-> Parser Date -> Parser (Maybe TimeOfDay -> Time)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Parser Date
pDate Parser (Maybe TimeOfDay -> Time)
-> Parser (Maybe TimeOfDay) -> Parser Time
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Parser (Maybe TimeOfDay)
pTimeOfDay) Parser (Priority -> Note) -> Parser Priority -> Parser Note
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Parser Priority
pPriority
, do String
s <- (Char -> Bool) -> Parser String
munch1 (Bool -> Char -> Bool
forall (f :: * -> *) a. Applicative f => a -> f a
pure Bool
True)
let (String
s', String
p) = Int -> String -> (String, String)
forall a. Int -> [a] -> ([a], [a])
splitAt (String -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length String
s Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
3) String
s
Note -> Parser Note
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Note -> Parser Note) -> Note -> Parser Note
forall a b. (a -> b) -> a -> b
$ case String -> Maybe Priority
tryPrio String
p of
Just Priority
prio -> String -> Priority -> Note
NormalMsg (Int -> String -> String
dropStripEnd Int
0 String
s') Priority
prio
Maybe Priority
Nothing -> String -> Priority -> Note
NormalMsg String
s Priority
NoPriority
]
where
tryPrio :: String -> Maybe Priority
tryPrio :: String -> Maybe Priority
tryPrio [Char
' ', Char
'#', Char
x]
| Char
x Char -> String -> Bool
forall (t :: * -> *) a. (Foldable t, Eq a) => a -> t a -> Bool
`elem` (String
"Aa" :: String) = Priority -> Maybe Priority
forall a. a -> Maybe a
Just Priority
A
| Char
x Char -> String -> Bool
forall (t :: * -> *) a. (Foldable t, Eq a) => a -> t a -> Bool
`elem` (String
"Bb" :: String) = Priority -> Maybe Priority
forall a. a -> Maybe a
Just Priority
B
| Char
x Char -> String -> Bool
forall (t :: * -> *) a. (Foldable t, Eq a) => a -> t a -> Bool
`elem` (String
"Cc" :: String) = Priority -> Maybe Priority
forall a. a -> Maybe a
Just Priority
C
tryPrio String
_ = Maybe Priority
forall a. Maybe a
Nothing
dropStripEnd :: Int -> String -> String
dropStripEnd :: Int -> String -> String
dropStripEnd Int
n = String -> String
forall a. [a] -> [a]
reverse (String -> String) -> (String -> String) -> String -> String
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Char -> Bool) -> String -> String
forall a. (a -> Bool) -> [a] -> [a]
dropWhile (Char -> Char -> Bool
forall a. Eq a => a -> a -> Bool
== Char
' ') (String -> String) -> (String -> String) -> String -> String
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Int -> String -> String
forall a. Int -> [a] -> [a]
drop Int
n (String -> String) -> (String -> String) -> String -> String
forall b c a. (b -> c) -> (a -> b) -> a -> c
. String -> String
forall a. [a] -> [a]
reverse
getLast :: String -> Parser String
getLast :: String -> Parser String
getLast String
ptn = Int -> String -> String
dropStripEnd (String -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length String
ptn)
(String -> String) -> ([String] -> String) -> [String] -> String
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [String] -> String
forall (t :: * -> *) a. Foldable t => t [a] -> [a]
concat
([String] -> String) -> Parser [String] -> Parser String
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Parser String -> Parser String -> Parser [String]
forall a sep. Parser a -> Parser sep -> Parser [a]
endBy1 (String -> Parser String
go String
"") (String -> Parser String
forall (f :: * -> *) a. Applicative f => a -> f a
pure String
ptn)
where
go :: String -> Parser String
go :: String -> Parser String
go String
consumed = do
String
str <- (Char -> Bool) -> Parser String
munch (Char -> Char -> Bool
forall a. Eq a => a -> a -> Bool
/= String -> Char
forall a. [a] -> a
head String
ptn)
String
word <- (Char -> Bool) -> Parser String
munch1 (Char -> Char -> Bool
forall a. Eq a => a -> a -> Bool
/= Char
' ')
(String -> Parser String)
-> (String -> Parser String) -> Bool -> String -> Parser String
forall a. a -> a -> Bool -> a
bool String -> Parser String
go String -> Parser String
forall (f :: * -> *) a. Applicative f => a -> f a
pure (String
word String -> String -> Bool
forall a. Eq a => a -> a -> Bool
== String
ptn) (String -> Parser String) -> String -> Parser String
forall a b. (a -> b) -> a -> b
$ String
consumed String -> String -> String
forall a. Semigroup a => a -> a -> a
<> String
str String -> String -> String
forall a. Semigroup a => a -> a -> a
<> String
word
pPriority :: Parser Priority
pPriority :: Parser Priority
pPriority = Parser Priority -> Parser Priority -> Parser Priority
forall a. Parser a -> Parser a -> Parser a
pLast (Priority -> Parser Priority
forall (f :: * -> *) a. Applicative f => a -> f a
pure Priority
NoPriority) (Parser Priority -> Parser Priority)
-> Parser Priority -> Parser Priority
forall a b. (a -> b) -> a -> b
$
Parser String
" " Parser String -> Parser () -> Parser ()
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f b
*> Parser ()
skipSpaces Parser () -> Parser Priority -> Parser Priority
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f b
*> [Parser Priority] -> Parser Priority
forall a. [Parser a] -> Parser a
choice
[ Parser String
"#" Parser String -> Parser String -> Parser String
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f b
*> (Parser String
"A" Parser String -> Parser String -> Parser String
forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> Parser String
"a") Parser String -> Priority -> Parser Priority
forall (f :: * -> *) a b. Functor f => f a -> b -> f b
$> Priority
A
, Parser String
"#" Parser String -> Parser String -> Parser String
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f b
*> (Parser String
"B" Parser String -> Parser String -> Parser String
forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> Parser String
"b") Parser String -> Priority -> Parser Priority
forall (f :: * -> *) a b. Functor f => f a -> b -> f b
$> Priority
B
, Parser String
"#" Parser String -> Parser String -> Parser String
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f b
*> (Parser String
"C" Parser String -> Parser String -> Parser String
forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> Parser String
"c") Parser String -> Priority -> Parser Priority
forall (f :: * -> *) a b. Functor f => f a -> b -> f b
$> Priority
C
]
pTimeOfDay :: Parser (Maybe TimeOfDay)
pTimeOfDay :: Parser (Maybe TimeOfDay)
pTimeOfDay = Parser (Maybe TimeOfDay)
-> Parser (Maybe TimeOfDay) -> Parser (Maybe TimeOfDay)
forall a. Parser a -> Parser a -> Parser a
pLast (Maybe TimeOfDay -> Parser (Maybe TimeOfDay)
forall (f :: * -> *) a. Applicative f => a -> f a
pure Maybe TimeOfDay
forall a. Maybe a
Nothing) (Parser (Maybe TimeOfDay) -> Parser (Maybe TimeOfDay))
-> Parser (Maybe TimeOfDay) -> Parser (Maybe TimeOfDay)
forall a b. (a -> b) -> a -> b
$
Parser ()
skipSpaces Parser () -> Parser (Maybe TimeOfDay) -> Parser (Maybe TimeOfDay)
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f b
*> [Parser (Maybe TimeOfDay)] -> Parser (Maybe TimeOfDay)
forall a. [Parser a] -> Parser a
choice
[ TimeOfDay -> Maybe TimeOfDay
forall a. a -> Maybe a
Just (TimeOfDay -> Maybe TimeOfDay)
-> Parser TimeOfDay -> Parser (Maybe TimeOfDay)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> (Int -> Int -> TimeOfDay
TimeOfDay (Int -> Int -> TimeOfDay)
-> Parser Int -> Parser (Int -> TimeOfDay)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Parser Int
pHour Parser (Int -> TimeOfDay)
-> Parser String -> Parser (Int -> TimeOfDay)
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f a
<* String -> Parser String
string String
":" Parser (Int -> TimeOfDay) -> Parser Int -> Parser TimeOfDay
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Parser Int
pMinute)
, TimeOfDay -> Maybe TimeOfDay
forall a. a -> Maybe a
Just (TimeOfDay -> Maybe TimeOfDay)
-> Parser TimeOfDay -> Parser (Maybe TimeOfDay)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> (Int -> Int -> TimeOfDay
TimeOfDay (Int -> Int -> TimeOfDay)
-> Parser Int -> Parser (Int -> TimeOfDay)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Parser Int
pHour Parser (Int -> TimeOfDay) -> Parser Int -> Parser TimeOfDay
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Int -> Parser Int
forall (f :: * -> *) a. Applicative f => a -> f a
pure Int
0 )
]
where
Parser Int
pMinute :: Parser Int = Int -> Int -> Parser Int
pNumBetween Int
1 Int
60
Parser Int
pHour :: Parser Int = Int -> Int -> Parser Int
pNumBetween Int
1 Int
24
pDate :: Parser Date
pDate :: Parser Date
pDate = Parser ()
skipSpaces Parser () -> Parser Date -> Parser Date
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f b
*> [Parser Date] -> Parser Date
forall a. [Parser a] -> Parser a
choice
[ Parser String -> String -> Date -> Parser Date
forall a. Parser String -> String -> a -> Parser a
pPrefix Parser String
"tod" String
"ay" Date
Today
, Parser String -> String -> Date -> Parser Date
forall a. Parser String -> String -> a -> Parser a
pPrefix Parser String
"tom" String
"orrow" Date
Tomorrow
, DayOfWeek -> Date
Next (DayOfWeek -> Date) -> Parser DayOfWeek -> Parser Date
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Parser DayOfWeek
pNext
, (Int, Maybe Int, Maybe Integer) -> Date
Date ((Int, Maybe Int, Maybe Integer) -> Date)
-> Parser (Int, Maybe Int, Maybe Integer) -> Parser Date
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Parser (Int, Maybe Int, Maybe Integer)
pDate'
]
where
Parser DayOfWeek
pNext :: Parser DayOfWeek = [Parser DayOfWeek] -> Parser DayOfWeek
forall a. [Parser a] -> Parser a
choice
[ Parser String -> String -> DayOfWeek -> Parser DayOfWeek
forall a. Parser String -> String -> a -> Parser a
pPrefix Parser String
"m" String
"onday" DayOfWeek
Monday , Parser String -> String -> DayOfWeek -> Parser DayOfWeek
forall a. Parser String -> String -> a -> Parser a
pPrefix Parser String
"tu" String
"esday" DayOfWeek
Tuesday
, Parser String -> String -> DayOfWeek -> Parser DayOfWeek
forall a. Parser String -> String -> a -> Parser a
pPrefix Parser String
"w" String
"ednesday" DayOfWeek
Wednesday, Parser String -> String -> DayOfWeek -> Parser DayOfWeek
forall a. Parser String -> String -> a -> Parser a
pPrefix Parser String
"th" String
"ursday" DayOfWeek
Thursday
, Parser String -> String -> DayOfWeek -> Parser DayOfWeek
forall a. Parser String -> String -> a -> Parser a
pPrefix Parser String
"f" String
"riday" DayOfWeek
Friday , Parser String -> String -> DayOfWeek -> Parser DayOfWeek
forall a. Parser String -> String -> a -> Parser a
pPrefix Parser String
"sa" String
"turday" DayOfWeek
Saturday
, Parser String -> String -> DayOfWeek -> Parser DayOfWeek
forall a. Parser String -> String -> a -> Parser a
pPrefix Parser String
"su" String
"nday" DayOfWeek
Sunday
]
numWithoutColon :: Parser Int
numWithoutColon :: Parser Int
numWithoutColon = do
Int
str <- Int -> Int -> Parser Int
pNumBetween Int
1 Int
12
Char
c <- Parser Char
get
if Char
c Char -> Char -> Bool
forall a. Eq a => a -> a -> Bool
== Char
':'
then Parser Int
forall a. Parser a
pfail
else Int -> Parser Int
forall (f :: * -> *) a. Applicative f => a -> f a
pure Int
str
pDate' :: Parser (Int, Maybe Int, Maybe Integer)
pDate' :: Parser (Int, Maybe Int, Maybe Integer)
pDate' =
(,,) (Int
-> Maybe Int -> Maybe Integer -> (Int, Maybe Int, Maybe Integer))
-> Parser Int
-> Parser
(Maybe Int -> Maybe Integer -> (Int, Maybe Int, Maybe Integer))
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Int -> Int -> Parser Int
pNumBetween Int
1 Int
31
Parser
(Maybe Int -> Maybe Integer -> (Int, Maybe Int, Maybe Integer))
-> Parser (Maybe Int)
-> Parser (Maybe Integer -> (Int, Maybe Int, Maybe Integer))
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Parser Int -> Parser (Maybe Int)
forall (f :: * -> *) a. Alternative f => f a -> f (Maybe a)
optional (Parser ()
skipSpaces Parser () -> Parser Int -> Parser Int
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f b
*> [Parser Int] -> Parser Int
forall a. [Parser a] -> Parser a
choice
[ Parser String -> String -> Int -> Parser Int
forall a. Parser String -> String -> a -> Parser a
pPrefix Parser String
"ja" String
"nuary" Int
1 , Parser String -> String -> Int -> Parser Int
forall a. Parser String -> String -> a -> Parser a
pPrefix Parser String
"f" String
"ebruary" Int
2
, Parser String -> String -> Int -> Parser Int
forall a. Parser String -> String -> a -> Parser a
pPrefix Parser String
"mar" String
"ch" Int
3 , Parser String -> String -> Int -> Parser Int
forall a. Parser String -> String -> a -> Parser a
pPrefix Parser String
"ap" String
"ril" Int
4
, Parser String -> String -> Int -> Parser Int
forall a. Parser String -> String -> a -> Parser a
pPrefix Parser String
"may" String
"" Int
5 , Parser String -> String -> Int -> Parser Int
forall a. Parser String -> String -> a -> Parser a
pPrefix Parser String
"jun" String
"e" Int
6
, Parser String -> String -> Int -> Parser Int
forall a. Parser String -> String -> a -> Parser a
pPrefix Parser String
"jul" String
"y" Int
7 , Parser String -> String -> Int -> Parser Int
forall a. Parser String -> String -> a -> Parser a
pPrefix Parser String
"au" String
"gust" Int
8
, Parser String -> String -> Int -> Parser Int
forall a. Parser String -> String -> a -> Parser a
pPrefix Parser String
"s" String
"eptember" Int
9 , Parser String -> String -> Int -> Parser Int
forall a. Parser String -> String -> a -> Parser a
pPrefix Parser String
"o" String
"ctober" Int
10
, Parser String -> String -> Int -> Parser Int
forall a. Parser String -> String -> a -> Parser a
pPrefix Parser String
"n" String
"ovember" Int
11, Parser String -> String -> Int -> Parser Int
forall a. Parser String -> String -> a -> Parser a
pPrefix Parser String
"d" String
"ecember" Int
12
, Parser Int
numWithoutColon
])
Parser (Maybe Integer -> (Int, Maybe Int, Maybe Integer))
-> Parser (Maybe Integer) -> Parser (Int, Maybe Int, Maybe Integer)
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Parser Integer -> Parser (Maybe Integer)
forall (f :: * -> *) a. Alternative f => f a -> f (Maybe a)
optional (Parser ()
skipSpaces Parser () -> Parser Integer -> Parser Integer
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f b
*> Parser Integer
forall a. (Read a, Integral a) => Parser a
num Parser Integer -> (Integer -> Parser Integer) -> Parser Integer
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= \Integer
i -> Bool -> Parser ()
forall (f :: * -> *). Alternative f => Bool -> f ()
guard (Integer
i Integer -> Integer -> Bool
forall a. Ord a => a -> a -> Bool
>= Integer
25) Parser () -> Integer -> Parser Integer
forall (f :: * -> *) a b. Functor f => f a -> b -> f b
$> Integer
i)
pPrefix :: Parser String -> String -> a -> Parser a
pPrefix :: forall a. Parser String -> String -> a -> Parser a
pPrefix Parser String
start String
leftover a
ret = do
Parser String -> Parser ()
forall (f :: * -> *) a. Functor f => f a -> f ()
void Parser String
start
String
l <- (Char -> Bool) -> Parser String
munch (Char -> Char -> Bool
forall a. Eq a => a -> a -> Bool
/= Char
' ')
Bool -> Parser ()
forall (f :: * -> *). Alternative f => Bool -> f ()
guard (String
l String -> String -> Bool
forall a. Eq a => [a] -> [a] -> Bool
`isPrefixOf` String
leftover)
a -> Parser a
forall (f :: * -> *) a. Applicative f => a -> f a
pure a
ret
pNumBetween :: Int -> Int -> Parser Int
pNumBetween :: Int -> Int -> Parser Int
pNumBetween Int
lo Int
hi = do
Int
n <- Parser Int
forall a. (Read a, Integral a) => Parser a
num
Int
n Int -> Parser () -> Parser Int
forall (f :: * -> *) a b. Functor f => a -> f b -> f a
<$ Bool -> Parser ()
forall (f :: * -> *). Alternative f => Bool -> f ()
guard (Int
n Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
>= Int
lo Bool -> Bool -> Bool
&& Int
n Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
<= Int
hi)
pLast :: Parser a -> Parser a -> Parser a
pLast :: forall a. Parser a -> Parser a -> Parser a
pLast Parser a
p Parser a
p' = Parser a
p' Parser a -> Parser a -> Parser a
forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> Parser a
p