neovimhaskell / nvim-hs

Neovim API for Haskell plugins as well as the plugin provider
Other
267 stars 18 forks source link

Hangs without showing any error messages #79

Closed Hogeyama closed 5 years ago

Hogeyama commented 5 years ago

Description

nvim-hs plugin gets unresponsive without showing any error message when it evaluates an expression like vim_command undefined. To reproduce, just run debug' (vim_command undefined) in ghci repl.

Cause

When it evaluates vim_command undefined, the undefined is wrapped in FunctionCall message at Neovim.RPC.FunctionCall.acall, and written in eventQueue. The event handler reads the message and evaluates it, and thus dies.

Possible solution

It can be solved by evaluating the function parameters before inserting into eventQueue:

acall :: (NvimObject result)
     => FunctionName
     -> [Object]
     -> Neovim env (STM (Either NeovimException result))
acall fn parameters = do
    evaluate (rnf parameters) -- impure exception founds here
    q <- Internal.asks' Internal.eventQueue
    mv <- liftIO newEmptyTMVarIO
    timestamp <- liftIO getCurrentTime
    atomically' . writeTQueue q . SomeMessage $ FunctionCall fn parameters mv timestamp
    return $ convertObject <$> readTMVar mv

Altenatively, it may be better to write a wrapper of writeTQueue though it requires NFData as subclass of Message.

writeMessage :: (MonadIO m, Message message) => TQueue SomeMessage -> message -> m ()
writeMessage q message = liftIO $ do
    evaluate (rnf message)
    atomically $ writeTQueue q (SomeMessage message)

I'll make a PR if you don't mind.

saep commented 5 years ago

A PR would be great! The proposed changes look good to me.