chiasma-0.10.0.0: lib/Chiasma/Data/Panes.hs
module Chiasma.Data.Panes where
import Chiasma.Class.CmdArgs (cmdArgs)
import qualified Chiasma.Codec as Codec
import Chiasma.Codec (TmuxCodec, multi, single)
import qualified Chiasma.Data.DecodeError as DecodeFailure
import Chiasma.Data.DecodeError (DecodeError (DecodeError))
import qualified Chiasma.Data.PaneSelection as PaneSelection
import Chiasma.Data.PaneSelection (PaneSelection)
import qualified Chiasma.Data.Target as Target
import Chiasma.Data.TmuxId (PaneId)
import Chiasma.Data.TmuxQuery (TmuxQuery)
import Chiasma.Data.TmuxRequest (TmuxRequest (TmuxRequest))
import Chiasma.Data.TmuxResponse (TmuxResponse (TmuxResponse))
import Chiasma.Data.WithPaneId (WithPaneId (WithPaneId))
import Chiasma.Effect.TmuxApi (TmuxApi)
-- |A 'TmuxApi' command for listing panes, with different query criteria.
-- The constructors taking a 'PaneSelection' list all panes that are present in the selected scope, but may constrain
-- the return value.
-- The constructors 'Get' and 'Find' return only the pane with the requested ID.
data Panes (p :: Type) (a :: Type) :: Type where
-- |Return all panes covered by the selection.
List :: PaneSelection -> Panes p [p]
-- |Return one pane covered by the selection, fail if there is none.
First :: PaneSelection -> Panes p p
-- |Return one pane covered by the selection, fail if there is none or more than one.
One :: PaneSelection -> Panes p p
-- |Return the pane with the specified ID, fail if there is none.
Get :: PaneId -> Panes p p
-- |Return the pane with the specified ID if it exists.
Find :: PaneId -> Panes p (Maybe p)
type TmuxPanes p =
TmuxApi (Panes p)
query ::
∀ p a .
TmuxCodec p =>
Panes p a ->
TmuxQuery
query _ =
Codec.query @p
selection :: Panes p a -> PaneSelection
selection = \case
List ps -> ps
First ps -> ps
One ps -> ps
Get i -> PaneSelection.InWindow (Target.Pane i)
Find _ -> PaneSelection.All
request ::
Panes p a ->
TmuxQuery ->
TmuxRequest
request (selection -> s) =
TmuxRequest "list-panes" (cmdArgs s) . Just
encode ::
∀ p a .
TmuxCodec p =>
Panes p a ->
TmuxRequest
encode (Get i) =
request (Get i) (Codec.query @(WithPaneId p))
encode (Find i) =
request (Find i) (Codec.query @(WithPaneId p))
encode cmd =
request cmd (query cmd)
sameId :: PaneId -> WithPaneId a -> Maybe a
sameId target (WithPaneId paneId p)
| target == paneId = Just p
| otherwise = Nothing
paneById ::
TmuxCodec p =>
PaneId ->
[Text] ->
Either DecodeError (Maybe p)
paneById paneId out = do
firstJust (sameId paneId) <$> multi out
decode ::
∀ p a .
TmuxCodec p =>
TmuxResponse ->
Panes p a ->
Either DecodeError a
decode (TmuxResponse out) = \case
List _ ->
multi out
First _ ->
multi out >>= \case
[] -> Left (DecodeError out DecodeFailure.TooFewFields)
a : _ -> Right a
One _ ->
single out
Get paneId -> do
ps <- multi @(WithPaneId p) out
maybeToRight (DecodeError out DecodeFailure.TargetMissing) (firstJust (sameId paneId) ps)
Find paneId -> do
ps <- multi @(WithPaneId p) out
pure (firstJust (sameId paneId) ps)