module System.Console.Haskeline.InputT where


import System.Console.Haskeline.History
import System.Console.Haskeline.Command.History
import System.Console.Haskeline.Command.Undo
import System.Console.Haskeline.Command.KillRing
import System.Console.Haskeline.Monads as Monads
import System.Console.Haskeline.Prefs
import System.Console.Haskeline.Completion
import System.Console.Haskeline.Backend
import System.Console.Haskeline.Term

import Control.Exception (IOException)
import Control.Monad.Catch
import Control.Monad.Fix
import Data.IORef
import System.Directory(getHomeDirectory)
import System.FilePath
import System.IO

-- | Application-specific customizations to the user interface.
data Settings m = Settings {Settings m -> CompletionFunc m
complete :: CompletionFunc m, -- ^ Custom tab completion.
                            Settings m -> Maybe FilePath
historyFile :: Maybe FilePath, -- ^ Where to read/write the history at the
                                                        -- start and end of each
                                                        -- line input session.
                            Settings m -> Bool
autoAddHistory :: Bool -- ^ If 'True', each nonblank line returned by
                                -- @getInputLine@ will be automatically added to the history.

                            }

-- | Because 'complete' is the only field of 'Settings' depending on @m@,
-- the expression @defaultSettings {completionFunc = f}@ leads to a type error
-- from being too general.  This function works around that issue, and may become unnecessary if another field
-- depending on @m@ is added.

setComplete :: CompletionFunc m -> Settings m -> Settings m
setComplete :: CompletionFunc m -> Settings m -> Settings m
setComplete CompletionFunc m
f Settings m
s = Settings m
s {complete :: CompletionFunc m
complete = CompletionFunc m
f}


