-- |API functions for obtaining Neovim's current mode.
module Ribosome.Api.Mode where

import Ribosome.Data.Mode (NvimMode)
import Ribosome.Host.Api.Effect (nvimGetMode, vimCallFunction)
import Ribosome.Host.Class.Msgpack.Decode (MsgpackDecode (..))
import Ribosome.Host.Class.Msgpack.Util (decodeString)
import Ribosome.Host.Effect.Rpc (Rpc)

-- |An encoding of Neovim's mode for only the most basic variants.
data SimpleMode =
  Normal
  |
  Visual
  |
  Insert
  |
  Other Text
  deriving stock (SimpleMode -> SimpleMode -> Bool
(SimpleMode -> SimpleMode -> Bool)
-> (SimpleMode -> SimpleMode -> Bool) -> Eq SimpleMode
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: SimpleMode -> SimpleMode -> Bool
$c/= :: SimpleMode -> SimpleMode -> Bool
== :: SimpleMode -> SimpleMode -> Bool
$c== :: SimpleMode -> SimpleMode -> Bool
Eq, Int -> SimpleMode -> ShowS
[SimpleMode] -> ShowS
SimpleMode -> String
(Int -> SimpleMode -> ShowS)
-> (SimpleMode -> String)
-> ([SimpleMode] -> ShowS)
-> Show SimpleMode
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [SimpleMode] -> ShowS
$cshowList :: [SimpleMode] -> ShowS
show :: SimpleMode -> String
$cshow :: SimpleMode -> String
showsPrec :: Int -> SimpleMode -> ShowS
$cshowsPrec :: Int -> SimpleMode -> ShowS
Show)

instance IsString SimpleMode where
  fromString :: String -> SimpleMode
fromString String
"n" = SimpleMode
Normal
  fromString String
"v" = SimpleMode
Visual
  fromString String
"V" = SimpleMode
Visual
  fromString String
"CTRL-V" = SimpleMode
Visual
  fromString String
"i" = SimpleMode
Insert
  fromString String
a = Text -> SimpleMode
Other (String -> Text
forall a. ToText a => a -> Text
toText String
a)

instance MsgpackDecode SimpleMode where
  fromMsgpack :: Object -> Either DecodeError SimpleMode
fromMsgpack =
    Object -> Either DecodeError SimpleMode
forall a.
(Typeable a, IsString a) =>
Object -> Either DecodeError a
decodeString

-- |Get the current mode as a 'SimpleMode'.
simpleMode ::
  Member Rpc r =>
  Sem r SimpleMode
simpleMode :: forall (r :: EffectRow). Member Rpc r => Sem r SimpleMode
simpleMode =
  Text -> [Object] -> Sem r SimpleMode
forall a (r :: EffectRow).
(Member Rpc r, MsgpackDecode a) =>
Text -> [Object] -> Sem r a
vimCallFunction Text
"mode" []

-- |Indicate whether Neovim is in visual mode.
visualModeActive ::
  Member Rpc r =>
  Sem r Bool
visualModeActive :: forall (r :: EffectRow). Member Rpc r => Sem r Bool
visualModeActive =
  (SimpleMode -> SimpleMode -> Bool
forall a. Eq a => a -> a -> Bool
== SimpleMode
Visual) (SimpleMode -> Bool) -> Sem r SimpleMode -> Sem r Bool
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Sem r SimpleMode
forall (r :: EffectRow). Member Rpc r => Sem r SimpleMode
simpleMode

-- |Get the current mode.
mode ::
  Member Rpc r =>
  Sem r NvimMode
mode :: forall (r :: EffectRow). Member Rpc r => Sem r NvimMode
mode =
  Sem r NvimMode
forall a (r :: EffectRow).
(Member Rpc r, MsgpackDecode a) =>
Sem r a
nvimGetMode