haskell-lsp-0.24.0.0: src/Language/Haskell/LSP/Capture.hs
{-# LANGUAGE DeriveAnyClass #-}
{-# LANGUAGE DeriveGeneric #-}
{-# LANGUAGE OverloadedStrings #-}
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
deriving (Show, Eq, Generic, ToJSON, FromJSON)
data CaptureContext = NoCapture | Capture (TChan Event)
noCapture :: CaptureContext
noCapture = NoCapture
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
atomically $ writeTChan chan $ FromServer time msg
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