-- | A monad transformer which carries all of the state and settings
-- relevant to a line-reading application.
newtype InputT m a = InputT {InputT m a
-> ReaderT
     RunTerm
     (ReaderT
        (IORef History)
        (ReaderT
           (IORef KillRing) (ReaderT Prefs (ReaderT (Settings m) m))))
     a
unInputT :: 
                                ReaderT RunTerm
                                -- Use ReaderT (IO _) vs StateT so that exceptions (e.g., ctrl-c)
                                -- don't cause us to lose the existing state.
                                (ReaderT (IORef History)
                                (ReaderT (IORef KillRing)
                                (ReaderT Prefs
                                (ReaderT (Settings m) m)))) a}
                            deriving (a -> InputT m b -> InputT m a
(a -> b) -> InputT m a -> InputT m b
(forall a b. (a -> b) -> InputT m a -> InputT m b)
-> (forall a b. a -> InputT m b -> InputT m a)
-> Functor (InputT m)
forall a b. a -> InputT m b -> InputT m a
forall a b. (a -> b) -> InputT m a -> InputT m b
forall (m :: * -> *) a b.
Functor m =>
a -> InputT m b -> InputT m a
forall (m :: * -> *) a b.
Functor m =>
(a -> b) -> InputT m a -> InputT m b
forall (f :: * -> *).
(forall a b. (a -> b) -> f a -> f b)
-> (forall a b. a -> f b -> f a) -> Functor f
<$ :: a -> InputT m b -> InputT m a
$c<$ :: forall (m :: * -> *) a b.
Functor m =>
a -> InputT m b -> InputT m a
fmap :: (a -> b) -> InputT m a -> InputT m b
$cfmap :: forall (m :: * -> *) a b.
Functor m =>
(a -> b) -> InputT m a -> InputT m b
Functor, Functor (InputT m)
a -> InputT m a
Functor (InputT m)
-> (forall a. a -> InputT m a)
-> (forall a b. InputT m (a -> b) -> InputT m a -> InputT m b)
-> (forall a b c.
    (a -> b -> c) -> InputT m a -> InputT m b -> InputT m c)
-> (forall a b. InputT m a -> InputT m b -> InputT m b)
-> (forall a b. InputT m a -> InputT m b -> InputT m a)
-> Applicative (InputT m)
InputT m a -> InputT m b -> InputT m b
InputT m a -> InputT m b -> InputT m a
InputT m (a -> b) -> InputT m a -> InputT m b
(a -> b -> c) -> InputT m a -> InputT m b -> InputT m c
forall a. a -> InputT m a
forall a b. InputT m a -> InputT m b -> InputT m a
forall a b. InputT m a -> InputT m b -> InputT m b
forall a b. InputT m (a -> b) -> InputT m a -> InputT m b
forall a b c.
(a -> b -> c) -> InputT m a -> InputT m b -> InputT m c
forall (f :: * -> *).
Functor f
-> (forall a. a -> f a)
-> (forall a b. f (a -> b) -> f a -> f b)
-> (forall a b c. (a -> b -> c) -> f a -> f b -> f c)
-> (forall a b. f a -> f b -> f b)
-> (forall a b. f a -> f b -> f a)
-> Applicative f
forall (m :: * -> *). Applicative m => Functor (InputT m)
forall (m :: * -> *) a. Applicative m => a -> InputT m a
forall (m :: * -> *) a b.
Applicative m =>
InputT m a -> InputT m b -> InputT m a
forall (m :: * -> *) a b.
Applicative m =>
InputT m a -> InputT m b -> InputT m b
forall (m :: * -> *) a b.
Applicative m =>
InputT m (a -> b) -> InputT m a -> InputT m b
forall (m :: * -> *) a b c.
Applicative m =>
(a -> b -> c) -> InputT m a -> InputT m b -> InputT m c
<* :: InputT m a -> InputT m b -> InputT m a
$c<* :: forall (m :: * -> *) a b.
Applicative m =>
InputT m a -> InputT m b -> InputT m a
*> :: InputT m a -> InputT m b -> InputT m b
$c*> :: forall (m :: * -> *) a b.
Applicative m =>
InputT m a -> InputT m b -> InputT m b
liftA2 :: (a -> b -> c) -> InputT m a -> InputT m b -> InputT m c
$cliftA2 :: forall (m :: * -> *) a b c.
Applicative m =>
(a -> b -> c) -> InputT m a -> InputT m b -> InputT m c
<*> :: InputT m (a -> b) -> InputT m a -> InputT m b
$c<*> :: forall (m :: * -> *) a b.
Applicative m =>
InputT m (a -> b) -> InputT m a -> InputT m b
pure :: a -> InputT m a
$cpure :: forall (m :: * -> *) a. Applicative m => a -> InputT m a
$cp1Applicative :: forall (m :: * -> *). Applicative m => Functor (InputT m)
Applicative, Applicative (InputT m)
a -> InputT m a
Applicative (InputT m)
-> (forall a b. InputT m a -> (a -> InputT m b) -> InputT m b)
-> (forall a b. InputT m a -> InputT m b -> InputT m b)
-> (forall a. a -> InputT m a)
-> Monad (InputT m)
InputT m a -> (a -> InputT m b) -> InputT m b
InputT m a -> InputT m b -> InputT m b
forall a. a -> InputT m a
forall a b. InputT m a -> InputT m b -> InputT m b
forall a b. InputT m a -> (a -> InputT m b) -> InputT m b
forall (m :: * -> *). Monad m => Applicative (InputT m)
forall (m :: * -> *) a. Monad m => a -> InputT m a
forall (m :: * -> *) a b.
Monad m =>
InputT m a -> InputT m b -> InputT m b
forall (m :: * -> *) a b.
Monad m =>
InputT m a -> (a -> InputT m b) -> InputT m b
forall (m :: * -> *).
Applicative m
-> (forall a b. m a -> (a -> m b) -> m b)
-> (forall a b. m a -> m b -> m b)
-> (forall a. a -> m a)
-> Monad m
return :: a -> InputT m a
$creturn :: forall (m :: * -> *) a. Monad m => a -> InputT m a
>> :: InputT m a -> InputT m b -> InputT m b
$c>> :: forall (m :: * -> *) a b.
Monad m =>
InputT m a -> InputT m b -> InputT m b
>>= :: InputT m a -> (a -> InputT m b) -> InputT m b
$c>>= :: forall (m :: * -> *) a b.
Monad m =>
InputT m a -> (a -> InputT m b) -> InputT m b
$cp1Monad :: forall (m :: * -> *). Monad m => Applicative (InputT m)
Monad, Monad (InputT m)
Monad (InputT m)
-> (forall a. IO a -> InputT m a) -> MonadIO (InputT m)
IO a -> InputT m a
forall a. IO a -> InputT m a
forall (m :: * -> *).
Monad m -> (forall a. IO a -> m a) -> MonadIO m
forall (m :: * -> *). MonadIO m => Monad (InputT m)
forall (m :: * -> *) a. MonadIO m => IO a -> InputT m a
liftIO :: IO a -> InputT m a
$cliftIO :: forall (m :: * -> *) a. MonadIO m => IO a -> InputT m a
$cp1MonadIO :: forall (m :: * -> *). MonadIO m => Monad (InputT m)
MonadIO,
                                      Monad (InputT m)
e -> InputT m a
Monad (InputT m)
-> (forall e a. Exception e => e -> InputT m a)
-> MonadThrow (InputT m)
forall e a. Exception e => e -> InputT m a
forall (m :: * -> *).
Monad m -> (forall e a. Exception e => e -> m a) -> MonadThrow m
forall (m :: * -> *). MonadThrow m => Monad (InputT m)
forall (m :: * -> *) e a.
(MonadThrow m, Exception e) =>
e -> InputT m a
throwM :: e -> InputT m a
$cthrowM :: forall (m :: * -> *) e a.
(MonadThrow m, Exception e) =>
e -> InputT m a
$cp1MonadThrow :: forall (m :: * -> *). MonadThrow m => Monad (InputT m)
MonadThrow, MonadThrow (InputT m)
MonadThrow (InputT m)
-> (forall e a.
    Exception e =>
    InputT m a -> (e -> InputT m a) -> InputT m a)
-> MonadCatch (InputT m)
InputT m a -> (e -> InputT m a) -> InputT m a
forall e a.
Exception e =>
InputT m a -> (e -> InputT m a) -> InputT m a
forall (m :: * -> *).
MonadThrow m
-> (forall e a. Exception e => m a -> (e -> m a) -> m a)
-> MonadCatch m
forall (m :: * -> *). MonadCatch m => MonadThrow (InputT m)
forall (m :: * -> *) e a.
(MonadCatch m, Exception e) =>
InputT m a -> (e -> InputT m a) -> InputT m a
catch :: InputT m a -> (e -> InputT m a) -> InputT m a
$ccatch :: forall (m :: * -> *) e a.
(MonadCatch m, Exception e) =>
InputT m a -> (e -> InputT m a) -> InputT m a
$cp1MonadCatch :: forall (m :: * -> *). MonadCatch m => MonadThrow (InputT m)
MonadCatch, MonadCatch (InputT m)
MonadCatch (InputT m)
-> (forall b.
    ((forall a. InputT m a -> InputT m a) -> InputT m b) -> InputT m b)
-> (forall b.
    ((forall a. InputT m a -> InputT m a) -> InputT m b) -> InputT m b)
-> (forall a b c.
    InputT m a
    -> (a -> ExitCase b -> InputT m c)
    -> (a -> InputT m b)
    -> InputT m (b, c))
-> MonadMask (InputT m)
InputT m a
-> (a -> ExitCase b -> InputT m c)
-> (a -> InputT m b)
-> InputT m (b, c)
((forall a. InputT m a -> InputT m a) -> InputT m b) -> InputT m b
((forall a. InputT m a -> InputT m a) -> InputT m b) -> InputT m b
forall b.
((forall a. InputT m a -> InputT m a) -> InputT m b) -> InputT m b
forall a b c.
InputT m a
-> (a -> ExitCase b -> InputT m c)
-> (a -> InputT m b)
-> InputT m (b, c)
forall (m :: * -> *).
MonadCatch m
-> (forall b. ((forall a. m a -> m a) -> m b) -> m b)
-> (forall b. ((forall a. m a -> m a) -> m b) -> m b)
-> (forall a b c.
    m a -> (a -> ExitCase b -> m c) -> (a -> m b) -> m (b, c))
-> MonadMask m
forall (m :: * -> *). MonadMask m => MonadCatch (InputT m)
forall (m :: * -> *) b.
MonadMask m =>
((forall a. InputT m a -> InputT m a) -> InputT m b) -> InputT m b
forall (m :: * -> *) a b c.
MonadMask m =>
InputT m a
-> (a -> ExitCase b -> InputT m c)
-> (a -> InputT m b)
-> InputT m (b, c)
generalBracket :: InputT m a
-> (a -> ExitCase b -> InputT m c)
-> (a -> InputT m b)
-> InputT m (b, c)
$cgeneralBracket :: forall (m :: * -> *) a b c.
MonadMask m =>
InputT m a
-> (a -> ExitCase b -> InputT m c)
-> (a -> InputT m b)
-> InputT m (b, c)
uninterruptibleMask :: ((forall a. InputT m a -> InputT m a) -> InputT m b) -> InputT m b
$cuninterruptibleMask :: forall (m :: * -> *) b.
MonadMask m =>
((forall a. InputT m a -> InputT m a) -> InputT m b) -> InputT m b
mask :: ((forall a. InputT m a -> InputT m a) -> InputT m b) -> InputT m b
$cmask :: forall (m :: * -> *) b.
MonadMask m =>
((forall a. InputT m a -> InputT m a) -> InputT m b) -> InputT m b
$cp1MonadMask :: forall (m :: * -> *). MonadMask m => MonadCatch (InputT m)
MonadMask)
                -- NOTE: we're explicitly *not* making InputT an instance of our
                -- internal MonadState/MonadReader classes.  Otherwise haddock
                -- displays those instances to the user, and it makes it seem like
                -- we implement the mtl versions of those classes.

