-- |API functions for applying syntax rules to Neovim.
module Ribosome.Api.Syntax where

import Ribosome.Data.Syntax (Syntax)
import Ribosome.Host.Api.Data (Window)
import Ribosome.Host.Api.Effect (vimCallFunction)
import Ribosome.Host.Class.Msgpack.Encode (MsgpackEncode (toMsgpack))
import qualified Ribosome.Host.Effect.Rpc as Rpc
import Ribosome.Host.Effect.Rpc (Rpc)
import Ribosome.Host.Modify (windo)
import Ribosome.Internal.Syntax (catCmds, syntaxCmds)

-- |Apply syntax rules to the current window.
executeSyntax ::
  Member Rpc r =>
  Syntax ->
  Sem r ()
executeSyntax :: forall (r :: EffectRow). Member Rpc r => Syntax -> Sem r ()
executeSyntax =
  RpcCall () -> Sem r ()
forall (r :: EffectRow) a. Member Rpc r => RpcCall a -> Sem r a
Rpc.sync (RpcCall () -> Sem r ())
-> (Syntax -> RpcCall ()) -> Syntax -> Sem r ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [[Text]] -> RpcCall ()
catCmds ([[Text]] -> RpcCall ())
-> (Syntax -> [[Text]]) -> Syntax -> RpcCall ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Syntax -> [[Text]]
syntaxCmds

-- |Apply syntax rules to a window.
executeWindowSyntax ::
  Member Rpc r =>
  Window ->
  Syntax ->
  Sem r ()
executeWindowSyntax :: forall (r :: EffectRow).
Member Rpc r =>
Window -> Syntax -> Sem r ()
executeWindowSyntax Window
win Syntax
syntax =
  Window -> Sem r () -> Sem r ()
forall (r :: EffectRow) a.
Member Rpc r =>
Window -> Sem r a -> Sem r a
windo Window
win (Syntax -> Sem r ()
forall (r :: EffectRow). Member Rpc r => Syntax -> Sem r ()
executeSyntax Syntax
syntax)

-- |Get the name of the syntax group at a given position.
syntaxName ::
  Member Rpc r =>
  Int ->
  Int ->
  Sem r (Text, Text)
syntaxName :: forall (r :: EffectRow).
Member Rpc r =>
Int -> Int -> Sem r (Text, Text)
syntaxName Int
l Int
c = do
  Object
synId <- Text -> [Object] -> Sem r Object
forall a (r :: EffectRow).
(Member Rpc r, MsgpackDecode a) =>
Text -> [Object] -> Sem r a
vimCallFunction Text
"synID" (Int -> Object
forall a. MsgpackEncode a => a -> Object
toMsgpack (Int -> Object) -> [Int] -> [Object]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> [Int
Item [Int]
l, Int
Item [Int]
c, Item [Int]
0])
  (,) (Text -> Text -> (Text, Text))
-> Sem r Text -> Sem r (Text -> (Text, Text))
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Text -> [Object] -> Sem r Text
forall a (r :: EffectRow).
(Member Rpc r, MsgpackDecode a) =>
Text -> [Object] -> Sem r a
vimCallFunction Text
"getline" [Int -> Object
forall a. MsgpackEncode a => a -> Object
toMsgpack Int
l] Sem r (Text -> (Text, Text)) -> Sem r Text -> Sem r (Text, Text)
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Text -> [Object] -> Sem r Text
forall a (r :: EffectRow).
(Member Rpc r, MsgpackDecode a) =>
Text -> [Object] -> Sem r a
vimCallFunction Text
"synIDattr" [Item [Object]
Object
synId, Text -> Object
forall a. MsgpackEncode a => a -> Object
toMsgpack (Text
"name" :: Text)]