packages feed

nvim-hs 0.0.5 → 0.0.6

raw patch · 21 files changed

+553/−240 lines, 21 filesdep +ansi-wl-pprintdep +time-locale-compat

Dependencies added: ansi-wl-pprint, time-locale-compat

Files

CHANGELOG.md view
@@ -1,4 +1,17 @@-# 0.0.4+# 0.0.6++* Noteworthy new API functions for the user's convenience:++  - `errOnInvalidResult`+  - `(:+)`++* ansi-wl-pprint is used for pretty printing of various things now. Most+  notably, the error type has been changed from `String` to `Doc`.+  This is a breaking change, but it was kind of announced in the issues+  list. In any case, uses of `err` can be fixed by enabling the+  `OverloadedStrings` extension. Other breakages have to be fixed by hand.++# 0.0.5  * Documentation received some love. 
LICENSE view
@@ -1,3 +1,18 @@+   Copyright 2015 Sebastian Witte <woozletoff@gmail.com>++   Licensed under the Apache License, Version 2.0 (the "License");+   you may not use this file except in compliance with the License.+   You may obtain a copy of the License at++       http://www.apache.org/licenses/LICENSE-2.0++   Unless required by applicable law or agreed to in writing, software+   distributed under the License is distributed on an "AS IS" BASIS,+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.+   See the License for the specific language governing permissions and+   limitations under the License.++ Apache License                            Version 2.0, January 2004                         http://www.apache.org/licenses/@@ -185,18 +200,4 @@       file or class name and description of purpose be included on the       same "printed page" as the copyright notice for easier       identification within third-party archives.--   Copyright {yyyy} {name of copyright owner}--   Licensed under the Apache License, Version 2.0 (the "License");-   you may not use this file except in compliance with the License.-   You may obtain a copy of the License at--       http://www.apache.org/licenses/LICENSE-2.0--   Unless required by applicable law or agreed to in writing, software-   distributed under the License is distributed on an "AS IS" BASIS,-   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.-   See the License for the specific language governing permissions and-   limitations under the License. 
+ README.md view
@@ -0,0 +1,38 @@+# nvim-hs++Neovim API for Haskell plugins as well as a plugin provider.+This library and executable should provide a basis for developing+plugins. This package should only contain broadly useful interfaces+to write plugins for neovim in haskell. The design goal is to create+an easy to use API that avoids most of the boilerplate while still retaining+some sense of reliability and type safety. Since Template Haskell is used+to generate the neovim bindings and to avoid some of the boilerplate+handy work, some exotic operating systems and architectures may not work.++[![Build Status](https://travis-ci.org/neovimhaskell/nvim-hs.svg?branch=master)](https://travis-ci.org/neovimhaskell/nvim-hs)+[![Hackage version](https://img.shields.io/hackage/v/nvim-hs.svg?style=flat)](https://hackage.haskell.org/package/nvim-hs)++# What do I have to expect if I were to use it now?++Check the issue list here on github.++# How do I start using this?++All you need to know is inside the+[Neovim](https://github.com/neovimhaskell/nvim-hs/blob/master/library/Neovim.hs)+module ([hackage](http://hackage.haskell.org/package/nvim-hs-0.0.5/docs/Neovim.html)).++# Contributing++Documentation, typo fixes and alike will almost always be merged.++If you want to bring forward new features or convenience libraries+for interacting with neovim, you should create an issue first. The features+of this (cabal) project should be kept small as this helps+reducing the development time. (For some tests it is+necessary to issue `cabal install`, so any change to to a module can+significantly increase the compilation time.)+If your idea solves a general problem, feel free to open an issue in the+library project of nvim-hs:+[nvim-hs-contrib](https://github.com/neovimhaskell/nvim-hs-contrib)+
library/Neovim.hs view
@@ -41,6 +41,7 @@     NeovimPlugin(..),     Plugin(..),     NvimObject(..),+    (+:),     Dictionary,     Object(..),     wrapPlugin,@@ -74,6 +75,10 @@     waitErr,     waitErr',     err,+    Doc,+    errOnInvalidResult,+    text,+    NeovimException(..),     -- ** Generated functions for neovim interaction     module Neovim.API.String, @@ -94,34 +99,38 @@     ) where  import           Control.Applicative-import           Control.Monad              (void)-import           Control.Monad.IO.Class     (liftIO)-import           Data.Default               (def)-import           Data.Int                   (Int16, Int32, Int64, Int8)-import           Data.MessagePack           (Object (..))+import           Control.Monad                (void)+import           Control.Monad.IO.Class       (liftIO)+import           Data.Default                 (def)+import           Data.Int                     (Int16, Int32, Int64, Int8)+import           Data.MessagePack             (Object (..)) import           Data.Monoid-import           Data.Word                  (Word, Word32,Word16, Word8)+import           Data.Word                    (Word, Word16, Word32, Word8) import           Neovim.API.String-import           Neovim.API.TH              (autocmd, command, command',-                                             function, function')-import           Neovim.Classes             (Dictionary, NvimObject (..))-import           Neovim.Config              (NeovimConfig (..))-import           Neovim.Context             (Neovim, Neovim', ask, asks, err,-                                             get, gets, modify, put)-import           Neovim.Main                (neovim)-import           Neovim.Plugin              (addAutocmd, addAutocmd')-import           Neovim.Plugin.Classes      (AutocmdOptions (..),-                                             CommandArguments (..), CommandOption (CmdSync, CmdRegister, CmdRange, CmdCount, CmdBang),-                                             RangeSpecification (..),-                                             Synchronous (..))-import qualified Neovim.Plugin.ConfigHelper as ConfigHelper-import           Neovim.Plugin.Internal     (NeovimPlugin (..), Plugin (..),-                                             wrapPlugin)-import           Neovim.Plugin.Startup      (StartupConfig(..))-import           Neovim.RPC.FunctionCall    (wait, wait', waitErr, waitErr')-import           Neovim.Util                (unlessM, whenM,-                                             withCustomEnvironment)-import           System.Log.Logger          (Priority (..))+import           Neovim.API.TH                (autocmd, command, command',+                                               function, function')+import           Neovim.Classes               (Dictionary, NvimObject (..), (+:))+import           Neovim.Config                (NeovimConfig (..))+import           Neovim.Context               (Neovim, Neovim',+                                               NeovimException (ErrorMessage),+                                               ask, asks, err,+                                               errOnInvalidResult, get, gets,+                                               modify, put)+import           Neovim.Main                  (neovim)+import           Neovim.Plugin                (addAutocmd, addAutocmd')+import           Neovim.Plugin.Classes        (AutocmdOptions (..),+                                               CommandArguments (..), CommandOption (CmdSync, CmdRegister, CmdRange, CmdCount, CmdBang),+                                               RangeSpecification (..),+                                               Synchronous (..))+import qualified Neovim.Plugin.ConfigHelper   as ConfigHelper+import           Neovim.Plugin.Internal       (NeovimPlugin (..), Plugin (..),+                                               wrapPlugin)+import           Neovim.Plugin.Startup        (StartupConfig (..))+import           Neovim.RPC.FunctionCall      (wait, wait', waitErr, waitErr')+import           Neovim.Util                  (unlessM, whenM,+                                               withCustomEnvironment)+import           System.Log.Logger            (Priority (..))+import           Text.PrettyPrint.ANSI.Leijen (Doc, text)  -- Installation {{{1 -- tl;dr installation {{{2@@ -245,8 +254,14 @@ The code sections that describe new functionality are followed by the source code documentation of the used functions (and possibly a few more). +The config directory location adheres to the+<http://standards.freedesktop.org/basedir-spec/basedir-spec-latest.html XDG-basedir specification>.+Unless you have changed some \$XDG_\* environment variables, the configuration+directory on unixoid systems (e.g. MacOS X, most GNU/Linux distribution, most+BSD distributions) is @\$HOME\/.config\/nvim@.+ Create a file called @nvim.hs@ in @\$XDG_CONFIG_HOME\/nvim@ (usually-@~\/.config\/nvim@ with the following content:+@~\/.config\/nvim@) with the following content:  @ import Neovim@@ -254,7 +269,7 @@ main = 'neovim' 'defaultConfig' @ -Adjust the fields in 'defaultConfig' according to the the parameters in 'NeovimConfig'.+Adjust the fields in 'defaultConfig' according to the parameters in 'NeovimConfig'. Depending on how you define the parameters, you may have to add some language extensions which GHC should point you to. @@ -326,17 +341,17 @@ it will present you with helpful error messages if your plugin's functions do not work together with neovim. -So, let's write a plugin that calculates the @n@th Fibonacci number. Don't we all+So, let\'s write a plugin that calculates the @n@th Fibonacci number. Don\'t we all love those! -File @~\/.config\/nvim\/lib\/Fibonacci/Plugin.hs@+File @\~\/.config\/nvim\/lib\/Fibonacci\/Plugin.hs@:  @ module Fibonacci.Plugin (fibonacci) where  import "Neovim" --- | Neovim is not really good with big numbers, so we return a 'String' here.+\-\- \| Neovim is not really good with big numbers, so we return a 'String' here. fibonacci :: 'Int' -> 'Neovim'' 'String' fibonacci n = 'return' . 'show' \$ fibs !! n   where@@ -344,7 +359,7 @@     fibs = 0:1:'scanl1' (+) fibs @ -File @~\/.config\/nvim\/lib/Fibonacci.hs@:+File @\~\/.config\/nvim\/lib\/Fibonacci.hs@:  @ \{\-\# LANGUAGE TemplateHaskell \#\-\}@@ -385,11 +400,11 @@ You can use any argument or result type as long as it is an instance of 'NvimObject'.  The second part of of the puzzle, which is the definition of @plugin@-in @~\/.config\/nvim\/lib\/Fibonaccin.hs@, shows what a plugin is. It is essentially two+in @~\/.config\/nvim\/lib\/Fibonacci.hs@, shows what a plugin is. It is essentially two lists of stateless and stateful functionality. A functionality can currently be one of three things: a function, a command and an autocmd in the context of vim terminology. In the end, all of those functionalities map to a function at the side-of /nvim-hs/. If you really want to know what the distinction between those, you+of /nvim-hs/. If you really want to know what the distinction between those is, you have to consult the @:help@ pages of neovim (e.g. @:help :function@, @:help :command@ and @:help :autocmd@). What's relevant from the side of /nvim-hs/ is the distinction between __stateful__ and __stateless__. A stateless function can be called at any@@ -440,7 +455,7 @@ -} -- 2}}} -- Creating a stateful plugin {{{2-{- $remote+{- $statefulplugin Now that we are a little bit comfortable with the interface provided by /nvim-hs/, we can start to write a more complicated plugin. Let's create a random number generator!@@ -452,14 +467,14 @@  import "Neovim" --- | Neovim isn't so good with big numbers here either.+\-\- | Neovim isn't so good with big numbers here either. nextRandom :: 'Neovim' r ['Int16'] 'Int16' nextRandom = do     r <- 'gets' 'head' -- get the head of the infinite random number list     'modify' 'tail'    -- set the list to its tail     'return' r -setNextRandom :: 'Int' -> 'Neovim' r ['Int16'] ()+setNextRandom :: 'Int16' -> 'Neovim' r ['Int16'] () setNextRandom n = 'modify' (n:) -- cons to the front of the infinite list @ 
library/Neovim/API/Parser.hs view
@@ -22,15 +22,17 @@ import           Control.Applicative import           Control.Exception.Lifted import           Control.Monad.Except-import qualified Data.ByteString          as B-import           Data.Map                 (Map)-import qualified Data.Map                 as Map+import qualified Data.ByteString              as B+import           Data.Map                     (Map)+import qualified Data.Map                     as Map import           Data.MessagePack import           Data.Monoid import           Data.Serialize-import           System.IO                (hClose)+import           System.IO                    (hClose) import           System.Process-import           Text.Parsec              as P+import           Text.Parsec                  as P+import           Text.PrettyPrint.ANSI.Leijen (Doc)+import qualified Text.PrettyPrint.ANSI.Leijen as P  import           Prelude @@ -79,11 +81,15 @@     deriving (Show)  -- | Run @nvim --api-info@ and parse its output.-parseAPI :: IO (Either String NeovimAPI)-parseAPI = join . fmap extractAPI <$> decodeAPI+parseAPI :: IO (Either Doc NeovimAPI)+parseAPI = decodeAPI >>= \case+    Left e ->+        (return . Left . P.text) e +    Right o ->+        (return . extractAPI) o -extractAPI :: Object -> Either String NeovimAPI+extractAPI :: Object -> Either Doc NeovimAPI extractAPI apiObj = NeovimAPI     <$> extractErrorTypes apiObj     <*> extractCustomTypes apiObj@@ -105,22 +111,22 @@         terminateProcess ph  -oMap :: Object -> Either String (Map Object Object)+oMap :: Object -> Either Doc (Map Object Object) oMap = \case     ObjectMap m ->         return m      o ->-        throwError $ "Object is not a map: " ++ show o+        throwError . P.text $ "Object is not a map: " ++ show o  -oLookup :: Object -> Object -> Either String Object+oLookup :: Object -> Object -> Either Doc Object oLookup qry o = oMap o-    >>= maybe (throwError ("No entry for" <> show qry)) return+    >>= maybe (throwError (P.text ("No entry for" <> show qry))) return         . Map.lookup qry  -oLookupDefault :: Object -> Object -> Object -> Either String Object+oLookupDefault :: Object -> Object -> Object -> Either Doc Object oLookupDefault d qry o = oMap o     >>= maybe (return d) return . Map.lookup qry @@ -128,7 +134,7 @@ -- | Extract a 'String' from on 'Object'. -- -- Works on @ObjectBinary@ and @ObjectString@ constructor.-oToString :: Object -> Either String String+oToString :: Object -> Either Doc String oToString = fromObject     -- ObjectBinary bs -> return $ U.toString bs     -- ObjectString t  -> return $ U.toString t@@ -137,24 +143,24 @@  -- | Extract an 'Int64' from an @Object@. ---oInt :: Object -> Either String Int64+oInt :: Object -> Either Doc Int64 oInt = fromObject  -oArr :: Object -> Either String [Object]+oArr :: Object -> Either Doc [Object] oArr = fromObject  -oToBool :: Object -> Either String Bool+oToBool :: Object -> Either Doc Bool oToBool = fromObject  -extractErrorTypes :: Object -> Either String [(String, Int64)]+extractErrorTypes :: Object -> Either Doc [(String, Int64)] extractErrorTypes objAPI =     extractTypeNameAndID =<< oLookup (ObjectBinary "error_types") objAPI  -extractTypeNameAndID :: Object -> Either String [(String, Int64)]+extractTypeNameAndID :: Object -> Either Doc [(String, Int64)] extractTypeNameAndID m = do     types <- Map.toList <$> oMap m     forM types $ \(errName, idMap) -> do@@ -163,24 +169,24 @@         return (n,i)  -extractCustomTypes :: Object -> Either String [(String, Int64)]+extractCustomTypes :: Object -> Either Doc [(String, Int64)] extractCustomTypes objAPI =     extractTypeNameAndID =<< oLookup (ObjectBinary "types") objAPI  -extractFunctions :: Object -> Either String [NeovimFunction]+extractFunctions :: Object -> Either Doc [NeovimFunction] extractFunctions objAPI = do     funList <- oArr =<< oLookup (ObjectBinary "functions") objAPI     forM funList extractFunction  -toParameterlist :: [Object] -> Either String [(NeovimType, String)]+toParameterlist :: [Object] -> Either Doc [(NeovimType, String)] toParameterlist ps = forM ps $ \p -> do     [t, n] <- mapM oToString =<< oArr p     t' <- parseType t     return (t', n) -extractFunction :: Object -> Either String NeovimFunction+extractFunction :: Object -> Either Doc NeovimFunction extractFunction funDefMap = NeovimFunction     <$> (oLookup (ObjectBinary "name") funDefMap >>= oToString)     <*> (oLookup (ObjectBinary "parameters") funDefMap@@ -191,8 +197,8 @@     <*> (oLookup (ObjectBinary "return_type") funDefMap             >>= oToString >>= parseType) -parseType :: String -> Either String NeovimType-parseType s = either (throwError . show) return $ parse (pType <* eof) s s+parseType :: String -> Either Doc NeovimType+parseType s = either (throwError . P.text . show) return $ parse (pType <* eof) s s   pType :: Parsec String u NeovimType
library/Neovim/API/TH.hs view
@@ -40,7 +40,7 @@ import           Language.Haskell.TH  import           Control.Applicative-import           Control.Arrow+import           Control.Arrow (first) import           Control.Concurrent.STM   (STM) import           Control.Exception import           Control.Exception.Lifted@@ -56,6 +56,7 @@ import           Data.Monoid import qualified Data.Set                 as Set import           Data.Text                (Text)+import           Text.PrettyPrint.ANSI.Leijen (text, (<+>))  import           Prelude @@ -69,7 +70,7 @@ -- 'ByteString' or 'String'. generateAPI :: Map String (Q Type) -> Q [Dec] generateAPI typeMap = do-    api <- either fail return =<< runIO parseAPI+    api <- either (fail . show) return =<< runIO parseAPI     let exceptionName = mkName "NeovimExceptionGen"         exceptions = (\(n,i) -> (mkName ("Neovim" <> n), i)) <$> errorTypes api         customTypesN = first mkName <$> customTypes api@@ -226,7 +227,10 @@             let n = nameBase typeName             clause                 [ varP o ]-                (normalB [|Left $ "Object is not convertible to: " <> n <> " Received: " <> show $(varE o)|])+                (normalB [|throwError $+                            text "Object is not convertible to:"+                            <+> text n+                            <+> text "Received:" <+> (text . show) $(varE o)|])                 []          toObjectClause :: Name -> Int64 -> Q Clause@@ -246,7 +250,7 @@         ]  --- | Define an exported function by providing a cutom name and referencing the+-- | Define an exported function by providing a custom name and referencing the -- function you want to export. -- -- Note that the name must start with an upper case letter.@@ -329,8 +333,8 @@ -- Example: @ $(command \"RememberThePrime\" 'someFunction) ['CmdBang'] @ -- -- Note that the list of command options (i.e. the last argument) removes--- duplicate options by means of some internally convienient sorting. You should--- simply not defined the same option twice.+-- duplicate options by means of some internally convenient sorting. You should+-- simply not define the same option twice. command :: String -> Name -> Q Exp command [] _ = error "Empty names are not allowed for exported commands." command customFunctionName@(c:_) functionName@@ -449,7 +453,7 @@     -- _ -> err "Wrong number of arguments"     errorCase :: Q Match     errorCase = match wildP-        (normalB [|err $ "Wrong number of arguments for function: "+        (normalB [|throw . ErrorMessage . text $ "Wrong number of arguments for function: "                         ++ $(litE (StringL (nameBase functionName))) |]) []      -- [x,y] -> case pure add <*> fromObject x <*> fromObject y of ...
library/Neovim/Classes.hs view
@@ -17,32 +17,44 @@ module Neovim.Classes     ( NvimObject(..)     , Dictionary+    , (+:)      , module Data.Int     , module Data.Word     ) where - import           Control.Applicative import           Control.Arrow import           Control.Monad.Except-import           Data.ByteString      (ByteString)-import           Data.Int             (Int16, Int32, Int64, Int8)-import           Data.Map             (Map)-import qualified Data.Map             as Map+import           Data.ByteString              (ByteString)+import           Data.Int                     (Int16, Int32, Int64, Int8)+import           Data.Map                     (Map)+import qualified Data.Map                     as Map import           Data.MessagePack import           Data.Monoid-import           Data.Text            as Text (Text)-import           Data.Traversable     hiding (forM, mapM)-import           Data.Word            (Word, Word16, Word32, Word64, Word8)+import           Data.Text                    as Text (Text)+import           Data.Traversable             hiding (forM, mapM)+import           Data.Word                    (Word, Word16, Word32, Word64,+                                               Word8)+import           Text.PrettyPrint.ANSI.Leijen (Doc, displayS, lparen,+                                               renderPretty, rparen, text)+import qualified Text.PrettyPrint.ANSI.Leijen as P  import           Prelude  -- FIXME saep 2014-11-28 Is assuming UTF-8 reasonable?-import qualified Data.ByteString.UTF8 as U (fromString, toString)-import           Data.Text.Encoding   (decodeUtf8, encodeUtf8)+import qualified Data.ByteString.UTF8         as U (fromString, toString)+import           Data.Text.Encoding           (decodeUtf8, encodeUtf8)  +infixr 5 +:+++-- | Convenient operator to create a list of 'Object' from normal values.+(+:) :: (NvimObject o) => o -> [Object] -> [Object]+o +: os = toObject o : os++ -- | A generic vim dictionary is a simply a map from strings to objects.  This -- type alias is sometimes useful as a type annotation especially if the -- OverloadedStrings extension is enabled.@@ -56,13 +68,12 @@      fromObjectUnsafe :: Object -> o     fromObjectUnsafe o = case fromObject o of-        Left e -> error $ unwords-            [ "Not the expected object:"-            , show o , "(", e, ")"-            ]+        Left e -> error . show $+            text "Not the expected object:" P.<+> (text . show) o+            P.<+> lparen P.<> e P.<> rparen         Right obj -> obj -    fromObject :: (NvimObject o) => Object -> Either String o+    fromObject :: (NvimObject o) => Object -> Either Doc o     fromObject = return . fromObjectUnsafe  @@ -71,7 +82,7 @@     toObject _           = ObjectNil      fromObject ObjectNil = return ()-    fromObject o         = throwError $ "Expected ObjectNil, but got " <> show o+    fromObject o         = throwError . text $ "Expected ObjectNil, but got " <> show o   -- We may receive truthy values from neovim, so we should be more forgiving@@ -95,7 +106,7 @@     fromObject (ObjectDouble o) = return o     fromObject (ObjectFloat o)  = return $ realToFrac o     fromObject (ObjectInt o)    = return $ fromIntegral o-    fromObject o                = throwError $ "Expected ObjectDouble, but got " <> show o+    fromObject o                = throwError . text $ "Expected ObjectDouble, but got " <> show o   instance NvimObject Integer where@@ -104,7 +115,7 @@     fromObject (ObjectInt o)    = return $ toInteger o     fromObject (ObjectDouble o) = return $ round o     fromObject (ObjectFloat o)  = return $ round o-    fromObject o                = throwError $ "Expected ObjectInt, but got " <> show o+    fromObject o                = throwError . text $ "Expected ObjectInt, but got " <> show o   instance NvimObject Int64 where@@ -113,7 +124,7 @@     fromObject (ObjectInt i)    = return i     fromObject (ObjectDouble o) = return $ round o     fromObject (ObjectFloat o)  = return $ round o-    fromObject o                = throwError $ "Expected any Integer value, but got " <> show o+    fromObject o                = throwError . text $ "Expected any Integer value, but got " <> show o   instance NvimObject Int32 where@@ -122,7 +133,7 @@     fromObject (ObjectInt i)    = return $ fromIntegral i     fromObject (ObjectDouble o) = return $ round o     fromObject (ObjectFloat o)  = return $ round o-    fromObject o                = throwError $ "Expected any Integer value, but got " <> show o+    fromObject o                = throwError . text $ "Expected any Integer value, but got " <> show o   instance NvimObject Int16 where@@ -131,7 +142,7 @@     fromObject (ObjectInt i)    = return $ fromIntegral i     fromObject (ObjectDouble o) = return $ round o     fromObject (ObjectFloat o)  = return $ round o-    fromObject o                = throwError $ "Expected any Integer value, but got " <> show o+    fromObject o                = throwError . text $ "Expected any Integer value, but got " <> show o   instance NvimObject Int8 where@@ -140,7 +151,7 @@     fromObject (ObjectInt i)    = return $ fromIntegral i     fromObject (ObjectDouble o) = return $ round o     fromObject (ObjectFloat o)  = return $ round o-    fromObject o                = throwError $ "Expected any Integer value, but got " <> show o+    fromObject o                = throwError . text $ "Expected any Integer value, but got " <> show o   instance NvimObject Word where@@ -149,7 +160,7 @@     fromObject (ObjectInt i)    = return $ fromIntegral i     fromObject (ObjectDouble o) = return $ round o     fromObject (ObjectFloat o)  = return $ round o-    fromObject o                = throwError $ "Expected any Integer value, but got " <> show o+    fromObject o                = throwError . text $ "Expected any Integer value, but got " <> show o   instance NvimObject Word64 where@@ -158,7 +169,7 @@     fromObject (ObjectInt i)    = return $ fromIntegral i     fromObject (ObjectDouble o) = return $ round o     fromObject (ObjectFloat o)  = return $ round o-    fromObject o                = throwError $ "Expected any Integer value, but got " <> show o+    fromObject o                = throwError . text $ "Expected any Integer value, but got " <> show o   instance NvimObject Word32 where@@ -167,7 +178,7 @@     fromObject (ObjectInt i)    = return $ fromIntegral i     fromObject (ObjectDouble o) = return $ round o     fromObject (ObjectFloat o)  = return $ round o-    fromObject o                = throwError $ "Expected any Integer value, but got " <> show o+    fromObject o                = throwError . text $ "Expected any Integer value, but got " <> show o   instance NvimObject Word16 where@@ -176,7 +187,7 @@     fromObject (ObjectInt i)    = return $ fromIntegral i     fromObject (ObjectDouble o) = return $ round o     fromObject (ObjectFloat o)  = return $ round o-    fromObject o                = throwError $ "Expected any Integer value, but got " <> show o+    fromObject o                = throwError . text $ "Expected any Integer value, but got " <> show o   instance NvimObject Word8 where@@ -185,7 +196,7 @@     fromObject (ObjectInt i)    = return $ fromIntegral i     fromObject (ObjectDouble o) = return $ round o     fromObject (ObjectFloat o)  = return $ round o-    fromObject o                = throwError $ "Expected any Integer value, but got " <> show o+    fromObject o                = throwError . text $ "Expected any Integer value, but got " <> show o   instance NvimObject Int where@@ -194,7 +205,7 @@     fromObject (ObjectInt i)    = return $ fromIntegral i     fromObject (ObjectDouble o) = return $ round o     fromObject (ObjectFloat o)  = return $ round o-    fromObject o                = throwError $ "Expected any Integer value, but got " <> show o+    fromObject o                = throwError . text $ "Expected any Integer value, but got " <> show o   instance NvimObject Char where@@ -202,7 +213,7 @@      fromObject str = case fromObject str of         Right [c] -> return c-        _   -> throwError $ "Expected one element string but got: " <> show str+        _   -> throwError . text $ "Expected one element string but got: " <> show str   instance NvimObject [Char] where@@ -210,14 +221,14 @@      fromObject (ObjectBinary o) = return $ U.toString o     fromObject (ObjectString o) = return $ U.toString o-    fromObject o                = throwError $ "Expected ObjectBinary, but got " <> show o+    fromObject o                = throwError . text $ "Expected ObjectBinary, but got " <> show o   instance NvimObject o => NvimObject [o] where     toObject                    = ObjectArray . map toObject      fromObject (ObjectArray os) = mapM fromObject os-    fromObject o                = throwError $ "Expected ObjectArray, but got " <> show o+    fromObject o                = throwError . text $ "Expected ObjectArray, but got " <> show o   instance NvimObject o => NvimObject (Maybe o) where@@ -241,7 +252,7 @@                                       return $ Left l                                    Left e2 ->-                                      throwError $ e1 ++ " -- " ++ e2+                                      throwError $ e1 P.<+> text "--" P.<+> e2   instance (Ord key, NvimObject key, NvimObject val)@@ -255,7 +266,7 @@                     . (fromObject *** fromObject))                 . Map.toList) om -    fromObject o = throwError $ "Expected ObjectMap, but got " <> show o+    fromObject o = throwError . text $ "Expected ObjectMap, but got " <> show o   instance NvimObject Text where@@ -263,14 +274,14 @@      fromObject (ObjectBinary o) = return $ decodeUtf8 o     fromObject (ObjectString o) = return $ decodeUtf8 o-    fromObject o                = throwError $ "Expected ObjectBinary, but got " <> show o+    fromObject o                = throwError . text $ "Expected ObjectBinary, but got " <> show o   instance NvimObject ByteString where     toObject                    = ObjectBinary      fromObject (ObjectBinary o) = return o-    fromObject o                = throwError $ "Expected ObjectBinary, but got " <> show o+    fromObject o                = throwError . text $ "Expected ObjectBinary, but got " <> show o   instance NvimObject Object where@@ -280,6 +291,12 @@     fromObjectUnsafe = id  +instance NvimObject Doc where+    toObject d = toObject $ displayS (renderPretty 1.0 240 d) ""++    fromObject = fmap text . fromObject++ -- By the magic of vim, i will create these. instance (NvimObject o1, NvimObject o2) => NvimObject (o1, o2) where     toObject (o1, o2) = ObjectArray $ [toObject o1, toObject o2]@@ -287,7 +304,7 @@     fromObject (ObjectArray [o1, o2]) = (,)         <$> fromObject o1         <*> fromObject o2-    fromObject o = throwError $ "Expected ObjectArray, but got " <> show o+    fromObject o = throwError . text $ "Expected ObjectArray, but got " <> show o  instance (NvimObject o1, NvimObject o2, NvimObject o3) => NvimObject (o1, o2, o3) where     toObject (o1, o2, o3) = ObjectArray $ [toObject o1, toObject o2, toObject o3]@@ -296,7 +313,7 @@         <$> fromObject o1         <*> fromObject o2         <*> fromObject o3-    fromObject o = throwError $ "Expected ObjectArray, but got " <> show o+    fromObject o = throwError . text $ "Expected ObjectArray, but got " <> show o   instance (NvimObject o1, NvimObject o2, NvimObject o3, NvimObject o4) => NvimObject (o1, o2, o3, o4) where@@ -307,7 +324,7 @@         <*> fromObject o2         <*> fromObject o3         <*> fromObject o4-    fromObject o = throwError $ "Expected ObjectArray, but got " <> show o+    fromObject o = throwError . text $ "Expected ObjectArray, but got " <> show o   instance (NvimObject o1, NvimObject o2, NvimObject o3, NvimObject o4, NvimObject o5) => NvimObject (o1, o2, o3, o4, o5) where@@ -319,7 +336,7 @@         <*> fromObject o3         <*> fromObject o4         <*> fromObject o5-    fromObject o = throwError $ "Expected ObjectArray, but got " <> show o+    fromObject o = throwError . text $ "Expected ObjectArray, but got " <> show o   instance (NvimObject o1, NvimObject o2, NvimObject o3, NvimObject o4, NvimObject o5, NvimObject o6) => NvimObject (o1, o2, o3, o4, o5, o6) where@@ -332,7 +349,7 @@         <*> fromObject o4         <*> fromObject o5         <*> fromObject o6-    fromObject o = throwError $ "Expected ObjectArray, but got " <> show o+    fromObject o = throwError . text $ "Expected ObjectArray, but got " <> show o   instance (NvimObject o1, NvimObject o2, NvimObject o3, NvimObject o4, NvimObject o5, NvimObject o6, NvimObject o7) => NvimObject (o1, o2, o3, o4, o5, o6, o7) where@@ -346,7 +363,7 @@         <*> fromObject o5         <*> fromObject o6         <*> fromObject o7-    fromObject o = throwError $ "Expected ObjectArray, but got " <> show o+    fromObject o = throwError . text $ "Expected ObjectArray, but got " <> show o   instance (NvimObject o1, NvimObject o2, NvimObject o3, NvimObject o4, NvimObject o5, NvimObject o6, NvimObject o7, NvimObject o8) => NvimObject (o1, o2, o3, o4, o5, o6, o7, o8) where@@ -361,7 +378,7 @@         <*> fromObject o6         <*> fromObject o7         <*> fromObject o8-    fromObject o = throwError $ "Expected ObjectArray, but got " <> show o+    fromObject o = throwError . text $ "Expected ObjectArray, but got " <> show o   instance (NvimObject o1, NvimObject o2, NvimObject o3, NvimObject o4, NvimObject o5, NvimObject o6, NvimObject o7, NvimObject o8, NvimObject o9) => NvimObject (o1, o2, o3, o4, o5, o6, o7, o8, o9) where@@ -377,7 +394,7 @@         <*> fromObject o7         <*> fromObject o8         <*> fromObject o9-    fromObject o = throwError $ "Expected ObjectArray, but got " <> show o+    fromObject o = throwError . text $ "Expected ObjectArray, but got " <> show o   -- 1}}}
library/Neovim/Config.hs view
@@ -19,7 +19,7 @@  import           System.Log             (Priority (..)) --- | This data type contins information about the configuration of neovim. See+-- | This data type contains information about the configuration of neovim. See -- the fields' documentation for what you possibly want to change. Also, the -- tutorial in the "Neovim" module should get you started. data NeovimConfig = Config
library/Neovim/Context.hs view
@@ -1,5 +1,4 @@-{-# LANGUAGE DeriveDataTypeable #-}-{-# LANGUAGE LambdaCase         #-}+{-# LANGUAGE LambdaCase #-} {- | Module      :  Neovim.Context Description :  The Neovim context@@ -22,6 +21,7 @@     runNeovim,     forkNeovim,     err,+    errOnInvalidResult,     restart,     quit, @@ -37,33 +37,42 @@     ) where  -import           Neovim.Context.Internal (FunctionMap, FunctionMapEntry, Neovim,-                                          Neovim', forkNeovim, mkFunctionMap,-                                          newUniqueFunctionName, runNeovim)-import qualified Neovim.Context.Internal as Internal+import           Neovim.Classes+import           Neovim.Context.Internal      (FunctionMap, FunctionMapEntry,+                                               Neovim, Neovim',+                                               NeovimException (ErrorMessage),+                                               forkNeovim, mkFunctionMap,+                                               newUniqueFunctionName, runNeovim)+import qualified Neovim.Context.Internal      as Internal -import           Control.Concurrent      (putMVar)+import           Control.Concurrent           (putMVar) import           Control.Exception import           Control.Monad.Except import           Control.Monad.IO.Class import           Control.Monad.Reader import           Control.Monad.State-import           Data.Data               (Typeable)+import           Data.MessagePack             (Object)+import           Text.PrettyPrint.ANSI.Leijen (Doc, text)  --- | Exceptions specific to /nvim-hs/.-data NeovimException-    = ErrorMessage String-    -- ^ Simply error message that is passed to neovim. It should currently only-    -- contain one line of text.-    deriving (Typeable, Show)+-- | @'throw'@ specialized to 'Doc'. If you do not care about pretty printing,+-- you can simply use 'text' in front of your string or use the+-- @OverloadedStrings@ extension to specify the error message.+err :: Doc ->  Neovim r st a+err = throw . ErrorMessage -instance Exception NeovimException +errOnInvalidResult :: (NvimObject o) => Neovim r st (Either Object Object) -> Neovim r st o+errOnInvalidResult a = a >>= \case+    Left o ->+        (err . text . show) o --- | @throw . ErrorMessage@-err :: String ->  Neovim r st a-err = throw . ErrorMessage+    Right o -> case fromObject o of+        Left e ->+            err e++        Right x ->+            return x   -- | Initiate a restart of the plugin provider.
library/Neovim/Context/Internal.hs view
@@ -1,3 +1,4 @@+{-# LANGUAGE DeriveDataTypeable         #-} {-# LANGUAGE FlexibleInstances          #-} {-# LANGUAGE GADTs                      #-} {-# LANGUAGE GeneralizedNewtypeDeriving #-}@@ -31,11 +32,14 @@ import           Control.Monad.Reader import           Control.Monad.State import           Control.Monad.Trans.Resource-import           Data.ByteString.UTF8         (fromString)+import qualified Data.ByteString.UTF8         as U (fromString)+import           Data.Data                    (Typeable) import           Data.Map                     (Map) import qualified Data.Map                     as Map import           Data.MessagePack             (Object)+import           Data.String                  (IsString (..)) import           System.Log.Logger+import           Text.PrettyPrint.ANSI.Leijen hiding ((<$>))  import           Prelude @@ -83,18 +87,42 @@ type Neovim' = Neovim () ()  +-- | Exceptions specific to /nvim-hs/.+data NeovimException+    = ErrorMessage Doc+    -- ^ Simply error message that is passed to neovim. It should currently only+    -- contain one line of text.+    deriving (Typeable, Show)+++instance Exception NeovimException+++instance IsString NeovimException where+    fromString = ErrorMessage . fromString+++instance Pretty NeovimException where+    pretty = \case+        ErrorMessage s -> s++ -- | Initialize a 'Neovim' context by supplying an 'InternalEnvironment'. runNeovim :: Config r st           -> st           -> Neovim r st a-          -> IO (Either String (a, st))+          -> IO (Either Doc (a, st)) runNeovim r st (Neovim a) = (try . runReaderT (runStateT (runResourceT a) st)) r >>= \case-    Left e -> do-        liftIO . errorM "Context" $ "Converting Exception to Error message: " ++ show e-        return . Left $ show (e :: SomeException)-    Right res -> return $ Right res+    Left e -> case fromException e of+        Just e' ->+            return . Left . pretty $ (e' :: NeovimException) +        Nothing -> do+            liftIO . errorM "Context" $ "Converting Exception to Error message: " ++ show e+            (return . Left . text . show) e+    Right res -> (return . Right) res + -- | Fork a neovim thread with the given custom config value and a custom -- state. The result of the thread is discarded and only the 'ThreadId' is -- returend immediately.@@ -117,7 +145,7 @@     tu <- asks' uniqueCounter     -- reverseing the integer string should distribute the first character more     -- evently and hence cause faster termination for comparisons.-    fmap (F . fromString . reverse . show) . liftIO . atomically $ do+    fmap (F . U.fromString . reverse . show) . liftIO . atomically $ do         u <- readTVar tu         modifyTVar' tu succ         return u@@ -134,6 +162,12 @@     -- is the communication endpoint for the arguments we have to pass.  +instance Pretty FunctionType where+    pretty = \case+        Stateless _ -> blue $ text "\\os -> Neovim' o"+        Stateful  _ -> green $ text "\\os -> Neovim r st o"++ -- | Type of the values stored in the function map. type FunctionMapEntry = (FunctionalityDescription, FunctionType) @@ -193,6 +227,8 @@      -- Local settings; intialized for each stateful component     , pluginSettings    :: Maybe (PluginSettings r st)+    -- ^ In a registered functionality this field contains a function (and+    -- possibly some context dependent values) to register new functionality.      , customConfig      :: r     -- ^ Plugin author supplyable custom configuration. Queried on the@@ -254,10 +290,10 @@     | Restart     -- ^ Restart the plugin provider. -    | Failure String+    | Failure Doc     -- ^ The plugin provider failed to start or some other error occured.      | InitSuccess     -- ^ The plugin provider started successfully. -    deriving (Show, Read, Eq, Ord)+    deriving (Show)
library/Neovim/Debug.hs view
@@ -17,22 +17,29 @@     quitDevelMain,     restartDevelMain, +    printGlobalFunctionMap,+     runNeovim,     runNeovim',     module Neovim,     ) where  import           Neovim-import           Neovim.Context          (runNeovim)-import qualified Neovim.Context.Internal as Internal-import           Neovim.Log              (disableLogger)-import           Neovim.Main             (CommandLineOptions (..),-                                          runPluginProvider)-import           Neovim.RPC.Common       (RPCConfig)+import           Neovim.Context               (runNeovim)+import qualified Neovim.Context.Internal      as Internal+import           Neovim.Log                   (disableLogger)+import           Neovim.Main                  (CommandLineOptions (..),+                                               runPluginProvider)+import           Neovim.RPC.Common            (RPCConfig)  import           Control.Concurrent+import           Control.Concurrent.STM import           Control.Monad+import qualified Data.Map                     as Map import           Foreign.Store+import           System.IO                    (stdout)+import           Text.PrettyPrint.ANSI.Leijen hiding ((<$>))+import qualified Text.PrettyPrint.ANSI.Leijen as Pretty  import           Prelude @@ -46,7 +53,7 @@ -- -- Tip: If you run a terminal inside a neovim instance, then this variable is -- automatically set.-debug :: r -> st -> Internal.Neovim r st a -> IO (Either String (a, st))+debug :: r -> st -> Internal.Neovim r st a -> IO (Either Doc (a, st)) debug r st a = disableLogger $ do     runPluginProvider def { env = True } Nothing transitionHandler Nothing   where@@ -64,7 +71,7 @@             return res          _ ->-            return $ Left "Unexpected transition state."+            return . Left $ text "Unexpected transition state."   -- | Run a 'Neovim'' function.@@ -74,7 +81,7 @@ -- @ -- -- See documentation for 'debug'.-debug' :: Internal.Neovim' a -> IO (Either String a)+debug' :: Internal.Neovim' a -> IO (Either Doc a) debug' a = fmap fst <$> debug () () a  @@ -102,7 +109,7 @@ -- develMain     :: Maybe NeovimConfig-    -> IO (Either String ([ThreadId], Internal.Config RPCConfig ()))+    -> IO (Either Doc ([ThreadId], Internal.Config RPCConfig ())) develMain mcfg = lookupStore 0 >>= \case     Nothing -> do         x <- disableLogger $@@ -132,10 +139,10 @@                     deleteStore x              mapM_ killThread tids-            return $ Left "Quit develMain"+            return . Left $ text "Quit develMain"          _ ->-            return $ Left "Unexpected transition state for develMain."+            return . Left $ text "Unexpected transition state for develMain."   -- | Quit a previously started plugin provider.@@ -147,15 +154,30 @@ restartDevelMain     :: Internal.Config RPCConfig ()     -> Maybe NeovimConfig-    -> IO (Either String ([ThreadId], Internal.Config RPCConfig ()))+    -> IO (Either Doc ([ThreadId], Internal.Config RPCConfig ())) restartDevelMain cfg mcfg = do     quitDevelMain cfg     develMain mcfg   -- | Convenience function to run a stateless 'Neovim' function.-runNeovim' :: Internal.Config r st -> Neovim' a -> IO (Either String a)+runNeovim' :: Internal.Config r st -> Neovim' a -> IO (Either Doc a) runNeovim' cfg =     fmap (fmap fst) . runNeovim (Internal.retypeConfig () () cfg) ()+++-- | Print the global function map to the console.+printGlobalFunctionMap :: Internal.Config r st -> IO ()+printGlobalFunctionMap cfg = do+    es <- fmap Map.toList . atomically $ readTMVar (Internal.globalFunctionMap cfg)+    let header = text "Printing global function map:"+        funs   = map (\(fname, (d, f)) ->+                    nest 3 (pretty fname+                    </> text "->"+                    </> pretty d <+> text ":"+                    <+> pretty f)) es+    displayIO stdout . renderPretty 0.4 80 $+        nest 2 (header <$$> vcat funs)+            <$$> Pretty.empty  
library/Neovim/Main.hs view
@@ -13,28 +13,29 @@     where  import           Neovim.Config-import qualified Neovim.Context.Internal    as Internal+import qualified Neovim.Context.Internal as Internal import           Neovim.Log-import           Neovim.Plugin              as P-import           Neovim.Plugin.Startup      (StartupConfig(..))-import           Neovim.RPC.Common          as RPC+import           Neovim.Plugin           as P+import           Neovim.Plugin.Startup   (StartupConfig (..))+import           Neovim.RPC.Common       as RPC import           Neovim.RPC.EventHandler import           Neovim.RPC.SocketReader+import           Neovim.Util             (oneLineErrorMessage) -import qualified Config.Dyre                as Dyre-import qualified Config.Dyre.Relaunch       as Dyre+import qualified Config.Dyre             as Dyre+import qualified Config.Dyre.Relaunch    as Dyre import           Control.Concurrent-import           Control.Concurrent.STM     (putTMVar, atomically)+import           Control.Concurrent.STM  (atomically, putTMVar) import           Control.Monad import           Data.Default import           Data.Maybe import           Data.Monoid import           Options.Applicative-import           System.IO                  (stdin, stdout)+import           System.IO               (stdin, stdout) import           System.SetEnv -import           System.Environment import           Prelude+import           System.Environment   logger :: String@@ -194,7 +195,7 @@                             conf         startPluginThreads startupConf allPlugins >>= \case             Left e -> do-                errorM logger $ "Error initializing plugins: " <> e+                errorM logger $ "Error initializing plugins: " <> oneLineErrorMessage e                 putMVar (Internal.transitionTo conf) $ Internal.Failure e                 transitionHandler [ehTid, srTid] conf @@ -220,7 +221,7 @@         Dyre.relaunchMaster Nothing      Internal.Failure e ->-        errorM logger e+        errorM logger $ oneLineErrorMessage e      Internal.Quit ->         return ()
library/Neovim/Plugin.hs view
@@ -1,5 +1,6 @@ {-# LANGUAGE GADTs               #-} {-# LANGUAGE LambdaCase          #-}+{-# LANGUAGE OverloadedStrings   #-} {-# LANGUAGE RecordWildCards     #-} {-# LANGUAGE ScopedTypeVariables #-} {- |@@ -57,6 +58,7 @@ import           Data.MessagePack import           Data.Traversable             (forM) import           System.Log.Logger+import           Text.PrettyPrint.ANSI.Leijen (Doc)  import           Prelude @@ -70,7 +72,7 @@  startPluginThreads :: Internal.Config StartupConfig ()                    -> [Neovim StartupConfig () NeovimPlugin]-                   -> IO (Either String ([FunctionMapEntry],[ThreadId]))+                   -> IO (Either Doc ([FunctionMapEntry],[ThreadId])) startPluginThreads cfg = fmap (fmap fst)     . runNeovim cfg ()     . foldM go ([], [])@@ -105,10 +107,9 @@                 (\n -> ("remote#define#FunctionOnHost", toObject n))                 (\c -> ("remote#define#FunctionOnChannel", toObject c))                 pName-        ret <- vim_call_function defineFunction-            [ host, toObject functionName, toObject s-            , toObject functionName, toObject (Map.empty :: Dictionary)-            ]+        ret <- vim_call_function defineFunction $+            host +: functionName +: s +: functionName +: (Map.empty :: Dictionary) +: []+         case ret of             Left e -> do                 liftIO . errorM logger $@@ -131,10 +132,9 @@                 (\n -> ("remote#define#CommandOnHost", toObject n))                 (\c -> ("remote#define#CommandOnChannel", toObject c))                 pName-        ret <- vim_call_function defineFunction-            [ host, toObject functionName, toObject sync-            , toObject functionName, toObject copts-            ]+        ret <- vim_call_function defineFunction $+                    host +: functionName +: sync +: functionName +: copts +: []+         case ret of             Left e -> do                 liftIO . errorM logger $@@ -151,10 +151,8 @@                 (\n -> ("remote#define#AutocmdOnHost", toObject n))                 (\c -> ("remote#define#AutocmdOnChannel", toObject c))                 pName-        ret <- vim_call_function defineFunction-            [ host, toObject functionName, toObject Async-            , toObject acmdType , toObject opts-            ]+        ret <- vim_call_function defineFunction $+                    host +:  functionName +:  Async  +:  acmdType  +:  opts +: []         case ret of             Left e -> do                 liftIO . errorM logger $
library/Neovim/Plugin/Classes.hs view
@@ -28,19 +28,21 @@  import           Neovim.Classes -import           Control.Applicative+import           Control.Applicative          hiding (empty) import           Control.Monad.Error.Class-import           Data.ByteString           (ByteString)-import           Data.Char                 (isDigit)+import           Data.ByteString              (ByteString)+import           Data.ByteString.UTF8         (toString)+import           Data.Char                    (isDigit) import           Data.Default-import           Data.List                 (groupBy, sort)-import qualified Data.Map                  as Map+import           Data.List                    (groupBy, sort)+import qualified Data.Map                     as Map import           Data.Maybe import           Data.MessagePack import           Data.String-import           Data.Traversable          (sequence)+import           Data.Traversable             (sequence)+import           Text.PrettyPrint.ANSI.Leijen hiding ((<$>)) -import           Prelude                   hiding (sequence)+import           Prelude                      hiding (sequence)   -- | Essentially just a string.@@ -48,6 +50,10 @@     deriving (Eq, Ord, Show, Read)  +instance Pretty FunctionName where+    pretty (F n) = blue . text $ toString n++ -- | Functionality specific functional description entries. -- -- All fields which are directly specified in these constructors are not@@ -81,6 +87,20 @@     deriving (Show, Read, Eq, Ord)  +instance Pretty FunctionalityDescription where+    pretty = \case+        Function fname s ->+            text "Function" <+> pretty s <+> pretty fname++        Command fname copts ->+            text "Command" <+> pretty copts <+> pretty fname++        Autocmd t fname aopts ->+            text "Autocmd" <+> (text . toString) t+                <+> pretty aopts+                <+> pretty fname++ -- | This option detemines how neovim should behave when calling some -- functionality on a remote host. data Synchronous@@ -98,6 +118,12 @@     deriving (Show, Read, Eq, Ord, Enum)  +instance Pretty Synchronous where+    pretty = \case+        Async -> red  $ text "async"+        Sync  -> blue $ text "sync"++ instance IsString Synchronous where     fromString = \case         "sync"  -> Sync@@ -158,6 +184,27 @@     deriving (Eq, Ord, Show, Read)  +instance Pretty CommandOption where+    pretty = \case+        CmdSync s ->+            pretty s++        CmdRegister ->+            text "\""++        CmdNargs n ->+            text n++        CmdRange rs ->+            pretty rs++        CmdCount c ->+            text (show c)++        CmdBang ->+            text "!"++ instance IsString CommandOption where     fromString = \case         "%"     -> CmdRange WholeFile@@ -177,6 +224,10 @@     deriving (Eq, Ord, Show, Read)  +instance Pretty CommandOptions where+    pretty (CommandOptions os) =+        cat $ map pretty os+ -- | Smart constructor for 'CommandOptions'. This sorts the command options and -- removes duplicate entries for semantically the same thing. Note that the -- smallest option stays for whatever ordering is defined. It is best to simply@@ -211,7 +262,7 @@             CmdNargs n    -> Just ("nargs"   , toObject n)             _             -> Nothing -    fromObject o = throwError $+    fromObject o = throwError . text $         "Did not expect to receive a CommandOptions object: " ++ show o  @@ -229,6 +280,18 @@     deriving (Eq, Ord, Show, Read)  +instance Pretty RangeSpecification where+    pretty = \case+        CurrentLine ->+            empty++        WholeFile ->+            text "%"++        RangeCount c ->+            text $ show c++ instance NvimObject RangeSpecification where     toObject = \case         CurrentLine  -> ObjectBinary ""@@ -263,6 +326,17 @@     deriving (Eq, Ord, Show, Read)  +instance Pretty CommandArguments where+    pretty CommandArguments{..} =+        cat $ catMaybes+            [ (\b -> if b then (text "!") else empty) <$> bang+            , (\(s,e) -> lparen <> (text . show) s <> comma+                         <+> (text . show) e <> rparen)+                <$> range+            , (text . show) <$> count+            , (text . show) <$> register+            ]+ instance Default CommandArguments where     def = CommandArguments             { bang     = Nothing@@ -293,7 +367,7 @@      fromObject ObjectNil = return def     fromObject o =-        throwError $ "Expected a map for CommandArguments object, but got: " ++ show o+        throwError . text $ "Expected a map for CommandArguments object, but got: " ++ show o   -- | Options that can be used to register an autocmd. See @:h :autocmd@ or any@@ -313,6 +387,13 @@     deriving (Show, Read, Eq, Ord)  +instance Pretty AutocmdOptions where+    pretty AutocmdOptions{..} =+        text acmdPattern+            <+> text (if acmdNested then "nested" else "unnested")+            <> maybe empty (\g -> empty <+> text g) acmdGroup++ instance Default AutocmdOptions where     def = AutocmdOptions         { acmdPattern = "*"@@ -329,7 +410,7 @@             ] ++ catMaybes             [ acmdGroup >>= \g -> return ("group", toObject g)             ]-    fromObject o = throwError $+    fromObject o = throwError . text $         "Did not expect to receive an AutocmdOptions object: " ++ show o  -- | Conveniennce class to extract a name from some value.
library/Neovim/Plugin/ConfigHelper/Internal.hs view
@@ -23,12 +23,14 @@  import           Config.Dyre             (Params) import           Config.Dyre.Compile+import           Config.Dyre.Paths       (getPaths) import           Control.Applicative     hiding (many, (<|>)) import           Control.Monad           (void, forM_) import           Data.Char import           Text.Parsec             hiding (Error, count) import           Text.Parsec.String import           System.SetEnv+import           System.Directory        (removeDirectoryRecursive)  import           Prelude @@ -51,14 +53,24 @@  -- | Note that restarting the plugin provider implies compilation because Dyre -- does this automatically. However, if the recompilation fails, the previously--- compiled bynary is executed. This essentially means that restarting may take+-- compiled binary is executed. This essentially means that restarting may take -- more time then you might expect.+--+-- If you provide a bang to the command, the cache directory of /nvim-hs/ is+-- forcibly removed. restartNvimhs :: CommandArguments               -> Neovim (Params NeovimConfig, [(String, Maybe String)]) [QuickfixListItem String] () restartNvimhs CommandArguments{..} = do     case bang of-        Just True -> recompileNvimhs-        _         -> return ()+        Just True -> do+            (_,_,_, cacheDir,_) <- liftIO . getPaths =<< asks fst+            liftIO $ removeDirectoryRecursive cacheDir++        _ ->+            return ()++    recompileNvimhs+     (_, env) <- ask     forM_ env $ \(var, val) -> liftIO $ do         maybe (unsetEnv var) (setEnv var) val
library/Neovim/Plugin/IPC/Classes.hs view
@@ -1,5 +1,6 @@ {-# LANGUAGE DeriveDataTypeable        #-} {-# LANGUAGE ExistentialQuantification #-}+{-# LANGUAGE RecordWildCards           #-} {- | Module      :  Neovim.Plugin.IPC.Classes Description :  Classes used for Inter Plugin Communication@@ -22,13 +23,15 @@     module Data.Time,     ) where -import           Neovim.Plugin.Classes  (FunctionName)+import           Neovim.Plugin.Classes        (FunctionName)  import           Control.Concurrent.STM-import           Data.Data              (Typeable, cast)-import           Data.Int               (Int64)+import           Data.Data                    (Typeable, cast)+import           Data.Int                     (Int64) import           Data.MessagePack import           Data.Time+import           Data.Time.Locale.Compat+import           Text.PrettyPrint.ANSI.Leijen hiding ((<$>))  import           Prelude @@ -63,6 +66,14 @@ instance Message FunctionCall  +instance Pretty FunctionCall where+    pretty (FunctionCall fname args _ t) =+        nest 2 $ text "Function call for:" <+> pretty fname+            <$$> text "Arguments:" <+> text (show args)+            <$$> text "Timestamp:"+                <+> (yellow . text . formatTime defaultTimeLocale "%H:%M:%S (%q)") t++ -- | A request is a data type containing the method to call, its arguments and -- an identifier used to map the result to the function that has been called. data Request = Request@@ -78,6 +89,13 @@ instance Message Request  +instance Pretty Request where+    pretty Request{..} =+        nest 2 $ text "Request" <+> (yellow . text . ('#':) . show) reqId+            <$$> (text "Method:" <+> pretty reqMethod)+            <$$> (text "Arguments:" <+> text (show reqArgs))++ -- | A notification is similar to a 'Request'. It essentially does the same -- thing, but the function is only called for its side effects. This type of -- message is sent by neovim if the caller there does not care about the result@@ -91,4 +109,11 @@   instance Message Notification+++instance Pretty Notification where+    pretty Notification{..} =+        nest 2 $ text "Notification"+            <$$> (text "Method:" <+> pretty notMethod)+            <$$> (text "Arguments:" <+> text (show notArgs)) 
library/Neovim/Quickfix.hs view
@@ -16,15 +16,17 @@     where  import           Control.Applicative-import           Control.Monad           (void)-import           Data.ByteString         as BS (ByteString, all, elem)-import qualified Data.Map                as Map+import           Control.Monad                (void)+import           Data.ByteString              as BS (ByteString, all, elem)+import qualified Data.Map                     as Map import           Data.Maybe import           Data.MessagePack import           Data.Monoid import           Neovim.API.String import           Neovim.Classes import           Neovim.Context+import           Text.PrettyPrint.ANSI.Leijen (Doc)+import qualified Text.PrettyPrint.ANSI.Leijen as P  import           Prelude @@ -36,7 +38,7 @@           -> QuickfixAction           -> Neovim r st () setqflist qs a =-    void $ vim_call_function "setqflist" [toObject qs, toObject a]+    void $ vim_call_function "setqflist" $ qs +: a +: []  -- | Quickfix list item. The parameter names should mostly conform to those in -- @:h setqflist()@. Some fields are merged to explicitly state mutually@@ -77,7 +79,7 @@         Warning -> ObjectBinary "W"         Error   -> ObjectBinary "E" -    fromObject o = case fromObject o :: Either String String of+    fromObject o = case fromObject o :: Either Doc String of         Right "W" -> return Warning         Right "E" -> return Error         _         -> return Error@@ -119,19 +121,19 @@      fromObject objectMap@(ObjectMap _) = do         m <- fromObject objectMap-        let l :: NvimObject o => ByteString -> Either String o+        let l :: NvimObject o => ByteString -> Either Doc o             l key = case Map.lookup key m of                 Just o -> fromObject o-                Nothing -> Left "Key not found."+                Nothing -> throwError . P.text $ "Key not found."         bufOrFile <- case (l "bufnr", l "filename") of             (Right b, _) -> return $ Left b             (_, Right f) -> return $ Right f-            _           -> throwError "No buffer number or file name inside quickfix list item."+            _           -> throwError . P.text $ "No buffer number or file name inside quickfix list item."         lnumOrPattern <- case (l "lnum", l "pattern") of             (Right lnum, _) -> return $ Left lnum             (_, Right pat)  -> return $ Right pat-            _              -> throwError "No line number or search pattern inside quickfix list item."-        let l' :: NvimObject o => ByteString -> Either String (Maybe o)+            _              -> throwError . P.text $ "No line number or search pattern inside quickfix list item."+        let l' :: NvimObject o => ByteString -> Either Doc (Maybe o)             l' key = case Map.lookup key m of                 Just o -> Just <$> fromObject o                 Nothing -> return Nothing@@ -150,7 +152,7 @@         errorType <- fromMaybe Error <$> l' "type"         return QFItem{..} -    fromObject o = throwError $ "Could not deserialize QuickfixListItem, expected a map but received: " ++ show o+    fromObject o = throwError . P.text $ "Could not deserialize QuickfixListItem, expected a map but received: " ++ show o   data QuickfixAction
library/Neovim/RPC/Classes.hs view
@@ -1,5 +1,6 @@ {-# LANGUAGE DeriveDataTypeable #-} {-# LANGUAGE LambdaCase         #-}+{-# LANGUAGE RecordWildCards    #-} {- | Module      :  Neovim.RPC.Classes Description :  Data types and classes for the RPC components@@ -16,15 +17,16 @@     ( Message (..),     ) where -import           Neovim.Classes            (NvimObject (..))-import           Neovim.Plugin.Classes     (FunctionName (..))-import qualified Neovim.Plugin.IPC.Classes as IPC+import           Neovim.Classes               (NvimObject (..), (+:))+import           Neovim.Plugin.Classes        (FunctionName (..))+import qualified Neovim.Plugin.IPC.Classes    as IPC  import           Control.Applicative import           Control.Monad.Error.Class-import           Data.Data                 (Typeable)-import           Data.Int                  (Int64)-import           Data.MessagePack          (Object (..))+import           Data.Data                    (Typeable)+import           Data.Int                     (Int64)+import           Data.MessagePack             (Object (..))+import           Text.PrettyPrint.ANSI.Leijen hiding ((<$>))  import           Prelude @@ -53,19 +55,20 @@  instance IPC.Message Message + instance NvimObject Message where     toObject = \case         Request (IPC.Request (F m) i ps) ->-            ObjectArray [ ObjectInt 0, ObjectInt i, ObjectBinary m, ObjectArray ps ]+            ObjectArray $  (0 :: Int64) +: i +: m +: ps +: []          Response i (Left e) ->-            ObjectArray [ ObjectInt 1, ObjectInt i, e, ObjectNil]+            ObjectArray $ (1 :: Int64) +: i +: e +: () +: []          Response i (Right r) ->-            ObjectArray [ ObjectInt 1, ObjectInt i, ObjectNil, r]+            ObjectArray $ (1 :: Int64) +: i +: () +: r +: []          Notification (IPC.Notification (F m) ps) ->-            ObjectArray [ ObjectInt 2, ObjectBinary m, ObjectArray ps ]+            ObjectArray $ (2 :: Int64) +: m +: ps +: []       fromObject = \case@@ -90,7 +93,19 @@             return $ Notification n          o ->-            throwError $ "Not a known/valid msgpack-rpc message" ++ show o+            throwError . text $ "Not a known/valid msgpack-rpc message" ++ show o ++instance Pretty Message where+    pretty = \case+        Request request ->+            pretty request++        Response i ret ->+            nest 2 $ text "Response" <+> (yellow . text . ('#':) . show) i+                <$$> either (red . text . show) (green . text. show) ret++        Notification notification ->+            pretty notification  
library/Neovim/RPC/FunctionCall.hs view
@@ -25,16 +25,17 @@  import           Neovim.Classes import           Neovim.Context-import qualified Neovim.Context.Internal    as Internal-import           Neovim.Plugin.Classes      (FunctionName)+import qualified Neovim.Context.Internal   as Internal+import           Neovim.Plugin.Classes     (FunctionName) import           Neovim.Plugin.IPC.Classes-import qualified Neovim.RPC.Classes         as MsgpackRPC+import qualified Neovim.RPC.Classes        as MsgpackRPC  import           Control.Applicative import           Control.Concurrent.STM import           Control.Monad.Reader import           Data.MessagePack import           Data.Monoid+import qualified Text.PrettyPrint.ANSI.Leijen as P  import           Prelude @@ -123,15 +124,15 @@  -- | Wait for the result of the 'STM' action and call @'err' . (loc++) . show@ -- if the action returned an error.-waitErr :: (Show e)+waitErr :: (P.Pretty e)         => String                              -- ^ Prefix error message with this.         -> Neovim r st (STM (Either e result)) -- ^ Function call to neovim         -> Neovim r st result-waitErr loc act = wait act >>= either (err . (loc++) . show) return+waitErr loc act = wait act >>= either (err . (P.<>) (P.text loc) . P.pretty) return   -- | 'waitErr' that discards the result.-waitErr' :: (Show e)+waitErr' :: (P.Pretty e)          => String          -> Neovim r st (STM (Either e result))          -> Neovim r st ()
library/Neovim/Util.hs view
@@ -14,6 +14,7 @@     withCustomEnvironment,     whenM,     unlessM,+    oneLineErrorMessage,     ) where  import           Control.Monad       (forM, forM_, when, unless)@@ -21,6 +22,7 @@ import           Neovim.Context import           System.SetEnv import           System.Environment+import qualified Text.PrettyPrint.ANSI.Leijen as P   -- | Execute the given action with a changed set of environment variables and@@ -50,3 +52,9 @@ -- | 'unless' with a monadic predicate. unlessM :: (Monad m) => m Bool -> m () -> m () unlessM mp a = mp >>= \p -> unless p a+++oneLineErrorMessage :: P.Doc -> String+oneLineErrorMessage d = case lines $ P.displayS (P.renderCompact d) "" of+    (x:_) -> x+    []    -> ""
nvim-hs.cabal view
@@ -1,5 +1,5 @@ name:                nvim-hs-version:             0.0.5+version:             0.0.6 synopsis:            Haskell plugin backend for neovim description:   This package provides a plugin provider for neovim. It allows you to write@@ -26,10 +26,12 @@ license-file:        LICENSE author:              Sebastian Witte maintainer:          woozletoff@gmail.com-copyright:           Copyright (C) Sebastian Witte+copyright:           Copyright 2015 Sebastian Witte <woozletoff@gmail.com> category:            Editor build-type:          Simple cabal-version:       >=1.10+-- TODO uncomment when somebody has cared about the new travis infrastructure (see #39)+-- tested-with:         GHC == 7.6.3, GHC == 7.8.4, GHC == 7.10.2 extra-source-files:    TestPlugins.vim                      , TestPlugins.hs                      , TestPlugins.sh@@ -40,7 +42,10 @@                      , test-files/compile-error-for-quickfix-test4                      , test-files/compile-error-for-quickfix-test5                      , test-files/hello-                     , CHANGELOG.md++extra-doc-files:       CHANGELOG.md+                     , README.md+ source-repository head     type:            git     location:        https://github.com/neovimhaskell/nvim-hs@@ -88,6 +93,7 @@                       , Neovim.API.TH   -- other-extensions:   build-depends:        base >=4.6 && < 5+                      , ansi-wl-pprint                       , bytestring                       , cereal                       , cereal-conduit@@ -107,6 +113,7 @@                       , lifted-base                       , mtl >= 2.2.1 && < 2.3                       , optparse-applicative+                      , time-locale-compat                       , parsec >= 3.1.9                       , process                       , resourcet@@ -136,6 +143,7 @@                       , hspec-discover                       , QuickCheck >=2.6 +                      , ansi-wl-pprint                       , bytestring                       , cereal                       , cereal-conduit@@ -152,6 +160,7 @@                       , lifted-base                       , mtl >= 2.2.1 && < 2.3                       , messagepack >= 0.4+                      , time-locale-compat                       , network                       , optparse-applicative                       , parsec >= 3.1.9