instance MonadTrans InputT where
    lift :: m a -> InputT m a
lift = ReaderT
  RunTerm
  (ReaderT
     (IORef History)
     (ReaderT
        (IORef KillRing) (ReaderT Prefs (ReaderT (Settings m) m))))
  a
-> InputT m a
forall (m :: * -> *) a.
ReaderT
  RunTerm
  (ReaderT
     (IORef History)
     (ReaderT
        (IORef KillRing) (ReaderT Prefs (ReaderT (Settings m) m))))
  a
-> InputT m a
InputT (ReaderT
   RunTerm
   (ReaderT
      (IORef History)
      (ReaderT
         (IORef KillRing) (ReaderT Prefs (ReaderT (Settings m) m))))
   a
 -> InputT m a)
-> (m a
    -> ReaderT
         RunTerm
         (ReaderT
            (IORef History)
            (ReaderT
               (IORef KillRing) (ReaderT Prefs (ReaderT (Settings m) m))))
         a)
-> m a
-> InputT m a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ReaderT
  (IORef History)
  (ReaderT (IORef KillRing) (ReaderT Prefs (ReaderT (Settings m) m)))
  a
-> ReaderT
     RunTerm
     (ReaderT
        (IORef History)
        (ReaderT
           (IORef KillRing) (ReaderT Prefs (ReaderT (Settings m) m))))
     a
forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift (ReaderT
   (IORef History)
   (ReaderT (IORef KillRing) (ReaderT Prefs (ReaderT (Settings m) m)))
   a
 -> ReaderT
      RunTerm
      (ReaderT
         (IORef History)
         (ReaderT
            (IORef KillRing) (ReaderT Prefs (ReaderT (Settings m) m))))
      a)
-> (m a
    -> ReaderT
         (IORef History)
         (ReaderT (IORef KillRing) (ReaderT Prefs (ReaderT (Settings m) m)))
         a)
-> m a
-> ReaderT
     RunTerm
     (ReaderT
        (IORef History)
        (ReaderT
           (IORef KillRing) (ReaderT Prefs (ReaderT (Settings m) m))))
     a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ReaderT (IORef KillRing) (ReaderT Prefs (ReaderT (Settings m) m)) a
-> ReaderT
     (IORef History)
     (ReaderT (IORef KillRing) (ReaderT Prefs (ReaderT (Settings m) m)))
     a
forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift (ReaderT
   (IORef KillRing) (ReaderT Prefs (ReaderT (Settings m) m)) a
 -> ReaderT
      (IORef History)
      (ReaderT (IORef KillRing) (ReaderT Prefs (ReaderT (Settings m) m)))
      a)
-> (m a
    -> ReaderT
         (IORef KillRing) (ReaderT Prefs (ReaderT (Settings m) m)) a)
-> m a
-> ReaderT
     (IORef History)
     (ReaderT (IORef KillRing) (ReaderT Prefs (ReaderT (Settings m) m)))
     a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ReaderT Prefs (ReaderT (Settings m) m) a
-> ReaderT
     (IORef KillRing) (ReaderT Prefs (ReaderT (Settings m) m)) a
forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift (ReaderT Prefs (ReaderT (Settings m) m) a
 -> ReaderT
      (IORef KillRing) (ReaderT Prefs (ReaderT (Settings m) m)) a)
-> (m a -> ReaderT Prefs (ReaderT (Settings m) m) a)
-> m a
-> ReaderT
     (IORef KillRing) (ReaderT Prefs (ReaderT (Settings m) m)) a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ReaderT (Settings m) m a
-> ReaderT Prefs (ReaderT (Settings m) m) a
forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift (ReaderT (Settings m) m a
 -> ReaderT Prefs (ReaderT (Settings m) m) a)
-> (m a -> ReaderT (Settings m) m a)
-> m a
-> ReaderT Prefs (ReaderT (Settings m) m) a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. m a -> ReaderT (Settings m) m a
forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift

instance ( MonadFix m ) => MonadFix (InputT m) where
    mfix :: (a -> InputT m a) -> InputT m a
mfix a -> InputT m a
f = ReaderT
  RunTerm
  (ReaderT
     (IORef History)
     (ReaderT
        (IORef KillRing) (ReaderT Prefs (ReaderT (Settings m) m))))
  a
-> InputT m a
forall (m :: * -> *) a.
ReaderT
  RunTerm
  (ReaderT
     (IORef History)
     (ReaderT
        (IORef KillRing) (ReaderT Prefs (ReaderT (Settings m) m))))
  a
-> InputT m a
InputT ((a
 -> ReaderT
      RunTerm
      (ReaderT
         (IORef History)
         (ReaderT
            (IORef KillRing) (ReaderT Prefs (ReaderT (Settings m) m))))
      a)
-> ReaderT
     RunTerm
     (ReaderT
        (IORef History)
        (ReaderT
           (IORef KillRing) (ReaderT Prefs (ReaderT (Settings m) m))))
     a
forall (m :: * -> *) a. MonadFix m => (a -> m a) -> m a
mfix (InputT m a
-> ReaderT
     RunTerm
     (ReaderT
        (IORef History)
        (ReaderT
           (IORef KillRing) (ReaderT Prefs (ReaderT (Settings m) m))))
     a
forall (m :: * -> *) a.
InputT m a
-> ReaderT
     RunTerm
     (ReaderT
        (IORef History)
        (ReaderT
           (IORef KillRing) (ReaderT Prefs (ReaderT (Settings m) m))))
     a
unInputT (InputT m a
 -> ReaderT
      RunTerm
      (ReaderT
         (IORef History)
         (ReaderT
            (IORef KillRing) (ReaderT Prefs (ReaderT (Settings m) m))))
      a)
-> (a -> InputT m a)
-> a
-> ReaderT
     RunTerm
     (ReaderT
        (IORef History)
        (ReaderT
           (IORef KillRing) (ReaderT Prefs (ReaderT (Settings m) m))))
     a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. a -> InputT m a
f))

-- | Get the current line input history.
getHistory :: MonadIO m => InputT m History
getHistory :: InputT m History
getHistory = ReaderT
  RunTerm
  (ReaderT
     (IORef History)
     (ReaderT
        (IORef KillRing) (ReaderT Prefs (ReaderT (Settings m) m))))
  History
-> InputT m History
forall (m :: * -> *) a.
ReaderT
  RunTerm
  (ReaderT
     (IORef History)
     (ReaderT
        (IORef KillRing) (ReaderT Prefs (ReaderT (Settings m) m))))
  a
-> InputT m a
InputT ReaderT
  RunTerm
  (ReaderT
     (IORef History)
     (ReaderT
        (IORef KillRing) (ReaderT Prefs (ReaderT (Settings m) m))))
  History
forall s (m :: * -> *). MonadState s m => m s
get

