{-# OPTIONS_GHC -Wno-ambiguous-fields #-}
module Chiasma.Command.Pane where

import Prelude hiding (output)

import qualified Chiasma.Codec.Data.Pane as Codec (Pane)
import qualified Chiasma.Codec.Data.PaneMode as Codec (PaneMode (PaneMode))
import Chiasma.Data.Axis (Axis)
import Chiasma.Data.CapturePaneParams (CaptureOutput (Stdout), escapeSequences, output, target)
import Chiasma.Data.CopyModeParams (target)
import Chiasma.Data.KillPaneParams (target)
import qualified Chiasma.Data.PaneSelection as PaneSelection
import qualified Chiasma.Data.Panes as Panes
import Chiasma.Data.Panes (TmuxPanes)
import Chiasma.Data.PipePaneParams (command, target)
import Chiasma.Data.ResizePaneParams (ResizeAbsolute (ResizeAbsolute), absolute, target)
import Chiasma.Data.SelectParams (target)
import qualified Chiasma.Data.SendKeysParams as SendKeysParams
import Chiasma.Data.SendKeysParams (Key, keys, target)
import Chiasma.Data.SplitParams (JoinPaneParams (axis, detach, source, target))
import qualified Chiasma.Data.Target as Target
import Chiasma.Data.TmuxCommand (
  TmuxCommand (CapturePane, CopyMode, KillPane, MovePane, PipePane, ResizePane, SelectPane, SendKeys),
  )
import Chiasma.Data.TmuxId (PaneId, WindowId)
import Chiasma.Data.View (View (View))
import qualified Chiasma.Effect.TmuxApi as Tmux
import Chiasma.Effect.TmuxApi (Tmux)

panes ::
  Member (TmuxPanes a) r =>
  Sem r [a]
panes :: forall a (r :: EffectRow). Member (TmuxPanes a) r => Sem r [a]
panes =
  Panes a [a] -> Sem r [a]
forall (command :: * -> *) (r :: EffectRow) a.
Member (TmuxApi command) r =>
command a -> Sem r a
Tmux.send (PaneSelection -> Panes a [a]
forall p. PaneSelection -> Panes p [p]
Panes.List PaneSelection
PaneSelection.All)

pane ::
  Member (TmuxPanes a) r =>
  PaneId ->
  Sem r (Maybe a)
pane :: forall a (r :: EffectRow).
Member (TmuxPanes a) r =>
PaneId -> Sem r (Maybe a)
pane PaneId
paneId =
  Panes a (Maybe a) -> Sem r (Maybe a)
forall (command :: * -> *) (r :: EffectRow) a.
Member (TmuxApi command) r =>
command a -> Sem r a
Tmux.send (PaneId -> Panes a (Maybe a)
forall p. PaneId -> Panes p (Maybe p)
Panes.Find PaneId
paneId)

windowPanes ::
  Member (TmuxPanes a) r =>
  WindowId ->
  Sem r [a]
windowPanes :: forall a (r :: EffectRow).
Member (TmuxPanes a) r =>
WindowId -> Sem r [a]
windowPanes WindowId
windowId =
  Panes a [a] -> Sem r [a]
forall (command :: * -> *) (r :: EffectRow) a.
Member (TmuxApi command) r =>
command a -> Sem r a
Tmux.send (PaneSelection -> Panes a [a]
forall p. PaneSelection -> Panes p [p]
Panes.List (Target -> PaneSelection
PaneSelection.InWindow (WindowId -> Target
Target.Window WindowId
windowId)))

firstWindowPane ::
  Member (TmuxPanes a) r =>
  WindowId ->
  Sem r a
firstWindowPane :: forall a (r :: EffectRow).
Member (TmuxPanes a) r =>
WindowId -> Sem r a
firstWindowPane WindowId
windowId =
  Panes a a -> Sem r a
forall (command :: * -> *) (r :: EffectRow) a.
Member (TmuxApi command) r =>
command a -> Sem r a
Tmux.send (PaneSelection -> Panes a a
forall p. PaneSelection -> Panes p p
Panes.First (Target -> PaneSelection
PaneSelection.InWindow (WindowId -> Target
Target.Window WindowId
windowId)))

closePane ::
  Member Tmux r =>
  PaneId ->
  Sem r ()
closePane :: forall (r :: EffectRow). Member Tmux r => PaneId -> Sem r ()
closePane PaneId
paneId =
  TmuxCommand () -> Sem r ()
forall (command :: * -> *) (r :: EffectRow) a.
Member (TmuxApi command) r =>
command a -> Sem r a
Tmux.send (KillPaneParams -> TmuxCommand ()
KillPane KillPaneParams
forall a. Default a => a
def { $sel:target:KillPaneParams :: Target
target = PaneId -> Target
Target.Pane PaneId
paneId })

isPaneIdOpen ::
  Member (TmuxPanes Codec.Pane) r =>
  PaneId ->
  Sem r Bool
isPaneIdOpen :: forall (r :: EffectRow).
Member (TmuxPanes Pane) r =>
PaneId -> Sem r Bool
isPaneIdOpen PaneId
paneId =
  Maybe Pane -> Bool
forall a. Maybe a -> Bool
isJust (Maybe Pane -> Bool) -> Sem r (Maybe Pane) -> Sem r Bool
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> PaneId -> Sem r (Maybe Pane)
forall a (r :: EffectRow).
Member (TmuxPanes a) r =>
PaneId -> Sem r (Maybe a)
pane PaneId
paneId

isPaneOpen ::
  Member (TmuxPanes Codec.Pane) r =>
  View PaneId ->
  Sem r Bool
isPaneOpen :: forall (r :: EffectRow).
Member (TmuxPanes Pane) r =>
View PaneId -> Sem r Bool
isPaneOpen (View Ident
_ (Just PaneId
paneId)) =
  PaneId -> Sem r Bool
forall (r :: EffectRow).
Member (TmuxPanes Pane) r =>
PaneId -> Sem r Bool
isPaneIdOpen PaneId
paneId
isPaneOpen View PaneId
_ =
  Bool -> Sem r Bool
forall a. a -> Sem r a
forall (f :: * -> *) a. Applicative f => a -> f a
pure Bool
False

movePane ::
  Member Tmux r =>
  PaneId ->
  PaneId ->
  Axis ->
  Sem r ()
movePane :: forall (r :: EffectRow).
Member Tmux r =>
PaneId -> PaneId -> Axis -> Sem r ()
movePane PaneId
paneId PaneId
refId Axis
axis =
  TmuxCommand () -> Sem r ()
forall (command :: * -> *) (r :: EffectRow) a.
Member (TmuxApi command) r =>
command a -> Sem r a
Tmux.send (JoinPaneParams -> TmuxCommand ()
MovePane JoinPaneParams
forall a. Default a => a
def {
    $sel:detach:JoinPaneParams :: Bool
detach = Bool
True,
    $sel:source:JoinPaneParams :: Maybe Target
source = Target -> Maybe Target
forall a. a -> Maybe a
Just (PaneId -> Target
Target.Pane PaneId
paneId),
    $sel:target:JoinPaneParams :: Target
target = PaneId -> Target
Target.Pane PaneId
refId,
    $sel:axis:JoinPaneParams :: Maybe Axis
axis = Axis -> Maybe Axis
forall a. a -> Maybe a
Just Axis
axis
  })

resizePane ::
  Member Tmux r =>
  PaneId ->
  Axis ->
  Int ->
  Sem r ()
resizePane :: forall (r :: EffectRow).
Member Tmux r =>
PaneId -> Axis -> Int -> Sem r ()
resizePane PaneId
paneId Axis
axis Int
size =
  TmuxCommand () -> Sem r ()
forall (command :: * -> *) (r :: EffectRow) a.
Member (TmuxApi command) r =>
command a -> Sem r a
Tmux.send (ResizePaneParams -> TmuxCommand ()
ResizePane ResizePaneParams
forall a. Default a => a
def {
    $sel:target:ResizePaneParams :: Target
target = PaneId -> Target
Target.Pane PaneId
paneId,
    $sel:absolute:ResizePaneParams :: Maybe ResizeAbsolute
absolute = ResizeAbsolute -> Maybe ResizeAbsolute
forall a. a -> Maybe a
Just (Axis -> Int -> ResizeAbsolute
ResizeAbsolute Axis
axis Int
size)
  })

sendKeys ::
  Member Tmux r =>
  PaneId ->
  [Key] ->
  Sem r ()
sendKeys :: forall (r :: EffectRow).
Member Tmux r =>
PaneId -> [Key] -> Sem r ()
sendKeys PaneId
paneId [Key]
lines' =
  [Key] -> (Key -> Sem r ()) -> Sem r ()
forall (t :: * -> *) (f :: * -> *) a b.
(Foldable t, Applicative f) =>
t a -> (a -> f b) -> f ()
for_ [Key]
lines' \ Key
line ->
    TmuxCommand () -> Sem r ()
forall (command :: * -> *) (r :: EffectRow) a.
Member (TmuxApi command) r =>
command a -> Sem r a
Tmux.send (SendKeysParams -> TmuxCommand ()
SendKeys SendKeysParams
forall a. Default a => a
def { $sel:target:SendKeysParams :: Target
target = PaneId -> Target
Target.Pane PaneId
paneId, $sel:keys:SendKeysParams :: [Key]
keys = [Item [Key]
Key
line] })

pipePane ::
  Member Tmux r =>
  PaneId ->
  Text ->
  Sem r ()
pipePane :: forall (r :: EffectRow).
Member Tmux r =>
PaneId -> Text -> Sem r ()
pipePane PaneId
paneId Text
cmd =
  TmuxCommand () -> Sem r ()
forall (command :: * -> *) (r :: EffectRow) a.
Member (TmuxApi command) r =>
command a -> Sem r ()
Tmux.schedule (PipePaneParams -> TmuxCommand ()
PipePane PipePaneParams
forall a. Default a => a
def { $sel:target:PipePaneParams :: Target
target = PaneId -> Target
Target.Pane PaneId
paneId, $sel:command:PipePaneParams :: Maybe Text
command = Text -> Maybe Text
forall a. a -> Maybe a
Just Text
cmd })

capturePane ::
  Member Tmux r =>
  PaneId ->
  Sem r [Text]
capturePane :: forall (r :: EffectRow). Member Tmux r => PaneId -> Sem r [Text]
capturePane PaneId
paneId =
  TmuxCommand [Text] -> Sem r [Text]
forall (command :: * -> *) (r :: EffectRow) a.
Member (TmuxApi command) r =>
command a -> Sem r a
Tmux.send (CapturePaneParams -> TmuxCommand [Text]
CapturePane CapturePaneParams
forall a. Default a => a
def { $sel:target:CapturePaneParams :: Target
target = PaneId -> Target
Target.Pane PaneId
paneId, $sel:escapeSequences:CapturePaneParams :: Bool
escapeSequences = Bool
True, $sel:output:CapturePaneParams :: Maybe CaptureOutput
output = CaptureOutput -> Maybe CaptureOutput
forall a. a -> Maybe a
Just CaptureOutput
Stdout})

selectPane ::
  Member Tmux r =>
  PaneId ->
  Sem r ()
selectPane :: forall (r :: EffectRow). Member Tmux r => PaneId -> Sem r ()
selectPane PaneId
paneId =
  TmuxCommand () -> Sem r ()
forall (command :: * -> *) (r :: EffectRow) a.
Member (TmuxApi command) r =>
command a -> Sem r a
Tmux.send (SelectParams -> TmuxCommand ()
SelectPane SelectParams
forall a. Default a => a
def { $sel:target:SelectParams :: Target
target = PaneId -> Target
Target.Pane PaneId
paneId })

copyMode ::
  Member Tmux r =>
  PaneId ->
  Sem r ()
copyMode :: forall (r :: EffectRow). Member Tmux r => PaneId -> Sem r ()
copyMode PaneId
paneId =
  TmuxCommand () -> Sem r ()
forall (command :: * -> *) (r :: EffectRow) a.
Member (TmuxApi command) r =>
command a -> Sem r a
Tmux.send (CopyModeParams -> TmuxCommand ()
CopyMode CopyModeParams
forall a. Default a => a
def { $sel:target:CopyModeParams :: Target
target = PaneId -> Target
Target.Pane PaneId
paneId })

paneMode ::
  Member (TmuxPanes Codec.PaneMode) r =>
  PaneId ->
  Sem r (Maybe Codec.PaneMode)
paneMode :: forall (r :: EffectRow).
Member (TmuxPanes PaneMode) r =>
PaneId -> Sem r (Maybe PaneMode)
paneMode =
  PaneId -> Sem r (Maybe PaneMode)
forall a (r :: EffectRow).
Member (TmuxPanes a) r =>
PaneId -> Sem r (Maybe a)
pane

quitCopyMode ::
  Member Tmux r =>
  Member (TmuxPanes Codec.PaneMode) r =>
  PaneId ->
  Sem r ()
quitCopyMode :: forall (r :: EffectRow).
(Member Tmux r, Member (TmuxPanes PaneMode) r) =>
PaneId -> Sem r ()
quitCopyMode PaneId
paneId =
  (PaneMode -> Sem r ()) -> Maybe PaneMode -> Sem r ()
forall (t :: * -> *) (f :: * -> *) a b.
(Foldable t, Applicative f) =>
(a -> f b) -> t a -> f ()
traverse_ PaneMode -> Sem r ()
check (Maybe PaneMode -> Sem r ()) -> Sem r (Maybe PaneMode) -> Sem r ()
forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< PaneId -> Sem r (Maybe PaneMode)
forall a (r :: EffectRow).
Member (TmuxPanes a) r =>
PaneId -> Sem r (Maybe a)
pane PaneId
paneId
  where
    check :: PaneMode -> Sem r ()
check (Codec.PaneMode PaneId
_ Text
mode) =
      Bool -> Sem r () -> Sem r ()
forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
when (Text
mode Text -> Text -> Bool
forall a. Eq a => a -> a -> Bool
== Text
"copy-mode") do
        TmuxCommand () -> Sem r ()
forall (command :: * -> *) (r :: EffectRow) a.
Member (TmuxApi command) r =>
command a -> Sem r a
Tmux.send (SendKeysParams -> TmuxCommand ()
SendKeys SendKeysParams
forall a. Default a => a
def { $sel:target:SendKeysParams :: Target
target = PaneId -> Target
Target.Pane PaneId
paneId, $sel:copyMode:SendKeysParams :: Bool
SendKeysParams.copyMode = Bool
True, $sel:keys:SendKeysParams :: [Key]
keys = [Item [Key]
Key
"cancel"] })