-- |Autocmd functions.
module Ribosome.Api.Autocmd (
  module Ribosome.Api.Autocmd,
  autocmd,
) where

import Data.MessagePack (Object)

import Ribosome.Host.Api.Autocmd (autocmd)
import Ribosome.Host.Api.Data (Buffer)
import Ribosome.Host.Api.Effect (bufferGetNumber, nvimExecAutocmds, vimGetOption, vimSetOption)
import Ribosome.Host.Class.Msgpack.Encode (toMsgpack)
import Ribosome.Host.Data.RpcType (AutocmdBuffer (AutocmdBuffer), AutocmdEvents, AutocmdId, AutocmdOptions, target)
import qualified Ribosome.Host.Effect.Rpc as Rpc
import Ribosome.Host.Effect.Rpc (Rpc)

-- |Trigger a set of autocmds.
--
-- Same as 'nvimExecAutocmds', but specializing the parameter type.
doautocmdWith ::
  Member Rpc r =>
  AutocmdEvents ->
  Map Text Object ->
  Sem r ()
doautocmdWith :: forall (r :: EffectRow).
Member Rpc r =>
AutocmdEvents -> Map Text Object -> Sem r ()
doautocmdWith =
  AutocmdEvents -> Map Text Object -> Sem r ()
forall p_0 (r :: EffectRow).
(Member Rpc r, MsgpackEncode p_0) =>
p_0 -> Map Text Object -> Sem r ()
nvimExecAutocmds

-- |Trigger a set of autocmds.
doautocmd ::
  Member Rpc r =>
  AutocmdEvents ->
  Sem r ()
doautocmd :: forall (r :: EffectRow). Member Rpc r => AutocmdEvents -> Sem r ()
doautocmd AutocmdEvents
events =
  AutocmdEvents -> Map Text Object -> Sem r ()
forall p_0 (r :: EffectRow).
(Member Rpc r, MsgpackEncode p_0) =>
p_0 -> Map Text Object -> Sem r ()
nvimExecAutocmds AutocmdEvents
events Map Text Object
forall a. Monoid a => a
mempty

-- |Trigger a user autocmd.
uautocmd ::
  Member Rpc r =>
  Text ->
  Sem r ()
uautocmd :: forall (r :: EffectRow). Member Rpc r => Text -> Sem r ()
uautocmd Text
name =
  AutocmdEvents -> Map Text Object -> Sem r ()
forall (r :: EffectRow).
Member Rpc r =>
AutocmdEvents -> Map Text Object -> Sem r ()
doautocmdWith AutocmdEvents
"User" [(Text
"pattern", Text -> Object
forall a. MsgpackEncode a => a -> Object
toMsgpack Text
name)]

-- |Execute an action with all autocmds disabled.
eventignore ::
  Members [Rpc, Resource] r =>
  Sem r a ->
  Sem r a
eventignore :: forall (r :: EffectRow) a.
Members '[Rpc, Resource] r =>
Sem r a -> Sem r a
eventignore =
  Sem r Text -> (Text -> Sem r ()) -> (Text -> Sem r a) -> Sem r a
forall (r :: EffectRow) a c b.
Member Resource r =>
Sem r a -> (a -> Sem r c) -> (a -> Sem r b) -> Sem r b
bracket Sem r Text
getAndSet Text -> Sem r ()
restore ((Text -> Sem r a) -> Sem r a)
-> (Sem r a -> Text -> Sem r a) -> Sem r a -> Sem r a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Sem r a -> Text -> Sem r a
forall a b. a -> b -> a
const
  where
    getAndSet :: Sem r Text
getAndSet = do
      Text
previous :: Text <- Text -> Sem r Text
forall a (r :: EffectRow).
(Member Rpc r, MsgpackDecode a) =>
Text -> Sem r a
vimGetOption Text
"eventignore"
      Text -> Text -> Sem r ()
forall p_1 (r :: EffectRow).
(Member Rpc r, MsgpackEncode p_1) =>
Text -> p_1 -> Sem r ()
vimSetOption Text
"eventignore" (Text
"all" :: Text)
      pure Text
previous
    restore :: Text -> Sem r ()
restore =
      Text -> Text -> Sem r ()
forall p_1 (r :: EffectRow).
(Member Rpc r, MsgpackEncode p_1) =>
Text -> p_1 -> Sem r ()
vimSetOption Text
"eventignore"

-- |Create an autocmd in a buffer.
bufferAutocmd ::
  Member Rpc r =>
  Buffer ->
  AutocmdEvents ->
  AutocmdOptions ->
  -- |Command to execute when the autocmd triggers.
  Text ->
  Sem r AutocmdId
bufferAutocmd :: forall (r :: EffectRow).
Member Rpc r =>
Buffer
-> AutocmdEvents -> AutocmdOptions -> Text -> Sem r AutocmdId
bufferAutocmd Buffer
buf AutocmdEvents
events AutocmdOptions
options Text
cmd = do
  Int
number <- Buffer -> Sem r Int
forall (r :: EffectRow). Member Rpc r => Buffer -> Sem r Int
bufferGetNumber Buffer
buf
  RpcCall AutocmdId -> Sem r AutocmdId
forall (r :: EffectRow) a. Member Rpc r => RpcCall a -> Sem r a
Rpc.sync do
    AutocmdEvents -> AutocmdOptions -> Text -> RpcCall AutocmdId
autocmd AutocmdEvents
events AutocmdOptions
options { $sel:target:AutocmdOptions :: Either AutocmdBuffer AutocmdPatterns
target = AutocmdBuffer -> Either AutocmdBuffer AutocmdPatterns
forall a b. a -> Either a b
Left (Int -> AutocmdBuffer
AutocmdBuffer Int
number) } Text
cmd