-- | Set the line input history.
putHistory :: MonadIO m => History -> InputT m ()
putHistory :: History -> InputT m ()
putHistory = ReaderT
  RunTerm
  (ReaderT
     (IORef History)
     (ReaderT
        (IORef KillRing) (ReaderT Prefs (ReaderT (Settings m) m))))
  ()
-> InputT m ()
forall (m :: * -> *) a.
ReaderT
  RunTerm
  (ReaderT
     (IORef History)
     (ReaderT
        (IORef KillRing) (ReaderT Prefs (ReaderT (Settings m) m))))
  a
-> InputT m a
InputT (ReaderT
   RunTerm
   (ReaderT
      (IORef History)
      (ReaderT
         (IORef KillRing) (ReaderT Prefs (ReaderT (Settings m) m))))
   ()
 -> InputT m ())
-> (History
    -> ReaderT
         RunTerm
         (ReaderT
            (IORef History)
            (ReaderT
               (IORef KillRing) (ReaderT Prefs (ReaderT (Settings m) m))))
         ())
-> History
-> InputT m ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. History
-> ReaderT
     RunTerm
     (ReaderT
        (IORef History)
        (ReaderT
           (IORef KillRing) (ReaderT Prefs (ReaderT (Settings m) m))))
     ()
forall s (m :: * -> *). MonadState s m => s -> m ()
put

-- | Change the current line input history.
modifyHistory :: MonadIO m => (History -> History) -> InputT m ()
modifyHistory :: (History -> History) -> InputT m ()
modifyHistory = ReaderT
  RunTerm
  (ReaderT
     (IORef History)
     (ReaderT
        (IORef KillRing) (ReaderT Prefs (ReaderT (Settings m) m))))
  ()
-> InputT m ()
forall (m :: * -> *) a.
ReaderT
  RunTerm
  (ReaderT
     (IORef History)
     (ReaderT
        (IORef KillRing) (ReaderT Prefs (ReaderT (Settings m) m))))
  a
-> InputT m a
InputT (ReaderT
   RunTerm
   (ReaderT
      (IORef History)
      (ReaderT
         (IORef KillRing) (ReaderT Prefs (ReaderT (Settings m) m))))
   ()
 -> InputT m ())
-> ((History -> History)
    -> ReaderT
         RunTerm
         (ReaderT
            (IORef History)
            (ReaderT
               (IORef KillRing) (ReaderT Prefs (ReaderT (Settings m) m))))
         ())
-> (History -> History)
-> InputT m ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (History -> History)
-> ReaderT
     RunTerm
     (ReaderT
        (IORef History)
        (ReaderT
           (IORef KillRing) (ReaderT Prefs (ReaderT (Settings m) m))))
     ()
forall s (m :: * -> *). MonadState s m => (s -> s) -> m ()
modify

-- for internal use only
type InputCmdT m = StateT Layout (UndoT (StateT HistLog (ReaderT (IORef KillRing)
                        -- HistLog can be just StateT, since its final state
                        -- isn't used outside of InputCmdT.
                (ReaderT Prefs (ReaderT (Settings m) m)))))

runInputCmdT :: MonadIO m => TermOps -> InputCmdT m a -> InputT m a
runInputCmdT :: TermOps -> InputCmdT m a -> InputT m a
runInputCmdT TermOps
tops InputCmdT m a
f = ReaderT
  RunTerm
  (ReaderT
     (IORef History)
     (ReaderT
        (IORef KillRing) (ReaderT Prefs (ReaderT (Settings m) m))))
  a
-> InputT m a
forall (m :: * -> *) a.
ReaderT
  RunTerm
  (ReaderT
     (IORef History)
     (ReaderT
        (IORef KillRing) (ReaderT Prefs (ReaderT (Settings m) m))))
  a
-> InputT m a
InputT (ReaderT
   RunTerm
   (ReaderT
      (IORef History)
      (ReaderT
         (IORef KillRing) (ReaderT Prefs (ReaderT (Settings m) m))))
   a
 -> InputT m a)
-> ReaderT
     RunTerm
     (ReaderT
        (IORef History)
        (ReaderT
           (IORef KillRing) (ReaderT Prefs (ReaderT (Settings m) m))))
     a
-> InputT m a
forall a b. (a -> b) -> a -> b
$ do
    Layout
layout <- IO Layout
-> ReaderT
     RunTerm
     (ReaderT
        (IORef History)
        (ReaderT
           (IORef KillRing) (ReaderT Prefs (ReaderT (Settings m) m))))
     Layout
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (IO Layout
 -> ReaderT
      RunTerm
      (ReaderT
         (IORef History)
         (ReaderT
            (IORef KillRing) (ReaderT Prefs (ReaderT (Settings m) m))))
      Layout)
-> IO Layout
-> ReaderT
     RunTerm
     (ReaderT
        (IORef History)
        (ReaderT
           (IORef KillRing) (ReaderT Prefs (ReaderT (Settings m) m))))
     Layout
forall a b. (a -> b) -> a -> b
$ TermOps -> IO Layout
getLayout TermOps
tops
    History
history <- ReaderT
  RunTerm
  (ReaderT
     (IORef History)
     (ReaderT
        (IORef KillRing) (ReaderT Prefs (ReaderT (Settings m) m))))
  History
forall s (m :: * -> *). MonadState s m => m s
get
    ReaderT
  (IORef History)
  (ReaderT (IORef KillRing) (ReaderT Prefs (ReaderT (Settings m) m)))
  a
-> ReaderT
     RunTerm
     (ReaderT
        (IORef History)
        (ReaderT
           (IORef KillRing) (ReaderT Prefs (ReaderT (Settings m) m))))
     a
forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift (ReaderT
   (IORef History)
   (ReaderT (IORef KillRing) (ReaderT Prefs (ReaderT (Settings m) m)))
   a
 -> ReaderT
      RunTerm
      (ReaderT
         (IORef History)
         (ReaderT
            (IORef KillRing) (ReaderT Prefs (ReaderT (Settings m) m))))
      a)
-> ReaderT
     (IORef History)
     (ReaderT (IORef KillRing) (ReaderT Prefs (ReaderT (Settings m) m)))
     a
-> ReaderT
     RunTerm
     (ReaderT
        (IORef History)
        (ReaderT
           (IORef KillRing) (ReaderT Prefs (ReaderT (Settings m) m))))
     a
forall a b. (a -> b) -> a -> b
$ ReaderT (IORef KillRing) (ReaderT Prefs (ReaderT (Settings m) m)) a
-> ReaderT
     (IORef History)
     (ReaderT (IORef KillRing) (ReaderT Prefs (ReaderT (Settings m) m)))
     a
forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift (ReaderT
   (IORef KillRing) (ReaderT Prefs (ReaderT (Settings m) m)) a
 -> ReaderT
      (IORef History)
      (ReaderT (IORef KillRing) (ReaderT Prefs (ReaderT (Settings m) m)))
      a)
