chiasma-0.2.0.0: lib/Chiasma/Native/Api.hs
{-# LANGUAGE UndecidableInstances #-}
module Chiasma.Native.Api where
import Chiasma.Data.TmuxError (TmuxError)
import Conduit (ConduitT, Flush, mapC, (.|))
import Control.Monad.Catch (MonadMask)
import qualified Control.Monad.Catch as Catch (bracket)
import Data.Conduit.Process.Typed (createSource)
import qualified Data.Text as Text (unwords)
import System.Process.Typed (
Process,
ProcessConfig,
getStdin,
getStdout,
proc,
setStdin,
setStdout,
startProcess,
stopProcess,
)
import Text.ParserCombinators.Parsec ()
import Chiasma.Api.Class (TmuxApi(..))
import Chiasma.Data.Cmd (Cmd(..), CmdArgs(..), CmdName(..))
import Chiasma.Data.Conduit (createSinkFlush)
import Chiasma.Native.Process (nativeTmuxProcess, socketArg)
import Chiasma.Native.StreamParse (parseConduit)
newtype TmuxNative =
TmuxNative { tmuxServerSocket :: Maybe FilePath }
deriving Show
formatCmd :: Cmd -> ByteString
formatCmd (Cmd (CmdName name) (CmdArgs args)) =
encodeUtf8 . Text.unwords $ name : args ++ ["\n"]
tmuxProcessConfig ::
MonadIO m =>
Maybe FilePath ->
ProcessConfig (ConduitT (Flush ByteString) Void m ()) (ConduitT () ByteString m ()) ()
tmuxProcessConfig sock =
cons args
where
cons =
setStdin createSinkFlush . setStdout createSource . proc "tmux"
args =
toString <$> (socketArg sock ++ ["-C", "attach"])
withProcess :: (MonadIO m, MonadMask m)
=> ProcessConfig stdin stdout stderr
-> (Process stdin stdout stderr -> m a)
-> m a
withProcess config = Catch.bracket (startProcess config) stopProcess
instance (MonadIO m, MonadDeepError e TmuxError m, MonadMask m) => TmuxApi m TmuxNative where
runCommands (TmuxNative socket) =
nativeTmuxProcess socket
withTmux (TmuxNative socket) f =
withProcess (tmuxProcessConfig socket) handler
where
handler prc =
let
stdin' = mapC (fmap formatCmd) .| getStdin prc
stdout' = getStdout prc .| parseConduit
in f stdin' stdout'