packages feed

haskell-lsp 0.22.0.0 → 0.23.0.0

raw patch · 8 files changed

+109/−40 lines, 8 filesdep ~haskell-lsp-typesPVP ok

version bump matches the API change (PVP)

Dependency ranges changed: haskell-lsp-types

API changes (from Hackage documentation)

- Language.Haskell.LSP.Core: [resCaptureFile] :: LanguageContextData config -> !Maybe FilePath
+ Language.Haskell.LSP.Capture: captureToFile :: FilePath -> IO CaptureContext
+ Language.Haskell.LSP.Capture: data CaptureContext
+ Language.Haskell.LSP.Capture: noCapture :: CaptureContext
+ Language.Haskell.LSP.Control: runWith :: Show config => IO ByteString -> (ByteString -> IO ()) -> InitializeCallbacks config -> Handlers -> Options -> Maybe FilePath -> IO Int
+ Language.Haskell.LSP.Core: ALERT :: Priority
+ Language.Haskell.LSP.Core: CRITICAL :: Priority
+ Language.Haskell.LSP.Core: DEBUG :: Priority
+ Language.Haskell.LSP.Core: EMERGENCY :: Priority
+ Language.Haskell.LSP.Core: ERROR :: Priority
+ Language.Haskell.LSP.Core: INFO :: Priority
+ Language.Haskell.LSP.Core: NOTICE :: Priority
+ Language.Haskell.LSP.Core: WARNING :: Priority
+ Language.Haskell.LSP.Core: [resCaptureContext] :: LanguageContextData config -> !CaptureContext
+ Language.Haskell.LSP.Core: data Priority
- Language.Haskell.LSP.Capture: FromClient :: UTCTime -> FromClientMessage -> Event
+ Language.Haskell.LSP.Capture: FromClient :: !UTCTime -> !FromClientMessage -> Event
- Language.Haskell.LSP.Capture: FromServer :: UTCTime -> FromServerMessage -> Event
+ Language.Haskell.LSP.Capture: FromServer :: !UTCTime -> !FromServerMessage -> Event
- Language.Haskell.LSP.Capture: captureFromClient :: FromClientMessage -> Maybe FilePath -> IO ()
+ Language.Haskell.LSP.Capture: captureFromClient :: FromClientMessage -> CaptureContext -> IO ()
- Language.Haskell.LSP.Capture: captureFromServer :: FromServerMessage -> Maybe FilePath -> IO ()
+ Language.Haskell.LSP.Capture: captureFromServer :: FromServerMessage -> CaptureContext -> IO ()
- Language.Haskell.LSP.Core: LanguageContextData :: !Int -> !Handlers -> !Options -> !SendFunc -> !VFSData -> !DiagnosticStore -> !Maybe config -> !TVar Int -> LspFuncs config -> !Maybe FilePath -> ![WorkspaceFolder] -> !ProgressData -> LanguageContextData config
+ Language.Haskell.LSP.Core: LanguageContextData :: !Int -> !Handlers -> !Options -> !SendFunc -> !VFSData -> !DiagnosticStore -> !Maybe config -> !TVar Int -> LspFuncs config -> !CaptureContext -> ![WorkspaceFolder] -> !ProgressData -> LanguageContextData config
- Language.Haskell.LSP.Core: defaultLanguageContextData :: Handlers -> Options -> LspFuncs config -> TVar Int -> SendFunc -> Maybe FilePath -> VFS -> LanguageContextData config
+ Language.Haskell.LSP.Core: defaultLanguageContextData :: Handlers -> Options -> LspFuncs config -> TVar Int -> SendFunc -> CaptureContext -> VFS -> LanguageContextData config

Files