-> ReaderT
     (IORef KillRing) (ReaderT Prefs (ReaderT (Settings m) m)) a
-> ReaderT
     (IORef History)
     (ReaderT (IORef KillRing) (ReaderT Prefs (ReaderT (Settings m) m)))
     a
forall a b. (a -> b) -> a -> b
$ HistLog
-> StateT
     HistLog
     (ReaderT (IORef KillRing) (ReaderT Prefs (ReaderT (Settings m) m)))
     a
-> ReaderT
     (IORef KillRing) (ReaderT Prefs (ReaderT (Settings m) m)) a
forall (m :: * -> *) s a. Monad m => s -> StateT s m a -> m a
evalStateT' (History -> HistLog
histLog History
history) (StateT
   HistLog
   (ReaderT (IORef KillRing) (ReaderT Prefs (ReaderT (Settings m) m)))
   a
 -> ReaderT
      (IORef KillRing) (ReaderT Prefs (ReaderT (Settings m) m)) a)
-> StateT
     HistLog
     (ReaderT (IORef KillRing) (ReaderT Prefs (ReaderT (Settings m) m)))
     a
-> ReaderT
     (IORef KillRing) (ReaderT Prefs (ReaderT (Settings m) m)) a
forall a b. (a -> b) -> a -> b
$ UndoT
  (StateT
     HistLog
     (ReaderT
        (IORef KillRing) (ReaderT Prefs (ReaderT (Settings m) m))))
  a
-> StateT
     HistLog
     (ReaderT (IORef KillRing) (ReaderT Prefs (ReaderT (Settings m) m)))
     a
forall (m :: * -> *) a. Monad m => UndoT m a -> m a
runUndoT (UndoT
   (StateT
      HistLog
      (ReaderT
         (IORef KillRing) (ReaderT Prefs (ReaderT (Settings m) m))))
   a
 -> StateT
      HistLog
      (ReaderT (IORef KillRing) (ReaderT Prefs (ReaderT (Settings m) m)))
      a)
-> UndoT
     (StateT
        HistLog
        (ReaderT
           (IORef KillRing) (ReaderT Prefs (ReaderT (Settings m) m))))
     a
-> StateT
     HistLog
     (ReaderT (IORef KillRing) (ReaderT Prefs (ReaderT (Settings m) m)))
     a
forall a b. (a -> b) -> a -> b
$ Layout
-> InputCmdT m a
-> UndoT
     (StateT
        HistLog
        (ReaderT
           (IORef KillRing) (ReaderT Prefs (ReaderT (Settings m) m))))
     a
forall (m :: * -> *) s a. Monad m => s -> StateT s m a -> m a
evalStateT' Layout
layout InputCmdT m a
f

instance (MonadIO m, MonadMask m) => CommandMonad (InputCmdT m) where
    runCompletion :: (FilePath, FilePath) -> InputCmdT m (FilePath, [Completion])
runCompletion (FilePath, FilePath)
lcs = do
        Settings m
settings <- StateT
  Layout
  (UndoT
     (StateT
        HistLog
        (ReaderT
           (IORef KillRing) (ReaderT Prefs (ReaderT (Settings m) m)))))
  (Settings m)
forall r (m :: * -> *). MonadReader r m => m r
ask
        StateT
  Undo
  (StateT
     HistLog
     (ReaderT
        (IORef KillRing) (ReaderT Prefs (ReaderT (Settings m) m))))
  (FilePath, [Completion])
-> InputCmdT m (FilePath, [Completion])
forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift (StateT
   Undo
   (StateT
      HistLog
      (ReaderT
         (IORef KillRing) (ReaderT Prefs (ReaderT (Settings m) m))))
   (FilePath, [Completion])
 -> InputCmdT m (FilePath, [Completion]))
-> StateT
     Undo
     (StateT
        HistLog
        (ReaderT
           (IORef KillRing) (ReaderT Prefs (ReaderT (Settings m) m))))
     (FilePath, [Completion])
-> InputCmdT m (FilePath, [Completion])
forall a b. (a -> b) -> a -> b
$ StateT
  HistLog
  (ReaderT (IORef KillRing) (ReaderT Prefs (ReaderT (Settings m) m)))
  (FilePath, [Completion])
-> StateT
     Undo
     (StateT
        HistLog
        (ReaderT
           (IORef KillRing) (ReaderT Prefs (ReaderT (Settings m) m))))
     (FilePath, [Completion])
forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift (StateT
   HistLog
   (ReaderT (IORef KillRing) (ReaderT Prefs (ReaderT (Settings m) m)))
   (FilePath, [Completion])
 -> StateT
      Undo
      (StateT
         HistLog
         (ReaderT
            (IORef KillRing) (ReaderT Prefs (ReaderT (Settings m) m))))
      (FilePath, [Completion]))
-> StateT
     HistLog
     (ReaderT (IORef KillRing) (ReaderT Prefs (ReaderT (Settings m) m)))
     (FilePath, [Completion])
-> StateT
     Undo
     (StateT
        HistLog
        (ReaderT
           (IORef KillRing) (ReaderT Prefs (ReaderT (Settings m) m))))
     (FilePath, [Completion])
forall a b. (a -> b) -> a -> b
$ ReaderT
  (IORef KillRing)
  (ReaderT Prefs (ReaderT (Settings m) m))
  (FilePath, [Completion])
-> StateT
     HistLog
     (ReaderT (IORef KillRing) (ReaderT Prefs (ReaderT (Settings m) m)))
     (FilePath, [Completion])
forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift (ReaderT
   (IORef KillRing)
   (ReaderT Prefs (ReaderT (Settings m) m))
   (FilePath, [Completion])
 -> StateT
      HistLog
      (ReaderT (IORef KillRing) (ReaderT Prefs (ReaderT (Settings m) m)))
      (FilePath, [Completion]))
-> ReaderT
     (IORef KillRing)
     (ReaderT Prefs (ReaderT (Settings m) m))
     (FilePath, [Completion])
-> StateT
     HistLog
     (ReaderT (IORef KillRing) (ReaderT Prefs (ReaderT (Settings m) m)))
     (FilePath, [Completion])
forall a b. (a -> b) -> a -> b
$ ReaderT Prefs (ReaderT (Settings m) m) (FilePath, [Completion])
-> ReaderT
     (IORef KillRing)
     (ReaderT Prefs (ReaderT (Settings m) m))
     (FilePath, [Completion])
forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift (ReaderT Prefs (ReaderT (Settings m) m) (FilePath, [Completion])
 -> ReaderT
      (IORef KillRing)
      (ReaderT Prefs (ReaderT (Settings m) m))
      (FilePath, [Completion]))
-> ReaderT Prefs (ReaderT (Settings m) m) (FilePath, [Completion])
-> ReaderT
     (IORef KillRing)
     (ReaderT Prefs (ReaderT (Settings m) m))
     (FilePath, [Completion])
