-- | Provides the 'MonadHaskeline' typeclass.
--
-- @since 0.1
module Effects.Haskeline
  ( -- * Class
    MonadHaskeline (..),

    -- * ReaderT
    -- $readert

    -- * Runners
    runInputTEnv,
    runInputTEnvWith,

    -- * Haskeline Re-exports

    -- ** Types
    InputT,
    InputTEnv,

    -- ** IO Runners
    H.runInputT,
    H.runInputTBehavior,
    H.runInputTBehaviorWithPrefs,

    -- ** Config
    H.defaultSettings,
    H.defaultBehavior,
    H.defaultPrefs,
  )
where

import Control.Monad.Catch (MonadMask)
import Control.Monad.IO.Class (MonadIO)
import Control.Monad.Reader (ReaderT (ReaderT), runReaderT)
import Control.Monad.Reader.Class (MonadReader (ask))
import Control.Monad.Trans (MonadTrans (lift))
import GHC.Stack (HasCallStack)
import System.Console.Haskeline (InputT)
import System.Console.Haskeline qualified as H
import System.Console.Haskeline.History (History)
import System.Console.Haskeline.ReaderT (InputTEnv)
import System.Console.Haskeline.ReaderT qualified as HR

-- NOTE: We implement most of the effectful functions from
-- System.Console.Haskeline. What is missing is functions of the form
-- 'foo :: Input m a -> m a' i.e. they run the input to produce a result in the
-- underlying monad.
--
-- Ultimately, such functions like
--
--   runInputT :: Settings m -> InputT m a -> m a
--
-- do not make sense to mock anyway, since custom monads will implement
-- their own functions, and "real" code will call the real runInputT.

-- | Allows haskeline effects.
--
-- @since 0.1
class (Monad m) => MonadHaskeline m where
  -- | Lifted 'H.haveTerminalUI'.
  --
  -- @since 0.1
  haveTerminalUI :: (HasCallStack) => m Bool

  -- | Lifted 'H.getInputLine'.
  --
  -- @since 0.1
  getInputLine :: (HasCallStack) => String -> m (Maybe String)

  -- | Lifted 'H.getInputLineWithInitial'.
  --
  -- @since 0.1
  getInputLineWithInitial :: (HasCallStack) => String -> (String, String) -> m (Maybe String)

  -- | Lifted 'H.getInputChar'.
  --
  -- @since 0.1
  getInputChar :: (HasCallStack) => String -> m (Maybe Char)

  -- | Lifted 'H.getPassword'.
  --
  -- @since 0.1
  getPassword :: (HasCallStack) => Maybe Char -> String -> m (Maybe String)

  -- | Lifted 'H.waitForAnyKey'.
  --
  -- @since 0.1
  waitForAnyKey :: (HasCallStack) => String -> m Bool

  -- | Lifted 'H.outputStr'.
  --
  -- @since 0.1
  outputStr :: (HasCallStack) => String -> m ()

  -- | Lifted 'H.outputStrLn'.
  --
  -- @since 0.1
  outputStrLn :: (HasCallStack) => String -> m ()

  -- | Lifted 'H.getExternalPrint'.
  --
  -- @since 0.1
  getExternalPrint :: (HasCallStack) => m (String -> IO ())

  -- | Lifted 'H.getHistory'.
  --
  -- @since 0.1
  getHistory :: (HasCallStack) => m History

  -- | Lifted 'H.putHistory'.
  --
  -- @since 0.1
  putHistory :: (HasCallStack) => History -> m ()

  -- | Lifted 'H.modifyHistory'.
  --
  -- @since 0.1
  modifyHistory :: (HasCallStack) => (History -> History) -> m ()

  -- | Lifted 'H.withInterrupt'.
  --
  -- @since 0.1
  withInterrupt :: (HasCallStack) => m a -> m a

  -- | Lifted 'H.handleInterrupt'.
  --
  -- @since 0.1
  handleInterrupt :: (HasCallStack) => m a -> m a -> m a

