{-# LANGUAGE DuplicateRecordFields #-}
{-# LANGUAGE RankNTypes #-}
module Development.IDE.LSP.Notifications
( setHandlersNotifications
) where
import Development.IDE.LSP.Server
import qualified Language.Haskell.LSP.Core as LSP
import Language.Haskell.LSP.Types
import qualified Language.Haskell.LSP.Types as LSP
import Development.IDE.Core.IdeConfiguration
import Development.IDE.Core.Service
import Development.IDE.Core.Shake
import Development.IDE.Types.Location
import Development.IDE.Types.Logger
import Development.IDE.Types.Options
import Control.Monad.Extra
import Data.Foldable as F
import Data.Maybe
import qualified Data.HashMap.Strict as M
import qualified Data.HashSet as S
import qualified Data.Text as Text
import Development.IDE.Core.FileStore (setSomethingModified, setFileModified, typecheckParents)
import Development.IDE.Core.FileExists (modifyFileExists)
import Development.IDE.Core.OfInterest
whenUriFile :: Uri -> (NormalizedFilePath -> IO ()) -> IO ()
whenUriFile uri act = whenJust (LSP.uriToFilePath uri) $ act . toNormalizedFilePath'
setHandlersNotifications :: PartialHandlers c
setHandlersNotifications = PartialHandlers $ \WithMessage{..} x -> return x
{LSP.didOpenTextDocumentNotificationHandler = withNotification (LSP.didOpenTextDocumentNotificationHandler x) $
\_ ide (DidOpenTextDocumentParams TextDocumentItem{_uri,_version}) -> do
updatePositionMapping ide (VersionedTextDocumentIdentifier _uri (Just _version)) (List [])
whenUriFile _uri $ \file -> do
modifyFilesOfInterest ide (M.insert file OnDisk)
setFileModified ide False file
logInfo (ideLogger ide) $ "Opened text document: " <> getUri _uri
,LSP.didChangeTextDocumentNotificationHandler = withNotification (LSP.didChangeTextDocumentNotificationHandler x) $
\_ ide (DidChangeTextDocumentParams identifier@VersionedTextDocumentIdentifier{_uri} changes) -> do
updatePositionMapping ide identifier changes
whenUriFile _uri $ \file -> do
modifyFilesOfInterest ide (M.insert file Modified)
setFileModified ide False file
logInfo (ideLogger ide) $ "Modified text document: " <> getUri _uri
,LSP.didSaveTextDocumentNotificationHandler = withNotification (LSP.didSaveTextDocumentNotificationHandler x) $
\_ ide (DidSaveTextDocumentParams TextDocumentIdentifier{_uri}) -> do
whenUriFile _uri $ \file -> do
modifyFilesOfInterest ide (M.insert file OnDisk)
setFileModified ide True file
logInfo (ideLogger ide) $ "Saved text document: " <> getUri _uri
,LSP.didCloseTextDocumentNotificationHandler = withNotification (LSP.didCloseTextDocumentNotificationHandler x) $
\_ ide (DidCloseTextDocumentParams TextDocumentIdentifier{_uri}) -> do
whenUriFile _uri $ \file -> do
modifyFilesOfInterest ide (M.delete file)
IdeOptions{optCheckParents} <- getIdeOptionsIO $ shakeExtras ide
when (optCheckParents >= CheckOnClose) $ typecheckParents ide file
logInfo (ideLogger ide) $ "Closed text document: " <> getUri _uri
,LSP.didChangeWatchedFilesNotificationHandler = withNotification (LSP.didChangeWatchedFilesNotificationHandler x) $
\_ ide (DidChangeWatchedFilesParams fileEvents) -> do
let events =
mapMaybe
(\(FileEvent uri ev) ->
(, ev /= FcDeleted) . toNormalizedFilePath'
<$> LSP.uriToFilePath uri
)
( F.toList fileEvents )
let msg = Text.pack $ show events
logInfo (ideLogger ide) $ "Files created or deleted: " <> msg
modifyFileExists ide events
setSomethingModified ide
,LSP.didChangeWorkspaceFoldersNotificationHandler = withNotification (LSP.didChangeWorkspaceFoldersNotificationHandler x) $
\_ ide (DidChangeWorkspaceFoldersParams events) -> do
let add = S.union
substract = flip S.difference
modifyWorkspaceFolders ide
$ add (foldMap (S.singleton . parseWorkspaceFolder) (_added events))
. substract (foldMap (S.singleton . parseWorkspaceFolder) (_removed events))
}