forall a b. (a -> b) -> a -> b
$ ReaderT (Settings m) m (FilePath, [Completion])
-> ReaderT Prefs (ReaderT (Settings m) m) (FilePath, [Completion])
forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift (ReaderT (Settings m) m (FilePath, [Completion])
 -> ReaderT Prefs (ReaderT (Settings m) m) (FilePath, [Completion]))
-> ReaderT (Settings m) m (FilePath, [Completion])
-> ReaderT Prefs (ReaderT (Settings m) m) (FilePath, [Completion])
forall a b. (a -> b) -> a -> b
$ m (FilePath, [Completion])
-> ReaderT (Settings m) m (FilePath, [Completion])
forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift (m (FilePath, [Completion])
 -> ReaderT (Settings m) m (FilePath, [Completion]))
-> m (FilePath, [Completion])
-> ReaderT (Settings m) m (FilePath, [Completion])
forall a b. (a -> b) -> a -> b
$ Settings m -> CompletionFunc m
forall (m :: * -> *). Settings m -> CompletionFunc m
complete Settings m
settings (FilePath, FilePath)
lcs

-- | Run a line-reading application.  Uses 'defaultBehavior' to determine the
-- interaction behavior.
runInputTWithPrefs :: (MonadIO m, MonadMask m) => Prefs -> Settings m -> InputT m a -> m a
runInputTWithPrefs :: Prefs -> Settings m -> InputT m a -> m a
runInputTWithPrefs = Behavior -> Prefs -> Settings m -> InputT m a -> m a
forall (m :: * -> *) a.
(MonadIO m, MonadMask m) =>
Behavior -> Prefs -> Settings m -> InputT m a -> m a
runInputTBehaviorWithPrefs Behavior
defaultBehavior

-- | Run a line-reading application.  This function should suffice for most applications.
--
-- This function is equivalent to @'runInputTBehavior' 'defaultBehavior'@.  It 
-- uses terminal-style interaction if 'stdin' is connected to a terminal and has
-- echoing enabled.  Otherwise (e.g., if 'stdin' is a pipe), it uses file-style interaction.
--
-- If it uses terminal-style interaction, 'Prefs' will be read from the user's @~/.haskeline@ file
-- (if present).
-- If it uses file-style interaction, 'Prefs' are not relevant and will not be read.
runInputT :: (MonadIO m, MonadMask m) => Settings m -> InputT m a -> m a
runInputT :: Settings m -> InputT m a -> m a
runInputT = Behavior -> Settings m -> InputT m a -> m a
forall (m :: * -> *) a.
(MonadIO m, MonadMask m) =>
Behavior -> Settings m -> InputT m a -> m a
runInputTBehavior Behavior
defaultBehavior

-- | Returns 'True' if the current session uses terminal-style interaction.  (See 'Behavior'.)
haveTerminalUI :: Monad m => InputT m Bool
haveTerminalUI :: InputT m Bool
haveTerminalUI = ReaderT
  RunTerm
  (ReaderT
     (IORef History)
     (ReaderT
        (IORef KillRing) (ReaderT Prefs (ReaderT (Settings m) m))))
  Bool
-> InputT m Bool
forall (m :: * -> *) a.
ReaderT
  RunTerm
  (ReaderT
     (IORef History)
     (ReaderT
        (IORef KillRing) (ReaderT Prefs (ReaderT (Settings m) m))))
  a
-> InputT m a
InputT (ReaderT
   RunTerm
   (ReaderT
      (IORef History)
      (ReaderT
         (IORef KillRing) (ReaderT Prefs (ReaderT (Settings m) m))))
   Bool
 -> InputT m Bool)
-> ReaderT
     RunTerm
     (ReaderT
        (IORef History)
        (ReaderT
           (IORef KillRing) (ReaderT Prefs (ReaderT (Settings m) m))))
     Bool
-> InputT m Bool
forall a b. (a -> b) -> a -> b
$ (RunTerm -> Bool)
-> ReaderT
     RunTerm
     (ReaderT
        (IORef History)
        (ReaderT
           (IORef KillRing) (ReaderT Prefs (ReaderT (Settings m) m))))
     Bool
forall r (m :: * -> *) a. MonadReader r m => (r -> a) -> m a
asks RunTerm -> Bool
isTerminalStyle


{- | Haskeline has two ways of interacting with the user:

 * \"Terminal-style\" interaction provides an rich user interface by connecting
   to the user's terminal (which may be different than 'stdin' or 'stdout').  
 
 * \"File-style\" interaction treats the input as a simple stream of characters, for example
    when reading from a file or pipe.  Input functions (e.g., @getInputLine@) print the prompt to 'stdout'.
 
 A 'Behavior' is a method for deciding at run-time which type of interaction to use.  
 
 For most applications (e.g., a REPL), 'defaultBehavior' should have the correct effect.
-}
data Behavior = Behavior (IO RunTerm)

-- | Create and use a RunTerm, ensuring that it will be closed even if
-- an async exception occurs during the creation or use.
withBehavior :: (MonadIO m, MonadMask m) => Behavior -> (RunTerm -> m a) -> m a
withBehavior :: Behavior -> (RunTerm -> m a) -> m a
withBehavior (Behavior IO RunTerm
run) RunTerm -> m a
f = m RunTerm -> (RunTerm -> m ()) -> (RunTerm -> m a) -> m a
forall (m :: * -> *) a c b.
MonadMask m =>
m a -> (a -> m c) -> (a -> m b) -> m b
bracket (IO RunTerm -> m RunTerm
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO IO RunTerm
run) (IO () -> m ()
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (IO () -> m ()) -> (RunTerm -> IO ()) -> RunTerm -> m ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. RunTerm -> IO ()
closeTerm) RunTerm -> m a
f

-- | Run a line-reading application according to the given behavior.
--
-- If it uses terminal-style interaction, 'Prefs' will be read from the
-- user's @~/.haskeline@ file (if present).
-- If it uses file-style interaction, 'Prefs' are not relevant and will not be read.
runInputTBehavior :: (MonadIO m, MonadMask m) => Behavior -> Settings m -> InputT m a -> m a
runInputTBehavior :: Behavior -> Settings m -> InputT m a -> m a
runInputTBehavior Behavior
behavior Settings m
settings InputT m a
f = Behavior -> (RunTerm -> m a) -> m a
forall (m :: * -> *) a.
(MonadIO m, MonadMask m) =>
Behavior -> (RunTerm -> m a) -> m a
withBehavior Behavior
behavior ((RunTerm -> m a) -> m a) -> (RunTerm -> m a) -> m a
forall a b. (a -> b) -> a -> b
$ \RunTerm
run -> do
    Prefs
prefs <- if RunTerm -> Bool
isTerminalStyle RunTerm
run
                then IO Prefs -> m Prefs
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO IO Prefs
readPrefsFromHome
                else Prefs -> m Prefs
forall (m :: * -> *) a. Monad m => a -> m a
return Prefs
defaultPrefs
    Prefs -> Settings m -> RunTerm -> InputT m a -> m a
