{-# LANGUAGE DataKinds #-}
{-# LANGUAGE NumericUnderscores #-}
{-# LANGUAGE PatternSynonyms #-}
{-# LANGUAGE RecordWildCards #-}

module Unison.LSP.VFS where

import Colog.Core qualified as Colog
import Control.Lens
import Control.Monad.Reader
import Control.Monad.State
import Data.Map qualified as Map
import Data.Set qualified as Set
import Data.Set.Lens (setOf)
import Data.Text qualified as Text
import Data.Text.Utf16.Rope qualified as Rope
import Data.Tuple (swap)
import Language.LSP.Logging qualified as LSP
import Language.LSP.Protocol.Lens (HasCharacter (character), HasParams (params), HasTextDocument (textDocument), HasUri (uri))
import Language.LSP.Protocol.Lens qualified as LSP
import Language.LSP.Protocol.Message qualified as Msg
import Language.LSP.Protocol.Types
import Language.LSP.VFS as VFS hiding (character)
import Unison.LSP.Orphans ()
import Unison.LSP.Types
import Unison.Prelude
import Unison.Syntax.Lexer qualified as Lexer
import UnliftIO

-- | Some VFS combinators require Monad State, this provides it in a transactionally safe
-- manner so we're sure we don't edit the same file in two different actions at the same time.
usingVFS :: forall a. StateT VFS Lsp a -> Lsp a
usingVFS :: forall a. StateT VFS Lsp a -> Lsp a
usingVFS StateT VFS Lsp a
m = do
  MVar VFS
vfsVar' <- (Env -> MVar VFS) -> Lsp (MVar VFS)
forall r (m :: * -> *) a. MonadReader r m => (r -> a) -> m a
asks Env -> MVar VFS
vfsVar
  MVar VFS -> (VFS -> Lsp (VFS, a)) -> Lsp a
forall (m :: * -> *) a b.
MonadUnliftIO m =>
MVar a -> (a -> m (a, b)) -> m b
modifyMVar MVar VFS
vfsVar' ((VFS -> Lsp (VFS, a)) -> Lsp a) -> (VFS -> Lsp (VFS, a)) -> Lsp a
forall a b. (a -> b) -> a -> b
$ \VFS
vfs -> (a, VFS) -> (VFS, a)
forall a b. (a, b) -> (b, a)
swap ((a, VFS) -> (VFS, a)) -> Lsp (a, VFS) -> Lsp (VFS, a)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> StateT VFS Lsp a -> VFS -> Lsp (a, VFS)
forall s (m :: * -> *) a. StateT s m a -> s -> m (a, s)
runStateT StateT VFS Lsp a
m VFS
vfs

getVirtualFile :: Uri -> MaybeT Lsp VirtualFile
getVirtualFile :: Uri -> MaybeT Lsp VirtualFile
getVirtualFile Uri
fileUri = do
  VFS
vfs <- (Env -> MVar VFS) -> MaybeT Lsp (MVar VFS)
forall r (m :: * -> *) a. MonadReader r m => (r -> a) -> m a
asks Env -> MVar VFS
vfsVar MaybeT Lsp (MVar VFS)
-> (MVar VFS -> MaybeT Lsp VFS) -> MaybeT Lsp VFS
forall a b. MaybeT Lsp a -> (a -> MaybeT Lsp b) -> MaybeT Lsp b
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= MVar VFS -> MaybeT Lsp VFS
forall (m :: * -> *) a. MonadIO m => MVar a -> m a
readMVar
  Lsp (Maybe VirtualFile) -> MaybeT Lsp VirtualFile
forall (m :: * -> *) a. m (Maybe a) -> MaybeT m a
MaybeT (Lsp (Maybe VirtualFile) -> MaybeT Lsp VirtualFile)
-> (Maybe VirtualFile -> Lsp (Maybe VirtualFile))
-> Maybe VirtualFile
-> MaybeT Lsp VirtualFile
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Maybe VirtualFile -> Lsp (Maybe VirtualFile)
forall a. a -> Lsp a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Maybe VirtualFile -> MaybeT Lsp VirtualFile)
-> Maybe VirtualFile -> MaybeT Lsp VirtualFile
forall a b. (a -> b) -> a -> b
$ VFS
vfs VFS
-> Getting (Maybe VirtualFile) VFS (Maybe VirtualFile)
-> Maybe VirtualFile
forall s a. s -> Getting a s a -> a
^. (Map NormalizedUri VirtualFile
 -> Const (Maybe VirtualFile) (Map NormalizedUri VirtualFile))
-> VFS -> Const (Maybe VirtualFile) VFS
forall s a. HasVfsMap s a => Lens' s a
Lens' VFS (Map NormalizedUri VirtualFile)
vfsMap ((Map NormalizedUri VirtualFile
  -> Const (Maybe VirtualFile) (Map NormalizedUri VirtualFile))
 -> VFS -> Const (Maybe VirtualFile) VFS)
-> ((Maybe VirtualFile
     -> Const (Maybe VirtualFile) (Maybe VirtualFile))
    -> Map NormalizedUri VirtualFile
    -> Const (Maybe VirtualFile) (Map NormalizedUri VirtualFile))
-> Getting (Maybe VirtualFile) VFS (Maybe VirtualFile)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Index (Map NormalizedUri VirtualFile)
-> Lens'
     (Map NormalizedUri VirtualFile)
     (Maybe (IxValue (Map NormalizedUri VirtualFile)))
forall m. At m => Index m -> Lens' m (Maybe (IxValue m))
at (Uri -> NormalizedUri
toNormalizedUri (Uri -> NormalizedUri) -> Uri -> NormalizedUri
forall a b. (a -> b) -> a -> b
$ Uri
fileUri)

getFileContents :: Uri -> MaybeT Lsp (FileVersion, Text)
getFileContents :: Uri -> MaybeT Lsp (FileVersion, Text)
getFileContents Uri
fileUri = do
  VirtualFile
vf <- Uri -> MaybeT Lsp VirtualFile
getVirtualFile Uri
fileUri
  pure (VirtualFile
vf VirtualFile
-> Getting FileVersion VirtualFile FileVersion -> FileVersion
forall s a. s -> Getting a s a -> a
^. Getting FileVersion VirtualFile FileVersion
forall s a. HasLsp_version s a => Lens' s a
Lens' VirtualFile FileVersion
lsp_version, Rope -> Text
Rope.toText (Rope -> Text) -> Rope -> Text
forall a b. (a -> b) -> a -> b
$ VirtualFile
vf VirtualFile -> Getting Rope VirtualFile Rope -> Rope
forall s a. s -> Getting a s a -> a
^. Getting Rope VirtualFile Rope
forall s a. HasFile_text s a => Lens' s a
Lens' VirtualFile Rope
file_text)

vfsLogger :: Colog.LogAction (StateT VFS Lsp) (Colog.WithSeverity VfsLog)
vfsLogger :: LogAction (StateT VFS Lsp) (WithSeverity VfsLog)
vfsLogger = (WithSeverity VfsLog -> WithSeverity Text)
-> LogAction (StateT VFS Lsp) (WithSeverity Text)
-> LogAction (StateT VFS Lsp) (WithSeverity VfsLog)
forall a b (m :: * -> *).
(a -> b) -> LogAction m b -> LogAction m a
Colog.cmap ((VfsLog -> Text) -> WithSeverity VfsLog -> WithSeverity Text
forall a b. (a -> b) -> WithSeverity a -> WithSeverity b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap VfsLog -> Text
forall a. Show a => a -> Text
tShow) ((forall x. Lsp x -> StateT VFS Lsp x)
-> LogAction Lsp (WithSeverity Text)
-> LogAction (StateT VFS Lsp) (WithSeverity Text)
forall (m :: * -> *) (n :: * -> *) a.
(forall x. m x -> n x) -> LogAction m a -> LogAction n a
Colog.hoistLogAction Lsp x -> StateT VFS Lsp x
forall x. Lsp x -> StateT VFS Lsp x
forall (m :: * -> *) a. Monad m => m a -> StateT VFS m a
forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift LogAction Lsp (WithSeverity Text)
forall c (m :: * -> *).
MonadLsp c m =>
LogAction m (WithSeverity Text)
LSP.defaultClientLogger)

-- | Mark some files as needing to be checked.
markFilesDirty :: (Foldable f, HasUri doc Uri) => f doc -> Lsp ()
markFilesDirty :: forall (f :: * -> *) doc.
(Foldable f, HasUri doc Uri) =>
f doc -> Lsp ()
markFilesDirty f doc
docs = do
  TVar (Set Uri)
dirtyFilesV <- (Env -> TVar (Set Uri)) -> Lsp (TVar (Set Uri))
forall r (m :: * -> *) a. MonadReader r m => (r -> a) -> m a
asks Env -> TVar (Set Uri)
dirtyFilesVar
  TVar (Map Uri (TMVar FileAnalysis))
checkedFilesV <- (Env -> TVar (Map Uri (TMVar FileAnalysis)))
-> Lsp (TVar (Map Uri (TMVar FileAnalysis)))
forall r (m :: * -> *) a. MonadReader r m => (r -> a) -> m a
asks Env -> TVar (Map Uri (TMVar FileAnalysis))
checkedFilesVar
  let dirtyUris :: Set Uri
dirtyUris = Getting (Set Uri) (f doc) Uri -> f doc -> Set Uri
forall a s. Getting (Set a) s a -> s -> Set a
setOf ((doc -> Const (Set Uri) doc) -> f doc -> Const (Set Uri) (f doc)
forall (f :: * -> *) a. Foldable f => IndexedFold Int (f a) a
IndexedFold Int (f doc) doc
folded ((doc -> Const (Set Uri) doc) -> f doc -> Const (Set Uri) (f doc))
-> ((Uri -> Const (Set Uri) Uri) -> doc -> Const (Set Uri) doc)
-> Getting (Set Uri) (f doc) Uri
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Uri -> Const (Set Uri) Uri) -> doc -> Const (Set Uri) doc
forall s a. HasUri s a => Lens' s a
Lens' doc Uri
uri) f doc
docs
  STM () -> Lsp ()
forall (m :: * -> *) a. MonadIO m => STM a -> m a
atomically (STM () -> Lsp ()) -> STM () -> Lsp ()
forall a b. (a -> b) -> a -> b
$ do
    TVar (Set Uri) -> (Set Uri -> Set Uri) -> STM ()
forall a. TVar a -> (a -> a) -> STM ()
modifyTVar' TVar (Set Uri)
dirtyFilesV (Set Uri -> Set Uri -> Set Uri
forall a. Ord a => Set a -> Set a -> Set a
Set.union Set Uri
dirtyUris)
    Map Uri (TMVar FileAnalysis)
checkedFiles <- TVar (Map Uri (TMVar FileAnalysis))
-> STM (Map Uri (TMVar FileAnalysis))
forall a. TVar a -> STM a
readTVar TVar (Map Uri (TMVar FileAnalysis))
checkedFilesV
    -- Clear the analysis for any files which need to be re-checked.
    Set Uri -> (Uri -> STM ()) -> STM ()
forall (t :: * -> *) (f :: * -> *) a b.
(Foldable t, Applicative f) =>
t a -> (a -> f b) -> f ()
for_ Set Uri
dirtyUris \Uri
uri -> do
      case Uri -> Map Uri (TMVar FileAnalysis) -> Maybe (TMVar FileAnalysis)
forall k a. Ord k => k -> Map k a -> Maybe a
Map.lookup Uri
uri Map Uri (TMVar FileAnalysis)
checkedFiles of
        Maybe (TMVar FileAnalysis)
Nothing -> () -> STM ()
forall a. a -> STM a
forall (f :: * -> *) a. Applicative f => a -> f a
pure ()
        Just TMVar FileAnalysis
mvar -> STM (Maybe FileAnalysis) -> STM ()
forall (f :: * -> *) a. Functor f => f a -> f ()
void (STM (Maybe FileAnalysis) -> STM ())
-> STM (Maybe FileAnalysis) -> STM ()
forall a b. (a -> b) -> a -> b
$ TMVar FileAnalysis -> STM (Maybe FileAnalysis)
forall a. TMVar a -> STM (Maybe a)
tryTakeTMVar TMVar FileAnalysis
mvar

-- | Mark all files for re-checking.
--
-- We may want to do this when our names or perspective change.
markAllFilesDirty :: Lsp ()
markAllFilesDirty :: Lsp ()
markAllFilesDirty = do
  VFS
vfs <- (Env -> MVar VFS) -> Lsp (MVar VFS)
forall r (m :: * -> *) a. MonadReader r m => (r -> a) -> m a
asks Env -> MVar VFS
vfsVar Lsp (MVar VFS) -> (MVar VFS -> Lsp VFS) -> Lsp VFS
forall a b. Lsp a -> (a -> Lsp b) -> Lsp b
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= MVar VFS -> Lsp VFS
forall (m :: * -> *) a. MonadIO m => MVar a -> m a
readMVar
  [NormalizedUri] -> Lsp ()
forall (f :: * -> *) doc.
(Foldable f, HasUri doc Uri) =>
f doc -> Lsp ()
markFilesDirty ([NormalizedUri] -> Lsp ()) -> [NormalizedUri] -> Lsp ()
forall a b. (a -> b) -> a -> b
$ Map NormalizedUri VirtualFile -> [NormalizedUri]
forall k a. Map k a -> [k]
Map.keys (VFS
vfs VFS
-> Getting
     (Map NormalizedUri VirtualFile) VFS (Map NormalizedUri VirtualFile)
-> Map NormalizedUri VirtualFile
forall s a. s -> Getting a s a -> a
^. Getting
  (Map NormalizedUri VirtualFile) VFS (Map NormalizedUri VirtualFile)
forall s a. HasVfsMap s a => Lens' s a
Lens' VFS (Map NormalizedUri VirtualFile)
vfsMap)

-- | Returns the name or symbol which the provided position is contained in.
identifierAtPosition :: Uri -> Position -> MaybeT Lsp Text
identifierAtPosition :: Uri -> Position -> MaybeT Lsp Text
identifierAtPosition Uri
uri Position
pos = do
  Uri -> Position -> MaybeT Lsp (Text, Text)
identifierSplitAtPosition Uri
uri Position
pos MaybeT Lsp (Text, Text)
-> ((Text, Text) -> Text) -> MaybeT Lsp Text
forall (f :: * -> *) a b. Functor f => f a -> (a -> b) -> f b
<&> \(Text
before, Text
after) -> (Text
before Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
after)

-- | Returns the prefix and suffix of the symbol which the provided position is contained in.
identifierSplitAtPosition :: Uri -> Position -> MaybeT Lsp (Text, Text)
identifierSplitAtPosition :: Uri -> Position -> MaybeT Lsp (Text, Text)
identifierSplitAtPosition Uri
uri Position
pos = do
  VirtualFile
vf <- Uri -> MaybeT Lsp VirtualFile
getVirtualFile Uri
uri
  PosPrefixInfo {Text
fullLine :: Text
$sel:fullLine:PosPrefixInfo :: PosPrefixInfo -> Text
fullLine, Position
cursorPos :: Position
$sel:cursorPos:PosPrefixInfo :: PosPrefixInfo -> Position
cursorPos} <- Lsp (Maybe PosPrefixInfo) -> MaybeT Lsp PosPrefixInfo
forall (m :: * -> *) a. m (Maybe a) -> MaybeT m a
MaybeT (Position -> VirtualFile -> Lsp (Maybe PosPrefixInfo)
forall (m :: * -> *).
Monad m =>
Position -> VirtualFile -> m (Maybe PosPrefixInfo)
VFS.getCompletionPrefix Position
pos VirtualFile
vf)
  let (Text
before, Text
after) = Int -> Text -> (Text, Text)
Text.splitAt (Position
cursorPos Position -> Getting Int Position Int -> Int
forall s a. s -> Getting a s a -> a
^. (UInt -> Const Int UInt) -> Position -> Const Int Position
forall s a. HasCharacter s a => Lens' s a
Lens' Position UInt
character ((UInt -> Const Int UInt) -> Position -> Const Int Position)
-> ((Int -> Const Int Int) -> UInt -> Const Int UInt)
-> Getting Int Position Int
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (UInt -> Int) -> (Int -> Const Int Int) -> UInt -> Const Int UInt
forall (p :: * -> * -> *) (f :: * -> *) s a.
(Profunctor p, Contravariant f) =>
(s -> a) -> Optic' p f s a
to UInt -> Int
forall a b. (Integral a, Num b) => a -> b
fromIntegral) Text
fullLine
  (Text, Text) -> MaybeT Lsp (Text, Text)
forall a. a -> MaybeT Lsp a
forall (f :: * -> *) a. Applicative f => a -> f a
pure
    ( (Char -> Bool) -> Text -> Text
Text.takeWhileEnd Char -> Bool
isIdentifierChar Text
before,
      -- names can end with '!', and it's not a force, so we include it in the identifier if it's at the end.
      (Char -> Bool) -> Text -> Text
Text.takeWhile (\Char
c -> Char -> Bool
isIdentifierChar Char
c Bool -> Bool -> Bool
|| Char
c Char -> Char -> Bool
forall a. Eq a => a -> a -> Bool
== Char
'!') Text
after
    )
  where
    isIdentifierChar :: Char -> Bool
isIdentifierChar Char
c =
      -- Manually exclude '!' and apostrophe, since those are usually just forces and
      -- delays, which shouldn't be replaced by auto-complete.
      (Char
c Char -> Char -> Bool
forall a. Eq a => a -> a -> Bool
/= Char
'!' Bool -> Bool -> Bool
&& Char
c Char -> Char -> Bool
forall a. Eq a => a -> a -> Bool
/= Char
'\'')
        Bool -> Bool -> Bool
&& (Char
c Char -> Char -> Bool
forall a. Eq a => a -> a -> Bool
== Char
'.' Bool -> Bool -> Bool
|| Char -> Bool
Lexer.wordyIdChar Char
c Bool -> Bool -> Bool
|| Char -> Bool
Lexer.symbolyIdChar Char
c)

-- | Returns the prefix of the symbol at the provided location, and the range that prefix
-- spans.
completionPrefix :: Uri -> Position -> MaybeT Lsp (Range, Text)
completionPrefix :: Uri -> Position -> MaybeT Lsp (Range, Text)
completionPrefix Uri
uri Position
pos = do
  (Text
before, Text
_) <- Uri -> Position -> MaybeT Lsp (Text, Text)
identifierSplitAtPosition Uri
uri Position
pos
  let posLine :: UInt
posLine = Position
pos Position -> Getting UInt Position UInt -> UInt
forall s a. s -> Getting a s a -> a
^. Getting UInt Position UInt
forall s a. HasLine s a => Lens' s a
Lens' Position UInt
LSP.line
  let posChar :: UInt
posChar = Position
pos Position -> Getting UInt Position UInt -> UInt
forall s a. s -> Getting a s a -> a
^. Getting UInt Position UInt
forall s a. HasCharacter s a => Lens' s a
Lens' Position UInt
LSP.character
  let range :: Range
range = UInt -> UInt -> UInt -> UInt -> Range
mkRange UInt
posLine (UInt
posChar UInt -> UInt -> UInt
forall a. Num a => a -> a -> a
- Int -> UInt
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Text -> Int
Text.length Text
before)) UInt
posLine UInt
posChar
  (Range, Text) -> MaybeT Lsp (Range, Text)
forall a. a -> MaybeT Lsp a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Range
range, Text
before)

