packages feed

chiasma 0.1.0.0 → 0.2.0.0

raw patch · 91 files changed

+4271/−558 lines, 91 filesdep +aesondep +attoparsecdep +compositiondep −HTFdep −data-default-classdep ~basedep ~eitherdep ~freesetup-changedPVP ok

version bump matches the API change (PVP)

Dependencies added: aeson, attoparsec, composition, composition-extra, conduit, conduit-extra, containers, cornea, data-default, deepseq, exceptions, hedgehog, parsers, prettyprinter, prettyprinter-ansi-terminal, random, relude, stm-chans, stm-conduit, tasty, tasty-hedgehog, text, unliftio-core, uuid

Dependencies removed: HTF, data-default-class

Dependency ranges changed: base, either, free, lens, posix-pty, process, resourcet, split, typed-process, unliftio

API changes (from Hackage documentation)

- Chiasma.Api.Class: class DecodeTmuxResponse a
- Chiasma.Api.Class: decode :: DecodeTmuxResponse a => String -> Either TmuxError a
- Chiasma.Codec: [unQ] :: TmuxQuery -> String
- Chiasma.Codec.Decode: instance (Chiasma.Codec.Decode.TmuxDataDecode f, Chiasma.Codec.Decode.TmuxDataDecode g) => Chiasma.Codec.Decode.TmuxDataDecode (f GHC.Generics.:*: g)
- Chiasma.Codec.Decode: instance Chiasma.Codec.Decode.TmuxDataDecode f => Chiasma.Codec.Decode.TmuxDataDecode (GHC.Generics.M1 i c f)
- Chiasma.Data.Pane: Pane :: PaneId -> Int -> Int -> Pane
- Chiasma.Data.Pane: PaneId :: Int -> PaneId
- Chiasma.Data.Pane: [paneHeight] :: Pane -> Int
- Chiasma.Data.Pane: [paneId] :: Pane -> PaneId
- Chiasma.Data.Pane: [paneWidth] :: Pane -> Int
- Chiasma.Data.Pane: data Pane
- Chiasma.Data.Pane: instance Chiasma.Codec.Decode.TmuxPrimDecode Chiasma.Data.Pane.PaneId
- Chiasma.Data.Pane: instance Chiasma.Codec.TmuxCodec Chiasma.Data.Pane.Pane
- Chiasma.Data.Pane: instance GHC.Classes.Eq Chiasma.Data.Pane.Pane
- Chiasma.Data.Pane: instance GHC.Classes.Eq Chiasma.Data.Pane.PaneId
- Chiasma.Data.Pane: instance GHC.Generics.Generic Chiasma.Data.Pane.Pane
- Chiasma.Data.Pane: instance GHC.Show.Show Chiasma.Data.Pane.Pane
- Chiasma.Data.Pane: instance GHC.Show.Show Chiasma.Data.Pane.PaneId
- Chiasma.Data.Pane: newtype PaneId
- Chiasma.Data.TmuxThunk: Cmd :: CmdName -> CmdArgs -> Cmd
- Chiasma.Data.TmuxThunk: CmdArgs :: [String] -> CmdArgs
- Chiasma.Data.TmuxThunk: CmdName :: String -> CmdName
- Chiasma.Data.TmuxThunk: Cmds :: [Cmd] -> Cmds
- Chiasma.Data.TmuxThunk: DecodingFailed :: Cmds -> String -> TmuxDecodeError -> TmuxError
- Chiasma.Data.TmuxThunk: NoOutput :: Cmds -> TmuxError
- Chiasma.Data.TmuxThunk: OutputParsingFailed :: Cmds -> [String] -> ParseError -> TmuxError
- Chiasma.Data.TmuxThunk: ProcessFailed :: Cmds -> String -> TmuxError
- Chiasma.Data.TmuxThunk: cmd :: String -> [String] -> Cmd
- Chiasma.Data.TmuxThunk: data Cmd
- Chiasma.Data.TmuxThunk: data TmuxError
- Chiasma.Data.TmuxThunk: instance GHC.Classes.Eq Chiasma.Data.TmuxThunk.Cmd
- Chiasma.Data.TmuxThunk: instance GHC.Classes.Eq Chiasma.Data.TmuxThunk.CmdArgs
- Chiasma.Data.TmuxThunk: instance GHC.Classes.Eq Chiasma.Data.TmuxThunk.CmdName
- Chiasma.Data.TmuxThunk: instance GHC.Classes.Eq Chiasma.Data.TmuxThunk.Cmds
- Chiasma.Data.TmuxThunk: instance GHC.Classes.Eq Chiasma.Data.TmuxThunk.TmuxError
- Chiasma.Data.TmuxThunk: instance GHC.Show.Show Chiasma.Data.TmuxThunk.Cmd
- Chiasma.Data.TmuxThunk: instance GHC.Show.Show Chiasma.Data.TmuxThunk.CmdArgs
- Chiasma.Data.TmuxThunk: instance GHC.Show.Show Chiasma.Data.TmuxThunk.CmdName
- Chiasma.Data.TmuxThunk: instance GHC.Show.Show Chiasma.Data.TmuxThunk.Cmds
- Chiasma.Data.TmuxThunk: instance GHC.Show.Show Chiasma.Data.TmuxThunk.TmuxError
- Chiasma.Data.TmuxThunk: newtype CmdArgs
- Chiasma.Data.TmuxThunk: newtype CmdName
- Chiasma.Data.TmuxThunk: newtype Cmds
- Chiasma.Data.Window: Window :: WindowId -> Int -> Int -> Window
- Chiasma.Data.Window: WindowId :: Int -> WindowId
- Chiasma.Data.Window: [windowHeight] :: Window -> Int
- Chiasma.Data.Window: [windowId] :: Window -> WindowId
- Chiasma.Data.Window: [windowWidth] :: Window -> Int
- Chiasma.Data.Window: data Window
- Chiasma.Data.Window: instance Chiasma.Codec.Decode.TmuxPrimDecode Chiasma.Data.Window.WindowId
- Chiasma.Data.Window: instance Chiasma.Codec.TmuxCodec Chiasma.Data.Window.Window
- Chiasma.Data.Window: instance GHC.Classes.Eq Chiasma.Data.Window.Window
- Chiasma.Data.Window: instance GHC.Classes.Eq Chiasma.Data.Window.WindowId
- Chiasma.Data.Window: instance GHC.Generics.Generic Chiasma.Data.Window.Window
- Chiasma.Data.Window: instance GHC.Show.Show Chiasma.Data.Window.Window
- Chiasma.Data.Window: instance GHC.Show.Show Chiasma.Data.Window.WindowId
- Chiasma.Data.Window: newtype WindowId
- Chiasma.Monad.Buffered: instance Data.Default.Class.Default Chiasma.Monad.Buffered.TmuxState
- Chiasma.Monad.Buffered: runTmux :: (MonadIO m, TmuxApi api) => api -> TmuxProg b -> m (Either TmuxError b)
- Chiasma.Monad.Tmux: type TmuxProg = Free TmuxThunk
- Chiasma.Native.Api: class TmuxApi a
- Chiasma.Native.Api: instance Chiasma.Api.Class.TmuxApi Chiasma.Native.Api.TmuxNative
- Chiasma.Native.Api: runCommands :: (TmuxApi a, MonadIO m) => a -> ([String] -> Either TmuxDecodeError b) -> Cmds -> ExceptT TmuxError m [b]
+ Chiasma.Api.Class: withTmux :: TmuxApi m a => a -> (ConduitT (Flush Cmd) Void m () -> ConduitT () TmuxOutputBlock m () -> m b) -> m b
+ Chiasma.Codec: [$sel:unQ:TmuxQuery] :: TmuxQuery -> Text
+ Chiasma.Codec: genDecode :: (Generic a, TmuxDataDecode (Rep a)) => Text -> Either TmuxDecodeError a
+ Chiasma.Codec: instance Chiasma.Codec.TmuxCodec Chiasma.Data.TmuxId.PaneId
+ Chiasma.Codec: instance Chiasma.Codec.TmuxCodec Chiasma.Data.TmuxId.SessionId
+ Chiasma.Codec: instance Chiasma.Codec.TmuxCodec Chiasma.Data.TmuxId.WindowId
+ Chiasma.Codec.Data: Pane :: PaneId -> Int -> Int -> Pane
+ Chiasma.Codec.Data: Session :: SessionId -> Session
+ Chiasma.Codec.Data: Window :: WindowId -> Int -> Int -> Window
+ Chiasma.Codec.Data: [$sel:paneHeight:Pane] :: Pane -> Int
+ Chiasma.Codec.Data: [$sel:paneId:Pane] :: Pane -> PaneId
+ Chiasma.Codec.Data: [$sel:paneWidth:Pane] :: Pane -> Int
+ Chiasma.Codec.Data: [$sel:sessionId:Session] :: Session -> SessionId
+ Chiasma.Codec.Data: [$sel:windowHeight:Window] :: Window -> Int
+ Chiasma.Codec.Data: [$sel:windowId:Window] :: Window -> WindowId
+ Chiasma.Codec.Data: [$sel:windowWidth:Window] :: Window -> Int
+ Chiasma.Codec.Data: data Pane
+ Chiasma.Codec.Data: data Session
+ Chiasma.Codec.Data: data Window
+ Chiasma.Codec.Data.Pane: Pane :: PaneId -> Int -> Int -> Pane
+ Chiasma.Codec.Data.Pane: [$sel:paneHeight:Pane] :: Pane -> Int
+ Chiasma.Codec.Data.Pane: [$sel:paneId:Pane] :: Pane -> PaneId
+ Chiasma.Codec.Data.Pane: [$sel:paneWidth:Pane] :: Pane -> Int
+ Chiasma.Codec.Data.Pane: data Pane
+ Chiasma.Codec.Data.Pane: instance Chiasma.Codec.TmuxCodec Chiasma.Codec.Data.Pane.Pane
+ Chiasma.Codec.Data.Pane: instance Chiasma.Data.TmuxId.HasPaneId Chiasma.Codec.Data.Pane.Pane
+ Chiasma.Codec.Data.Pane: instance GHC.Classes.Eq Chiasma.Codec.Data.Pane.Pane
+ Chiasma.Codec.Data.Pane: instance GHC.Generics.Generic Chiasma.Codec.Data.Pane.Pane
+ Chiasma.Codec.Data.Pane: instance GHC.Show.Show Chiasma.Codec.Data.Pane.Pane
+ Chiasma.Codec.Data.PaneCoords: PaneCoords :: SessionId -> WindowId -> PaneId -> PaneCoords
+ Chiasma.Codec.Data.PaneCoords: [$sel:paneId:PaneCoords] :: PaneCoords -> PaneId
+ Chiasma.Codec.Data.PaneCoords: [$sel:sessionId:PaneCoords] :: PaneCoords -> SessionId
+ Chiasma.Codec.Data.PaneCoords: [$sel:windowId:PaneCoords] :: PaneCoords -> WindowId
+ Chiasma.Codec.Data.PaneCoords: data PaneCoords
+ Chiasma.Codec.Data.PaneCoords: instance Chiasma.Codec.TmuxCodec Chiasma.Codec.Data.PaneCoords.PaneCoords
+ Chiasma.Codec.Data.PaneCoords: instance Chiasma.Data.TmuxId.HasPaneId Chiasma.Codec.Data.PaneCoords.PaneCoords
+ Chiasma.Codec.Data.PaneCoords: instance GHC.Classes.Eq Chiasma.Codec.Data.PaneCoords.PaneCoords
+ Chiasma.Codec.Data.PaneCoords: instance GHC.Generics.Generic Chiasma.Codec.Data.PaneCoords.PaneCoords
+ Chiasma.Codec.Data.PaneCoords: instance GHC.Show.Show Chiasma.Codec.Data.PaneCoords.PaneCoords
+ Chiasma.Codec.Data.PaneDetail: PaneDetail :: PaneId -> Int -> Int -> Int -> Int -> PaneDetail
+ Chiasma.Codec.Data.PaneDetail: [$sel:paneHeight:PaneDetail] :: PaneDetail -> Int
+ Chiasma.Codec.Data.PaneDetail: [$sel:paneId:PaneDetail] :: PaneDetail -> PaneId
+ Chiasma.Codec.Data.PaneDetail: [$sel:paneLeft:PaneDetail] :: PaneDetail -> Int
+ Chiasma.Codec.Data.PaneDetail: [$sel:paneTop:PaneDetail] :: PaneDetail -> Int
+ Chiasma.Codec.Data.PaneDetail: [$sel:paneWidth:PaneDetail] :: PaneDetail -> Int
+ Chiasma.Codec.Data.PaneDetail: data PaneDetail
+ Chiasma.Codec.Data.PaneDetail: instance Chiasma.Codec.TmuxCodec Chiasma.Codec.Data.PaneDetail.PaneDetail
+ Chiasma.Codec.Data.PaneDetail: instance Chiasma.Data.TmuxId.HasPaneId Chiasma.Codec.Data.PaneDetail.PaneDetail
+ Chiasma.Codec.Data.PaneDetail: instance GHC.Classes.Eq Chiasma.Codec.Data.PaneDetail.PaneDetail
+ Chiasma.Codec.Data.PaneDetail: instance GHC.Generics.Generic Chiasma.Codec.Data.PaneDetail.PaneDetail
+ Chiasma.Codec.Data.PaneDetail: instance GHC.Show.Show Chiasma.Codec.Data.PaneDetail.PaneDetail
+ Chiasma.Codec.Data.PaneMode: PaneMode :: PaneId -> Text -> PaneMode
+ Chiasma.Codec.Data.PaneMode: [$sel:paneId:PaneMode] :: PaneMode -> PaneId
+ Chiasma.Codec.Data.PaneMode: [$sel:paneMode:PaneMode] :: PaneMode -> Text
+ Chiasma.Codec.Data.PaneMode: data PaneMode
+ Chiasma.Codec.Data.PaneMode: instance Chiasma.Codec.TmuxCodec Chiasma.Codec.Data.PaneMode.PaneMode
+ Chiasma.Codec.Data.PaneMode: instance Chiasma.Data.TmuxId.HasPaneId Chiasma.Codec.Data.PaneMode.PaneMode
+ Chiasma.Codec.Data.PaneMode: instance GHC.Classes.Eq Chiasma.Codec.Data.PaneMode.PaneMode
+ Chiasma.Codec.Data.PaneMode: instance GHC.Generics.Generic Chiasma.Codec.Data.PaneMode.PaneMode
+ Chiasma.Codec.Data.PaneMode: instance GHC.Show.Show Chiasma.Codec.Data.PaneMode.PaneMode
+ Chiasma.Codec.Data.PanePid: PanePid :: PaneId -> Int -> PanePid
+ Chiasma.Codec.Data.PanePid: [$sel:paneId:PanePid] :: PanePid -> PaneId
+ Chiasma.Codec.Data.PanePid: [$sel:panePid:PanePid] :: PanePid -> Int
+ Chiasma.Codec.Data.PanePid: data PanePid
+ Chiasma.Codec.Data.PanePid: instance Chiasma.Codec.TmuxCodec Chiasma.Codec.Data.PanePid.PanePid
+ Chiasma.Codec.Data.PanePid: instance Chiasma.Data.TmuxId.HasPaneId Chiasma.Codec.Data.PanePid.PanePid
+ Chiasma.Codec.Data.PanePid: instance GHC.Classes.Eq Chiasma.Codec.Data.PanePid.PanePid
+ Chiasma.Codec.Data.PanePid: instance GHC.Generics.Generic Chiasma.Codec.Data.PanePid.PanePid
+ Chiasma.Codec.Data.PanePid: instance GHC.Show.Show Chiasma.Codec.Data.PanePid.PanePid
+ Chiasma.Codec.Data.Session: Session :: SessionId -> Session
+ Chiasma.Codec.Data.Session: [$sel:sessionId:Session] :: Session -> SessionId
+ Chiasma.Codec.Data.Session: data Session
+ Chiasma.Codec.Data.Session: instance Chiasma.Codec.TmuxCodec Chiasma.Codec.Data.Session.Session
+ Chiasma.Codec.Data.Session: instance GHC.Classes.Eq Chiasma.Codec.Data.Session.Session
+ Chiasma.Codec.Data.Session: instance GHC.Generics.Generic Chiasma.Codec.Data.Session.Session
+ Chiasma.Codec.Data.Session: instance GHC.Show.Show Chiasma.Codec.Data.Session.Session
+ Chiasma.Codec.Data.Window: Window :: WindowId -> Int -> Int -> Window
+ Chiasma.Codec.Data.Window: [$sel:windowHeight:Window] :: Window -> Int
+ Chiasma.Codec.Data.Window: [$sel:windowId:Window] :: Window -> WindowId
+ Chiasma.Codec.Data.Window: [$sel:windowWidth:Window] :: Window -> Int
+ Chiasma.Codec.Data.Window: data Window
+ Chiasma.Codec.Data.Window: instance Chiasma.Codec.TmuxCodec Chiasma.Codec.Data.Window.Window
+ Chiasma.Codec.Data.Window: instance GHC.Classes.Eq Chiasma.Codec.Data.Window.Window
+ Chiasma.Codec.Data.Window: instance GHC.Generics.Generic Chiasma.Codec.Data.Window.Window
+ Chiasma.Codec.Data.Window: instance GHC.Show.Show Chiasma.Codec.Data.Window.Window
+ Chiasma.Codec.Decode: BoolParsingFailure :: Text -> TmuxDecodeError
+ Chiasma.Codec.Decode: instance Chiasma.Codec.Decode.TmuxPrimDecode Chiasma.Data.TmuxId.PaneId
+ Chiasma.Codec.Decode: instance Chiasma.Codec.Decode.TmuxPrimDecode Chiasma.Data.TmuxId.SessionId
+ Chiasma.Codec.Decode: instance Chiasma.Codec.Decode.TmuxPrimDecode Chiasma.Data.TmuxId.WindowId
+ Chiasma.Codec.Decode: instance Chiasma.Codec.Decode.TmuxPrimDecode Data.Text.Internal.Text
+ Chiasma.Codec.Decode: instance Chiasma.Codec.Decode.TmuxPrimDecode GHC.Types.Bool
+ Chiasma.Codec.Decode: instance Chiasma.Codec.Decode.TmuxPrimDecode [GHC.Types.Char]
+ Chiasma.Codec.Decode: instance forall k (f :: k -> *) (g :: k -> *). (Chiasma.Codec.Decode.TmuxDataDecode f, Chiasma.Codec.Decode.TmuxDataDecode g) => Chiasma.Codec.Decode.TmuxDataDecode (f GHC.Generics.:*: g)
+ Chiasma.Codec.Decode: instance forall k (f :: k -> *) i (c :: GHC.Generics.Meta). Chiasma.Codec.Decode.TmuxDataDecode f => Chiasma.Codec.Decode.TmuxDataDecode (GHC.Generics.M1 i c f)
+ Chiasma.Codec.Query: formatQuery :: Text -> Text
+ Chiasma.Codec.Query: snakeCase :: Text -> Text
+ Chiasma.Codec.Query: trans :: Char -> Text
+ Chiasma.Command.Pane: capturePane :: MonadFree TmuxThunk m => PaneId -> m [Text]
+ Chiasma.Command.Pane: closePane :: MonadFree TmuxThunk m => PaneId -> m ()
+ Chiasma.Command.Pane: copyMode :: MonadFree TmuxThunk m => PaneId -> m ()
+ Chiasma.Command.Pane: firstWindowPane :: MonadFree TmuxThunk m => WindowId -> m Pane
+ Chiasma.Command.Pane: formatLine :: Text -> [Text]
+ Chiasma.Command.Pane: isPaneIdOpen :: MonadFree TmuxThunk m => PaneId -> m Bool
+ Chiasma.Command.Pane: isPaneOpen :: MonadFree TmuxThunk m => View PaneId -> m Bool
+ Chiasma.Command.Pane: movePane :: MonadFree TmuxThunk m => PaneId -> PaneId -> Bool -> m ()
+ Chiasma.Command.Pane: pane :: (MonadFree TmuxThunk m, TmuxCodec a, HasPaneId a) => PaneId -> m (Maybe a)
+ Chiasma.Command.Pane: paneCoords :: MonadFree TmuxThunk m => PaneId -> m (Maybe PaneCoords)
+ Chiasma.Command.Pane: paneMode :: MonadFree TmuxThunk m => PaneId -> m (Maybe PaneMode)
+ Chiasma.Command.Pane: panePid :: MonadFree TmuxThunk m => PaneId -> m (Maybe PanePid)
+ Chiasma.Command.Pane: panePids :: MonadFree TmuxThunk m => m [PanePid]
+ Chiasma.Command.Pane: paneTarget :: PaneId -> [Text]
+ Chiasma.Command.Pane: panes :: MonadFree TmuxThunk m => m [Pane]
+ Chiasma.Command.Pane: panesAs :: (MonadFree TmuxThunk m, TmuxCodec a) => m [a]
+ Chiasma.Command.Pane: pipePane :: MonadFree TmuxThunk m => PaneId -> Text -> m ()
+ Chiasma.Command.Pane: quitCopyMode :: MonadFree TmuxThunk m => PaneId -> m ()
+ Chiasma.Command.Pane: resizePane :: MonadFree TmuxThunk m => PaneId -> Bool -> Int -> m ()
+ Chiasma.Command.Pane: sameId :: HasPaneId a => PaneId -> a -> Bool
+ Chiasma.Command.Pane: selectPane :: MonadFree TmuxThunk m => PaneId -> m ()
+ Chiasma.Command.Pane: sendKeys :: MonadFree TmuxThunk m => PaneId -> [Text] -> m ()
+ Chiasma.Command.Pane: windowPanes :: MonadFree TmuxThunk m => WindowId -> m [Pane]
+ Chiasma.Command.Pane: windowPanesAs :: (MonadFree TmuxThunk m, TmuxCodec a) => WindowId -> m [a]
+ Chiasma.Command.Session: activateSession :: MonadFree TmuxThunk m => Int -> m ()
+ Chiasma.Command.Session: doesSessionExist :: MonadFree TmuxThunk m => SessionId -> m Bool
+ Chiasma.Command.Session: existingSessionId :: MonadFree TmuxThunk m => SessionId -> m (Maybe SessionId)
+ Chiasma.Command.Session: newSession :: MonadFree TmuxThunk m => Ident -> m Session
+ Chiasma.Command.Session: sameId :: SessionId -> Session -> Bool
+ Chiasma.Command.Session: sessions :: MonadFree TmuxThunk m => m [Session]
+ Chiasma.Command.Window: doesWindowExist :: MonadFree TmuxThunk m => WindowId -> m Bool
+ Chiasma.Command.Window: newSessionWindow :: MonadFree TmuxThunk m => SessionId -> m Window
+ Chiasma.Command.Window: newWindow :: MonadFree TmuxThunk m => SessionId -> Ident -> m Window
+ Chiasma.Command.Window: sameId :: WindowId -> Window -> Bool
+ Chiasma.Command.Window: sessionWindows :: MonadFree TmuxThunk m => SessionId -> m [Window]
+ Chiasma.Command.Window: splitWindow :: MonadFree TmuxThunk m => FilePath -> WindowId -> m Pane
+ Chiasma.Command.Window: splitWindowAs :: (MonadFree TmuxThunk m, TmuxCodec a) => FilePath -> WindowId -> m a
+ Chiasma.Command.Window: window :: MonadFree TmuxThunk m => WindowId -> m (Maybe Window)
+ Chiasma.Command.Window: windows :: MonadFree TmuxThunk m => m [Window]
+ Chiasma.Control.IO.Unsafe: unsafeLog :: Show a => a -> b -> b
+ Chiasma.Data.Cmd: Cmd :: CmdName -> CmdArgs -> Cmd
+ Chiasma.Data.Cmd: CmdArgs :: [Text] -> CmdArgs
+ Chiasma.Data.Cmd: CmdName :: Text -> CmdName
+ Chiasma.Data.Cmd: Cmds :: [Cmd] -> Cmds
+ Chiasma.Data.Cmd: cmd :: Text -> [Text] -> Cmd
+ Chiasma.Data.Cmd: data Cmd
+ Chiasma.Data.Cmd: instance GHC.Classes.Eq Chiasma.Data.Cmd.Cmd
+ Chiasma.Data.Cmd: instance GHC.Classes.Eq Chiasma.Data.Cmd.CmdArgs
+ Chiasma.Data.Cmd: instance GHC.Classes.Eq Chiasma.Data.Cmd.CmdName
+ Chiasma.Data.Cmd: instance GHC.Classes.Eq Chiasma.Data.Cmd.Cmds
+ Chiasma.Data.Cmd: instance GHC.Show.Show Chiasma.Data.Cmd.Cmd
+ Chiasma.Data.Cmd: instance GHC.Show.Show Chiasma.Data.Cmd.CmdArgs
+ Chiasma.Data.Cmd: instance GHC.Show.Show Chiasma.Data.Cmd.CmdName
+ Chiasma.Data.Cmd: instance GHC.Show.Show Chiasma.Data.Cmd.Cmds
+ Chiasma.Data.Cmd: newtype CmdArgs
+ Chiasma.Data.Cmd: newtype CmdName
+ Chiasma.Data.Cmd: newtype Cmds
+ Chiasma.Data.Conduit: createSinkFlush :: MonadIO m => StreamSpec 'STInput (ConduitT (Flush ByteString) o m ())
+ Chiasma.Data.Ident: Str :: Text -> Ident
+ Chiasma.Data.Ident: Uuid :: UUID -> Ident
+ Chiasma.Data.Ident: class Identifiable a
+ Chiasma.Data.Ident: data Ident
+ Chiasma.Data.Ident: generateIdent :: MonadIO m => m Ident
+ Chiasma.Data.Ident: identText :: Ident -> Text
+ Chiasma.Data.Ident: identify :: Identifiable a => a -> Ident
+ Chiasma.Data.Ident: instance Chiasma.Data.Ident.Identifiable Chiasma.Data.Ident.Ident
+ Chiasma.Data.Ident: instance Control.DeepSeq.NFData Chiasma.Data.Ident.Ident
+ Chiasma.Data.Ident: instance Data.Aeson.Types.FromJSON.FromJSON Chiasma.Data.Ident.Ident
+ Chiasma.Data.Ident: instance Data.Aeson.Types.ToJSON.ToJSON Chiasma.Data.Ident.Ident
+ Chiasma.Data.Ident: instance Data.Data.Data Chiasma.Data.Ident.Ident
+ Chiasma.Data.Ident: instance Data.Default.Class.Default Chiasma.Data.Ident.Ident
+ Chiasma.Data.Ident: instance Data.String.IsString Chiasma.Data.Ident.Ident
+ Chiasma.Data.Ident: instance GHC.Classes.Eq Chiasma.Data.Ident.Ident
+ Chiasma.Data.Ident: instance GHC.Classes.Ord Chiasma.Data.Ident.Ident
+ Chiasma.Data.Ident: instance GHC.Generics.Generic Chiasma.Data.Ident.Ident
+ Chiasma.Data.Ident: instance GHC.Show.Show Chiasma.Data.Ident.Ident
+ Chiasma.Data.Ident: instance Prettyprinter.Internal.Pretty Chiasma.Data.Ident.Ident
+ Chiasma.Data.Ident: parseIdent :: Text -> Ident
+ Chiasma.Data.Ident: sameIdent :: Identifiable a => Identifiable b => a -> b -> Bool
+ Chiasma.Data.List: head' :: [a] -> Maybe a
+ Chiasma.Data.List: last' :: [a] -> Maybe a
+ Chiasma.Data.List: tail' :: [a] -> Maybe [a]
+ Chiasma.Data.Maybe: findMaybe :: (a -> Maybe b) -> [a] -> Maybe b
+ Chiasma.Data.Maybe: maybeExcept :: MonadError e m => e -> Maybe a -> m a
+ Chiasma.Data.Maybe: orElse :: Maybe a -> Maybe a -> Maybe a
+ Chiasma.Data.RenderError: Fatal :: TmuxError -> RenderError
+ Chiasma.Data.RenderError: NoPrincipal :: Ident -> RenderError
+ Chiasma.Data.RenderError: Pack :: Text -> RenderError
+ Chiasma.Data.RenderError: Views :: ViewsError -> RenderError
+ Chiasma.Data.RenderError: _Fatal :: AsRenderError r_a10xW => Prism' r_a10xW TmuxError
+ Chiasma.Data.RenderError: _NoPrincipal :: AsRenderError r_a10xW => Prism' r_a10xW Ident
+ Chiasma.Data.RenderError: _Pack :: AsRenderError r_a10xW => Prism' r_a10xW Text
+ Chiasma.Data.RenderError: _RenderError :: AsRenderError r_a10xW => Prism' r_a10xW RenderError
+ Chiasma.Data.RenderError: _Views :: AsRenderError r_a10xW => Prism' r_a10xW ViewsError
+ Chiasma.Data.RenderError: class AsRenderError r_a10xW
+ Chiasma.Data.RenderError: data RenderError
+ Chiasma.Data.RenderError: instance Chiasma.Data.RenderError.AsRenderError Chiasma.Data.RenderError.RenderError
+ Chiasma.Data.RenderError: instance Data.DeepPrisms.DeepPrisms Chiasma.Data.RenderError.RenderError Chiasma.Data.RenderError.RenderError
+ Chiasma.Data.RenderError: instance Data.DeepPrisms.DeepPrisms Chiasma.Data.RenderError.RenderError Chiasma.Data.TmuxError.TmuxError
+ Chiasma.Data.RenderError: instance Data.DeepPrisms.DeepPrisms Chiasma.Data.RenderError.RenderError Chiasma.Data.Views.ViewsError
+ Chiasma.Data.RenderError: instance GHC.Classes.Eq Chiasma.Data.RenderError.RenderError
+ Chiasma.Data.RenderError: instance GHC.Show.Show Chiasma.Data.RenderError.RenderError
+ Chiasma.Data.TmuxError: CommandFailed :: Cmds -> [Text] -> TmuxError
+ Chiasma.Data.TmuxError: DecodingFailed :: Cmds -> Text -> TmuxDecodeError -> TmuxError
+ Chiasma.Data.TmuxError: InvalidOutput :: Text -> Text -> TmuxError
+ Chiasma.Data.TmuxError: NoOutput :: Cmds -> TmuxError
+ Chiasma.Data.TmuxError: OutputParsingFailed :: Cmds -> [Text] -> ParseError -> TmuxError
+ Chiasma.Data.TmuxError: ProcessFailed :: Cmds -> Text -> TmuxError
+ Chiasma.Data.TmuxError: [$sel:commandFailedCmds:ProcessFailed] :: TmuxError -> Cmds
+ Chiasma.Data.TmuxError: [$sel:commandFailedError:ProcessFailed] :: TmuxError -> [Text]
+ Chiasma.Data.TmuxError: [$sel:decodingFailedCmds:ProcessFailed] :: TmuxError -> Cmds
+ Chiasma.Data.TmuxError: [$sel:decodingFailedError:ProcessFailed] :: TmuxError -> TmuxDecodeError
+ Chiasma.Data.TmuxError: [$sel:decodingFailedOutput:ProcessFailed] :: TmuxError -> Text
+ Chiasma.Data.TmuxError: [$sel:invalidOutputCommand:ProcessFailed] :: TmuxError -> Text
+ Chiasma.Data.TmuxError: [$sel:invalidOutputReason:ProcessFailed] :: TmuxError -> Text
+ Chiasma.Data.TmuxError: [$sel:parsingFailedCmds:ProcessFailed] :: TmuxError -> Cmds
+ Chiasma.Data.TmuxError: [$sel:parsingFailedError:ProcessFailed] :: TmuxError -> ParseError
+ Chiasma.Data.TmuxError: [$sel:parsingFailedOutput:ProcessFailed] :: TmuxError -> [Text]
+ Chiasma.Data.TmuxError: [$sel:processFailedCmds:ProcessFailed] :: TmuxError -> Cmds
+ Chiasma.Data.TmuxError: [$sel:processFailedReason:ProcessFailed] :: TmuxError -> Text
+ Chiasma.Data.TmuxError: data TmuxError
+ Chiasma.Data.TmuxError: instance Data.DeepPrisms.DeepPrisms Chiasma.Data.TmuxError.TmuxError Chiasma.Data.TmuxError.TmuxError
+ Chiasma.Data.TmuxError: instance GHC.Classes.Eq Chiasma.Data.TmuxError.TmuxError
+ Chiasma.Data.TmuxError: instance GHC.Show.Show Chiasma.Data.TmuxError.TmuxError
+ Chiasma.Data.TmuxId: PaneId :: Int -> PaneId
+ Chiasma.Data.TmuxId: SessionId :: Int -> SessionId
+ Chiasma.Data.TmuxId: TmuxIdPrefix :: Char -> TmuxIdPrefix a
+ Chiasma.Data.TmuxId: WindowId :: Int -> WindowId
+ Chiasma.Data.TmuxId: class HasPaneId a
+ Chiasma.Data.TmuxId: class TmuxId a
+ Chiasma.Data.TmuxId: formatId :: TmuxId a => a -> Text
+ Chiasma.Data.TmuxId: instance Chiasma.Data.TmuxId.TmuxId Chiasma.Data.TmuxId.PaneId
+ Chiasma.Data.TmuxId: instance Chiasma.Data.TmuxId.TmuxId Chiasma.Data.TmuxId.SessionId
+ Chiasma.Data.TmuxId: instance Chiasma.Data.TmuxId.TmuxId Chiasma.Data.TmuxId.WindowId
+ Chiasma.Data.TmuxId: instance GHC.Classes.Eq Chiasma.Data.TmuxId.PaneId
+ Chiasma.Data.TmuxId: instance GHC.Classes.Eq Chiasma.Data.TmuxId.SessionId
+ Chiasma.Data.TmuxId: instance GHC.Classes.Eq Chiasma.Data.TmuxId.WindowId
+ Chiasma.Data.TmuxId: instance GHC.Classes.Ord Chiasma.Data.TmuxId.PaneId
+ Chiasma.Data.TmuxId: instance GHC.Classes.Ord Chiasma.Data.TmuxId.SessionId
+ Chiasma.Data.TmuxId: instance GHC.Classes.Ord Chiasma.Data.TmuxId.WindowId
+ Chiasma.Data.TmuxId: instance GHC.Generics.Generic Chiasma.Data.TmuxId.PaneId
+ Chiasma.Data.TmuxId: instance GHC.Generics.Generic Chiasma.Data.TmuxId.SessionId
+ Chiasma.Data.TmuxId: instance GHC.Generics.Generic Chiasma.Data.TmuxId.WindowId
+ Chiasma.Data.TmuxId: instance GHC.Num.Num Chiasma.Data.TmuxId.PaneId
+ Chiasma.Data.TmuxId: instance GHC.Num.Num Chiasma.Data.TmuxId.SessionId
+ Chiasma.Data.TmuxId: instance GHC.Num.Num Chiasma.Data.TmuxId.WindowId
+ Chiasma.Data.TmuxId: instance GHC.Show.Show Chiasma.Data.TmuxId.PaneId
+ Chiasma.Data.TmuxId: instance GHC.Show.Show Chiasma.Data.TmuxId.SessionId
+ Chiasma.Data.TmuxId: instance GHC.Show.Show Chiasma.Data.TmuxId.WindowId
+ Chiasma.Data.TmuxId: instance Prettyprinter.Internal.Pretty Chiasma.Data.TmuxId.PaneId
+ Chiasma.Data.TmuxId: instance Prettyprinter.Internal.Pretty Chiasma.Data.TmuxId.SessionId
+ Chiasma.Data.TmuxId: instance Prettyprinter.Internal.Pretty Chiasma.Data.TmuxId.WindowId
+ Chiasma.Data.TmuxId: newtype PaneId
+ Chiasma.Data.TmuxId: newtype SessionId
+ Chiasma.Data.TmuxId: newtype TmuxIdPrefix a
+ Chiasma.Data.TmuxId: newtype WindowId
+ Chiasma.Data.TmuxId: number :: TmuxId a => a -> Int
+ Chiasma.Data.TmuxId: paneId :: HasPaneId a => a -> PaneId
+ Chiasma.Data.TmuxId: panePrefix :: Char
+ Chiasma.Data.TmuxId: prefix :: TmuxId a => TmuxIdPrefix a
+ Chiasma.Data.TmuxId: sessionPrefix :: Char
+ Chiasma.Data.TmuxId: windowPrefix :: Char
+ Chiasma.Data.TmuxThunk: Flush :: (() -> next) -> TmuxThunk next
+ Chiasma.Data.View: View :: Ident -> Maybe a -> View a
+ Chiasma.Data.View: [$sel:viewId:View] :: View a -> Maybe a
+ Chiasma.Data.View: [$sel:viewIdent:View] :: View a -> Ident
+ Chiasma.Data.View: _viewId :: HasView c_aRzy a_aRx7 => Lens' c_aRzy (Maybe a_aRx7)
+ Chiasma.Data.View: _viewIdent :: HasView c_aRzy a_aRx7 => Lens' c_aRzy Ident
+ Chiasma.Data.View: class HasView c_aRzy a_aRx7 | c_aRzy -> a_aRx7
+ Chiasma.Data.View: data View a
+ Chiasma.Data.View: instance Chiasma.Data.Ident.Identifiable (Chiasma.Data.View.View a)
+ Chiasma.Data.View: instance Chiasma.Data.View.HasView (Chiasma.Data.View.View a) a
+ Chiasma.Data.View: instance GHC.Classes.Eq a => GHC.Classes.Eq (Chiasma.Data.View.View a)
+ Chiasma.Data.View: instance GHC.Show.Show a => GHC.Show.Show (Chiasma.Data.View.View a)
+ Chiasma.Data.View: setViewId :: a -> View a -> View a
+ Chiasma.Data.View: view :: HasView c_aRzy a_aRx7 => Lens' c_aRzy (View a_aRx7)
+ Chiasma.Data.Views: NoPaneId :: Ident -> ViewsError
+ Chiasma.Data.Views: NoSuchPane :: Ident -> ViewsError
+ Chiasma.Data.Views: NoSuchSession :: Ident -> ViewsError
+ Chiasma.Data.Views: NoSuchWindow :: Ident -> ViewsError
+ Chiasma.Data.Views: Views :: [View SessionId] -> [View WindowId] -> [View PaneId] -> [Doc AnsiStyle] -> Views
+ Chiasma.Data.Views: [$sel:_log:Views] :: Views -> [Doc AnsiStyle]
+ Chiasma.Data.Views: [$sel:_panes:Views] :: Views -> [View PaneId]
+ Chiasma.Data.Views: [$sel:_sessions:Views] :: Views -> [View SessionId]
+ Chiasma.Data.Views: [$sel:_windows:Views] :: Views -> [View WindowId]
+ Chiasma.Data.Views: _NoPaneId :: AsViewsError r_aScM => Prism' r_aScM Ident
+ Chiasma.Data.Views: _NoSuchPane :: AsViewsError r_aScM => Prism' r_aScM Ident
+ Chiasma.Data.Views: _NoSuchSession :: AsViewsError r_aScM => Prism' r_aScM Ident
+ Chiasma.Data.Views: _NoSuchWindow :: AsViewsError r_aScM => Prism' r_aScM Ident
+ Chiasma.Data.Views: _ViewsError :: AsViewsError r_aScM => Prism' r_aScM ViewsError
+ Chiasma.Data.Views: class AsViewsError r_aScM
+ Chiasma.Data.Views: class HasViews c_aStQ
+ Chiasma.Data.Views: data Views
+ Chiasma.Data.Views: data ViewsError
+ Chiasma.Data.Views: instance Chiasma.Data.Views.AsViewsError Chiasma.Data.Views.ViewsError
+ Chiasma.Data.Views: instance Chiasma.Data.Views.HasViews Chiasma.Data.Views.Views
+ Chiasma.Data.Views: instance Data.DeepLenses.DeepLenses Chiasma.Data.Views.Views Chiasma.Data.Views.Views
+ Chiasma.Data.Views: instance Data.DeepPrisms.DeepPrisms Chiasma.Data.Views.ViewsError Chiasma.Data.Views.ViewsError
+ Chiasma.Data.Views: instance Data.Default.Class.Default Chiasma.Data.Views.Views
+ Chiasma.Data.Views: instance GHC.Classes.Eq Chiasma.Data.Views.Views
+ Chiasma.Data.Views: instance GHC.Classes.Eq Chiasma.Data.Views.ViewsError
+ Chiasma.Data.Views: instance GHC.Generics.Generic Chiasma.Data.Views.Views
+ Chiasma.Data.Views: instance GHC.Show.Show Chiasma.Data.Views.Views
+ Chiasma.Data.Views: instance GHC.Show.Show Chiasma.Data.Views.ViewsError
+ Chiasma.Data.Views: log :: HasViews c_aStQ => Lens' c_aStQ [Doc AnsiStyle]
+ Chiasma.Data.Views: panes :: HasViews c_aStQ => Lens' c_aStQ [View PaneId]
+ Chiasma.Data.Views: sessions :: HasViews c_aStQ => Lens' c_aStQ [View SessionId]
+ Chiasma.Data.Views: views :: HasViews c_aStQ => Lens' c_aStQ Views
+ Chiasma.Data.Views: windows :: HasViews c_aStQ => Lens' c_aStQ [View WindowId]
+ Chiasma.Data.WindowState: WindowState :: Window -> Pane -> Ident -> RenderableTree -> PaneId -> WindowState
+ Chiasma.Data.WindowState: [$sel:wsLayout:WindowState] :: WindowState -> RenderableTree
+ Chiasma.Data.WindowState: [$sel:wsNativeRefPane:WindowState] :: WindowState -> Pane
+ Chiasma.Data.WindowState: [$sel:wsNativeWindow:WindowState] :: WindowState -> Window
+ Chiasma.Data.WindowState: [$sel:wsReferencePane:WindowState] :: WindowState -> PaneId
+ Chiasma.Data.WindowState: [$sel:wsWindowIdent:WindowState] :: WindowState -> Ident
+ Chiasma.Data.WindowState: data WindowState
+ Chiasma.Data.WindowState: instance GHC.Classes.Eq Chiasma.Data.WindowState.WindowState
+ Chiasma.Data.WindowState: instance GHC.Show.Show Chiasma.Data.WindowState.WindowState
+ Chiasma.Lens.Tree: LeafIndexTree :: Tree l p -> LeafIndexTree l p
+ Chiasma.Lens.Tree: NodeIndexTree :: Tree l p -> NodeIndexTree l p
+ Chiasma.Lens.Tree: [$sel:litTree:LeafIndexTree] :: LeafIndexTree l p -> Tree l p
+ Chiasma.Lens.Tree: [$sel:nitTree:NodeIndexTree] :: NodeIndexTree l p -> Tree l p
+ Chiasma.Lens.Tree: _litTree :: HasLeafIndexTree c_aMwG l_aMrh p_aMri => Lens' c_aMwG (Tree l_aMrh p_aMri)
+ Chiasma.Lens.Tree: _nitTree :: HasNodeIndexTree c_aMr9 l_aMnF p_aMnG => Lens' c_aMr9 (Tree l_aMnF p_aMnG)
+ Chiasma.Lens.Tree: class HasLeafIndexTree c_aMwG l_aMrh p_aMri | c_aMwG -> l_aMrh p_aMri
+ Chiasma.Lens.Tree: class HasNodeIndexTree c_aMr9 l_aMnF p_aMnG | c_aMr9 -> l_aMnF p_aMnG
+ Chiasma.Lens.Tree: instance (Data.Data.Data l, Data.Data.Data p) => Control.Lens.Plated.Plated (Chiasma.Lens.Tree.LeafIndexTree l p)
+ Chiasma.Lens.Tree: instance (Data.Data.Data l, Data.Data.Data p) => Control.Lens.Plated.Plated (Chiasma.Lens.Tree.NodeIndexTree l p)
+ Chiasma.Lens.Tree: instance (GHC.Classes.Eq l, GHC.Classes.Eq p) => GHC.Classes.Eq (Chiasma.Lens.Tree.LeafIndexTree l p)
+ Chiasma.Lens.Tree: instance (GHC.Classes.Eq l, GHC.Classes.Eq p) => GHC.Classes.Eq (Chiasma.Lens.Tree.NodeIndexTree l p)
+ Chiasma.Lens.Tree: instance (GHC.Show.Show l, GHC.Show.Show p) => GHC.Show.Show (Chiasma.Lens.Tree.LeafIndexTree l p)
+ Chiasma.Lens.Tree: instance (GHC.Show.Show l, GHC.Show.Show p) => GHC.Show.Show (Chiasma.Lens.Tree.NodeIndexTree l p)
+ Chiasma.Lens.Tree: instance Chiasma.Data.Ident.Identifiable p => Control.Lens.At.Ixed (Chiasma.Lens.Tree.LeafIndexTree l p)
+ Chiasma.Lens.Tree: instance Chiasma.Lens.Tree.HasLeafIndexTree (Chiasma.Lens.Tree.LeafIndexTree l p) l p
+ Chiasma.Lens.Tree: instance Chiasma.Lens.Tree.HasNodeIndexTree (Chiasma.Lens.Tree.NodeIndexTree l p) l p
+ Chiasma.Lens.Tree: leafByIdent :: (Identifiable p, Data l, Data p) => Ident -> Tree l p -> Maybe p
+ Chiasma.Lens.Tree: leafByIdentTraversal :: Identifiable p => Ident -> Traversal' (Tree l p) p
+ Chiasma.Lens.Tree: leafDataTraversal :: Traversal' (Tree l p) p
+ Chiasma.Lens.Tree: leafIndexTree :: HasLeafIndexTree c_aMwG l_aMrh p_aMri => Lens' c_aMwG (LeafIndexTree l_aMrh p_aMri)
+ Chiasma.Lens.Tree: leavesByIdent :: (Identifiable p, Data l, Data p) => Ident -> Tree l p -> [p]
+ Chiasma.Lens.Tree: leavesByIdentRecursive :: (Identifiable p, Data l, Data p) => Ident -> Fold (LeafIndexTree l p) p
+ Chiasma.Lens.Tree: modifyLeafByIdent :: (Identifiable p, Data l, Data p) => Ident -> (p -> p) -> Tree l p -> Tree l p
+ Chiasma.Lens.Tree: newtype LeafIndexTree l p
+ Chiasma.Lens.Tree: newtype NodeIndexTree l p
+ Chiasma.Lens.Tree: nodeIndexTree :: HasNodeIndexTree c_aMr9 l_aMnF p_aMnG => Lens' c_aMr9 (NodeIndexTree l_aMnF p_aMnG)
+ Chiasma.Lens.Tree: plateWrap :: (Data l, Data p) => (Tree l p -> t l p) -> (t l p -> Tree l p) -> Traversal' (t l p) (t l p)
+ Chiasma.Lens.Tree: subtrees :: forall l p m. Monad m => (TreeSub l p -> m (TreeSub l p)) -> Tree l p -> m (Tree l p)
+ Chiasma.Lens.Tree: subtreesWithLayout :: forall l p m. Monad m => ((l, TreeSub l p) -> m (l, TreeSub l p)) -> Tree l p -> m (Tree l p)
+ Chiasma.Lens.Tree: treesAndSubs :: Monad m => (Tree l p -> m (Tree l p)) -> (TreeSub l p -> m (TreeSub l p)) -> Tree l p -> m (Tree l p)
+ Chiasma.Lens.Tree: type LayoutIndexTree = NodeIndexTree LayoutView PaneView
+ Chiasma.Lens.Tree: type PaneIndexTree = LeafIndexTree LayoutView PaneView
+ Chiasma.Lens.Where: where1 :: (Applicative f, Traversable t) => (a -> Bool) -> Over (->) f (t a) (t a) a a
+ Chiasma.Monad.EvalFreeT: CmdBuffer :: [Cmd] -> CmdBuffer
+ Chiasma.Monad.EvalFreeT: evalFreeF :: Monad m => CommandExec m -> CmdBuffer -> FreeF TmuxThunk a (FreeT TmuxThunk m a) -> m (Either TmuxError a)
+ Chiasma.Monad.EvalFreeT: evalFreeT :: Monad m => CommandExec m -> CmdBuffer -> FreeT TmuxThunk m a -> m (Either TmuxError a)
+ Chiasma.Monad.EvalFreeT: instance Data.Default.Class.Default Chiasma.Monad.EvalFreeT.CmdBuffer
+ Chiasma.Monad.EvalFreeT: newtype CmdBuffer
+ Chiasma.Monad.EvalFreeT: type CommandExec m = (forall b. (Text -> Either TmuxDecodeError b) -> Cmds -> m (Either TmuxError [b]))
+ Chiasma.Monad.IndividualProcess: TmuxState :: [Cmd] -> TmuxState
+ Chiasma.Monad.IndividualProcess: instance Data.Default.Class.Default Chiasma.Monad.IndividualProcess.TmuxState
+ Chiasma.Monad.IndividualProcess: interpret :: (TmuxApi m api, MonadDeepError e TmuxError m) => TmuxState -> api -> TmuxProg a -> m a
+ Chiasma.Monad.IndividualProcess: newtype TmuxState
+ Chiasma.Monad.IndividualProcess: runTmux :: (TmuxApi m api, MonadDeepError e TmuxError m) => api -> TmuxProg a -> m a
+ Chiasma.Monad.IndividualProcess: type TmuxProg = Free TmuxThunk
+ Chiasma.Monad.Stream: executeCommands :: MonadIO m => WriteCmd m -> ReadOutput m -> (Text -> Either TmuxDecodeError a) -> Cmds -> m (Either TmuxError [a])
+ Chiasma.Monad.Stream: handleProcessOutput :: Cmds -> (Text -> Either TmuxDecodeError a) -> [TmuxOutputBlock] -> Either TmuxError [a]
+ Chiasma.Monad.Stream: runTmux :: (MonadIO m, MonadDeepError e TmuxError m, TmuxApi m api) => api -> TmuxProg m a -> m a
+ Chiasma.Monad.Stream: runTmuxE :: (MonadIO m, TmuxApi m api) => api -> TmuxProg m a -> m (Either TmuxError a)
+ Chiasma.Monad.Stream: runTmuxProg :: MonadIO m => TmuxProg m a -> WriteCmd m -> ReadOutput m -> m (Either TmuxError a)
+ Chiasma.Monad.Stream: type ReadOutput m = ConduitT () TmuxOutputBlock m ()
+ Chiasma.Monad.Stream: type TmuxProg = FreeT TmuxThunk
+ Chiasma.Monad.Stream: type WriteCmd m = ConduitT (Flush Cmd) Void m ()
+ Chiasma.Monad.Tmux: flush :: MonadFree TmuxThunk m => m ()
+ Chiasma.Monad.Tmux: readFirst :: forall a m. (TmuxCodec a, MonadFree TmuxThunk m) => Text -> [Text] -> m (Maybe a)
+ Chiasma.Monad.Tmux: readRaw :: forall m. MonadFree TmuxThunk m => Text -> [Text] -> m [Text]
+ Chiasma.Monad.Tmux: unsafeReadFirst :: forall a m. (TmuxCodec a, MonadFree TmuxThunk m) => Text -> [Text] -> m a
+ Chiasma.Monad.Tmux: unsafeReadOne :: forall a m. (TmuxCodec a, MonadFree TmuxThunk m) => Text -> [Text] -> m a
+ Chiasma.Native.Api: [$sel:tmuxServerSocket:TmuxNative] :: TmuxNative -> Maybe FilePath
+ Chiasma.Native.Api: formatCmd :: Cmd -> ByteString
+ Chiasma.Native.Api: instance (Control.Monad.IO.Class.MonadIO m, Control.Monad.DeepError.MonadDeepError e Chiasma.Data.TmuxError.TmuxError m, Control.Monad.Catch.MonadMask m) => Chiasma.Api.Class.TmuxApi m Chiasma.Native.Api.TmuxNative
+ Chiasma.Native.Api: instance GHC.Show.Show Chiasma.Native.Api.TmuxNative
+ Chiasma.Native.Api: tmuxProcessConfig :: MonadIO m => Maybe FilePath -> ProcessConfig (ConduitT (Flush ByteString) Void m ()) (ConduitT () ByteString m ()) ()
+ Chiasma.Native.Api: withProcess :: (MonadIO m, MonadMask m) => ProcessConfig stdin stdout stderr -> (Process stdin stdout stderr -> m a) -> m a
+ Chiasma.Native.Parse: beginLine :: GenParser st Text
+ Chiasma.Native.Parse: endLine :: GenParser st Text
+ Chiasma.Native.Parse: parseBlock :: GenParser st [Text]
+ Chiasma.Native.Parse: tillEol :: GenParser st Text
+ Chiasma.Native.Process: cmdBytes :: [Text] -> ByteString
+ Chiasma.Native.Process: formatCmd :: Cmd -> Text
+ Chiasma.Native.Process: handleProcessOutput :: Cmds -> ExitCode -> (Text -> Either TmuxDecodeError a) -> Text -> Either TmuxError [a]
+ Chiasma.Native.Process: socketArg :: Maybe FilePath -> [Text]
+ Chiasma.Native.StreamParse: Error :: [Text] -> TmuxOutputBlock
+ Chiasma.Native.StreamParse: Success :: [Text] -> TmuxOutputBlock
+ Chiasma.Native.StreamParse: data TmuxOutputBlock
+ Chiasma.Native.StreamParse: instance GHC.Classes.Eq Chiasma.Native.StreamParse.End
+ Chiasma.Native.StreamParse: instance GHC.Classes.Eq Chiasma.Native.StreamParse.TmuxOutputBlock
+ Chiasma.Native.StreamParse: instance GHC.Show.Show Chiasma.Native.StreamParse.End
+ Chiasma.Native.StreamParse: instance GHC.Show.Show Chiasma.Native.StreamParse.TmuxOutputBlock
+ Chiasma.Native.StreamParse: parseBlocks :: (Alternative m, CharParsing m, Monad m, LookAheadParsing m) => m [TmuxOutputBlock]
+ Chiasma.Native.StreamParse: parseConduit :: MonadThrow m => ConduitT ByteString TmuxOutputBlock m ()
+ Chiasma.Pack: describeVertical :: Bool -> Doc a
+ Chiasma.Pack: needPositioning :: NonEmpty MeasureTreeSub -> Bool
+ Chiasma.Pack: packPane :: (MonadDeepState s Views m, MonadFree TmuxThunk m) => PaneId -> Bool -> PaneId -> m ()
+ Chiasma.Pack: packTree :: (MonadDeepState s Views m, MonadFree TmuxThunk m) => MeasureTree -> m ()
+ Chiasma.Pack: packWindow :: (MonadDeepState s Views m, MonadFree TmuxThunk m) => WindowState -> m ()
+ Chiasma.Pack: positionView :: (MonadDeepState s Views m, MonadFree TmuxThunk m) => Bool -> PaneId -> MeasureTreeSub -> m ()
+ Chiasma.Pack: resizeView :: MonadDeepState s Views m => MonadFree TmuxThunk m => Bool -> MeasureTreeSub -> m ()
+ Chiasma.Pane: addPane :: MonadDeepState s Views m => Ident -> m (View PaneId)
+ Chiasma.Prelude: (!!?) :: [a] -> Int -> Maybe a
+ Chiasma.Prelude: ($!!) :: NFData a => (a -> b) -> a -> b
+ Chiasma.Prelude: ($!) :: forall (r :: RuntimeRep) a (b :: TYPE r). (a -> b) -> a -> b
+ Chiasma.Prelude: ($) :: forall (r :: RuntimeRep) a (b :: TYPE r). (a -> b) -> a -> b
+ Chiasma.Prelude: ($<) :: Contravariant f => f b -> b -> f a
+ Chiasma.Prelude: ($>) :: Functor f => f a -> b -> f b
+ Chiasma.Prelude: (&&&) :: Arrow a => a b c -> a b c' -> a b (c, c')
+ Chiasma.Prelude: (&&) :: Bool -> Bool -> Bool
+ Chiasma.Prelude: (&&^) :: Monad m => m Bool -> m Bool -> m Bool
+ Chiasma.Prelude: (&) :: a -> (a -> b) -> b
+ Chiasma.Prelude: (*) :: Num a => a -> a -> a
+ Chiasma.Prelude: (**) :: Floating a => a -> a -> a
+ Chiasma.Prelude: (*>) :: Applicative f => f a -> f b -> f b
+ Chiasma.Prelude: (+) :: Num a => a -> a -> a
+ Chiasma.Prelude: (++) :: [a] -> [a] -> [a]
+ Chiasma.Prelude: (-) :: Num a => a -> a -> a
+ Chiasma.Prelude: (.) :: (b -> c) -> (a -> b) -> a -> c
+ Chiasma.Prelude: (/) :: Fractional a => a -> a -> a
+ Chiasma.Prelude: (/=) :: Eq a => a -> a -> Bool
+ Chiasma.Prelude: (:|) :: a -> [a] -> NonEmpty a
+ Chiasma.Prelude: (<$!>) :: Monad m => (a -> b) -> m a -> m b
+ Chiasma.Prelude: (<$$>) :: (Functor f0, Functor f1) => (a -> b) -> f1 (f0 a) -> f1 (f0 b)
+ Chiasma.Prelude: (<$) :: Functor f => a -> f b -> f a
+ Chiasma.Prelude: (<$>) :: Functor f => (a -> b) -> f a -> f b
+ Chiasma.Prelude: (<&>) :: Functor f => f a -> (a -> b) -> f b
+ Chiasma.Prelude: (<) :: Ord a => a -> a -> Bool
+ Chiasma.Prelude: (<*) :: Applicative f => f a -> f b -> f a
+ Chiasma.Prelude: (<**>) :: Applicative f => f a -> f (a -> b) -> f b
+ Chiasma.Prelude: (<*>) :: Applicative f => f (a -> b) -> f a -> f b
+ Chiasma.Prelude: (<<$>>) :: (Functor f, Functor g) => (a -> b) -> f (g a) -> f (g b)
+ Chiasma.Prelude: (<<<) :: forall k cat (b :: k) (c :: k) (a :: k). Category cat => cat b c -> cat a b -> cat a c
+ Chiasma.Prelude: (<=) :: Ord a => a -> a -> Bool
+ Chiasma.Prelude: (<=<) :: Monad m => (b -> m c) -> (a -> m b) -> a -> m c
+ Chiasma.Prelude: (<>) :: Semigroup a => a -> a -> a
+ Chiasma.Prelude: (<|>) :: Alternative f => f a -> f a -> f a
+ Chiasma.Prelude: (=<<) :: Monad m => (a -> m b) -> m a -> m b
+ Chiasma.Prelude: (==) :: Eq a => a -> a -> Bool
+ Chiasma.Prelude: (>$$<) :: Contravariant f => f b -> (a -> b) -> f a
+ Chiasma.Prelude: (>$) :: Contravariant f => b -> f b -> f a
+ Chiasma.Prelude: (>$<) :: Contravariant f => (a -> b) -> f b -> f a
+ Chiasma.Prelude: (>) :: Ord a => a -> a -> Bool
+ Chiasma.Prelude: (>=) :: Ord a => a -> a -> Bool
+ Chiasma.Prelude: (>=>) :: Monad m => (a -> m b) -> (b -> m c) -> a -> m c
+ Chiasma.Prelude: (>>) :: Monad m => m a -> m b -> m b
+ Chiasma.Prelude: (>>=) :: Monad m => m a -> (a -> m b) -> m b
+ Chiasma.Prelude: (>>>) :: forall k cat (a :: k) (b :: k) (c :: k). Category cat => cat a b -> cat b c -> cat a c
+ Chiasma.Prelude: (?:) :: Maybe a -> a -> a
+ Chiasma.Prelude: (??) :: Functor f => f (a -> b) -> a -> f b
+ Chiasma.Prelude: (^) :: (Num a, Integral b) => a -> b -> a
+ Chiasma.Prelude: (^^) :: (Fractional a, Integral b) => a -> b -> a
+ Chiasma.Prelude: (||) :: Bool -> Bool -> Bool
+ Chiasma.Prelude: (||^) :: Monad m => m Bool -> m Bool -> m Bool
+ Chiasma.Prelude: -- | Type of single element of the structure.
+ Chiasma.Prelude: All :: Bool -> All
+ Chiasma.Prelude: Alt :: f a -> Alt (f :: k -> Type) (a :: k)
+ Chiasma.Prelude: Any :: Bool -> Any
+ Chiasma.Prelude: Ap :: f a -> Ap (f :: k -> Type) (a :: k)
+ Chiasma.Prelude: AppendMode :: IOMode
+ Chiasma.Prelude: Bug :: SomeException -> CallStack -> Bug
+ Chiasma.Prelude: Comparison :: (a -> a -> Ordering) -> Comparison a
+ Chiasma.Prelude: Compose :: f (g a) -> Compose (f :: k -> Type) (g :: k1 -> k) (a :: k1)
+ Chiasma.Prelude: Const :: a -> Const a (b :: k)
+ Chiasma.Prelude: D# :: Double# -> Double
+ Chiasma.Prelude: Down :: a -> Down a
+ Chiasma.Prelude: Dual :: a -> Dual a
+ Chiasma.Prelude: EQ :: Ordering
+ Chiasma.Prelude: Endo :: (a -> a) -> Endo a
+ Chiasma.Prelude: Equivalence :: (a -> a -> Bool) -> Equivalence a
+ Chiasma.Prelude: ExceptT :: m (Either e a) -> ExceptT e (m :: Type -> Type) a
+ Chiasma.Prelude: F# :: Float# -> Float
+ Chiasma.Prelude: False :: Bool
+ Chiasma.Prelude: First :: Maybe a -> First a
+ Chiasma.Prelude: GT :: Ordering
+ Chiasma.Prelude: Identity :: a -> Identity a
+ Chiasma.Prelude: Just :: a -> Maybe a
+ Chiasma.Prelude: LT :: Ordering
+ Chiasma.Prelude: Last :: Maybe a -> Last a
+ Chiasma.Prelude: Left :: a -> Either a b
+ Chiasma.Prelude: MaybeT :: m (Maybe a) -> MaybeT (m :: Type -> Type) a
+ Chiasma.Prelude: Nothing :: Maybe a
+ Chiasma.Prelude: Op :: (b -> a) -> Op a b
+ Chiasma.Prelude: Option :: Maybe a -> Option a
+ Chiasma.Prelude: Predicate :: (a -> Bool) -> Predicate a
+ Chiasma.Prelude: Product :: a -> Product a
+ Chiasma.Prelude: Proxy :: Proxy (t :: k)
+ Chiasma.Prelude: ReadMode :: IOMode
+ Chiasma.Prelude: ReadWriteMode :: IOMode
+ Chiasma.Prelude: ReaderT :: (r -> m a) -> ReaderT r (m :: Type -> Type) a
+ Chiasma.Prelude: Right :: b -> Either a b
+ Chiasma.Prelude: SomeException :: e -> SomeException
+ Chiasma.Prelude: SomeNat :: Proxy n -> SomeNat
+ Chiasma.Prelude: StateT :: (s -> m (a, s)) -> StateT s (m :: Type -> Type) a
+ Chiasma.Prelude: Sum :: a -> Sum a
+ Chiasma.Prelude: True :: Bool
+ Chiasma.Prelude: Undefined :: Undefined
+ Chiasma.Prelude: WriteMode :: IOMode
+ Chiasma.Prelude: ZipList :: [a] -> ZipList a
+ Chiasma.Prelude: [appEndo] :: Endo a -> a -> a
+ Chiasma.Prelude: [getAll] :: All -> Bool
+ Chiasma.Prelude: [getAlt] :: Alt (f :: k -> Type) (a :: k) -> f a
+ Chiasma.Prelude: [getAny] :: Any -> Bool
+ Chiasma.Prelude: [getAp] :: Ap (f :: k -> Type) (a :: k) -> f a
+ Chiasma.Prelude: [getComparison] :: Comparison a -> a -> a -> Ordering
+ Chiasma.Prelude: [getCompose] :: Compose (f :: k -> Type) (g :: k1 -> k) (a :: k1) -> f (g a)
+ Chiasma.Prelude: [getConst] :: Const a (b :: k) -> a
+ Chiasma.Prelude: [getDown] :: Down a -> a
+ Chiasma.Prelude: [getDual] :: Dual a -> a
+ Chiasma.Prelude: [getEquivalence] :: Equivalence a -> a -> a -> Bool
+ Chiasma.Prelude: [getFirst] :: First a -> Maybe a
+ Chiasma.Prelude: [getLast] :: Last a -> Maybe a
+ Chiasma.Prelude: [getOp] :: Op a b -> b -> a
+ Chiasma.Prelude: [getOption] :: Option a -> Maybe a
+ Chiasma.Prelude: [getPredicate] :: Predicate a -> a -> Bool
+ Chiasma.Prelude: [getProduct] :: Product a -> a
+ Chiasma.Prelude: [getSum] :: Sum a -> a
+ Chiasma.Prelude: [getZipList] :: ZipList a -> [a]
+ Chiasma.Prelude: [runIdentity] :: Identity a -> a
+ Chiasma.Prelude: [runMaybeT] :: MaybeT (m :: Type -> Type) a -> m (Maybe a)
+ Chiasma.Prelude: [runReaderT] :: ReaderT r (m :: Type -> Type) a -> r -> m a
+ Chiasma.Prelude: [runStateT] :: StateT s (m :: Type -> Type) a -> s -> m (a, s)
+ Chiasma.Prelude: abs :: Num a => a -> a
+ Chiasma.Prelude: absurd :: Void -> a
+ Chiasma.Prelude: acos :: Floating a => a -> a
+ Chiasma.Prelude: acosh :: Floating a => a -> a
+ Chiasma.Prelude: all :: Foldable t => (a -> Bool) -> t a -> Bool
+ Chiasma.Prelude: allM :: (Foldable f, Monad m) => (a -> m Bool) -> f a -> m Bool
+ Chiasma.Prelude: and :: Foldable t => t Bool -> Bool
+ Chiasma.Prelude: andM :: (Foldable f, Monad m) => f (m Bool) -> m Bool
+ Chiasma.Prelude: any :: Foldable t => (a -> Bool) -> t a -> Bool
+ Chiasma.Prelude: anyM :: (Foldable f, Monad m) => (a -> m Bool) -> f a -> m Bool
+ Chiasma.Prelude: appendFile :: MonadIO m => FilePath -> String -> m ()
+ Chiasma.Prelude: appendFileBS :: MonadIO m => FilePath -> ByteString -> m ()
+ Chiasma.Prelude: appendFileLBS :: MonadIO m => FilePath -> LByteString -> m ()
+ Chiasma.Prelude: appendFileLText :: MonadIO m => FilePath -> LText -> m ()
+ Chiasma.Prelude: appendFileText :: MonadIO m => FilePath -> Text -> m ()
+ Chiasma.Prelude: appliedTo :: Applicative f => f a -> f (a -> b) -> f b
+ Chiasma.Prelude: asTypeOf :: a -> a -> a
+ Chiasma.Prelude: asin :: Floating a => a -> a
+ Chiasma.Prelude: asinh :: Floating a => a -> a
+ Chiasma.Prelude: asum :: (Foldable t, Alternative f) => t (f a) -> f a
+ Chiasma.Prelude: asumMap :: forall b m f a. (Foldable f, Alternative m) => (a -> m b) -> f a -> m b
+ Chiasma.Prelude: atan :: Floating a => a -> a
+ Chiasma.Prelude: atan2 :: RealFloat a => a -> a -> a
+ Chiasma.Prelude: atanh :: Floating a => a -> a
+ Chiasma.Prelude: atomicModifyIORef :: MonadIO m => IORef a -> (a -> (a, b)) -> m b
+ Chiasma.Prelude: atomicModifyIORef' :: MonadIO m => IORef a -> (a -> (a, b)) -> m b
+ Chiasma.Prelude: atomicModifyIORef'_ :: MonadIO m => IORef a -> (a -> a) -> m ()
+ Chiasma.Prelude: atomicModifyIORef_ :: MonadIO m => IORef a -> (a -> a) -> m ()
+ Chiasma.Prelude: atomicWriteIORef :: MonadIO m => IORef a -> a -> m ()
+ Chiasma.Prelude: atomically :: MonadIO m => STM a -> m a
+ Chiasma.Prelude: biList :: Bifoldable t => t a a -> [a]
+ Chiasma.Prelude: biall :: Bifoldable t => (a -> Bool) -> (b -> Bool) -> t a b -> Bool
+ Chiasma.Prelude: biand :: Bifoldable t => t Bool Bool -> Bool
+ Chiasma.Prelude: biany :: Bifoldable t => (a -> Bool) -> (b -> Bool) -> t a b -> Bool
+ Chiasma.Prelude: biasum :: (Bifoldable t, Alternative f) => t (f a) (f a) -> f a
+ Chiasma.Prelude: bielem :: (Bifoldable t, Eq a) => a -> t a a -> Bool
+ Chiasma.Prelude: bifind :: Bifoldable t => (a -> Bool) -> t a a -> Maybe a
+ Chiasma.Prelude: bifold :: (Bifoldable p, Monoid m) => p m m -> m
+ Chiasma.Prelude: bifoldMap :: (Bifoldable p, Monoid m) => (a -> m) -> (b -> m) -> p a b -> m
+ Chiasma.Prelude: bifoldMapDefault :: (Bitraversable t, Monoid m) => (a -> m) -> (b -> m) -> t a b -> m
+ Chiasma.Prelude: bifoldl :: Bifoldable p => (c -> a -> c) -> (c -> b -> c) -> c -> p a b -> c
+ Chiasma.Prelude: bifoldl' :: Bifoldable t => (a -> b -> a) -> (a -> c -> a) -> a -> t b c -> a
+ Chiasma.Prelude: bifoldlM :: (Bifoldable t, Monad m) => (a -> b -> m a) -> (a -> c -> m a) -> a -> t b c -> m a
+ Chiasma.Prelude: bifoldr :: Bifoldable p => (a -> c -> c) -> (b -> c -> c) -> c -> p a b -> c
+ Chiasma.Prelude: bifoldr' :: Bifoldable t => (a -> c -> c) -> (b -> c -> c) -> c -> t a b -> c
+ Chiasma.Prelude: bifoldrM :: (Bifoldable t, Monad m) => (a -> c -> m c) -> (b -> c -> m c) -> c -> t a b -> m c
+ Chiasma.Prelude: bifor :: (Bitraversable t, Applicative f) => t a b -> (a -> f c) -> (b -> f d) -> f (t c d)
+ Chiasma.Prelude: bifor_ :: (Bifoldable t, Applicative f) => t a b -> (a -> f c) -> (b -> f d) -> f ()
+ Chiasma.Prelude: bilength :: Bifoldable t => t a b -> Int
+ Chiasma.Prelude: bimap :: Bifunctor p => (a -> b) -> (c -> d) -> p a c -> p b d
+ Chiasma.Prelude: bimapDefault :: Bitraversable t => (a -> b) -> (c -> d) -> t a c -> t b d
+ Chiasma.Prelude: binull :: Bifoldable t => t a b -> Bool
+ Chiasma.Prelude: bior :: Bifoldable t => t Bool Bool -> Bool
+ Chiasma.Prelude: bisequence :: (Bitraversable t, Applicative f) => t (f a) (f b) -> f (t a b)
+ Chiasma.Prelude: bisequence_ :: (Bifoldable t, Applicative f) => t (f a) (f b) -> f ()
+ Chiasma.Prelude: bitraverse :: (Bitraversable t, Applicative f) => (a -> f c) -> (b -> f d) -> t a b -> f (t c d)
+ Chiasma.Prelude: bitraverse_ :: (Bifoldable t, Applicative f) => (a -> f c) -> (b -> f d) -> t a b -> f ()
+ Chiasma.Prelude: bool :: a -> a -> Bool -> a
+ Chiasma.Prelude: boundedEnumFrom :: (Enum a, Bounded a) => a -> [a]
+ Chiasma.Prelude: boundedEnumFromThen :: (Enum a, Bounded a) => a -> a -> [a]
+ Chiasma.Prelude: break :: (a -> Bool) -> [a] -> ([a], [a])
+ Chiasma.Prelude: bug :: (HasCallStack, Exception e) => e -> a
+ Chiasma.Prelude: byteSwap16 :: Word16 -> Word16
+ Chiasma.Prelude: byteSwap32 :: Word32 -> Word32
+ Chiasma.Prelude: byteSwap64 :: Word64 -> Word64
+ Chiasma.Prelude: callStack :: HasCallStack => CallStack
+ Chiasma.Prelude: catMaybes :: [Maybe a] -> [a]
+ Chiasma.Prelude: catchSTM :: Exception e => STM a -> (e -> STM a) -> STM a
+ Chiasma.Prelude: ceiling :: (RealFrac a, Integral b) => a -> b
+ Chiasma.Prelude: chainedTo :: Monad m => (a -> m b) -> m a -> m b
+ Chiasma.Prelude: chr :: Int -> Char
+ Chiasma.Prelude: class Applicative f => Alternative (f :: Type -> Type)
+ Chiasma.Prelude: class Functor f => Applicative (f :: Type -> Type)
+ Chiasma.Prelude: class Bifoldable (p :: Type -> Type -> Type)
+ Chiasma.Prelude: class Bifunctor (p :: Type -> Type -> Type)
+ Chiasma.Prelude: class (Bifunctor t, Bifoldable t) => Bitraversable (t :: Type -> Type -> Type)
+ Chiasma.Prelude: class Bounded a
+ Chiasma.Prelude: class a ~R# b => Coercible (a :: k) (b :: k)
+ Chiasma.Prelude: class Contravariant (f :: Type -> Type)
+ Chiasma.Prelude: class ConvertUtf8 a b
+ Chiasma.Prelude: class Default a
+ Chiasma.Prelude: class Enum a
+ Chiasma.Prelude: class Eq a
+ Chiasma.Prelude: class (Typeable e, Show e) => Exception e
+ Chiasma.Prelude: class Fractional a => Floating a
+ Chiasma.Prelude: class Foldable (t :: Type -> Type)
+ Chiasma.Prelude: class Num a => Fractional a
+ Chiasma.Prelude: class Functor (f :: Type -> Type)
+ Chiasma.Prelude: class Generic a
+ Chiasma.Prelude: class Hashable a
+ Chiasma.Prelude: class (Real a, Enum a) => Integral a
+ Chiasma.Prelude: class IsLabel (x :: Symbol) a
+ Chiasma.Prelude: class IsList l
+ Chiasma.Prelude: class IsString a
+ Chiasma.Prelude: class KnownNat (n :: Nat)
+ Chiasma.Prelude: class LazyStrict l s | l -> s, s -> l
+ Chiasma.Prelude: class Applicative m => Monad (m :: Type -> Type)
+ Chiasma.Prelude: class Monad m => MonadFail (m :: Type -> Type)
+ Chiasma.Prelude: class Monad m => MonadIO (m :: Type -> Type)
+ Chiasma.Prelude: class (Alternative m, Monad m) => MonadPlus (m :: Type -> Type)
+ Chiasma.Prelude: class Monad m => MonadReader r (m :: Type -> Type) | m -> r
+ Chiasma.Prelude: class Monad m => MonadState s (m :: Type -> Type) | m -> s
+ Chiasma.Prelude: class MonadTrans (t :: Type -> Type -> Type -> Type)
+ Chiasma.Prelude: class Semigroup a => Monoid a
+ Chiasma.Prelude: class NFData a
+ Chiasma.Prelude: class Num a
+ Chiasma.Prelude: class One x where {
+ Chiasma.Prelude: class Eq a => Ord a
+ Chiasma.Prelude: class Read a
+ Chiasma.Prelude: class (Num a, Ord a) => Real a
+ Chiasma.Prelude: class (RealFrac a, Floating a) => RealFloat a
+ Chiasma.Prelude: class (Real a, Fractional a) => RealFrac a
+ Chiasma.Prelude: class Semigroup a
+ Chiasma.Prelude: class Show a
+ Chiasma.Prelude: class ToLText a
+ Chiasma.Prelude: class ToString a
+ Chiasma.Prelude: class ToText a
+ Chiasma.Prelude: class (Functor t, Foldable t) => Traversable (t :: Type -> Type)
+ Chiasma.Prelude: class Typeable (a :: k)
+ Chiasma.Prelude: coerce :: forall (k :: RuntimeRep) (a :: TYPE k) (b :: TYPE k). Coercible a b => a -> b
+ Chiasma.Prelude: compare :: Ord a => a -> a -> Ordering
+ Chiasma.Prelude: comparing :: Ord a => (b -> a) -> b -> b -> Ordering
+ Chiasma.Prelude: comparisonEquivalence :: Comparison a -> Equivalence a
+ Chiasma.Prelude: concat :: Foldable t => t [a] -> [a]
+ Chiasma.Prelude: concatMap :: Foldable t => (a -> [b]) -> t a -> [b]
+ Chiasma.Prelude: const :: a -> b -> a
+ Chiasma.Prelude: contramap :: Contravariant f => (a -> b) -> f b -> f a
+ Chiasma.Prelude: cos :: Floating a => a -> a
+ Chiasma.Prelude: cosh :: Floating a => a -> a
+ Chiasma.Prelude: currentCallStack :: IO [String]
+ Chiasma.Prelude: curry :: ((a, b) -> c) -> a -> b -> c
+ Chiasma.Prelude: cycle :: [a] -> [a]
+ Chiasma.Prelude: cycle1 :: Semigroup m => m -> m
+ Chiasma.Prelude: data Bool
+ Chiasma.Prelude: data Bug
+ Chiasma.Prelude: data ByteString
+ Chiasma.Prelude: data CallStack
+ Chiasma.Prelude: data Char
+ Chiasma.Prelude: data Constraint
+ Chiasma.Prelude: data Double
+ Chiasma.Prelude: data Either a b
+ Chiasma.Prelude: data Float
+ Chiasma.Prelude: data Handle
+ Chiasma.Prelude: data HashMap k v
+ Chiasma.Prelude: data HashSet a
+ Chiasma.Prelude: data IO a
+ Chiasma.Prelude: data IOMode
+ Chiasma.Prelude: data IORef a
+ Chiasma.Prelude: data IdentityT (f :: k -> Type) (a :: k)
+ Chiasma.Prelude: data Int
+ Chiasma.Prelude: data Int16
+ Chiasma.Prelude: data Int32
+ Chiasma.Prelude: data Int64
+ Chiasma.Prelude: data Int8
+ Chiasma.Prelude: data IntMap a
+ Chiasma.Prelude: data IntSet
+ Chiasma.Prelude: data Integer
+ Chiasma.Prelude: data MVar a
+ Chiasma.Prelude: data Map k a
+ Chiasma.Prelude: data Maybe a
+ Chiasma.Prelude: data Nat
+ Chiasma.Prelude: data Natural
+ Chiasma.Prelude: data NonEmpty a
+ Chiasma.Prelude: data Ordering
+ Chiasma.Prelude: data Proxy (t :: k)
+ Chiasma.Prelude: data Ratio a
+ Chiasma.Prelude: data STM a
+ Chiasma.Prelude: data Seq a
+ Chiasma.Prelude: data Set a
+ Chiasma.Prelude: data ShortByteString
+ Chiasma.Prelude: data SomeException
+ Chiasma.Prelude: data SomeNat
+ Chiasma.Prelude: data TMVar a
+ Chiasma.Prelude: data TVar a
+ Chiasma.Prelude: data Text
+ Chiasma.Prelude: data Undefined
+ Chiasma.Prelude: data UnicodeException
+ Chiasma.Prelude: data Void
+ Chiasma.Prelude: data Word
+ Chiasma.Prelude: data Word16
+ Chiasma.Prelude: data Word32
+ Chiasma.Prelude: data Word64
+ Chiasma.Prelude: data Word8
+ Chiasma.Prelude: data WrappedMonoid m
+ Chiasma.Prelude: dbg :: Monad m => Text -> m ()
+ Chiasma.Prelude: dbgm :: Monad m => Show a => m a -> m a
+ Chiasma.Prelude: dbgs :: Monad m => Show a => a -> m ()
+ Chiasma.Prelude: decodeFloat :: RealFloat a => a -> (Integer, Int)
+ Chiasma.Prelude: decodeUtf8 :: ConvertUtf8 a b => b -> a
+ Chiasma.Prelude: decodeUtf8' :: ByteString -> Either UnicodeException Text
+ Chiasma.Prelude: decodeUtf8Strict :: ConvertUtf8 a b => b -> Either UnicodeException a
+ Chiasma.Prelude: decodeUtf8With :: OnDecodeError -> ByteString -> Text
+ Chiasma.Prelude: deepseq :: NFData a => a -> b -> b
+ Chiasma.Prelude: def :: Default a => a
+ Chiasma.Prelude: defaultComparison :: Ord a => Comparison a
+ Chiasma.Prelude: defaultEquivalence :: Eq a => Equivalence a
+ Chiasma.Prelude: denominator :: Ratio a -> a
+ Chiasma.Prelude: die :: MonadIO m => String -> m a
+ Chiasma.Prelude: displayException :: Exception e => e -> String
+ Chiasma.Prelude: div :: Integral a => a -> a -> a
+ Chiasma.Prelude: divMod :: Integral a => a -> a -> (a, a)
+ Chiasma.Prelude: drop :: Int -> [a] -> [a]
+ Chiasma.Prelude: dropWhile :: (a -> Bool) -> [a] -> [a]
+ Chiasma.Prelude: either :: (a -> c) -> (b -> c) -> Either a b -> c
+ Chiasma.Prelude: elem :: (Foldable f, DisallowElem f, Eq a) => a -> f a -> Bool
+ Chiasma.Prelude: empty :: Alternative f => f a
+ Chiasma.Prelude: encodeFloat :: RealFloat a => Integer -> Int -> a
+ Chiasma.Prelude: encodeUtf8 :: ConvertUtf8 a b => a -> b
+ Chiasma.Prelude: enumFrom :: Enum a => a -> [a]
+ Chiasma.Prelude: enumFromThen :: Enum a => a -> a -> [a]
+ Chiasma.Prelude: enumFromThenTo :: Enum a => a -> a -> a -> [a]
+ Chiasma.Prelude: enumFromTo :: Enum a => a -> a -> [a]
+ Chiasma.Prelude: error :: forall (r :: RuntimeRep) (a :: TYPE r) t. (HasCallStack, IsText t) => t -> a
+ Chiasma.Prelude: etaReaderT :: forall r (m :: Type -> Type) a. ReaderT r m a -> ReaderT r m a
+ Chiasma.Prelude: evalState :: State s a -> s -> a
+ Chiasma.Prelude: evalStateT :: Monad m => StateT s m a -> s -> m a
+ Chiasma.Prelude: evaluateNF :: (NFData a, MonadIO m) => a -> m a
+ Chiasma.Prelude: evaluateNF_ :: (NFData a, MonadIO m) => a -> m ()
+ Chiasma.Prelude: evaluateWHNF :: MonadIO m => a -> m a
+ Chiasma.Prelude: evaluateWHNF_ :: MonadIO m => a -> m ()
+ Chiasma.Prelude: evaluatingState :: s -> State s a -> a
+ Chiasma.Prelude: evaluatingStateT :: Functor f => s -> StateT s f a -> f a
+ Chiasma.Prelude: even :: Integral a => a -> Bool
+ Chiasma.Prelude: exceptToMaybeT :: forall (m :: Type -> Type) e a. Functor m => ExceptT e m a -> MaybeT m a
+ Chiasma.Prelude: execState :: State s a -> s -> s
+ Chiasma.Prelude: execStateT :: Monad m => StateT s m a -> s -> m s
+ Chiasma.Prelude: executingState :: s -> State s a -> s
+ Chiasma.Prelude: executingStateT :: Functor f => s -> StateT s f a -> f s
+ Chiasma.Prelude: exitFailure :: MonadIO m => m a
+ Chiasma.Prelude: exitSuccess :: MonadIO m => m a
+ Chiasma.Prelude: exitWith :: MonadIO m => ExitCode -> m a
+ Chiasma.Prelude: exp :: Floating a => a -> a
+ Chiasma.Prelude: fail :: MonadFail m => String -> m a
+ Chiasma.Prelude: filter :: (a -> Bool) -> [a] -> [a]
+ Chiasma.Prelude: filterM :: Applicative m => (a -> m Bool) -> [a] -> m [a]
+ Chiasma.Prelude: find :: Foldable t => (a -> Bool) -> t a -> Maybe a
+ Chiasma.Prelude: first :: Bifunctor p => (a -> b) -> p a c -> p b c
+ Chiasma.Prelude: fix :: (a -> a) -> a
+ Chiasma.Prelude: flap :: Functor f => f (a -> b) -> a -> f b
+ Chiasma.Prelude: flip :: (a -> b -> c) -> b -> a -> c
+ Chiasma.Prelude: flipfoldl' :: Foldable f => (a -> b -> b) -> b -> f a -> b
+ Chiasma.Prelude: floatDigits :: RealFloat a => a -> Int
+ Chiasma.Prelude: floatRadix :: RealFloat a => a -> Integer
+ Chiasma.Prelude: floatRange :: RealFloat a => a -> (Int, Int)
+ Chiasma.Prelude: floor :: (RealFrac a, Integral b) => a -> b
+ Chiasma.Prelude: fmap :: Functor f => (a -> b) -> f a -> f b
+ Chiasma.Prelude: fold :: (Foldable t, Monoid m) => t m -> m
+ Chiasma.Prelude: foldMap :: (Foldable t, Monoid m) => (a -> m) -> t a -> m
+ Chiasma.Prelude: foldMap' :: (Foldable t, Monoid m) => (a -> m) -> t a -> m
+ Chiasma.Prelude: foldMapA :: (Semigroup b, Monoid b, Applicative m, Foldable f) => (a -> m b) -> f a -> m b
+ Chiasma.Prelude: foldMapM :: (Monoid b, Monad m, Foldable f) => (a -> m b) -> f a -> m b
+ Chiasma.Prelude: foldl :: Foldable t => (b -> a -> b) -> b -> t a -> b
+ Chiasma.Prelude: foldl' :: Foldable t => (b -> a -> b) -> b -> t a -> b
+ Chiasma.Prelude: foldlM :: (Foldable t, Monad m) => (b -> a -> m b) -> b -> t a -> m b
+ Chiasma.Prelude: foldr :: Foldable t => (a -> b -> b) -> b -> t a -> b
+ Chiasma.Prelude: forM :: (Traversable t, Monad m) => t a -> (a -> m b) -> m (t b)
+ Chiasma.Prelude: forM_ :: (Foldable t, Monad m) => t a -> (a -> m b) -> m ()
+ Chiasma.Prelude: for_ :: (Foldable t, Applicative f) => t a -> (a -> f b) -> f ()
+ Chiasma.Prelude: force :: NFData a => a -> a
+ Chiasma.Prelude: forever :: Applicative f => f a -> f b
+ Chiasma.Prelude: fromEnum :: Enum a => a -> Int
+ Chiasma.Prelude: fromException :: Exception e => SomeException -> Maybe e
+ Chiasma.Prelude: fromInteger :: Num a => Integer -> a
+ Chiasma.Prelude: fromIntegral :: (Integral a, Num b) => a -> b
+ Chiasma.Prelude: fromLabel :: IsLabel x a => a
+ Chiasma.Prelude: fromLazy :: LazyStrict l s => l -> s
+ Chiasma.Prelude: fromLeft :: a -> Either a b -> a
+ Chiasma.Prelude: fromList :: IsList l => [Item l] -> l
+ Chiasma.Prelude: fromListN :: IsList l => Int -> [Item l] -> l
+ Chiasma.Prelude: fromMaybe :: a -> Maybe a -> a
+ Chiasma.Prelude: fromRational :: Fractional a => Rational -> a
+ Chiasma.Prelude: fromRight :: b -> Either a b -> b
+ Chiasma.Prelude: fromShort :: ShortByteString -> ByteString
+ Chiasma.Prelude: fromStrict :: LazyStrict l s => s -> l
+ Chiasma.Prelude: fromString :: IsString a => String -> a
+ Chiasma.Prelude: fst :: (a, b) -> a
+ Chiasma.Prelude: gcd :: Integral a => a -> a -> a
+ Chiasma.Prelude: genericDrop :: Integral i => i -> [a] -> [a]
+ Chiasma.Prelude: genericLength :: Num i => [a] -> i
+ Chiasma.Prelude: genericReplicate :: Integral i => i -> a -> [a]
+ Chiasma.Prelude: genericSplitAt :: Integral i => i -> [a] -> ([a], [a])
+ Chiasma.Prelude: genericTake :: Integral i => i -> [a] -> [a]
+ Chiasma.Prelude: getCallStack :: CallStack -> [([Char], SrcLoc)]
+ Chiasma.Prelude: getLine :: MonadIO m => m Text
+ Chiasma.Prelude: getStackTrace :: IO (Maybe [Location])
+ Chiasma.Prelude: group :: Eq a => [a] -> [[a]]
+ Chiasma.Prelude: guard :: Alternative f => Bool -> f ()
+ Chiasma.Prelude: guardM :: MonadPlus m => m Bool -> m ()
+ Chiasma.Prelude: guarded :: Alternative f => (a -> Bool) -> a -> f a
+ Chiasma.Prelude: hashNub :: (Eq a, Hashable a) => [a] -> [a]
+ Chiasma.Prelude: hashWithSalt :: Hashable a => Int -> a -> Int
+ Chiasma.Prelude: head :: IsNonEmpty f a a "head" => f a -> a
+ Chiasma.Prelude: id :: a -> a
+ Chiasma.Prelude: identity :: a -> a
+ Chiasma.Prelude: ifM :: Monad m => m Bool -> m a -> m a -> m a
+ Chiasma.Prelude: infix 4 >=
+ Chiasma.Prelude: infix 9 !!?
+ Chiasma.Prelude: infixl 0 `on`
+ Chiasma.Prelude: infixl 1 <&>
+ Chiasma.Prelude: infixl 3 <|>
+ Chiasma.Prelude: infixl 4 <<$>>
+ Chiasma.Prelude: infixl 6 `xor`
+ Chiasma.Prelude: infixl 7 *
+ Chiasma.Prelude: infixr 0 ?:
+ Chiasma.Prelude: infixr 1 =<<
+ Chiasma.Prelude: infixr 2 ||
+ Chiasma.Prelude: infixr 3 &&
+ Chiasma.Prelude: infixr 5 :|
+ Chiasma.Prelude: infixr 6 <>
+ Chiasma.Prelude: infixr 8 <$$>
+ Chiasma.Prelude: infixr 9 `Compose`
+ Chiasma.Prelude: init :: IsNonEmpty f a [a] "init" => f a -> [a]
+ Chiasma.Prelude: inits :: [a] -> [[a]]
+ Chiasma.Prelude: integerToBounded :: (Integral a, Bounded a) => Integer -> Maybe a
+ Chiasma.Prelude: integerToNatural :: Integer -> Maybe Natural
+ Chiasma.Prelude: intercalate :: [a] -> [[a]] -> [a]
+ Chiasma.Prelude: intersperse :: a -> [a] -> [a]
+ Chiasma.Prelude: isDenormalized :: RealFloat a => a -> Bool
+ Chiasma.Prelude: isEmptyTMVar :: TMVar a -> STM Bool
+ Chiasma.Prelude: isIEEE :: RealFloat a => a -> Bool
+ Chiasma.Prelude: isInfinite :: RealFloat a => a -> Bool
+ Chiasma.Prelude: isJust :: Maybe a -> Bool
+ Chiasma.Prelude: isLeft :: Either a b -> Bool
+ Chiasma.Prelude: isNaN :: RealFloat a => a -> Bool
+ Chiasma.Prelude: isNegativeZero :: RealFloat a => a -> Bool
+ Chiasma.Prelude: isNothing :: Maybe a -> Bool
+ Chiasma.Prelude: isPrefixOf :: Eq a => [a] -> [a] -> Bool
+ Chiasma.Prelude: isRight :: Either a b -> Bool
+ Chiasma.Prelude: iterate :: (a -> a) -> a -> [a]
+ Chiasma.Prelude: join :: Monad m => m (m a) -> m a
+ Chiasma.Prelude: last :: IsNonEmpty f a a "last" => f a -> a
+ Chiasma.Prelude: lcm :: Integral a => a -> a -> a
+ Chiasma.Prelude: leftToMaybe :: Either l r -> Maybe l
+ Chiasma.Prelude: lefts :: [Either a b] -> [a]
+ Chiasma.Prelude: length :: Foldable t => t a -> Int
+ Chiasma.Prelude: lenientDecode :: OnDecodeError
+ Chiasma.Prelude: lift :: (MonadTrans t, Monad m) => m a -> t m a
+ Chiasma.Prelude: liftA2 :: Applicative f => (a -> b -> c) -> f a -> f b -> f c
+ Chiasma.Prelude: liftA3 :: Applicative f => (a -> b -> c -> d) -> f a -> f b -> f c -> f d
+ Chiasma.Prelude: liftIO :: MonadIO m => IO a -> m a
+ Chiasma.Prelude: lines :: IsText t "lines" => t -> [t]
+ Chiasma.Prelude: listToMaybe :: [a] -> Maybe a
+ Chiasma.Prelude: logBase :: Floating a => a -> a -> a
+ Chiasma.Prelude: makeClassy :: Name -> DecsQ
+ Chiasma.Prelude: many :: Alternative f => f a -> f [a]
+ Chiasma.Prelude: map :: (a -> b) -> [a] -> [b]
+ Chiasma.Prelude: mapAccumL :: Traversable t => (a -> b -> (a, c)) -> a -> t b -> (a, t c)
+ Chiasma.Prelude: mapAccumR :: Traversable t => (a -> b -> (a, c)) -> a -> t b -> (a, t c)
+ Chiasma.Prelude: mapAndUnzipM :: Applicative m => (a -> m (b, c)) -> [a] -> m ([b], [c])
+ Chiasma.Prelude: mapLeft :: (a -> c) -> Either a b -> Either c b
+ Chiasma.Prelude: mapM :: (Traversable t, Monad m) => (a -> m b) -> t a -> m (t b)
+ Chiasma.Prelude: mapM_ :: (Foldable t, Monad m) => (a -> m b) -> t a -> m ()
+ Chiasma.Prelude: mapMaybe :: (a -> Maybe b) -> [a] -> [b]
+ Chiasma.Prelude: mapMaybeM :: Monad m => (a -> m (Maybe b)) -> [a] -> m [b]
+ Chiasma.Prelude: mappend :: Monoid a => a -> a -> a
+ Chiasma.Prelude: max :: Ord a => a -> a -> a
+ Chiasma.Prelude: maxBound :: Bounded a => a
+ Chiasma.Prelude: maxInt :: Int
+ Chiasma.Prelude: maybe :: b -> (a -> b) -> Maybe a -> b
+ Chiasma.Prelude: maybeToExceptT :: forall (m :: Type -> Type) e a. Functor m => e -> MaybeT m a -> ExceptT e m a
+ Chiasma.Prelude: maybeToLeft :: r -> Maybe l -> Either l r
+ Chiasma.Prelude: maybeToList :: Maybe a -> [a]
+ Chiasma.Prelude: maybeToMonoid :: Monoid m => Maybe m -> m
+ Chiasma.Prelude: maybeToRight :: l -> Maybe r -> Either l r
+ Chiasma.Prelude: mconcat :: Monoid a => [a] -> a
+ Chiasma.Prelude: mempty :: Monoid a => a
+ Chiasma.Prelude: memptyIfFalse :: Monoid m => Bool -> m -> m
+ Chiasma.Prelude: memptyIfTrue :: Monoid m => Bool -> m -> m
+ Chiasma.Prelude: mfilter :: MonadPlus m => (a -> Bool) -> m a -> m a
+ Chiasma.Prelude: min :: Ord a => a -> a -> a
+ Chiasma.Prelude: minBound :: Bounded a => a
+ Chiasma.Prelude: minInt :: Int
+ Chiasma.Prelude: mkWeakTMVar :: TMVar a -> IO () -> IO (Weak (TMVar a))
+ Chiasma.Prelude: mod :: Integral a => a -> a -> a
+ Chiasma.Prelude: modify' :: MonadState s m => (s -> s) -> m ()
+ Chiasma.Prelude: modifyIORef :: MonadIO m => IORef a -> (a -> a) -> m ()
+ Chiasma.Prelude: modifyIORef' :: MonadIO m => IORef a -> (a -> a) -> m ()
+ Chiasma.Prelude: modifyTVar' :: TVar a -> (a -> a) -> STM ()
+ Chiasma.Prelude: mplus :: MonadPlus m => m a -> m a -> m a
+ Chiasma.Prelude: mtimesDefault :: (Integral b, Monoid a) => b -> a -> a
+ Chiasma.Prelude: mzero :: MonadPlus m => m a
+ Chiasma.Prelude: natVal :: forall (n :: Nat) proxy. KnownNat n => proxy n -> Natural
+ Chiasma.Prelude: negate :: Num a => a -> a
+ Chiasma.Prelude: newEmptyMVar :: MonadIO m => m (MVar a)
+ Chiasma.Prelude: newEmptyTMVar :: STM (TMVar a)
+ Chiasma.Prelude: newEmptyTMVarIO :: MonadIO m => m (TMVar a)
+ Chiasma.Prelude: newIORef :: MonadIO m => a -> m (IORef a)
+ Chiasma.Prelude: newMVar :: MonadIO m => a -> m (MVar a)
+ Chiasma.Prelude: newTMVar :: a -> STM (TMVar a)
+ Chiasma.Prelude: newTMVarIO :: MonadIO m => a -> m (TMVar a)
+ Chiasma.Prelude: newTVar :: a -> STM (TVar a)
+ Chiasma.Prelude: newTVarIO :: MonadIO m => a -> m (TVar a)
+ Chiasma.Prelude: newtype All
+ Chiasma.Prelude: newtype Alt (f :: k -> Type) (a :: k)
+ Chiasma.Prelude: newtype Any
+ Chiasma.Prelude: newtype Ap (f :: k -> Type) (a :: k)
+ Chiasma.Prelude: newtype Comparison a
+ Chiasma.Prelude: newtype Compose (f :: k -> Type) (g :: k1 -> k) (a :: k1)
+ Chiasma.Prelude: newtype Const a (b :: k)
+ Chiasma.Prelude: newtype Down a
+ Chiasma.Prelude: newtype Dual a
+ Chiasma.Prelude: newtype Endo a
+ Chiasma.Prelude: newtype Equivalence a
+ Chiasma.Prelude: newtype ExceptT e (m :: Type -> Type) a
+ Chiasma.Prelude: newtype First a
+ Chiasma.Prelude: newtype Identity a
+ Chiasma.Prelude: newtype Last a
+ Chiasma.Prelude: newtype MaybeT (m :: Type -> Type) a
+ Chiasma.Prelude: newtype Op a b
+ Chiasma.Prelude: newtype Option a
+ Chiasma.Prelude: newtype Predicate a
+ Chiasma.Prelude: newtype Product a
+ Chiasma.Prelude: newtype ReaderT r (m :: Type -> Type) a
+ Chiasma.Prelude: newtype StateT s (m :: Type -> Type) a
+ Chiasma.Prelude: newtype Sum a
+ Chiasma.Prelude: newtype ZipList a
+ Chiasma.Prelude: nonEmpty :: [a] -> Maybe (NonEmpty a)
+ Chiasma.Prelude: not :: Bool -> Bool
+ Chiasma.Prelude: notElem :: (Foldable f, DisallowElem f, Eq a) => a -> f a -> Bool
+ Chiasma.Prelude: null :: Foldable t => t a -> Bool
+ Chiasma.Prelude: numerator :: Ratio a -> a
+ Chiasma.Prelude: odd :: Integral a => a -> Bool
+ Chiasma.Prelude: on :: (b -> b -> c) -> (a -> b) -> a -> a -> c
+ Chiasma.Prelude: one :: One x => OneItem x -> x
+ Chiasma.Prelude: optional :: Alternative f => f a -> f (Maybe a)
+ Chiasma.Prelude: or :: Foldable t => t Bool -> Bool
+ Chiasma.Prelude: orM :: (Foldable f, Monad m) => f (m Bool) -> m Bool
+ Chiasma.Prelude: ord :: Char -> Int
+ Chiasma.Prelude: ordNub :: Ord a => [a] -> [a]
+ Chiasma.Prelude: otherwise :: Bool
+ Chiasma.Prelude: partitionEithers :: [Either a b] -> ([a], [b])
+ Chiasma.Prelude: pass :: Applicative f => f ()
+ Chiasma.Prelude: pattern Exc :: Exception e => e -> SomeException
+ Chiasma.Prelude: permutations :: [a] -> [[a]]
+ Chiasma.Prelude: phantom :: (Functor f, Contravariant f) => f a -> f b
+ Chiasma.Prelude: pi :: Floating a => a
+ Chiasma.Prelude: pred :: Enum a => a -> a
+ Chiasma.Prelude: prettyCallStack :: CallStack -> String
+ Chiasma.Prelude: prettySrcLoc :: SrcLoc -> String
+ Chiasma.Prelude: print :: forall a m. (MonadIO m, Show a) => a -> m ()
+ Chiasma.Prelude: product :: forall a f. (Foldable f, Num a) => f a -> a
+ Chiasma.Prelude: properFraction :: (RealFrac a, Integral b) => a -> (b, a)
+ Chiasma.Prelude: pure :: Applicative f => a -> f a
+ Chiasma.Prelude: putBS :: MonadIO m => ByteString -> m ()
+ Chiasma.Prelude: putBSLn :: MonadIO m => ByteString -> m ()
+ Chiasma.Prelude: putLBS :: MonadIO m => LByteString -> m ()
+ Chiasma.Prelude: putLBSLn :: MonadIO m => LByteString -> m ()
+ Chiasma.Prelude: putLText :: MonadIO m => LText -> m ()
+ Chiasma.Prelude: putLTextLn :: MonadIO m => LText -> m ()
+ Chiasma.Prelude: putMVar :: MonadIO m => MVar a -> a -> m ()
+ Chiasma.Prelude: putStr :: MonadIO m => String -> m ()
+ Chiasma.Prelude: putStrLn :: MonadIO m => String -> m ()
+ Chiasma.Prelude: putTMVar :: TMVar a -> a -> STM ()
+ Chiasma.Prelude: putText :: MonadIO m => Text -> m ()
+ Chiasma.Prelude: putTextLn :: MonadIO m => Text -> m ()
+ Chiasma.Prelude: quot :: Integral a => a -> a -> a
+ Chiasma.Prelude: quotRem :: Integral a => a -> a -> (a, a)
+ Chiasma.Prelude: readEither :: Read a => String -> Either Text a
+ Chiasma.Prelude: readFile :: MonadIO m => FilePath -> m String
+ Chiasma.Prelude: readFileBS :: MonadIO m => FilePath -> m ByteString
+ Chiasma.Prelude: readFileLBS :: MonadIO m => FilePath -> m LByteString
+ Chiasma.Prelude: readFileLText :: MonadIO m => FilePath -> m LText
+ Chiasma.Prelude: readFileText :: MonadIO m => FilePath -> m Text
+ Chiasma.Prelude: readIORef :: MonadIO m => IORef a -> m a
+ Chiasma.Prelude: readMVar :: MonadIO m => MVar a -> m a
+ Chiasma.Prelude: readMaybe :: Read a => String -> Maybe a
+ Chiasma.Prelude: readTMVar :: TMVar a -> STM a
+ Chiasma.Prelude: readTVar :: TVar a -> STM a
+ Chiasma.Prelude: readTVarIO :: MonadIO m => TVar a -> m a
+ Chiasma.Prelude: reader :: MonadReader r m => (r -> a) -> m a
+ Chiasma.Prelude: reads :: Read a => ReadS a
+ Chiasma.Prelude: realToFrac :: (Real a, Fractional b) => a -> b
+ Chiasma.Prelude: recip :: Fractional a => a -> a
+ Chiasma.Prelude: rem :: Integral a => a -> a -> a
+ Chiasma.Prelude: repeat :: a -> [a]
+ Chiasma.Prelude: replicate :: Int -> a -> [a]
+ Chiasma.Prelude: replicateM :: Applicative m => Int -> m a -> m [a]
+ Chiasma.Prelude: replicateM_ :: Applicative m => Int -> m a -> m ()
+ Chiasma.Prelude: return :: Monad m => a -> m a
+ Chiasma.Prelude: reverse :: [a] -> [a]
+ Chiasma.Prelude: rightToMaybe :: Either l r -> Maybe r
+ Chiasma.Prelude: rights :: [Either a b] -> [b]
+ Chiasma.Prelude: rnf :: NFData a => a -> ()
+ Chiasma.Prelude: round :: (RealFrac a, Integral b) => a -> b
+ Chiasma.Prelude: runExceptT :: ExceptT e m a -> m (Either e a)
+ Chiasma.Prelude: runReader :: Reader r a -> r -> a
+ Chiasma.Prelude: runState :: State s a -> s -> (a, s)
+ Chiasma.Prelude: scanl :: (b -> a -> b) -> b -> [a] -> [b]
+ Chiasma.Prelude: scanl' :: (b -> a -> b) -> b -> [a] -> [b]
+ Chiasma.Prelude: scanl1 :: (a -> a -> a) -> [a] -> [a]
+ Chiasma.Prelude: scanr :: (a -> b -> b) -> b -> [a] -> [b]
+ Chiasma.Prelude: scanr1 :: (a -> a -> a) -> [a] -> [a]
+ Chiasma.Prelude: sconcat :: Semigroup a => NonEmpty a -> a
+ Chiasma.Prelude: second :: Bifunctor p => (b -> c) -> p a b -> p a c
+ Chiasma.Prelude: seq :: forall (r :: RuntimeRep) a (b :: TYPE r). a -> b -> b
+ Chiasma.Prelude: sequence :: (Traversable t, Monad m) => t (m a) -> m (t a)
+ Chiasma.Prelude: sequenceA :: (Traversable t, Applicative f) => t (f a) -> f (t a)
+ Chiasma.Prelude: sequenceA_ :: (Foldable t, Applicative f) => t (f a) -> f ()
+ Chiasma.Prelude: sequence_ :: (Foldable t, Monad m) => t (m a) -> m ()
+ Chiasma.Prelude: show :: forall b a. (Show a, IsString b) => a -> b
+ Chiasma.Prelude: showStackTrace :: IO (Maybe String)
+ Chiasma.Prelude: signum :: Num a => a -> a
+ Chiasma.Prelude: sin :: Floating a => a -> a
+ Chiasma.Prelude: sinh :: Floating a => a -> a
+ Chiasma.Prelude: snd :: (a, b) -> b
+ Chiasma.Prelude: some :: Alternative f => f a -> f [a]
+ Chiasma.Prelude: someNatVal :: Natural -> SomeNat
+ Chiasma.Prelude: sort :: Ord a => [a] -> [a]
+ Chiasma.Prelude: sortBy :: (a -> a -> Ordering) -> [a] -> [a]
+ Chiasma.Prelude: sortNub :: Ord a => [a] -> [a]
+ Chiasma.Prelude: sortOn :: Ord b => (a -> b) -> [a] -> [a]
+ Chiasma.Prelude: sortWith :: Ord b => (a -> b) -> [a] -> [a]
+ Chiasma.Prelude: splitAt :: Int -> [a] -> ([a], [a])
+ Chiasma.Prelude: sqrt :: Floating a => a -> a
+ Chiasma.Prelude: stderr :: Handle
+ Chiasma.Prelude: stdin :: Handle
+ Chiasma.Prelude: stdout :: Handle
+ Chiasma.Prelude: stimes :: (Semigroup a, Integral b) => b -> a -> a
+ Chiasma.Prelude: stimesIdempotent :: Integral b => b -> a -> a
+ Chiasma.Prelude: stimesIdempotentMonoid :: (Integral b, Monoid a) => b -> a -> a
+ Chiasma.Prelude: stimesMonoid :: (Integral b, Monoid a) => b -> a -> a
+ Chiasma.Prelude: strictDecode :: OnDecodeError
+ Chiasma.Prelude: subsequences :: [a] -> [[a]]
+ Chiasma.Prelude: subtract :: Num a => a -> a -> a
+ Chiasma.Prelude: succ :: Enum a => a -> a
+ Chiasma.Prelude: sum :: forall a f. (Foldable f, Num a) => f a -> a
+ Chiasma.Prelude: swap :: (a, b) -> (b, a)
+ Chiasma.Prelude: swapMVar :: MonadIO m => MVar a -> a -> m a
+ Chiasma.Prelude: swapTMVar :: TMVar a -> a -> STM a
+ Chiasma.Prelude: tail :: IsNonEmpty f a [a] "tail" => f a -> [a]
+ Chiasma.Prelude: tails :: [a] -> [[a]]
+ Chiasma.Prelude: take :: Int -> [a] -> [a]
+ Chiasma.Prelude: takeMVar :: MonadIO m => MVar a -> m a
+ Chiasma.Prelude: takeTMVar :: TMVar a -> STM a
+ Chiasma.Prelude: takeWhile :: (a -> Bool) -> [a] -> [a]
+ Chiasma.Prelude: tan :: Floating a => a -> a
+ Chiasma.Prelude: tanh :: Floating a => a -> a
+ Chiasma.Prelude: throwSTM :: Exception e => e -> STM a
+ Chiasma.Prelude: toEnum :: Enum a => Int -> a
+ Chiasma.Prelude: toException :: Exception e => e -> SomeException
+ Chiasma.Prelude: toInteger :: Integral a => a -> Integer
+ Chiasma.Prelude: toIntegralSized :: (Integral a, Integral b, Bits a, Bits b) => a -> Maybe b
+ Chiasma.Prelude: toLText :: ToLText a => a -> LText
+ Chiasma.Prelude: toLazy :: LazyStrict l s => s -> l
+ Chiasma.Prelude: toList :: Foldable t => t a -> [a]
+ Chiasma.Prelude: toRational :: Real a => a -> Rational
+ Chiasma.Prelude: toShort :: ByteString -> ShortByteString
+ Chiasma.Prelude: toStrict :: LazyStrict l s => l -> s
+ Chiasma.Prelude: toString :: ToString a => a -> String
+ Chiasma.Prelude: toText :: ToText a => a -> Text
+ Chiasma.Prelude: trace :: String -> a -> a
+ Chiasma.Prelude: traceId :: String -> String
+ Chiasma.Prelude: traceM :: Applicative f => String -> f ()
+ Chiasma.Prelude: traceShow :: Show a => a -> b -> b
+ Chiasma.Prelude: traceShowId :: Show a => a -> a
+ Chiasma.Prelude: traceShowM :: (Show a, Applicative f) => a -> f ()
+ Chiasma.Prelude: transpose :: [[a]] -> [[a]]
+ Chiasma.Prelude: traverse :: (Traversable t, Applicative f) => (a -> f b) -> t a -> f (t b)
+ Chiasma.Prelude: traverse_ :: (Foldable t, Applicative f) => (a -> f b) -> t a -> f ()
+ Chiasma.Prelude: truncate :: (RealFrac a, Integral b) => a -> b
+ Chiasma.Prelude: tryPutMVar :: MonadIO m => MVar a -> a -> m Bool
+ Chiasma.Prelude: tryPutTMVar :: TMVar a -> a -> STM Bool
+ Chiasma.Prelude: tryReadMVar :: MonadIO m => MVar a -> m (Maybe a)
+ Chiasma.Prelude: tryReadTMVar :: TMVar a -> STM (Maybe a)
+ Chiasma.Prelude: tryTakeMVar :: MonadIO m => MVar a -> m (Maybe a)
+ Chiasma.Prelude: tryTakeTMVar :: TMVar a -> STM (Maybe a)
+ Chiasma.Prelude: tuple :: Applicative f => f a -> f b -> f (a, b)
+ Chiasma.Prelude: type FilePath = String
+ Chiasma.Prelude: type HasCallStack = ?callStack :: CallStack
+ Chiasma.Prelude: type LByteString = ByteString
+ Chiasma.Prelude: type LText = Text
+ Chiasma.Prelude: type OnDecodeError = OnError Word8 Char
+ Chiasma.Prelude: type OnError a b = String -> Maybe a -> Maybe b
+ Chiasma.Prelude: type Rational = Ratio Integer
+ Chiasma.Prelude: type Reader r = ReaderT r Identity
+ Chiasma.Prelude: type State s = StateT s Identity
+ Chiasma.Prelude: type String = [Char]
+ Chiasma.Prelude: type family OneItem x;
+ Chiasma.Prelude: uncons :: [a] -> Maybe (a, [a])
+ Chiasma.Prelude: uncurry :: (a -> b -> c) -> (a, b) -> c
+ Chiasma.Prelude: undefined :: forall (r :: RuntimeRep) (a :: TYPE r). HasCallStack => a
+ Chiasma.Prelude: unfoldr :: (b -> Maybe (a, b)) -> b -> [a]
+ Chiasma.Prelude: unit :: Applicative f => f ()
+ Chiasma.Prelude: unless :: Applicative f => Bool -> f () -> f ()
+ Chiasma.Prelude: unlessM :: Monad m => m Bool -> m () -> m ()
+ Chiasma.Prelude: unlines :: IsText t "unlines" => [t] -> t
+ Chiasma.Prelude: unsafeLogAnd :: Text -> b -> b
+ Chiasma.Prelude: unsafeLogS :: Show a => a -> a
+ Chiasma.Prelude: unsafeLogSAnd :: Show a => a -> b -> b
+ Chiasma.Prelude: unstableNub :: (Eq a, Hashable a) => [a] -> [a]
+ Chiasma.Prelude: unwords :: IsText t "unwords" => [t] -> t
+ Chiasma.Prelude: unzip :: [(a, b)] -> ([a], [b])
+ Chiasma.Prelude: unzip3 :: [(a, b, c)] -> ([a], [b], [c])
+ Chiasma.Prelude: usingReader :: r -> Reader r a -> a
+ Chiasma.Prelude: usingReaderT :: r -> ReaderT r m a -> m a
+ Chiasma.Prelude: usingState :: s -> State s a -> (a, s)
+ Chiasma.Prelude: usingStateT :: s -> StateT s m a -> m (a, s)
+ Chiasma.Prelude: vacuous :: Functor f => f Void -> f a
+ Chiasma.Prelude: viaNonEmpty :: (NonEmpty a -> b) -> [a] -> Maybe b
+ Chiasma.Prelude: void :: Functor f => f a -> f ()
+ Chiasma.Prelude: when :: Applicative f => Bool -> f () -> f ()
+ Chiasma.Prelude: whenJust :: Applicative f => Maybe a -> (a -> f ()) -> f ()
+ Chiasma.Prelude: whenJustM :: Monad m => m (Maybe a) -> (a -> m ()) -> m ()
+ Chiasma.Prelude: whenLeft :: Applicative f => a -> Either l r -> (l -> f a) -> f a
+ Chiasma.Prelude: whenLeftM :: Monad m => a -> m (Either l r) -> (l -> m a) -> m a
+ Chiasma.Prelude: whenLeftM_ :: Monad m => m (Either l r) -> (l -> m ()) -> m ()
+ Chiasma.Prelude: whenLeft_ :: Applicative f => Either l r -> (l -> f ()) -> f ()
+ Chiasma.Prelude: whenM :: Monad m => m Bool -> m () -> m ()
+ Chiasma.Prelude: whenNotNull :: Applicative f => [a] -> (NonEmpty a -> f ()) -> f ()
+ Chiasma.Prelude: whenNotNullM :: Monad m => m [a] -> (NonEmpty a -> m ()) -> m ()
+ Chiasma.Prelude: whenNothing :: Applicative f => Maybe a -> f a -> f a
+ Chiasma.Prelude: whenNothingM :: Monad m => m (Maybe a) -> m a -> m a
+ Chiasma.Prelude: whenNothingM_ :: Monad m => m (Maybe a) -> m () -> m ()
+ Chiasma.Prelude: whenNothing_ :: Applicative f => Maybe a -> f () -> f ()
+ Chiasma.Prelude: whenRight :: Applicative f => a -> Either l r -> (r -> f a) -> f a
+ Chiasma.Prelude: whenRightM :: Monad m => a -> m (Either l r) -> (r -> m a) -> m a
+ Chiasma.Prelude: whenRightM_ :: Monad m => m (Either l r) -> (r -> m ()) -> m ()
+ Chiasma.Prelude: whenRight_ :: Applicative f => Either l r -> (r -> f ()) -> f ()
+ Chiasma.Prelude: withFile :: FilePath -> IOMode -> (Handle -> IO r) -> IO r
+ Chiasma.Prelude: withFrozenCallStack :: HasCallStack => (HasCallStack => a) -> a
+ Chiasma.Prelude: withReader :: (r' -> r) -> Reader r a -> Reader r' a
+ Chiasma.Prelude: withReaderT :: forall r' r (m :: Type -> Type) a. (r' -> r) -> ReaderT r m a -> ReaderT r' m a
+ Chiasma.Prelude: withState :: (s -> s) -> State s a -> State s a
+ Chiasma.Prelude: words :: IsText t "words" => t -> [t]
+ Chiasma.Prelude: writeFile :: MonadIO m => FilePath -> String -> m ()
+ Chiasma.Prelude: writeFileBS :: MonadIO m => FilePath -> ByteString -> m ()
+ Chiasma.Prelude: writeFileLBS :: MonadIO m => FilePath -> LByteString -> m ()
+ Chiasma.Prelude: writeFileLText :: MonadIO m => FilePath -> LText -> m ()
+ Chiasma.Prelude: writeFileText :: MonadIO m => FilePath -> Text -> m ()
+ Chiasma.Prelude: writeIORef :: MonadIO m => IORef a -> a -> m ()
+ Chiasma.Prelude: writeTVar :: TVar a -> a -> STM ()
+ Chiasma.Prelude: xor :: Bits a => a -> a -> a
+ Chiasma.Prelude: zip :: [a] -> [b] -> [(a, b)]
+ Chiasma.Prelude: zip3 :: [a] -> [b] -> [c] -> [(a, b, c)]
+ Chiasma.Prelude: zipWith :: (a -> b -> c) -> [a] -> [b] -> [c]
+ Chiasma.Prelude: zipWithM :: Applicative m => (a -> b -> m c) -> [a] -> [b] -> m [c]
+ Chiasma.Prelude: zipWithM_ :: Applicative m => (a -> b -> m c) -> [a] -> [b] -> m ()
+ Chiasma.Prelude: }
+ Chiasma.Render: render :: (MonadDeepState s Views m, MonadFree TmuxThunk m, MonadError RenderError m) => FilePath -> Ident -> Ident -> ViewTree -> m ()
+ Chiasma.Render: renderTree :: (MonadDeepState s Views m, MonadFree TmuxThunk m) => Ident -> Window -> RenderableTree -> m ()
+ Chiasma.Session: ensureSession :: MonadDeepState s Views m => MonadFree TmuxThunk m => View SessionId -> View WindowId -> m (SessionId, Maybe WindowId)
+ Chiasma.Session: findOrCreateSession :: MonadDeepState s Views m => Ident -> m (View SessionId)
+ Chiasma.Session: spawnSession :: MonadDeepState s Views m => MonadFree TmuxThunk m => View SessionId -> View WindowId -> m (SessionId, WindowId)
+ Chiasma.Test.Screenshot: loadScreenshot :: MonadIO m => FilePath -> m (Maybe Text)
+ Chiasma.Test.Screenshot: recordScreenshot :: MonadFree TmuxThunk m => MonadIO m => FilePath -> Int -> m ()
+ Chiasma.Test.Screenshot: screenshot :: MonadFree TmuxThunk m => MonadIO m => Bool -> FilePath -> Text -> Int -> m (Maybe ([Text], [Text]))
+ Chiasma.Test.Screenshot: storeScreenshot :: MonadIO m => FilePath -> [Text] -> m ()
+ Chiasma.Test.Screenshot: takeScreenshot :: MonadFree TmuxThunk m => MonadIO m => Int -> m [Text]
+ Chiasma.Test.Screenshot: testScreenshot :: MonadFree TmuxThunk m => MonadIO m => FilePath -> Int -> m (Maybe ([Text], [Text]))
+ Chiasma.Test.Tmux: Terminal :: Handle -> Pty -> Terminal
+ Chiasma.Test.Tmux: TmuxTestConf :: Int -> Int -> Int -> Bool -> TmuxTestConf
+ Chiasma.Test.Tmux: [$sel:ttcFontSize:TmuxTestConf] :: TmuxTestConf -> Int
+ Chiasma.Test.Tmux: [$sel:ttcGui:TmuxTestConf] :: TmuxTestConf -> Bool
+ Chiasma.Test.Tmux: [$sel:ttcHeight:TmuxTestConf] :: TmuxTestConf -> Int
+ Chiasma.Test.Tmux: [$sel:ttcWidth:TmuxTestConf] :: TmuxTestConf -> Int
+ Chiasma.Test.Tmux: data Terminal
+ Chiasma.Test.Tmux: data TmuxTestConf
+ Chiasma.Test.Tmux: instance Data.Default.Class.Default Chiasma.Test.Tmux.TmuxTestConf
+ Chiasma.Test.Tmux: instance GHC.Classes.Eq Chiasma.Test.Tmux.TmuxTestConf
+ Chiasma.Test.Tmux: instance GHC.Show.Show Chiasma.Test.Tmux.TmuxTestConf
+ Chiasma.Test.Tmux: killPid :: Integral a => a -> IO ()
+ Chiasma.Test.Tmux: killProcess :: TmuxNative -> Process () () () -> IO ()
+ Chiasma.Test.Tmux: runAndKillTmux :: (TmuxNative -> IO a) -> TmuxNative -> Process () () () -> IO a
+ Chiasma.Test.Tmux: sleep :: MonadIO f => Double -> f ()
+ Chiasma.Test.Tmux: testTmuxProcessConfig :: TmuxTestConf -> FilePath -> FilePath -> Terminal -> IO (ProcessConfig () () ())
+ Chiasma.Test.Tmux: tmuxGuiSpec :: (TmuxNative -> IO a) -> IO a
+ Chiasma.Test.Tmux: tmuxSpec' :: TmuxTestConf -> (TmuxNative -> IO a) -> IO a
+ Chiasma.Test.Tmux: unsafeTerminal :: IO Terminal
+ Chiasma.Test.Tmux: urxvtArgs :: Int -> Int -> Int -> [Text]
+ Chiasma.Test.Tmux: usleep :: MonadIO f => Double -> f ()
+ Chiasma.Ui.Data.Measure: MLayout :: PaneId -> Int -> Int -> Bool -> MLayout
+ Chiasma.Ui.Data.Measure: MPane :: PaneId -> Int -> Int -> MPane
+ Chiasma.Ui.Data.Measure: Measured :: Int -> a -> Measured a
+ Chiasma.Ui.Data.Measure: [$sel:_lMainPosition:MLayout] :: MLayout -> Int
+ Chiasma.Ui.Data.Measure: [$sel:_lOffPosition:MLayout] :: MLayout -> Int
+ Chiasma.Ui.Data.Measure: [$sel:_mainPosition:MPane] :: MPane -> Int
+ Chiasma.Ui.Data.Measure: [$sel:_offPosition:MPane] :: MPane -> Int
+ Chiasma.Ui.Data.Measure: [$sel:_paneId:MPane] :: MPane -> PaneId
+ Chiasma.Ui.Data.Measure: [$sel:_reference:MLayout] :: MLayout -> PaneId
+ Chiasma.Ui.Data.Measure: [$sel:_size:Measured] :: Measured a -> Int
+ Chiasma.Ui.Data.Measure: [$sel:_vertical:MLayout] :: MLayout -> Bool
+ Chiasma.Ui.Data.Measure: [$sel:_view:Measured] :: Measured a -> a
+ Chiasma.Ui.Data.Measure: class HasMLayout c_avMv
+ Chiasma.Ui.Data.Measure: class HasMPane c_avGZ
+ Chiasma.Ui.Data.Measure: class HasMeasured c_avSQ a_avN4 | c_avSQ -> a_avN4
+ Chiasma.Ui.Data.Measure: data MLayout
+ Chiasma.Ui.Data.Measure: data MPane
+ Chiasma.Ui.Data.Measure: data Measured a
+ Chiasma.Ui.Data.Measure: instance Chiasma.Ui.Data.Measure.HasMLayout Chiasma.Ui.Data.Measure.MLayout
+ Chiasma.Ui.Data.Measure: instance Chiasma.Ui.Data.Measure.HasMPane Chiasma.Ui.Data.Measure.MPane
+ Chiasma.Ui.Data.Measure: instance Chiasma.Ui.Data.Measure.HasMeasured (Chiasma.Ui.Data.Measure.Measured a) a
+ Chiasma.Ui.Data.Measure: instance GHC.Classes.Eq Chiasma.Ui.Data.Measure.MLayout
+ Chiasma.Ui.Data.Measure: instance GHC.Classes.Eq Chiasma.Ui.Data.Measure.MPane
+ Chiasma.Ui.Data.Measure: instance GHC.Classes.Eq a => GHC.Classes.Eq (Chiasma.Ui.Data.Measure.Measured a)
+ Chiasma.Ui.Data.Measure: instance GHC.Show.Show Chiasma.Ui.Data.Measure.MLayout
+ Chiasma.Ui.Data.Measure: instance GHC.Show.Show Chiasma.Ui.Data.Measure.MPane
+ Chiasma.Ui.Data.Measure: instance GHC.Show.Show a => GHC.Show.Show (Chiasma.Ui.Data.Measure.Measured a)
+ Chiasma.Ui.Data.Measure: instance Prettyprinter.Internal.Pretty Chiasma.Ui.Data.Measure.MLayout
+ Chiasma.Ui.Data.Measure: instance Prettyprinter.Internal.Pretty Chiasma.Ui.Data.Measure.MPane
+ Chiasma.Ui.Data.Measure: instance Prettyprinter.Internal.Pretty a => Prettyprinter.Internal.Pretty (Chiasma.Ui.Data.Measure.Measured a)
+ Chiasma.Ui.Data.Measure: lMainPosition :: HasMLayout c_avMv => Lens' c_avMv Int
+ Chiasma.Ui.Data.Measure: lOffPosition :: HasMLayout c_avMv => Lens' c_avMv Int
+ Chiasma.Ui.Data.Measure: mLayout :: HasMLayout c_avMv => Lens' c_avMv MLayout
+ Chiasma.Ui.Data.Measure: mPane :: HasMPane c_avGZ => Lens' c_avGZ MPane
+ Chiasma.Ui.Data.Measure: mainPosition :: HasMPane c_avGZ => Lens' c_avGZ Int
+ Chiasma.Ui.Data.Measure: measured :: HasMeasured c_avSQ a_avN4 => Lens' c_avSQ (Measured a_avN4)
+ Chiasma.Ui.Data.Measure: offPosition :: HasMPane c_avGZ => Lens' c_avGZ Int
+ Chiasma.Ui.Data.Measure: paneId :: HasMPane c_avGZ => Lens' c_avGZ PaneId
+ Chiasma.Ui.Data.Measure: reference :: HasMLayout c_avMv => Lens' c_avMv PaneId
+ Chiasma.Ui.Data.Measure: size :: HasMeasured c_avSQ a_avN4 => Lens' c_avSQ Int
+ Chiasma.Ui.Data.Measure: type MeasureTree = NTree (Measured MLayout) (Measured MPane)
+ Chiasma.Ui.Data.Measure: type MeasureTreeSub = NNode (Measured MLayout) (Measured MPane)
+ Chiasma.Ui.Data.Measure: vertical :: HasMLayout c_avMv => Lens' c_avMv Bool
+ Chiasma.Ui.Data.Measure: view :: HasMeasured c_avSQ a_avN4 => Lens' c_avSQ a_avN4
+ Chiasma.Ui.Data.RenderableTree: RLayout :: RPane -> Bool -> RLayout
+ Chiasma.Ui.Data.RenderableTree: RPane :: PaneId -> Int -> Int -> RPane
+ Chiasma.Ui.Data.RenderableTree: Renderable :: ViewState -> ViewGeometry -> a -> Renderable a
+ Chiasma.Ui.Data.RenderableTree: [$sel:_geometry:Renderable] :: Renderable a -> ViewGeometry
+ Chiasma.Ui.Data.RenderableTree: [$sel:_id:RPane] :: RPane -> PaneId
+ Chiasma.Ui.Data.RenderableTree: [$sel:_left:RPane] :: RPane -> Int
+ Chiasma.Ui.Data.RenderableTree: [$sel:_ref:RLayout] :: RLayout -> RPane
+ Chiasma.Ui.Data.RenderableTree: [$sel:_state:Renderable] :: Renderable a -> ViewState
+ Chiasma.Ui.Data.RenderableTree: [$sel:_top:RPane] :: RPane -> Int
+ Chiasma.Ui.Data.RenderableTree: [$sel:_vertical:RLayout] :: RLayout -> Bool
+ Chiasma.Ui.Data.RenderableTree: [$sel:_view:Renderable] :: Renderable a -> a
+ Chiasma.Ui.Data.RenderableTree: data RLayout
+ Chiasma.Ui.Data.RenderableTree: data RPane
+ Chiasma.Ui.Data.RenderableTree: data Renderable a
+ Chiasma.Ui.Data.RenderableTree: instance GHC.Classes.Eq Chiasma.Ui.Data.RenderableTree.RLayout
+ Chiasma.Ui.Data.RenderableTree: instance GHC.Classes.Eq Chiasma.Ui.Data.RenderableTree.RPane
+ Chiasma.Ui.Data.RenderableTree: instance GHC.Classes.Eq a => GHC.Classes.Eq (Chiasma.Ui.Data.RenderableTree.Renderable a)
+ Chiasma.Ui.Data.RenderableTree: instance GHC.Show.Show Chiasma.Ui.Data.RenderableTree.RLayout
+ Chiasma.Ui.Data.RenderableTree: instance GHC.Show.Show Chiasma.Ui.Data.RenderableTree.RPane
+ Chiasma.Ui.Data.RenderableTree: instance GHC.Show.Show a => GHC.Show.Show (Chiasma.Ui.Data.RenderableTree.Renderable a)
+ Chiasma.Ui.Data.RenderableTree: instance Prettyprinter.Internal.Pretty Chiasma.Ui.Data.RenderableTree.RLayout
+ Chiasma.Ui.Data.RenderableTree: instance Prettyprinter.Internal.Pretty Chiasma.Ui.Data.RenderableTree.RPane
+ Chiasma.Ui.Data.RenderableTree: instance Prettyprinter.Internal.Pretty a => Prettyprinter.Internal.Pretty (Chiasma.Ui.Data.RenderableTree.Renderable a)
+ Chiasma.Ui.Data.RenderableTree: mayPretty :: Text -> Maybe Float -> Doc a
+ Chiasma.Ui.Data.RenderableTree: type RenderableLayout = Renderable RLayout
+ Chiasma.Ui.Data.RenderableTree: type RenderableNode = NNode RenderableLayout RenderablePane
+ Chiasma.Ui.Data.RenderableTree: type RenderablePane = Renderable RPane
+ Chiasma.Ui.Data.RenderableTree: type RenderableTree = NTree RenderableLayout RenderablePane
+ Chiasma.Ui.Data.Tree: Leaf :: p -> Node f l p
+ Chiasma.Ui.Data.Tree: Sub :: Tree f l p -> Node f l p
+ Chiasma.Ui.Data.Tree: Tree :: l -> f (Node f l p) -> Tree f l p
+ Chiasma.Ui.Data.Tree: [$sel:_forest:Tree] :: Tree f l p -> f (Node f l p)
+ Chiasma.Ui.Data.Tree: [$sel:_leafData:Sub] :: Node f l p -> p
+ Chiasma.Ui.Data.Tree: [$sel:_subTree:Sub] :: Node f l p -> Tree f l p
+ Chiasma.Ui.Data.Tree: [$sel:_treeData:Tree] :: Tree f l p -> l
+ Chiasma.Ui.Data.Tree: class HasNode c_anrU f_anj0 l_anj1 p_anj2 | c_anrU -> f_anj0 l_anj1 p_anj2
+ Chiasma.Ui.Data.Tree: class HasTree c_anoa f_anj3 l_anj4 p_anj5 | c_anoa -> f_anj3 l_anj4 p_anj5
+ Chiasma.Ui.Data.Tree: data Node f l p
+ Chiasma.Ui.Data.Tree: data Tree f l p
+ Chiasma.Ui.Data.Tree: forest :: HasTree c_anoa f_anj3 l_anj4 p_anj5 => Lens' c_anoa (f_anj3 (Node f_anj3 l_anj4 p_anj5))
+ Chiasma.Ui.Data.Tree: instance (Data.Foldable.Foldable f, Prettyprinter.Internal.Pretty l, Prettyprinter.Internal.Pretty p) => Prettyprinter.Internal.Pretty (Chiasma.Ui.Data.Tree.Node f l p)
+ Chiasma.Ui.Data.Tree: instance (Data.Foldable.Foldable f, Prettyprinter.Internal.Pretty l, Prettyprinter.Internal.Pretty p) => Prettyprinter.Internal.Pretty (Chiasma.Ui.Data.Tree.Tree f l p)
+ Chiasma.Ui.Data.Tree: instance (GHC.Classes.Eq l, GHC.Classes.Eq p) => GHC.Classes.Eq (Chiasma.Ui.Data.Tree.Node GHC.Base.NonEmpty l p)
+ Chiasma.Ui.Data.Tree: instance (GHC.Classes.Eq l, GHC.Classes.Eq p) => GHC.Classes.Eq (Chiasma.Ui.Data.Tree.Node [] l p)
+ Chiasma.Ui.Data.Tree: instance (GHC.Classes.Eq l, GHC.Classes.Eq p) => GHC.Classes.Eq (Chiasma.Ui.Data.Tree.Tree GHC.Base.NonEmpty l p)
+ Chiasma.Ui.Data.Tree: instance (GHC.Classes.Eq l, GHC.Classes.Eq p) => GHC.Classes.Eq (Chiasma.Ui.Data.Tree.Tree [] l p)
+ Chiasma.Ui.Data.Tree: instance (GHC.Show.Show l, GHC.Show.Show p) => GHC.Show.Show (Chiasma.Ui.Data.Tree.Node GHC.Base.NonEmpty l p)
+ Chiasma.Ui.Data.Tree: instance (GHC.Show.Show l, GHC.Show.Show p) => GHC.Show.Show (Chiasma.Ui.Data.Tree.Node [] l p)
+ Chiasma.Ui.Data.Tree: instance (GHC.Show.Show l, GHC.Show.Show p) => GHC.Show.Show (Chiasma.Ui.Data.Tree.Tree GHC.Base.NonEmpty l p)
+ Chiasma.Ui.Data.Tree: instance (GHC.Show.Show l, GHC.Show.Show p) => GHC.Show.Show (Chiasma.Ui.Data.Tree.Tree [] l p)
+ Chiasma.Ui.Data.Tree: instance Chiasma.Ui.Data.Tree.HasNode (Chiasma.Ui.Data.Tree.Node f l p) f l p
+ Chiasma.Ui.Data.Tree: instance Chiasma.Ui.Data.Tree.HasTree (Chiasma.Ui.Data.Tree.Tree f l p) f l p
+ Chiasma.Ui.Data.Tree: leafData :: HasNode c_anrU f_anj0 l_anj1 p_anj2 => Traversal' c_anrU p_anj2
+ Chiasma.Ui.Data.Tree: node :: HasNode c_anrU f_anj0 l_anj1 p_anj2 => Lens' c_anrU (Node f_anj0 l_anj1 p_anj2)
+ Chiasma.Ui.Data.Tree: subTree :: HasNode c_anrU f_anj0 l_anj1 p_anj2 => Traversal' c_anrU (Tree f_anj0 l_anj1 p_anj2)
+ Chiasma.Ui.Data.Tree: tree :: HasTree c_anoa f_anj3 l_anj4 p_anj5 => Lens' c_anoa (Tree f_anj3 l_anj4 p_anj5)
+ Chiasma.Ui.Data.Tree: treeData :: HasTree c_anoa f_anj3 l_anj4 p_anj5 => Lens' c_anoa l_anj4
+ Chiasma.Ui.Data.Tree: type LNode l p = Node [] l p
+ Chiasma.Ui.Data.Tree: type LTree l p = Tree [] l p
+ Chiasma.Ui.Data.Tree: type NNode l p = Node NonEmpty l p
+ Chiasma.Ui.Data.Tree: type NTree l p = Tree NonEmpty l p
+ Chiasma.Ui.Data.TreeModError: AmbiguousLayout :: Ident -> Int -> TreeModError
+ Chiasma.Ui.Data.TreeModError: AmbiguousPane :: Ident -> Int -> TreeModError
+ Chiasma.Ui.Data.TreeModError: LayoutExists :: LayoutView -> TreeModError
+ Chiasma.Ui.Data.TreeModError: LayoutMissing :: Ident -> TreeModError
+ Chiasma.Ui.Data.TreeModError: NoTrees :: TreeModError
+ Chiasma.Ui.Data.TreeModError: PaneExists :: PaneView -> TreeModError
+ Chiasma.Ui.Data.TreeModError: PaneMissing :: Ident -> TreeModError
+ Chiasma.Ui.Data.TreeModError: _AmbiguousLayout :: AsTreeModError r_aL47 => Prism' r_aL47 (Ident, Int)
+ Chiasma.Ui.Data.TreeModError: _AmbiguousPane :: AsTreeModError r_aL47 => Prism' r_aL47 (Ident, Int)
+ Chiasma.Ui.Data.TreeModError: _LayoutExists :: AsTreeModError r_aL47 => Prism' r_aL47 LayoutView
+ Chiasma.Ui.Data.TreeModError: _LayoutMissing :: AsTreeModError r_aL47 => Prism' r_aL47 Ident
+ Chiasma.Ui.Data.TreeModError: _NoTrees :: AsTreeModError r_aL47 => Prism' r_aL47 ()
+ Chiasma.Ui.Data.TreeModError: _PaneExists :: AsTreeModError r_aL47 => Prism' r_aL47 PaneView
+ Chiasma.Ui.Data.TreeModError: _PaneMissing :: AsTreeModError r_aL47 => Prism' r_aL47 Ident
+ Chiasma.Ui.Data.TreeModError: _TreeModError :: AsTreeModError r_aL47 => Prism' r_aL47 TreeModError
+ Chiasma.Ui.Data.TreeModError: class AsTreeModError r_aL47
+ Chiasma.Ui.Data.TreeModError: data TreeModError
+ Chiasma.Ui.Data.TreeModError: instance Chiasma.Ui.Data.TreeModError.AsTreeModError Chiasma.Ui.Data.TreeModError.TreeModError
+ Chiasma.Ui.Data.TreeModError: instance Data.DeepPrisms.DeepPrisms Chiasma.Ui.Data.TreeModError.TreeModError Chiasma.Ui.Data.TreeModError.TreeModError
+ Chiasma.Ui.Data.TreeModError: instance GHC.Classes.Eq Chiasma.Ui.Data.TreeModError.TreeModError
+ Chiasma.Ui.Data.TreeModError: instance GHC.Show.Show Chiasma.Ui.Data.TreeModError.TreeModError
+ Chiasma.Ui.Data.View: Layout :: Bool -> Layout
+ Chiasma.Ui.Data.View: Pane :: Bool -> Bool -> Maybe FilePath -> Pane
+ Chiasma.Ui.Data.View: Tree :: l -> [TreeSub l p] -> Tree l p
+ Chiasma.Ui.Data.View: TreeLeaf :: p -> TreeSub l p
+ Chiasma.Ui.Data.View: TreeNode :: Tree l p -> TreeSub l p
+ Chiasma.Ui.Data.View: View :: Ident -> ViewState -> ViewGeometry -> a -> View a
+ Chiasma.Ui.Data.View: [$sel:_cwd:Pane] :: Pane -> Maybe FilePath
+ Chiasma.Ui.Data.View: [$sel:_extra:View] :: View a -> a
+ Chiasma.Ui.Data.View: [$sel:_geometry:View] :: View a -> ViewGeometry
+ Chiasma.Ui.Data.View: [$sel:_ident:View] :: View a -> Ident
+ Chiasma.Ui.Data.View: [$sel:_leafData:TreeNode] :: TreeSub l p -> p
+ Chiasma.Ui.Data.View: [$sel:_open:Pane] :: Pane -> Bool
+ Chiasma.Ui.Data.View: [$sel:_pin:Pane] :: Pane -> Bool
+ Chiasma.Ui.Data.View: [$sel:_state:View] :: View a -> ViewState
+ Chiasma.Ui.Data.View: [$sel:_subTree:TreeNode] :: TreeSub l p -> Tree l p
+ Chiasma.Ui.Data.View: [$sel:treeData:Tree] :: Tree l p -> l
+ Chiasma.Ui.Data.View: [$sel:treeSubs:Tree] :: Tree l p -> [TreeSub l p]
+ Chiasma.Ui.Data.View: [$sel:vertical:Layout] :: Layout -> Bool
+ Chiasma.Ui.Data.View: _treeData :: HasTree c_aEp4 l_aDPI p_aDPJ => Lens' c_aEp4 l_aDPI
+ Chiasma.Ui.Data.View: _treeSubs :: HasTree c_aEp4 l_aDPI p_aDPJ => Lens' c_aEp4 [TreeSub l_aDPI p_aDPJ]
+ Chiasma.Ui.Data.View: _vertical :: HasLayout c_aDkB => Lens' c_aDkB Bool
+ Chiasma.Ui.Data.View: class HasLayout c_aDkB
+ Chiasma.Ui.Data.View: class HasPane c_aDad
+ Chiasma.Ui.Data.View: class HasTree c_aEp4 l_aDPI p_aDPJ | c_aEp4 -> l_aDPI p_aDPJ
+ Chiasma.Ui.Data.View: class HasTreeSub c_aEsb l_aDPG p_aDPH | c_aEsb -> l_aDPG p_aDPH
+ Chiasma.Ui.Data.View: class HasView c_aDOV a_aDkM | c_aDOV -> a_aDkM
+ Chiasma.Ui.Data.View: consLayout :: Ident -> LayoutView
+ Chiasma.Ui.Data.View: consLayoutAs :: Bool -> Ident -> LayoutView
+ Chiasma.Ui.Data.View: consLayoutVertical :: Ident -> LayoutView
+ Chiasma.Ui.Data.View: consPane :: Ident -> PaneView
+ Chiasma.Ui.Data.View: cwd :: HasPane c_aDad => Lens' c_aDad (Maybe FilePath)
+ Chiasma.Ui.Data.View: data Pane
+ Chiasma.Ui.Data.View: data Tree l p
+ Chiasma.Ui.Data.View: data TreeSub l p
+ Chiasma.Ui.Data.View: data View a
+ Chiasma.Ui.Data.View: extra :: HasView c_aDOV a_aDkM => Lens' c_aDOV a_aDkM
+ Chiasma.Ui.Data.View: geometry :: HasView c_aDOV a_aDkM => Lens' c_aDOV ViewGeometry
+ Chiasma.Ui.Data.View: ident :: HasView c_aDOV a_aDkM => Lens' c_aDOV Ident
+ Chiasma.Ui.Data.View: instance (Data.Data.Data l, Data.Data.Data p) => Control.Lens.Plated.Plated (Chiasma.Ui.Data.View.Tree l p)
+ Chiasma.Ui.Data.View: instance (Data.Data.Data l, Data.Data.Data p) => Data.Data.Data (Chiasma.Ui.Data.View.Tree l p)
+ Chiasma.Ui.Data.View: instance (Data.Data.Data l, Data.Data.Data p) => Data.Data.Data (Chiasma.Ui.Data.View.TreeSub l p)
+ Chiasma.Ui.Data.View: instance (GHC.Classes.Eq l, GHC.Classes.Eq p) => GHC.Classes.Eq (Chiasma.Ui.Data.View.Tree l p)
+ Chiasma.Ui.Data.View: instance (GHC.Classes.Eq l, GHC.Classes.Eq p) => GHC.Classes.Eq (Chiasma.Ui.Data.View.TreeSub l p)
+ Chiasma.Ui.Data.View: instance (GHC.Show.Show l, GHC.Show.Show p) => GHC.Show.Show (Chiasma.Ui.Data.View.Tree l p)
+ Chiasma.Ui.Data.View: instance (GHC.Show.Show l, GHC.Show.Show p) => GHC.Show.Show (Chiasma.Ui.Data.View.TreeSub l p)
+ Chiasma.Ui.Data.View: instance (Prettyprinter.Internal.Pretty l, Prettyprinter.Internal.Pretty p) => Prettyprinter.Internal.Pretty (Chiasma.Ui.Data.View.Tree l p)
+ Chiasma.Ui.Data.View: instance (Prettyprinter.Internal.Pretty l, Prettyprinter.Internal.Pretty p) => Prettyprinter.Internal.Pretty (Chiasma.Ui.Data.View.TreeSub l p)
+ Chiasma.Ui.Data.View: instance Chiasma.Data.Ident.Identifiable (Chiasma.Ui.Data.View.View a)
+ Chiasma.Ui.Data.View: instance Chiasma.Data.Ident.Identifiable l => Chiasma.Data.Ident.Identifiable (Chiasma.Ui.Data.View.Tree l p)
+ Chiasma.Ui.Data.View: instance Chiasma.Data.Ident.Identifiable l => Control.Lens.At.Ixed (Chiasma.Ui.Data.View.Tree l p)
+ Chiasma.Ui.Data.View: instance Chiasma.Ui.Data.View.HasLayout Chiasma.Ui.Data.View.Layout
+ Chiasma.Ui.Data.View: instance Chiasma.Ui.Data.View.HasPane Chiasma.Ui.Data.View.Pane
+ Chiasma.Ui.Data.View: instance Chiasma.Ui.Data.View.HasTree (Chiasma.Ui.Data.View.Tree l p) l p
+ Chiasma.Ui.Data.View: instance Chiasma.Ui.Data.View.HasTreeSub (Chiasma.Ui.Data.View.TreeSub l p) l p
+ Chiasma.Ui.Data.View: instance Chiasma.Ui.Data.View.HasView (Chiasma.Ui.Data.View.View a) a
+ Chiasma.Ui.Data.View: instance Data.Bifoldable.Bifoldable Chiasma.Ui.Data.View.Tree
+ Chiasma.Ui.Data.View: instance Data.Bifoldable.Bifoldable Chiasma.Ui.Data.View.TreeSub
+ Chiasma.Ui.Data.View: instance Data.Bifunctor.Bifunctor Chiasma.Ui.Data.View.Tree
+ Chiasma.Ui.Data.View: instance Data.Bifunctor.Bifunctor Chiasma.Ui.Data.View.TreeSub
+ Chiasma.Ui.Data.View: instance Data.Data.Data Chiasma.Ui.Data.View.Layout
+ Chiasma.Ui.Data.View: instance Data.Data.Data Chiasma.Ui.Data.View.Pane
+ Chiasma.Ui.Data.View: instance Data.Data.Data a => Data.Data.Data (Chiasma.Ui.Data.View.View a)
+ Chiasma.Ui.Data.View: instance Data.Default.Class.Default Chiasma.Ui.Data.View.Layout
+ Chiasma.Ui.Data.View: instance Data.Default.Class.Default Chiasma.Ui.Data.View.Pane
+ Chiasma.Ui.Data.View: instance Data.Default.Class.Default a => Data.Default.Class.Default (Chiasma.Ui.Data.View.View a)
+ Chiasma.Ui.Data.View: instance GHC.Classes.Eq Chiasma.Ui.Data.View.Layout
+ Chiasma.Ui.Data.View: instance GHC.Classes.Eq Chiasma.Ui.Data.View.Pane
+ Chiasma.Ui.Data.View: instance GHC.Classes.Eq a => GHC.Classes.Eq (Chiasma.Ui.Data.View.View a)
+ Chiasma.Ui.Data.View: instance GHC.Generics.Generic (Chiasma.Ui.Data.View.Tree l p)
+ Chiasma.Ui.Data.View: instance GHC.Generics.Generic (Chiasma.Ui.Data.View.TreeSub l p)
+ Chiasma.Ui.Data.View: instance GHC.Generics.Generic (Chiasma.Ui.Data.View.View a)
+ Chiasma.Ui.Data.View: instance GHC.Generics.Generic Chiasma.Ui.Data.View.Layout
+ Chiasma.Ui.Data.View: instance GHC.Generics.Generic Chiasma.Ui.Data.View.Pane
+ Chiasma.Ui.Data.View: instance GHC.Show.Show Chiasma.Ui.Data.View.Layout
+ Chiasma.Ui.Data.View: instance GHC.Show.Show Chiasma.Ui.Data.View.Pane
+ Chiasma.Ui.Data.View: instance GHC.Show.Show a => GHC.Show.Show (Chiasma.Ui.Data.View.View a)
+ Chiasma.Ui.Data.View: instance Prettyprinter.Internal.Pretty (Chiasma.Ui.Data.View.View Chiasma.Ui.Data.View.Layout)
+ Chiasma.Ui.Data.View: instance Prettyprinter.Internal.Pretty (Chiasma.Ui.Data.View.View Chiasma.Ui.Data.View.Pane)
+ Chiasma.Ui.Data.View: instance Prettyprinter.Internal.Pretty Chiasma.Ui.Data.View.Layout
+ Chiasma.Ui.Data.View: instance Prettyprinter.Internal.Pretty Chiasma.Ui.Data.View.Pane
+ Chiasma.Ui.Data.View: layout :: HasLayout c_aDkB => Lens' c_aDkB Layout
+ Chiasma.Ui.Data.View: leafData :: HasTreeSub c_aEsb l_aDPG p_aDPH => Traversal' c_aEsb p_aDPH
+ Chiasma.Ui.Data.View: newtype Layout
+ Chiasma.Ui.Data.View: open :: HasPane c_aDad => Lens' c_aDad Bool
+ Chiasma.Ui.Data.View: pane :: HasPane c_aDad => Lens' c_aDad Pane
+ Chiasma.Ui.Data.View: pin :: HasPane c_aDad => Lens' c_aDad Bool
+ Chiasma.Ui.Data.View: prettyView :: Doc a -> Ident -> ViewState -> ViewGeometry -> Doc a
+ Chiasma.Ui.Data.View: state :: HasView c_aDOV a_aDkM => Lens' c_aDOV ViewState
+ Chiasma.Ui.Data.View: subTree :: HasTreeSub c_aEsb l_aDPG p_aDPH => Traversal' c_aEsb (Tree l_aDPG p_aDPH)
+ Chiasma.Ui.Data.View: tree :: HasTree c_aEp4 l_aDPI p_aDPJ => Lens' c_aEp4 (Tree l_aDPI p_aDPJ)
+ Chiasma.Ui.Data.View: treeSub :: HasTreeSub c_aEsb l_aDPG p_aDPH => Lens' c_aEsb (TreeSub l_aDPG p_aDPH)
+ Chiasma.Ui.Data.View: type LayoutView = View Layout
+ Chiasma.Ui.Data.View: type PaneView = View Pane
+ Chiasma.Ui.Data.View: type ViewTree = Tree LayoutView PaneView
+ Chiasma.Ui.Data.View: type ViewTreeSub = TreeSub LayoutView PaneView
+ Chiasma.Ui.Data.View: view :: HasView c_aDOV a_aDkM => Lens' c_aDOV (View a_aDkM)
+ Chiasma.Ui.Data.ViewGeometry: ViewGeometry :: Maybe Float -> Maybe Float -> Maybe Float -> Maybe Float -> Maybe Float -> Maybe Float -> ViewGeometry
+ Chiasma.Ui.Data.ViewGeometry: [$sel:fixedSize:ViewGeometry] :: ViewGeometry -> Maybe Float
+ Chiasma.Ui.Data.ViewGeometry: [$sel:maxSize:ViewGeometry] :: ViewGeometry -> Maybe Float
+ Chiasma.Ui.Data.ViewGeometry: [$sel:minSize:ViewGeometry] :: ViewGeometry -> Maybe Float
+ Chiasma.Ui.Data.ViewGeometry: [$sel:minimizedSize:ViewGeometry] :: ViewGeometry -> Maybe Float
+ Chiasma.Ui.Data.ViewGeometry: [$sel:position:ViewGeometry] :: ViewGeometry -> Maybe Float
+ Chiasma.Ui.Data.ViewGeometry: [$sel:weight:ViewGeometry] :: ViewGeometry -> Maybe Float
+ Chiasma.Ui.Data.ViewGeometry: data ViewGeometry
+ Chiasma.Ui.Data.ViewGeometry: instance Data.Data.Data Chiasma.Ui.Data.ViewGeometry.ViewGeometry
+ Chiasma.Ui.Data.ViewGeometry: instance Data.Default.Class.Default Chiasma.Ui.Data.ViewGeometry.ViewGeometry
+ Chiasma.Ui.Data.ViewGeometry: instance GHC.Classes.Eq Chiasma.Ui.Data.ViewGeometry.ViewGeometry
+ Chiasma.Ui.Data.ViewGeometry: instance GHC.Generics.Generic Chiasma.Ui.Data.ViewGeometry.ViewGeometry
+ Chiasma.Ui.Data.ViewGeometry: instance GHC.Show.Show Chiasma.Ui.Data.ViewGeometry.ViewGeometry
+ Chiasma.Ui.Data.ViewGeometry: instance Prettyprinter.Internal.Pretty Chiasma.Ui.Data.ViewGeometry.ViewGeometry
+ Chiasma.Ui.Data.ViewGeometry: mayPretty :: Text -> Maybe Float -> Doc a
+ Chiasma.Ui.Data.ViewState: ViewState :: Bool -> ViewState
+ Chiasma.Ui.Data.ViewState: [$sel:minimized:ViewState] :: ViewState -> Bool
+ Chiasma.Ui.Data.ViewState: instance Data.Data.Data Chiasma.Ui.Data.ViewState.ViewState
+ Chiasma.Ui.Data.ViewState: instance Data.Default.Class.Default Chiasma.Ui.Data.ViewState.ViewState
+ Chiasma.Ui.Data.ViewState: instance GHC.Classes.Eq Chiasma.Ui.Data.ViewState.ViewState
+ Chiasma.Ui.Data.ViewState: instance GHC.Generics.Generic Chiasma.Ui.Data.ViewState.ViewState
+ Chiasma.Ui.Data.ViewState: instance GHC.Show.Show Chiasma.Ui.Data.ViewState.ViewState
+ Chiasma.Ui.Data.ViewState: newtype ViewState
+ Chiasma.Ui.Lens.Ident: matchIdent :: Identifiable a => Ident -> Traversal' a a
+ Chiasma.Ui.Lens.Ident: matchIdentL :: Identifiable a => Ident -> Traversal' [a] a
+ Chiasma.Ui.Lens.Ident: matchIdentP :: Identifiable a => Ident -> Prism' a a
+ Chiasma.Ui.Measure: actualMaxSizes :: NonEmpty (ViewState, ViewGeometry) -> NonEmpty (Maybe Float)
+ Chiasma.Ui.Measure: actualMinSizes :: NonEmpty (ViewState, ViewGeometry) -> NonEmpty Float
+ Chiasma.Ui.Measure: actualSize :: (ViewGeometry -> Maybe Float) -> ViewState -> ViewGeometry -> Maybe Float
+ Chiasma.Ui.Measure: effectiveFixedSize :: ViewState -> ViewGeometry -> Maybe Float
+ Chiasma.Ui.Measure: isMinimized :: ViewState -> ViewGeometry -> Bool
+ Chiasma.Ui.Measure: measureLayout :: RenderableTree -> Int -> Int -> Bool -> MeasureTree
+ Chiasma.Ui.Measure: measureLayoutViews :: Float -> NonEmpty RenderableNode -> NonEmpty Int
+ Chiasma.Ui.Measure: measureSub :: Int -> Int -> Bool -> RenderableNode -> Int -> MeasureTreeSub
+ Chiasma.Ui.Measure: measureTree :: RenderableTree -> Int -> Int -> MeasureTree
+ Chiasma.Ui.Measure: minimizedSizeOrDefault :: ViewGeometry -> Float
+ Chiasma.Ui.Measure: subMeasureData :: RenderableNode -> (ViewState, ViewGeometry)
+ Chiasma.Ui.Measure.Balance: Balance :: NonEmpty Float -> NonEmpty (Maybe Float) -> NonEmpty Float -> NonEmpty Bool -> Float -> Balance
+ Chiasma.Ui.Measure.Balance: [$sel:balanceMax:Balance] :: Balance -> NonEmpty (Maybe Float)
+ Chiasma.Ui.Measure.Balance: [$sel:balanceMin:Balance] :: Balance -> NonEmpty Float
+ Chiasma.Ui.Measure.Balance: [$sel:balanceMinimized:Balance] :: Balance -> NonEmpty Bool
+ Chiasma.Ui.Measure.Balance: [$sel:balanceTotal:Balance] :: Balance -> Float
+ Chiasma.Ui.Measure.Balance: [$sel:balanceWeights:Balance] :: Balance -> NonEmpty Float
+ Chiasma.Ui.Measure.Balance: balanceSizes :: NonEmpty Float -> NonEmpty (Maybe Float) -> NonEmpty Float -> NonEmpty Bool -> Float -> NonEmpty Int
+ Chiasma.Ui.Measure.Balance: cutSizes :: Balance -> NonEmpty Float
+ Chiasma.Ui.Measure.Balance: data Balance
+ Chiasma.Ui.Measure.Balance: distRest :: Balance -> Float -> NonEmpty Float -> NonEmpty Float -> NonEmpty Float
+ Chiasma.Ui.Measure.Balance: distributeOnAll :: Balance -> NonEmpty Float
+ Chiasma.Ui.Measure.Balance: distributeOnUnbounded :: Balance -> NonEmpty Float
+ Chiasma.Ui.Measure.Balance: distributeSizes :: Balance -> NonEmpty Float
+ Chiasma.Ui.Measure.Balance: ensureMinimum2 :: NonEmpty Float -> NonEmpty Float
+ Chiasma.Ui.Measure.Balance: hasUnbounded :: Balance -> Bool
+ Chiasma.Ui.Measure.Balance: rectifySizes :: NonEmpty Float -> NonEmpty Int
+ Chiasma.Ui.Measure.Balance: reverseWeights :: NonEmpty Float -> NonEmpty Float
+ Chiasma.Ui.Measure.Balance: roundSizes :: NonEmpty Float -> NonEmpty Int
+ Chiasma.Ui.Measure.Balance: saturate :: NonEmpty Float -> NonEmpty Float -> NonEmpty Float -> Float -> NonEmpty Float
+ Chiasma.Ui.Measure.Balance: trimWeights :: NonEmpty Bool -> NonEmpty Float -> NonEmpty Float
+ Chiasma.Ui.Measure.Balance: weightsWithoutMinimized :: Balance -> NonEmpty Float
+ Chiasma.Ui.Measure.Balance: zipWith3NE :: (a -> b -> c -> d) -> NonEmpty a -> NonEmpty b -> NonEmpty c -> NonEmpty d
+ Chiasma.Ui.Measure.Weights: amendAndNormalizeWeights :: NonEmpty (Maybe Float) -> NonEmpty Float
+ Chiasma.Ui.Measure.Weights: normalizeWeights :: NonEmpty Float -> NonEmpty Float
+ Chiasma.Ui.Measure.Weights: viewWeights :: NonEmpty (ViewState, ViewGeometry) -> NonEmpty Float
+ Chiasma.Ui.Pane: paneSetOpen :: PaneView -> PaneView
+ Chiasma.Ui.Pane: paneToggleOpen :: PaneView -> PaneView
+ Chiasma.Ui.ShowTree: formatLayout :: LayoutView -> Text
+ Chiasma.Ui.ShowTree: formatPane :: PaneView -> Text
+ Chiasma.Ui.ShowTree: formatViewTree :: ViewTree -> Tree Text Text
+ Chiasma.Ui.ShowTree: indent :: [Text] -> [Text]
+ Chiasma.Ui.ShowTree: printViewTree :: MonadIO m => ViewTree -> m ()
+ Chiasma.Ui.ShowTree: showTree :: Tree Text Text -> [Text]
+ Chiasma.Ui.ShowTree: showTreeSub :: TreeSub Text Text -> [Text]
+ Chiasma.Ui.ShowTree: showViewTree :: ViewTree -> [Text]
+ Chiasma.Ui.ViewTree: Ambiguous :: Int -> ToggleResult a
+ Chiasma.Ui.ViewTree: Consistent :: ToggleStatus
+ Chiasma.Ui.ViewTree: Minimized :: ToggleStatus
+ Chiasma.Ui.ViewTree: Multiple :: Int -> ToggleStatus
+ Chiasma.Ui.ViewTree: NotFound :: ToggleResult a
+ Chiasma.Ui.ViewTree: Opened :: ToggleStatus
+ Chiasma.Ui.ViewTree: Pristine :: ToggleStatus
+ Chiasma.Ui.ViewTree: Success :: a -> ToggleResult a
+ Chiasma.Ui.ViewTree: checkToggleResult :: ToggleStatus -> a -> ToggleResult a
+ Chiasma.Ui.ViewTree: data ToggleResult a
+ Chiasma.Ui.ViewTree: data ToggleStatus
+ Chiasma.Ui.ViewTree: depthTraverseTree :: forall a. Monoid a => (a -> ViewTree -> (a, ViewTree)) -> (PaneView -> (a, PaneView)) -> ViewTree -> (a, ViewTree)
+ Chiasma.Ui.ViewTree: ensurePaneOpen :: Ident -> ViewTree -> ToggleResult ViewTree
+ Chiasma.Ui.ViewTree: ensurePaneOpenTraversal :: Traversal a (ToggleResult a) ViewTree (ToggleResult ViewTree) -> Ident -> a -> ToggleResult a
+ Chiasma.Ui.ViewTree: ensurePaneOpenTraversal' :: Traversal' a ViewTree -> Ident -> a -> ToggleResult a
+ Chiasma.Ui.ViewTree: ensurePaneViewOpen :: Ident -> PaneView -> (ToggleStatus, PaneView)
+ Chiasma.Ui.ViewTree: hasOpenPanes :: ViewTree -> Bool
+ Chiasma.Ui.ViewTree: instance GHC.Base.Applicative Chiasma.Ui.ViewTree.ToggleResult
+ Chiasma.Ui.ViewTree: instance GHC.Base.Functor Chiasma.Ui.ViewTree.ToggleResult
+ Chiasma.Ui.ViewTree: instance GHC.Base.Monad Chiasma.Ui.ViewTree.ToggleResult
+ Chiasma.Ui.ViewTree: instance GHC.Base.Monoid (Chiasma.Ui.ViewTree.ToggleResult a)
+ Chiasma.Ui.ViewTree: instance GHC.Base.Monoid Chiasma.Ui.ViewTree.ToggleStatus
+ Chiasma.Ui.ViewTree: instance GHC.Base.Semigroup (Chiasma.Ui.ViewTree.ToggleResult a)
+ Chiasma.Ui.ViewTree: instance GHC.Base.Semigroup Chiasma.Ui.ViewTree.ToggleStatus
+ Chiasma.Ui.ViewTree: instance GHC.Classes.Eq Chiasma.Ui.ViewTree.ToggleStatus
+ Chiasma.Ui.ViewTree: instance GHC.Classes.Eq a => GHC.Classes.Eq (Chiasma.Ui.ViewTree.ToggleResult a)
+ Chiasma.Ui.ViewTree: instance GHC.Show.Show Chiasma.Ui.ViewTree.ToggleStatus
+ Chiasma.Ui.ViewTree: instance GHC.Show.Show a => GHC.Show.Show (Chiasma.Ui.ViewTree.ToggleResult a)
+ Chiasma.Ui.ViewTree: isOpenPaneNode :: ViewTreeSub -> Bool
+ Chiasma.Ui.ViewTree: modCounted :: Monad m => (a -> m a) -> a -> WriterT (Sum Int) m a
+ Chiasma.Ui.ViewTree: modifyPane :: (PaneView -> PaneView) -> Ident -> ViewTree -> Either TreeModError ViewTree
+ Chiasma.Ui.ViewTree: modifyPaneUniqueM :: Monad m => (PaneView -> m PaneView) -> Ident -> ViewTree -> ExceptT TreeModError m ViewTree
+ Chiasma.Ui.ViewTree: modifyTreeUniqueM :: Monad m => (ViewTree -> m ViewTree) -> Ident -> ViewTree -> ExceptT TreeModError m ViewTree
+ Chiasma.Ui.ViewTree: openFirstPaneNode :: ViewTreeSub -> (ToggleStatus, ViewTreeSub)
+ Chiasma.Ui.ViewTree: openFirstPinnedPaneNode :: ViewTreeSub -> (ToggleStatus, ViewTreeSub)
+ Chiasma.Ui.ViewTree: openPane :: Ident -> ViewTree -> Either TreeModError ViewTree
+ Chiasma.Ui.ViewTree: openPaneView :: PaneView -> (ToggleStatus, PaneView)
+ Chiasma.Ui.ViewTree: openPinnedPaneView :: PaneView -> (ToggleStatus, PaneView)
+ Chiasma.Ui.ViewTree: openPinnedSubs :: ToggleStatus -> ViewTree -> (ToggleStatus, ViewTree)
+ Chiasma.Ui.ViewTree: skipFold :: Traversable t => (a -> (ToggleStatus, a)) -> ToggleStatus -> t a -> (ToggleStatus, t a)
+ Chiasma.Ui.ViewTree: toggleLayout :: Ident -> ViewTree -> ToggleResult ViewTree
+ Chiasma.Ui.ViewTree: toggleLayout1 :: Ident -> ViewTree -> Either TreeModError ViewTree
+ Chiasma.Ui.ViewTree: toggleLayoutNode :: Ident -> ToggleStatus -> ViewTree -> (ToggleStatus, ViewTree)
+ Chiasma.Ui.ViewTree: toggleLayoutOpenTraversal' :: Traversal' a ViewTree -> Ident -> a -> ToggleResult a
+ Chiasma.Ui.ViewTree: togglePane :: Ident -> ViewTree -> ToggleResult ViewTree
+ Chiasma.Ui.ViewTree: togglePaneNode :: Ident -> ViewTreeSub -> (ToggleStatus, ViewTreeSub)
+ Chiasma.Ui.ViewTree: togglePaneOpenTraversal' :: Traversal' a ViewTree -> Ident -> a -> ToggleResult a
+ Chiasma.Ui.ViewTree: togglePaneView :: Ident -> PaneView -> (ToggleStatus, PaneView)
+ Chiasma.Ui.ViewTree: treeToggleOpen :: ViewTree -> ViewTree
+ Chiasma.View: addView :: MonadDeepState s Views m => Setter a -> Ident -> m (View a)
+ Chiasma.View: findOrCreateView :: MonadDeepState s Views m => Getter a -> Setter a -> Ident -> m (View a)
+ Chiasma.View: insertPane :: View PaneId -> Views -> Views
+ Chiasma.View: insertSession :: View SessionId -> Views -> Views
+ Chiasma.View: insertView :: Lens' Views [View a] -> View a -> Views -> Views
+ Chiasma.View: insertWindow :: View WindowId -> Views -> Views
+ Chiasma.View: pane :: Ident -> Views -> Either ViewsError (View PaneId)
+ Chiasma.View: paneById :: PaneId -> Views -> Maybe (View PaneId)
+ Chiasma.View: paneId :: Ident -> Views -> Either ViewsError PaneId
+ Chiasma.View: sameId :: Eq a => a -> View a -> Bool
+ Chiasma.View: session :: Ident -> Views -> Either ViewsError (View SessionId)
+ Chiasma.View: sessionById :: SessionId -> Views -> Maybe (View SessionId)
+ Chiasma.View: type Getter a = Ident -> Views -> Either ViewsError (View a)
+ Chiasma.View: type Setter a = View a -> Views -> Views
+ Chiasma.View: updatePane :: View PaneId -> Views -> Views
+ Chiasma.View: updateSession :: View SessionId -> Views -> Views
+ Chiasma.View: updateView :: Lens' Views [View a] -> (Ident -> ViewsError) -> View a -> Views -> Views
+ Chiasma.View: updateWindow :: View WindowId -> Views -> Views
+ Chiasma.View: view :: Lens' Views [View a] -> (Ident -> ViewsError) -> Ident -> Views -> Either ViewsError (View a)
+ Chiasma.View: viewById :: Eq a => Lens' Views [View a] -> a -> Views -> Maybe (View a)
+ Chiasma.View: viewsLog :: MonadDeepState s Views m => Doc AnsiStyle -> m ()
+ Chiasma.View: viewsLogS :: MonadDeepState s Views m => Text -> m ()
+ Chiasma.View: window :: Ident -> Views -> Either ViewsError (View WindowId)
+ Chiasma.View: windowById :: WindowId -> Views -> Maybe (View WindowId)
+ Chiasma.View.State: paneId :: (MonadDeepState s Views m, MonadDeepError e ViewsError m) => Ident -> m PaneId
+ Chiasma.Window: ensurePane :: (MonadDeepState s Views m, MonadFree TmuxThunk m) => FilePath -> WindowId -> PaneView -> m (Maybe RenderableNode)
+ Chiasma.Window: ensurePaneClosed :: (MonadDeepState s Views m, MonadFree TmuxThunk m) => Maybe PaneDetail -> m ()
+ Chiasma.Window: ensurePaneOpen :: (MonadDeepState s Views m, MonadFree TmuxThunk m) => FilePath -> Maybe PaneDetail -> WindowId -> m PaneDetail
+ Chiasma.Window: ensureView :: (MonadDeepState s Views m, MonadFree TmuxThunk m) => FilePath -> WindowId -> ViewTree -> m (Maybe RenderableTree)
+ Chiasma.Window: ensureWindow :: (MonadDeepState s Views m, MonadFree TmuxThunk m, MonadError RenderError m) => SessionId -> View WindowId -> Maybe WindowId -> ViewTree -> m Window
+ Chiasma.Window: findOrCreatePane :: MonadDeepState s Views m => Ident -> m (View PaneId)
+ Chiasma.Window: findOrCreateWindow :: MonadDeepState s Views m => Ident -> m (View WindowId)
+ Chiasma.Window: findPrincipal :: ViewTree -> Maybe PaneView
+ Chiasma.Window: findPrincipalSub :: ViewTreeSub -> Maybe PaneView
+ Chiasma.Window: nativePane :: MonadFree TmuxThunk m => WindowId -> View PaneId -> m (Maybe PaneDetail)
+ Chiasma.Window: openPane :: (MonadDeepState s Views m, MonadFree TmuxThunk m) => FilePath -> WindowId -> m PaneDetail
+ Chiasma.Window: principalPane :: (MonadDeepState s Views m, MonadError RenderError m) => ViewTree -> m (PaneView, View PaneId)
+ Chiasma.Window: refPane :: RenderableNode -> RPane
+ Chiasma.Window: registerWindowId :: MonadDeepState s Views m => Ident -> WindowId -> m ()
+ Chiasma.Window: renderableTree :: ViewState -> ViewGeometry -> Bool -> [RenderableNode] -> Maybe RenderableTree
+ Chiasma.Window: spawnWindow :: (MonadDeepState s Views m, MonadFree TmuxThunk m) => SessionId -> Ident -> m Window
+ Chiasma.Window: syncPrincipal :: (MonadDeepState s Views m, MonadFree TmuxThunk m, MonadError RenderError m) => WindowId -> ViewTree -> m ()
+ Chiasma.Window: viewPosition :: ViewTreeSub -> Float
+ Chiasma.Window: windowState :: (MonadDeepState s Views m, MonadFree TmuxThunk m) => Ident -> Window -> RenderableTree -> m WindowState
- Chiasma.Api.Class: class TmuxApi a
+ Chiasma.Api.Class: class TmuxApi m a
- Chiasma.Api.Class: runCommands :: (TmuxApi a, MonadIO m) => a -> ([String] -> Either TmuxDecodeError b) -> Cmds -> ExceptT TmuxError m [b]
+ Chiasma.Api.Class: runCommands :: TmuxApi m a => a -> (Text -> Either TmuxDecodeError b) -> Cmds -> m [b]
- Chiasma.Codec: TmuxQuery :: String -> TmuxQuery
+ Chiasma.Codec: TmuxQuery :: Text -> TmuxQuery
- Chiasma.Codec: decode :: (TmuxCodec a, Generic a, TmuxDataDecode (Rep a)) => [String] -> Either TmuxDecodeError a
+ Chiasma.Codec: decode :: (TmuxCodec a, Generic a, TmuxDataDecode (Rep a)) => Text -> Either TmuxDecodeError a
- Chiasma.Codec: query :: (TmuxCodec a, Generic a, TmuxDataQuery (Rep a)) => TmuxQuery
+ Chiasma.Codec: query :: (TmuxCodec a, TmuxDataQuery (Rep a)) => TmuxQuery
- Chiasma.Codec.Decode: IntParsingFailure :: String -> TmuxDecodeError
+ Chiasma.Codec.Decode: IntParsingFailure :: Text -> TmuxDecodeError
- Chiasma.Codec.Decode: ParseFailure :: String -> ParseError -> TmuxDecodeError
+ Chiasma.Codec.Decode: ParseFailure :: Text -> ParseError -> TmuxDecodeError
- Chiasma.Codec.Decode: TooManyFields :: [String] -> TmuxDecodeError
+ Chiasma.Codec.Decode: TooManyFields :: [Text] -> TmuxDecodeError
- Chiasma.Codec.Decode: decode' :: TmuxDataDecode f => [String] -> Either TmuxDecodeError ([String], f a)
+ Chiasma.Codec.Decode: decode' :: TmuxDataDecode f => [Text] -> Either TmuxDecodeError ([Text], f a)
- Chiasma.Codec.Decode: idParser :: Char -> GenParser Char st String
+ Chiasma.Codec.Decode: idParser :: Char -> GenParser Char st Text
- Chiasma.Codec.Decode: parseId :: (Int -> a) -> Char -> String -> Either TmuxDecodeError a
+ Chiasma.Codec.Decode: parseId :: (Int -> a) -> Char -> Text -> Either TmuxDecodeError a
- Chiasma.Codec.Decode: primDecode :: TmuxPrimDecode a => String -> Either TmuxDecodeError a
+ Chiasma.Codec.Decode: primDecode :: TmuxPrimDecode a => Text -> Either TmuxDecodeError a
- Chiasma.Codec.Decode: readInt :: String -> String -> Either TmuxDecodeError Int
+ Chiasma.Codec.Decode: readInt :: Text -> Text -> Either TmuxDecodeError Int
- Chiasma.Codec.Query: query' :: TmuxDataQuery f => [String]
+ Chiasma.Codec.Query: query' :: TmuxDataQuery f => [Text]
- Chiasma.Data.TmuxThunk: Read :: Cmd -> ([String] -> Either TmuxDecodeError a) -> ([a] -> next) -> TmuxThunk next
+ Chiasma.Data.TmuxThunk: Read :: Cmd -> (Text -> Either TmuxDecodeError a) -> ([a] -> next) -> TmuxThunk next
- Chiasma.Monad.Tmux: read :: forall a. TmuxCodec a => String -> [String] -> TmuxProg [a]
+ Chiasma.Monad.Tmux: read :: forall a m. (TmuxCodec a, MonadFree TmuxThunk m) => Text -> [Text] -> m [a]
- Chiasma.Monad.Tmux: write :: String -> [String] -> TmuxProg ()
+ Chiasma.Monad.Tmux: write :: MonadFree TmuxThunk m => Text -> [Text] -> m ()
- Chiasma.Native.Api: TmuxNative :: FilePath -> TmuxNative
+ Chiasma.Native.Api: TmuxNative :: Maybe FilePath -> TmuxNative
- Chiasma.Native.Parse: resultLines :: String -> Either ParseError [[String]]
+ Chiasma.Native.Parse: resultLines :: Text -> Either ParseError [[Text]]
- Chiasma.Native.Parse: resultParser :: GenParser Char st [[String]]
+ Chiasma.Native.Parse: resultParser :: GenParser st [[Text]]
- Chiasma.Native.Process: nativeTmuxProcess :: MonadIO m => FilePath -> ([String] -> Either TmuxDecodeError a) -> Cmds -> m (Either TmuxError [a])
+ Chiasma.Native.Process: nativeTmuxProcess :: (MonadIO m, MonadDeepError e TmuxError m) => Maybe FilePath -> (Text -> Either TmuxDecodeError a) -> Cmds -> m [a]
- Chiasma.Native.Process: tmuxProcessConfig :: FilePath -> [String] -> ProcessConfig () () ()
+ Chiasma.Native.Process: tmuxProcessConfig :: Maybe FilePath -> [Text] -> ProcessConfig () () ()
- Chiasma.Test.File: fixture :: MonadIO m => String -> FilePath -> m FilePath
+ Chiasma.Test.File: fixture :: MonadIO m => Text -> FilePath -> m FilePath
- Chiasma.Test.File: tempDir :: MonadIO m => String -> FilePath -> m FilePath
+ Chiasma.Test.File: tempDir :: MonadIO m => Text -> FilePath -> m FilePath
- Chiasma.Test.File: tempDirIO :: String -> FilePath -> IO FilePath
+ Chiasma.Test.File: tempDirIO :: Text -> FilePath -> IO FilePath
- Chiasma.Test.Tmux: withTestTmux :: (TmuxNative -> IO a) -> FilePath -> IO a
+ Chiasma.Test.Tmux: withTestTmux :: TmuxTestConf -> (TmuxNative -> IO a) -> FilePath -> IO a

Files

LICENSE view
@@ -1,30 +1,34 @@-Copyright Torsten Schmits (c) 2018+Copyright (c) 2020 Torsten Schmits -All rights reserved.+Redistribution and use in source and binary forms, with or without modification, are permitted provided that the+following conditions are met: -Redistribution and use in source and binary forms, with or without-modification, are permitted provided that the following conditions are met:+  1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following+  disclaimer.+  2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following+  disclaimer in the documentation and/or other materials provided with the distribution. -    * Redistributions of source code must retain the above copyright-      notice, this list of conditions and the following disclaimer.+Subject to the terms and conditions of this license, each copyright holder and contributor hereby grants to those+receiving rights under this license a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable (except+for failure to satisfy the conditions of this license) patent license to make, have made, use, offer to sell, sell,+import, and otherwise transfer this software, where such license applies only to those patent claims, already acquired+or hereafter acquired, licensable by such copyright holder or contributor that are necessarily infringed by: -    * Redistributions in binary form must reproduce the above-      copyright notice, this list of conditions and the following-      disclaimer in the documentation and/or other materials provided-      with the distribution.+  (a) their Contribution(s) (the licensed copyrights of copyright holders and non-copyrightable additions of+  contributors, in source or binary form) alone; or+  (b) combination of their Contribution(s) with the work of authorship to which such Contribution(s) was added by such+  copyright holder or contributor, if, at the time the Contribution is added, such addition causes such combination to+  be necessarily infringed. The patent license shall not apply to any other combinations which include the Contribution. -    * Neither the name of Torsten Schmits nor the names of other-      contributors may be used to endorse or promote products derived-      from this software without specific prior written permission.+Except as expressly stated above, no rights or licenses from any copyright holder or contributor is granted under this+license, whether expressly, by implication, estoppel or otherwise. -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS-"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT-LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR-A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT-OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,-SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT-LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,-DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY-THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT-(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE-OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.+DISCLAIMER++THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,+INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE+DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,+SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR+SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,+WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
− README.md
@@ -1,3 +0,0 @@-# Intro--**chiasma** is a tmux api client for Haskell.
− Setup.hs
@@ -1,2 +0,0 @@-import Distribution.Simple-main = defaultMain
chiasma.cabal view
@@ -1,26 +1,24 @@-cabal-version: 1.12+cabal-version: 2.2 --- This file has been generated from package.yaml by hpack version 0.31.1.+-- This file has been generated from package.yaml by hpack version 0.34.4. -- -- see: https://github.com/sol/hpack------ hash: 3809c3d5d4204b2ce3be054873e25b993f46159354efa61c45f34aa594ce9f29  name:           chiasma-version:        0.1.0.0+version:        0.2.0.0 synopsis:       tmux api-description:    Please see the README on GitHub at <https://github.com/tek/chiasma-hs>+description:    Please see the README on GitHub at <https://github.com/tek/chiasma> category:       Terminal homepage:       https://github.com/tek/chiasma-hs#readme bug-reports:    https://github.com/tek/chiasma-hs/issues author:         Torsten Schmits maintainer:     tek@tryp.io-copyright:      2019 Torsten Schmits-license:        MIT+copyright:      2021 Torsten Schmits+license:        BSD-2-Clause-Patent license-file:   LICENSE build-type:     Simple extra-source-files:-    README.md+    readme.md  source-repository head   type: git@@ -30,77 +28,409 @@   exposed-modules:       Chiasma.Api.Class       Chiasma.Codec+      Chiasma.Codec.Data+      Chiasma.Codec.Data.Pane+      Chiasma.Codec.Data.PaneCoords+      Chiasma.Codec.Data.PaneDetail+      Chiasma.Codec.Data.PaneMode+      Chiasma.Codec.Data.PanePid+      Chiasma.Codec.Data.Session+      Chiasma.Codec.Data.Window       Chiasma.Codec.Decode       Chiasma.Codec.Query-      Chiasma.Data.Pane+      Chiasma.Command.Pane+      Chiasma.Command.Session+      Chiasma.Command.Window+      Chiasma.Control.IO.Unsafe+      Chiasma.Data.Cmd+      Chiasma.Data.Conduit+      Chiasma.Data.Ident+      Chiasma.Data.List+      Chiasma.Data.Maybe+      Chiasma.Data.RenderError+      Chiasma.Data.TmuxError+      Chiasma.Data.TmuxId       Chiasma.Data.TmuxThunk-      Chiasma.Data.Window-      Chiasma.Monad.Buffered-      Chiasma.Monad.Simple+      Chiasma.Data.View+      Chiasma.Data.Views+      Chiasma.Data.WindowState+      Chiasma.Lens.Tree+      Chiasma.Lens.Where+      Chiasma.Monad.EvalFreeT+      Chiasma.Monad.IndividualProcess+      Chiasma.Monad.Stream       Chiasma.Monad.Tmux       Chiasma.Native.Api       Chiasma.Native.Parse       Chiasma.Native.Process+      Chiasma.Native.StreamParse+      Chiasma.Pack+      Chiasma.Pane+      Chiasma.Prelude+      Chiasma.Render+      Chiasma.Session       Chiasma.Test.File+      Chiasma.Test.Screenshot       Chiasma.Test.Tmux+      Chiasma.Ui.Data.Measure+      Chiasma.Ui.Data.RenderableTree+      Chiasma.Ui.Data.Tree+      Chiasma.Ui.Data.TreeModError+      Chiasma.Ui.Data.View+      Chiasma.Ui.Data.ViewGeometry+      Chiasma.Ui.Data.ViewState+      Chiasma.Ui.Lens.Ident+      Chiasma.Ui.Measure+      Chiasma.Ui.Measure.Balance+      Chiasma.Ui.Measure.Weights+      Chiasma.Ui.Pane+      Chiasma.Ui.ShowTree+      Chiasma.Ui.ViewTree+      Chiasma.View+      Chiasma.View.State+      Chiasma.Window   other-modules:+      Prelude       Paths_chiasma+  autogen-modules:+      Paths_chiasma   hs-source-dirs:       lib-  default-extensions: ExistentialQuantification UnicodeSyntax TypeApplications ScopedTypeVariables DeriveGeneric DeriveAnyClass+  default-extensions:+      AllowAmbiguousTypes+      ApplicativeDo+      BangPatterns+      BinaryLiterals+      BlockArguments+      ConstraintKinds+      DataKinds+      DefaultSignatures+      DeriveAnyClass+      DeriveDataTypeable+      DeriveFoldable+      DeriveFunctor+      DeriveGeneric+      DeriveTraversable+      DerivingStrategies+      DisambiguateRecordFields+      DoAndIfThenElse+      DuplicateRecordFields+      EmptyDataDecls+      ExistentialQuantification+      FlexibleContexts+      FlexibleInstances+      FunctionalDependencies+      GADTs+      GeneralizedNewtypeDeriving+      InstanceSigs+      KindSignatures+      LambdaCase+      LiberalTypeSynonyms+      MultiParamTypeClasses+      MultiWayIf+      NamedFieldPuns+      OverloadedStrings+      OverloadedLists+      PackageImports+      PartialTypeSignatures+      PatternGuards+      PatternSynonyms+      PolyKinds+      QuantifiedConstraints+      QuasiQuotes+      RankNTypes+      RecordWildCards+      RecursiveDo+      ScopedTypeVariables+      StandaloneDeriving+      TemplateHaskell+      TupleSections+      TypeApplications+      TypeFamilies+      TypeFamilyDependencies+      TypeOperators+      TypeSynonymInstances+      UndecidableInstances+      UnicodeSyntax+      ViewPatterns   build-depends:-      base >=4.7 && <5+      aeson >=1.4 && <1.6+    , attoparsec ==0.13.*+    , base ==4.*     , bytestring-    , data-default-class+    , composition ==1.0.*+    , composition-extra ==2.0.*+    , conduit ==1.3.*+    , conduit-extra ==1.3.*+    , containers+    , cornea ==0.4.*+    , data-default ==0.7.*+    , deepseq     , directory-    , either+    , either >=5.0.1 && <5.1+    , exceptions     , filepath-    , free-    , lens+    , free ==5.1.*+    , lens ==4.*     , mtl     , parsec-    , posix-pty-    , process-    , resourcet-    , split+    , parsers ==0.12.*+    , posix-pty ==0.2.*+    , prettyprinter >=1.6 && <1.8+    , prettyprinter-ansi-terminal ==1.1.*+    , process ==1.6.*+    , random ==1.1.*+    , relude >=0.7 && <1.2+    , resourcet ==1.2.*+    , split ==0.2.*+    , stm-chans ==3.0.*+    , stm-conduit ==4.0.*+    , text     , transformers-    , typed-process+    , typed-process ==0.2.*     , unix-    , unliftio+    , unliftio ==0.2.*+    , unliftio-core >=0.1 && <0.3+    , uuid ==1.3.*+  mixins:+      base hiding (Prelude)   default-language: Haskell2010 +test-suite chiasma-integration+  type: exitcode-stdio-1.0+  main-is: Main.hs+  other-modules:+      Chiasma.Test.IndividualProcessTest+      Chiasma.Test.ProcessTest+      Chiasma.Test.RenderTest+      Chiasma.Test.TmuxStreamTest+      Chiasma.Test.Util+      Paths_chiasma+  hs-source-dirs:+      integration+  default-extensions:+      AllowAmbiguousTypes+      ApplicativeDo+      BangPatterns+      BinaryLiterals+      BlockArguments+      ConstraintKinds+      DataKinds+      DefaultSignatures+      DeriveAnyClass+      DeriveDataTypeable+      DeriveFoldable+      DeriveFunctor+      DeriveGeneric+      DeriveTraversable+      DerivingStrategies+      DisambiguateRecordFields+      DoAndIfThenElse+      DuplicateRecordFields+      EmptyDataDecls+      ExistentialQuantification+      FlexibleContexts+      FlexibleInstances+      FunctionalDependencies+      GADTs+      GeneralizedNewtypeDeriving+      InstanceSigs+      KindSignatures+      LambdaCase+      LiberalTypeSynonyms+      MultiParamTypeClasses+      MultiWayIf+      NamedFieldPuns+      OverloadedStrings+      OverloadedLists+      PackageImports+      PartialTypeSignatures+      PatternGuards+      PatternSynonyms+      PolyKinds+      QuantifiedConstraints+      QuasiQuotes+      RankNTypes+      RecordWildCards+      RecursiveDo+      ScopedTypeVariables+      StandaloneDeriving+      TemplateHaskell+      TupleSections+      TypeApplications+      TypeFamilies+      TypeFamilyDependencies+      TypeOperators+      TypeSynonymInstances+      UndecidableInstances+      UnicodeSyntax+      ViewPatterns+  ghc-options: -threaded -rtsopts -with-rtsopts=-N+  build-depends:+      aeson >=1.4 && <1.6+    , attoparsec ==0.13.*+    , base ==4.*+    , bytestring+    , chiasma+    , composition ==1.0.*+    , composition-extra ==2.0.*+    , conduit ==1.3.*+    , conduit-extra ==1.3.*+    , containers+    , cornea ==0.4.*+    , data-default ==0.7.*+    , deepseq+    , directory+    , either >=5.0.1 && <5.1+    , exceptions+    , filepath+    , free ==5.1.*+    , hedgehog+    , lens ==4.*+    , mtl+    , parsec+    , parsers ==0.12.*+    , posix-pty ==0.2.*+    , prettyprinter >=1.6 && <1.8+    , prettyprinter-ansi-terminal ==1.1.*+    , process ==1.6.*+    , random ==1.1.*+    , relude >=0.7 && <1.2+    , resourcet ==1.2.*+    , split ==0.2.*+    , stm-chans ==3.0.*+    , stm-conduit ==4.0.*+    , tasty+    , tasty-hedgehog+    , text+    , transformers+    , typed-process ==0.2.*+    , unix+    , unliftio ==0.2.*+    , unliftio-core >=0.1 && <0.3+    , uuid ==1.3.*+  mixins:+      base hiding (Prelude)+    , chiasma (Chiasma.Prelude as Prelude)+    , chiasma hiding (Chiasma.Prelude)+  default-language: Haskell2010+ test-suite chiasma-unit   type: exitcode-stdio-1.0-  main-is: SpecMain.hs+  main-is: Main.hs   other-modules:-      BufferedSpec-      CodecSpec-      OutputParseSpec-      SimpleSpec+      Chiasma.Test.CodecTest+      Chiasma.Test.LensTest+      Chiasma.Test.OutputParseTest+      Chiasma.Test.PinTest+      Chiasma.Test.StreamParseTest+      Chiasma.Test.Util       Paths_chiasma   hs-source-dirs:-      test/u-  default-extensions: ExistentialQuantification UnicodeSyntax TypeApplications ScopedTypeVariables DeriveGeneric DeriveAnyClass+      test+  default-extensions:+      AllowAmbiguousTypes+      ApplicativeDo+      BangPatterns+      BinaryLiterals+      BlockArguments+      ConstraintKinds+      DataKinds+      DefaultSignatures+      DeriveAnyClass+      DeriveDataTypeable+      DeriveFoldable+      DeriveFunctor+      DeriveGeneric+      DeriveTraversable+      DerivingStrategies+      DisambiguateRecordFields+      DoAndIfThenElse+      DuplicateRecordFields+      EmptyDataDecls+      ExistentialQuantification+      FlexibleContexts+      FlexibleInstances+      FunctionalDependencies+      GADTs+      GeneralizedNewtypeDeriving+      InstanceSigs+      KindSignatures+      LambdaCase+      LiberalTypeSynonyms+      MultiParamTypeClasses+      MultiWayIf+      NamedFieldPuns+      OverloadedStrings+      OverloadedLists+      PackageImports+      PartialTypeSignatures+      PatternGuards+      PatternSynonyms+      PolyKinds+      QuantifiedConstraints+      QuasiQuotes+      RankNTypes+      RecordWildCards+      RecursiveDo+      ScopedTypeVariables+      StandaloneDeriving+      TemplateHaskell+      TupleSections+      TypeApplications+      TypeFamilies+      TypeFamilyDependencies+      TypeOperators+      TypeSynonymInstances+      UndecidableInstances+      UnicodeSyntax+      ViewPatterns   ghc-options: -threaded -rtsopts -with-rtsopts=-N   build-depends:-      HTF-    , base >=4.7 && <5+      aeson >=1.4 && <1.6+    , attoparsec ==0.13.*+    , base ==4.*     , bytestring     , chiasma-    , data-default-class+    , composition ==1.0.*+    , composition-extra ==2.0.*+    , conduit ==1.3.*+    , conduit-extra ==1.3.*+    , containers+    , cornea ==0.4.*+    , data-default ==0.7.*+    , deepseq     , directory-    , either+    , either >=5.0.1 && <5.1+    , exceptions     , filepath-    , free-    , lens+    , free ==5.1.*+    , hedgehog+    , lens ==4.*     , mtl     , parsec-    , posix-pty-    , process-    , resourcet-    , split+    , parsers ==0.12.*+    , posix-pty ==0.2.*+    , prettyprinter >=1.6 && <1.8+    , prettyprinter-ansi-terminal ==1.1.*+    , process ==1.6.*+    , random ==1.1.*+    , relude >=0.7 && <1.2+    , resourcet ==1.2.*+    , split ==0.2.*+    , stm-chans ==3.0.*+    , stm-conduit ==4.0.*+    , tasty+    , tasty-hedgehog+    , text     , transformers-    , typed-process+    , typed-process ==0.2.*     , unix-    , unliftio+    , unliftio ==0.2.*+    , unliftio-core >=0.1 && <0.3+    , uuid ==1.3.*+  mixins:+      base hiding (Prelude)+    , chiasma (Chiasma.Prelude as Prelude)+    , chiasma hiding (Chiasma.Prelude)   default-language: Haskell2010
+ integration/Chiasma/Test/IndividualProcessTest.hs view
@@ -0,0 +1,42 @@+module Chiasma.Test.IndividualProcessTest where++import Chiasma.Codec.Data (Pane(Pane), Window(Window))+import Chiasma.Data.TmuxError (TmuxError)+import Chiasma.Data.TmuxId (PaneId(..), WindowId(..))+import Chiasma.Monad.IndividualProcess (TmuxProg, runTmux)+import qualified Chiasma.Monad.Tmux as Tmux (read, write)+import Chiasma.Native.Api (TmuxNative(..))+import Hedgehog ((===))++import Chiasma.Test.Tmux (tmuxSpec)+import Chiasma.Test.Util (UnitTest)++prog :: TmuxProg ([Pane], [Pane], [Window])+prog = do+  panes1 <- Tmux.read "list-panes" ["-t", "%0"]+  Tmux.write "new-window" []+  Tmux.write "new-window" []+  wins <- Tmux.read "list-windows" []+  panes <- Tmux.read "list-panes" ["-a"]+  return (panes1, panes, wins)++p :: Int -> Pane+p i = Pane (PaneId i) 240 60++w :: Int -> Window+w i = Window (WindowId i) 240 60++runProg :: TmuxNative -> IO (Either TmuxError ([Pane], [Pane], [Window]))+runProg api = runExceptT $ runTmux api prog++test_individual :: UnitTest+test_individual = do+  result :: Either TmuxError ([Pane], [Pane], [Window]) <- liftIO (tmuxSpec runProg)+  Right ([p0], [p0, p1, p2], [w0, w1, w2]) === result+  where+    p0 = p 0+    p1 = p 1+    p2 = p 2+    w0 = w 0+    w1 = w 1+    w2 = w 2
+ integration/Chiasma/Test/ProcessTest.hs view
@@ -0,0 +1,42 @@+module Chiasma.Test.ProcessTest where++import Chiasma.Data.Conduit (createSinkFlush)+import Chiasma.Native.Api (TmuxNative(..))+import Chiasma.Native.Process (socketArg)+import Conduit (ConduitT, Flush(..), mapC, runConduit, sinkList, yieldMany, (.|))+import Data.ByteString.Internal (packChars)+import qualified Data.Conduit.Combinators as Conduit (concatMap, take)+import Data.Conduit.Process.Typed (+  Process,+  createSource,+  getStdin,+  getStdout,+  proc,+  setStdin,+  setStdout,+  withProcessTerm,+  )+import qualified Data.Text as Text (splitOn)+import Hedgehog (assert)++import Chiasma.Test.Tmux (tmuxSpec)+import Chiasma.Test.Util (UnitTest)++run :: Process (ConduitT (Flush ByteString) Void IO ()) (ConduitT () ByteString IO ()) () -> IO [Text]+run prc = do+  let stdin' = mapC (fmap packChars) .| getStdin prc+  let stdout' = getStdout prc+  runConduit $ yieldMany ([Chunk "list-panes\n"] :: [Flush String]) .| stdin'+  runConduit $ yieldMany ([Flush] :: [Flush String]) .| stdin'+  runConduit $ stdout' .| Conduit.take 2 .| mapC decodeUtf8 .| Conduit.concatMap (Text.splitOn "\n") .| sinkList++test_process :: UnitTest+test_process = do+  out <- liftIO $ tmuxSpec $ \(TmuxNative sock) -> do+    withProcessTerm (pc (args sock)) run+  assert (length out > 3)+    where+      pc =+        setStdin createSinkFlush . setStdout createSource . proc "tmux"+      args sock =+        toString <$> socketArg sock ++ ["-C", "attach"]
+ integration/Chiasma/Test/RenderTest.hs view
@@ -0,0 +1,216 @@+module Chiasma.Test.RenderTest where++import Chiasma.Codec.Data.PaneDetail (PaneDetail(..))+import Chiasma.Command.Pane (panesAs)+import Chiasma.Command.Session (activateSession)+import Chiasma.Data.Ident (Ident(Str))+import Chiasma.Data.TmuxError (TmuxError)+import Chiasma.Data.TmuxId (PaneId(PaneId), SessionId(SessionId), WindowId(WindowId))+import Chiasma.Data.View (viewIdent)+import qualified Chiasma.Data.View as Tmux (View(View))+import Chiasma.Data.Views (Views(Views))+import Chiasma.Monad.Stream (runTmux)+import Chiasma.Native.Api (TmuxNative(..))+import Chiasma.Render (render)+import Chiasma.Ui.Data.View (Tree(..), TreeSub(..), ViewTree, consLayout, consLayoutVertical)+import qualified Chiasma.Ui.Data.View as Ui (Pane(Pane), View(View))+import Chiasma.Ui.Data.ViewGeometry (ViewGeometry(..))+import Chiasma.Ui.Data.ViewState (ViewState(ViewState))+import Chiasma.Ui.ViewTree (togglePane)+import qualified Chiasma.Ui.ViewTree as ToggleResult (ToggleResult(Success))+import Hedgehog (evalEither, (===))+import Test.Tasty (TestTree, testGroup)+import UnliftIO (throwString)+import UnliftIO.Directory (getCurrentDirectory)++import Chiasma.Test.Tmux (sleep, tmuxSpec)+import Chiasma.Test.Util (UnitTest, integrationTest)++id0, id1, id2, id3 :: Ident+id0 = Str "0"+id1 = Str "1"+id2 = Str "2"+id3 = Str "3"++views :: Views+views =+  Views+    [Tmux.View id0 (Just (SessionId 0))]+    [Tmux.View id0 (Just (WindowId 0))]+    [Tmux.View id0 (Just (PaneId 0))]+    []++renderOnce :: ViewTree -> TmuxNative -> FilePath -> Views -> IO Views+renderOnce tree api cwd vs = do+  r <- runExceptT $ runStateT (runTmux api $ render cwd id1 id1 tree) vs+  either (throwString . show) (return . snd) r++safeRender :: Views -> ViewTree -> TmuxNative -> IO Views+safeRender vs tree api = do+  cwd <- getCurrentDirectory+  vs1 <- renderOnce tree api cwd vs+  _ <- runExceptT @TmuxError $ runTmux api $ activateSession 0+  _ <- runExceptT @TmuxError $ runTmux api $ activateSession 1+  sleep 1+  renderOnce tree api cwd vs1++runRender :: ViewTree -> TmuxNative -> IO ([Tmux.View PaneId], Either TmuxError [PaneDetail])+runRender tree api = do+  (Views _ _ vs2 _) <- safeRender views tree api+  sleep 1+  ps <- runExceptT @TmuxError $ runTmux api panesAs+  return (sortOn viewIdent vs2, sortOn paneLeft . drop 1 <$> ps)++renderSpec :: ViewTree -> [PaneDetail] -> UnitTest+renderSpec tree target = do+  (_, pse) <- liftIO $ tmuxSpec $ runRender tree+  ps <- evalEither pse+  target === ps++treeImbalanced :: ViewTree+treeImbalanced =+  Tree (consLayout id0) [+    TreeLeaf (openPane id0 def),+    TreeLeaf (openPane id1 (ViewGeometry Nothing Nothing (Just 150) Nothing Nothing Nothing))+    ]+  where+    openPane i geo = Ui.View i (ViewState False) geo (Ui.Pane True False Nothing)++imbalancedTarget :: [PaneDetail]+imbalancedTarget =+  [+    PaneDetail { paneId = PaneId 1, paneWidth = 89, paneHeight = 60, paneTop = 0, paneLeft = 0 },+    PaneDetail { paneId = PaneId 2, paneWidth = 150, paneHeight = 60, paneTop = 0, paneLeft = 90 }+    ]++test_imbalanced :: UnitTest+test_imbalanced =+  renderSpec treeImbalanced imbalancedTarget++treeNested :: ViewTree+treeNested =+  Tree (consLayoutVertical id0) [+    TreeNode $+      Tree (consLayout id1) [+        TreeLeaf (openPane id0 def),+        TreeNode $+          Tree (consLayoutVertical id2) [+            TreeLeaf (openPane id1 def),+            TreeLeaf (openPane id2 def)+            ]+        ]+    ]+  where+    openPane i geo = Ui.View i (ViewState False) geo (Ui.Pane True False Nothing)++nestedTarget :: [PaneDetail]+nestedTarget =+  [+    PaneDetail { paneId = PaneId 1, paneWidth = 120, paneHeight = 60, paneTop = 0, paneLeft = 0 },+    PaneDetail { paneId = PaneId 2, paneWidth = 119, paneHeight = 30, paneTop = 0, paneLeft = 121 },+    PaneDetail { paneId = PaneId 3, paneWidth = 119, paneHeight = 29, paneTop = 31, paneLeft = 121 }+  ]++test_nested :: UnitTest+test_nested =+  renderSpec treeNested nestedTarget++treeTwoLayouts :: ViewTree+treeTwoLayouts =+  Tree (consLayout id0) [+    TreeNode $+      Tree (consLayoutVertical id1) [+        TreeLeaf (openPane id0 def)+        ],+    TreeNode $+      Tree (consLayoutVertical id2) [+        TreeLeaf (openPane id1 def)+        ]+    ]+  where+    openPane i geo = Ui.View i (ViewState False) geo (Ui.Pane True False Nothing)++twoLayoutsTarget :: [PaneDetail]+twoLayoutsTarget =+  [+    PaneDetail { paneId = PaneId 1, paneWidth = 120, paneHeight = 60, paneTop = 0, paneLeft = 0 },+    PaneDetail { paneId = PaneId 2, paneWidth = 119, paneHeight = 60, paneTop = 0, paneLeft = 121 }+    ]++test_twoLayouts :: UnitTest+test_twoLayouts =+  renderSpec treeTwoLayouts twoLayoutsTarget++treePosition :: ViewTree+treePosition =+  Tree (consLayout id0) [+    TreeLeaf (openPane id0 1 (Just 10)),+    TreeLeaf (openPane id1 4 (Just 20)),+    TreeLeaf (openPane id2 2 (Just 30)),+    TreeLeaf (openPane id3 3 Nothing)+    ]+  where+    openPane i pos size =+      Ui.View i (ViewState False) def { position = Just pos, fixedSize = size } (Ui.Pane True False Nothing)++positionTarget :: [PaneDetail]+positionTarget =+  [+    PaneDetail { paneId = PaneId 1, paneWidth = 10, paneHeight = 60, paneTop = 0, paneLeft = 0 },+    PaneDetail { paneId = PaneId 2, paneWidth = 30, paneHeight = 60, paneTop = 0, paneLeft = 11 },+    PaneDetail { paneId = PaneId 3, paneWidth = 177, paneHeight = 60, paneTop = 0, paneLeft = 42 },+    PaneDetail { paneId = PaneId 4, paneWidth = 20, paneHeight = 60, paneTop = 0, paneLeft = 220 }+    ]++test_position :: UnitTest+test_position =+  renderSpec treePosition positionTarget++treeSuccessiveOpen :: ViewTree+treeSuccessiveOpen =+  Tree (consLayout id0) [+    TreeNode $ Tree (consLayoutVertical id1) [+      TreeLeaf (pane id0 True False)+      ],+    TreeNode $ Tree (consLayoutVertical id2) [+      TreeLeaf (pane id1 False True),+      TreeLeaf (pane id2 False False)+      ]+    ]+  where+    pane i open pin =+      Ui.View i (ViewState False) def (Ui.Pane open pin Nothing)++successiveOpenTarget :: [PaneDetail]+successiveOpenTarget =+  [+    PaneDetail { paneId = PaneId 1, paneWidth = 120, paneHeight = 60, paneTop = 0, paneLeft = 0 },+    PaneDetail { paneId = PaneId 2, paneWidth = 119, paneHeight = 30, paneTop = 0, paneLeft = 121 },+    PaneDetail { paneId = PaneId 3, paneWidth = 119, paneHeight = 29, paneTop = 31, paneLeft = 121 }+    ]++test_successiveOpen :: UnitTest+test_successiveOpen = do+  ps <- liftIO $ tmuxSpec \ api -> do+    vs1 <- safeRender views treeSuccessiveOpen api+    sleep 0.2+    vs2 <- safeRender vs1 tree1 api+    sleep 0.2+    _ <- safeRender vs2 tree2 api+    sleep 0.2+    runExceptT @TmuxError $ runTmux api panesAs+  ps1 <- evalEither (sortOn paneId . drop 1 <$> ps)+  successiveOpenTarget === ps1+  where+    (ToggleResult.Success tree2) = togglePane id2 tree1+    (ToggleResult.Success tree1) = togglePane id1 treeSuccessiveOpen++test_render :: TestTree+test_render =+  testGroup "render" [+    integrationTest "imbalanced tree" test_imbalanced,+    integrationTest "nested panes" test_nested,+    integrationTest "two layouts" test_twoLayouts,+    integrationTest "fixed pane position" test_position,+    integrationTest "open multiple panes" test_successiveOpen+  ]
+ integration/Chiasma/Test/TmuxStreamTest.hs view
@@ -0,0 +1,44 @@+module Chiasma.Test.TmuxStreamTest where++import Chiasma.Codec.Data (Pane(Pane), Window(Window))+import Chiasma.Data.TmuxError (TmuxError)+import Chiasma.Data.TmuxId (PaneId(..), WindowId(..))+import Chiasma.Data.TmuxThunk (TmuxThunk)+import Chiasma.Monad.Stream (runTmux)+import qualified Chiasma.Monad.Tmux as Tmux (read, write)+import Chiasma.Native.Api (TmuxNative(..))+import Control.Monad.Free.Class (MonadFree)+import Hedgehog ((===))++import Chiasma.Test.Tmux (tmuxSpec)+import Chiasma.Test.Util (UnitTest)++prog :: MonadFree TmuxThunk m => m ([Pane], [Pane], [Window])+prog = do+  panes1 <- Tmux.read "list-panes" ["-t", "%0"]+  Tmux.write "new-window" []+  Tmux.write "new-window" []+  wins <- Tmux.read "list-windows" []+  panes <- Tmux.read "list-panes" ["-a"]+  return (panes1, panes, wins)++p :: Int -> Pane+p i = Pane (PaneId i) 240 60++w :: Int -> Window+w i = Window (WindowId i) 240 60++runProg :: TmuxNative -> IO (Either TmuxError ([Pane], [Pane], [Window]))+runProg api = runExceptT @TmuxError $ runTmux api prog++test_streamed :: UnitTest+test_streamed = do+  result <- liftIO (tmuxSpec runProg)+  (Right ([p0], [p0, p1, p2], [w0, w1, w2])) === result+  where+    p0 = p 0+    p1 = p 1+    p2 = p 2+    w0 = w 0+    w1 = w 1+    w2 = w 2
+ integration/Chiasma/Test/Util.hs view
@@ -0,0 +1,19 @@+module Chiasma.Test.Util where++import Hedgehog (TestT, withTests, property, test)+import Test.Tasty (TestName, TestTree)+import Test.Tasty.Hedgehog (testProperty)+import qualified System.Environment as Environment++type UnitTest = TestT IO ()++checkEnv :: UnitTest -> UnitTest+checkEnv t =+  maybe unit (const t) =<< liftIO (Environment.lookupEnv "DISPLAY")++integrationTest ::+  TestName ->+  UnitTest ->+  TestTree+integrationTest desc =+  testProperty desc . withTests 1 . property . test . checkEnv
+ integration/Main.hs view
@@ -0,0 +1,21 @@+module Main where++import Chiasma.Test.IndividualProcessTest (test_individual)+import Chiasma.Test.ProcessTest (test_process)+import Chiasma.Test.RenderTest (test_render)+import Chiasma.Test.TmuxStreamTest (test_streamed)+import Chiasma.Test.Util (integrationTest)+import Test.Tasty (TestTree, defaultMain, testGroup)++tests :: TestTree+tests =+  testGroup "all" [+    integrationTest "use individual subprocesses for queries" test_individual,+    integrationTest "tmux control process" test_process,+    test_render,+    integrationTest "streamed tmux commands" test_streamed+  ]++main :: IO ()+main =+  defaultMain tests
lib/Chiasma/Api/Class.hs view
@@ -1,15 +1,19 @@-module Chiasma.Api.Class(-  TmuxApi(..),-  DecodeTmuxResponse(..),-) where+module Chiasma.Api.Class where -import Control.Monad.IO.Class (MonadIO)-import Control.Monad.Trans.Except (ExceptT)+import Conduit (ConduitT, Flush)+ import Chiasma.Codec.Decode (TmuxDecodeError)-import Chiasma.Data.TmuxThunk (Cmds, TmuxError)+import Chiasma.Data.Cmd (Cmd, Cmds)+import Chiasma.Native.StreamParse (TmuxOutputBlock) -class TmuxApi a where-  runCommands :: MonadIO m => a -> ([String] -> Either TmuxDecodeError b) -> Cmds -> ExceptT TmuxError m [b]+class TmuxApi m a where+  runCommands ::+    a ->+    (Text -> Either TmuxDecodeError b) ->+    Cmds ->+    m [b] -class DecodeTmuxResponse a where-  decode :: String -> Either TmuxError a+  withTmux ::+    a ->+    (ConduitT (Flush Cmd) Void m () -> ConduitT () TmuxOutputBlock m () -> m b) ->+    m b
lib/Chiasma/Codec.hs view
@@ -1,32 +1,37 @@-{-# LANGUAGE DefaultSignatures #-}-{-# LANGUAGE FlexibleContexts #-}-{-# LANGUAGE AllowAmbiguousTypes #-}+module Chiasma.Codec where -module Chiasma.Codec(-  TmuxCodec(..),-  TmuxQuery(..),-) where+import Chiasma.Data.TmuxId (PaneId, SessionId, WindowId)+import qualified Data.Text as Text (drop, dropEnd, splitOn, take, takeEnd, unwords)+import GHC.Generics (Rep, to) -import GHC.Generics (Generic, Rep, to) import Chiasma.Codec.Decode (TmuxDataDecode(..), TmuxDecodeError(TooManyFields)) import Chiasma.Codec.Query (TmuxDataQuery(..))  newtype TmuxQuery =-  TmuxQuery { unQ :: String }+  TmuxQuery { unQ :: Text }   deriving (Eq, Show) -genDecode :: (Generic a, TmuxDataDecode (Rep a)) => [String] -> Either TmuxDecodeError a+genDecode :: (Generic a, TmuxDataDecode (Rep a)) => Text -> Either TmuxDecodeError a genDecode fields = do-  (rest, result) <- decode' fields+  (rest, result) <- decode' (Text.splitOn " " . trim $ fields)   case rest of     [] -> return $ to result     a -> Left $ TooManyFields a+  where+    trim text =+      if Text.take 1 text == " " && Text.takeEnd 1 text == " "+      then Text.drop 1 . Text.dropEnd 1 $ text+      else text  class TmuxCodec a where-    decode :: [String] -> Either TmuxDecodeError a-    default decode :: (Generic a, TmuxDataDecode (Rep a)) => [String] -> Either TmuxDecodeError a+    decode :: Text -> Either TmuxDecodeError a+    default decode :: (Generic a, TmuxDataDecode (Rep a)) => Text -> Either TmuxDecodeError a     decode = genDecode      query :: TmuxQuery-    default query :: (Generic a, TmuxDataQuery (Rep a)) => TmuxQuery-    query = TmuxQuery $ unwords $ query' @(Rep a)+    default query :: TmuxDataQuery (Rep a) => TmuxQuery+    query = TmuxQuery $ Text.unwords $ query' @(Rep a)++instance TmuxCodec SessionId+instance TmuxCodec WindowId+instance TmuxCodec PaneId
+ lib/Chiasma/Codec/Data.hs view
@@ -0,0 +1,9 @@+module Chiasma.Codec.Data(+  Session(..),+  Window(..),+  Pane(..),+) where++import Chiasma.Codec.Data.Pane (Pane(..))+import Chiasma.Codec.Data.Session (Session(..))+import Chiasma.Codec.Data.Window (Window(..))
+ lib/Chiasma/Codec/Data/Pane.hs view
@@ -0,0 +1,16 @@+module Chiasma.Codec.Data.Pane where++import Chiasma.Codec (TmuxCodec)+import Chiasma.Data.TmuxId (HasPaneId, PaneId)+import qualified Chiasma.Data.TmuxId as HasPaneId (HasPaneId(..))++data Pane =+  Pane {+    paneId :: PaneId,+    paneWidth :: Int,+    paneHeight :: Int+  }+  deriving (Eq, Show, Generic, TmuxCodec)++instance HasPaneId Pane where+  paneId = paneId
+ lib/Chiasma/Codec/Data/PaneCoords.hs view
@@ -0,0 +1,17 @@+module Chiasma.Codec.Data.PaneCoords where++import Chiasma.Data.TmuxId (HasPaneId, PaneId, SessionId, WindowId)+import qualified Chiasma.Data.TmuxId as HasPaneId (HasPaneId(..))++import Chiasma.Codec (TmuxCodec)++data PaneCoords =+  PaneCoords {+    sessionId :: SessionId,+    windowId :: WindowId,+    paneId :: PaneId+  }+  deriving (Eq, Show, Generic, TmuxCodec)++instance HasPaneId PaneCoords where+  paneId = paneId
+ lib/Chiasma/Codec/Data/PaneDetail.hs view
@@ -0,0 +1,18 @@+module Chiasma.Codec.Data.PaneDetail where++import Chiasma.Codec (TmuxCodec)+import Chiasma.Data.TmuxId (HasPaneId, PaneId)+import qualified Chiasma.Data.TmuxId as HasPaneId (HasPaneId(..))++data PaneDetail =+  PaneDetail {+    paneId :: PaneId,+    paneWidth :: Int,+    paneHeight :: Int,+    paneTop :: Int,+    paneLeft :: Int+  }+  deriving (Eq, Show, Generic, TmuxCodec)++instance HasPaneId PaneDetail where+  paneId = paneId
+ lib/Chiasma/Codec/Data/PaneMode.hs view
@@ -0,0 +1,15 @@+module Chiasma.Codec.Data.PaneMode where++import Chiasma.Codec (TmuxCodec)+import Chiasma.Data.TmuxId (HasPaneId, PaneId)+import qualified Chiasma.Data.TmuxId as HasPaneId (HasPaneId(paneId))++data PaneMode =+  PaneMode {+    paneId :: PaneId,+    paneMode :: Text+  }+  deriving (Eq, Show, Generic, TmuxCodec)++instance HasPaneId PaneMode where+  paneId = paneId
+ lib/Chiasma/Codec/Data/PanePid.hs view
@@ -0,0 +1,15 @@+module Chiasma.Codec.Data.PanePid where++import Chiasma.Codec (TmuxCodec)+import Chiasma.Data.TmuxId (HasPaneId, PaneId)+import qualified Chiasma.Data.TmuxId as HasPaneId (HasPaneId(paneId))++data PanePid =+  PanePid {+    paneId :: PaneId,+    panePid :: Int+  }+  deriving (Eq, Show, Generic, TmuxCodec)++instance HasPaneId PanePid where+  paneId = paneId
+ lib/Chiasma/Codec/Data/Session.hs view
@@ -0,0 +1,11 @@+module Chiasma.Codec.Data.Session where++import Chiasma.Codec (TmuxCodec)+import Chiasma.Data.TmuxId (SessionId)++-- must be data for now because of how derivation of `TmuxCodec` is implemented+data Session =+  Session {+    sessionId :: SessionId+  }+  deriving (Eq, Show, Generic, TmuxCodec)
+ lib/Chiasma/Codec/Data/Window.hs view
@@ -0,0 +1,12 @@+module Chiasma.Codec.Data.Window where++import Chiasma.Codec (TmuxCodec)+import Chiasma.Data.TmuxId (WindowId)++data Window =+  Window {+    windowId :: WindowId,+    windowWidth :: Int,+    windowHeight :: Int+  }+  deriving (Eq, Show, Generic, TmuxCodec)
lib/Chiasma/Codec/Decode.hs view
@@ -1,41 +1,38 @@-{-# LANGUAGE FlexibleInstances #-} {-# LANGUAGE TypeOperators #-} -module Chiasma.Codec.Decode(-  TmuxDecodeError(..),-  TmuxPrimDecode(..),-  TmuxDataDecode(..),-  idParser,-  parseId,-  readInt,-) where+module Chiasma.Codec.Decode where -import GHC.Generics ((:*:)(..), K1(..), M1(..))-import Data.Bifunctor (first, second)-import Text.Read (readEither)+import qualified Data.Text as Text (null, unpack)+import Data.Text.Read (decimal)+import GHC.Generics (K1(..), M1(..), (:*:)(..))+import Prelude hiding (many)+import Text.Parsec.Char (char, digit) import Text.ParserCombinators.Parsec (   GenParser,   ParseError,-  parse,   many,+  parse,   )-import Text.Parsec.Char (char, digit) +import Chiasma.Data.TmuxId (PaneId(..), SessionId(..), WindowId(..), panePrefix, sessionPrefix, windowPrefix)+ data TmuxDecodeError =-  ParseFailure String ParseError+  ParseFailure Text ParseError   |-  IntParsingFailure String+  IntParsingFailure Text   |+  BoolParsingFailure Text+  |   TooFewFields   |-  TooManyFields [String]+  TooManyFields [Text]   deriving (Eq, Show)  class TmuxPrimDecode a where-  primDecode :: String -> Either TmuxDecodeError a+  primDecode :: Text -> Either TmuxDecodeError a  class TmuxDataDecode f where-  decode' :: [String] -> Either TmuxDecodeError ([String], f a)+  decode' :: [Text] -> Either TmuxDecodeError ([Text], f a)  instance (TmuxDataDecode f, TmuxDataDecode g) => TmuxDataDecode (f :*: g) where   decode' fields = do@@ -53,18 +50,49 @@     return (as, K1 prim)   decode' [] = Left TooFewFields -readInt :: String -> String -> Either TmuxDecodeError Int+readInt :: Text -> Text -> Either TmuxDecodeError Int readInt input num =-  first (const $ IntParsingFailure input) $ readEither num+  first (const $ IntParsingFailure input) parsed+  where+    parsed = do+      (num', rest) <- decimal num+      if Text.null rest then Right num' else Left ""  instance TmuxPrimDecode Int where   primDecode field = readInt field field -idParser :: Char -> GenParser Char st String-idParser sym = char sym >> many digit+instance TmuxPrimDecode Bool where+  primDecode field =+    convert =<< readInt field field+    where+      convert 0 =+        Right False+      convert 1 =+        Right True+      convert _ =+        Left (BoolParsingFailure $ "got non-bool `" <> show field <> "`") -parseId :: (Int -> a) -> Char -> String -> Either TmuxDecodeError a+idParser :: Char -> GenParser Char st Text+idParser sym =+  char sym *> (toText <$> many digit)++parseId :: (Int -> a) -> Char -> Text -> Either TmuxDecodeError a parseId cons sym input = do-  num <- first (ParseFailure "id") $ parse (idParser sym) "none" input+  num <- first (ParseFailure "id") $ parse (idParser sym) "none" (Text.unpack input)   i <- readInt input num   return $ cons i++instance TmuxPrimDecode SessionId where+  primDecode = parseId SessionId sessionPrefix++instance TmuxPrimDecode WindowId where+  primDecode = parseId WindowId windowPrefix++instance TmuxPrimDecode PaneId where+  primDecode = parseId PaneId panePrefix++instance TmuxPrimDecode [Char] where+  primDecode = Right . toString++instance TmuxPrimDecode Text where+  primDecode = Right
lib/Chiasma/Codec/Query.hs view
@@ -1,20 +1,14 @@-{-# LANGUAGE FlexibleInstances #-}-{-# LANGUAGE PolyKinds #-}-{-# LANGUAGE TypeOperators #-} {-# LANGUAGE AllowAmbiguousTypes #-}+{-# LANGUAGE TypeOperators #-} -module Chiasma.Codec.Query(-  TmuxDataQuery(..),-) where+module Chiasma.Codec.Query where -import GHC.Generics ((:*:), D1, C1, S1, Selector, selName)-import GHC.Unicode (isUpper, toLower)+import Data.Char (isUpper, toLower)+import qualified Data.Text as Text (concatMap, singleton)+import GHC.Generics (C1, D1, S1, Selector, selName, (:*:))  class TmuxDataQuery f where-  query' :: [String]--instance (TmuxDataQuery f, TmuxDataQuery g) => TmuxDataQuery (f :*: g) where-  query' = query' @f ++ query' @g+  query' :: [Text]  instance TmuxDataQuery f => (TmuxDataQuery (D1 c f)) where   query' = query' @f@@ -22,18 +16,22 @@ instance TmuxDataQuery f => (TmuxDataQuery (C1 c f)) where   query' = query' @f -trans :: Char -> String-trans a | isUpper a = ['_', toLower a]-trans a = [a]+instance (TmuxDataQuery f, TmuxDataQuery g) => TmuxDataQuery (f :*: g) where+  query' = query' @f <> query' @g -snakeCase :: String -> String-snakeCase = (>>= trans)+trans :: Char -> Text+trans a | isUpper a = toText @String ['_', toLower a]+trans a = Text.singleton a -formatQuery :: String -> String-formatQuery q = "#{" ++ snakeCase q ++ "}"+snakeCase :: Text -> Text+snakeCase =+  Text.concatMap trans +formatQuery :: Text -> Text+formatQuery q = "#{" <> snakeCase q <> "}"+ instance Selector s => (TmuxDataQuery (S1 s f)) where   query' =-    [formatQuery query]+    [formatQuery (toText query)]     where       query = selName (undefined :: t s f p)
+ lib/Chiasma/Command/Pane.hs view
@@ -0,0 +1,173 @@+module Chiasma.Command.Pane where++import Data.List (dropWhileEnd)+import qualified Data.Text as Text (intercalate, singleton, splitOn)++import Chiasma.Codec (TmuxCodec)+import qualified Chiasma.Codec.Data as Codec (Pane)+import qualified Chiasma.Codec.Data.PaneCoords as Codec (PaneCoords)+import qualified Chiasma.Codec.Data.PaneMode as Codec (PaneMode(PaneMode))+import qualified Chiasma.Codec.Data.PanePid as Codec (PanePid)+import Chiasma.Data.TmuxId (HasPaneId, PaneId, WindowId, formatId)+import qualified Chiasma.Data.TmuxId as HasPaneId (paneId)+import Chiasma.Data.TmuxThunk (TmuxThunk)+import Chiasma.Data.View (View(View))+import qualified Chiasma.Monad.Tmux as Tmux (read, readRaw, unsafeReadFirst, write)+import Control.Monad.Free.Class (MonadFree)++paneTarget :: PaneId -> [Text]+paneTarget paneId =+  ["-t", formatId paneId]++sameId :: HasPaneId a => PaneId -> a -> Bool+sameId target candidate = target == HasPaneId.paneId candidate++panesAs :: (MonadFree TmuxThunk m, TmuxCodec a) => m [a]+panesAs =+  Tmux.read "list-panes" ["-a"]++panes :: MonadFree TmuxThunk m => m [Codec.Pane]+panes =+  panesAs++pane :: (MonadFree TmuxThunk m, TmuxCodec a, HasPaneId a) => PaneId -> m (Maybe a)+pane paneId =+  find (sameId paneId) <$> Tmux.read "list-panes" ["-t", formatId paneId]++windowPanesAs :: (MonadFree TmuxThunk m, TmuxCodec a) => WindowId -> m [a]+windowPanesAs windowId =+  Tmux.read "list-panes" ["-t", formatId windowId]++windowPanes :: MonadFree TmuxThunk m => WindowId -> m [Codec.Pane]+windowPanes =+  windowPanesAs++firstWindowPane :: MonadFree TmuxThunk m => WindowId -> m Codec.Pane+firstWindowPane windowId =+  Tmux.unsafeReadFirst "list-panes" ["-t", formatId windowId]++closePane :: MonadFree TmuxThunk m => PaneId -> m ()+closePane paneId =+  Tmux.write "kill-pane" (paneTarget paneId)++isPaneIdOpen ::+  MonadFree TmuxThunk m =>+  PaneId ->+  m Bool+isPaneIdOpen paneId =+  any (sameId paneId) <$> panes++isPaneOpen ::+  MonadFree TmuxThunk m =>+  View PaneId ->+  m Bool+isPaneOpen (View _ (Just paneId)) =+  isPaneIdOpen paneId+isPaneOpen _ = return False++movePane ::+  MonadFree TmuxThunk m =>+  PaneId ->+  PaneId ->+  Bool ->+  m ()+movePane paneId refId vertical =+  Tmux.write "move-pane" ["-d", "-s", formatId paneId, "-t", formatId refId, direction]+  where+    direction = if vertical then "-v" else "-h"++resizePane ::+  MonadFree TmuxThunk m =>+  PaneId ->+  Bool ->+  Int ->+  m ()+resizePane paneId vertical size =+  Tmux.write "resize-pane" ["-t", formatId paneId, direction, show size]+  where+    direction = if vertical then "-y" else "-x"++formatLine :: Text -> [Text]+formatLine line =+  ["\"" <> replace "\"" "\\\"" line <> Text.singleton '"', "enter"]+  where+    replace from to =+      Text.intercalate to . Text.splitOn from++sendKeys ::+  MonadFree TmuxThunk m =>+  PaneId ->+  [Text] ->+  m ()+sendKeys paneId lines' =+  traverse_ send formatted+  where+    formatted = lines' >>= formatLine+    send line = Tmux.write "send-keys" (paneTarget paneId <> [line])++pipePane ::+  MonadFree TmuxThunk m =>+  PaneId ->+  Text ->+  m ()+pipePane paneId cmd =+  Tmux.write "pipe-pane" (paneTarget paneId <> [cmd])++capturePane ::+  MonadFree TmuxThunk m =>+  PaneId ->+  m [Text]+capturePane paneId = do+  lines' <- Tmux.readRaw "capture-pane" (paneTarget paneId <> ["-p", "-e"])+  return $ dropWhileEnd ("" ==) lines'++panePid ::+  MonadFree TmuxThunk m =>+  PaneId ->+  m (Maybe Codec.PanePid)+panePid =+  pane++panePids ::+  MonadFree TmuxThunk m =>+  m [Codec.PanePid]+panePids =+  panesAs++paneCoords ::+  MonadFree TmuxThunk m =>+  PaneId ->+  m (Maybe Codec.PaneCoords)+paneCoords =+  pane++selectPane ::+  MonadFree TmuxThunk m =>+  PaneId ->+  m ()+selectPane paneId =+  Tmux.write "select-pane" (paneTarget paneId)++copyMode ::+  MonadFree TmuxThunk m =>+  PaneId ->+  m ()+copyMode =+  Tmux.write "copy-mode" . paneTarget++paneMode ::+  MonadFree TmuxThunk m =>+  PaneId ->+  m (Maybe Codec.PaneMode)+paneMode =+  pane++quitCopyMode ::+  MonadFree TmuxThunk m =>+  PaneId ->+  m ()+quitCopyMode paneId =+  traverse_ check =<< pane paneId+  where+    check (Codec.PaneMode _ mode) =+      when (mode == "copy-mode") (sendKeys paneId ["C-c"])
+ lib/Chiasma/Command/Session.hs view
@@ -0,0 +1,33 @@+module Chiasma.Command.Session where++import Control.Monad.Free.Class (MonadFree)++import Chiasma.Codec.Data (Session(Session))+import Chiasma.Data.Ident (Ident, identText)+import Chiasma.Data.TmuxId (SessionId)+import Chiasma.Data.TmuxThunk (TmuxThunk)+import qualified Chiasma.Monad.Tmux as Tmux (read, unsafeReadOne, write)++sameId :: SessionId -> Session -> Bool+sameId target (Session i) = target == i++sessions :: MonadFree TmuxThunk m => m [Session]+sessions =+  Tmux.read "list-sessions" []++doesSessionExist :: MonadFree TmuxThunk m => SessionId -> m Bool+doesSessionExist sessionId =+  any (sameId sessionId) <$> sessions++existingSessionId :: MonadFree TmuxThunk m => SessionId -> m (Maybe SessionId)+existingSessionId sessionId = do+  exists <- doesSessionExist sessionId+  return $ if exists then Just sessionId else Nothing++newSession :: MonadFree TmuxThunk m => Ident -> m Session+newSession name =+  Tmux.unsafeReadOne "new-session" ["-s", identText name, "-P"]++activateSession :: MonadFree TmuxThunk m => Int -> m ()+activateSession sessionId =+  Tmux.write "send-keys" ["-t", "%1", "'tmux switch-client -t \\$" <> show sessionId <> "'", "enter"]
+ lib/Chiasma/Command/Window.hs view
@@ -0,0 +1,53 @@+module Chiasma.Command.Window where++import Control.Monad.Free.Class (MonadFree)++import Chiasma.Codec (TmuxCodec)+import Chiasma.Codec.Data (Pane, Window(Window))+import Chiasma.Data.Ident (Ident, identText)+import Chiasma.Data.TmuxId (SessionId, TmuxId(formatId), WindowId)+import Chiasma.Data.TmuxThunk (TmuxThunk)+import qualified Chiasma.Monad.Tmux as Tmux (read, unsafeReadFirst, unsafeReadOne)++sameId :: WindowId -> Window -> Bool+sameId target (Window i _ _) = target == i++windows :: MonadFree TmuxThunk m => m [Window]+windows =+  Tmux.read "list-windows" ["-a"]++window :: MonadFree TmuxThunk m => WindowId -> m (Maybe Window)+window windowId =+  find (sameId windowId) <$> windows++sessionWindows :: MonadFree TmuxThunk m => SessionId -> m [Window]+sessionWindows sid =+  Tmux.read "list-windows" ["-t", formatId sid]++newSessionWindow :: MonadFree TmuxThunk m => SessionId -> m Window+newSessionWindow sid =+  Tmux.unsafeReadOne "list-windows" ["-t", formatId sid]++doesWindowExist :: MonadFree TmuxThunk m => WindowId -> m Bool+doesWindowExist windowId =+  any (sameId windowId) <$> windows++newWindow :: MonadFree TmuxThunk m => SessionId -> Ident -> m Window+newWindow sid name =+  Tmux.unsafeReadOne "new-window" ["-t", formatId sid, "-n", identText name, "-P"]++splitWindowAs ::+  (MonadFree TmuxThunk m, TmuxCodec a) =>+  FilePath ->+  WindowId ->+  m a+splitWindowAs dir windowId =+  Tmux.unsafeReadFirst "split-window" ["-t", formatId windowId, "-d", "-P", "-c", toText dir]++splitWindow ::+  (MonadFree TmuxThunk m) =>+  FilePath ->+  WindowId ->+  m Pane+splitWindow =+  splitWindowAs
+ lib/Chiasma/Control/IO/Unsafe.hs view
@@ -0,0 +1,6 @@+module Chiasma.Control.IO.Unsafe where++import GHC.IO.Unsafe (unsafePerformIO)++unsafeLog :: Show a => a -> b -> b+unsafeLog a b = unsafePerformIO $ print a >> return b
+ lib/Chiasma/Data/Cmd.hs view
@@ -0,0 +1,26 @@+module Chiasma.Data.Cmd(+  CmdName(..),+  CmdArgs(..),+  Cmd(..),+  Cmds(..),+  cmd,+) where++newtype CmdName =+  CmdName Text+  deriving (Eq, Show)++newtype CmdArgs =+  CmdArgs [Text]+  deriving (Eq, Show)++data Cmd =+  Cmd CmdName CmdArgs+  deriving (Eq, Show)++newtype Cmds =+  Cmds [Cmd]+  deriving (Eq, Show)++cmd :: Text -> [Text] -> Cmd+cmd name args = Cmd (CmdName name) (CmdArgs args)
+ lib/Chiasma/Data/Conduit.hs view
@@ -0,0 +1,10 @@+{-# LANGUAGE DataKinds #-}++module Chiasma.Data.Conduit where++import Conduit (ConduitT, Flush)+import Data.Conduit.Binary (sinkHandleFlush)+import Data.Conduit.Process.Typed (StreamSpec, StreamType(STInput), createPipe)++createSinkFlush :: MonadIO m => StreamSpec 'STInput (ConduitT (Flush ByteString) o m ())+createSinkFlush = sinkHandleFlush <$> createPipe
+ lib/Chiasma/Data/Ident.hs view
@@ -0,0 +1,59 @@+module Chiasma.Data.Ident where++import Data.Aeson (FromJSON, ToJSON(toEncoding), defaultOptions, genericToEncoding)+import Data.Data (Data)+import Data.Text.Prettyprint.Doc (Pretty(..))+import Data.UUID (UUID)+import qualified Data.UUID as UUID (fromText, toText)+import System.Random (randomIO)+import qualified Text.Show as Show++data Ident =+  Str Text+  |+  Uuid UUID+  deriving (Eq, Generic, Data, NFData, Ord)++instance Show Ident where+  show = toString . identText++class Identifiable a where+  identify :: a -> Ident++instance Identifiable Ident where+  identify = id++instance Pretty Ident where+  pretty (Str s) = pretty s+  pretty (Uuid u) = pretty . UUID.toText $ u++instance Default Ident where+  def = Str ""++instance IsString Ident where+  fromString = Str . toText++instance FromJSON Ident where++instance ToJSON Ident where+  toEncoding = genericToEncoding defaultOptions++sameIdent ::+  Identifiable a =>+  Identifiable b =>+  a ->+  b ->+  Bool+sameIdent target b =+  identify target == identify b++identText :: Ident -> Text+identText (Str a) = a+identText (Uuid a) = UUID.toText a++generateIdent :: MonadIO m => m Ident+generateIdent = liftIO $ Uuid <$> randomIO++parseIdent :: Text -> Ident+parseIdent text =+  maybe (Str text) Uuid (UUID.fromText text)
+ lib/Chiasma/Data/List.hs view
@@ -0,0 +1,16 @@+module Chiasma.Data.List(+  head',+  tail',+  last',+) where++head' :: [a] -> Maybe a+head' (a : _) = Just a+head' _ = Nothing++tail' :: [a] -> Maybe [a]+tail' (_ : as) = Just as+tail' _ = Nothing++last' :: [a] -> Maybe a+last' = head' . reverse
+ lib/Chiasma/Data/Maybe.hs view
@@ -0,0 +1,17 @@+module Chiasma.Data.Maybe where++import Control.Monad.Error.Class (MonadError(throwError))++maybeExcept :: MonadError e m => e -> Maybe a -> m a+maybeExcept e Nothing = throwError e+maybeExcept _ (Just a) = return a++findMaybe :: (a -> Maybe b) -> [a] -> Maybe b+findMaybe f as =+  case mapMaybe f as of+    (a : _) -> Just a+    _ -> Nothing++orElse :: Maybe a -> Maybe a -> Maybe a+orElse _ (Just a) = Just a+orElse fallback Nothing = fallback
− lib/Chiasma/Data/Pane.hs
@@ -1,23 +0,0 @@-module Chiasma.Data.Pane(-  Pane(..),-  PaneId(..),-) where--import GHC.Generics (Generic)-import Chiasma.Codec (TmuxCodec)-import Chiasma.Codec.Decode (TmuxPrimDecode(..), parseId)--newtype PaneId =-  PaneId Int-  deriving (Eq, Show)--instance TmuxPrimDecode PaneId where-  primDecode = parseId PaneId '%'--data Pane =-  Pane {-    paneId :: PaneId,-    paneWidth :: Int,-    paneHeight :: Int-  }-  deriving (Eq, Show, Generic, TmuxCodec)
+ lib/Chiasma/Data/RenderError.hs view
@@ -0,0 +1,17 @@+module Chiasma.Data.RenderError where++import Chiasma.Data.Ident (Ident)+import Chiasma.Data.TmuxError (TmuxError)+import Chiasma.Data.Views (ViewsError)++data RenderError =+  NoPrincipal Ident+  |+  Views ViewsError+  |+  Pack Text+  |+  Fatal TmuxError+  deriving (Eq, Show)++deepPrisms ''RenderError
+ lib/Chiasma/Data/TmuxError.hs view
@@ -0,0 +1,39 @@+module Chiasma.Data.TmuxError where++import Chiasma.Codec.Decode (TmuxDecodeError)+import Text.ParserCombinators.Parsec (ParseError)++import Chiasma.Data.Cmd (Cmds(..))++data TmuxError =+  ProcessFailed {+    processFailedCmds :: Cmds,+    processFailedReason :: Text+    }+  |+  OutputParsingFailed {+    parsingFailedCmds :: Cmds,+    parsingFailedOutput :: [Text],+    parsingFailedError :: ParseError+  }+  |+  NoOutput Cmds+  |+  DecodingFailed {+    decodingFailedCmds :: Cmds,+    decodingFailedOutput :: Text,+    decodingFailedError :: TmuxDecodeError+  }+  |+  InvalidOutput {+    invalidOutputReason :: Text,+    invalidOutputCommand :: Text+  }+  |+  CommandFailed {+    commandFailedCmds :: Cmds,+    commandFailedError :: [Text]+  }+  deriving (Eq, Show)++deepPrisms ''TmuxError
+ lib/Chiasma/Data/TmuxId.hs view
@@ -0,0 +1,64 @@+module Chiasma.Data.TmuxId where++import Data.Text.Prettyprint.Doc (Pretty(..))++sessionPrefix :: Char+sessionPrefix = '$'++newtype SessionId =+  SessionId Int+  deriving (Eq, Show, Generic)+  deriving newtype (Num, Ord)++instance Pretty SessionId where+  pretty = pretty . formatId++windowPrefix :: Char+windowPrefix = '@'++newtype WindowId =+  WindowId Int+  deriving (Eq, Show, Generic)+  deriving newtype (Num, Ord)++instance Pretty WindowId where+  pretty = pretty . formatId++panePrefix :: Char+panePrefix = '%'++newtype PaneId =+  PaneId Int+  deriving (Eq, Show, Generic)+  deriving newtype (Num, Ord)++instance Pretty PaneId where+  pretty = pretty . formatId++class HasPaneId a where+  paneId :: a -> PaneId++newtype TmuxIdPrefix a =+  TmuxIdPrefix Char++class TmuxId a where+  prefix :: TmuxIdPrefix a+  number :: a -> Int++  formatId :: a -> Text+  formatId a =+    toText (p : show (number a))+    where+      (TmuxIdPrefix p) = prefix @a++instance TmuxId SessionId where+  prefix = TmuxIdPrefix sessionPrefix+  number (SessionId i) = i++instance TmuxId WindowId where+  prefix = TmuxIdPrefix windowPrefix+  number (WindowId i) = i++instance TmuxId PaneId where+  prefix = TmuxIdPrefix panePrefix+  number (PaneId i) = i
lib/Chiasma/Data/TmuxThunk.hs view
@@ -1,53 +1,16 @@-{-# LANGUAGE DeriveFunctor #-}-{-# LANGUAGE StandaloneDeriving #-}--module Chiasma.Data.TmuxThunk(-  CmdName(..),-  CmdArgs(..),-  TmuxThunk(..),-  TmuxError(..),-  Cmd(..),-  Cmds(..),-  cmd,-) where+module Chiasma.Data.TmuxThunk where -import Text.ParserCombinators.Parsec (ParseError) import Chiasma.Codec.Decode (TmuxDecodeError)--newtype CmdName =-  CmdName String-  deriving (Eq, Show)--newtype CmdArgs =-  CmdArgs [String]-  deriving (Eq, Show)--data Cmd =-  Cmd CmdName CmdArgs-  deriving (Eq, Show)--newtype Cmds =-  Cmds [Cmd]-  deriving (Eq, Show)--data TmuxError =-  ProcessFailed Cmds String-  |-  OutputParsingFailed Cmds [String] ParseError-  |-  NoOutput Cmds-  |-  DecodingFailed Cmds String TmuxDecodeError-  deriving (Eq, Show)+import Chiasma.Data.Cmd (Cmd(..))+import Chiasma.Data.TmuxError (TmuxError(..))  data TmuxThunk next =-  ∀ a . Read Cmd ([String] -> Either TmuxDecodeError a) ([a] -> next)+  ∀ a . Read Cmd (Text -> Either TmuxDecodeError a) ([a] -> next)   |   Write Cmd (() -> next)   |+  Flush (() -> next)+  |   Failed TmuxError  deriving instance Functor TmuxThunk--cmd :: String -> [String] -> Cmd-cmd name args = Cmd (CmdName name) (CmdArgs args)
+ lib/Chiasma/Data/View.hs view
@@ -0,0 +1,21 @@+module Chiasma.Data.View where++import Chiasma.Data.Ident (Ident, Identifiable(..))+import Control.Lens (makeClassy_)+import qualified Control.Lens as Lens (set)++data View a =+  View {+    viewIdent :: Ident,+    viewId :: Maybe a+  }+  deriving (Eq, Show)++makeClassy_ ''View++instance Identifiable (View a) where+  identify = viewIdent++setViewId :: a -> View a -> View a+setViewId =+  Lens.set _viewId . Just
+ lib/Chiasma/Data/Views.hs view
@@ -0,0 +1,37 @@+{-# LANGUAGE DeriveAnyClass #-}++module Chiasma.Data.Views where++import Data.Text.Prettyprint.Doc (Doc)+import Data.Text.Prettyprint.Doc.Render.Terminal (AnsiStyle)++import Chiasma.Data.Ident (Ident)+import Chiasma.Data.TmuxId (PaneId, SessionId, WindowId)+import Chiasma.Data.View (View)++data ViewsError =+  NoSuchSession Ident+  |+  NoSuchWindow Ident+  |+  NoSuchPane Ident+  |+  NoPaneId Ident+  deriving (Eq, Show)++deepPrisms ''ViewsError++data Views =+  Views {+    _sessions :: [View SessionId],+    _windows :: [View WindowId],+    _panes :: [View PaneId],+    _log :: [Doc AnsiStyle]+  }+  deriving (Show, Generic, Default)++instance Eq Views where+  (Views sa wa pa _) == (Views sb wb pb _) =+    (sa == sb) && (wa == wb) && (pa == pb)++deepLenses ''Views
− lib/Chiasma/Data/Window.hs
@@ -1,23 +0,0 @@-module Chiasma.Data.Window(-  Window(..),-  WindowId(..),-) where--import GHC.Generics (Generic)-import Chiasma.Codec (TmuxCodec)-import Chiasma.Codec.Decode (TmuxPrimDecode(..), parseId)--newtype WindowId =-  WindowId Int-  deriving (Eq, Show)--instance TmuxPrimDecode WindowId where-  primDecode = parseId WindowId '@'--data Window =-  Window {-    windowId :: WindowId,-    windowWidth :: Int,-    windowHeight :: Int-  }-  deriving (Eq, Show, Generic, TmuxCodec)
+ lib/Chiasma/Data/WindowState.hs view
@@ -0,0 +1,18 @@+module Chiasma.Data.WindowState(+  WindowState(..),+) where++import qualified Chiasma.Codec.Data as Codec (Window, Pane)+import Chiasma.Data.Ident (Ident)+import Chiasma.Data.TmuxId (PaneId)+import Chiasma.Ui.Data.RenderableTree (RenderableTree)++data WindowState =+  WindowState {+    wsNativeWindow :: Codec.Window,+    wsNativeRefPane :: Codec.Pane,+    wsWindowIdent :: Ident,+    wsLayout :: RenderableTree,+    wsReferencePane :: PaneId+  }+  deriving (Eq, Show)
+ lib/Chiasma/Lens/Tree.hs view
@@ -0,0 +1,127 @@+{-# LANGUAGE TemplateHaskell #-}+{-# LANGUAGE TypeFamilies #-}+{-# LANGUAGE RankNTypes #-}+{-# LANGUAGE FunctionalDependencies #-}+{-# LANGUAGE DeriveDataTypeable #-}++module Chiasma.Lens.Tree where++import Chiasma.Data.Ident (Ident, Identifiable(..))+import Chiasma.Ui.Data.View+import Chiasma.Ui.Lens.Ident (matchIdentP)+import Control.Lens (+  Fold,+  Index,+  IxValue,+  Ixed(ix),+  Plated(..),+  Traversal',+  cosmos,+  each,+  makeClassy_,+  over,+  preview,+  toListOf,+  transform,+  )+import Data.Data (Data)+import Data.Foldable (foldrM)++newtype NodeIndexTree l p =+  NodeIndexTree {+    nitTree :: Tree l p+  }+  deriving (Eq, Show)++makeClassy_ ''NodeIndexTree++newtype LeafIndexTree l p =+  LeafIndexTree {+    litTree :: Tree l p+  }+  deriving (Eq, Show)++makeClassy_ ''LeafIndexTree++plateWrap :: (Data l, Data p) => (Tree l p -> t l p) -> (t l p -> Tree l p) -> Traversal' (t l p) (t l p)+plateWrap consWrapper unconsWrapper f wrappedTree =+  consWrapper <$> plate g (unconsWrapper wrappedTree)+  where+    g tree' = unconsWrapper <$> f (consWrapper tree')++instance (Data l, Data p) => Plated (NodeIndexTree l p) where+  plate = plateWrap NodeIndexTree nitTree++instance (Data l, Data p) => Plated (LeafIndexTree l p) where+  plate = plateWrap LeafIndexTree litTree++type LayoutIndexTree = NodeIndexTree LayoutView PaneView+type PaneIndexTree = LeafIndexTree LayoutView PaneView++type instance Index (NodeIndexTree _ _) = Ident+type instance Index (LeafIndexTree _ _) = Ident++type instance IxValue (NodeIndexTree l _) = l+type instance IxValue (LeafIndexTree _ p) = p++leafDataTraversal :: Traversal' (Tree l p) p+leafDataTraversal = _treeSubs . each . leafData++leafByIdentTraversal :: Identifiable p => Ident -> Traversal' (Tree l p) p+leafByIdentTraversal ident' = leafDataTraversal . matchIdentP ident'++instance Identifiable p => Ixed (LeafIndexTree l p) where+  ix ident' = _litTree . leafByIdentTraversal ident'++leavesByIdentRecursive :: (Identifiable p, Data l, Data p) => Ident -> Fold (LeafIndexTree l p) p+leavesByIdentRecursive ident' = cosmos . ix ident'++leafByIdent :: (Identifiable p, Data l, Data p) => Ident -> Tree l p -> Maybe p+leafByIdent ident' = preview (leavesByIdentRecursive ident') . LeafIndexTree++leavesByIdent :: (Identifiable p, Data l, Data p) => Ident -> Tree l p -> [p]+leavesByIdent ident' = toListOf (leavesByIdentRecursive ident') . LeafIndexTree++modifyLeafByIdent :: (Identifiable p, Data l, Data p) => Ident -> (p -> p) -> Tree l p -> Tree l p+modifyLeafByIdent ident' f tree' =+  litTree $ (transform $ over (ix ident') f) (LeafIndexTree tree')++-- subtreesWithLayout :: Traversal' (Tree l p) (l, TreeSub l p)+subtreesWithLayout :: ∀ l p m. Monad m => ((l, TreeSub l p) -> m (l, TreeSub l p)) -> Tree l p -> m (Tree l p)+subtreesWithLayout f (Tree l0 sub) = do+  (newL, newSub) <- foldrM applySub (l0, []) sub+  return (Tree newL newSub)+  where+    prependSub s (newL, newN) = (newL, newN : s)+    applySub :: TreeSub l p -> (l, [TreeSub l p]) -> m (l, [TreeSub l p])+    applySub (TreeNode t) (l, s) = do+      recur <- (\rsub -> (l, TreeNode rsub)) <$> subtreesWithLayout f t+      (fmap (prependSub s) . f) recur+    applySub p (l, s) =+      (fmap (prependSub s) . f) (l, p)++subtrees :: ∀ l p m. Monad m => (TreeSub l p -> m (TreeSub l p)) -> Tree l p -> m (Tree l p)+subtrees f (Tree l sub) = do+  newSub <- mapM applySub sub+  return (Tree l newSub)+  where+    applySub :: TreeSub l p -> m (TreeSub l p)+    applySub (TreeNode t) = do+      recur <- subtrees f t+      f (TreeNode recur)+    applySub p = f p++treesAndSubs ::+  Monad m =>+  (Tree l p -> m (Tree l p)) ->+  (TreeSub l p -> m (TreeSub l p)) ->+  Tree l p ->+  m (Tree l p)+treesAndSubs ft fs (Tree l sub) = do+  treeResult <- mapM applySub sub+  ft (Tree l treeResult)+  where+    applySub (TreeNode t) = do+      recur <- treesAndSubs ft fs t+      fs (TreeNode recur)+    applySub p = fs p
+ lib/Chiasma/Lens/Where.hs view
@@ -0,0 +1,10 @@+{-# LANGUAGE RankNTypes #-}++module Chiasma.Lens.Where(+  where1,+) where++import Control.Lens (Over, filtered, taking)++where1 :: (Applicative f, Traversable t) => (a -> Bool) -> Over (->) f (t a) (t a) a a+where1 predicate = taking 1 $ traverse . filtered predicate
− lib/Chiasma/Monad/Buffered.hs
@@ -1,29 +0,0 @@-module Chiasma.Monad.Buffered(-  runTmux,-) where--import Control.Monad.Free (Free(..))-import Control.Monad.IO.Class (MonadIO)-import Control.Monad.Trans.Except (ExceptT, runExceptT, throwE)-import Data.Default.Class (Default(def))-import Chiasma.Api.Class (TmuxApi(..))-import Chiasma.Data.TmuxThunk (Cmd(..), Cmds(..), TmuxThunk(..), TmuxError)-import Chiasma.Monad.Tmux (TmuxProg)--newtype TmuxState = TmuxState [Cmd]--instance Default TmuxState where-  def = TmuxState def--interpret :: (MonadIO m, TmuxApi api) => TmuxState -> api -> TmuxProg b -> ExceptT TmuxError m b-interpret (TmuxState cmds) api (Pure a) = a <$ runCommands api (const $ Right ()) (Cmds cmds)-interpret (TmuxState cmds) api (Free (Read cmd decode next)) = do-  a <- runCommands api decode $ Cmds (cmd : cmds)-  interpret def api (next a)-interpret (TmuxState cmds) api (Free (Write cmd next)) =-  interpret (TmuxState (cmd : cmds)) api (next ())-interpret _ _ (Free (Failed err)) =-  throwE err--runTmux :: (MonadIO m, TmuxApi api) => api -> TmuxProg b -> m (Either TmuxError b)-runTmux api prog = runExceptT $ interpret def api prog
+ lib/Chiasma/Monad/EvalFreeT.hs view
@@ -0,0 +1,50 @@+module Chiasma.Monad.EvalFreeT where++import Control.Monad.Trans.Free (FreeF(..), FreeT(..))++import Chiasma.Codec.Decode (TmuxDecodeError)+import Chiasma.Data.Cmd (Cmd(..), Cmds(..))+import Chiasma.Data.TmuxError (TmuxError)+import Chiasma.Data.TmuxThunk (TmuxThunk(..))++newtype CmdBuffer = CmdBuffer [Cmd]++instance Default CmdBuffer where+  def = CmdBuffer def++type CommandExec m =+  (∀ b. (Text -> Either TmuxDecodeError b) -> Cmds -> m (Either TmuxError [b]))++evalFreeF ::+  Monad m =>+  CommandExec m ->+  CmdBuffer ->+  FreeF TmuxThunk a (FreeT TmuxThunk m a) ->+  m (Either TmuxError a)+evalFreeF _ (CmdBuffer []) (Pure a) =+  return (Right a)+evalFreeF exec (CmdBuffer cmds) (Pure a) =+  Right a <$ exec (const $ Right ()) (Cmds cmds)+evalFreeF exec (CmdBuffer cmds) (Free (Read cmd decode next)) = do+  a <- exec decode $ Cmds (cmd : cmds)+  case a of+    Right a' -> evalFreeT exec def (next a')+    Left err -> return (Left err)+evalFreeF exec (CmdBuffer cmds) (Free (Write cmd next)) =+  evalFreeT exec (CmdBuffer (cmd : cmds)) (next ())+evalFreeF exec (CmdBuffer cmds) (Free (Flush next)) =+  exec (const $ Right ()) (Cmds cmds) >>= \case+    Right _ -> evalFreeT exec def (next ())+    Left err -> return (Left err)+evalFreeF _ _ (Free (Failed err)) =+  return (Left err)++evalFreeT ::+  Monad m =>+  CommandExec m ->+  CmdBuffer ->+  FreeT TmuxThunk m a ->+  m (Either TmuxError a)+evalFreeT exec s (FreeT ma) = do+  inner <- ma+  evalFreeF exec s inner
+ lib/Chiasma/Monad/IndividualProcess.hs view
@@ -0,0 +1,40 @@+module Chiasma.Monad.IndividualProcess where++import Control.Monad.Free (Free(..))++import Chiasma.Api.Class (TmuxApi(..))+import Chiasma.Data.Cmd (Cmd(..), Cmds(..))+import Chiasma.Data.TmuxError (TmuxError)+import Chiasma.Data.TmuxThunk (TmuxThunk(..))++type TmuxProg = Free TmuxThunk++newtype TmuxState = TmuxState [Cmd]++instance Default TmuxState where+  def = TmuxState def++interpret ::+  (TmuxApi m api, MonadDeepError e TmuxError m) =>+  TmuxState ->+  api ->+  TmuxProg a ->+  m a+interpret (TmuxState cmds) api (Pure a) = a <$ runCommands api (const $ Right ()) (Cmds cmds)+interpret (TmuxState cmds) api (Free (Read cmd decode next)) = do+  a <- runCommands api decode $ Cmds (cmd : cmds)+  interpret def api (next a)+interpret (TmuxState cmds) api (Free (Write cmd next)) =+  interpret (TmuxState (cmd : cmds)) api (next ())+interpret (TmuxState cmds) api (Free (Flush next)) = do+  _ <- runCommands api (const $ Right ()) (Cmds cmds)+  interpret def api (next ())+interpret _ _ (Free (Failed err)) =+  throwHoist err++runTmux ::+  (TmuxApi m api, MonadDeepError e TmuxError m) =>+  api ->+  TmuxProg a ->+  m a+runTmux = interpret def
− lib/Chiasma/Monad/Simple.hs
@@ -1,38 +0,0 @@-module Chiasma.Monad.Simple(-  -- tmuxProcessConfig,-  -- tmuxProcess,-  -- interpret,-  -- runTmux,-) where---- import GHC.IO.Exception (ExitCode(ExitSuccess))--- import Control.Monad (when)--- import Control.Monad.Free (foldFree)--- import Control.Monad.IO.Class (MonadIO)--- import Control.Monad.Trans.Except (ExceptT(ExceptT), catchE, runExceptT)--- import qualified Data.ByteString.Lazy.Internal as B (unpackChars)--- import Data.Functor (void)--- import Data.List.Split (linesBy)--- import System.Process.Typed (ProcessConfig, readProcessStdout, proc)--- import UnliftIO (throwIO)--- import Chiasma.Data.TmuxThunk (Cmd(..), CmdName(..), CmdArgs(..), Cmds(..), TmuxThunk(..), TmuxError(..))--- import Chiasma.Monad.Tmux (TmuxProg)---- tmuxProcessConfig :: CmdName -> CmdArgs -> ProcessConfig () () ()--- tmuxProcessConfig (CmdName cmd) (CmdArgs args) =---   proc "tmux" (["-C", cmd] ++ args)---- tmuxProcess :: MonadIO m => Cmd -> m (Either TmuxError [String])--- tmuxProcess cmd@(Cmd name args) = do---   (code, out) <- readProcessStdout $ tmuxProcessConfig name args---   let outLines = linesBy (=='\n') $ B.unpackChars out---   return $ case code of---     ExitSuccess -> Right outLines---     _ -> Left $ TmuxProcessFailed (Cmds [cmd]) outLines---- interpret :: MonadIO m => TmuxThunk a next -> ExceptT TmuxError m next--- interpret (Read cmd next) = next <$> tmuxProcess cmd--- interpret (Write cmd next) = next <$> void (tmuxProcess cmd)---- runTmux :: MonadIO m => TmuxProg a next -> m (Either TmuxError next)--- runTmux = runExceptT . foldFree interpret
+ lib/Chiasma/Monad/Stream.hs view
@@ -0,0 +1,80 @@+module Chiasma.Monad.Stream where++import Conduit (ConduitT, Flush(..), runConduit, sinkList, yield, yieldMany, (.|))+import Control.Monad.Trans.Free (FreeT(..))+import qualified Data.Conduit.Combinators as Conduit (drop, take)++import Chiasma.Api.Class (TmuxApi(..))+import Chiasma.Codec.Decode (TmuxDecodeError)+import Chiasma.Data.Cmd (Cmd(..), Cmds(..))+import Chiasma.Data.TmuxError (TmuxError)+import qualified Chiasma.Data.TmuxError as TmuxError (TmuxError(ProcessFailed, DecodingFailed, CommandFailed))+import Chiasma.Data.TmuxThunk (TmuxThunk)+import Chiasma.Monad.EvalFreeT (evalFreeT)+import Chiasma.Native.StreamParse (TmuxOutputBlock)+import qualified Chiasma.Native.StreamParse as TmuxOutputBlock (TmuxOutputBlock(..))++type TmuxProg = FreeT TmuxThunk++type WriteCmd m =+  ConduitT (Flush Cmd) Void m ()++type ReadOutput m =+  ConduitT () TmuxOutputBlock m ()++handleProcessOutput ::+  Cmds ->+  (Text -> Either TmuxDecodeError a) ->+  [TmuxOutputBlock] ->+  Either TmuxError [a]+handleProcessOutput cs@(Cmds cmds) _ output | length output < length cmds =+  Left $ TmuxError.ProcessFailed cs "tmux terminated before all commands were processed"+handleProcessOutput cmds decode output = do+  readOutput <- foldl validate (Right []) output+  traverse decode' readOutput+  where+    validate (Left err) _ = Left err+    validate _ (TmuxOutputBlock.Success a) = Right a+    validate _ (TmuxOutputBlock.Error a) = Left $ TmuxError.CommandFailed cmds a+    decode' outputLine =+      mapLeft (TmuxError.DecodingFailed cmds outputLine) . decode $ outputLine++executeCommands ::+  MonadIO m =>+  WriteCmd m ->+  ReadOutput m ->+  (Text -> Either TmuxDecodeError a) ->+  Cmds ->+  m (Either TmuxError [a])+executeCommands writeCmd readOutput decode cs@(Cmds cmds) = do+  output <- runConduit $ do+    yieldMany (Chunk <$> reverse cmds) .| writeCmd+    yield Flush .| writeCmd+    readOutput .| Conduit.take (length cmds) .| sinkList+  return $ handleProcessOutput cs decode output++runTmuxProg ::+  MonadIO m =>+  TmuxProg m a ->+  WriteCmd m ->+  ReadOutput m ->+  m (Either TmuxError a)+runTmuxProg prog writeCmd readOutput = do+  runConduit $ readOutput .| Conduit.drop 1+  evalFreeT (executeCommands writeCmd readOutput) def prog++runTmuxE ::+  (MonadIO m, TmuxApi m api) =>+  api ->+  TmuxProg m a ->+  m (Either TmuxError a)+runTmuxE api prog =+  withTmux api (runTmuxProg prog)++runTmux ::+  (MonadIO m, MonadDeepError e TmuxError m, TmuxApi m api) =>+  api ->+  TmuxProg m a ->+  m a+runTmux api =+  hoistEither <=< runTmuxE api
lib/Chiasma/Monad/Tmux.hs view
@@ -1,21 +1,49 @@-{-# LANGUAGE ScopedTypeVariables #-}+module Chiasma.Monad.Tmux where -module Chiasma.Monad.Tmux(-  Chiasma.Monad.Tmux.read,-  write,-  TmuxProg,-) where+import Control.Monad.Free (liftF)+import Control.Monad.Free.Class (MonadFree) -import Control.Monad.Free (Free, liftF) import Chiasma.Codec (TmuxCodec, TmuxQuery(unQ)) import qualified Chiasma.Codec as TmuxCodec (TmuxCodec(decode, query))-import Chiasma.Data.TmuxThunk (TmuxThunk(..), cmd)--type TmuxProg = Free TmuxThunk+import Chiasma.Data.Cmd (cmd)+import Chiasma.Data.TmuxError (TmuxError(InvalidOutput))+import Chiasma.Data.TmuxThunk (TmuxThunk(..)) -read :: ∀ a . TmuxCodec a => String -> [String] -> TmuxProg [a]+read :: ∀ a m . (TmuxCodec a, MonadFree TmuxThunk m) => Text -> [Text] -> m [a] read name args =-  liftF $ Read (cmd name (args ++ ["-F", "'" ++ unQ (TmuxCodec.query @a) ++ "'"])) TmuxCodec.decode id+  liftF $ Read (cmd name (args <> formatArgs)) TmuxCodec.decode id+  where+    formatArgs = ["-F", "'", unQ (TmuxCodec.query @a), "'"] -write :: String -> [String] -> TmuxProg ()+unsafeReadOne :: ∀ a m . (TmuxCodec a, MonadFree TmuxThunk m) => Text -> [Text] -> m a+unsafeReadOne name args = do+  outputs <- read name args+  case outputs of+    [a] -> return a+    [] -> liftF $ Failed $ InvalidOutput "no data" (name <> unwords args)+    _ -> liftF $ Failed $ InvalidOutput "multiple outputs for `unsafeReadOne`" (name <> unwords args)++readFirst :: ∀ a m . (TmuxCodec a, MonadFree TmuxThunk m) => Text -> [Text] -> m (Maybe a)+readFirst name args = do+  outputs <- read name args+  return $ case outputs of+    (a : _) -> Just a+    [] -> Nothing++unsafeReadFirst :: ∀ a m . (TmuxCodec a, MonadFree TmuxThunk m) => Text -> [Text] -> m a+unsafeReadFirst name args = do+  mayFirst <- readFirst name args+  case mayFirst of+    (Just a) -> return a+    Nothing -> liftF $ Failed $ InvalidOutput "no data" (name <> unwords args)++readRaw :: ∀ m . (MonadFree TmuxThunk m) => Text -> [Text] -> m [Text]+readRaw name args =+  liftF $ Read (cmd name args) Right id++write :: MonadFree TmuxThunk m => Text -> [Text] -> m () write name args = liftF $ Write (cmd name args) id++flush :: MonadFree TmuxThunk m => m ()+flush =+  liftF $ Flush id
lib/Chiasma/Native/Api.hs view
@@ -1,15 +1,67 @@-module Chiasma.Native.Api(-  TmuxApi(..),-  TmuxNative(..),-) where+{-# LANGUAGE UndecidableInstances #-} -import Control.Monad.Trans.Except (ExceptT(ExceptT))+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.Native.Process (nativeTmuxProcess)+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 FilePath+  TmuxNative { tmuxServerSocket :: Maybe FilePath }+  deriving Show -instance TmuxApi TmuxNative where-  runCommands (TmuxNative socket) decode cmds = ExceptT $ nativeTmuxProcess socket decode cmds+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'
lib/Chiasma/Native/Parse.hs view
@@ -1,43 +1,35 @@-module Chiasma.Native.Parse(-  resultParser,-  resultLines,-) where+module Chiasma.Native.Parse where -import Text.ParserCombinators.Parsec (-  GenParser,+import qualified Data.Text as T (pack)+import Prelude hiding (many)+import Text.Parsec (   ParseError,-  parse,   many,-  skipMany,   manyTill,-  notFollowedBy,+  parse,+  skipMany,   try,   )-import Text.Parsec.Char (endOfLine, string, anyChar)+import Text.Parsec.Char (anyChar, endOfLine, string)+import Text.Parsec.Text (GenParser) -tillEol :: GenParser Char st String-tillEol = manyTill anyChar endOfLine+tillEol :: GenParser st Text+tillEol = T.pack <$> manyTill anyChar endOfLine -beginLine :: GenParser Char st String+beginLine :: GenParser st Text beginLine = string "%begin" >> tillEol -endLine :: GenParser Char st String+endLine :: GenParser st Text endLine = string "%end" >> tillEol -notBeginLine :: GenParser Char st String-notBeginLine = notFollowedBy (string "%begin") >> tillEol--parseBlock :: GenParser Char st [String]+parseBlock :: GenParser st [Text] parseBlock = do-  _ <- skipMany notBeginLine-  _ <- beginLine+  _ <- manyTill tillEol (try beginLine)   manyTill tillEol (try endLine) -resultParser :: GenParser Char st [[String]]-resultParser = do-  result <- many (try parseBlock)-  skipMany tillEol-  return result+resultParser :: GenParser st [[Text]]+resultParser =+  many (try parseBlock) <* skipMany tillEol -resultLines :: String -> Either ParseError [[String]]+resultLines :: Text -> Either ParseError [[Text]] resultLines = parse resultParser "tmux output"
lib/Chiasma/Native/Process.hs view
@@ -1,45 +1,57 @@-module Chiasma.Native.Process(-  tmuxProcessConfig,-  nativeTmuxProcess,-) where+module Chiasma.Native.Process where -import GHC.IO.Exception (ExitCode(ExitSuccess))-import Control.Monad.IO.Class (MonadIO)-import Data.ByteString.Lazy (ByteString)-import Data.ByteString.Lazy.Internal (packChars, unpackChars)-import Data.Either.Combinators (mapLeft)-import Data.List (intercalate)-import System.Process.Typed (ProcessConfig, readProcessStdout, proc, setStdin, byteStringInput)+import qualified Data.ByteString.Lazy as Lazy (ByteString)+import Data.ByteString.Lazy.Internal (unpackChars)+import qualified Data.Text as Text (intercalate, lines, pack, unwords)+import System.Exit (ExitCode(ExitSuccess))+import System.Process.Typed (ProcessConfig, byteStringInput, proc, readProcessStdout, setStdin)+ import Chiasma.Codec.Decode (TmuxDecodeError)-import Chiasma.Data.TmuxThunk (CmdName(..), Cmd(..), CmdArgs(..), Cmds(..), TmuxError(..))-import qualified Chiasma.Data.TmuxThunk as TmuxError (-  TmuxError(OutputParsingFailed, NoOutput, ProcessFailed, DecodingFailed)+import Chiasma.Data.Cmd (Cmd(..), CmdArgs(..), CmdName(..), Cmds(..))+import Chiasma.Data.TmuxError (TmuxError)+import qualified Chiasma.Data.TmuxError as TmuxError (+  TmuxError(OutputParsingFailed, NoOutput, ProcessFailed, DecodingFailed),   ) import Chiasma.Native.Parse (resultLines) -cmdBytes :: [String] -> ByteString-cmdBytes cmds = packChars $ intercalate "\n" $ reverse $ "" : cmds+cmdBytes :: [Text] -> Lazy.ByteString+cmdBytes cmds = encodeUtf8 $ Text.intercalate "\n" $ reverse $ "" : cmds -tmuxProcessConfig :: FilePath -> [String] -> ProcessConfig () () ()+socketArg :: Maybe FilePath -> [Text]+socketArg (Just socket) = ["-S", toText socket]+socketArg Nothing = []++tmuxProcessConfig :: Maybe FilePath -> [Text] -> ProcessConfig () () () tmuxProcessConfig socket cmds =-  setStdin (byteStringInput $ cmdBytes cmds) $ proc "tmux" ["-S", socket, "-C", "attach"]+  cons args+  where+  cons =+    setStdin (byteStringInput $ cmdBytes cmds) . proc "tmux"+  args =+    toString <$> (socketArg socket <> ["-C", "attach"]) -handleProcessOutput :: Cmds -> ExitCode -> ([String] -> Either TmuxDecodeError a) -> String -> Either TmuxError [a]+handleProcessOutput :: Cmds -> ExitCode -> (Text -> Either TmuxDecodeError a) -> Text -> Either TmuxError [a] handleProcessOutput cmds ExitSuccess decode out = do-  outputs <- mapLeft (TmuxError.OutputParsingFailed cmds (lines out)) $ resultLines out+  outputs <- mapLeft (TmuxError.OutputParsingFailed cmds (Text.lines out)) $ resultLines out   case reverse outputs of     output : _ -> traverse decode' output     _ -> Left $ TmuxError.NoOutput cmds   where-    decode' = mapLeft (TmuxError.DecodingFailed cmds out) . decode . words+    decode' = mapLeft (TmuxError.DecodingFailed cmds out) . decode handleProcessOutput cmds _ _ out =   Left $ TmuxError.ProcessFailed cmds out -formatCmd :: Cmd -> String-formatCmd (Cmd (CmdName name) (CmdArgs args)) = unwords $ name : args+formatCmd :: Cmd -> Text+formatCmd (Cmd (CmdName name) (CmdArgs args)) =+  Text.unwords $ name : args -nativeTmuxProcess :: MonadIO m => FilePath -> ([String] -> Either TmuxDecodeError a) -> Cmds -> m (Either TmuxError [a])+nativeTmuxProcess ::+  (MonadIO m, MonadDeepError e TmuxError m) =>+  Maybe FilePath ->+  (Text -> Either TmuxDecodeError a) ->+  Cmds ->+  m [a] nativeTmuxProcess socket decode cmds@(Cmds cmds') = do   let cmdLines = fmap formatCmd cmds'   (code, out) <- readProcessStdout $ tmuxProcessConfig socket cmdLines-  return $ handleProcessOutput cmds code decode $ unpackChars out+  hoistEither $ handleProcessOutput cmds code decode $ Text.pack $ unpackChars out
+ lib/Chiasma/Native/StreamParse.hs view
@@ -0,0 +1,65 @@+module Chiasma.Native.StreamParse(+  parseConduit,+  parseBlocks,+  TmuxOutputBlock(..),+) where++import Conduit (ConduitT, mapC, (.|))+import Control.Monad.Catch (MonadThrow)+import Data.Attoparsec.ByteString (Parser)+import Data.Conduit.Attoparsec (conduitParser)+import qualified Data.Text as T (pack)+import Text.Parser.Char (CharParsing, anyChar, newline, string)+import Text.Parser.Combinators (choice, manyTill, notFollowedBy, skipMany, try)+import Text.Parser.LookAhead (LookAheadParsing, lookAhead)++data End =+  EndSuccess+  |+  EndError+  deriving (Eq, Show)++data TmuxOutputBlock =+  Success [Text]+  |+  Error [Text]+  deriving (Eq, Show)++tillEol :: (Alternative m, CharParsing m) => m Text+tillEol = T.pack <$> manyTill anyChar newline++beginLine :: (Alternative m, CharParsing m, Monad m) => m ()+beginLine = void $ string "%begin" >> tillEol++endLine :: (Alternative m, CharParsing m) => m End+endLine = do+  end <- choice [EndSuccess <$ string "%end", EndError <$ string "%error"]+  _ <- tillEol+  return end++notBeginLine :: (Alternative m, CharParsing m, Monad m) => m ()+notBeginLine = void $ notFollowedBy (string "%begin") >> tillEol++-- |Parse a sequence of lines between a %start and a %end line.+-- Tmux pads output lines with a single space on both sides, so strip those if the leading one is present.+parseBlock :: (Alternative m, CharParsing m, Monad m, LookAheadParsing m) => m TmuxOutputBlock+parseBlock = do+  _ <- skipMany notBeginLine+  _ <- beginLine+  dataLines <- manyTill tillEol $ try $ lookAhead endLine+  end <- endLine+  return $ case end of+    EndSuccess -> Success dataLines+    EndError -> Error dataLines++parseBlocks :: (Alternative m, CharParsing m, Monad m, LookAheadParsing m) => m [TmuxOutputBlock]+parseBlocks = do+  result <- many (try parseBlock)+  skipMany tillEol+  return result++parser :: Parser TmuxOutputBlock+parser = parseBlock++parseConduit :: MonadThrow m => ConduitT ByteString TmuxOutputBlock m ()+parseConduit = conduitParser parser .| mapC snd
+ lib/Chiasma/Pack.hs view
@@ -0,0 +1,109 @@+module Chiasma.Pack where++import qualified Chiasma.Codec.Data as Codec (Window(Window))+import Chiasma.Command.Pane (movePane, resizePane)+import Chiasma.Data.TmuxId (PaneId)+import Chiasma.Data.TmuxThunk (TmuxThunk)+import Chiasma.Data.Views (Views)+import Chiasma.Data.WindowState (WindowState(..))+import Chiasma.Ui.Data.Measure (MLayout(..), MPane(..), MeasureTree, MeasureTreeSub, Measured(Measured))+import Chiasma.Ui.Data.Tree (Node(Sub, Leaf), Tree(Tree))+import qualified Chiasma.Ui.Data.Tree as Tree (subTree)+import Chiasma.Ui.Measure (measureTree)+import Chiasma.View (viewsLog)+import Control.Lens (each, mapMOf_)+import Control.Monad.Free.Class (MonadFree)+import qualified Data.List.NonEmpty as NonEmpty (reverse, toList)+import qualified Data.Set as Set (fromList, size)+import Data.Text.Prettyprint.Doc (Doc, line, pretty, (<+>))++packPane ::+  (MonadDeepState s Views m, MonadFree TmuxThunk m) =>+  PaneId ->+  Bool ->+  PaneId ->+  m ()+packPane refId vertical paneId =+  when (paneId /= refId) $ movePane paneId refId vertical++positionView ::+  (MonadDeepState s Views m, MonadFree TmuxThunk m) =>+  Bool ->+  PaneId ->+  MeasureTreeSub ->+  m ()+positionView vertical refId =+  position+  where+    position (Sub (Tree (Measured _ (MLayout layoutRef _ _ _)) _)) =+      packPane refId vertical layoutRef+    position (Leaf (Measured _ (MPane paneId _ _))) =+      packPane refId vertical paneId++describeVertical :: Bool -> Doc a+describeVertical True = "vertically"+describeVertical False = "horizontally"++resizeView ::+  MonadDeepState s Views m =>+  MonadFree TmuxThunk m =>+  Bool ->+  MeasureTreeSub ->+  m ()+resizeView vertical (Sub (Tree (Measured size (MLayout refId _ _ _)) _)) = do+  viewsLog $ "resizing layout with ref" <+> pretty refId <+> "to" <+> pretty size <+> describeVertical vertical+  resizePane refId vertical size+resizeView vertical (Leaf (Measured size (MPane paneId _ _))) = do+  viewsLog $ "resizing pane" <+> pretty paneId <+> "to" <+> pretty size <+> describeVertical vertical+  resizePane paneId vertical size++needPositioning ::+  NonEmpty MeasureTreeSub ->+  Bool+needPositioning sub =+  wrongOrder || wrongDirection || unaligned+  where+    wrongOrder =+      sort positions /= positions+    wrongDirection =+      Set.size (Set.fromList positions) /= length positions+    unaligned =+      length sub > 1 && Set.size (Set.fromList offPositions) > 1+    positions =+      NonEmpty.toList $ position <$> sub+    position (Sub (Tree (Measured _ (MLayout _ mainPos _ _)) _)) =+      mainPos+    position (Leaf (Measured _ (MPane _ mainPos _))) =+      mainPos+    offPositions =+      NonEmpty.toList $ offPosition <$> sub+    offPosition (Sub (Tree (Measured _ (MLayout _ _ offPos _)) _)) =+      offPos+    offPosition (Leaf (Measured _ (MPane _ _ offPos))) =+      offPos++packTree ::+  (MonadDeepState s Views m, MonadFree TmuxThunk m) =>+  MeasureTree ->+  m ()+packTree =+  pack+  where+    pack (Tree (Measured _ (MLayout ref _ _ vertical)) sub) = do+      when needPos runPos+      mapMOf_ (each . Tree.subTree) pack sub+      traverse_ (resizeView vertical) sub+      where+        needPos = needPositioning sub+        runPos = do+          viewsLog $ "repositioning views" <+> pretty sub+          traverse_ (positionView vertical ref) (NonEmpty.reverse sub)++packWindow ::+  (MonadDeepState s Views m, MonadFree TmuxThunk m) =>+  WindowState ->+  m ()+packWindow (WindowState (Codec.Window _ width height) _ _ tree _) = do+  let measures = measureTree tree width height+  viewsLog $ "measured tree:" <> line <> pretty measures+  packTree measures
+ lib/Chiasma/Pane.hs view
@@ -0,0 +1,14 @@+module Chiasma.Pane where++import Chiasma.Data.Ident (Ident)+import Chiasma.Data.TmuxId (PaneId)+import qualified Chiasma.Data.View as Tmux (View(View))+import Chiasma.Data.Views (Views)+import qualified Chiasma.View as Views (insertPane)++addPane :: MonadDeepState s Views m => Ident -> m (Tmux.View PaneId)+addPane ident = do+  modify $ Views.insertPane pane+  return pane+  where+    pane = Tmux.View ident Nothing
+ lib/Chiasma/Prelude.hs view
@@ -0,0 +1,71 @@+{-# LANGUAGE NoImplicitPrelude #-}++module Chiasma.Prelude (+  module Cornea,+  module Data.Default,+  module Data.Foldable,+  module Relude,+  dbg,+  dbgs,+  dbgm,+  makeClassy,+  mapLeft,+  tuple,+  undefined,+  unit,+  unsafeLogAnd,+  unsafeLogS,+  unsafeLogSAnd,+  (<$$>),+) where++import Control.Lens (makeClassy)+import Cornea+import Data.Default (Default(def))+import Data.Either.Combinators (mapLeft)+import Data.Foldable (foldl, traverse_)+import Data.Functor.Syntax ((<$$>))+import GHC.Err (undefined)+import GHC.IO.Unsafe (unsafePerformIO)+import Relude hiding (Type, ask, asks, get, gets, hoistEither, hoistMaybe, local, modify, put, state, undefined)++dbg :: Monad m => Text -> m ()+dbg msg = do+  () <- return $ unsafePerformIO (putStrLn (toString msg))+  return ()++dbgs :: Monad m => Show a => a -> m ()+dbgs =+  dbg . show++dbgm :: Monad m => Show a => m a -> m a+dbgm ma = do+  a <- ma+  dbgs a+  return a++unit ::+  Applicative f =>+  f ()+unit =+  pure ()++tuple ::+  Applicative f =>+  f a ->+  f b ->+  f (a, b)+tuple fa fb =+  (,) <$> fa <*> fb++unsafeLogSAnd :: Show a => a -> b -> b+unsafeLogSAnd a b =+  unsafePerformIO $ print a >> return b++unsafeLogAnd :: Text -> b -> b+unsafeLogAnd a b =+  unsafePerformIO $ putStrLn (toString a) >> return b++unsafeLogS :: Show a => a -> a+unsafeLogS a =+  unsafePerformIO $ print a >> return a
+ lib/Chiasma/Render.hs view
@@ -0,0 +1,41 @@+module Chiasma.Render where++import qualified Chiasma.Codec.Data as Codec (Window(Window))+import Chiasma.Data.Ident (Ident, identText)+import Chiasma.Data.RenderError (RenderError)+import Chiasma.Data.TmuxThunk (TmuxThunk)+import Chiasma.Data.Views (Views)+import Chiasma.Pack (packWindow)+import Chiasma.Session (ensureSession, findOrCreateSession)+import Chiasma.Ui.Data.RenderableTree (RenderableTree)+import Chiasma.Ui.Data.View (ViewTree)+import Chiasma.View (viewsLog)+import Chiasma.Window (ensureView, ensureWindow, findOrCreateWindow, windowState)+import Control.Monad.Error.Class (MonadError)+import Control.Monad.Free.Class (MonadFree)+import Data.Text.Prettyprint.Doc (line, pretty)++renderTree ::+  (MonadDeepState s Views m, MonadFree TmuxThunk m) =>+  Ident ->+  Codec.Window ->+  RenderableTree ->+  m ()+renderTree windowIdent window tree = do+  viewsLog $ pretty ("rendering tree in window " <> identText windowIdent <> ":") <> line <> pretty tree+  wState <- windowState windowIdent window tree+  packWindow wState++render ::+  (MonadDeepState s Views m, MonadFree TmuxThunk m, MonadError RenderError m) =>+  FilePath ->+  Ident ->+  Ident ->+  ViewTree ->+  m ()+render cwd sessionIdent windowIdent tree = do+  initialSession <- findOrCreateSession sessionIdent+  initialWindow <- findOrCreateWindow windowIdent+  (sid, newSessionWid) <- ensureSession initialSession initialWindow+  window@(Codec.Window windowId _ _) <- ensureWindow sid initialWindow newSessionWid tree+  traverse_ (renderTree windowIdent window) =<< ensureView cwd windowId tree
+ lib/Chiasma/Session.hs view
@@ -0,0 +1,49 @@+{-# LANGUAGE FlexibleContexts #-}++module Chiasma.Session where++import Control.Monad.Free.Class (MonadFree)++import qualified Chiasma.Codec.Data as Codec (Session(Session), Window(Window))+import Chiasma.Command.Session (existingSessionId, newSession)+import Chiasma.Command.Window (newSessionWindow)+import Chiasma.Data.Ident (Ident)+import Chiasma.Data.TmuxId (SessionId, WindowId)+import Chiasma.Data.TmuxThunk (TmuxThunk)+import qualified Chiasma.Data.View as Tmux (View(viewId, viewIdent), setViewId)+import Chiasma.Data.Views (Views)+import Chiasma.View (findOrCreateView, viewsLogS)+import qualified Chiasma.View as Views (insertSession, session, updateSession, updateWindow)++findOrCreateSession ::+  MonadDeepState s Views m =>+  Ident ->+  m (Tmux.View SessionId)+findOrCreateSession =+  findOrCreateView Views.session Views.insertSession++spawnSession ::+  MonadDeepState s Views m =>+  MonadFree TmuxThunk m =>+  Tmux.View SessionId ->+  Tmux.View WindowId ->+  m (SessionId, WindowId)+spawnSession session' window = do+  Codec.Session sid <- newSession (Tmux.viewIdent session')+  modify $ Views.updateSession $ Tmux.setViewId sid session'+  Codec.Window wid _ _ <- newSessionWindow sid+  modify $ Views.updateWindow $ Tmux.setViewId wid window+  viewsLogS $ "spawned session " <> show session' <> " with id " <> show sid <> " and window id " <> show wid+  return (sid, wid)++ensureSession ::+  MonadDeepState s Views m =>+  MonadFree TmuxThunk m =>+  Tmux.View SessionId ->+  Tmux.View WindowId ->+  m (SessionId, Maybe WindowId)+ensureSession session' window = do+  existing <- join <$> traverse existingSessionId (Tmux.viewId session')+  case existing of+    Just sid -> return (sid, Nothing)+    Nothing -> second Just <$> spawnSession session' window
lib/Chiasma/Test/File.hs view
@@ -4,15 +4,14 @@   fixture, ) where -import Control.Monad.IO.Class (liftIO, MonadIO) import System.Directory (canonicalizePath, createDirectoryIfMissing, removePathForcibly) import System.FilePath ((</>)) -testDir :: String -> IO FilePath-testDir prefix = canonicalizePath $ "test" </> prefix+testDir :: Text -> IO FilePath+testDir prefix = canonicalizePath $ "test" </> toString prefix  -- raises exception if cwd is not the package root so we don't damage anything-tempDirIO :: String -> FilePath -> IO FilePath+tempDirIO :: Text -> FilePath -> IO FilePath tempDirIO prefix path = do   base <- testDir prefix   let dir = base </> "temp"@@ -22,11 +21,11 @@   createDirectoryIfMissing True absPath   return absPath -tempDir :: MonadIO m => String -> FilePath -> m FilePath+tempDir :: MonadIO m => Text -> FilePath -> m FilePath tempDir prefix path =   liftIO $ tempDirIO prefix path -fixture :: MonadIO m => String -> FilePath -> m FilePath+fixture :: MonadIO m => Text -> FilePath -> m FilePath fixture prefix path = do   base <- liftIO $ testDir prefix   return $ base </> "fixtures" </> path
+ lib/Chiasma/Test/Screenshot.hs view
@@ -0,0 +1,67 @@+module Chiasma.Test.Screenshot where++import Control.Monad.Free.Class (MonadFree)+import qualified Data.ByteString as ByteString (writeFile)+import qualified Data.Text as Text (lines, unlines)+import qualified Data.Text.Encoding as Text (encodeUtf8)+import System.FilePath (takeDirectory, (</>))+import UnliftIO.Directory (createDirectoryIfMissing, doesFileExist)++import Chiasma.Command.Pane (capturePane)+import Chiasma.Data.TmuxId (PaneId(PaneId))+import Chiasma.Data.TmuxThunk (TmuxThunk)++loadScreenshot :: MonadIO m => FilePath -> m (Maybe Text)+loadScreenshot path =+  ifM (doesFileExist path) (Just . toText <$> liftIO (readFile path)) (pure Nothing)++storeScreenshot :: MonadIO m => FilePath -> [Text] -> m ()+storeScreenshot path text = do+  createDirectoryIfMissing True (takeDirectory path)+  liftIO $ ByteString.writeFile path (Text.encodeUtf8 . Text.unlines $ text)++takeScreenshot ::+  MonadFree TmuxThunk m =>+  MonadIO m =>+  Int ->+  m [Text]+takeScreenshot =+  capturePane . PaneId++recordScreenshot ::+  MonadFree TmuxThunk m =>+  MonadIO m =>+  FilePath ->+  Int ->+  m ()+recordScreenshot path paneId = do+  current <- takeScreenshot paneId+  storeScreenshot path current++testScreenshot ::+  MonadFree TmuxThunk m =>+  MonadIO m =>+  FilePath ->+  Int ->+  m (Maybe ([Text], [Text]))+testScreenshot path pane = do+  current <- takeScreenshot pane+  loadScreenshot path >>= check current+  where+    check current (Just existing) =+      return $ Just (current, Text.lines existing)+    check current Nothing =+      Nothing <$ storeScreenshot path current++screenshot ::+  MonadFree TmuxThunk m =>+  MonadIO m =>+  Bool ->+  FilePath ->+  Text ->+  Int ->+  m (Maybe ([Text], [Text]))+screenshot record storage name paneId =+  if record then Nothing <$ recordScreenshot path paneId else testScreenshot path paneId+  where+    path = storage </> toString name
lib/Chiasma/Test/Tmux.hs view
@@ -1,71 +1,121 @@-module Chiasma.Test.Tmux(-  withTestTmux,-  tmuxSpec,-) where+module Chiasma.Test.Tmux where -import GHC.Real (fromIntegral)-import GHC.IO.Handle (Handle)+import Chiasma.Data.TmuxError (TmuxError)+import Chiasma.Monad.Stream (runTmux)+import qualified Chiasma.Monad.Tmux as Tmux (write)+import Chiasma.Native.Api (TmuxNative(..))+import Control.Concurrent (threadDelay)+import System.Directory (doesFileExist) import System.FilePath ((</>))-import System.Posix.Pty (Pty, resizePty, createPty)-import System.Posix.Terminal (openPseudoTerminal) import System.Posix.IO (fdToHandle)-import qualified System.Posix.Signals as Signal (signalProcess, killProcess)+import System.Posix.Pty (Pty, createPty, resizePty)+import qualified System.Posix.Signals as Signal (killProcess, signalProcess)+import System.Posix.Terminal (openPseudoTerminal) import System.Process (getPid) import System.Process.Typed (-  ProcessConfig,   Process,-  withProcess,+  ProcessConfig,+  StreamSpec,   proc,+  setStderr,   setStdin,   setStdout,-  setStderr,-  useHandleClose,   unsafeProcessHandle,+  useHandleClose,+  withProcessWait,   )-import UnliftIO (finally)+import UnliftIO (finally, throwString)+import UnliftIO.Exception (tryAny) import UnliftIO.Temporary (withSystemTempDirectory)-import Chiasma.Native.Api (TmuxNative(..))+ import Chiasma.Test.File (fixture)  data Terminal = Terminal Handle Pty +data TmuxTestConf =+  TmuxTestConf {+    ttcWidth :: Int,+    ttcHeight :: Int,+    ttcFontSize :: Int,+    ttcGui :: Bool+  }+  deriving (Eq, Show)++instance Default TmuxTestConf where+  def = TmuxTestConf 240 61 18 True++usleep :: MonadIO f => Double -> f ()+usleep =+  liftIO . threadDelay . round++sleep :: MonadIO f => Double -> f ()+sleep seconds =+  usleep $ seconds * 1e6+ unsafeTerminal :: IO Terminal unsafeTerminal = do   (_, slave) <- openPseudoTerminal   mayPty <- createPty slave   handle <- fdToHandle slave-  pty <- maybe (error "couldn't spawn pty") return mayPty+  pty <- maybe (throwString "couldn't spawn pty") return mayPty   return $ Terminal handle pty -testTmuxProcessConfig :: FilePath -> FilePath -> Terminal -> IO (ProcessConfig () () ())-testTmuxProcessConfig socket confFile (Terminal handle pty) = do-  resizePty pty (1000, 1000)-  let stream = useHandleClose handle-  let stdio = setStdin stream . setStdout stream . setStderr stream-  return $ stdio $ proc "tmux" ["-S", socket, "-f", confFile]+urxvtArgs :: Int -> Int -> Int -> [Text]+urxvtArgs width height fontSize =+  ["-geometry", show width <> "x" <> show height, "-fn", "xft:monospace:size=" <> show fontSize, "-e", "tmux"] +testTmuxProcessConfig :: TmuxTestConf -> FilePath -> FilePath -> Terminal -> IO (ProcessConfig () () ())+testTmuxProcessConfig (TmuxTestConf width height fontSize gui) socket confFile (Terminal handle pty) = do+  confFileExists <- doesFileExist confFile+  resizePty pty (width, height)+  let+    stream :: StreamSpec st ()+    stream = useHandleClose handle+    stdio = setStdin stream . setStdout stream . setStderr stream+    tmuxArgs = ["-S", toText socket, "-f", toText confFileArg]+    confFileArg = if confFileExists then confFile else "/dev/null"+    prc =+      if gui+      then proc "urxvt" (toString <$> urxvtArgs width height fontSize ++ tmuxArgs)+      else proc "tmux" (toString <$> tmuxArgs)+  return $ stdio prc+ killPid :: Integral a => a -> IO () killPid =-  Signal.signalProcess Signal.killProcess . fromIntegral+  void . tryAny . Signal.signalProcess Signal.killProcess . fromIntegral -killProcess :: Process () () () -> IO ()-killProcess prc = do+killProcess :: TmuxNative -> Process () () () -> IO ()+killProcess api prc = do+  _ <- runExceptT @TmuxError $ runTmux api $ Tmux.write "kill-server" []   let handle = unsafeProcessHandle prc   mayPid <- getPid handle   maybe (return ()) killPid mayPid +-- FIXME find a way to wait for tmux deterministically instead of sleeping+-- if the first tmux control mode process from a TmuxProg runs before urxvt has started the server,+-- it will not use the test tmux.conf+-- maybe start tmux first, then urxvt? runAndKillTmux :: (TmuxNative -> IO a) -> TmuxNative -> Process () () () -> IO a-runAndKillTmux thunk api prc =-  finally (thunk api) (killProcess prc)+runAndKillTmux thunk api prc = do+  sleep 0.2+  finally (thunk api) (killProcess api prc) -withTestTmux :: (TmuxNative -> IO a) -> FilePath -> IO a-withTestTmux thunk tempDir = do+withTestTmux :: TmuxTestConf -> (TmuxNative -> IO a) -> FilePath -> IO a+withTestTmux tConf thunk tempDir = do   let socket = tempDir </> "tmux_socket"   conf <- fixture "u" "tmux.conf"   terminal <- unsafeTerminal-  pc <- testTmuxProcessConfig socket conf terminal-  withProcess pc $ runAndKillTmux thunk (TmuxNative socket)+  pc <- testTmuxProcessConfig tConf socket conf terminal+  withProcessWait pc $ runAndKillTmux thunk (TmuxNative $ Just socket) +tmuxSpec' :: TmuxTestConf -> (TmuxNative -> IO a) -> IO a+tmuxSpec' conf thunk =+  withSystemTempDirectory "chiasma-test" $ withTestTmux conf thunk+ tmuxSpec :: (TmuxNative -> IO a) -> IO a-tmuxSpec thunk =-  withSystemTempDirectory "chiasma-test" $ withTestTmux thunk+tmuxSpec =+  tmuxSpec' def { ttcGui = False }++tmuxGuiSpec :: (TmuxNative -> IO a) -> IO a+tmuxGuiSpec =+  tmuxSpec' def
+ lib/Chiasma/Ui/Data/Measure.hs view
@@ -0,0 +1,52 @@+module Chiasma.Ui.Data.Measure where++import Chiasma.Data.TmuxId (PaneId(..))+import Data.Text.Prettyprint.Doc (Pretty(..), (<+>))++import Chiasma.Ui.Data.Tree (NNode, NTree)++data MPane =+  MPane {+    _paneId :: PaneId,+    _mainPosition :: Int,+    _offPosition :: Int+  }+  deriving (Eq, Show)++makeClassy ''MPane++data MLayout =+  MLayout {+    _reference :: PaneId,+    _lMainPosition :: Int,+    _lOffPosition :: Int,+    _vertical :: Bool+  }+  deriving (Eq, Show)++makeClassy ''MLayout++data Measured a =+  Measured {+    _size :: Int,+    _view :: a+  }+  deriving (Eq, Show)++makeClassy ''Measured++type MeasureTree = NTree (Measured MLayout) (Measured MPane)+type MeasureTreeSub = NNode (Measured MLayout) (Measured MPane)++instance Pretty MLayout where+  pretty (MLayout (PaneId refId) mainPos offPos vertical') =+    "l –" <+> "ref:" <+> pretty refId <+> "pos:" <+> pretty mainPos <+> "(" <> pretty offPos <> ")" <+>+      if vertical' then "v" else "h"++instance Pretty MPane where+  pretty (MPane (PaneId paneId') mainPos offPos) =+    "p –" <+> pretty paneId' <+> "pos:" <+> pretty mainPos <+> "(" <> pretty offPos <> ")"++instance Pretty a => Pretty (Measured a) where+  pretty (Measured size' a) =+    pretty a <+> "size:" <+> pretty size'
+ lib/Chiasma/Ui/Data/RenderableTree.hs view
@@ -0,0 +1,54 @@+module Chiasma.Ui.Data.RenderableTree where++import Data.Text.Prettyprint.Doc (Doc, Pretty(..), emptyDoc, space, (<+>))++import Chiasma.Data.TmuxId (PaneId(..))+import Chiasma.Ui.Data.Tree (NNode, NTree)+import Chiasma.Ui.Data.ViewGeometry (ViewGeometry(ViewGeometry))+import Chiasma.Ui.Data.ViewState (ViewState)++data RLayout =+  RLayout {+    _ref :: RPane,+    _vertical :: Bool+  }+  deriving (Eq, Show)++data RPane =+  RPane {+    _id :: PaneId,+    _top :: Int,+    _left :: Int+  }+  deriving (Eq, Show)++data Renderable a =+  Renderable {+    _state :: ViewState,+    _geometry :: ViewGeometry,+    _view :: a+  }+  deriving (Eq, Show)++type RenderableLayout = Renderable RLayout+type RenderablePane = Renderable RPane+type RenderableTree = NTree RenderableLayout RenderablePane+type RenderableNode = NNode RenderableLayout RenderablePane++instance Pretty RLayout where+  pretty (RLayout (RPane (PaneId refId) _ _) vertical) =+    "l –" <+> "ref:" <+> pretty refId <+> "pos:" <+> if vertical then "v" else "h"++instance Pretty RPane where+  pretty (RPane (PaneId paneId) top left) =+    "p –" <+> pretty paneId <+> pretty top <+> pretty left++mayPretty :: Text -> Maybe Float -> Doc a+mayPretty prefix (Just a) =+  space <> pretty (prefix <> ":") <+> pretty a+mayPretty _ Nothing =+  emptyDoc++instance Pretty a => Pretty (Renderable a) where+  pretty (Renderable _ (ViewGeometry minSize maxSize fixedSize _ _ _) a) =+    pretty a <> mayPretty "min" minSize <> mayPretty "max" maxSize <> mayPretty "fixed" fixedSize
+ lib/Chiasma/Ui/Data/Tree.hs view
@@ -0,0 +1,45 @@+{-# LANGUAGE TemplateHaskell #-}++module Chiasma.Ui.Data.Tree where++import Data.Text.Prettyprint.Doc (Pretty(..), vsep, nest)++data Tree f l p =+  Tree {+    _treeData :: l,+    _forest :: f (Node f l p)+    }++deriving instance (Eq l, Eq p) => Eq (Tree [] l p)+deriving instance (Show l, Show p) => Show (Tree [] l p)++deriving instance (Eq l, Eq p) => Eq (Tree NonEmpty l p)+deriving instance (Show l, Show p) => Show (Tree NonEmpty l p)++data Node f l p =+  Sub { _subTree :: Tree f l p }+  |+  Leaf { _leafData :: p }++makeClassy ''Tree+makeClassy ''Node++deriving instance (Eq l, Eq p) => Eq (Node [] l p)+deriving instance (Show l, Show p) => Show (Node [] l p)++deriving instance (Eq l, Eq p) => Eq (Node NonEmpty l p)+deriving instance (Show l, Show p) => Show (Node NonEmpty l p)++type LTree l p = Tree [] l p+type LNode l p = Node [] l p++type NTree l p = Tree NonEmpty l p+type NNode l p = Node NonEmpty l p++instance (Foldable f, Pretty l, Pretty p) => Pretty (Tree f l p) where+  pretty (Tree l sub) =+    nest 2 $ vsep $ pretty l : (pretty <$> toList sub)++instance (Foldable f, Pretty l, Pretty p) => Pretty (Node f l p) where+  pretty (Sub tree') = pretty tree'+  pretty (Leaf a) = pretty a
+ lib/Chiasma/Ui/Data/TreeModError.hs view
@@ -0,0 +1,22 @@+module Chiasma.Ui.Data.TreeModError where++import Chiasma.Data.Ident (Ident)+import Chiasma.Ui.Data.View (LayoutView, PaneView)++data TreeModError =+  PaneExists PaneView+  |+  LayoutExists LayoutView+  |+  PaneMissing Ident+  |+  LayoutMissing Ident+  |+  AmbiguousPane Ident Int+  |+  AmbiguousLayout Ident Int+  |+  NoTrees+  deriving (Eq, Show)++deepPrisms ''TreeModError
+ lib/Chiasma/Ui/Data/View.hs view
@@ -0,0 +1,151 @@+module Chiasma.Ui.Data.View where++import Chiasma.Data.Ident (Ident, Identifiable(..))+import Control.Lens (Index, IxValue, Ixed(ix), makeClassy_)+import Control.Lens.Plated (Plated)+import Data.Data (Data)+import Data.Text.Prettyprint.Doc (Doc, Pretty(..), emptyDoc, nest, space, vsep, (<+>))+import Prelude hiding (state)++import Chiasma.Ui.Data.ViewGeometry (ViewGeometry)+import Chiasma.Ui.Data.ViewState (ViewState(ViewState))+import Chiasma.Ui.Lens.Ident (matchIdentP)++data Pane =+  Pane {+    _open :: Bool,+    _pin :: Bool,+    _cwd :: Maybe FilePath+  }+  deriving (Eq, Show, Data, Generic)++makeClassy ''Pane++instance Default Pane where+  def = Pane False False Nothing++newtype Layout =+  Layout {+    vertical :: Bool+  }+  deriving (Eq, Show, Data, Generic)++makeClassy_ ''Layout++instance Default Layout where+  def = Layout True++data View a =+  View {+    _ident :: Ident,+    _state :: ViewState,+    _geometry :: ViewGeometry,+    _extra :: a+  }+  deriving (Eq, Show, Data, Generic)++makeClassy ''View++instance Default a => Default (View a) where+  def = View def def def def++type PaneView = View Pane+type LayoutView = View Layout++instance Pretty Layout where+  pretty (Layout vertical) =+    if vertical then "▤" else "▥"++instance Pretty Pane where+  pretty (Pane open' pin' _) =+    (if open' then "🔓" else "🔒") <+> (if pin' then "📌" else emptyDoc)++prettyView :: Doc a -> Ident -> ViewState -> ViewGeometry -> Doc a+prettyView sym ident' (ViewState minimized) geo =+  sym <+> pretty ident' <+> "⎸" <+> (if minimized then "▂" <> space else emptyDoc) <> pretty geo++instance Pretty (View Pane) where+  pretty (View ident' st geo a) =+    prettyView "◳" ident' st geo <> pretty a++instance Pretty (View Layout) where+  pretty (View ident' st geo a) =+    prettyView (pretty a) ident' st geo++consPane :: Ident -> PaneView+consPane ident' = View ident' (ViewState False) def (Pane False False Nothing)++consLayoutAs :: Bool -> Ident -> LayoutView+consLayoutAs vert ident' = View ident' (ViewState False) def (Layout vert)++consLayout :: Ident -> LayoutView+consLayout =+  consLayoutAs False++consLayoutVertical :: Ident -> LayoutView+consLayoutVertical =+  consLayoutAs True++instance Identifiable (View a) where+  identify = _ident++-- split in two so there can be no lone leaves (panes without layout) as type 'Tree'+data Tree l p =+  Tree {+    treeData :: l,+    treeSubs :: [TreeSub l p]+    }+  deriving (Eq, Show, Data, Generic)++instance Bifunctor Tree where+  first f (Tree l sub) = Tree (f l) (fmap (first f) sub)++  second f (Tree l sub) =+    Tree l (fmap (second f) sub)++instance Bifoldable Tree where+  bifoldMap fl fr (Tree l sub) = mappend (fl l) (foldMap (bifoldMap fl fr) sub)++data TreeSub l p =+  TreeNode { _subTree :: Tree l p }+  |+  TreeLeaf { _leafData :: p }+  deriving (Eq, Show, Data, Generic)++instance Bifunctor TreeSub where+  first f (TreeNode t) = TreeNode (first f t)+  first _ (TreeLeaf p) = TreeLeaf p++  second f (TreeNode t) = TreeNode (second f t)+  second f (TreeLeaf p) = TreeLeaf (f p)++instance Bifoldable TreeSub where+  bifoldMap fl fr (TreeNode t) = bifoldMap fl fr t+  bifoldMap _ fr (TreeLeaf p) = fr p++instance (Data l, Data p) => Plated (Tree l p)++makeClassy_ ''Tree+makeClassy ''TreeSub++type ViewTree = Tree LayoutView PaneView+type ViewTreeSub = TreeSub LayoutView PaneView++instance Identifiable l => Identifiable (Tree l p) where+  identify (Tree l _) = identify l++type instance Index (Tree _ _) = Ident+type instance IxValue (Tree l p) = Tree l p++instance Identifiable l => Ixed (Tree l p) where+  ix = matchIdentP++instance (Pretty l, Pretty p) => Pretty (TreeSub l p) where+  pretty (TreeNode a) =+    pretty a+  pretty (TreeLeaf a) =+    pretty a++instance (Pretty l, Pretty p) => Pretty (Tree l p) where+  pretty (Tree l sub) =+    nest 2 . vsep $ pretty l : (pretty <$> sub)
+ lib/Chiasma/Ui/Data/ViewGeometry.hs view
@@ -0,0 +1,27 @@+{-# LANGUAGE DeriveAnyClass #-}++module Chiasma.Ui.Data.ViewGeometry where++import Data.Data (Data)+import Data.Text.Prettyprint.Doc (Doc, Pretty(..), emptyDoc, space, (<+>))++data ViewGeometry =+  ViewGeometry {+    minSize :: Maybe Float,+    maxSize :: Maybe Float,+    fixedSize :: Maybe Float,+    minimizedSize :: Maybe Float,+    weight :: Maybe Float,+    position :: Maybe Float+  }+  deriving (Eq, Show, Data, Generic, Default)++mayPretty :: Text -> Maybe Float -> Doc a+mayPretty prefix (Just a) =+  space <> pretty prefix <> ":" <+> pretty a+mayPretty _ Nothing =+  emptyDoc++instance Pretty ViewGeometry where+  pretty (ViewGeometry minSize maxSize fixedSize _ _ _) =+    foldl @[] (<>) emptyDoc (uncurry mayPretty <$> [("min", minSize), ("max", maxSize), ("fixed", fixedSize)])
+ lib/Chiasma/Ui/Data/ViewState.hs view
@@ -0,0 +1,12 @@+module Chiasma.Ui.Data.ViewState where++import Data.Data (Data)++newtype ViewState =+  ViewState {+    minimized :: Bool+  }+  deriving (Eq, Show, Data, Generic)++instance Default ViewState where+  def = ViewState False
+ lib/Chiasma/Ui/Lens/Ident.hs view
@@ -0,0 +1,23 @@+{-# LANGUAGE RankNTypes #-}++module Chiasma.Ui.Lens.Ident(+  matchIdent,+  matchIdentL,+  matchIdentP,+) where++import Control.Lens (Traversal', Prism', filtered, each, prism)+import Chiasma.Data.Ident (Ident, Identifiable(..), sameIdent)++matchIdent :: Identifiable a => Ident -> Traversal' a a+matchIdent = filtered . sameIdent++matchIdentL :: Identifiable a => Ident -> Traversal' [a] a+matchIdentL ident = each . matchIdent ident++identEither :: Identifiable a => Ident -> a -> Either a a+identEither target a =+  if sameIdent target a then Right a else Left a++matchIdentP :: Identifiable a => Ident -> Prism' a a+matchIdentP ident = prism id (identEither ident)
+ lib/Chiasma/Ui/Measure.hs view
@@ -0,0 +1,76 @@+module Chiasma.Ui.Measure where++import qualified Data.List.NonEmpty as NonEmpty (zip)+import GHC.Float (int2Float)++import Chiasma.Data.Maybe (orElse)+import Chiasma.Ui.Data.Measure (MLayout(..), MPane(..), MeasureTree, MeasureTreeSub, Measured(..))+import Chiasma.Ui.Data.RenderableTree (RLayout(..), RPane(..), Renderable(..), RenderableNode, RenderableTree)+import Chiasma.Ui.Data.Tree (Tree(..))+import qualified Chiasma.Ui.Data.Tree as Tree (Node(..))+import Chiasma.Ui.Data.ViewGeometry (ViewGeometry(minSize, maxSize, fixedSize))+import Chiasma.Ui.Data.ViewState (ViewState(ViewState))+import Chiasma.Ui.Measure.Balance (balanceSizes)+import Chiasma.Ui.Measure.Weights (viewWeights)++minimizedSizeOrDefault :: ViewGeometry -> Float+minimizedSizeOrDefault = fromMaybe 2 . minSize++effectiveFixedSize :: ViewState -> ViewGeometry -> Maybe Float+effectiveFixedSize (ViewState minimized) viewGeom =+  if minimized then Just (minimizedSizeOrDefault viewGeom) else fixedSize viewGeom++actualSize :: (ViewGeometry -> Maybe Float) ->  ViewState -> ViewGeometry -> Maybe Float+actualSize getter viewState viewGeom =+  orElse (getter viewGeom) (effectiveFixedSize viewState viewGeom)++actualMinSizes :: NonEmpty (ViewState, ViewGeometry) -> NonEmpty Float+actualMinSizes =+  fmap (fromMaybe 0.0 . uncurry (actualSize minSize))++actualMaxSizes :: NonEmpty (ViewState, ViewGeometry) -> NonEmpty (Maybe Float)+actualMaxSizes =+  fmap (uncurry $ actualSize maxSize)++isMinimized :: ViewState -> ViewGeometry -> Bool+isMinimized (ViewState minimized) _ = minimized++subMeasureData :: RenderableNode -> (ViewState, ViewGeometry)+subMeasureData (Tree.Sub (Tree (Renderable s g _) _)) = (s, g)+subMeasureData (Tree.Leaf (Renderable s g _)) = (s, g)++measureLayoutViews :: Float -> NonEmpty RenderableNode -> NonEmpty Int+measureLayoutViews total views =+  balanceSizes minSizes maxSizes weights minimized cells+  where+    measureData = fmap subMeasureData views+    paneSpacers = int2Float (length views) - 1.0+    cells = total - paneSpacers+    sizesInCells s = if s > 1 then s else s * cells+    minSizes = fmap sizesInCells (actualMinSizes measureData)+    maxSizes = fmap (fmap sizesInCells) (actualMaxSizes measureData)+    minimized = fmap (uncurry isMinimized) measureData+    weights = viewWeights measureData++measureSub :: Int -> Int -> Bool -> RenderableNode -> Int -> MeasureTreeSub+measureSub width height vertical (Tree.Sub tree) size =+  Tree.Sub $ measureLayout tree newWidth newHeight vertical+  where+    (newWidth, newHeight) = if vertical then (width, size) else (size, height)+measureSub _ _ vertical (Tree.Leaf (Renderable _ _ (RPane paneId top left))) size =+  Tree.Leaf (Measured size (MPane paneId (if vertical then top else left) (if vertical then left else top)))++measureLayout :: RenderableTree -> Int -> Int -> Bool -> MeasureTree+measureLayout (Tree (Renderable _ _ (RLayout (RPane refId refTop refLeft) vertical)) sub) width height parentVertical =+  Tree (Measured sizeInParent (MLayout refId mainPos offPos vertical)) measuredSub+  where+    sizeInParent = if parentVertical then height else width+    mainPos = if parentVertical then refTop else refLeft+    offPos = if parentVertical then refLeft else refTop+    subTotalSize = if vertical then height else width+    sizes = measureLayoutViews (int2Float subTotalSize) sub+    measuredSub = uncurry (measureSub width height vertical) <$> NonEmpty.zip sub sizes++measureTree :: RenderableTree -> Int -> Int -> MeasureTree+measureTree tree width height =+  measureLayout tree width height False
+ lib/Chiasma/Ui/Measure/Balance.hs view
@@ -0,0 +1,157 @@+module Chiasma.Ui.Measure.Balance where++import Data.List (zipWith3)+import qualified Data.List.NonEmpty as NonEmpty (+  filter,+  toList,+  zip,+  zipWith,+  )+import GHC.Float (float2Int, int2Float)+import GHC.Float.RealFracMethods (floorFloatInt)++import Chiasma.Ui.Measure.Weights (+  amendAndNormalizeWeights,+  normalizeWeights,+  )++zipWith3NE :: (a -> b -> c -> d)  ->  NonEmpty a -> NonEmpty b -> NonEmpty c -> NonEmpty d+zipWith3NE z ~(a :| as) ~(b :| bs) ~(c :| cs) =+  z a b c :| zipWith3 z as bs cs++data Balance =+  Balance {+    balanceMin :: NonEmpty Float,+    balanceMax :: NonEmpty (Maybe Float),+    balanceWeights :: NonEmpty Float,+    balanceMinimized :: NonEmpty Bool,+    balanceTotal :: Float+  }++reverseWeights :: NonEmpty Float -> NonEmpty Float+reverseWeights weights =+  if norm > 0 then fmap (/ norm) r else r+  where+    r = fmap (1 -) weights+    norm = sum r++cutSizes :: Balance -> NonEmpty Float+cutSizes (Balance min' _ weights _ total) =+  fmap addDist cut+  where+    surplus = sum min' - total+    dist = fmap (surplus *) (reverseWeights weights)+    cut = fmap (uncurry (-)) (NonEmpty.zip min' dist)+    negOrZero a = if a < 0 then a else 0+    neg = fmap negOrZero cut+    negTotal = sum neg+    negCount = length (NonEmpty.filter (< 0) neg)+    dist2 = negTotal / int2Float (length min' - negCount)+    addDist a = if a < 0 then 0 else a + dist2++distributeOnUnbounded :: Balance -> NonEmpty Float+distributeOnUnbounded (Balance min' max' weights _ total) =+  NonEmpty.zipWith addWeights initial newWeights+  where+    initial = NonEmpty.zipWith fromMaybe min' max'+    newWeights = normalizeWeights $ NonEmpty.zipWith weightOrZeroIfMax weights max'+    addWeights i w = i + (w * surplus)+    surplus = total - sum initial+    weightOrZeroIfMax w = maybe w (const 0)++weightsWithoutMinimized :: Balance -> NonEmpty Float+weightsWithoutMinimized (Balance _ _ weights minimized _) =+  normalizeWeights zeroIfMinimizedWeights+  where+    zeroIfMinimizedWeights = NonEmpty.zipWith zeroIfMinimized weights minimized+    zeroIfMinimized w m = if m then 0 else w++trimWeights :: NonEmpty Bool -> NonEmpty Float -> NonEmpty Float+trimWeights unsat withoutMinimized =+  amendAndNormalizeWeights onlyUnsat+  where+    onlyUnsat = NonEmpty.zipWith weightIfUnsat unsat withoutMinimized+    weightIfUnsat s w = if s then Just w else Nothing++distRest :: Balance -> Float -> NonEmpty Float -> NonEmpty Float -> NonEmpty Float+distRest balance rest sizes effectiveMax =+  NonEmpty.zipWith addRestWeights sizes restW+  where+    unsat = NonEmpty.zipWith (>) effectiveMax sizes+    unsatLeft = or unsat+    withoutMinimized = weightsWithoutMinimized balance+    restW =+      if unsatLeft+      then trimWeights unsat withoutMinimized+      else withoutMinimized+    addRestWeights s w = s + w * rest++saturate :: NonEmpty Float -> NonEmpty Float -> NonEmpty Float -> Float -> NonEmpty Float+saturate initial max' initialWeights total =+  loop initial initialWeights+  where+    loop current weights =+      if new == current || rest <= 0 then new else loop new newWeights+      where+        rest = total - sum current+        unsatWeights = zipWith3NE (\s m w -> if s >= m then 0 else w) current max' weights+        newWeights = normalizeWeights unsatWeights+        new = zipWith3NE (\l h w -> min (l + w * rest) h) current max' newWeights++distributeOnAll :: Balance -> NonEmpty Float+distributeOnAll balance@(Balance min' max' weights _ total) =+  if rest <= 0 then sizes else distRest balance rest sizes effectiveMax+  where+    effectiveMax = fromMaybe 1e6 <$> max'+    sizes = saturate min' effectiveMax weights total+    rest = total - sum sizes++hasUnbounded :: Balance -> Bool+hasUnbounded =+  any isNothing . balanceMax++distributeSizes :: Balance -> NonEmpty Float+distributeSizes balance =+  handler balance+  where+    handler =+      if (maxTotal < balanceTotal balance) && hasUnbounded balance+      then distributeOnUnbounded+      else distributeOnAll+    maxTotal = sum (catMaybes $ NonEmpty.toList $ balanceMax balance)++roundSizes :: NonEmpty Float -> NonEmpty Int+roundSizes (head' :| tail') =+  roundedHead + (float2Int surplus) :| roundedTail+  where+    (surplus, roundedTail) = mapAccumL folder diff0 tail'+    (roundedHead, diff0) = diff head'+    folder z a =+      (z + z1, a1)+      where+        (a1, z1) = diff a+    diff a = (floorFloatInt a, a - int2Float (floor a))++ensureMinimum2 :: NonEmpty Float -> NonEmpty Float+ensureMinimum2 sizes =+  choose <$> positives+  where+    positive = max 0+    positives = positive <$> sizes+    positivesCount = length $ NonEmpty.filter (>= 2) sizes+    unders = amountUnderTwo <$> positives+    sub = sum unders / int2Float positivesCount+    amountUnderTwo a = positive (2 - a)+    choose a = max 2 (a - sub)++rectifySizes :: NonEmpty Float -> NonEmpty Int+rectifySizes =+  roundSizes . ensureMinimum2++-- FIXME need to round manually, keeping track of the surplus, in order to achieve determinism+balanceSizes :: NonEmpty Float -> NonEmpty (Maybe Float) -> NonEmpty Float -> NonEmpty Bool -> Float -> NonEmpty Int+balanceSizes minSizes maxSizes weights minimized total =+  rectifySizes (fit balance)+  where+    fit = if sum minSizes > total then cutSizes else distributeSizes+    balance = Balance minSizes maxSizes weights minimized total
+ lib/Chiasma/Ui/Measure/Weights.hs view
@@ -0,0 +1,38 @@+module Chiasma.Ui.Measure.Weights(+  viewWeights,+  normalizeWeights,+  amendAndNormalizeWeights,+) where++import qualified Data.List.NonEmpty as NonEmpty (toList, filter)+import GHC.Float (int2Float)++import Chiasma.Ui.Data.ViewGeometry (ViewGeometry(ViewGeometry))+import Chiasma.Ui.Data.ViewState (ViewState(ViewState))++effectiveWeight :: ViewState -> ViewGeometry -> Maybe Float+effectiveWeight (ViewState minimized) (ViewGeometry _ _ fixedSize _ weight _) =+  if isJust fixedSize || minimized then Just 0 else weight++amendWeights :: NonEmpty (Maybe Float) -> NonEmpty Float+amendWeights weights =+  fmap (fromMaybe emptyWeight) weights+  where+    total = sum (catMaybes $ NonEmpty.toList weights)+    normTotal = if total == 0 then 1 else total+    empties = length (NonEmpty.filter isNothing weights)+    normEmpties = if empties == 0 then 1 else empties+    emptyWeight = normTotal / int2Float normEmpties++normalizeWeights :: NonEmpty Float -> NonEmpty Float+normalizeWeights weights =+  fmap (/ normTotal) weights+  where+    total = sum weights+    normTotal = if total == 0 then 1 else total++amendAndNormalizeWeights :: NonEmpty (Maybe Float) -> NonEmpty Float+amendAndNormalizeWeights = normalizeWeights . amendWeights++viewWeights :: NonEmpty (ViewState, ViewGeometry) -> NonEmpty Float+viewWeights = amendAndNormalizeWeights . fmap (uncurry effectiveWeight)
+ lib/Chiasma/Ui/Pane.hs view
@@ -0,0 +1,17 @@+module Chiasma.Ui.Pane(+  paneToggleOpen,+  paneSetOpen,+) where++import Chiasma.Ui.Data.View (View(View), PaneView, Pane(Pane))+import Chiasma.Ui.Data.ViewState (ViewState(ViewState))++paneToggleOpen :: PaneView -> PaneView+paneToggleOpen (View i s g (Pane False pin cwd)) =+  View i s g (Pane True pin cwd)+paneToggleOpen (View i (ViewState m) g e) =+  View i (ViewState (not m)) g e++paneSetOpen :: PaneView -> PaneView+paneSetOpen (View i s g (Pane _ pin cwd)) =+  View i s g (Pane True pin cwd)
+ lib/Chiasma/Ui/ShowTree.hs view
@@ -0,0 +1,41 @@+module Chiasma.Ui.ShowTree where++import Chiasma.Data.Ident (identText)+import Chiasma.Ui.Data.View (+  LayoutView,+  Pane(Pane),+  PaneView,+  Tree(Tree),+  TreeSub(TreeNode, TreeLeaf),+  View(View),+  ViewTree,+  )++formatLayout :: LayoutView -> Text+formatLayout (View ident _ _ _) = "l: " <> identText ident++formatPane :: PaneView -> Text+formatPane (View ident _ _ (Pane open _ _)) =+  "p: " <> identText ident <> openFrag+  where+    openFrag = " " <> if open then "open" else "closed"++formatViewTree :: ViewTree -> Tree Text Text+formatViewTree = bimap formatLayout formatPane++indent :: [Text] -> [Text]+indent = fmap (" " <>)++showTreeSub :: TreeSub Text Text -> [Text]+showTreeSub (TreeNode tree) = showTree tree+showTreeSub (TreeLeaf pane) = [pane]++showTree :: Tree Text Text -> [Text]+showTree (Tree l sub) =+  l : indent (sub >>= showTreeSub)++showViewTree :: ViewTree -> [Text]+showViewTree = showTree . formatViewTree++printViewTree :: MonadIO m => ViewTree -> m ()+printViewTree = liftIO . traverse_ putStrLn . fmap toString . showViewTree
+ lib/Chiasma/Ui/ViewTree.hs view
@@ -0,0 +1,314 @@+module Chiasma.Ui.ViewTree where++import Chiasma.Data.Ident (Ident)+import Chiasma.Lens.Tree (+  LeafIndexTree(..),+  _litTree,+  leafDataTraversal,+  )+import Control.Lens (+  Traversal,+  Traversal',+  anyOf,+  cosmos,+  filtered,+  has,+  ix,+  mapMOf,+  over,+  transformM,+  )+import Control.Monad.Error.Class (throwError)+import Control.Monad.Trans.Writer (WriterT, runWriterT, tell)+import Data.Composition ((.:))++import Chiasma.Ui.Data.TreeModError (TreeModError(PaneMissing, AmbiguousPane, LayoutMissing, AmbiguousLayout))+import Chiasma.Ui.Data.View (+  Pane(Pane),+  PaneView,+  Tree(Tree),+  TreeSub(TreeNode, TreeLeaf),+  View(View),+  ViewTree,+  ViewTreeSub,+  )+import qualified Chiasma.Ui.Data.View as Pane (open)+import qualified Chiasma.Ui.Data.View as TreeSub (leafData)+import qualified Chiasma.Ui.Data.View as View (extra)+import Chiasma.Ui.Data.ViewState (ViewState(ViewState))+import Chiasma.Ui.Pane (paneSetOpen, paneToggleOpen)++modCounted :: Monad m => (a -> m a) -> a -> WriterT (Sum Int) m a+modCounted f a = do+  tell (Sum 1)+  lift $ f a++treeToggleOpen :: ViewTree -> ViewTree+treeToggleOpen (Tree l sub) =+  Tree l (snd $ mapAccumL toggle False sub)+  where+    toggle False (TreeLeaf p) = (True, TreeLeaf (paneToggleOpen p))+    toggle a b = (a, b)++modifyTreeUniqueM :: Monad m => (ViewTree -> m ViewTree) -> Ident -> ViewTree -> ExceptT TreeModError m ViewTree+modifyTreeUniqueM f ident tree = do+  let st = (transformM $ mapMOf (ix ident) (modCounted f)) tree+  (result, Sum count) <- lift $ runWriterT st+  case count of+    1 -> return result+    0 -> throwError $ LayoutMissing ident+    n -> throwError $ AmbiguousLayout ident n++toggleLayout1 :: Ident -> ViewTree -> Either TreeModError ViewTree+toggleLayout1 ident tree =+  runIdentity $ runExceptT $ modifyTreeUniqueM (Identity . treeToggleOpen) ident tree++modifyPaneUniqueM :: Monad m => (PaneView -> m PaneView) -> Ident -> ViewTree -> ExceptT TreeModError m ViewTree+modifyPaneUniqueM f ident tree = do+  let st = (transformM $ mapMOf (ix ident) (modCounted f)) (LeafIndexTree tree)+  (result, Sum count) <- lift $ runWriterT st+  case count of+    1 -> return $ litTree result+    0 -> throwError $ PaneMissing ident+    n -> throwError $ AmbiguousPane ident n++modifyPane :: (PaneView -> PaneView) -> Ident -> ViewTree -> Either TreeModError ViewTree+modifyPane modification ident tree =+  runIdentity $ runExceptT $ modifyPaneUniqueM (Identity . modification) ident tree++openPane :: Ident -> ViewTree -> Either TreeModError ViewTree+openPane =+  modifyPane paneSetOpen++hasOpenPanes :: ViewTree -> Bool+hasOpenPanes tree =+  has (cosmos . _litTree . leafDataTraversal . filtered isOpen) (LeafIndexTree tree)+  where+    isOpen (View _ _ _ (Pane open _ _)) = open++depthTraverseTree ::+  ∀ a.+  Monoid a =>+  (a -> ViewTree -> (a, ViewTree)) ->+  (PaneView -> (a, PaneView)) ->+  ViewTree ->+  (a, ViewTree)+depthTraverseTree transformNode transformLeaf =+  recur+  where+    recur :: ViewTree -> (a, ViewTree)+    recur (Tree l sub) =+      uncurry transformNode . bimap fold (Tree l) . unzip $ (recSub <$> sub)+    recSub :: ViewTreeSub -> (a, ViewTreeSub)+    recSub (TreeNode t) =+      second TreeNode $ recur t+    recSub (TreeLeaf l) =+      second TreeLeaf $ transformLeaf l++data ToggleStatus =+  Minimized+  |+  Opened+  |+  Pristine+  |+  Multiple Int+  |+  Consistent+  deriving (Eq, Show)++instance Semigroup ToggleStatus where+  Pristine <> a = a+  a <> Pristine = a+  Multiple a <> Multiple b = Multiple (a + b)+  Multiple a <> _ = Multiple (a + 1)+  _ <> Multiple a = Multiple (a + 1)+  _ <> _ = Multiple 2++instance Monoid ToggleStatus where+  mempty = Pristine++data ToggleResult a =+  Success a+  |+  NotFound+  |+  Ambiguous Int+  deriving (Eq, Show, Functor)++instance Semigroup (ToggleResult a) where+  NotFound <> a = a+  a <> NotFound = a+  Ambiguous a <> Ambiguous b = Ambiguous (a + b)+  Ambiguous a <> _ = Ambiguous (a + 1)+  _ <> Ambiguous a = Ambiguous (a + 1)+  _ <> _ = Ambiguous 2++instance Monoid (ToggleResult a) where+  mempty = NotFound++instance Applicative ToggleResult where+  pure = Success+  (Success f) <*> fa = fmap f fa+  NotFound <*> _ = NotFound+  Ambiguous n <*> _ = Ambiguous n++instance Monad ToggleResult where+    Success a >>= f = f a+    NotFound >>= _ = NotFound+    Ambiguous n >>= _ = Ambiguous n++openPinnedSubs :: ToggleStatus -> ViewTree -> (ToggleStatus, ViewTree)+openPinnedSubs Pristine t =+  (Pristine, t)+openPinnedSubs Opened (Tree l sub) =+  (Opened, Tree l (openPinnedPane <$> sub))+  where+    openPinnedPane :: ViewTreeSub -> ViewTreeSub+    openPinnedPane (TreeLeaf (View i s g (Pane False True cwd))) =+      TreeLeaf $ View i s g (Pane True True cwd)+    openPinnedPane v =+      v+openPinnedSubs a t =+  (a, t)++checkToggleResult ::+  ToggleStatus ->+  a ->+  ToggleResult a+checkToggleResult =+  checkResult+  where+    checkResult Pristine _ = NotFound+    checkResult (Multiple n) _ = Ambiguous n+    checkResult _ result = Success result++togglePaneView :: Ident -> PaneView -> (ToggleStatus, PaneView)+togglePaneView ident (View i s g (Pane False p c)) | ident == i =+  (Opened, View i s g (Pane True p c))+togglePaneView ident (View i (ViewState minimized) g (Pane True p c)) | ident == i =+  (Minimized, View i (ViewState (not minimized)) g (Pane False p c))+togglePaneView _ v =+  (Pristine, v)++togglePaneNode :: Ident -> ViewTreeSub -> (ToggleStatus, ViewTreeSub)+togglePaneNode ident (TreeLeaf v) =+  second TreeLeaf (togglePaneView ident v)+togglePaneNode _ t =+  (Pristine, t)++togglePane :: Ident -> ViewTree -> ToggleResult ViewTree+togglePane ident =+  uncurry checkToggleResult . depthTraverseTree openPinnedSubs (togglePaneView ident)++togglePaneOpenTraversal' ::+  Traversal' a ViewTree ->+  Ident ->+  a ->+  ToggleResult a+togglePaneOpenTraversal' lens =+  mapMOf lens . togglePane++ensurePaneViewOpen :: Ident -> PaneView -> (ToggleStatus, PaneView)+ensurePaneViewOpen ident (View i s g (Pane False p c)) | ident == i =+  (Opened, View i s g (Pane True p c))+ensurePaneViewOpen ident v@(View i _ _ _) | ident == i =+  (Consistent, v)+ensurePaneViewOpen _ v =+  (Pristine, v)++ensurePaneOpen :: Ident -> ViewTree -> ToggleResult ViewTree+ensurePaneOpen ident =+  uncurry checkToggleResult . depthTraverseTree openPinnedSubs (ensurePaneViewOpen ident)++ensurePaneOpenTraversal ::+  Traversal a (ToggleResult a) ViewTree (ToggleResult ViewTree) ->+  Ident ->+  a ->+  ToggleResult a+ensurePaneOpenTraversal lens =+  over lens . ensurePaneOpen++ensurePaneOpenTraversal' ::+  Traversal' a ViewTree ->+  Ident ->+  a ->+  ToggleResult a+ensurePaneOpenTraversal' lens =+  mapMOf lens . ensurePaneOpen++skipFold ::+  Traversable t =>+  (a -> (ToggleStatus, a)) ->+  ToggleStatus ->+  t a ->+  (ToggleStatus, t a)+skipFold f =+  mapAccumL skipper+  where+    skipper Pristine a =+      f a+    skipper status a =+      (status, a)++isOpenPaneNode :: ViewTreeSub -> Bool+isOpenPaneNode =+  anyOf (TreeSub.leafData . View.extra . Pane.open) id++openPinnedPaneView :: PaneView -> (ToggleStatus, PaneView)+openPinnedPaneView (View i s g (Pane False True c)) =+  (Opened, View i s g (Pane True True c))+openPinnedPaneView v =+  (Pristine, v)++openFirstPinnedPaneNode :: ViewTreeSub -> (ToggleStatus, ViewTreeSub)+openFirstPinnedPaneNode (TreeLeaf v) =+  second TreeLeaf (openPinnedPaneView v)+openFirstPinnedPaneNode a =+  (Pristine, a)++openPaneView :: PaneView -> (ToggleStatus, PaneView)+openPaneView (View i s g (Pane False p c)) =+  (Opened, View i s g (Pane True p c))+openPaneView v =+  (Pristine, v)++openFirstPaneNode :: ViewTreeSub -> (ToggleStatus, ViewTreeSub)+openFirstPaneNode (TreeLeaf v) =+  second TreeLeaf (openPaneView v)+openFirstPaneNode a =+  (Pristine, a)++-- TODO recurse when opening pane+toggleLayoutNode :: Ident -> ToggleStatus -> ViewTree -> (ToggleStatus, ViewTree)+toggleLayoutNode ident previous (Tree v@(View i (ViewState minimized) g l) sub) | ident == i =+  first (previous <>) (if open then toggleMinimized else openPane')+  where+    open =+      any isOpenPaneNode sub+    toggleMinimized =+      (Minimized, Tree (View i (ViewState (not minimized)) g l) sub)+    openPane' =+      second (Tree v) (uncurry regularIfPristine openFirstPinned)+    openFirstPinned =+      skipFold openFirstPinnedPaneNode Pristine sub+    openFirstRegular =+      skipFold openFirstPaneNode Pristine sub+    regularIfPristine Pristine _ =+      openFirstRegular+    regularIfPristine status a =+      (status, a)+toggleLayoutNode _ a t =+  (a, t)++toggleLayout :: Ident -> ViewTree -> ToggleResult ViewTree+toggleLayout ident =+  uncurry checkToggleResult . depthTraverseTree (uncurry openPinnedSubs .: toggleLayoutNode ident) (Pristine,)++toggleLayoutOpenTraversal' ::+  Traversal' a ViewTree ->+  Ident ->+  a ->+  ToggleResult a+toggleLayoutOpenTraversal' lens =+  mapMOf lens . toggleLayout
+ lib/Chiasma/View.hs view
@@ -0,0 +1,103 @@+{-# LANGUAGE RankNTypes #-}++module Chiasma.View where++import Chiasma.Data.Ident (Ident, identText, sameIdent)+import Chiasma.Data.TmuxId (PaneId, SessionId, WindowId)+import Chiasma.Data.View (View(View), viewIdent)+import Chiasma.Data.Views (Views, ViewsError(..))+import qualified Chiasma.Data.Views as Views (log, panes, sessions, windows)+import Chiasma.Lens.Where (where1)+import Control.Lens (Lens', over)+import qualified Control.Lens as Lens (over, set, view)+import Data.Text.Prettyprint.Doc (Doc, pretty)+import Data.Text.Prettyprint.Doc.Render.Terminal (AnsiStyle)++sameId :: Eq a => a -> View a -> Bool+sameId id' (View _ (Just vid)) = id' == vid+sameId _ _ = False++view :: Lens' Views [View a] -> (Ident -> ViewsError) -> Ident -> Views -> Either ViewsError (View a)+view viewsL consError ident =+  maybeToRight (consError ident) . find (sameIdent ident) . Lens.view viewsL++viewById :: Eq a => Lens' Views [View a] -> a -> Views -> Maybe (View a)+viewById viewsL id' =+  find (sameId id') . Lens.view viewsL++insertView :: Lens' Views [View a] -> View a -> Views -> Views+insertView viewsL newView = Lens.over viewsL (newView :)++updateView :: Lens' Views [View a] -> (Ident -> ViewsError) -> View a -> Views -> Views+updateView viewsL _ newView =+  Lens.set (viewsL . where1 (sameIdent (viewIdent newView))) newView++session :: Ident -> Views -> Either ViewsError (View SessionId)+session = view Views.sessions NoSuchSession++sessionById :: SessionId -> Views -> Maybe (View SessionId)+sessionById = viewById Views.sessions++insertSession :: View SessionId -> Views -> Views+insertSession = insertView Views.sessions++updateSession :: View SessionId -> Views -> Views+updateSession = updateView Views.sessions NoSuchSession++window :: Ident -> Views -> Either ViewsError (View WindowId)+window = view Views.windows NoSuchWindow++windowById :: WindowId -> Views -> Maybe (View WindowId)+windowById = viewById Views.windows++insertWindow :: View WindowId -> Views -> Views+insertWindow = insertView Views.windows++updateWindow :: View WindowId -> Views -> Views+updateWindow = updateView Views.windows NoSuchWindow++pane :: Ident -> Views -> Either ViewsError (View PaneId)+pane = view Views.panes NoSuchPane++paneById :: PaneId -> Views -> Maybe (View PaneId)+paneById = viewById Views.panes++paneId :: Ident -> Views -> Either ViewsError PaneId+paneId paneIdent views =+  pane paneIdent views >>= trans+  where+    trans (View _ (Just paneId')) = Right paneId'+    trans _ = Left $ NoPaneId paneIdent++insertPane :: View PaneId -> Views -> Views+insertPane = insertView Views.panes++updatePane :: View PaneId -> Views -> Views+updatePane = updateView Views.panes NoSuchPane++type Getter a = Ident -> Views -> Either ViewsError (View a)+type Setter a = View a -> Views -> Views++addView :: MonadDeepState s Views m => Setter a -> Ident -> m (View a)+addView setter ident = do+  modify $ setter newView+  viewsLogS $ "added tmux view " <> identText ident+  return newView+  where+    newView = View ident Nothing++findOrCreateView :: (MonadDeepState s Views m) => Getter a -> Setter a -> Ident -> m (View a)+findOrCreateView getter setter ident = do+  existing <- gets $ getter ident+  either (const $ addView setter ident) return existing++viewsLog :: MonadDeepState s Views m => Doc AnsiStyle -> m ()+viewsLog message =+  modify f+  where+    f :: Views -> Views+    f = over Views.log (message :)++viewsLogS :: MonadDeepState s Views m => Text -> m ()+viewsLogS =+  viewsLog . pretty
+ lib/Chiasma/View/State.hs view
@@ -0,0 +1,17 @@+module Chiasma.View.State where++import Chiasma.Data.Ident (Ident)+import Chiasma.Data.TmuxId (PaneId)+import Control.Monad.DeepError (MonadDeepError, hoistEither)+import Control.Monad.DeepState (MonadDeepState, gets)++import Chiasma.Data.Views (Views, ViewsError)+import qualified Chiasma.View as Views (paneId)++paneId ::+  (MonadDeepState s Views m, MonadDeepError e ViewsError m) =>+  Ident ->+  m PaneId+paneId paneIdent = do+  pid <- gets $ Views.paneId paneIdent+  hoistEither pid
+ lib/Chiasma/Window.hs view
@@ -0,0 +1,225 @@+module Chiasma.Window where++import qualified Chiasma.Codec.Data as Codec (Pane(Pane, paneId), Window(Window, windowId))+import qualified Chiasma.Codec.Data.PaneDetail as Codec (PaneDetail(PaneDetail))+import qualified Chiasma.Codec.Data.PaneDetail as PaneDetail (PaneDetail(..))+import qualified Chiasma.Command.Pane as Cmd (closePane, firstWindowPane, windowPanesAs)+import qualified Chiasma.Command.Window as Cmd (newWindow, splitWindowAs, window)+import Chiasma.Data.Ident (Ident, identText, identify)+import Chiasma.Data.Maybe (findMaybe, maybeExcept, orElse)+import Chiasma.Data.RenderError (RenderError)+import qualified Chiasma.Data.RenderError as RenderError (RenderError(NoPrincipal))+import Chiasma.Data.TmuxId (PaneId, SessionId, WindowId)+import Chiasma.Data.TmuxThunk (TmuxThunk)+import qualified Chiasma.Data.View as Tmux (View(View))+import Chiasma.Data.Views (Views)+import Chiasma.Data.WindowState (WindowState(..))+import Chiasma.Pane (addPane)+import Chiasma.Ui.Data.RenderableTree (+  RLayout(..),+  RPane(..),+  Renderable(..),+  RenderableNode,+  RenderableTree,+  )+import qualified Chiasma.Ui.Data.Tree as Tree (Node(Sub, Leaf), Tree(Tree))+import Chiasma.Ui.Data.View (Tree(..), TreeSub(..), ViewTree, ViewTreeSub)+import qualified Chiasma.Ui.Data.View as Ui (Layout(..), Pane(Pane), PaneView, View(View))+import Chiasma.Ui.Data.ViewGeometry (ViewGeometry(ViewGeometry, position))+import Chiasma.Ui.Data.ViewState (ViewState)+import Chiasma.View (findOrCreateView, viewsLog, viewsLogS)+import qualified Chiasma.View as Views (insertPane, insertWindow, pane, paneById, updatePane, updateWindow, window)+import Control.Monad.Error.Class (MonadError)+import Control.Monad.Free.Class (MonadFree)+import qualified Data.List.NonEmpty as NonEmpty (head, nonEmpty)+import Data.Text.Prettyprint.Doc (line, pretty, vsep, (<+>))++findOrCreateWindow ::+  (MonadDeepState s Views m) =>+  Ident ->+  m (Tmux.View WindowId)+findOrCreateWindow =+  findOrCreateView Views.window Views.insertWindow++registerWindowId ::+  (MonadDeepState s Views m) =>+  Ident ->+  WindowId ->+  m ()+registerWindowId ident windowId =+  modify $ Views.updateWindow $ Tmux.View ident (Just windowId)++spawnWindow ::+  (MonadDeepState s Views m, MonadFree TmuxThunk m) =>+  SessionId ->+  Ident ->+  m Codec.Window+spawnWindow sid ident = do+  win@(Codec.Window windowId _ _) <- Cmd.newWindow sid ident+  registerWindowId ident windowId+  viewsLogS $ "spawned window in session " <> show sid <> " with id " <> show windowId+  return win++findPrincipalSub :: ViewTreeSub -> Maybe Ui.PaneView+findPrincipalSub (TreeNode t) = findPrincipal t+findPrincipalSub (TreeLeaf p@(Ui.View _ _ _ (Ui.Pane True _ _))) = Just p+findPrincipalSub _ = Nothing++findPrincipal :: ViewTree -> Maybe Ui.PaneView+findPrincipal (Tree _ sub) =+  findMaybe findPrincipalSub sub++principalPane ::+  (MonadDeepState s Views m, MonadError RenderError m) =>+  ViewTree ->+  m (Ui.PaneView, Tmux.View PaneId)+principalPane tree = do+  uiPane@(Ui.View uiPaneIdent _ _ _) <- maybeExcept (RenderError.NoPrincipal $ identify tree) $ findPrincipal tree+  existingTmuxPane <- gets $ Views.pane uiPaneIdent+  tmuxPane <- either (const $ addPane uiPaneIdent) return existingTmuxPane+  return (uiPane, tmuxPane)++syncPrincipal ::+  (MonadDeepState s Views m, MonadFree TmuxThunk m, MonadError RenderError m) =>+  WindowId ->+  ViewTree ->+  m ()+syncPrincipal windowId tree@(Tree (Ui.View layoutIdent _ _ _) _) = do+  (Codec.Pane paneId _ _) <- Cmd.firstWindowPane windowId+  existing <- gets (Views.paneById paneId)+  case existing of+    Nothing -> do+      (_, Tmux.View paneIdent _) <- principalPane tree+      viewsLog $ "setting principal of layout" <+> pretty layoutIdent <+> " to pane " <+> pretty paneIdent <+> "/" <+>+        pretty paneId+      modify $ Views.updatePane (Tmux.View paneIdent (Just paneId))+    _ -> return ()++ensureWindow ::+  (MonadDeepState s Views m, MonadFree TmuxThunk m, MonadError RenderError m) =>+  SessionId ->+  Tmux.View WindowId ->+  Maybe WindowId ->+  ViewTree ->+  m Codec.Window+ensureWindow sid (Tmux.View ident mayWid) newSessionWid tree = do+  preexisting <- join <$> traverse Cmd.window (orElse newSessionWid mayWid)+  window <- maybe (spawnWindow sid ident) return preexisting+  syncPrincipal (Codec.windowId window) tree+  return window++findOrCreatePane :: MonadDeepState s Views m => Ident -> m (Tmux.View PaneId)+findOrCreatePane =+  findOrCreateView Views.pane Views.insertPane++nativePane ::+  MonadFree TmuxThunk m =>+  WindowId ->+  Tmux.View PaneId ->+  m (Maybe Codec.PaneDetail)+nativePane windowId (Tmux.View _ (Just paneId)) =+  find sameId <$> Cmd.windowPanesAs windowId+  where+    sameId (Codec.PaneDetail i _ _ _ _) = i == paneId+nativePane _ _ = return Nothing++openPane ::+  (MonadDeepState s Views m, MonadFree TmuxThunk m) =>+  FilePath ->+  WindowId ->+  m Codec.PaneDetail+openPane dir windowId = do+  detail <- Cmd.splitWindowAs dir windowId+  viewsLogS $ "opened pane " <> show (PaneDetail.paneId detail) <> " in window " <> show windowId+  return detail++ensurePaneOpen ::+  (MonadDeepState s Views m, MonadFree TmuxThunk m) =>+  FilePath ->+  Maybe Codec.PaneDetail ->+  WindowId ->+  m Codec.PaneDetail+ensurePaneOpen _ (Just detail) _ =+  return detail+ensurePaneOpen dir Nothing windowId =+  openPane dir windowId++ensurePaneClosed ::+  (MonadDeepState s Views m, MonadFree TmuxThunk m) =>+  Maybe Codec.PaneDetail ->+  m ()+ensurePaneClosed (Just (Codec.PaneDetail i _ _ _ _)) = do+  viewsLogS $ "closing pane " <> show i+  Cmd.closePane i+ensurePaneClosed _ = return ()++ensurePane ::+  (MonadDeepState s Views m, MonadFree TmuxThunk m) =>+  FilePath ->+  WindowId ->+  Ui.PaneView ->+  m (Maybe RenderableNode)+ensurePane cwd windowId (Ui.View paneIdent vState geometry (Ui.Pane open _ customDir)) = do+  tmuxPane <- findOrCreatePane paneIdent+  existingPane <- nativePane windowId tmuxPane+  updatedPane <-+    if open then Just <$> ensurePaneOpen dir existingPane windowId+    else Nothing <$ ensurePaneClosed existingPane+  modify $ Views.updatePane (Tmux.View paneIdent (PaneDetail.paneId <$> updatedPane))+  return $ cons <$> updatedPane+  where+    dir = fromMaybe cwd customDir+    cons (Codec.PaneDetail i _ _ top left) =+      Tree.Leaf . Renderable vState geometry $ RPane i top left++refPane :: RenderableNode -> RPane+refPane (Tree.Sub (Tree.Tree (Renderable _ _ (RLayout ref _)) _)) = ref+refPane (Tree.Leaf (Renderable _ _ pane)) = pane++renderableTree ::+  ViewState ->+  ViewGeometry ->+  Bool ->+  [RenderableNode] ->+  Maybe RenderableTree+renderableTree vState geometry vertical sub = do+  sub' <- NonEmpty.nonEmpty sub+  return $ Tree.Tree (Renderable vState geometry (RLayout (refPane $ NonEmpty.head sub') vertical)) sub'++viewPosition :: ViewTreeSub -> Float+viewPosition (TreeNode (Tree (Ui.View _ _ ViewGeometry { position = pos } _) _)) =+  fromMaybe 0.5 pos+viewPosition (TreeLeaf (Ui.View _ _ ViewGeometry { position = pos } _)) =+  fromMaybe 0.5 pos++ensureView ::+  (MonadDeepState s Views m, MonadFree TmuxThunk m) =>+  FilePath ->+  WindowId ->+  ViewTree ->+  m (Maybe RenderableTree)+ensureView cwd windowId =+  ensureTree+  where+    ensureTree (Tree (Ui.View layoutIdent vState geometry (Ui.Layout vertical)) sub) = do+      ensuredSub <- traverse ensureNode sortedSub+      viewsLog $ pretty ("new sub for layout `" <> identText layoutIdent <> "`:") <> line <>+        vsep (pretty <$> ensuredSub)+      return $ renderableTree vState geometry vertical $ catMaybes ensuredSub+      where+        sortedSub = sortOn viewPosition sub+    ensureNode (TreeNode t) = do+      newTree <- ensureTree t+      return $ Tree.Sub <$> newTree+    ensureNode (TreeLeaf v) =+      ensurePane cwd windowId v++windowState ::+  (MonadDeepState s Views m, MonadFree TmuxThunk m) =>+  Ident ->+  Codec.Window ->+  RenderableTree ->+  m WindowState+windowState windowIdent window tree = do+  nativeRef <- Cmd.firstWindowPane (Codec.windowId window)+  return $ WindowState window nativeRef windowIdent tree (Codec.paneId nativeRef)
+ lib/Prelude.hs view
@@ -0,0 +1,5 @@+module Prelude (+  module Chiasma.Prelude,+) where++import Chiasma.Prelude
+ readme.md view
@@ -0,0 +1,3 @@+# Intro++**chiasma** is a tmux api client for Haskell.
+ test/Chiasma/Test/CodecTest.hs view
@@ -0,0 +1,24 @@+module Chiasma.Test.CodecTest where++import Chiasma.Codec (TmuxCodec(decode, query), TmuxQuery(TmuxQuery))+import Chiasma.Data.TmuxId (PaneId(..), WindowId(..))+import Hedgehog ((===))++import Chiasma.Test.Util (UnitTest)++data Dat =+  Dat {+    paneId :: PaneId,+    windowId :: WindowId+  }+  deriving (Eq, Show, Generic)++instance TmuxCodec Dat++test_decode :: UnitTest+test_decode =+  Right (Dat (PaneId 1) (WindowId 2)) === decode " %1 @2 "++test_query :: UnitTest+test_query =+  TmuxQuery "#{pane_id} #{window_id}" === query @Dat
+ test/Chiasma/Test/LensTest.hs view
@@ -0,0 +1,102 @@+module Chiasma.Test.LensTest where++import Chiasma.Data.Ident (Ident(Str))+import Chiasma.Lens.Tree (leafByIdent, modifyLeafByIdent, treesAndSubs)+import Chiasma.Ui.Data.View (+  Pane(Pane),+  PaneView,+  Tree(Tree),+  TreeSub(TreeNode, TreeLeaf),+  View(View),+  ViewTree,+  ViewTreeSub,+  consLayout,+  consPane,+  )+import qualified Chiasma.Ui.Data.View as View (_ident, ident)+import Chiasma.Ui.Data.ViewState (ViewState(ViewState))+import Chiasma.Ui.ViewTree (togglePane)+import qualified Chiasma.Ui.ViewTree as ToggleResult (ToggleResult(..))+import Control.Lens (transformM)+import qualified Control.Lens as Lens (set)+import Hedgehog ((===))+import Test.Tasty (TestTree, testGroup)+import Chiasma.Test.Util (UnitTest, unitTest)++id0, id1, id2, id3, id4 :: Ident+id0 = Str "0"+id1 = Str "1"+id2 = Str "2"+id3 = Str "3"+id4 = Str "4"++tree :: ViewTree+tree =+  Tree (consLayout id0) [subtree, TreeLeaf (consPane id2)]+  where+    subtree = st id2 subtree2+    subtree2 = st id3 subtree3+    subtree3 = st id4 (TreeLeaf openPane)+    openPane = View id1 (ViewState False) def (Pane True False Nothing)+    st i s =+      TreeNode $ Tree (consLayout i) [s]++test_modify :: UnitTest+test_modify = do+  let+    ident = Str "changed"+    modded = modifyLeafByIdent id1 (Lens.set View.ident ident) tree+  Nothing === leafByIdent ident tree+  Just ident === (View._ident <$> leafByIdent ident modded)++failOnPaneIdent :: Ident -> ViewTree -> Maybe ViewTree+failOnPaneIdent target t@(Tree _ sub) =+  t <$ traverse match sub+  where+    match (TreeLeaf (View i _ _ _)) = if target == i then Nothing else Just ()+    match _ = Just ()++test_monadicModify :: UnitTest+test_monadicModify = do+  Nothing === (transformM (failOnPaneIdent id2) tree)+  Just tree === (transformM (failOnPaneIdent id4) tree)++insertPane :: Ident -> PaneView -> ViewTree -> ViewTree+insertPane targetLayout pane (Tree l sub) =+  if View._ident l == targetLayout then Tree l (TreeLeaf pane : sub) else Tree l sub++ensurePaneUnique :: Ident -> ViewTreeSub -> Maybe ViewTreeSub+ensurePaneUnique paneIdent (TreeLeaf (View ident _ _ _)) | ident == paneIdent = Nothing+ensurePaneUnique _ n = Just n++subtreesTarget :: ViewTree+subtreesTarget =+  Tree (consLayout id0) [subtree, TreeLeaf (consPane id2)]+  where+    subtree = TreeNode $ Tree (consLayout id2) [TreeLeaf $ consPane id4, subtree2]+    subtree2 = TreeNode $ Tree (consLayout id3) [subtree3]+    subtree3 = TreeNode $ Tree (consLayout id4) [TreeLeaf openPane]+    openPane = View id1 (ViewState False) def (Pane True False Nothing)++test_subtrees :: UnitTest+test_subtrees =+  Just subtreesTarget === treesAndSubs (Just . insertPane id2 (consPane id4)) (ensurePaneUnique id4) tree++togglePaneTree :: ViewTree+togglePaneTree =+  Tree (consLayout id0) [TreeLeaf (consPane id0), TreeLeaf (consPane id0), TreeLeaf (consPane id2)]++test_togglePane :: UnitTest+test_togglePane = do+  ToggleResult.Ambiguous 2 === togglePane id0 togglePaneTree+  ToggleResult.NotFound === togglePane id1 togglePaneTree+  ToggleResult.Success (1 :: Int) === (1 <$ togglePane id2 togglePaneTree)++test_lenses :: TestTree+test_lenses =+  testGroup "lenses" [+    unitTest "modify leaves by ident" test_modify,+    unitTest "monadically transform leaves" test_monadicModify,+    unitTest "traverse all subtrees" test_subtrees,+    unitTest "toggle a pane" test_togglePane+  ]
+ test/Chiasma/Test/OutputParseTest.hs view
@@ -0,0 +1,29 @@+module Chiasma.Test.OutputParseTest where++import Chiasma.Native.Parse (resultLines)+import qualified Data.Text as T (unlines)+import Hedgehog ((===))++import Chiasma.Test.Util (UnitTest)++paneLine :: Text+paneLine = "%0 100 100"++tmuxOutput :: Text+tmuxOutput = T.unlines [+  "%begin 123",+  "%end 123",+  "%session-changed $0 0",+  "%begin 234",+  paneLine,+  "b",+  "%end 234",+  "%begin 345",+  "c",+  "d",+  "%end 345"+  ]++test_outputParse :: UnitTest+test_outputParse =+  Right [[], [paneLine, "b"], ["c", "d"]] === resultLines tmuxOutput
+ test/Chiasma/Test/PinTest.hs view
@@ -0,0 +1,98 @@+module Chiasma.Test.PinTest where++import Chiasma.Data.Ident (Ident(Str))+import Chiasma.Ui.Data.View (+  Pane(Pane),+  Tree(Tree),+  TreeSub(TreeNode, TreeLeaf),+  View(View),+  ViewTree,+  ViewTreeSub,+  consLayout,+  )+import Chiasma.Ui.ViewTree (toggleLayout, togglePane)+import qualified Chiasma.Ui.ViewTree as ToggleResult (ToggleResult(..))+import Hedgehog ((===))+import Test.Tasty (TestTree, testGroup)++import Chiasma.Test.Util (UnitTest, unitTest)++node :: ViewTreeSub -> View Pane -> ViewTreeSub+node sub p =+  TreeNode $ Tree (consLayout "l") [sub, TreeLeaf p]++paneWith :: Bool -> Text -> ViewTreeSub+paneWith open i = TreeLeaf $ View (Str i) def def (Pane open False Nothing)++pane :: Text -> ViewTreeSub+pane =+  paneWith False++ppaneWithIdent :: Text -> Bool -> View Pane+ppaneWithIdent name open =+  View (Str name) def def (Pane open True Nothing)++ppaneWith :: Bool -> View Pane+ppaneWith =+  ppaneWithIdent "pin"++ppane :: View Pane+ppane =+  ppaneWith False++subtree4 :: ViewTreeSub+subtree4 = node subtree5 ppane++subtree5 :: ViewTreeSub+subtree5 = node subtree6 ppane++subtree6 :: ViewTreeSub+subtree6 = TreeNode $ Tree (consLayout (Str "l")) [pane "p2"]++tree :: ViewTree+tree =+  Tree (consLayout (Str "root")) [subtree4, subtree1, subtree4]+  where+    subtree1 = node subtree2 ppane+    subtree2 = node subtree3 ppane+    subtree3 = TreeNode $ Tree (consLayout (Str "l1")) [pane "p1"]++target :: ViewTree+target =+  Tree (consLayout (Str "root")) [subtree4, subtree1, subtree4]+  where+    subtree1 = node subtree2 (ppaneWith True)+    subtree2 = node subtree3 (ppaneWith True)+    subtree3 = TreeNode $ Tree (consLayout (Str "l1")) [TreeLeaf $ View (Str "p1") def def (Pane True False Nothing)]++test_pinOpenNonpinned :: UnitTest+test_pinOpenNonpinned =+  ToggleResult.Success target === togglePane (Str "p1") tree++test_layoutPinOpenNonpinned :: UnitTest+test_layoutPinOpenNonpinned =+  ToggleResult.Success target === toggleLayout (Str "l1") tree++pinnedTree :: ViewTree+pinnedTree =+  Tree (consLayout (Str "root")) [pane "left", subtree]+  where+    subtree = TreeNode $ Tree (consLayout (Str "l1")) [pane "p2", TreeLeaf $ ppaneWithIdent "p1" False]++pinnedTarget :: ViewTree+pinnedTarget =+  Tree (consLayout (Str "root")) [pane "left", subtree]+  where+    subtree = TreeNode $ Tree (consLayout (Str "l1")) [paneWith False "p2", TreeLeaf $ ppaneWithIdent "p1" True]++test_pinOpenPinned :: UnitTest+test_pinOpenPinned =+  ToggleResult.Success pinnedTarget === toggleLayout (Str "l1") pinnedTree++test_pin :: TestTree+test_pin =+  testGroup "pin" [+    unitTest "open an unpinned pane" test_pinOpenNonpinned,+    unitTest "open an unpinned layout" test_layoutPinOpenNonpinned,+    unitTest "open a pinned pane" test_pinOpenPinned+  ]
+ test/Chiasma/Test/StreamParseTest.hs view
@@ -0,0 +1,30 @@+module Chiasma.Test.StreamParseTest where++import Chiasma.Native.StreamParse (TmuxOutputBlock(Success), parseConduit)+import Conduit+import Data.ByteString.Internal (packChars)+import Data.Conduit.List+import qualified Data.Text as T (unpack)+import Hedgehog ((===))++import Chiasma.Test.Util (UnitTest)++paneLine :: Text+paneLine = "%0 100 100"++tmuxOutput :: [Text]+tmuxOutput = [+  "%begin 123\n",+  "%end 123\n",+  "%session-changed $0 0\n%begin 234\n",+  paneLine <> "\nb\n%end 234\n",+  "%begin 345\n",+  "c\n",+  "d\n",+  "%end 345\n"+  ]++test_streamParse :: UnitTest+test_streamParse = do+  r <- runConduit $ sourceList tmuxOutput .| mapC (packChars . T.unpack) .| parseConduit .| sinkList+  [Success [], Success [paneLine, "b"], Success ["c", "d"]] === r
+ test/Chiasma/Test/Util.hs view
@@ -0,0 +1,14 @@+module Chiasma.Test.Util where++import Hedgehog (TestT, withTests, property, test)+import Test.Tasty (TestName, TestTree)+import Test.Tasty.Hedgehog (testProperty)++type UnitTest = TestT IO ()++unitTest ::+  TestName ->+  UnitTest ->+  TestTree+unitTest desc =+  testProperty desc . withTests 1 . property . test
+ test/Main.hs view
@@ -0,0 +1,24 @@+module Main where++import Chiasma.Test.CodecTest (test_decode, test_query)+import Chiasma.Test.LensTest (test_lenses)+import Chiasma.Test.OutputParseTest (test_outputParse)+import Chiasma.Test.PinTest (test_pin)+import Chiasma.Test.StreamParseTest (test_streamParse)+import Chiasma.Test.Util (unitTest)+import Test.Tasty (TestTree, defaultMain, testGroup)++tests :: TestTree+tests =+  testGroup "all" [+    unitTest "tmux-decode a value" test_decode,+    unitTest "tmux-encode a query" test_query,+    test_lenses,+    unitTest "parse tmux output" test_outputParse,+    test_pin,+    unitTest "parse tmux output in stream" test_streamParse+  ]++main :: IO ()+main =+  defaultMain tests
− test/u/BufferedSpec.hs
@@ -1,45 +0,0 @@-{-# OPTIONS_GHC -F -pgmF htfpp #-}--module BufferedSpec(-  htf_thisModulesTests-) where--import Test.Framework-import Chiasma.Native.Api (TmuxNative(..))-import Chiasma.Data.Pane (Pane(Pane), PaneId(..))-import Chiasma.Data.Window (Window(Window), WindowId(..))-import Chiasma.Data.TmuxThunk (TmuxError)-import Chiasma.Monad.Buffered (runTmux)-import Chiasma.Monad.Tmux (TmuxProg)-import qualified Chiasma.Monad.Tmux as Tmux (read, write)-import Chiasma.Test.Tmux (tmuxSpec)--prog :: TmuxProg ([Pane], [Pane], [Window])-prog = do-  panes1 <- Tmux.read "list-panes" ["-t", "%0"]-  Tmux.write "new-window" []-  Tmux.write "new-window" []-  wins <- Tmux.read @Window "list-windows" []-  panes <- Tmux.read "list-panes" ["-a"]-  return (panes1, panes, wins)--p :: Int -> Pane-p i = Pane (PaneId i) 1000 999--w :: Int -> Window-w i = Window (WindowId i) 1000 999--runProg :: TmuxNative -> IO (Either TmuxError ([Pane], [Pane], [Window]))-runProg api = runTmux api prog--test_buffered :: IO ()-test_buffered = do-  result <- tmuxSpec runProg-  assertEqual (Right ([p0], [p0, p1, p2], [w0, w1, w2])) result-  where-    p0 = p 0-    p1 = p 1-    p2 = p 2-    w0 = w 0-    w1 = w 1-    w2 = w 2
− test/u/CodecSpec.hs
@@ -1,27 +0,0 @@-{-# OPTIONS_GHC -F -pgmF htfpp #-}--module CodecSpec(-  htf_thisModulesTests,-) where-import GHC.Generics (Generic)-import Test.Framework-import Chiasma.Data.Pane (PaneId(..))-import Chiasma.Data.Window (WindowId(..))-import Chiasma.Codec (TmuxCodec(decode, query), TmuxQuery(TmuxQuery))--data Dat =-  Dat {-    paneId :: PaneId,-    windowId :: WindowId-  }-  deriving (Eq, Show, Generic)--instance TmuxCodec Dat--test_decode :: IO ()-test_decode =-  assertEqual (Right $ Dat (PaneId 1) (WindowId 2)) $ decode ["%1", "@2"]--test_query :: IO ()-test_query =-  assertEqual (TmuxQuery "#{pane_id} #{window_id}") (query @Dat)
− test/u/OutputParseSpec.hs
@@ -1,30 +0,0 @@-{-# OPTIONS_GHC -F -pgmF htfpp #-}--module OutputParseSpec(-  htf_thisModulesTests-) where--import Test.Framework-import Chiasma.Native.Parse (resultLines)--paneLine :: String-paneLine = "%0 100 100"--tmuxOutput :: String-tmuxOutput = unlines [-  "%begin 123",-  "%end 123",-  "%session-changed $0 0",-  "%begin 234",-  paneLine,-  "b",-  "%end 234",-  "%begin 345",-  "c",-  "d",-  "%end 345"-  ]--test_outputParse :: IO ()-test_outputParse =-  assertEqual (Right [[], [paneLine, "b"], ["c", "d"]]) (resultLines tmuxOutput)
− test/u/SimpleSpec.hs
@@ -1,32 +0,0 @@-{-# OPTIONS_GHC -F -pgmF htfpp #-}--module SimpleSpec(-  htf_thisModulesTests-) where---- import Data.Either (isLeft)-import Test.Framework--- import UnliftIO (try)--- import Chiasma.Data.TmuxThunk (TmuxError)--- import Chiasma.Monad.Simple (runTmux)--- import Chiasma.Monad.Tmux (TmuxProg)--- import qualified Chiasma.Monad.Tmux as Tmux (read, write)---- number :: TmuxProg a String--- number = return "1"---- prog :: TmuxProg a [String]--- prog = do---   a <- number---   out <- Tmux.read "list-panes" ["-t", "%" ++ a]---   Tmux.write "new-windowXXX" []---   return out---- runProg :: IO [String]--- runProg = runTmux prog--test_simple :: IO ()-test_simple =-  return ()-  -- result <- try runProg-  -- assertEqual True (isLeft (result :: Either TmuxError [String]))
− test/u/SpecMain.hs
@@ -1,12 +0,0 @@-{-# OPTIONS_GHC -F -pgmF htfpp #-}--module Main where--import {-@ HTF_TESTS @-} BufferedSpec-import {-@ HTF_TESTS @-} OutputParseSpec-import {-@ HTF_TESTS @-} CodecSpec-import Test.Framework-import Test.Framework.BlackBoxTest ()--main :: IO ()-main = htfMain htf_importedTests