forall (m :: * -> *) a.
(MonadIO m, MonadMask m) =>
Prefs -> Settings m -> RunTerm -> InputT m a -> m a
execInputT Prefs
prefs Settings m
settings RunTerm
run InputT m a
f

-- | Run a line-reading application.
runInputTBehaviorWithPrefs :: (MonadIO m, MonadMask m)
    => Behavior -> Prefs -> Settings m -> InputT m a -> m a
runInputTBehaviorWithPrefs :: Behavior -> Prefs -> Settings m -> InputT m a -> m a
runInputTBehaviorWithPrefs Behavior
behavior Prefs
prefs Settings m
settings InputT m a
f
    = Behavior -> (RunTerm -> m a) -> m a
forall (m :: * -> *) a.
(MonadIO m, MonadMask m) =>
Behavior -> (RunTerm -> m a) -> m a
withBehavior Behavior
behavior ((RunTerm -> m a) -> m a) -> (RunTerm -> m a) -> m a
forall a b. (a -> b) -> a -> b
$ (RunTerm -> InputT m a -> m a) -> InputT m a -> RunTerm -> m a
forall a b c. (a -> b -> c) -> b -> a -> c
flip (Prefs -> Settings m -> RunTerm -> InputT m a -> m a
forall (m :: * -> *) a.
(MonadIO m, MonadMask m) =>
Prefs -> Settings m -> RunTerm -> InputT m a -> m a
execInputT Prefs
prefs Settings m
settings) InputT m a
f

-- | Helper function to feed the parameters into an InputT.
execInputT :: (MonadIO m, MonadMask m) => Prefs -> Settings m -> RunTerm
                -> InputT m a -> m a
execInputT :: Prefs -> Settings m -> RunTerm -> InputT m a -> m a
execInputT Prefs
prefs Settings m
settings RunTerm
run (InputT ReaderT
  RunTerm
  (ReaderT
     (IORef History)
     (ReaderT
        (IORef KillRing) (ReaderT Prefs (ReaderT (Settings m) m))))
  a
f)
    = Settings m -> ReaderT (Settings m) m a -> m a
forall r (m :: * -> *) a. r -> ReaderT r m a -> m a
runReaderT' Settings m
settings (ReaderT (Settings m) m a -> m a)
-> ReaderT (Settings m) m a -> m a
forall a b. (a -> b) -> a -> b
$ Prefs
-> ReaderT Prefs (ReaderT (Settings m) m) a
-> ReaderT (Settings m) m a
forall r (m :: * -> *) a. r -> ReaderT r m a -> m a
runReaderT' Prefs
prefs
            (ReaderT Prefs (ReaderT (Settings m) m) a
 -> ReaderT (Settings m) m a)
-> ReaderT Prefs (ReaderT (Settings m) m) a
-> ReaderT (Settings m) m a
forall a b. (a -> b) -> a -> b
$ ReaderT (IORef KillRing) (ReaderT Prefs (ReaderT (Settings m) m)) a
-> ReaderT Prefs (ReaderT (Settings m) m) a
forall (m :: * -> *) a.
MonadIO m =>
ReaderT (IORef KillRing) m a -> m a
runKillRing
            (ReaderT
   (IORef KillRing) (ReaderT Prefs (ReaderT (Settings m) m)) a
 -> ReaderT Prefs (ReaderT (Settings m) m) a)
-> ReaderT
     (IORef KillRing) (ReaderT Prefs (ReaderT (Settings m) m)) a
-> ReaderT Prefs (ReaderT (Settings m) m) a
forall a b. (a -> b) -> a -> b
$ Maybe FilePath
-> Maybe Int
-> ReaderT
     (IORef History)
     (ReaderT (IORef KillRing) (ReaderT Prefs (ReaderT (Settings m) m)))
     a
-> ReaderT
     (IORef KillRing) (ReaderT Prefs (ReaderT (Settings m) m)) a
forall (m :: * -> *) a.
(MonadIO m, MonadMask m) =>
Maybe FilePath -> Maybe Int -> ReaderT (IORef History) m a -> m a
runHistoryFromFile (Settings m -> Maybe FilePath
forall (m :: * -> *). Settings m -> Maybe FilePath
historyFile Settings m
settings) (Prefs -> Maybe Int
maxHistorySize Prefs
prefs)
            (ReaderT
   (IORef History)
   (ReaderT (IORef KillRing) (ReaderT Prefs (ReaderT (Settings m) m)))
   a
 -> ReaderT
      (IORef KillRing) (ReaderT Prefs (ReaderT (Settings m) m)) a)
-> ReaderT
     (IORef History)
     (ReaderT (IORef KillRing) (ReaderT Prefs (ReaderT (Settings m) m)))
     a
-> ReaderT
     (IORef KillRing) (ReaderT Prefs (ReaderT (Settings m) m)) a
forall a b. (a -> b) -> a -> b
$ ReaderT
  RunTerm
  (ReaderT
     (IORef History)
     (ReaderT
        (IORef KillRing) (ReaderT Prefs (ReaderT (Settings m) m))))
  a
-> RunTerm
-> ReaderT
     (IORef History)
     (ReaderT (IORef KillRing) (ReaderT Prefs (ReaderT (Settings m) m)))
     a
forall r (m :: * -> *) a. ReaderT r m a -> r -> m a
runReaderT ReaderT
  RunTerm
  (ReaderT
     (IORef History)
     (ReaderT
        (IORef KillRing) (ReaderT Prefs (ReaderT (Settings m) m))))
  a
f RunTerm
run

-- | Map a user interaction by modifying the base monad computation.
mapInputT :: (forall b . m b -> m b) -> InputT m a -> InputT m a
mapInputT :: (forall b. m b -> m b) -> InputT m a -> InputT m a
mapInputT forall b. m b -> m b
f = ReaderT
  RunTerm
  (ReaderT
     (IORef History)
     (ReaderT
        (IORef KillRing) (ReaderT Prefs (ReaderT (Settings m) m))))
  a
-> InputT m a
forall (m :: * -> *) a.
ReaderT
  RunTerm
  (ReaderT
     (IORef History)
     (ReaderT
        (IORef KillRing) (ReaderT Prefs (ReaderT (Settings m) m))))
  a
-> InputT m a
InputT (ReaderT
   RunTerm
   (ReaderT
      (IORef History)
      (ReaderT
         (IORef KillRing) (ReaderT Prefs (ReaderT (Settings m) m))))
   a
 -> InputT m a)
-> (InputT m a
    -> ReaderT
         RunTerm
         (ReaderT
            (IORef History)
            (ReaderT
               (IORef KillRing) (ReaderT Prefs (ReaderT (Settings m) m))))
         a)
-> InputT m a
-> InputT m a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (ReaderT
   (IORef History)
   (ReaderT (IORef KillRing) (ReaderT Prefs (ReaderT (Settings m) m)))
   a
 -> ReaderT
      (IORef History)
      (ReaderT (IORef KillRing) (ReaderT Prefs (ReaderT (Settings m) m)))
      a)