--- Handlers for tracking file changes.

lspOpenFile :: Msg.TNotificationMessage 'Msg.Method_TextDocumentDidOpen -> Lsp ()
lspOpenFile :: TNotificationMessage 'Method_TextDocumentDidOpen -> Lsp ()
lspOpenFile TNotificationMessage 'Method_TextDocumentDidOpen
msg = do
  StateT VFS Lsp () -> Lsp ()
forall a. StateT VFS Lsp a -> Lsp a
usingVFS (StateT VFS Lsp () -> Lsp ())
-> (TNotificationMessage 'Method_TextDocumentDidOpen
    -> StateT VFS Lsp ())
-> TNotificationMessage 'Method_TextDocumentDidOpen
-> Lsp ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. LogAction (StateT VFS Lsp) (WithSeverity VfsLog)
-> TMessage 'Method_TextDocumentDidOpen -> StateT VFS Lsp ()
forall (m :: * -> *).
MonadState VFS m =>
LogAction m (WithSeverity VfsLog)
-> TMessage 'Method_TextDocumentDidOpen -> m ()
openVFS LogAction (StateT VFS Lsp) (WithSeverity VfsLog)
vfsLogger (TNotificationMessage 'Method_TextDocumentDidOpen -> Lsp ())
-> TNotificationMessage 'Method_TextDocumentDidOpen -> Lsp ()
forall a b. (a -> b) -> a -> b
$ TNotificationMessage 'Method_TextDocumentDidOpen
msg
  [TextDocumentItem] -> Lsp ()
forall (f :: * -> *) doc.
(Foldable f, HasUri doc Uri) =>
f doc -> Lsp ()
markFilesDirty [TNotificationMessage 'Method_TextDocumentDidOpen
msg TNotificationMessage 'Method_TextDocumentDidOpen
-> Getting
     TextDocumentItem
     (TNotificationMessage 'Method_TextDocumentDidOpen)
     TextDocumentItem
-> TextDocumentItem
forall s a. s -> Getting a s a -> a
^. (DidOpenTextDocumentParams
 -> Const TextDocumentItem DidOpenTextDocumentParams)
-> TNotificationMessage 'Method_TextDocumentDidOpen
-> Const
     TextDocumentItem (TNotificationMessage 'Method_TextDocumentDidOpen)
forall s a. HasParams s a => Lens' s a
Lens'
  (TNotificationMessage 'Method_TextDocumentDidOpen)
  DidOpenTextDocumentParams
params ((DidOpenTextDocumentParams
  -> Const TextDocumentItem DidOpenTextDocumentParams)
 -> TNotificationMessage 'Method_TextDocumentDidOpen
 -> Const
      TextDocumentItem
      (TNotificationMessage 'Method_TextDocumentDidOpen))
-> ((TextDocumentItem -> Const TextDocumentItem TextDocumentItem)
    -> DidOpenTextDocumentParams
    -> Const TextDocumentItem DidOpenTextDocumentParams)
-> Getting
     TextDocumentItem
     (TNotificationMessage 'Method_TextDocumentDidOpen)
     TextDocumentItem
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (TextDocumentItem -> Const TextDocumentItem TextDocumentItem)
-> DidOpenTextDocumentParams
-> Const TextDocumentItem DidOpenTextDocumentParams
forall s a. HasTextDocument s a => Lens' s a
Lens' DidOpenTextDocumentParams TextDocumentItem
textDocument]

lspCloseFile :: Msg.TNotificationMessage 'Msg.Method_TextDocumentDidClose -> Lsp ()
lspCloseFile :: TNotificationMessage 'Method_TextDocumentDidClose -> Lsp ()
lspCloseFile TNotificationMessage 'Method_TextDocumentDidClose
msg =
  StateT VFS Lsp () -> Lsp ()
forall a. StateT VFS Lsp a -> Lsp a
usingVFS (StateT VFS Lsp () -> Lsp ())
-> (TNotificationMessage 'Method_TextDocumentDidClose
    -> StateT VFS Lsp ())
-> TNotificationMessage 'Method_TextDocumentDidClose
-> Lsp ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. LogAction (StateT VFS Lsp) (WithSeverity VfsLog)
-> TMessage 'Method_TextDocumentDidClose -> StateT VFS Lsp ()
forall (m :: * -> *).
MonadState VFS m =>
LogAction m (WithSeverity VfsLog)
-> TMessage 'Method_TextDocumentDidClose -> m ()
closeVFS LogAction (StateT VFS Lsp) (WithSeverity VfsLog)
vfsLogger (TNotificationMessage 'Method_TextDocumentDidClose -> Lsp ())
-> TNotificationMessage 'Method_TextDocumentDidClose -> Lsp ()
forall a b. (a -> b) -> a -> b
$ TNotificationMessage 'Method_TextDocumentDidClose
msg

lspChangeFile :: Msg.TNotificationMessage 'Msg.Method_TextDocumentDidChange -> Lsp ()
lspChangeFile :: TNotificationMessage 'Method_TextDocumentDidChange -> Lsp ()
lspChangeFile TNotificationMessage 'Method_TextDocumentDidChange
msg = do
  StateT VFS Lsp () -> Lsp ()
forall a. StateT VFS Lsp a -> Lsp a
usingVFS (StateT VFS Lsp () -> Lsp ())
-> (TNotificationMessage 'Method_TextDocumentDidChange
    -> StateT VFS Lsp ())
-> TNotificationMessage 'Method_TextDocumentDidChange
-> Lsp ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. LogAction (StateT VFS Lsp) (WithSeverity VfsLog)
-> TMessage 'Method_TextDocumentDidChange -> StateT VFS Lsp ()
forall (m :: * -> *).
MonadState VFS m =>
LogAction m (WithSeverity VfsLog)
-> TMessage 'Method_TextDocumentDidChange -> m ()
changeFromClientVFS LogAction (StateT VFS Lsp) (WithSeverity VfsLog)
vfsLogger (TNotificationMessage 'Method_TextDocumentDidChange -> Lsp ())
-> TNotificationMessage 'Method_TextDocumentDidChange -> Lsp ()
forall a b. (a -> b) -> a -> b
$ TNotificationMessage 'Method_TextDocumentDidChange
msg
  [VersionedTextDocumentIdentifier] -> Lsp ()
forall (f :: * -> *) doc.
(Foldable f, HasUri doc Uri) =>
f doc -> Lsp ()
markFilesDirty [TNotificationMessage 'Method_TextDocumentDidChange
msg TNotificationMessage 'Method_TextDocumentDidChange
-> Getting
     VersionedTextDocumentIdentifier
     (TNotificationMessage 'Method_TextDocumentDidChange)
     VersionedTextDocumentIdentifier
-> VersionedTextDocumentIdentifier
forall s a. s -> Getting a s a -> a
^. (DidChangeTextDocumentParams
 -> Const
      VersionedTextDocumentIdentifier DidChangeTextDocumentParams)
-> TNotificationMessage 'Method_TextDocumentDidChange
-> Const
     VersionedTextDocumentIdentifier
     (TNotificationMessage 'Method_TextDocumentDidChange)
forall s a. HasParams s a => Lens' s a
Lens'
  (TNotificationMessage 'Method_TextDocumentDidChange)
  DidChangeTextDocumentParams
params ((DidChangeTextDocumentParams
  -> Const
       VersionedTextDocumentIdentifier DidChangeTextDocumentParams)
 -> TNotificationMessage 'Method_TextDocumentDidChange
 -> Const
      VersionedTextDocumentIdentifier
      (TNotificationMessage 'Method_TextDocumentDidChange))
-> ((VersionedTextDocumentIdentifier
     -> Const
          VersionedTextDocumentIdentifier VersionedTextDocumentIdentifier)
    -> DidChangeTextDocumentParams
    -> Const
         VersionedTextDocumentIdentifier DidChangeTextDocumentParams)
-> Getting
     VersionedTextDocumentIdentifier
     (TNotificationMessage 'Method_TextDocumentDidChange)
     VersionedTextDocumentIdentifier
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (VersionedTextDocumentIdentifier
 -> Const
      VersionedTextDocumentIdentifier VersionedTextDocumentIdentifier)
-> DidChangeTextDocumentParams
-> Const
     VersionedTextDocumentIdentifier DidChangeTextDocumentParams
forall s a. HasTextDocument s a => Lens' s a
Lens' DidChangeTextDocumentParams VersionedTextDocumentIdentifier
textDocument]