ChangeLog.md view
@@ -1,5 +1,16 @@ # Revision history for haskell-lsp +## 0.23.0.0++* Add runWith for transporots other than stdio (@paulyoung)+* Fix race condition in event captures (@bgamari)+* Tweak the sectionSeparator (@alanz)+* Add hashWithSaltInstances (@ndmitchell)+* Fix CompletionItem.tags not being optional (@bubba)+* Avoid unnecessary normalisation in Binary instance for+  NormalizedFilePath (@cocreature)+* Fix ordering of TH splices (@fendor)+ ## 0.22.0.0  * ResponseMessage results are now an Either type (@greenhat)
haskell-lsp.cabal view
@@ -1,5 +1,5 @@ name:                haskell-lsp-version:             0.22.0.0+version:             0.23.0.0 synopsis:            Haskell library for the Microsoft Language Server Protocol  description:         An implementation of the types, and basic message server to@@ -46,7 +46,7 @@                      , filepath                      , hslogger                      , hashable-                     , haskell-lsp-types == 0.22.*+                     , haskell-lsp-types == 0.23.*                      , lens >= 4.15.2                      , mtl                      , network-uri
src/Language/Haskell/LSP/Capture.hs view
@@ -1,30 +1,55 @@ {-# LANGUAGE DeriveAnyClass #-} {-# LANGUAGE DeriveGeneric #-} {-# LANGUAGE OverloadedStrings #-}-module Language.Haskell.LSP.Capture where+module Language.Haskell.LSP.Capture+  ( Event(..)+  , CaptureContext+  , noCapture+  , captureToFile+  , captureFromClient+  , captureFromServer+  ) where  import Data.Aeson import Data.ByteString.Lazy.Char8 as BSL import Data.Time.Clock import GHC.Generics import Language.Haskell.LSP.Messages+import System.IO+import Language.Haskell.LSP.Utility+import Control.Concurrent+import Control.Monad+import Control.Concurrent.STM -data Event = FromClient UTCTime FromClientMessage-           | FromServer UTCTime FromServerMessage+data Event = FromClient !UTCTime !FromClientMessage+           | FromServer !UTCTime !FromServerMessage   deriving (Show, Eq, Generic, ToJSON, FromJSON) -captureFromServer :: FromServerMessage -> Maybe FilePath -> IO ()-captureFromServer _ Nothing = return ()-captureFromServer msg (Just fp) = do-  time <- getCurrentTime-  let entry = FromServer time msg+data CaptureContext = NoCapture | Capture (TChan Event) -  BSL.appendFile fp $ BSL.append (encode entry) "\n"+noCapture :: CaptureContext+noCapture = NoCapture -captureFromClient :: FromClientMessage -> Maybe FilePath -> IO ()-captureFromClient _ Nothing = return ()-captureFromClient msg (Just fp) = do+captureToFile :: FilePath -> IO CaptureContext+captureToFile fname = do+    logs $ "haskell-lsp:Logging to " ++ fname+    chan <- newTChanIO+    _tid <- forkIO $ withFile fname WriteMode $ writeToHandle chan+    return $ Capture chan++captureFromServer :: FromServerMessage -> CaptureContext -> IO ()+captureFromServer _ NoCapture = return ()+captureFromServer msg (Capture chan) = do   time <- getCurrentTime-  let entry = FromClient time msg+  atomically $ writeTChan chan $ FromServer time msg -  BSL.appendFile fp $ BSL.append (encode entry) "\n"+captureFromClient :: FromClientMessage -> CaptureContext -> IO ()+captureFromClient _ NoCapture = return ()+captureFromClient msg (Capture chan) = do+  time <- getCurrentTime+  atomically $ writeTChan chan $ FromClient time msg++writeToHandle :: TChan Event -> Handle -> IO ()+writeToHandle chan hdl = forever $ do+    ev <- atomically $ readTChan chan+    BSL.hPutStrLn hdl $ encode ev
src/Language/Haskell/LSP/Control.hs view
@@ -8,6 +8,7 @@ module Language.Haskell.LSP.Control   (     run+  , runWith   , runWithHandles   ) where @@ -50,8 +51,7 @@     -> IO Int run = runWithHandles stdin stdout --- | Starts listening and sending requests and responses--- at the specified handles.+-- | Convenience function for 'runWith' using the specified handles. runWithHandles :: (Show config) =>        Handle     -- ^ Handle to read client input from.@@ -63,20 +63,44 @@     -> Maybe FilePath     -> IO Int         -- exit code runWithHandles hin hout initializeCallbacks h o captureFp = do--  logm $ B.pack "\n\n\n\n\nhaskell-lsp:Starting up server ..."   hSetBuffering hin NoBuffering   hSetEncoding  hin utf8    hSetBuffering hout NoBuffering   hSetEncoding  hout utf8 +  let+    clientIn = BS.hGetSome hin defaultChunkSize++    clientOut out = do+      BSL.hPut hout out+      hFlush hout++  runWith clientIn clientOut initializeCallbacks h o captureFp++-- | Starts listening and sending requests and responses+-- using the specified I/O.+runWith :: (Show config) =>+       IO BS.ByteString+    -- ^ Client input.+    -> (BSL.ByteString -> IO ())+    -- ^ Function to provide output to.+    -> Core.InitializeCallbacks config+    -> Core.Handlers+    -> Core.Options+    -> Maybe FilePath+    -> IO Int         -- exit code+runWith clientIn clientOut initializeCallbacks h o captureFp = do++  logm $ B.pack "\n\n\n\n\nhaskell-lsp:Starting up server ..."+   timestamp <- formatTime defaultTimeLocale (iso8601DateFormat (Just "%H-%M-%S")) <$> getCurrentTime   let timestampCaptureFp = fmap (\f -> dropExtension f ++ timestamp ++ takeExtension f)                                 captureFp+  captureCtx <- maybe (return noCapture) captureToFile timestampCaptureFp    cout <- atomically newTChan :: IO (TChan FromServerMessage)-  _rhpid <- forkIO $ sendServer cout hout timestampCaptureFp+  _rhpid <- forkIO $ sendServer cout clientOut captureCtx     let sendFunc :: Core.SendFunc@@ -85,20 +109,20 @@    tvarId <- atomically $ newTVar 0   initVFS $ \vfs -> do-    tvarDat <- atomically $ newTVar $ Core.defaultLanguageContextData h o lf tvarId sendFunc timestampCaptureFp vfs+    tvarDat <- atomically $ newTVar $ Core.defaultLanguageContextData h o lf tvarId sendFunc captureCtx vfs -    ioLoop hin initializeCallbacks tvarDat+    ioLoop clientIn initializeCallbacks tvarDat    return 1   -- --------------------------------------------------------------------- -ioLoop :: (Show config) => Handle+ioLoop :: (Show config) => IO BS.ByteString                    -> Core.InitializeCallbacks config                    -> TVar (Core.LanguageContextData config)                    -> IO ()-ioLoop hin dispatcherProc tvarDat =+ioLoop clientIn dispatcherProc tvarDat =   go (parse parser "")   where     go :: Result BS.ByteString -> IO ()@@ -106,7 +130,7 @@       "\nhaskell-lsp: Failed to parse message header:\n" <> B.intercalate " > " (map str2lbs ctxs) <> ": " <>       str2lbs err <> "\n exiting 1 ...\n"     go (Partial c) = do-      bs <- BS.hGetSome hin defaultChunkSize+      bs <- clientIn       if BS.null bs         then logm $ B.pack "\nhaskell-lsp:Got EOF, exiting 1 ...\n"         else go (c bs)@@ -123,8 +147,8 @@ -- ---------------------------------------------------------------------  -- | Simple server to make sure all output is serialised-sendServer :: TChan FromServerMessage -> Handle -> Maybe FilePath -> IO ()-sendServer msgChan clientH captureFp =+sendServer :: TChan FromServerMessage -> (BSL.ByteString -> IO ()) -> CaptureContext -> IO ()+sendServer msgChan clientOut captureCtxt =   forever $ do     msg <- atomically $ readTChan msgChan @@ -138,11 +162,10 @@                  , BSL.fromStrict _TWO_CRLF                  , str ] -    BSL.hPut clientH out-    hFlush clientH+    clientOut out     logm $ B.pack "<--2--" <> str -    captureFromServer msg captureFp+    captureFromServer msg captureCtxt  -- | --
src/Language/Haskell/LSP/Core.hs view
@@ -27,6 +27,7 @@   , sendErrorLogS   , sendErrorShowS   , reverseSortEdit+  , Priority(..)   ) where  import           Control.Concurrent.Async@@ -86,7 +87,7 @@   , resConfig              :: !(Maybe config)   , resLspId               :: !(TVar Int)   , resLspFuncs            :: LspFuncs config -- NOTE: Cannot be strict, lazy initialization-  , resCaptureFile         :: !(Maybe FilePath)+  , resCaptureContext      :: !CaptureContext   , resWorkspaceFolders    :: ![J.WorkspaceFolder]   , resProgressData        :: !ProgressData   }@@ -348,7 +349,7 @@       ctx <- readTVarIO ctxVar       -- Capture exit notification       case J.fromJSON v :: J.Result J.ExitNotification of-        J.Success n -> captureFromClient (NotExit n) (resCaptureFile ctx)+        J.Success n -> captureFromClient (NotExit n) (resCaptureContext ctx)         J.Error _ -> return ()       logm $ B.pack "haskell-lsp:Got exit, exiting"       exitSuccess@@ -417,7 +418,7 @@            ctx <- readTVarIO tvarDat           let req' = wrapper req-          captureFromClient req' (resCaptureFile ctx)+          captureFromClient req' (resCaptureContext ctx)            case mh of             Just h -> h req@@ -484,7 +485,7 @@     J.Success req -> do       ctx <- readTVarIO tvarDat -      captureFromClient (notification req) (resCaptureFile ctx)+      captureFromClient (notification req) (resCaptureContext ctx)        case parseConfig req of         Left err -> do@@ -605,10 +606,10 @@ -- | -- ---defaultLanguageContextData :: Handlers -> Options -> LspFuncs config -> TVar Int -> SendFunc -> Maybe FilePath -> VFS -> LanguageContextData config-defaultLanguageContextData h o lf tv sf cf vfs =+defaultLanguageContextData :: Handlers -> Options -> LspFuncs config -> TVar Int -> SendFunc -> CaptureContext -> VFS -> LanguageContextData config+defaultLanguageContextData h o lf tv sf cc vfs =   LanguageContextData _INITIAL_RESPONSE_SEQUENCE h o sf (VFSData vfs mempty) mempty-                      Nothing tv lf cf mempty defaultProgressData+                      Nothing tv lf cc mempty defaultProgressData  defaultProgressData :: ProgressData defaultProgressData = ProgressData 0 Map.empty
test/InitialConfigurationSpec.hs view
@@ -6,6 +6,7 @@ import           Control.Concurrent.STM import           Data.Aeson import           Data.Default+import           Language.Haskell.LSP.Capture import           Language.Haskell.LSP.Core import           Language.Haskell.LSP.Types import           Language.Haskell.LSP.VFS@@ -40,7 +41,7 @@                                                         undefined                                                         tvarLspId                                                         (const $ return ())-                                                        Nothing+                                                        noCapture                                                         vfs      let putMsg msg =
test/JsonSpec.hs view
@@ -3,6 +3,8 @@ {-# LANGUAGE OverloadedStrings    #-} {-# LANGUAGE TypeSynonymInstances #-} {-# OPTIONS_GHC -fno-warn-orphans #-}+-- For the use of MarkedString+{-# OPTIONS_GHC -fno-warn-deprecations #-} -- | Test for JSON serialization module JsonSpec where @@ -44,6 +46,11 @@          (propertyJsonRoundtrip :: ResponseMessage () -> Property)     prop "ResponseMessage JSON value"          (propertyJsonRoundtrip :: ResponseMessage J.Value -> Property)+  describe "JSON decoding regressions" $+    it "CompletionItem" $+      (J.decode "{\"jsonrpc\":\"2.0\",\"result\":[{\"label\":\"raisebox\"}],\"id\":1}" :: Maybe CompletionResponse)+        `shouldNotBe` Nothing+    responseMessageSpec :: Spec responseMessageSpec = do
test/WorkspaceFoldersSpec.hs view
@@ -6,6 +6,7 @@ import Control.Concurrent.STM import Data.Aeson import Data.Default+import Language.Haskell.LSP.Capture import Language.Haskell.LSP.Core import Language.Haskell.LSP.Types import Language.Haskell.LSP.VFS@@ -31,7 +32,7 @@                                                         undefined                                                         tvarLspId                                                         (const $ return ())-                                                        Nothing+                                                        noCapture                                                         vfs      let putMsg msg =