module Ribosome.Test.Tmux where import Hedgehog (TestT) import Chiasma.Command.Pane (sendKeys) import Chiasma.Data.TmuxError (TmuxError) import Chiasma.Data.TmuxId (PaneId(PaneId)) import Chiasma.Monad.Stream (runTmux) import Chiasma.Native.Api (TmuxNative(TmuxNative)) import Chiasma.Test.Tmux (TmuxTestConf, withSystemTempDir) import qualified Chiasma.Test.Tmux as Chiasma (tmuxGuiSpec, tmuxSpec, tmuxSpec') import Control.Exception.Lifted (bracket) import Data.DeepPrisms (DeepPrisms) import qualified Data.Text.IO as Text import qualified Neovim.Context.Internal as Internal ( StateTransition(Quit), newConfig, retypeConfig, ) import Neovim.Plugin (Plugin(Plugin)) import Neovim.Plugin.Internal (wrapPlugin) import Neovim.RPC.Common (SocketType(UnixSocket), createHandle, newRPCConfig) import System.Directory (doesPathExist) import System.FilePath ((</>)) import Ribosome.Config.Setting (updateSetting) import Ribosome.Config.Settings (tmuxSocket) import Ribosome.Control.Concurrent.Wait (waitIOPredDef) import Ribosome.Control.Exception (catchAny, tryAny) import Ribosome.Control.Monad.Ribo (NvimE, Ribo) import Ribosome.Control.Ribosome (Ribosome(Ribosome), newRibosomeTMVar) import Ribosome.Error.Report.Class (ReportError) import Ribosome.Msgpack.Encode (toMsgpack) import Ribosome.Nvim.Api.IO (vimSetVar) import Ribosome.Nvim.Api.RpcCall (RpcError) import Ribosome.Plugin.RpcHandler (RpcHandler) import Ribosome.System.Time (sleep) import Ribosome.Test.Embed ( Runner, TestConfig(..), inTestT, runPlugin, runTest, startHandlers, testNvimProcessConfig, withProcessTerm, ) import Ribosome.Test.Orphans () import Ribosome.Test.Run (UnitTest) import Ribosome.Test.Unit (uSpec) runSocketNvimHs :: MonadIO m => MonadFail m => ReportError e => RpcHandler e env n => MonadBaseControl IO m => TestConfig -> env -> n a -> Handle -> m a runSocketNvimHs :: TestConfig -> env -> n a -> Handle -> m a runSocketNvimHs TestConfig conf env ribo n a specThunk Handle socket = do Config RPCConfig nvimConf <- IO (Config RPCConfig) -> m (Config RPCConfig) forall (m :: * -> *) a. MonadIO m => IO a -> m a liftIO (IO (Maybe String) -> IO RPCConfig -> IO (Config RPCConfig) forall env. IO (Maybe String) -> IO env -> IO (Config env) Internal.newConfig (Maybe String -> IO (Maybe String) forall (f :: * -> *) a. Applicative f => a -> f a pure Maybe String forall a. Maybe a Nothing) IO RPCConfig forall (io :: * -> *). (Applicative io, MonadIO io) => io RPCConfig newRPCConfig) let testCfg :: Config env testCfg = env -> Config RPCConfig -> Config env forall env anotherEnv. env -> Config anotherEnv -> Config env Internal.retypeConfig env ribo Config RPCConfig nvimConf m (IO ()) -> (IO () -> m ()) -> (IO () -> m a) -> m a forall (m :: * -> *) a b c. MonadBaseControl IO m => m a -> (a -> m b) -> (a -> m c) -> m c bracket (Handle -> Handle -> TestConfig -> Config RPCConfig -> m (IO ()) forall (m :: * -> *). MonadIO m => Handle -> Handle -> TestConfig -> Config RPCConfig -> m (IO ()) startHandlers Handle socket Handle socket TestConfig conf Config RPCConfig nvimConf) IO () -> m () forall (m :: * -> *) a. MonadIO m => IO a -> m a liftIO (m a -> IO () -> m a forall a b. a -> b -> a const (m a -> IO () -> m a) -> m a -> IO () -> m a forall a b. (a -> b) -> a -> b $ TestConfig -> Config env -> n a -> m a forall (m :: * -> *) e env (n :: * -> *) a. (MonadIO m, MonadFail m, ReportError e, RpcHandler e env n, MonadBaseControl IO m) => TestConfig -> Config env -> n a -> m a runTest TestConfig conf Config env testCfg n a specThunk) externalNvimCmdline :: FilePath -> Text externalNvimCmdline :: String -> Text externalNvimCmdline String socket = Text "nvim --listen " Text -> Text -> Text forall a. Semigroup a => a -> a -> a <> String -> Text forall a. ToText a => a -> Text toText String socket Text -> Text -> Text forall a. Semigroup a => a -> a -> a <> Text " -n -u NONE -i NONE" startNvimInTmux :: TmuxNative -> FilePath -> IO Handle startNvimInTmux :: TmuxNative -> String -> IO Handle startNvimInTmux TmuxNative api String temp = do IO (Either TmuxError ()) -> IO () forall (f :: * -> *) a. Functor f => f a -> f () void (IO (Either TmuxError ()) -> IO ()) -> IO (Either TmuxError ()) -> IO () forall a b. (a -> b) -> a -> b $ forall e (m :: * -> *) a. ExceptT e m a -> m (Either e a) forall (m :: * -> *) a. ExceptT TmuxError m a -> m (Either TmuxError a) runExceptT @TmuxError (ExceptT TmuxError IO () -> IO (Either TmuxError ())) -> ExceptT TmuxError IO () -> IO (Either TmuxError ()) forall a b. (a -> b) -> a -> b $ TmuxNative -> TmuxProg (ExceptT TmuxError IO) () -> ExceptT TmuxError IO () forall (m :: * -> *) e api a. (MonadIO m, MonadDeepError e TmuxError m, TmuxApi m api) => api -> TmuxProg m a -> m a runTmux TmuxNative api (TmuxProg (ExceptT TmuxError IO) () -> ExceptT TmuxError IO ()) -> TmuxProg (ExceptT TmuxError IO) () -> ExceptT TmuxError IO () forall a b. (a -> b) -> a -> b $ PaneId -> [Text] -> TmuxProg (ExceptT TmuxError IO) () forall (m :: * -> *). MonadFree TmuxThunk m => PaneId -> [Text] -> m () sendKeys (Int -> PaneId PaneId Int 0) [String -> Text externalNvimCmdline String socket] Either (WaitError Text) String _ <- IO String -> (String -> IO Bool) -> IO (Either (WaitError Text) String) forall (m :: * -> *) a. (MonadIO m, MonadBaseControl IO m) => m a -> (a -> m Bool) -> m (Either (WaitError Text) a) waitIOPredDef (String -> IO String forall (f :: * -> *) a. Applicative f => a -> f a pure String socket) String -> IO Bool doesPathExist (SomeException -> IO Handle) -> IO Handle -> IO Handle forall (m :: * -> *) a. MonadBaseControl IO m => (SomeException -> m a) -> m a -> m a catchAny SomeException -> IO Handle forall (m :: * -> *) a. MonadFail m => SomeException -> m a err (SocketType -> IO Handle forall (io :: * -> *). (Functor io, MonadIO io) => SocketType -> io Handle createHandle (String -> SocketType UnixSocket String socket)) where socket :: String socket = String temp String -> String -> String </> String "nvim-socket" err :: SomeException -> m a err (SomeException e e) = String -> m a forall (m :: * -> *) a. MonadFail m => String -> m a fail (String "startNvimInTmux: createHandle failed: " String -> String -> String forall a. Semigroup a => a -> a -> a <> e -> String forall b a. (Show a, IsString b) => a -> b show e e) runGui :: MonadIO m => MonadFail m => ReportError e => RpcHandler e env n => MonadBaseControl IO m => TmuxNative -> FilePath -> TestConfig -> env -> n a -> m a runGui :: TmuxNative -> String -> TestConfig -> env -> n a -> m a runGui TmuxNative api String temp TestConfig conf env ribo n a specThunk = TestConfig -> env -> n a -> Handle -> m a forall (m :: * -> *) e env (n :: * -> *) a. (MonadIO m, MonadFail m, ReportError e, RpcHandler e env n, MonadBaseControl IO m) => TestConfig -> env -> n a -> Handle -> m a runSocketNvimHs TestConfig conf env ribo n a specThunk (Handle -> m a) -> m Handle -> m a forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b =<< IO Handle -> m Handle forall (m :: * -> *) a. MonadIO m => IO a -> m a liftIO (TmuxNative -> String -> IO Handle startNvimInTmux TmuxNative api String temp) unsafeGuiSpec :: MonadIO m => MonadFail m => ReportError e => RpcHandler e env n => MonadBaseControl IO m => TmuxNative -> FilePath -> Runner n -> TestConfig -> env -> n a -> m a unsafeGuiSpec :: TmuxNative -> String -> Runner n -> TestConfig -> env -> n a -> m a unsafeGuiSpec TmuxNative api String temp Runner n runner TestConfig conf env s n a specThunk = TmuxNative -> String -> TestConfig -> env -> n a -> m a forall (m :: * -> *) e env (n :: * -> *) a. (MonadIO m, MonadFail m, ReportError e, RpcHandler e env n, MonadBaseControl IO m) => TmuxNative -> String -> TestConfig -> env -> n a -> m a runGui TmuxNative api String temp TestConfig conf env s (n a -> m a) -> n a -> m a forall a b. (a -> b) -> a -> b $ TestConfig -> n a -> n a Runner n runner TestConfig conf n a specThunk unsafeGuiSpecR :: MonadIO m => MonadFail m => ReportError e => MonadBaseControl IO m => RpcHandler e (Ribosome env) n => TmuxNative -> FilePath -> Runner n -> TestConfig -> env -> n a -> m a unsafeGuiSpecR :: TmuxNative -> String -> Runner n -> TestConfig -> env -> n a -> m a unsafeGuiSpecR TmuxNative api String temp Runner n runner TestConfig conf env s n a specThunk = do TMVar (RibosomeState env) tv <- env -> m (TMVar (RibosomeState env)) forall (m :: * -> *) s. MonadIO m => s -> m (TMVar (RibosomeState s)) newRibosomeTMVar env s let ribo :: Ribosome env ribo = Text -> TMVar (RibosomeState env) -> Ribosome env forall s. Text -> TMVar (RibosomeState s) -> Ribosome s Ribosome (TestConfig -> Text tcPluginName TestConfig conf) TMVar (RibosomeState env) tv TmuxNative -> String -> Runner n -> TestConfig -> Ribosome env -> n a -> m a forall (m :: * -> *) e env (n :: * -> *) a. (MonadIO m, MonadFail m, ReportError e, RpcHandler e env n, MonadBaseControl IO m) => TmuxNative -> String -> Runner n -> TestConfig -> env -> n a -> m a unsafeGuiSpec TmuxNative api String temp Runner n runner TestConfig conf Ribosome env ribo n a specThunk guiSpec :: MonadIO m => MonadFail m => ReportError e => MonadBaseControl IO m => DeepPrisms e RpcError => TestConfig -> TmuxNative -> s -> Ribo s e a -> m a guiSpec :: TestConfig -> TmuxNative -> s -> Ribo s e a -> m a guiSpec TestConfig conf TmuxNative api s env Ribo s e a specThunk = do (String -> m a) -> m a forall (m :: * -> *) a. (MonadIO m, MonadBaseControl IO m) => (String -> m a) -> m a withSystemTempDir String -> m a run where run :: String -> m a run String tempdir = TmuxNative -> String -> Runner (Ribo s e) -> TestConfig -> s -> Ribo s e a -> m a forall (m :: * -> *) e env (n :: * -> *) a. (MonadIO m, MonadFail m, ReportError e, MonadBaseControl IO m, RpcHandler e (Ribosome env) n) => TmuxNative -> String -> Runner n -> TestConfig -> env -> n a -> m a unsafeGuiSpecR TmuxNative api String tempdir Runner (Ribo s e) forall (m :: * -> *) e. (MonadIO m, NvimE e m) => Runner m uSpec TestConfig conf s env Ribo s e a specThunk withTmux :: DeepPrisms e RpcError => Ribo s e a -> TmuxNative -> Ribo s e a withTmux :: Ribo s e a -> TmuxNative -> Ribo s e a withTmux Ribo s e a thunk (TmuxNative (Just String socket)) = Setting String -> String -> Ribo s e () forall (m :: * -> *) e a. (MonadRibo m, Nvim m, MonadDeepError e RpcError m, MsgpackEncode a) => Setting a -> a -> m () updateSetting Setting String tmuxSocket String socket Ribo s e () -> Ribo s e a -> Ribo s e a forall (f :: * -> *) a b. Applicative f => f a -> f b -> f b *> Ribo s e a thunk withTmux Ribo s e a _ TmuxNative _ = Text -> Ribo s e a forall (m :: * -> *) a. MonadIO m => Text -> m a throwText Text "no socket in test tmux" tmuxSpec :: DeepPrisms e RpcError => ReportError e => TestConfig -> s -> TestT (Ribo s e) () -> UnitTest tmuxSpec :: TestConfig -> s -> TestT (Ribo s e) () -> UnitTest tmuxSpec TestConfig conf s env TestT (Ribo s e) () specThunk = TestT (Ribo s e) () -> (forall x. Ribo s e x -> IO x) -> UnitTest forall (n :: * -> *) (m :: * -> *) a. TestT n a -> (forall x. n x -> m x) -> TestT m a inTestT TestT (Ribo s e) () specThunk \ Ribo s e x th -> (TmuxNative -> IO x) -> IO x forall (m :: * -> *) a. (MonadIO m, MonadBaseControl IO m) => (TmuxNative -> m a) -> m a Chiasma.tmuxSpec \ TmuxNative api -> TestConfig -> TmuxNative -> s -> Ribo s e x -> IO x forall (m :: * -> *) e s a. (MonadIO m, MonadFail m, ReportError e, MonadBaseControl IO m, DeepPrisms e RpcError) => TestConfig -> TmuxNative -> s -> Ribo s e a -> m a guiSpec TestConfig conf TmuxNative api s env (Ribo s e x -> TmuxNative -> Ribo s e x forall e s a. DeepPrisms e RpcError => Ribo s e a -> TmuxNative -> Ribo s e a withTmux Ribo s e x th TmuxNative api) tmuxSpec' :: DeepPrisms e RpcError => ReportError e => TmuxTestConf -> TestConfig -> s -> TestT (Ribo s e) () -> UnitTest tmuxSpec' :: TmuxTestConf -> TestConfig -> s -> TestT (Ribo s e) () -> UnitTest tmuxSpec' TmuxTestConf tmuxConf TestConfig conf s env TestT (Ribo s e) () specThunk = TestT (Ribo s e) () -> (forall x. Ribo s e x -> IO x) -> UnitTest forall (n :: * -> *) (m :: * -> *) a. TestT n a -> (forall x. n x -> m x) -> TestT m a inTestT TestT (Ribo s e) () specThunk \ Ribo s e x th -> TmuxTestConf -> (TmuxNative -> IO x) -> IO x forall (m :: * -> *) a. (MonadIO m, MonadBaseControl IO m) => TmuxTestConf -> (TmuxNative -> m a) -> m a Chiasma.tmuxSpec' TmuxTestConf tmuxConf \ TmuxNative api -> TestConfig -> TmuxNative -> s -> Ribo s e x -> IO x forall (m :: * -> *) e s a. (MonadIO m, MonadFail m, ReportError e, MonadBaseControl IO m, DeepPrisms e RpcError) => TestConfig -> TmuxNative -> s -> Ribo s e a -> m a guiSpec TestConfig conf TmuxNative api s env (Ribo s e x -> TmuxNative -> Ribo s e x forall e s a. DeepPrisms e RpcError => Ribo s e a -> TmuxNative -> Ribo s e a withTmux Ribo s e x th TmuxNative api) tmuxSpecDef :: DeepPrisms e RpcError => ReportError e => Default s => TestT (Ribo s e) () -> UnitTest tmuxSpecDef :: TestT (Ribo s e) () -> UnitTest tmuxSpecDef = TestConfig -> s -> TestT (Ribo s e) () -> UnitTest forall e s. (DeepPrisms e RpcError, ReportError e) => TestConfig -> s -> TestT (Ribo s e) () -> UnitTest tmuxSpec TestConfig forall a. Default a => a def s forall a. Default a => a def tmuxGuiSpec :: DeepPrisms e RpcError => ReportError e => TestConfig -> s -> Ribo s e () -> UnitTest tmuxGuiSpec :: TestConfig -> s -> Ribo s e () -> UnitTest tmuxGuiSpec TestConfig conf s env Ribo s e () specThunk = (TmuxNative -> UnitTest) -> UnitTest forall (m :: * -> *) a. (MonadIO m, MonadBaseControl IO m) => (TmuxNative -> m a) -> m a Chiasma.tmuxGuiSpec TmuxNative -> UnitTest run where run :: TmuxNative -> UnitTest run TmuxNative api = TestConfig -> TmuxNative -> s -> Ribo s e () -> UnitTest forall (m :: * -> *) e s a. (MonadIO m, MonadFail m, ReportError e, MonadBaseControl IO m, DeepPrisms e RpcError) => TestConfig -> TmuxNative -> s -> Ribo s e a -> m a guiSpec TestConfig conf TmuxNative api s env (Ribo s e () -> TmuxNative -> Ribo s e () forall e s a. DeepPrisms e RpcError => Ribo s e a -> TmuxNative -> Ribo s e a withTmux Ribo s e () specThunk TmuxNative api) tmuxGuiSpecDef :: DeepPrisms e RpcError => ReportError e => Default s => Ribo s e () -> UnitTest tmuxGuiSpecDef :: Ribo s e () -> UnitTest tmuxGuiSpecDef = TestConfig -> s -> Ribo s e () -> UnitTest forall e s. (DeepPrisms e RpcError, ReportError e) => TestConfig -> s -> Ribo s e () -> UnitTest tmuxGuiSpec TestConfig forall a. Default a => a def s forall a. Default a => a def withTmuxInt :: NvimE e m => MonadIO m => Text -> m () -> TmuxNative -> m () withTmuxInt :: Text -> m () -> TmuxNative -> m () withTmuxInt Text name m () thunk (TmuxNative (Just String socket)) = do () <- Text -> Object -> m () forall (m :: * -> *) e a. (Nvim m, MonadDeepError e RpcError m, MsgpackDecode a) => Text -> Object -> m a vimSetVar (Text name Text -> Text -> Text forall a. Semigroup a => a -> a -> a <> Text "_tmux_socket") (String -> Object forall a. MsgpackEncode a => a -> Object toMsgpack String socket) m () thunk withTmuxInt Text _ m () _ TmuxNative _ = Text -> m () forall (m :: * -> *) a. MonadIO m => Text -> m a throwText Text "no socket in test tmux" runTmuxWithPlugin :: MonadIO m => MonadFail m => ReportError e => RpcHandler e env n => MonadBaseControl IO m => TmuxNative -> TestConfig -> Plugin env -> n () -> m () runTmuxWithPlugin :: TmuxNative -> TestConfig -> Plugin env -> n () -> m () runTmuxWithPlugin TmuxNative api TestConfig conf plugin :: Plugin env plugin@(Plugin env env [ExportedFunctionality env] _) n () thunk = do (String -> m ()) -> m () forall (m :: * -> *) a. (MonadIO m, MonadBaseControl IO m) => (String -> m a) -> m a withSystemTempDir String -> m () runProc where runProc :: String -> m () runProc String temp = (SomeException -> m ()) -> (() -> m ()) -> Either SomeException () -> m () forall a c b. (a -> c) -> (b -> c) -> Either a b -> c either SomeException -> m () forall (m :: * -> *). MonadIO m => SomeException -> m () logError () -> m () forall (f :: * -> *) a. Applicative f => a -> f a pure (Either SomeException () -> m ()) -> m (Either SomeException ()) -> m () forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b =<< (m () -> m (Either SomeException ()) forall (m :: * -> *) a. MonadBaseControl IO m => m a -> m (Either SomeException a) tryAny (ProcessConfig Handle Handle () -> (Process Handle Handle () -> m ()) -> m () forall (m :: * -> *) stdin stdout stderr a. (MonadIO m, MonadBaseControl IO m) => ProcessConfig stdin stdout stderr -> (Process stdin stdout stderr -> m a) -> m a withProcessTerm (TestConfig -> ProcessConfig Handle Handle () testNvimProcessConfig TestConfig conf) (String -> Process Handle Handle () -> m () run String temp))) run :: String -> Process Handle Handle () -> m () run String temp Process Handle Handle () prc = do Config env nvimConf <- IO (Config env) -> m (Config env) forall (m :: * -> *) a. MonadIO m => IO a -> m a liftIO (IO (Maybe String) -> IO env -> IO (Config env) forall env. IO (Maybe String) -> IO env -> IO (Config env) Internal.newConfig (Maybe String -> IO (Maybe String) forall (f :: * -> *) a. Applicative f => a -> f a pure Maybe String forall a. Maybe a Nothing) (env -> IO env forall (f :: * -> *) a. Applicative f => a -> f a pure env env)) m (MVar StateTransition) -> (MVar StateTransition -> m ()) -> (MVar StateTransition -> m ()) -> m () forall (m :: * -> *) a b c. MonadBaseControl IO m => m a -> (a -> m b) -> (a -> m c) -> m c bracket (Process Handle Handle () -> Config env -> String -> m (MVar StateTransition) acquire Process Handle Handle () prc Config env nvimConf String temp) MVar StateTransition -> m () forall (f :: * -> *). MonadIO f => MVar StateTransition -> f () release (m () -> MVar StateTransition -> m () forall a b. a -> b -> a const (m () -> MVar StateTransition -> m ()) -> m () -> MVar StateTransition -> m () forall a b. (a -> b) -> a -> b $ TestConfig -> Config env -> n () -> m () forall (m :: * -> *) e env (n :: * -> *) a. (MonadIO m, MonadFail m, ReportError e, RpcHandler e env n, MonadBaseControl IO m) => TestConfig -> Config env -> n a -> m a runTest TestConfig conf Config env nvimConf n () thunk) acquire :: Process Handle Handle () -> Config env -> String -> m (MVar StateTransition) acquire Process Handle Handle () _ Config env nvimConf String temp = do Handle socket <- IO Handle -> m Handle forall (m :: * -> *) a. MonadIO m => IO a -> m a liftIO (TmuxNative -> String -> IO Handle startNvimInTmux TmuxNative api String temp) Handle -> Handle -> [Neovim () NeovimPlugin] -> Config env -> m (MVar StateTransition) forall (m :: * -> *) c. (MonadIO m, MonadBaseControl IO m) => Handle -> Handle -> [Neovim () NeovimPlugin] -> Config c -> m (MVar StateTransition) runPlugin Handle socket Handle socket [Plugin env -> Neovim () NeovimPlugin forall (m :: * -> *) env. Applicative m => Plugin env -> m NeovimPlugin wrapPlugin Plugin env plugin] Config env nvimConf m (MVar StateTransition) -> m () -> m (MVar StateTransition) forall (f :: * -> *) a b. Applicative f => f a -> f b -> f a <* Double -> m () forall (m :: * -> *). MonadIO m => Double -> m () sleep Double 0.5 release :: MVar StateTransition -> f () release MVar StateTransition transitions = MVar StateTransition -> StateTransition -> f Bool forall (m :: * -> *) a. MonadIO m => MVar a -> a -> m Bool tryPutMVar MVar StateTransition transitions StateTransition Internal.Quit f Bool -> f () -> f () forall (f :: * -> *) a b. Applicative f => f a -> f b -> f b *> Double -> f () forall (m :: * -> *). MonadIO m => Double -> m () sleep Double 0.5 logError :: SomeException -> m () logError (SomeException e e) = IO () -> m () forall (m :: * -> *) a. MonadIO m => IO a -> m a liftIO (Handle -> Text -> IO () Text.hPutStr Handle stderr (Text "runTmuxWithPlugin: nvim process failed with: " Text -> Text -> Text forall a. Semigroup a => a -> a -> a <> e -> Text forall b a. (Show a, IsString b) => a -> b show e e)) tmuxIntegrationSpecDef :: NvimE e n => MonadIO m => MonadIO n => MonadFail m => ReportError e => RpcHandler e env n => MonadBaseControl IO m => Text -> Plugin env -> n () -> m () tmuxIntegrationSpecDef :: Text -> Plugin env -> n () -> m () tmuxIntegrationSpecDef Text name Plugin env plugin n () specThunk = (TmuxNative -> m ()) -> m () forall (m :: * -> *) a. (MonadIO m, MonadBaseControl IO m) => (TmuxNative -> m a) -> m a Chiasma.tmuxGuiSpec TmuxNative -> m () run where run :: TmuxNative -> m () run TmuxNative api = TmuxNative -> TestConfig -> Plugin env -> n () -> m () forall (m :: * -> *) e env (n :: * -> *). (MonadIO m, MonadFail m, ReportError e, RpcHandler e env n, MonadBaseControl IO m) => TmuxNative -> TestConfig -> Plugin env -> n () -> m () runTmuxWithPlugin TmuxNative api TestConfig forall a. Default a => a def Plugin env plugin (Text -> n () -> TmuxNative -> n () forall e (m :: * -> *). (NvimE e m, MonadIO m) => Text -> m () -> TmuxNative -> m () withTmuxInt Text name n () specThunk TmuxNative api)