module Ribosome.Test.Exists( waitForPlugin, sleep, ) where import Data.Time.Clock.POSIX import Data.Strings (strCapitalize) import Control.Monad.IO.Class import Control.Concurrent (threadDelay) import Neovim epochSeconds :: MonadIO f => f Int epochSeconds = liftIO $ fmap round getPOSIXTime sleep :: MonadIO f => Double -> f () sleep seconds = liftIO $ threadDelay $ round $ seconds * 10e6 retry :: MonadIO f => Double -> Int -> f a -> (a -> f (Either String b)) -> f b retry interval timeout thunk check = do start <- epochSeconds step start where step start = do result <- thunk checked <- check result recurse start checked recurse _ (Right b) = return b recurse start (Left e) = do current <- epochSeconds if (current - start) < timeout then do sleep interval step start else fail e waitForPlugin :: String -> Double -> Int -> Neovim env () waitForPlugin name interval timeout = do retry interval timeout thunk check where thunk = vim_call_function "exists" [toObject $ "*" ++ (strCapitalize name) ++ "Poll"] check (Right (ObjectInt 1)) = return $ Right () check (Right a) = return $ Left $ errormsg ++ "weird return type " ++ (show a) check (Left e) = return $ Left $ errormsg ++ (show e) errormsg = "plugin didn't start within " ++ (show timeout) ++ " seconds: "