packages feed

sarsi-0.0.4.0: sarsi-nvim/NVIM/Client.hs

module NVIM.Client where

-- | A primitive NVIM RPC synchronous client.

import Data.Binary.Machine (streamGet)
import Data.Binary.Put (runPut)
import Data.ByteString (hGetSome, hPut)
import Data.ByteString.Lazy (toStrict)
import Data.Machine ((<~), asParts, auto, final, run, source)
import Data.MessagePack.Object (Object(..))
import Data.MessagePack.RPC (Answer(..), Request(..), Message(..), getMessage, putRequest)
import Data.Text (Text)
import System.IO (Handle, stdin, stdout)
import qualified Data.Text as Text

data Command = VimCommand [Object] | VimCallFunction Text [Object]

runCommand :: Command -> IO Answer
runCommand = runCommandWith stdin stdout

runCommandWith :: Handle -> Handle -> Command -> IO Answer
runCommandWith hIn hOut cmd = do
  hPut hOut $ toStrict $ runPut $ putRequest $ mkRequest cmd
  xs <- hGetSome hIn 1024
  let ys = run $ final <~ asParts <~ auto unpack <~ streamGet getMessage <~ source [xs]
  return $ mkAnswer $ ys
    where
      mkAnswer [a] = a
      mkAnswer _   = Error $ ObjectStr $ Text.pack "No RPC answer received."
      mkRequest (VimCommand xs) =
        Request 0 (Text.pack "vim_command") xs
      mkRequest (VimCallFunction m xs) =
        Request 0 (Text.pack "vim_call_function") [ ObjectStr m, ObjectArray xs ]
      unpack (Right (Response _ a)) = [a]
      unpack _                      = []