module Ribosome.Api.Autocmd where

import Control.Exception.Lifted (bracket)

import Ribosome.Control.Monad.Ribo (NvimE)
import Ribosome.Msgpack.Encode (toMsgpack)
import Ribosome.Nvim.Api.Data (Buffer)
import Ribosome.Nvim.Api.IO (bufferGetNumber, vimCommand, vimGetOption, vimSetOption)

doautocmd ::
  NvimE e m =>
  Bool ->
  Text ->
  m ()
doautocmd :: Bool -> Text -> m ()
doautocmd Bool
silent Text
name =
  Text -> m ()
forall (m :: * -> *) e.
(Nvim m, MonadDeepError e RpcError m) =>
Text -> m ()
vimCommand (Text -> m ()) -> Text -> m ()
forall a b. (a -> b) -> a -> b
$ Text
pre Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
"doautocmd " Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
name
  where
    pre :: Text
pre =
      if Bool
silent then Text
"silent! " else Text
""

uautocmd ::
  NvimE e m =>
  Bool ->
  Text ->
  m ()
uautocmd :: Bool -> Text -> m ()
uautocmd Bool
silent Text
name =
  Bool -> Text -> m ()
forall e (m :: * -> *). NvimE e m => Bool -> Text -> m ()
doautocmd Bool
silent (Text -> m ()) -> Text -> m ()
forall a b. (a -> b) -> a -> b
$ Text
"User " Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
name

eventignore ::
  NvimE e m =>
  MonadBaseControl IO m =>
  m a ->
  m a
eventignore :: m a -> m a
eventignore =
  m Object -> (Object -> m ()) -> (Object -> m a) -> m a
forall (m :: * -> *) a b c.
MonadBaseControl IO m =>
m a -> (a -> m b) -> (a -> m c) -> m c
bracket m Object
getAndSet Object -> m ()
restore ((Object -> m a) -> m a) -> (m a -> Object -> m a) -> m a -> m a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. m a -> Object -> m a
forall a b. a -> b -> a
const
  where
    getAndSet :: m Object
getAndSet = do
      Object
previous <- Text -> m Object
forall (m :: * -> *) e a.
(Nvim m, MonadDeepError e RpcError m, MsgpackDecode a) =>
Text -> m a
vimGetOption Text
"eventignore"
      Text -> Object -> m ()
forall (m :: * -> *) e.
(Nvim m, MonadDeepError e RpcError m) =>
Text -> Object -> m ()
vimSetOption Text
"eventignore" (Text -> Object
forall a. MsgpackEncode a => a -> Object
toMsgpack (Text
"all" :: Text))
      return Object
previous
    restore :: Object -> m ()
restore =
      Text -> Object -> m ()
forall (m :: * -> *) e.
(Nvim m, MonadDeepError e RpcError m) =>
Text -> Object -> m ()
vimSetOption Text
"eventignore"

bufferAutocmd ::
  NvimE e m =>
  Buffer ->
  Text ->
  Text ->
  Text ->
  m ()
bufferAutocmd :: Buffer -> Text -> Text -> Text -> m ()
bufferAutocmd Buffer
buffer Text
grp Text
event Text
cmd = do
  Int
number <- Buffer -> m Int
forall (m :: * -> *) e.
(Nvim m, MonadDeepError e RpcError m) =>
Buffer -> m Int
bufferGetNumber Buffer
buffer
  Text -> m ()
forall (m :: * -> *) e.
(Nvim m, MonadDeepError e RpcError m) =>
Text -> m ()
vimCommand (Text -> m ()) -> Text -> m ()
forall a b. (a -> b) -> a -> b
$ Text
"augroup " Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
grp
  Text -> m ()
forall (m :: * -> *) e.
(Nvim m, MonadDeepError e RpcError m) =>
Text -> m ()
vimCommand (Text -> m ()) -> Text -> m ()
forall a b. (a -> b) -> a -> b
$ Text
"autocmd " Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
" " Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
event Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
" <buffer=" Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Int -> Text
forall b a. (Show a, IsString b) => a -> b
show Int
number Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
"> " Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
cmd
  Text -> m ()
forall (m :: * -> *) e.
(Nvim m, MonadDeepError e RpcError m) =>
Text -> m ()
vimCommand Text
"augroup end"