-> ReaderT
     RunTerm
     (ReaderT
        (IORef History)
        (ReaderT
           (IORef KillRing) (ReaderT Prefs (ReaderT (Settings m) m))))
     a
-> ReaderT
     RunTerm
     (ReaderT
        (IORef History)
        (ReaderT
           (IORef KillRing) (ReaderT Prefs (ReaderT (Settings m) m))))
     a
forall (m :: * -> *) a (n :: * -> *) b r.
(m a -> n b) -> ReaderT r m a -> ReaderT r n b
mapReaderT ((ReaderT
   (IORef KillRing) (ReaderT Prefs (ReaderT (Settings m) m)) a
 -> ReaderT
      (IORef KillRing) (ReaderT Prefs (ReaderT (Settings m) m)) a)
-> ReaderT
     (IORef History)
     (ReaderT (IORef KillRing) (ReaderT Prefs (ReaderT (Settings m) m)))
     a
-> ReaderT
     (IORef History)
     (ReaderT (IORef KillRing) (ReaderT Prefs (ReaderT (Settings m) m)))
     a
forall (m :: * -> *) a (n :: * -> *) b r.
(m a -> n b) -> ReaderT r m a -> ReaderT r n b
mapReaderT ((ReaderT Prefs (ReaderT (Settings m) m) a
 -> ReaderT Prefs (ReaderT (Settings m) m) a)
-> ReaderT
     (IORef KillRing) (ReaderT Prefs (ReaderT (Settings m) m)) a
-> ReaderT
     (IORef KillRing) (ReaderT Prefs (ReaderT (Settings m) m)) a
forall (m :: * -> *) a (n :: * -> *) b r.
(m a -> n b) -> ReaderT r m a -> ReaderT r n b
mapReaderT
                                  ((ReaderT (Settings m) m a -> ReaderT (Settings m) m a)
-> ReaderT Prefs (ReaderT (Settings m) m) a
-> ReaderT Prefs (ReaderT (Settings m) m) a
forall (m :: * -> *) a (n :: * -> *) b r.
(m a -> n b) -> ReaderT r m a -> ReaderT r n b
mapReaderT ((m a -> m a)
-> ReaderT (Settings m) m a -> ReaderT (Settings m) m a
forall (m :: * -> *) a (n :: * -> *) b r.
(m a -> n b) -> ReaderT r m a -> ReaderT r n b
mapReaderT m a -> m a
forall b. m b -> m b
f))))
                    (ReaderT
   RunTerm
   (ReaderT
      (IORef History)
      (ReaderT
         (IORef KillRing) (ReaderT Prefs (ReaderT (Settings m) m))))
   a
 -> ReaderT
      RunTerm
      (ReaderT
         (IORef History)
         (ReaderT
            (IORef KillRing) (ReaderT Prefs (ReaderT (Settings m) m))))
      a)
-> (InputT m a
    -> ReaderT
         RunTerm
         (ReaderT
            (IORef History)
            (ReaderT
               (IORef KillRing) (ReaderT Prefs (ReaderT (Settings m) m))))
         a)
-> InputT m a
-> ReaderT
     RunTerm
     (ReaderT
        (IORef History)
        (ReaderT
           (IORef KillRing) (ReaderT Prefs (ReaderT (Settings m) m))))
     a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. InputT m a
-> ReaderT
     RunTerm
     (ReaderT
        (IORef History)
        (ReaderT
           (IORef KillRing) (ReaderT Prefs (ReaderT (Settings m) m))))
     a
forall (m :: * -> *) a.
InputT m a
-> ReaderT
     RunTerm
     (ReaderT
        (IORef History)
        (ReaderT
           (IORef KillRing) (ReaderT Prefs (ReaderT (Settings m) m))))
     a
unInputT

-- | Read input from 'stdin'.  
-- Use terminal-style interaction if 'stdin' is connected to
-- a terminal and has echoing enabled.  Otherwise (e.g., if 'stdin' is a pipe), use
-- file-style interaction.
--
-- This behavior should suffice for most applications.  
defaultBehavior :: Behavior
defaultBehavior :: Behavior
defaultBehavior = IO RunTerm -> Behavior
Behavior IO RunTerm
defaultRunTerm

-- | Use file-style interaction, reading input from the given 'Handle'.  
useFileHandle :: Handle -> Behavior
useFileHandle :: Handle -> Behavior
useFileHandle = IO RunTerm -> Behavior
Behavior (IO RunTerm -> Behavior)
-> (Handle -> IO RunTerm) -> Handle -> Behavior
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Handle -> IO RunTerm
fileHandleRunTerm

-- | Use file-style interaction, reading input from the given file.
useFile :: FilePath -> Behavior
useFile :: FilePath -> Behavior
useFile FilePath
file = IO RunTerm -> Behavior
Behavior (IO RunTerm -> Behavior) -> IO RunTerm -> Behavior
forall a b. (a -> b) -> a -> b
$ do
            Handle
h <- FilePath -> IOMode -> IO Handle
openBinaryFile FilePath
file IOMode
ReadMode
            RunTerm
rt <- Handle -> IO RunTerm
fileHandleRunTerm Handle
h
            RunTerm -> IO RunTerm
forall (m :: * -> *) a. Monad m => a -> m a
return RunTerm
rt { closeTerm :: IO ()
closeTerm = RunTerm -> IO ()
closeTerm RunTerm
rt IO () -> IO () -> IO ()
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> Handle -> IO ()
hClose Handle
h}

-- | Use terminal-style interaction whenever possible, even if 'stdin' and/or 'stdout' are not
-- terminals.
--
-- If it cannot open the user's terminal, use file-style interaction, reading input from 'stdin'.
preferTerm :: Behavior
preferTerm :: Behavior
preferTerm = IO RunTerm -> Behavior
Behavior IO RunTerm
terminalRunTerm


-- | Read 'Prefs' from @~/.haskeline.@   If there is an error reading the file,
-- the 'defaultPrefs' will be returned.
readPrefsFromHome :: IO Prefs
readPrefsFromHome :: IO Prefs
readPrefsFromHome = (IOException -> IO Prefs) -> IO Prefs -> IO Prefs
forall (m :: * -> *) e a.
(MonadCatch m, Exception e) =>
(e -> m a) -> m a -> m a
handle (\(IOException
_::IOException) -> Prefs -> IO Prefs
forall (m :: * -> *) a. Monad m => a -> m a
return Prefs
defaultPrefs) (IO Prefs -> IO Prefs) -> IO Prefs -> IO Prefs
forall a b. (a -> b) -> a -> b
$ do
    FilePath
home <- IO FilePath
getHomeDirectory
    FilePath -> IO Prefs
readPrefs (FilePath
home FilePath -> FilePath -> FilePath
</> FilePath
".haskeline")