ribosome-0.4.0.0: lib/Ribosome/Plugin/TH.hs
{-# OPTIONS_GHC -fno-warn-orphans #-}
module Ribosome.Plugin.TH where
import qualified Data.Text as Text (unpack)
import Language.Haskell.TH (ExpQ, Lit(StringL), Name, listE, litE, nameBase)
import Neovim.Plugin.Classes (
AutocmdOptions,
Synchronous(..),
)
import Ribosome.Data.String (capitalize)
import Ribosome.Plugin.TH.Command (handlerParams, rpcCommand)
import Ribosome.Plugin.TH.Handler (
RpcDef(RpcDef),
RpcDefDetail(RpcFunction, RpcAutocmd),
RpcHandlerConfig(RpcHandlerConfig),
argsCase,
defaultRpcHandlerConfig,
functionParamTypes,
lambdaNames,
listParamsPattern,
rpcLambdaWithErrorCase,
)
functionImplementation :: Name -> ExpQ
functionImplementation name = do
paramTypes <- functionParamTypes name
paramNames <- lambdaNames (length paramTypes)
rpcLambdaWithErrorCase name (argsCase name (listParamsPattern paramNames) paramNames)
rpcFunction :: String -> Synchronous -> Name -> ExpQ
rpcFunction name sync funcName = do
fun <- functionImplementation funcName
[|RpcDef (RpcFunction sync) $((litE (StringL name))) $(return fun)|]
rpcAutocmd :: String -> Name -> Synchronous -> Maybe AutocmdOptions -> String -> ExpQ
rpcAutocmd name funcName sync options event = do
fun <- functionImplementation funcName
[|RpcDef (RpcAutocmd event sync (fromMaybe def options)) $((litE (StringL name))) $(return fun)|]
vimName :: Name -> Maybe String -> String
vimName funcName =
capitalize . fromMaybe (nameBase funcName)
rpcHandler :: (RpcHandlerConfig -> RpcHandlerConfig) -> Name -> ExpQ
rpcHandler confTrans =
handler (confTrans defaultRpcHandlerConfig)
where
handler (RpcHandlerConfig sync name cmd autocmd auOptions) funcName = do
params <- handlerParams funcName
rpcFun <- rpcFunction vimName' sync funcName
rpcCmd <- traverse (rpcCommand vimName' funcName params sync) cmd
rpcAu <- traverse (rpcAutocmd vimName' funcName sync auOptions) (Text.unpack <$> autocmd)
listE $ return <$> rpcFun : maybeToList rpcCmd <> maybeToList rpcAu
where
vimName' = vimName funcName (Text.unpack <$> name)
rpcHandlerDef :: Name -> ExpQ
rpcHandlerDef =
rpcHandler id