@@ -26,23 +26,19 @@ import Neovim.Plugin.Classes
2626import Neovim.Plugin.IPC (SomeMessage )
2727
2828import Control.Applicative
29- import Control.Concurrent (ThreadId , forkIO )
30- import Control.Concurrent (MVar , newEmptyMVar )
31- import Control.Concurrent.STM
29+ import Control.Concurrent (MVar , ThreadId , forkIO )
3230import Control.Exception (ArithException , ArrayException ,
3331 ErrorCall , PatternMatchFail )
34- import Control.Monad.Base
35- import Control.Monad.Catch
3632import Control.Monad.Except
3733import Control.Monad.Reader
38- import Control.Monad.State
3934import Control.Monad.Trans.Resource
4035import qualified Data.ByteString.UTF8 as U (fromString )
4136import Data.Map (Map )
4237import qualified Data.Map as Map
4338import Data.MessagePack (Object )
4439import System.Log.Logger
4540import Text.PrettyPrint.ANSI.Leijen hiding ((<$>) )
41+ import UnliftIO
4642
4743import Prelude
4844
@@ -56,38 +52,40 @@ import Prelude
5652-- good practice to factor them out. This allows you to write tests and spot
5753-- errors easier. Essentially, you should treat this similar to 'IO' in general
5854-- haskell programs.
59- newtype Neovim r st a = Neovim
60- { unNeovim :: ResourceT (StateT st ( ReaderT (Config r st ) IO ) ) a }
55+ newtype Neovim env a = Neovim
56+ { unNeovim :: ResourceT (ReaderT (Config env ) IO ) a }
6157
62- deriving (Functor , Applicative , Monad , MonadIO , MonadState st
63- , MonadThrow , MonadCatch , MonadMask , MonadResource )
64-
65-
66- instance MonadBase IO (Neovim r st ) where
67- liftBase = liftIO
58+ deriving (Functor , Applicative , Monad , MonadIO
59+ , MonadThrow , MonadResource )
6860
6961
7062-- | User facing instance declaration for the reader state.
71- instance MonadReader r (Neovim r st ) where
63+ instance MonadReader env (Neovim env ) where
7264 ask = Neovim $ asks customConfig
7365 local f (Neovim a) = do
74- r <- Neovim $ ask
75- s <- get
76- fmap fst . liftIO $ runReaderT (runStateT (runResourceT a) s)
66+ r <- Neovim ask
67+ liftIO $ runReaderT (runResourceT a)
7768 (r { customConfig = f (customConfig r)})
7869
7970
71+
72+ -- newtype UnliftIO m = UnliftIO { unliftIO :: forall a. m a -> IO a }
73+
74+ instance MonadUnliftIO (Neovim env ) where
75+ askUnliftIO = Neovim . withUnliftIO $ \ x ->
76+ return (UnliftIO (unliftIO x . unNeovim))
77+
8078-- | Same as 'ask' for the 'InternalConfig'.
81- ask' :: Neovim r st (Config r st )
82- ask' = Neovim $ ask
79+ ask' :: Neovim env (Config env )
80+ ask' = Neovim ask
8381
8482
8583-- | Same as 'asks' for the 'InternalConfig'.
86- asks' :: (Config r st -> a ) -> Neovim r st a
84+ asks' :: (Config env -> a ) -> Neovim env a
8785asks' = Neovim . asks
8886
8987-- | Convenience alias for @'Neovim' () ()@.
90- type Neovim' = Neovim () ()
88+ type Neovim' = Neovim ()
9189
9290exceptionHandlers :: [Handler IO (Either Doc a )]
9391exceptionHandlers =
@@ -102,19 +100,17 @@ exceptionHandlers =
102100
103101-- | Initialize a 'Neovim' context by supplying an 'InternalEnvironment'.
104102runNeovim :: NFData a
105- => Config r st
106- -> st
107- -> Neovim r st a
108- -> IO (Either Doc (a , st ))
109- runNeovim = runNeovimInternal (\ (a,st) -> a `deepseq` return (a, st))
110-
111- runNeovimInternal :: ((a , st ) -> IO (a , st ))
112- -> Config r st
113- -> st
114- -> Neovim r st a
115- -> IO (Either Doc (a , st ))
116- runNeovimInternal f r st (Neovim a) =
117- (try . runReaderT (runStateT (runResourceT a) st)) r >>= \ case
103+ => Config env
104+ -> Neovim env a
105+ -> IO (Either Doc a )
106+ runNeovim = runNeovimInternal (\ a -> a `deepseq` return a)
107+
108+ runNeovimInternal :: (a -> IO a )
109+ -> Config env
110+ -> Neovim env a
111+ -> IO (Either Doc a )
112+ runNeovimInternal f r (Neovim a) =
113+ (try . runReaderT (runResourceT a)) r >>= \ case
118114 Left e -> case fromException e of
119115 Just e' ->
120116 return . Left . pretty $ (e' :: NeovimException )
@@ -131,19 +127,19 @@ runNeovimInternal f r st (Neovim a) =
131127-- returend immediately.
132128-- FIXME This function is pretty much unused and mayhave undesired effects,
133129-- namely that you cannot register autocmds in the forked thread.
134- forkNeovim :: NFData a => ir -> ist -> Neovim ir ist a -> Neovim r st ThreadId
135- forkNeovim r st a = do
130+ forkNeovim :: NFData a => iEnv -> Neovim iEnv a -> Neovim env ThreadId
131+ forkNeovim r a = do
136132 cfg <- ask'
137133 let threadConfig = cfg
138134 { pluginSettings = Nothing -- <- slightly problematic
139135 , customConfig = r
140136 }
141- liftIO . forkIO . void $ runNeovim threadConfig st a
137+ liftIO . forkIO . void $ runNeovim threadConfig a
142138
143139
144140-- | Create a new unique function name. To prevent possible name clashes, digits
145141-- are stripped from the given suffix.
146- newUniqueFunctionName :: Neovim r st FunctionName
142+ newUniqueFunctionName :: Neovim env FunctionName
147143newUniqueFunctionName = do
148144 tu <- asks' uniqueCounter
149145 -- reverseing the integer string should distribute the first character more
@@ -200,7 +196,7 @@ mkFunctionMap = Map.fromList . map (\e -> (name (fst e), e))
200196--
201197-- Note that you most probably do not want to change the fields prefixed with an
202198-- underscore.
203- data Config r st = Config
199+ data Config env = Config
204200 -- Global settings; initialized once
205201 { eventQueue :: TQueue SomeMessage
206202 -- ^ A queue of messages that the event handler will propagate to
@@ -229,11 +225,11 @@ data Config r st = Config
229225 -- it's appropriate targets.
230226
231227 -- Local settings; intialized for each stateful component
232- , pluginSettings :: Maybe (PluginSettings r st )
228+ , pluginSettings :: Maybe (PluginSettings env )
233229 -- ^ In a registered functionality this field contains a function (and
234230 -- possibly some context dependent values) to register new functionality.
235231
236- , customConfig :: r
232+ , customConfig :: env
237233 -- ^ Plugin author supplyable custom configuration. Queried on the
238234 -- user-facing side with 'ask' or 'asks'.
239235 }
@@ -243,38 +239,38 @@ data Config r st = Config
243239-- config.
244240--
245241-- Sets the 'pluginSettings' field to 'Nothing'.
246- retypeConfig :: r -> st -> Config anotherR anotherSt -> Config r st
247- retypeConfig r _ cfg = cfg { pluginSettings = Nothing , customConfig = r }
242+ retypeConfig :: env -> Config anotherEnv -> Config env
243+ retypeConfig r cfg = cfg { pluginSettings = Nothing , customConfig = r }
248244
249245
250246-- | This GADT is used to share information between stateless and stateful
251247-- plugin threads since they work fundamentally in the same way. They both
252248-- contain a function to register some functionality in the plugin provider
253249-- as well as some values which are specific to the one or the other context.
254- data PluginSettings r st where
250+ data PluginSettings env where
255251 StatelessSettings
256252 :: (FunctionalityDescription
257253 -> ([Object ] -> Neovim' Object )
258254 -> Neovim' (Maybe FunctionMapEntry ))
259- -> PluginSettings () ()
255+ -> PluginSettings ()
260256
261257 StatefulSettings
262258 :: (FunctionalityDescription
263- -> ([Object ] -> Neovim r st Object )
259+ -> ([Object ] -> Neovim env Object )
264260 -> TQueue SomeMessage
265- -> TVar (Map FunctionName ([Object ] -> Neovim r st Object ))
266- -> Neovim r st (Maybe FunctionMapEntry ))
261+ -> TVar (Map FunctionName ([Object ] -> Neovim env Object ))
262+ -> Neovim env (Maybe FunctionMapEntry ))
267263 -> TQueue SomeMessage
268- -> TVar (Map FunctionName ([Object ] -> Neovim r st Object ))
269- -> PluginSettings r st
264+ -> TVar (Map FunctionName ([Object ] -> Neovim env Object ))
265+ -> PluginSettings env
270266
271267
272268-- | Create a new 'InternalConfig' object by providing the minimal amount of
273269-- necessary information.
274270--
275271-- This function should only be called once per /nvim-hs/ session since the
276272-- arguments are shared across processes.
277- newConfig :: IO (Maybe String ) -> IO r -> IO (Config r context )
273+ newConfig :: IO (Maybe String ) -> IO env -> IO (Config env )
278274newConfig ioProviderName r = Config
279275 <$> newTQueueIO
280276 <*> newEmptyMVar
0 commit comments