module Ribosome.Internal.IO where

import Control.Concurrent (forkIO)
import Control.Monad.Trans.Resource (runResourceT)
import Neovim.Context.Internal (Config(..), Neovim(..), retypeConfig, runNeovim)
import qualified Control.Monad.Reader as ReaderT

retypeNeovim :: (e0 -> e1) -> Neovim e1 a -> Neovim e0 a
retypeNeovim :: (e0 -> e1) -> Neovim e1 a -> Neovim e0 a
retypeNeovim e0 -> e1
transform Neovim e1 a
thunk = do
  Config e0
env <- ResourceT (ReaderT (Config e0) IO) (Config e0)
-> Neovim e0 (Config e0)
forall env a. ResourceT (ReaderT (Config env) IO) a -> Neovim env a
Neovim ResourceT (ReaderT (Config e0) IO) (Config e0)
forall r (m :: * -> *). MonadReader r m => m r
ReaderT.ask
  IO a -> Neovim e0 a
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (IO a -> Neovim e0 a) -> IO a -> Neovim e0 a
forall a b. (a -> b) -> a -> b
$ ReaderT (Config e0) IO a -> Config e0 -> IO a
forall r (m :: * -> *) a. ReaderT r m a -> r -> m a
runReaderT ((Config e0 -> Config e1)
-> ReaderT (Config e1) IO a -> ReaderT (Config e0) IO a
forall r' r (m :: * -> *) a.
(r' -> r) -> ReaderT r m a -> ReaderT r' m a
withReaderT (Config e0 -> Config e0 -> Config e1
newEnv Config e0
env) (ReaderT (Config e1) IO a -> ReaderT (Config e0) IO a)
-> ReaderT (Config e1) IO a -> ReaderT (Config e0) IO a
forall a b. (a -> b) -> a -> b
$ ResourceT (ReaderT (Config e1) IO) a -> ReaderT (Config e1) IO a
forall (m :: * -> *) a. MonadUnliftIO m => ResourceT m a -> m a
runResourceT (ResourceT (ReaderT (Config e1) IO) a -> ReaderT (Config e1) IO a)
-> ResourceT (ReaderT (Config e1) IO) a -> ReaderT (Config e1) IO a
forall a b. (a -> b) -> a -> b
$ Neovim e1 a -> ResourceT (ReaderT (Config e1) IO) a
forall env a. Neovim env a -> ResourceT (ReaderT (Config env) IO) a
unNeovim Neovim e1 a
thunk) Config e0
env
  where
    newEnv :: Config e0 -> Config e0 -> Config e1
newEnv = e1 -> Config e0 -> Config e1
forall env anotherEnv. env -> Config anotherEnv -> Config env
retypeConfig (e1 -> Config e0 -> Config e1)
-> (Config e0 -> e1) -> Config e0 -> Config e0 -> Config e1
forall b c a. (b -> c) -> (a -> b) -> a -> c
. e0 -> e1
transform (e0 -> e1) -> (Config e0 -> e0) -> Config e0 -> e1
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Config e0 -> e0
forall env. Config env -> env
customConfig

forkNeovim :: Neovim e () -> Neovim e ()
forkNeovim :: Neovim e () -> Neovim e ()
forkNeovim Neovim e ()
thunk = do
  Config e
env <- ResourceT (ReaderT (Config e) IO) (Config e) -> Neovim e (Config e)
forall env a. ResourceT (ReaderT (Config env) IO) a -> Neovim env a
Neovim ResourceT (ReaderT (Config e) IO) (Config e)
forall r (m :: * -> *). MonadReader r m => m r
ReaderT.ask
  ThreadId
_ <- IO ThreadId -> Neovim e ThreadId
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (IO ThreadId -> Neovim e ThreadId)
-> IO ThreadId -> Neovim e ThreadId
forall a b. (a -> b) -> a -> b
$ IO () -> IO ThreadId
forkIO (IO () -> IO ThreadId) -> IO () -> IO ThreadId
forall a b. (a -> b) -> a -> b
$ IO (Either (Doc AnsiStyle) ()) -> IO ()
forall (f :: * -> *) a. Functor f => f a -> f ()
void (IO (Either (Doc AnsiStyle) ()) -> IO ())
-> IO (Either (Doc AnsiStyle) ()) -> IO ()
forall a b. (a -> b) -> a -> b
$ Config e -> Neovim e () -> IO (Either (Doc AnsiStyle) ())
forall a env.
NFData a =>
Config env -> Neovim env a -> IO (Either (Doc AnsiStyle) a)
runNeovim Config e
env Neovim e ()
thunk
  return ()