{-# LANGUAGE DeriveDataTypeable, DeriveFunctor, FlexibleInstances, FlexibleContexts, MultiParamTypeClasses, TypeOperators, GeneralizedNewtypeDeriving, Trustworthy #-} module System.Console.Wizard.Haskeline ( UnexpectedEOF (..) , Haskeline , haskeline , withSettings , WithSettings(..) ) where import System.Console.Wizard import System.Console.Wizard.Internal import System.Console.Haskeline import Control.Monad.Trans import Control.Monad.Trans.Maybe import Control.Exception import Data.Typeable -- | The Haskeline back-end will throw this exception if EOF is encountered -- when it is not expected. Specifically, when actions such as 'getInputLine' return 'Nothing'. data UnexpectedEOF = UnexpectedEOF deriving (Show, Typeable) instance Exception UnexpectedEOF -- | Haskeline supports all the following features completely. newtype Haskeline a = Haskeline (( Output :+: OutputLn :+: Line :+: Character :+: LinePrewritten :+: Password :+: ArbitraryIO :+: WithSettings) a) deriving ( (:<:) Output , (:<:) OutputLn , (:<:) Line , (:<:) Character , (:<:) LinePrewritten , (:<:) Password , (:<:) ArbitraryIO , (:<:) WithSettings , Functor , Run (InputT IO) ) -- | Modifies a wizard so that it will run with different Haskeline 'Settings' to the top level input monad. withSettings :: (WithSettings :<: b) => Settings IO -> Wizard b a -> Wizard b a withSettings sets (Wizard (MaybeT v)) = Wizard $ MaybeT $ inject (WithSettings sets v) data WithSettings w = WithSettings (Settings IO) w deriving (Functor) instance Run (InputT IO) Output where runAlgebra (Output s w) = outputStr s >> w instance Run (InputT IO) OutputLn where runAlgebra (OutputLn s w) = outputStrLn s >> w instance Run (InputT IO) Line where runAlgebra (Line s w) = getInputLine s >>= mEof w instance Run (InputT IO) Character where runAlgebra (Character s w) = getInputChar s >>= mEof w instance Run (InputT IO) LinePrewritten where runAlgebra (LinePrewritten p s1 s2 w) = getInputLineWithInitial p (s1,s2) >>= mEof w instance Run (InputT IO) Password where runAlgebra (Password p mc w) = getPassword mc p >>= mEof w instance Run (InputT IO) ArbitraryIO where runAlgebra (ArbitraryIO iov f) = liftIO iov >>= f instance Run (InputT IO) WithSettings where runAlgebra (WithSettings sets w) = liftIO (runInputT sets w) mEof = maybe (throw UnexpectedEOF) -- | A simple identity function, used to restrict types if the type inferred by GHC is too general. -- You could achieve the same effect with a type signature, but this is slightly less typing. haskeline :: Wizard Haskeline a -> Wizard Haskeline a haskeline = id