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)