-- | @since 0.1
instance (MonadIO m, MonadMask m) => MonadHaskeline (InputT m) where
  haveTerminalUI :: HasCallStack => InputT m Bool
haveTerminalUI = InputT m Bool
forall (m :: * -> *). Monad m => InputT m Bool
H.haveTerminalUI
  {-# INLINEABLE haveTerminalUI #-}
  getInputLine :: HasCallStack => String -> InputT m (Maybe String)
getInputLine = String -> InputT m (Maybe String)
forall (m :: * -> *).
(MonadIO m, MonadMask m) =>
String -> InputT m (Maybe String)
H.getInputLine
  {-# INLINEABLE getInputLine #-}
  getInputLineWithInitial :: HasCallStack =>
String -> (String, String) -> InputT m (Maybe String)
getInputLineWithInitial = String -> (String, String) -> InputT m (Maybe String)
forall (m :: * -> *).
(MonadIO m, MonadMask m) =>
String -> (String, String) -> InputT m (Maybe String)
H.getInputLineWithInitial
  {-# INLINEABLE getInputLineWithInitial #-}
  getInputChar :: HasCallStack => String -> InputT m (Maybe Char)
getInputChar = String -> InputT m (Maybe Char)
forall (m :: * -> *).
(MonadIO m, MonadMask m) =>
String -> InputT m (Maybe Char)
H.getInputChar
  {-# INLINEABLE getInputChar #-}
  getPassword :: HasCallStack => Maybe Char -> String -> InputT m (Maybe String)
getPassword = Maybe Char -> String -> InputT m (Maybe String)
forall (m :: * -> *).
(MonadIO m, MonadMask m) =>
Maybe Char -> String -> InputT m (Maybe String)
H.getPassword
  {-# INLINEABLE getPassword #-}
  waitForAnyKey :: HasCallStack => String -> InputT m Bool
waitForAnyKey = String -> InputT m Bool
forall (m :: * -> *).
(MonadIO m, MonadMask m) =>
String -> InputT m Bool
H.waitForAnyKey
  {-# INLINEABLE waitForAnyKey #-}
  outputStr :: HasCallStack => String -> InputT m ()
outputStr = String -> InputT m ()
forall (m :: * -> *). MonadIO m => String -> InputT m ()
H.outputStr
  {-# INLINEABLE outputStr #-}
  outputStrLn :: HasCallStack => String -> InputT m ()
outputStrLn = String -> InputT m ()
forall (m :: * -> *). MonadIO m => String -> InputT m ()
H.outputStrLn
  {-# INLINEABLE outputStrLn #-}
  getExternalPrint :: HasCallStack => InputT m (String -> IO ())
getExternalPrint = InputT m (String -> IO ())
forall (m :: * -> *). MonadIO m => InputT m (String -> IO ())
H.getExternalPrint
  {-# INLINEABLE getExternalPrint #-}
  getHistory :: HasCallStack => InputT m History
getHistory = InputT m History
forall (m :: * -> *). MonadIO m => InputT m History
H.getHistory
  {-# INLINEABLE getHistory #-}
  putHistory :: HasCallStack => History -> InputT m ()
putHistory = History -> InputT m ()
forall (m :: * -> *). MonadIO m => History -> InputT m ()
H.putHistory
  {-# INLINEABLE putHistory #-}
  modifyHistory :: HasCallStack => (History -> History) -> InputT m ()
modifyHistory = (History -> History) -> InputT m ()
forall (m :: * -> *).
MonadIO m =>
(History -> History) -> InputT m ()
H.modifyHistory
  {-# INLINEABLE modifyHistory #-}
  withInterrupt :: forall a. HasCallStack => InputT m a -> InputT m a
withInterrupt = InputT m a -> InputT m a
forall (m :: * -> *) a.
(MonadIO m, MonadMask m) =>
InputT m a -> InputT m a
H.withInterrupt
  {-# INLINEABLE withInterrupt #-}
  handleInterrupt :: forall a. HasCallStack => InputT m a -> InputT m a -> InputT m a
handleInterrupt = InputT m a -> InputT m a -> InputT m a
forall (m :: * -> *) a. MonadMask m => m a -> m a -> m a
H.handleInterrupt
  {-# INLINEABLE handleInterrupt #-}

-- $readert
--
-- We provide two (overlapping) 'Control.Monad.Reader.ReaderT' instances:
-- A standard instance i.e.
--
-- @
--   instance ('MonadHaskeline' m) => 'MonadHaskeline' ('Control.Monad.Reader.ReaderT.ReaderT' e m)
-- @
--
-- And one in terms of the concrete (abstract) haskeline environment:
--
-- @
--   instance 'MonadHaskeline' ('Control.Monad.Reader.ReaderT.ReaderT' ('InputTEnv' m) m)
-- @
--
-- The latter is the intended way to run the application in real code:
--
-- @
--   run :: ('MonadHaskeline' m, ...) => m ()
--
--   -- Uses 'Control.Monad.Reader.ReaderT.ReaderT' ('InputTEnv' m) instance
--   main :: IO ()
--   main = 'runInputTDefault' 'runReaderT' run
-- @
--
-- On the other hand, the former is useful for deriving e.g.
--
-- @
--   newtype AppT e m a = MkAppT {unAppT :: 'Control.Monad.Reader.ReaderT.ReaderT' e m a }
--     deriving ('Applicative', 'Functor', 'Monad') via ('Control.Monad.Reader.ReaderT.ReaderT' e m)
--
--   deriving instance ('MonadHaskeline' m) => 'MonadHaskeline' (AppT env m)
-- @
--
-- This allows typical usage with some custom type that picks up the
-- instances automatically.

-- | @since 0.1
instance {-# OVERLAPPABLE #-} (MonadHaskeline m) => MonadHaskeline (ReaderT e m) where
  haveTerminalUI :: HasCallStack => ReaderT e m Bool
haveTerminalUI = m Bool -> ReaderT e m Bool
forall (m :: * -> *) a. Monad m => m a -> ReaderT e m a
forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift m Bool
forall (m :: * -> *). (MonadHaskeline m, HasCallStack) => m Bool
haveTerminalUI
  {-# INLINEABLE haveTerminalUI #-}
  getInputLine :: HasCallStack => String -> ReaderT e m (Maybe String)
getInputLine = m (Maybe String) -> ReaderT e m (Maybe String)
forall (m :: * -> *) a. Monad m => m a -> ReaderT e m a
forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift (m (Maybe String) -> ReaderT e m (Maybe String))
-> (String -> m (Maybe String))
-> String
-> ReaderT e m (Maybe String)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. String -> m (Maybe String)
forall (m :: * -> *).
(MonadHaskeline m, HasCallStack) =>
String -> m (Maybe String)
getInputLine
  {-# INLINEABLE getInputLine #-}
  getInputLineWithInitial :: HasCallStack =>
String -> (String, String) -> ReaderT e m (Maybe String)
getInputLineWithInitial String
s = m (Maybe String) -> ReaderT e m (Maybe String)
forall (m :: * -> *) a. Monad m => m a -> ReaderT e m a
forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift (m (Maybe String) -> ReaderT e m (Maybe String))
-> ((String, String) -> m (Maybe String))
-> (String, String)
-> ReaderT e m (Maybe String)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. String -> (String, String) -> m (Maybe String)
forall (m :: * -> *).
(MonadHaskeline m, HasCallStack) =>
String -> (String, String) -> m (Maybe String)
getInputLineWithInitial String
s
  {-# INLINEABLE getInputLineWithInitial #-}
  getInputChar :: HasCallStack => String -> ReaderT e m (Maybe Char)
getInputChar = m (Maybe Char) -> ReaderT e m (Maybe Char)
forall (m :: * -> *) a. Monad m => m a -> ReaderT e m a
forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift (m (Maybe Char) -> ReaderT e m (Maybe Char))
-> (String -> m (Maybe Char)) -> String -> ReaderT e m (Maybe Char)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. String -> m (Maybe Char)
forall (m :: * -> *).
(MonadHaskeline m, HasCallStack) =>
String -> m (Maybe Char)
getInputChar
  {-# INLINEABLE getInputChar #-}
  getPassword :: HasCallStack => Maybe Char -> String -> ReaderT e m (Maybe String)
getPassword Maybe Char
c = m (Maybe String) -> ReaderT e m (Maybe String)
forall (m :: * -> *) a. Monad m => m a -> ReaderT e m a
forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift (m (Maybe String) -> ReaderT e m (Maybe String))
-> (String -> m (Maybe String))
-> String
-> ReaderT e m (Maybe String)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Maybe Char -> String -> m (Maybe String)
forall (m :: * -> *).
(MonadHaskeline m, HasCallStack) =>
Maybe Char -> String -> m (Maybe String)
getPassword Maybe Char
c
  {-# INLINEABLE getPassword #-}
  waitForAnyKey :: HasCallStack => String -> ReaderT e m Bool
waitForAnyKey = m Bool -> ReaderT e m Bool
forall (m :: * -> *) a. Monad m => m a -> ReaderT e m a
forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift (m Bool -> ReaderT e m Bool)
-> (String -> m Bool) -> String -> ReaderT e m Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. String -> m Bool
forall (m :: * -> *).
(MonadHaskeline m, HasCallStack) =>
String -> m Bool
waitForAnyKey
  {-# INLINEABLE waitForAnyKey #-}
  outputStr :: HasCallStack => String -> ReaderT e m ()
outputStr = m () -> ReaderT e m ()
forall (m :: * -> *) a. Monad m => m a -> ReaderT e m a
forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift (m () -> ReaderT e m ())
-> (String -> m ()) -> String -> ReaderT e m ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. String -> m ()
forall (m :: * -> *).
(MonadHaskeline m, HasCallStack) =>
String -> m ()
outputStr
  {-# INLINEABLE outputStr #-}
  outputStrLn :: HasCallStack => String -> ReaderT e m ()
outputStrLn = m () -> ReaderT e m ()
forall (m :: * -> *) a. Monad m => m a -> ReaderT e m a
forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift (m () -> ReaderT e m ())
-> (String -> m ()) -> String -> ReaderT e m ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. String -> m ()
forall (m :: * -> *).
(MonadHaskeline m, HasCallStack) =>
String -> m ()
outputStrLn
  {-# INLINEABLE outputStrLn #-}
  getExternalPrint :: HasCallStack => ReaderT e m (String -> IO ())
getExternalPrint = m (String -> IO ()) -> ReaderT e m (String -> IO ())
forall (m :: * -> *) a. Monad m => m a -> ReaderT e m a
forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift m (String -> IO ())
forall (m :: * -> *).
(MonadHaskeline m, HasCallStack) =>
m (String -> IO ())
getExternalPrint
  {-# INLINEABLE getExternalPrint #-}
  getHistory :: HasCallStack => ReaderT e m History
getHistory = m History -> ReaderT e m History
forall (m :: * -> *) a. Monad m => m a -> ReaderT e m a
forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift m History
forall (m :: * -> *). (MonadHaskeline m, HasCallStack) => m History
getHistory
  {-# INLINEABLE getHistory #-}
  putHistory :: HasCallStack => History -> ReaderT e m ()
putHistory = m () -> ReaderT e m ()
forall (m :: * -> *) a. Monad m => m a -> ReaderT e m a
forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift (m () -> ReaderT e m ())
-> (History -> m ()) -> History -> ReaderT e m ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. History -> m ()
forall (m :: * -> *).
(MonadHaskeline m, HasCallStack) =>
History -> m ()
putHistory
  {-# INLINEABLE putHistory #-}
  modifyHistory :: HasCallStack => (History -> History) -> ReaderT e m ()
modifyHistory = m () -> ReaderT e m ()
forall (m :: * -> *) a. Monad m => m a -> ReaderT e m a
forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift (m () -> ReaderT e m ())
-> ((History -> History) -> m ())
-> (History -> History)
-> ReaderT e m ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (History -> History) -> m ()
forall (m :: * -> *).
(MonadHaskeline m, HasCallStack) =>
(History -> History) -> m ()
modifyHistory
  {-# INLINEABLE modifyHistory #-}
  withInterrupt :: forall a. HasCallStack => ReaderT e m a -> ReaderT e m a
withInterrupt ReaderT e m a
rdr = ReaderT e m e
forall r (m :: * -> *). MonadReader r m => m r
ask ReaderT e m e -> (e -> ReaderT e m a) -> ReaderT e m a
forall a b. ReaderT e m a -> (a -> ReaderT e m b) -> ReaderT e m b
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= \e
env -> m a -> ReaderT e m a
forall (m :: * -> *) a. Monad m => m a -> ReaderT e m a
forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift (m a -> ReaderT e m a) -> m a -> ReaderT e m a
forall a b. (a -> b) -> a -> b
$ m a -> m a
forall a. HasCallStack => m a -> m a
forall (m :: * -> *) a.
(MonadHaskeline m, HasCallStack) =>
m a -> m a
withInterrupt (m a -> m a) -> m a -> m a
forall a b. (a -> b) -> a -> b
$ ReaderT e m a -> e -> m a
forall r (m :: * -> *) a. ReaderT r m a -> r -> m a
runReaderT ReaderT e m a
rdr e
env
  {-# INLINEABLE withInterrupt #-}
  handleInterrupt :: forall a.
HasCallStack =>
ReaderT e m a -> ReaderT e m a -> ReaderT e m a
handleInterrupt ReaderT e m a
m1 ReaderT e m a
m2 =
    ReaderT e m e
forall r (m :: * -> *). MonadReader r m => m r
ask ReaderT e m e -> (e -> ReaderT e m a) -> ReaderT e m a
forall a b. ReaderT e m a -> (a -> ReaderT e m b) -> ReaderT e m b
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= \e
env ->
      m a -> ReaderT e m a
forall (m :: * -> *) a. Monad m => m a -> ReaderT e m a
forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift (m a -> ReaderT e m a) -> m a -> ReaderT e m a
forall a b. (a -> b) -> a -> b
$ m a -> m a -> m a
forall a. HasCallStack => m a -> m a -> m a
forall (m :: * -> *) a.
(MonadHaskeline m, HasCallStack) =>
m a -> m a -> m a
handleInterrupt (ReaderT e m a -> e -> m a
forall r (m :: * -> *) a. ReaderT r m a -> r -> m a
runReaderT ReaderT e m a
m1 e
env) (ReaderT e m a -> e -> m a
forall r (m :: * -> *) a. ReaderT r m a -> r -> m a
runReaderT ReaderT e m a
m2 e
env)
  {-# INLINEABLE handleInterrupt #-}

-- | @since 0.1
instance {-# OVERLAPPING #-} (MonadIO m, MonadMask m) => MonadHaskeline (ReaderT (InputTEnv m) m) where
  haveTerminalUI :: HasCallStack => ReaderT (InputTEnv m) m Bool
haveTerminalUI = InputT m Bool -> ReaderT (InputTEnv m) m Bool
forall (m :: * -> *) a. InputT m a -> ReaderT (InputTEnv m) m a
liftReaderT InputT m Bool
forall (m :: * -> *). Monad m => InputT m Bool
H.haveTerminalUI
  {-# INLINEABLE haveTerminalUI #-}
  getInputLine :: HasCallStack => String -> ReaderT (InputTEnv m) m (Maybe String)
getInputLine = InputT m (Maybe String) -> ReaderT (InputTEnv m) m (Maybe String)
forall (m :: * -> *) a. InputT m a -> ReaderT (InputTEnv m) m a
liftReaderT (InputT m (Maybe String) -> ReaderT (InputTEnv m) m (Maybe String))
-> (String -> InputT m (Maybe String))
-> String
-> ReaderT (InputTEnv m) m (Maybe String)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. String -> InputT m (Maybe String)
forall (m :: * -> *).
(MonadIO m, MonadMask m) =>
String -> InputT m (Maybe String)
H.getInputLine
  {-# INLINEABLE getInputLine #-}
  getInputLineWithInitial :: HasCallStack =>
String
-> (String, String) -> ReaderT (InputTEnv m) m (Maybe String)
getInputLineWithInitial String
s = InputT m (Maybe String) -> ReaderT (InputTEnv m) m (Maybe String)
forall (m :: * -> *) a. InputT m a -> ReaderT (InputTEnv m) m a
liftReaderT (InputT m (Maybe String) -> ReaderT (InputTEnv m) m (Maybe String))
-> ((String, String) -> InputT m (Maybe String))
-> (String, String)
-> ReaderT (InputTEnv m) m (Maybe String)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. String -> (String, String) -> InputT m (Maybe String)
forall (m :: * -> *).
(MonadIO m, MonadMask m) =>
String -> (String, String) -> InputT m (Maybe String)
H.getInputLineWithInitial String
s
  {-# INLINEABLE getInputLineWithInitial #-}
  getInputChar :: HasCallStack => String -> ReaderT (InputTEnv m) m (Maybe Char)
getInputChar = InputT m (Maybe Char) -> ReaderT (InputTEnv m) m (Maybe Char)
forall (m :: * -> *) a. InputT m a -> ReaderT (InputTEnv m) m a
liftReaderT (InputT m (Maybe Char) -> ReaderT (InputTEnv m) m (Maybe Char))
-> (String -> InputT m (Maybe Char))
-> String
-> ReaderT (InputTEnv m) m (Maybe Char)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. String -> InputT m (Maybe Char)
forall (m :: * -> *).
(MonadIO m, MonadMask m) =>
String -> InputT m (Maybe Char)
H.getInputChar
  {-# INLINEABLE getInputChar #-}
  getPassword :: HasCallStack =>
Maybe Char -> String -> ReaderT (InputTEnv m) m (Maybe String)
getPassword Maybe Char
c = InputT m (Maybe String) -> ReaderT (InputTEnv m) m (Maybe String)
forall (m :: * -> *) a. InputT m a -> ReaderT (InputTEnv m) m a
liftReaderT (InputT m (Maybe String) -> ReaderT (InputTEnv m) m (Maybe String))
-> (String -> InputT m (Maybe String))
-> String
-> ReaderT (InputTEnv m) m (Maybe String)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Maybe Char -> String -> InputT m (Maybe String)
forall (m :: * -> *).
(MonadIO m, MonadMask m) =>
Maybe Char -> String -> InputT m (Maybe String)
H.getPassword Maybe Char
c
  {-# INLINEABLE getPassword #-}
  waitForAnyKey :: HasCallStack => String -> ReaderT (InputTEnv m) m Bool
waitForAnyKey = InputT m Bool -> ReaderT (InputTEnv m) m Bool
forall (m :: * -> *) a. InputT m a -> ReaderT (InputTEnv m) m a
liftReaderT (InputT m Bool -> ReaderT (InputTEnv m) m Bool)
-> (String -> InputT m Bool)
-> String
-> ReaderT (InputTEnv m) m Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. String -> InputT m Bool
forall (m :: * -> *).
(MonadIO m, MonadMask m) =>
String -> InputT m Bool
H.waitForAnyKey
  {-# INLINEABLE waitForAnyKey #-}
  outputStr :: HasCallStack => String -> ReaderT (InputTEnv m) m ()
outputStr = InputT m () -> ReaderT (InputTEnv m) m ()
forall (m :: * -> *) a. InputT m a -> ReaderT (InputTEnv m) m a
liftReaderT (InputT m () -> ReaderT (InputTEnv m) m ())
-> (String -> InputT m ()) -> String -> ReaderT (InputTEnv m) m ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. String -> InputT m ()
forall (m :: * -> *). MonadIO m => String -> InputT m ()
H.outputStr
  {-# INLINEABLE outputStr #-}
  outputStrLn :: HasCallStack => String -> ReaderT (InputTEnv m) m ()
outputStrLn = InputT m () -> ReaderT (InputTEnv m) m ()
forall (m :: * -> *) a. InputT m a -> ReaderT (InputTEnv m) m a
liftReaderT (InputT m () -> ReaderT (InputTEnv m) m ())
-> (String -> InputT m ()) -> String -> ReaderT (InputTEnv m) m ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. String -> InputT m ()
forall (m :: * -> *). MonadIO m => String -> InputT m ()
H.outputStrLn
  {-# INLINEABLE outputStrLn #-}
  getExternalPrint :: HasCallStack => ReaderT (InputTEnv m) m (String -> IO ())
getExternalPrint = InputT m (String -> IO ())
-> ReaderT (InputTEnv m) m (String -> IO ())
forall (m :: * -> *) a. InputT m a -> ReaderT (InputTEnv m) m a
liftReaderT InputT m (String -> IO ())
forall (m :: * -> *). MonadIO m => InputT m (String -> IO ())
H.getExternalPrint
  {-# INLINEABLE getExternalPrint #-}
  getHistory :: HasCallStack => ReaderT (InputTEnv m) m History
getHistory = InputT m History -> ReaderT (InputTEnv m) m History
forall (m :: * -> *) a. InputT m a -> ReaderT (InputTEnv m) m a
liftReaderT InputT m History
forall (m :: * -> *). MonadIO m => InputT m History
H.getHistory
  {-# INLINEABLE getHistory #-}
  putHistory :: HasCallStack => History -> ReaderT (InputTEnv m) m ()
putHistory = InputT m () -> ReaderT (InputTEnv m) m ()
forall (m :: * -> *) a. InputT m a -> ReaderT (InputTEnv m) m a
liftReaderT (InputT m () -> ReaderT (InputTEnv m) m ())
-> (History -> InputT m ())
-> History
-> ReaderT (InputTEnv m) m ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. History -> InputT m ()
forall (m :: * -> *). MonadIO m => History -> InputT m ()
H.putHistory
  {-# INLINEABLE putHistory #-}
  modifyHistory :: HasCallStack => (History -> History) -> ReaderT (InputTEnv m) m ()
modifyHistory = InputT m () -> ReaderT (InputTEnv m) m ()
forall (m :: * -> *) a. InputT m a -> ReaderT (InputTEnv m) m a
liftReaderT (InputT m () -> ReaderT (InputTEnv m) m ())
-> ((History -> History) -> InputT m ())
-> (History -> History)
-> ReaderT (InputTEnv m) m ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (History -> History) -> InputT m ()
forall (m :: * -> *).
MonadIO m =>
(History -> History) -> InputT m ()
H.modifyHistory
  {-# INLINEABLE modifyHistory #-}
  withInterrupt :: forall a.
HasCallStack =>
ReaderT (InputTEnv m) m a -> ReaderT (InputTEnv m) m a
withInterrupt ReaderT (InputTEnv m) m a
r = ReaderT (InputTEnv m) m (InputTEnv m)
forall r (m :: * -> *). MonadReader r m => m r
ask ReaderT (InputTEnv m) m (InputTEnv m)
-> (InputTEnv m -> ReaderT (InputTEnv m) m a)
-> ReaderT (InputTEnv m) m a
forall a b.
ReaderT (InputTEnv m) m a
-> (a -> ReaderT (InputTEnv m) m b) -> ReaderT (InputTEnv m) m b
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= InputT m a -> ReaderT (InputTEnv m) m a
forall (m :: * -> *) a. InputT m a -> ReaderT (InputTEnv m) m a
liftReaderT (InputT m a -> ReaderT (InputTEnv m) m a)
-> (InputTEnv m -> InputT m a)
-> InputTEnv m
-> ReaderT (InputTEnv m) m a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. InputT m a -> InputT m a
forall (m :: * -> *) a.
(MonadIO m, MonadMask m) =>
InputT m a -> InputT m a
H.withInterrupt (InputT m a -> InputT m a)
-> (InputTEnv m -> InputT m a) -> InputTEnv m -> InputT m a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. m a -> InputT m a
forall (m :: * -> *) a. Monad m => m a -> InputT m a
forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift (m a -> InputT m a)
-> (InputTEnv m -> m a) -> InputTEnv m -> InputT m a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ReaderT (InputTEnv m) m a -> InputTEnv m -> m a
forall r (m :: * -> *) a. ReaderT r m a -> r -> m a
runReaderT ReaderT (InputTEnv m) m a
r
  {-# INLINEABLE withInterrupt #-}
  handleInterrupt :: forall a.
HasCallStack =>
ReaderT (InputTEnv m) m a
-> ReaderT (InputTEnv m) m a -> ReaderT (InputTEnv m) m a
handleInterrupt ReaderT (InputTEnv m) m a
r1 ReaderT (InputTEnv m) m a
r2 = do
    env <- ReaderT (InputTEnv m) m (InputTEnv m)
forall r (m :: * -> *). MonadReader r m => m r
ask
    liftReaderT $
      H.handleInterrupt
        (lift $ runReaderT r1 env)
        (lift $ runReaderT r2 env)
  {-# INLINEABLE handleInterrupt #-}

liftReaderT :: InputT m a -> ReaderT (InputTEnv m) m a
liftReaderT :: forall (m :: * -> *) a. InputT m a -> ReaderT (InputTEnv m) m a
liftReaderT = InputT m a -> ReaderT (InputTEnv m) m a
forall (m :: * -> *) a. InputT m a -> ReaderT (InputTEnv m) m a
HR.toReaderT
{-# INLINEABLE liftReaderT #-}

-- | 'runInputTWith' with default haskeline settings.
--
-- @since 0.1
runInputTEnv :: (MonadIO m, MonadMask m) => (InputTEnv m -> m a) -> m a
runInputTEnv :: forall (m :: * -> *) a.
(MonadIO m, MonadMask m) =>
(InputTEnv m -> m a) -> m a
runInputTEnv = (InputT m a -> m a) -> (InputTEnv m -> m a) -> m a
forall (m :: * -> *) a.
(InputT m a -> m a) -> (InputTEnv m -> m a) -> m a
runInputTEnvWith (Settings m -> InputT m a -> m a
forall (m :: * -> *) a.
(MonadIO m, MonadMask m) =>
Settings m -> InputT m a -> m a
H.runInputT Settings m
forall (m :: * -> *). MonadIO m => Settings m
H.defaultSettings)
{-# INLINEABLE runInputTEnv #-}

-- | Runs 'Control.Monad.Reader.ReaderT' 'InputTEnv' in 'IO' with 'InputT'
-- runner.
--
-- @since 0.1
runInputTEnvWith ::
  -- | 'InputT' Runner.
  (InputT m a -> m a) ->
  -- | Action.
  (InputTEnv m -> m a) ->
  -- | IO Result.
  m a
runInputTEnvWith :: forall (m :: * -> *) a.
(InputT m a -> m a) -> (InputTEnv m -> m a) -> m a
runInputTEnvWith InputT m a -> m a
runInput InputTEnv m -> m a
onEnv = InputT m a -> m a
runInput (InputT m a -> m a) -> InputT m a -> m a
forall a b. (a -> b) -> a -> b
$ ReaderT (InputTEnv m) m a -> InputT m a
forall (m :: * -> *) a. ReaderT (InputTEnv m) m a -> InputT m a
HR.fromReaderT (ReaderT (InputTEnv m) m a -> InputT m a)
-> ReaderT (InputTEnv m) m a -> InputT m a
forall a b. (a -> b) -> a -> b
$ (InputTEnv m -> m a) -> ReaderT (InputTEnv m) m a
forall r (m :: * -> *) a. (r -> m a) -> ReaderT r m a
ReaderT InputTEnv m -> m a
onEnv
{-# INLINEABLE runInputTEnvWith #-}