nvim-hs 2.2.0.3 → 2.3.0.0
raw patch · 15 files changed
+106/−69 lines, 15 filesbinary-added
Files
- CHANGELOG.md +9/−0
- README.md +10/−1
- api binary
- apiblobs/0.4.3.msgpack binary
- apiblobs/0.5.0.msgpack binary
- apiblobs/0.6.1.msgpack binary
- apiblobs/0.8.0.msgpack binary
- library/Neovim/API/Parser.hs +20/−14
- library/Neovim/Debug.hs +1/−1
- library/Neovim/Main.hs +1/−1
- library/Neovim/RPC/Common.hs +35/−14
- library/Neovim/Test.hs +1/−1
- nvim-hs-devel.sh +0/−34
- nvim-hs.cabal +9/−3
- test-suite/Neovim/RPC/CommonSpec.hs +20/−0
CHANGELOG.md view
@@ -1,3 +1,12 @@+# 2.3.0.0++* Windows is now rudimentarily supported. Since I couldn't find a library to+ connect to named pipes on windows and I didn't want to extend or write one,+ you have to use TCP sockets or Standard in and out to communicate with+ neovim. If you start neovim with `nvim --listen localhost:`, it will set the+ `NVIM` environment variable, so that nvim-hs can automatically connect to the+ neovim instance without passing any arguments.+ # 2.2.0.0 * NeovimException are now thrown from (synchronous) remote functions and are no
README.md view
@@ -9,7 +9,6 @@ to generate the neovim bindings and to avoid some of the boilerplate handy work, some exotic operating systems and architectures may not work. -[](https://travis-ci.org/neovimhaskell/nvim-hs) [](https://hackage.haskell.org/package/nvim-hs) [](http://stackage.org/lts/package/nvim-hs) [](http://stackage.org/nightly/package/nvim-hs)@@ -17,6 +16,16 @@ # What do I have to expect if I were to use it now? Check the issue list here on github.++## For Windows users++Named pipes are not supported at the momend #103. You therefore have to start+`nvim-hs` instances by connecting to STDIN and STDOUT or TCP. By default `nvim-hs`+connects to the listen socket pointed to by the `NVIM` environment variable and +the functions in the module `Neovim.Debug` rely on that. If you want to be able to +run these functions, start Neovim with `nvim --listen localhost:` or similar+(This example command starts neovim with a socket listening on `localhost` and +random a random TCP port.) # How do I start using this?
api view
binary file changed (28544 → 30761 bytes)
+ apiblobs/0.4.3.msgpack view
binary file changed (absent → 25287 bytes)
+ apiblobs/0.5.0.msgpack view
binary file changed (absent → 27983 bytes)
+ apiblobs/0.6.1.msgpack view
binary file changed (absent → 28544 bytes)
+ apiblobs/0.8.0.msgpack view
binary file changed (absent → 30761 bytes)
library/Neovim/API/Parser.hs view
@@ -1,3 +1,4 @@+{-# LANGUAGE CPP #-} {- | Module : Neovim.API.Parser Description : P.Parser for the msgpack output stram API@@ -22,10 +23,10 @@ import qualified Data.ByteString.Lazy as LB import Data.Map (Map) import qualified Data.Map as Map-import Data.MessagePack-import Data.Serialize+import Data.MessagePack ( Object )+import Data.Serialize ( decode ) import Neovim.Compat.Megaparsec as P-import System.Process.Typed+import System.Process.Typed ( proc, readProcessStdout_ ) import UnliftIO.Exception ( SomeException, catch,@@ -71,8 +72,18 @@ -- | Run @nvim --api-info@ and parse its output. parseAPI :: IO (Either (Doc AnsiStyle) NeovimAPI)-parseAPI = either (Left . pretty) extractAPI <$> (decodeAPI `catch` readFromAPIFile)+parseAPI = either (Left . pretty) extractAPI <$> +#ifndef WINDOWS+ (decodeAPI `catch` \(_ignored :: SomeException) -> readFromAPIFile) +decodeAPI :: IO (Either String Object)+decodeAPI =+ decode . LB.toStrict <$> readProcessStdout_ (proc "nvim" ["--api-info"])++#else+ readFromAPIFile+#endif+ extractAPI :: Object -> Either (Doc AnsiStyle) NeovimAPI extractAPI apiObj = fromObject apiObj >>= \apiMap ->@@ -81,18 +92,13 @@ <*> extractCustomTypes apiMap <*> extractFunctions apiMap -readFromAPIFile :: SomeException -> IO (Either String Object)-readFromAPIFile _ = (decode <$> B.readFile "api") `catch` returnPreviousExceptionAsText+readFromAPIFile :: IO (Either String Object)+readFromAPIFile = (decode <$> B.readFile "api") `catch` returnNoApiForCodegeneratorErrorMessage where- returnPreviousExceptionAsText :: SomeException -> IO (Either String Object)- returnPreviousExceptionAsText _ =+ returnNoApiForCodegeneratorErrorMessage :: SomeException -> IO (Either String Object)+ returnNoApiForCodegeneratorErrorMessage _ = return . Left $- "The 'nvim' process could not be started and there is no file named\- \ 'api' in the working directory as a substitute."--decodeAPI :: IO (Either String Object)-decodeAPI =- decode . LB.toStrict <$> readProcessStdout_ (proc "nvim" ["--api-info"])+ "The 'nvim' process could not be started and there is no file named 'api' in the working directory as a substitute." oLookup :: (NvimObject o) => String -> Map String Object -> Either (Doc AnsiStyle) o oLookup qry = maybe throwErrorMessage fromObject . Map.lookup qry
library/Neovim/Debug.hs view
@@ -53,7 +53,7 @@ -- | Run a 'Neovim' function. -- -- This function connects to the socket pointed to by the environment variable--- @$NVIM_LISTEN_ADDRESS@ and executes the command. It does not register itself+-- @$NVIM@ and executes the command. It does not register itself -- as a real plugin provider, you can simply call neovim-functions from the -- module "Neovim.API.String" this way. --
library/Neovim/Main.hs view
@@ -86,7 +86,7 @@ <*> switch ( long "environment" <> short 'e'- <> help "Read connection information from $NVIM_LISTEN_ADDRESS.")+ <> help "Read connection information from $NVIM.") <*> optional ((,) <$> strOption (long "log-file"
library/Neovim/RPC/Common.hs view
@@ -1,4 +1,4 @@-{-# LANGUAGE RankNTypes #-}+{-# LANGUAGE RankNTypes, CPP #-} {- | Module : Neovim.RPC.Common Description : Common functons for the RPC module@@ -25,12 +25,17 @@ import Data.String import Data.Time import Network.Socket as N hiding (SocketType)-import System.Environment (getEnv) import System.IO (BufferMode (..), Handle, IOMode(ReadWriteMode), hClose, hSetBuffering) import System.Log.Logger+import Neovim.Compat.Megaparsec as P import Prelude+import UnliftIO.Environment (lookupEnv)+import Data.Maybe (catMaybes)+import Data.List (intercalate)+import qualified Data.List as List+import qualified Text.Megaparsec.Char.Lexer as L -- | Things shared between the socket reader and the event handler.@@ -58,7 +63,7 @@ -- suitable for an embedded neovim which is used in test cases. | Environment -- ^ Read the connection information from the environment- -- variable @NVIM_LISTEN_ADDRESS@.+ -- variable @NVIM@. | UnixSocket FilePath -- ^ Use a unix socket. | TCP Int String@@ -77,7 +82,11 @@ return h UnixSocket f ->- createHandle . Stdout =<< createUnixSocketHandle f+#ifndef WINDOWS+ liftIO $ createHandle . Stdout =<< flip socketToHandle ReadWriteMode =<< getSocketUnix f+#else+ error "Windows' named pipes are not supported"+#endif TCP p h -> createHandle . Stdout =<< createTCPSocketHandle p h@@ -86,27 +95,39 @@ createHandle . Stdout =<< createSocketHandleFromEnvironment where- createUnixSocketHandle :: (MonadIO io) => FilePath -> io Handle- createUnixSocketHandle f =- liftIO $ getSocketUnix f >>= flip socketToHandle ReadWriteMode- createTCPSocketHandle :: (MonadIO io) => Int -> String -> io Handle createTCPSocketHandle p h = liftIO $ getSocketTCP (fromString h) p >>= flip socketToHandle ReadWriteMode . fst - createSocketHandleFromEnvironment = do- listenAddress <- liftIO (getEnv "NVIM_LISTEN_ADDRESS")- case words listenAddress of- [unixSocket] -> createHandle (UnixSocket unixSocket)- [h,p] -> createHandle (TCP (read p) h)+ createSocketHandleFromEnvironment = liftIO $ do+ -- NVIM_LISTEN_ADDRESS is for backwards compatibility+ envValues <- catMaybes <$> mapM lookupEnv ["NVIM", "NVIM_LISTEN_ADDRESS"]+ listenAdresses <- mapM parseNvimEnvironmentVariable envValues+ case listenAdresses of+ (s:_) -> createHandle s _ -> do let errMsg = unlines [ "Unhandled socket type from environment variable: "- , "\t" <> listenAddress+ , "\t" <> intercalate ", " envValues ] liftIO $ errorM "createHandle" errMsg error errMsg +parseNvimEnvironmentVariable :: MonadFail m => String -> m SocketType+parseNvimEnvironmentVariable envValue =+ either (fail . show) pure $ parse (P.try pTcpAddress <|> pUnixSocket) envValue envValue++pUnixSocket :: P.Parser SocketType+pUnixSocket = UnixSocket <$> P.some anySingle <* P.eof++pTcpAddress :: P.Parser SocketType+pTcpAddress = do+ prefixes <- P.some (P.try (P.many (P.anySingleBut ':') <* P.single ':'))+ port <- L.lexeme P.eof L.decimal+ P.eof+ pure $ TCP port (List.intercalate ":" prefixes)++ -- fail $ "Unsupported format for $NVIM environment variable: " <> envValue -- | Close the handle and print a warning if the conduit chain has been -- interrupted prematurely.
library/Neovim/Test.hs view
@@ -107,7 +107,7 @@ nvimProcess <- startProcess $ setStdin createPipe $ setStdout createPipe- $ proc "nvim" (["-n","-u","NONE","--embed"] ++ args)+ $ proc "nvim" (["-n","--clean","--embed"] ++ args) cfg <- Internal.newConfig (pure Nothing) newRPCConfig
− nvim-hs-devel.sh
@@ -1,34 +0,0 @@-#!/bin/sh--# Helper script to run nvim-hs in a development environment.--# You should not name this script nvim-hs and put it on your path.-if [ x"$0" = x`which nvim-hs` ] ; then- echo "This script has the potential to run in an infinite loop. Exiting now..."- exit 1-fi--# This variable defines where the sandbox or stack files can be found. Adjust it-# appropriately and then delete the line after it.-sandbox_directory=$HOME/git/nvim-hs-echo "I should have read the comments. Silly me." && exit 1--old_pwd="`pwd`"-cd "$sandbox_directory"--if [ -d "$sandbox_directory/.cabal-sandbox" ] ; then- # We detect the sandbox by checking for the directory .cabal-sandbox- # This should work most of the time.- env CABAL_SANDBOX_CONFIG="$sandbox_directory"/cabal.sandbox.config cabal \- exec "$sandbox_directory/.cabal-sandbox/bin/nvim-hs" -- "$@"-elif [ -d "$sandbox_directory/.stack-work" ] ; then- # Stack leaves behind a .stack-work directory, so we take its present as a- # sign to use this approach.- stack exec nvim-hs -- "$@"-else- echo "No development directories found. Have you built the project?"- exit 2-fi-cd "$old_pwd"--# vim: foldmethod=marker sts=2 ts=4 expandtab sw=4
nvim-hs.cabal view
@@ -1,5 +1,5 @@ name: nvim-hs-version: 2.2.0.3+version: 2.3.0.0 synopsis: Haskell plugin backend for neovim description: This package provides a plugin provider for neovim. It allows you to write@@ -30,11 +30,14 @@ category: Editor build-type: Simple cabal-version: 1.18-extra-source-files: nvim-hs-devel.sh- , test-files/hello+extra-source-files: test-files/hello , apiblobs/0.1.7.msgpack , apiblobs/0.2.0.msgpack , apiblobs/0.3.0.msgpack+ , apiblobs/0.4.3.msgpack+ , apiblobs/0.5.0.msgpack+ , apiblobs/0.6.1.msgpack+ , apiblobs/0.8.0.msgpack , api extra-doc-files: CHANGELOG.md@@ -139,6 +142,8 @@ default-language: Haskell2010 ghc-options: -Wall + if os(windows)+ cpp-options: -DWINDOWS test-suite hspec type: exitcode-stdio-1.0@@ -194,6 +199,7 @@ , Neovim.EmbeddedRPCSpec , Neovim.Plugin.ClassesSpec , Neovim.RPC.SocketReaderSpec+ , Neovim.RPC.CommonSpec ghc-options: -threaded -rtsopts -with-rtsopts=-N
+ test-suite/Neovim/RPC/CommonSpec.hs view
@@ -0,0 +1,20 @@+module Neovim.RPC.CommonSpec where++import Neovim.RPC.Common++import Test.Hspec++spec :: Spec+spec = do+ describe "Parsing of $NVIM environment variable" $ do+ it "is a UnixSocket if it doesn't contain a colon" $ do+ UnixSocket actual <- parseNvimEnvironmentVariable "/some/file"+ actual `shouldBe` "/some/file"+ it "is a tcp connection if it contains a colon" $ do+ TCP actualPort actualHostname <- parseNvimEnvironmentVariable "localhost:12345"+ actualPort `shouldBe` 12345+ actualHostname `shouldBe` "localhost"+ it "the last number after many colons is the port" $ do+ TCP actualPort actualHostname <- parseNvimEnvironmentVariable "the:cake:is:a:lie:777"+ actualPort `shouldBe` 777+ actualHostname `shouldBe` "the:cake:is:a:lie"