{-# LANGUAGE BangPatterns #-}
{-# LANGUAGE BinaryLiterals #-}
{-# LANGUAGE DerivingVia #-}
{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE FunctionalDependencies #-}
{-# LANGUAGE GADTs #-}
{-# LANGUAGE GeneralizedNewtypeDeriving #-}
{-# LANGUAGE LambdaCase #-}
{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE RankNTypes #-}
{-# LANGUAGE RoleAnnotations #-}
{-# LANGUAGE ScopedTypeVariables #-}
{-# LANGUAGE TypeFamilyDependencies #-}
{-# LANGUAGE TypeInType #-}
{-# LANGUAGE TypeOperators #-}
{-# LANGUAGE UndecidableInstances #-}
{-# OPTIONS_GHC -Wno-unticked-promoted-constructors #-}
{-# OPTIONS_GHC -fprint-explicit-kinds #-}
module Language.LSP.Server.Core where
import Colog.Core (
LogAction (..),
Severity (..),
WithSeverity (..),
(<&),
)
import Control.Concurrent.Async
import Control.Concurrent.STM
import Control.Exception qualified as E
import Control.Lens (at, (^.), (^?), _Just)
import Control.Monad
import Control.Monad.Catch (
MonadCatch,
MonadMask,
MonadThrow,
)
import Control.Monad.Fix
import Control.Monad.IO.Class
import Control.Monad.IO.Unlift
import Control.Monad.Trans.Class
import Control.Monad.Trans.Identity
import Control.Monad.Trans.Reader
import Data.Aeson qualified as J
import Data.Default
import Data.Functor.Product
import Data.HashMap.Strict qualified as HM
import Data.IxMap
import Data.Kind
import Data.List qualified as L
import Data.List.NonEmpty (NonEmpty (..))
import Data.Map.Strict qualified as Map
import Data.Maybe
import Data.Monoid (Ap (..))
import Data.Ord (Down (Down))
import Data.Row
import Data.Text (Text)
import Data.Text qualified as T
import Data.UUID qualified as UUID
import Language.LSP.Diagnostics
import Language.LSP.Protocol.Capabilities
import Language.LSP.Protocol.Lens qualified as L
import Language.LSP.Protocol.Message
import Language.LSP.Protocol.Message qualified as L
import Language.LSP.Protocol.Types
import Language.LSP.Protocol.Types qualified as L
import Language.LSP.Protocol.Utils.Misc (prettyJSON)
import Language.LSP.Protocol.Utils.SMethodMap (SMethodMap)
import Language.LSP.Protocol.Utils.SMethodMap qualified as SMethodMap
import Language.LSP.VFS
import Prettyprinter
import System.Random hiding (next)
{-# ANN module ("HLint: ignore Eta reduce" :: String) #-}
{-# ANN module ("HLint: ignore Redundant do" :: String) #-}
{-# ANN module ("HLint: ignore Reduce duplication" :: String) #-}
data LspCoreLog
=
NewConfig J.Value
| ConfigurationParseError J.Value T.Text
| ConfigurationNotSupported
| BadConfigurationResponse ResponseError
| WrongConfigSections [J.Value]
deriving (Int -> LspCoreLog -> ShowS
[LspCoreLog] -> ShowS
LspCoreLog -> String
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [LspCoreLog] -> ShowS
$cshowList :: [LspCoreLog] -> ShowS
show :: LspCoreLog -> String
$cshow :: LspCoreLog -> String
showsPrec :: Int -> LspCoreLog -> ShowS
$cshowsPrec :: Int -> LspCoreLog -> ShowS
Show)
instance Pretty LspCoreLog where
pretty :: forall ann. LspCoreLog -> Doc ann
pretty (NewConfig Value
config) = Doc ann
"LSP: set new config:" forall ann. Doc ann -> Doc ann -> Doc ann
<+> forall ann. Value -> Doc ann
prettyJSON Value
config
pretty (LspCoreLog
ConfigurationNotSupported) = Doc ann
"LSP: not requesting configuration since the client does not support workspace/configuration"
pretty (ConfigurationParseError Value
settings Text
err) =
forall ann. [Doc ann] -> Doc ann
vsep
[ Doc ann
"LSP: configuration parse error:"
, forall a ann. Pretty a => a -> Doc ann
pretty Text
err
, Doc ann
"when parsing"
, forall ann. Value -> Doc ann
prettyJSON Value
settings
]
pretty (BadConfigurationResponse ResponseError
err) = Doc ann
"LSP: error when requesting configuration: " forall ann. Doc ann -> Doc ann -> Doc ann
<+> forall a ann. Pretty a => a -> Doc ann
pretty ResponseError
err
pretty (WrongConfigSections [Value]
sections) = Doc ann
"LSP: expected only one configuration section, got: " forall ann. Doc ann -> Doc ann -> Doc ann
<+> (forall ann. Value -> Doc ann
prettyJSON forall a b. (a -> b) -> a -> b
$ forall a. ToJSON a => a -> Value
J.toJSON [Value]
sections)
newtype LspT config m a = LspT {forall config (m :: * -> *) a.
LspT config m a -> ReaderT (LanguageContextEnv config) m a
unLspT :: ReaderT (LanguageContextEnv config) m a}
deriving (forall a b. a -> LspT config m b -> LspT config m a
forall a b. (a -> b) -> LspT config m a -> LspT config m b
forall config (m :: * -> *) a b.
Functor m =>
a -> LspT config m b -> LspT config m a
forall config (m :: * -> *) a b.
Functor m =>
(a -> b) -> LspT config m a -> LspT config m b
forall (f :: * -> *).
(forall a b. (a -> b) -> f a -> f b)
-> (forall a b. a -> f b -> f a) -> Functor f
<$ :: forall a b. a -> LspT config m b -> LspT config m a
$c<$ :: forall config (m :: * -> *) a b.
Functor m =>
a -> LspT config m b -> LspT config m a
fmap :: forall a b. (a -> b) -> LspT config m a -> LspT config m b
$cfmap :: forall config (m :: * -> *) a b.
Functor m =>
(a -> b) -> LspT config m a -> LspT config m b
Functor, forall a. a -> LspT config m a
forall a b. LspT config m a -> LspT config m b -> LspT config m a
forall a b. LspT config m a -> LspT config m b -> LspT config m b
forall a b.
LspT config m (a -> b) -> LspT config m a -> LspT config m b
forall a b c.
(a -> b -> c)
-> LspT config m a -> LspT config m b -> LspT config m c
forall {config} {m :: * -> *}.
Applicative m =>
Functor (LspT config m)
forall config (m :: * -> *) a.
Applicative m =>
a -> LspT config m a
forall config (m :: * -> *) a b.
Applicative m =>
LspT config m a -> LspT config m b -> LspT config m a
forall config (m :: * -> *) a b.
Applicative m =>
LspT config m a -> LspT config m b -> LspT config m b
forall config (m :: * -> *) a b.
Applicative m =>
LspT config m (a -> b) -> LspT config m a -> LspT config m b
forall config (m :: * -> *) a b c.
Applicative m =>
(a -> b -> c)
-> LspT config m a -> LspT config m b -> LspT config m c
forall (f :: * -> *).
Functor f
-> (forall a. a -> f a)
-> (forall a b. f (a -> b) -> f a -> f b)
-> (forall a b c. (a -> b -> c) -> f a -> f b -> f c)
-> (forall a b. f a -> f b -> f b)
-> (forall a b. f a -> f b -> f a)
-> Applicative f
<* :: forall a b. LspT config m a -> LspT config m b -> LspT config m a
$c<* :: forall config (m :: * -> *) a b.
Applicative m =>
LspT config m a -> LspT config m b -> LspT config m a
*> :: forall a b. LspT config m a -> LspT config m b -> LspT config m b
$c*> :: forall config (m :: * -> *) a b.
Applicative m =>
LspT config m a -> LspT config m b -> LspT config m b
liftA2 :: forall a b c.
(a -> b -> c)
-> LspT config m a -> LspT config m b -> LspT config m c
$cliftA2 :: forall config (m :: * -> *) a b c.
Applicative m =>
(a -> b -> c)
-> LspT config m a -> LspT config m b -> LspT config m c
<*> :: forall a b.
LspT config m (a -> b) -> LspT config m a -> LspT config m b
$c<*> :: forall config (m :: * -> *) a b.
Applicative m =>
LspT config m (a -> b) -> LspT config m a -> LspT config m b
pure :: forall a. a -> LspT config m a
$cpure :: forall config (m :: * -> *) a.
Applicative m =>
a -> LspT config m a
Applicative, forall a. a -> LspT config m a
forall a b. LspT config m a -> LspT config m b -> LspT config m b
forall a b.
LspT config m a -> (a -> LspT config m b) -> LspT config m b
forall {config} {m :: * -> *}.
Monad m =>
Applicative (LspT config m)
forall config (m :: * -> *) a. Monad m => a -> LspT config m a
forall config (m :: * -> *) a b.
Monad m =>
LspT config m a -> LspT config m b -> LspT config m b
forall config (m :: * -> *) a b.
Monad m =>
LspT config m a -> (a -> LspT config m b) -> LspT config m b
forall (m :: * -> *).
Applicative m
-> (forall a b. m a -> (a -> m b) -> m b)
-> (forall a b. m a -> m b -> m b)
-> (forall a. a -> m a)
-> Monad m
return :: forall a. a -> LspT config m a
$creturn :: forall config (m :: * -> *) a. Monad m => a -> LspT config m a
>> :: forall a b. LspT config m a -> LspT config m b -> LspT config m b
$c>> :: forall config (m :: * -> *) a b.
Monad m =>
LspT config m a -> LspT config m b -> LspT config m b
>>= :: forall a b.
LspT config m a -> (a -> LspT config m b) -> LspT config m b
$c>>= :: forall config (m :: * -> *) a b.
Monad m =>
LspT config m a -> (a -> LspT config m b) -> LspT config m b
Monad, forall e a.
Exception e =>
LspT config m a -> (e -> LspT config m a) -> LspT config m a
forall {config} {m :: * -> *}.
MonadCatch m =>
MonadThrow (LspT config m)
forall config (m :: * -> *) e a.
(MonadCatch m, Exception e) =>
LspT config m a -> (e -> LspT config m a) -> LspT config m a
forall (m :: * -> *).
MonadThrow m
-> (forall e a. Exception e => m a -> (e -> m a) -> m a)
-> MonadCatch m
catch :: forall e a.
Exception e =>
LspT config m a -> (e -> LspT config m a) -> LspT config m a
$ccatch :: forall config (m :: * -> *) e a.
(MonadCatch m, Exception e) =>
LspT config m a -> (e -> LspT config m a) -> LspT config m a
MonadCatch, forall a. IO a -> LspT config m a
forall {config} {m :: * -> *}. MonadIO m => Monad (LspT config m)
forall config (m :: * -> *) a. MonadIO m => IO a -> LspT config m a
forall (m :: * -> *).
Monad m -> (forall a. IO a -> m a) -> MonadIO m
liftIO :: forall a. IO a -> LspT config m a
$cliftIO :: forall config (m :: * -> *) a. MonadIO m => IO a -> LspT config m a
MonadIO, forall b.
((forall a. LspT config m a -> LspT config m a) -> LspT config m b)
-> LspT config m b
forall a b c.
LspT config m a
-> (a -> ExitCase b -> LspT config m c)
-> (a -> LspT config m b)
-> LspT config m (b, c)
forall {config} {m :: * -> *}.
MonadMask m =>
MonadCatch (LspT config m)
forall config (m :: * -> *) b.
MonadMask m =>
((forall a. LspT config m a -> LspT config m a) -> LspT config m b)
-> LspT config m b
forall config (m :: * -> *) a b c.
MonadMask m =>
LspT config m a
-> (a -> ExitCase b -> LspT config m c)
-> (a -> LspT config m b)
-> LspT config m (b, c)
forall (m :: * -> *).
MonadCatch m
-> (forall b. ((forall a. m a -> m a) -> m b) -> m b)
-> (forall b. ((forall a. m a -> m a) -> m b) -> m b)
-> (forall a b c.
m a -> (a -> ExitCase b -> m c) -> (a -> m b) -> m (b, c))
-> MonadMask m
generalBracket :: forall a b c.
LspT config m a
-> (a -> ExitCase b -> LspT config m c)
-> (a -> LspT config m b)
-> LspT config m (b, c)
$cgeneralBracket :: forall config (m :: * -> *) a b c.
MonadMask m =>
LspT config m a
-> (a -> ExitCase b -> LspT config m c)
-> (a -> LspT config m b)
-> LspT config m (b, c)
uninterruptibleMask :: forall b.
((forall a. LspT config m a -> LspT config m a) -> LspT config m b)
-> LspT config m b
$cuninterruptibleMask :: forall config (m :: * -> *) b.
MonadMask m =>
((forall a. LspT config m a -> LspT config m a) -> LspT config m b)
-> LspT config m b
mask :: forall b.
((forall a. LspT config m a -> LspT config m a) -> LspT config m b)
-> LspT config m b
$cmask :: forall config (m :: * -> *) b.
MonadMask m =>
((forall a. LspT config m a -> LspT config m a) -> LspT config m b)
-> LspT config m b
MonadMask, forall e a. Exception e => e -> LspT config m a
forall {config} {m :: * -> *}.
MonadThrow m =>
Monad (LspT config m)
forall config (m :: * -> *) e a.
(MonadThrow m, Exception e) =>
e -> LspT config m a
forall (m :: * -> *).
Monad m -> (forall e a. Exception e => e -> m a) -> MonadThrow m
throwM :: forall e a. Exception e => e -> LspT config m a
$cthrowM :: forall config (m :: * -> *) e a.
(MonadThrow m, Exception e) =>
e -> LspT config m a
MonadThrow, forall config (m :: * -> *) a. Monad m => m a -> LspT config m a
forall (m :: * -> *) a. Monad m => m a -> LspT config m a
forall (t :: (* -> *) -> * -> *).
(forall (m :: * -> *) a. Monad m => m a -> t m a) -> MonadTrans t
lift :: forall (m :: * -> *) a. Monad m => m a -> LspT config m a
$clift :: forall config (m :: * -> *) a. Monad m => m a -> LspT config m a
MonadTrans, forall b.
((forall a. LspT config m a -> IO a) -> IO b) -> LspT config m b
forall {config} {m :: * -> *}.
MonadUnliftIO m =>
MonadIO (LspT config m)
forall config (m :: * -> *) b.
MonadUnliftIO m =>
((forall a. LspT config m a -> IO a) -> IO b) -> LspT config m b
forall (m :: * -> *).
MonadIO m
-> (forall b. ((forall a. m a -> IO a) -> IO b) -> m b)
-> MonadUnliftIO m
withRunInIO :: forall b.
((forall a. LspT config m a -> IO a) -> IO b) -> LspT config m b
$cwithRunInIO :: forall config (m :: * -> *) b.
MonadUnliftIO m =>
((forall a. LspT config m a -> IO a) -> IO b) -> LspT config m b
MonadUnliftIO, forall a. (a -> LspT config m a) -> LspT config m a
forall {config} {m :: * -> *}. MonadFix m => Monad (LspT config m)
forall config (m :: * -> *) a.
MonadFix m =>
(a -> LspT config m a) -> LspT config m a
forall (m :: * -> *).
Monad m -> (forall a. (a -> m a) -> m a) -> MonadFix m
mfix :: forall a. (a -> LspT config m a) -> LspT config m a
$cmfix :: forall config (m :: * -> *) a.
MonadFix m =>
(a -> LspT config m a) -> LspT config m a
MonadFix)
deriving (NonEmpty (LspT config m a) -> LspT config m a
LspT config m a -> LspT config m a -> LspT config m a
forall b. Integral b => b -> LspT config m a -> LspT config m a
forall a.
(a -> a -> a)
-> (NonEmpty a -> a)
-> (forall b. Integral b => b -> a -> a)
-> Semigroup a
forall config (m :: * -> *) a.
(Applicative m, Semigroup a) =>
NonEmpty (LspT config m a) -> LspT config m a
forall config (m :: * -> *) a.
(Applicative m, Semigroup a) =>
LspT config m a -> LspT config m a -> LspT config m a
forall config (m :: * -> *) a b.
(Applicative m, Semigroup a, Integral b) =>
b -> LspT config m a -> LspT config m a
stimes :: forall b. Integral b => b -> LspT config m a -> LspT config m a
$cstimes :: forall config (m :: * -> *) a b.
(Applicative m, Semigroup a, Integral b) =>
b -> LspT config m a -> LspT config m a
sconcat :: NonEmpty (LspT config m a) -> LspT config m a
$csconcat :: forall config (m :: * -> *) a.
(Applicative m, Semigroup a) =>
NonEmpty (LspT config m a) -> LspT config m a
<> :: LspT config m a -> LspT config m a -> LspT config m a
$c<> :: forall config (m :: * -> *) a.
(Applicative m, Semigroup a) =>
LspT config m a -> LspT config m a -> LspT config m a
Semigroup, LspT config m a
[LspT config m a] -> LspT config m a
LspT config m a -> LspT config m a -> LspT config m a
forall a.
Semigroup a -> a -> (a -> a -> a) -> ([a] -> a) -> Monoid a
forall {config} {m :: * -> *} {a}.
(Applicative m, Monoid a) =>
Semigroup (LspT config m a)
forall config (m :: * -> *) a.
(Applicative m, Monoid a) =>
LspT config m a
forall config (m :: * -> *) a.
(Applicative m, Monoid a) =>
[LspT config m a] -> LspT config m a
forall config (m :: * -> *) a.
(Applicative m, Monoid a) =>
LspT config m a -> LspT config m a -> LspT config m a
mconcat :: [LspT config m a] -> LspT config m a
$cmconcat :: forall config (m :: * -> *) a.
(Applicative m, Monoid a) =>
[LspT config m a] -> LspT config m a
mappend :: LspT config m a -> LspT config m a -> LspT config m a
$cmappend :: forall config (m :: * -> *) a.
(Applicative m, Monoid a) =>
LspT config m a -> LspT config m a -> LspT config m a
mempty :: LspT config m a
$cmempty :: forall config (m :: * -> *) a.
(Applicative m, Monoid a) =>
LspT config m a
Monoid) via (Ap (LspT config m) a)
type role LspT representational representational nominal
runLspT :: LanguageContextEnv config -> LspT config m a -> m a
runLspT :: forall config (m :: * -> *) a.
LanguageContextEnv config -> LspT config m a -> m a
runLspT LanguageContextEnv config
env = forall a b c. (a -> b -> c) -> b -> a -> c
flip forall r (m :: * -> *) a. ReaderT r m a -> r -> m a
runReaderT LanguageContextEnv config
env forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall config (m :: * -> *) a.
LspT config m a -> ReaderT (LanguageContextEnv config) m a
unLspT
{-# INLINE runLspT #-}
type LspM config = LspT config IO
class MonadUnliftIO m => MonadLsp config m | m -> config where
getLspEnv :: m (LanguageContextEnv config)
instance MonadUnliftIO m => MonadLsp config (LspT config m) where
{-# SPECIALIZE instance MonadLsp config (LspT config IO) #-}
{-# INLINE getLspEnv #-}
getLspEnv :: LspT config m (LanguageContextEnv config)
getLspEnv = forall config (m :: * -> *) a.
ReaderT (LanguageContextEnv config) m a -> LspT config m a
LspT forall (m :: * -> *) r. Monad m => ReaderT r m r
ask
instance MonadLsp c m => MonadLsp c (ReaderT r m) where
{-# SPECIALIZE instance MonadLsp config (ReaderT r (LspT config IO)) #-}
{-# INLINE getLspEnv #-}
getLspEnv :: ReaderT r m (LanguageContextEnv c)
getLspEnv = forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift forall config (m :: * -> *).
MonadLsp config m =>
m (LanguageContextEnv config)
getLspEnv
instance MonadLsp c m => MonadLsp c (IdentityT m) where
getLspEnv :: IdentityT @(*) m (LanguageContextEnv c)
getLspEnv = forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift forall config (m :: * -> *).
MonadLsp config m =>
m (LanguageContextEnv config)
getLspEnv
data LanguageContextEnv config = LanguageContextEnv
{ forall config. LanguageContextEnv config -> Handlers IO
resHandlers :: !(Handlers IO)
, forall config. LanguageContextEnv config -> Text
resConfigSection :: T.Text
, forall config.
LanguageContextEnv config -> config -> Value -> Either Text config
resParseConfig :: !(config -> J.Value -> Either T.Text config)
, forall config. LanguageContextEnv config -> config -> IO ()
resOnConfigChange :: !(config -> IO ())
, forall config.
LanguageContextEnv config -> FromServerMessage -> IO ()
resSendMessage :: !(FromServerMessage -> IO ())
,
forall config.
LanguageContextEnv config -> LanguageContextState config
resState :: !(LanguageContextState config)
, forall config. LanguageContextEnv config -> ClientCapabilities
resClientCapabilities :: !L.ClientCapabilities
, forall config. LanguageContextEnv config -> Maybe String
resRootPath :: !(Maybe FilePath)
}
data Handlers m = Handlers
{ forall (m :: * -> *).
Handlers m
-> SMethodMap
@'ClientToServer @'Request (ClientMessageHandler m 'Request)
reqHandlers :: !(SMethodMap (ClientMessageHandler m Request))
, forall (m :: * -> *).
Handlers m
-> SMethodMap
@'ClientToServer
@'Notification
(ClientMessageHandler m 'Notification)
notHandlers :: !(SMethodMap (ClientMessageHandler m Notification))
}
instance Semigroup (Handlers config) where
Handlers SMethodMap
@'ClientToServer @'Request (ClientMessageHandler config 'Request)
r1 SMethodMap
@'ClientToServer
@'Notification
(ClientMessageHandler config 'Notification)
n1 <> :: Handlers config -> Handlers config -> Handlers config
<> Handlers SMethodMap
@'ClientToServer @'Request (ClientMessageHandler config 'Request)
r2 SMethodMap
@'ClientToServer
@'Notification
(ClientMessageHandler config 'Notification)
n2 = forall (m :: * -> *).
SMethodMap
@'ClientToServer @'Request (ClientMessageHandler m 'Request)
-> SMethodMap
@'ClientToServer
@'Notification
(ClientMessageHandler m 'Notification)
-> Handlers m
Handlers (SMethodMap
@'ClientToServer @'Request (ClientMessageHandler config 'Request)
r1 forall a. Semigroup a => a -> a -> a
<> SMethodMap
@'ClientToServer @'Request (ClientMessageHandler config 'Request)
r2) (SMethodMap
@'ClientToServer
@'Notification
(ClientMessageHandler config 'Notification)
n1 forall a. Semigroup a => a -> a -> a
<> SMethodMap
@'ClientToServer
@'Notification
(ClientMessageHandler config 'Notification)
n2)
instance Monoid (Handlers config) where
mempty :: Handlers config
mempty = forall (m :: * -> *).
SMethodMap
@'ClientToServer @'Request (ClientMessageHandler m 'Request)
-> SMethodMap
@'ClientToServer
@'Notification
(ClientMessageHandler m 'Notification)
-> Handlers m
Handlers forall a. Monoid a => a
mempty forall a. Monoid a => a
mempty
notificationHandler :: forall (m :: Method ClientToServer Notification) f. SMethod m -> Handler f m -> Handlers f
notificationHandler :: forall (m :: Method 'ClientToServer 'Notification) (f :: * -> *).
SMethod @'ClientToServer @'Notification m
-> Handler @'ClientToServer @'Notification f m -> Handlers f
notificationHandler SMethod @'ClientToServer @'Notification m
m Handler @'ClientToServer @'Notification f m
h = forall (m :: * -> *).
SMethodMap
@'ClientToServer @'Request (ClientMessageHandler m 'Request)
-> SMethodMap
@'ClientToServer
@'Notification
(ClientMessageHandler m 'Notification)
-> Handlers m
Handlers forall a. Monoid a => a
mempty (forall {f :: MessageDirection} {t :: MessageKind} (a :: Method f t)
(v :: Method f t -> *).
SMethod @f @t a -> v a -> SMethodMap @f @t v
SMethodMap.singleton SMethod @'ClientToServer @'Notification m
m (forall (f :: * -> *) (t :: MessageKind)
(m :: Method 'ClientToServer t).
Handler @'ClientToServer @t f m -> ClientMessageHandler f t m
ClientMessageHandler Handler @'ClientToServer @'Notification f m
h))
requestHandler :: forall (m :: Method ClientToServer Request) f. SMethod m -> Handler f m -> Handlers f
requestHandler :: forall (m :: Method 'ClientToServer 'Request) (f :: * -> *).
SMethod @'ClientToServer @'Request m
-> Handler @'ClientToServer @'Request f m -> Handlers f
requestHandler SMethod @'ClientToServer @'Request m
m Handler @'ClientToServer @'Request f m
h = forall (m :: * -> *).
SMethodMap
@'ClientToServer @'Request (ClientMessageHandler m 'Request)
-> SMethodMap
@'ClientToServer
@'Notification
(ClientMessageHandler m 'Notification)
-> Handlers m
Handlers (forall {f :: MessageDirection} {t :: MessageKind} (a :: Method f t)
(v :: Method f t -> *).
SMethod @f @t a -> v a -> SMethodMap @f @t v
SMethodMap.singleton SMethod @'ClientToServer @'Request m
m (forall (f :: * -> *) (t :: MessageKind)
(m :: Method 'ClientToServer t).
Handler @'ClientToServer @t f m -> ClientMessageHandler f t m
ClientMessageHandler Handler @'ClientToServer @'Request f m
h)) forall a. Monoid a => a
mempty
newtype ClientMessageHandler f (t :: MessageKind) (m :: Method ClientToServer t) = ClientMessageHandler (Handler f m)
type family Handler (f :: Type -> Type) (m :: Method from t) = (result :: Type) | result -> f t m where
Handler f (m :: Method _from Request) = TRequestMessage m -> (Either ResponseError (MessageResult m) -> f ()) -> f ()
Handler f (m :: Method _from Notification) = TNotificationMessage m -> f ()
data m <~> n = Iso
{ forall {k} (m :: k -> *) (n :: k -> *).
(<~>) @k m n -> forall (a :: k). m a -> n a
forward :: forall a. m a -> n a
, forall {k} (m :: k -> *) (n :: k -> *).
(<~>) @k m n -> forall (a :: k). n a -> m a
backward :: forall a. n a -> m a
}
transmuteHandlers :: (m <~> n) -> Handlers m -> Handlers n
transmuteHandlers :: forall (m :: * -> *) (n :: * -> *).
(<~>) @(*) m n -> Handlers m -> Handlers n
transmuteHandlers (<~>) @(*) m n
nat = forall (m :: * -> *) (n :: * -> *).
(forall (a :: Method 'ClientToServer 'Request).
Handler @'ClientToServer @'Request m a
-> Handler @'ClientToServer @'Request n a)
-> (forall (a :: Method 'ClientToServer 'Notification).
Handler @'ClientToServer @'Notification m a
-> Handler @'ClientToServer @'Notification n a)
-> Handlers m
-> Handlers n
mapHandlers (\Handler @'ClientToServer @'Request m a
i TRequestMessage @'ClientToServer a
m Either ResponseError (MessageResult @'ClientToServer @'Request a)
-> n ()
k -> forall {k} (m :: k -> *) (n :: k -> *).
(<~>) @k m n -> forall (a :: k). m a -> n a
forward (<~>) @(*) m n
nat (Handler @'ClientToServer @'Request m a
i TRequestMessage @'ClientToServer a
m (forall {k} (m :: k -> *) (n :: k -> *).
(<~>) @k m n -> forall (a :: k). n a -> m a
backward (<~>) @(*) m n
nat forall b c a. (b -> c) -> (a -> b) -> a -> c
. Either ResponseError (MessageResult @'ClientToServer @'Request a)
-> n ()
k))) (\Handler @'ClientToServer @'Notification m a
i TNotificationMessage @'ClientToServer a
m -> forall {k} (m :: k -> *) (n :: k -> *).
(<~>) @k m n -> forall (a :: k). m a -> n a
forward (<~>) @(*) m n
nat (Handler @'ClientToServer @'Notification m a
i TNotificationMessage @'ClientToServer a
m))
mapHandlers ::
(forall (a :: Method ClientToServer Request). Handler m a -> Handler n a) ->
(forall (a :: Method ClientToServer Notification). Handler m a -> Handler n a) ->
Handlers m ->
Handlers n
mapHandlers :: forall (m :: * -> *) (n :: * -> *).
(forall (a :: Method 'ClientToServer 'Request).
Handler @'ClientToServer @'Request m a
-> Handler @'ClientToServer @'Request n a)
-> (forall (a :: Method 'ClientToServer 'Notification).
Handler @'ClientToServer @'Notification m a
-> Handler @'ClientToServer @'Notification n a)
-> Handlers m
-> Handlers n
mapHandlers forall (a :: Method 'ClientToServer 'Request).
Handler @'ClientToServer @'Request m a
-> Handler @'ClientToServer @'Request n a
mapReq forall (a :: Method 'ClientToServer 'Notification).
Handler @'ClientToServer @'Notification m a
-> Handler @'ClientToServer @'Notification n a
mapNot (Handlers SMethodMap
@'ClientToServer @'Request (ClientMessageHandler m 'Request)
reqs SMethodMap
@'ClientToServer
@'Notification
(ClientMessageHandler m 'Notification)
nots) = forall (m :: * -> *).
SMethodMap
@'ClientToServer @'Request (ClientMessageHandler m 'Request)
-> SMethodMap
@'ClientToServer
@'Notification
(ClientMessageHandler m 'Notification)
-> Handlers m
Handlers SMethodMap
@'ClientToServer @'Request (ClientMessageHandler n 'Request)
reqs' SMethodMap
@'ClientToServer
@'Notification
(ClientMessageHandler n 'Notification)
nots'
where
reqs' :: SMethodMap
@'ClientToServer @'Request (ClientMessageHandler n 'Request)
reqs' = forall {f :: MessageDirection} {t :: MessageKind}
(u :: Method f t -> *) (v :: Method f t -> *).
(forall (a :: Method f t). u a -> v a)
-> SMethodMap @f @t u -> SMethodMap @f @t v
SMethodMap.map (\(ClientMessageHandler Handler @'ClientToServer @'Request m a
i) -> forall (f :: * -> *) (t :: MessageKind)
(m :: Method 'ClientToServer t).
Handler @'ClientToServer @t f m -> ClientMessageHandler f t m
ClientMessageHandler forall a b. (a -> b) -> a -> b
$ forall (a :: Method 'ClientToServer 'Request).
Handler @'ClientToServer @'Request m a
-> Handler @'ClientToServer @'Request n a
mapReq Handler @'ClientToServer @'Request m a
i) SMethodMap
@'ClientToServer @'Request (ClientMessageHandler m 'Request)
reqs
nots' :: SMethodMap
@'ClientToServer
@'Notification
(ClientMessageHandler n 'Notification)
nots' = forall {f :: MessageDirection} {t :: MessageKind}
(u :: Method f t -> *) (v :: Method f t -> *).
(forall (a :: Method f t). u a -> v a)
-> SMethodMap @f @t u -> SMethodMap @f @t v
SMethodMap.map (\(ClientMessageHandler Handler @'ClientToServer @'Notification m a
i) -> forall (f :: * -> *) (t :: MessageKind)
(m :: Method 'ClientToServer t).
Handler @'ClientToServer @t f m -> ClientMessageHandler f t m
ClientMessageHandler forall a b. (a -> b) -> a -> b
$ forall (a :: Method 'ClientToServer 'Notification).
Handler @'ClientToServer @'Notification m a
-> Handler @'ClientToServer @'Notification n a
mapNot Handler @'ClientToServer @'Notification m a
i) SMethodMap
@'ClientToServer
@'Notification
(ClientMessageHandler m 'Notification)
nots
data LanguageContextState config = LanguageContextState
{ forall config. LanguageContextState config -> TVar VFSData
resVFS :: !(TVar VFSData)
, forall config. LanguageContextState config -> TVar DiagnosticStore
resDiagnostics :: !(TVar DiagnosticStore)
, forall config. LanguageContextState config -> TVar config
resConfig :: !(TVar config)
, forall config.
LanguageContextState config -> TVar [WorkspaceFolder]
resWorkspaceFolders :: !(TVar [WorkspaceFolder])
, forall config. LanguageContextState config -> ProgressData
resProgressData :: !ProgressData
, forall config. LanguageContextState config -> TVar ResponseMap
resPendingResponses :: !(TVar ResponseMap)
, forall config.
LanguageContextState config -> TVar (RegistrationMap 'Notification)
resRegistrationsNot :: !(TVar (RegistrationMap Notification))
, forall config.
LanguageContextState config -> TVar (RegistrationMap 'Request)
resRegistrationsReq :: !(TVar (RegistrationMap Request))
, forall config. LanguageContextState config -> TVar Int32
resLspId :: !(TVar Int32)
}
type ResponseMap = IxMap LspId (Product SMethod ServerResponseCallback)
type RegistrationMap (t :: MessageKind) = SMethodMap (Product RegistrationId (ClientMessageHandler IO t))
data RegistrationToken (m :: Method ClientToServer t) = RegistrationToken (SMethod m) (RegistrationId m)
newtype RegistrationId (m :: Method ClientToServer t) = RegistrationId Text
deriving (RegistrationId @t m -> RegistrationId @t m -> Bool
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
forall (t :: MessageKind) (m :: Method 'ClientToServer t).
RegistrationId @t m -> RegistrationId @t m -> Bool
/= :: RegistrationId @t m -> RegistrationId @t m -> Bool
$c/= :: forall (t :: MessageKind) (m :: Method 'ClientToServer t).
RegistrationId @t m -> RegistrationId @t m -> Bool
== :: RegistrationId @t m -> RegistrationId @t m -> Bool
$c== :: forall (t :: MessageKind) (m :: Method 'ClientToServer t).
RegistrationId @t m -> RegistrationId @t m -> Bool
Eq)
data ProgressData = ProgressData
{ ProgressData -> TVar Int32
progressNextId :: !(TVar Int32)
, ProgressData -> TVar (Map ProgressToken (IO ()))
progressCancel :: !(TVar (Map.Map ProgressToken (IO ())))
}
data VFSData = VFSData
{ VFSData -> VFS
vfsData :: !VFS
, VFSData -> Map String String
reverseMap :: !(Map.Map FilePath FilePath)
}
{-# INLINE modifyState #-}
modifyState :: MonadLsp config m => (LanguageContextState config -> TVar a) -> (a -> a) -> m ()
modifyState :: forall config (m :: * -> *) a.
MonadLsp config m =>
(LanguageContextState config -> TVar a) -> (a -> a) -> m ()
modifyState LanguageContextState config -> TVar a
sel a -> a
f = do
TVar a
tvarDat <- LanguageContextState config -> TVar a
sel forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall config.
LanguageContextEnv config -> LanguageContextState config
resState forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> forall config (m :: * -> *).
MonadLsp config m =>
m (LanguageContextEnv config)
getLspEnv
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO forall a b. (a -> b) -> a -> b
$ forall a. STM a -> IO a
atomically forall a b. (a -> b) -> a -> b
$ forall a. TVar a -> (a -> a) -> STM ()
modifyTVar' TVar a
tvarDat a -> a
f
{-# INLINE stateState #-}
stateState :: MonadLsp config m => (LanguageContextState config -> TVar s) -> (s -> (a, s)) -> m a
stateState :: forall config (m :: * -> *) s a.
MonadLsp config m =>
(LanguageContextState config -> TVar s) -> (s -> (a, s)) -> m a
stateState LanguageContextState config -> TVar s
sel s -> (a, s)
f = do
TVar s
tvarDat <- LanguageContextState config -> TVar s
sel forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall config.
LanguageContextEnv config -> LanguageContextState config
resState forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> forall config (m :: * -> *).
MonadLsp config m =>
m (LanguageContextEnv config)
getLspEnv
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO forall a b. (a -> b) -> a -> b
$ forall a. STM a -> IO a
atomically forall a b. (a -> b) -> a -> b
$ forall s a. TVar s -> (s -> (a, s)) -> STM a
stateTVar TVar s
tvarDat s -> (a, s)
f
{-# INLINE getsState #-}
getsState :: MonadLsp config m => (LanguageContextState config -> TVar a) -> m a
getsState :: forall config (m :: * -> *) a.
MonadLsp config m =>
(LanguageContextState config -> TVar a) -> m a
getsState LanguageContextState config -> TVar a
f = do
TVar a
tvarDat <- LanguageContextState config -> TVar a
f forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall config.
LanguageContextEnv config -> LanguageContextState config
resState forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> forall config (m :: * -> *).
MonadLsp config m =>
m (LanguageContextEnv config)
getLspEnv
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO forall a b. (a -> b) -> a -> b
$ forall a. TVar a -> IO a
readTVarIO TVar a
tvarDat
data Options = Options
{ Options -> Maybe TextDocumentSyncOptions
optTextDocumentSync :: Maybe L.TextDocumentSyncOptions
, Options -> Maybe String
optCompletionTriggerCharacters :: Maybe [Char]
, Options -> Maybe String
optCompletionAllCommitCharacters :: Maybe [Char]
, Options -> Maybe String
optSignatureHelpTriggerCharacters :: Maybe [Char]
, Options -> Maybe String
optSignatureHelpRetriggerCharacters :: Maybe [Char]
, Options -> Maybe [CodeActionKind]
optCodeActionKinds :: Maybe [CodeActionKind]
, Options -> Maybe (NonEmpty Char)
optDocumentOnTypeFormattingTriggerCharacters :: Maybe (NonEmpty Char)
, Options -> Maybe [Text]
optExecuteCommandCommands :: Maybe [Text]
, Options
-> Maybe
(Rec
((.+)
@(*) ((.==) @(*) "name" Text) ((.==) @(*) "version" (Maybe Text))))
optServerInfo :: Maybe (Rec ("name" .== Text .+ "version" .== Maybe Text))
}
instance Default Options where
def :: Options
def =
Maybe TextDocumentSyncOptions
-> Maybe String
-> Maybe String
-> Maybe String
-> Maybe String
-> Maybe [CodeActionKind]
-> Maybe (NonEmpty Char)
-> Maybe [Text]
-> Maybe
(Rec
((.+)
@(*) ((.==) @(*) "name" Text) ((.==) @(*) "version" (Maybe Text))))
-> Options
Options
forall a. Maybe a
Nothing
forall a. Maybe a
Nothing
forall a. Maybe a
Nothing
forall a. Maybe a
Nothing
forall a. Maybe a
Nothing
forall a. Maybe a
Nothing
forall a. Maybe a
Nothing
forall a. Maybe a
Nothing
forall a. Maybe a
Nothing
defaultOptions :: Options
defaultOptions :: Options
defaultOptions = forall a. Default a => a
def
data ProgressAmount = ProgressAmount (Maybe UInt) (Maybe Text)
data ProgressCancelledException = ProgressCancelledException
deriving (Int -> ProgressCancelledException -> ShowS
[ProgressCancelledException] -> ShowS
ProgressCancelledException -> String
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [ProgressCancelledException] -> ShowS
$cshowList :: [ProgressCancelledException] -> ShowS
show :: ProgressCancelledException -> String
$cshow :: ProgressCancelledException -> String
showsPrec :: Int -> ProgressCancelledException -> ShowS
$cshowsPrec :: Int -> ProgressCancelledException -> ShowS
Show)
instance E.Exception ProgressCancelledException
data ProgressCancellable = Cancellable | NotCancellable
data ServerDefinition config = forall m a.
ServerDefinition
{ forall config. ServerDefinition config -> config
defaultConfig :: config
, forall config. ServerDefinition config -> Text
configSection :: T.Text
, forall config.
ServerDefinition config -> config -> Value -> Either Text config
parseConfig :: config -> J.Value -> Either T.Text config
, ()
onConfigChange :: config -> m ()
, ()
doInitialize :: LanguageContextEnv config -> TMessage Method_Initialize -> IO (Either ResponseError a)
, ()
staticHandlers :: ClientCapabilities -> Handlers m
, ()
interpretHandler :: a -> (m <~> IO)
, forall config. ServerDefinition config -> Options
options :: Options
}
newtype ServerResponseCallback (m :: Method ServerToClient Request)
= ServerResponseCallback (Either ResponseError (MessageResult m) -> IO ())
addResponseHandler :: MonadLsp config f => LspId m -> (Product SMethod ServerResponseCallback) m -> f Bool
addResponseHandler :: forall config (f :: * -> *) (m :: Method 'ServerToClient 'Request).
MonadLsp config f =>
LspId @'ServerToClient m
-> Product
@(Method 'ServerToClient 'Request)
(SMethod @'ServerToClient @'Request)
ServerResponseCallback
m
-> f Bool
addResponseHandler LspId @'ServerToClient m
lid Product
@(Method 'ServerToClient 'Request)
(SMethod @'ServerToClient @'Request)
ServerResponseCallback
m
h = do
forall config (m :: * -> *) s a.
MonadLsp config m =>
(LanguageContextState config -> TVar s) -> (s -> (a, s)) -> m a
stateState forall config. LanguageContextState config -> TVar ResponseMap
resPendingResponses forall a b. (a -> b) -> a -> b
$ \ResponseMap
pending ->
case forall {a} (k :: a -> *) (m :: a) (f :: a -> *).
IxOrd @a k =>
k m -> f m -> IxMap @a k f -> Maybe (IxMap @a k f)
insertIxMap LspId @'ServerToClient m
lid Product
@(Method 'ServerToClient 'Request)
(SMethod @'ServerToClient @'Request)
ServerResponseCallback
m
h ResponseMap
pending of
Just !ResponseMap
m -> (Bool
True, ResponseMap
m)
Maybe ResponseMap
Nothing -> (Bool
False, ResponseMap
pending)
sendNotification ::
forall (m :: Method ServerToClient Notification) f config.
MonadLsp config f =>
SServerMethod m ->
MessageParams m ->
f ()
sendNotification :: forall (m :: Method 'ServerToClient 'Notification) (f :: * -> *)
config.
MonadLsp config f =>
SServerMethod @'Notification m
-> MessageParams @'ServerToClient @'Notification m -> f ()
sendNotification SServerMethod @'Notification m
m MessageParams @'ServerToClient @'Notification m
params =
let msg :: TNotificationMessage @'ServerToClient m
msg = forall (f :: MessageDirection) (m :: Method f 'Notification).
Text
-> SMethod @f @'Notification m
-> MessageParams @f @'Notification m
-> TNotificationMessage @f m
TNotificationMessage Text
"2.0" SServerMethod @'Notification m
m MessageParams @'ServerToClient @'Notification m
params
in case forall {t :: MessageKind} (m :: Method 'ServerToClient t).
SServerMethod @t m -> ServerNotOrReq @t m
splitServerMethod SServerMethod @'Notification m
m of
ServerNotOrReq @'Notification m
IsServerNot -> forall config (m :: * -> *).
MonadLsp config m =>
FromServerMessage -> m ()
sendToClient forall a b. (a -> b) -> a -> b
$ forall (m :: Method 'ServerToClient 'Notification).
((TMessage @'ServerToClient @'Notification m :: *)
~ (TNotificationMessage @'ServerToClient m :: *)) =>
TNotificationMessage @'ServerToClient m -> FromServerMessage
fromServerNot TNotificationMessage @'ServerToClient m
msg
ServerNotOrReq @'Notification m
IsServerEither -> forall config (m :: * -> *).
MonadLsp config m =>
FromServerMessage -> m ()
sendToClient forall a b. (a -> b) -> a -> b
$ forall (t :: MessageKind) (m :: Method 'ServerToClient t)
(a :: Method 'ClientToServer 'Request -> *).
SMethod @'ServerToClient @t m
-> TMessage @'ServerToClient @t m -> FromServerMessage' a
FromServerMess SServerMethod @'Notification m
m forall a b. (a -> b) -> a -> b
$ forall (s :: Symbol) (f :: MessageDirection).
TNotificationMessage @f ('Method_CustomMethod @f @'Notification s)
-> TCustomMessage s f 'Notification
NotMess TNotificationMessage @'ServerToClient m
msg
sendRequest ::
forall (m :: Method ServerToClient Request) f config.
MonadLsp config f =>
SServerMethod m ->
MessageParams m ->
(Either ResponseError (MessageResult m) -> f ()) ->
f (LspId m)
sendRequest :: forall (m :: Method 'ServerToClient 'Request) (f :: * -> *) config.
MonadLsp config f =>
SServerMethod @'Request m
-> MessageParams @'ServerToClient @'Request m
-> (Either
ResponseError (MessageResult @'ServerToClient @'Request m)
-> f ())
-> f (LspId @'ServerToClient m)
sendRequest SServerMethod @'Request m
m MessageParams @'ServerToClient @'Request m
params Either ResponseError (MessageResult @'ServerToClient @'Request m)
-> f ()
resHandler = do
LspId @'ServerToClient m
reqId <- forall (f :: MessageDirection) (m :: Method f 'Request).
Int32 -> LspId @f m
IdInt forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> forall config (m :: * -> *). MonadLsp config m => m Int32
freshLspId
f () -> IO ()
rio <- forall (m :: * -> *) a. MonadUnliftIO m => m (m a -> IO a)
askRunInIO
Bool
success <- forall config (f :: * -> *) (m :: Method 'ServerToClient 'Request).
MonadLsp config f =>
LspId @'ServerToClient m
-> Product
@(Method 'ServerToClient 'Request)
(SMethod @'ServerToClient @'Request)
ServerResponseCallback
m
-> f Bool
addResponseHandler LspId @'ServerToClient m
reqId (forall {k} (f :: k -> *) (g :: k -> *) (a :: k).
f a -> g a -> Product @k f g a
Pair SServerMethod @'Request m
m (forall (m :: Method 'ServerToClient 'Request).
(Either ResponseError (MessageResult @'ServerToClient @'Request m)
-> IO ())
-> ServerResponseCallback m
ServerResponseCallback (f () -> IO ()
rio forall b c a. (b -> c) -> (a -> b) -> a -> c
. Either ResponseError (MessageResult @'ServerToClient @'Request m)
-> f ()
resHandler)))
forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
unless Bool
success forall a b. (a -> b) -> a -> b
$ forall a. HasCallStack => String -> a
error String
"LSP: could not send FromServer request as id is reused"
let msg :: TRequestMessage @'ServerToClient m
msg = forall (f :: MessageDirection) (m :: Method f 'Request).
Text
-> LspId @f m
-> SMethod @f @'Request m
-> MessageParams @f @'Request m
-> TRequestMessage @f m
TRequestMessage Text
"2.0" LspId @'ServerToClient m
reqId SServerMethod @'Request m
m MessageParams @'ServerToClient @'Request m
params
~() <- case forall {t :: MessageKind} (m :: Method 'ServerToClient t).
SServerMethod @t m -> ServerNotOrReq @t m
splitServerMethod SServerMethod @'Request m
m of
ServerNotOrReq @'Request m
IsServerReq -> forall config (m :: * -> *).
MonadLsp config m =>
FromServerMessage -> m ()
sendToClient forall a b. (a -> b) -> a -> b
$ forall (m :: Method 'ServerToClient 'Request).
((TMessage @'ServerToClient @'Request m :: *)
~ (TRequestMessage @'ServerToClient m :: *)) =>
TRequestMessage @'ServerToClient m -> FromServerMessage
fromServerReq TRequestMessage @'ServerToClient m
msg
ServerNotOrReq @'Request m
IsServerEither -> forall config (m :: * -> *).
MonadLsp config m =>
FromServerMessage -> m ()
sendToClient forall a b. (a -> b) -> a -> b
$ forall (t :: MessageKind) (m :: Method 'ServerToClient t)
(a :: Method 'ClientToServer 'Request -> *).
SMethod @'ServerToClient @t m
-> TMessage @'ServerToClient @t m -> FromServerMessage' a
FromServerMess SServerMethod @'Request m
m forall a b. (a -> b) -> a -> b
$ forall (s :: Symbol) (f :: MessageDirection).
TRequestMessage @f ('Method_CustomMethod @f @'Request s)
-> TCustomMessage s f 'Request
ReqMess TRequestMessage @'ServerToClient m
msg
forall (m :: * -> *) a. Monad m => a -> m a
return LspId @'ServerToClient m
reqId
getVirtualFile :: MonadLsp config m => NormalizedUri -> m (Maybe VirtualFile)
getVirtualFile :: forall config (m :: * -> *).
MonadLsp config m =>
NormalizedUri -> m (Maybe VirtualFile)
getVirtualFile NormalizedUri
uri = do
VFS
dat <- VFSData -> VFS
vfsData forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> forall config (m :: * -> *) a.
MonadLsp config m =>
(LanguageContextState config -> TVar a) -> m a
getsState forall config. LanguageContextState config -> TVar VFSData
resVFS
forall (f :: * -> *) a. Applicative f => a -> f a
pure forall a b. (a -> b) -> a -> b
$ VFS
dat forall s a. s -> Getting a s a -> a
^. forall s a. HasVfsMap s a => Lens' s a
vfsMap forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall m. At m => Index m -> Lens' m (Maybe (IxValue m))
at NormalizedUri
uri
{-# INLINE getVirtualFile #-}
getVirtualFiles :: MonadLsp config m => m VFS
getVirtualFiles :: forall config (m :: * -> *). MonadLsp config m => m VFS
getVirtualFiles = VFSData -> VFS
vfsData forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> forall config (m :: * -> *) a.
MonadLsp config m =>
(LanguageContextState config -> TVar a) -> m a
getsState forall config. LanguageContextState config -> TVar VFSData
resVFS
{-# INLINE getVirtualFiles #-}
snapshotVirtualFiles :: LanguageContextEnv c -> STM VFS
snapshotVirtualFiles :: forall c. LanguageContextEnv c -> STM VFS
snapshotVirtualFiles LanguageContextEnv c
env = VFSData -> VFS
vfsData forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> forall a. TVar a -> STM a
readTVar (forall config. LanguageContextState config -> TVar VFSData
resVFS forall a b. (a -> b) -> a -> b
$ forall config.
LanguageContextEnv config -> LanguageContextState config
resState LanguageContextEnv c
env)
{-# INLINE snapshotVirtualFiles #-}
persistVirtualFile :: MonadLsp config m => LogAction m (WithSeverity VfsLog) -> FilePath -> NormalizedUri -> m (Maybe FilePath)
persistVirtualFile :: forall config (m :: * -> *).
MonadLsp config m =>
LogAction m (WithSeverity VfsLog)
-> String -> NormalizedUri -> m (Maybe String)
persistVirtualFile LogAction m (WithSeverity VfsLog)
logger String
dir NormalizedUri
uri = do
forall (m :: * -> *) a. Monad m => m (m a) -> m a
join forall a b. (a -> b) -> a -> b
$ forall config (m :: * -> *) s a.
MonadLsp config m =>
(LanguageContextState config -> TVar s) -> (s -> (a, s)) -> m a
stateState forall config. LanguageContextState config -> TVar VFSData
resVFS forall a b. (a -> b) -> a -> b
$ \VFSData
vfs ->
case forall (m :: * -> *).
MonadIO m =>
LogAction m (WithSeverity VfsLog)
-> String -> VFS -> NormalizedUri -> Maybe (String, m ())
persistFileVFS LogAction m (WithSeverity VfsLog)
logger String
dir (VFSData -> VFS
vfsData VFSData
vfs) NormalizedUri
uri of
Maybe (String, m ())
Nothing -> (forall (m :: * -> *) a. Monad m => a -> m a
return forall a. Maybe a
Nothing, VFSData
vfs)
Just (String
fn, m ()
write) ->
let !revMap :: Map String String
revMap = case Uri -> Maybe String
uriToFilePath (NormalizedUri -> Uri
fromNormalizedUri NormalizedUri
uri) of
Just String
uri_fp -> forall k a. Ord k => k -> a -> Map k a -> Map k a
Map.insert String
fn String
uri_fp forall a b. (a -> b) -> a -> b
$ VFSData -> Map String String
reverseMap VFSData
vfs
Maybe String
Nothing -> VFSData -> Map String String
reverseMap VFSData
vfs
!vfs' :: VFSData
vfs' = VFSData
vfs{reverseMap :: Map String String
reverseMap = Map String String
revMap}
act :: m (Maybe String)
act = do
m ()
write
forall (f :: * -> *) a. Applicative f => a -> f a
pure (forall a. a -> Maybe a
Just String
fn)
in (m (Maybe String)
act, VFSData
vfs')
getVersionedTextDoc :: MonadLsp config m => TextDocumentIdentifier -> m VersionedTextDocumentIdentifier
getVersionedTextDoc :: forall config (m :: * -> *).
MonadLsp config m =>
TextDocumentIdentifier -> m VersionedTextDocumentIdentifier
getVersionedTextDoc TextDocumentIdentifier
doc = do
let uri :: Uri
uri = TextDocumentIdentifier
doc forall s a. s -> Getting a s a -> a
^. forall s a. HasUri s a => Lens' s a
L.uri
Maybe VirtualFile
mvf <- forall config (m :: * -> *).
MonadLsp config m =>
NormalizedUri -> m (Maybe VirtualFile)
getVirtualFile (Uri -> NormalizedUri
toNormalizedUri Uri
uri)
let ver :: Int32
ver = case Maybe VirtualFile
mvf of
Just (VirtualFile Int32
lspver Int
_ Rope
_) -> Int32
lspver
Maybe VirtualFile
Nothing -> Int32
0
forall (m :: * -> *) a. Monad m => a -> m a
return (Uri -> Int32 -> VersionedTextDocumentIdentifier
VersionedTextDocumentIdentifier Uri
uri Int32
ver)
{-# INLINE getVersionedTextDoc #-}
reverseFileMap :: MonadLsp config m => m (FilePath -> FilePath)
reverseFileMap :: forall config (m :: * -> *). MonadLsp config m => m ShowS
reverseFileMap = do
VFSData
vfs <- forall config (m :: * -> *) a.
MonadLsp config m =>
(LanguageContextState config -> TVar a) -> m a
getsState forall config. LanguageContextState config -> TVar VFSData
resVFS
let f :: ShowS
f String
fp = forall a. a -> Maybe a -> a
fromMaybe String
fp forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall k a. Ord k => k -> Map k a -> Maybe a
Map.lookup String
fp forall b c a. (b -> c) -> (a -> b) -> a -> c
. VFSData -> Map String String
reverseMap forall a b. (a -> b) -> a -> b
$ VFSData
vfs
forall (m :: * -> *) a. Monad m => a -> m a
return ShowS
f
{-# INLINE reverseFileMap #-}
sendToClient :: MonadLsp config m => FromServerMessage -> m ()
sendToClient :: forall config (m :: * -> *).
MonadLsp config m =>
FromServerMessage -> m ()
sendToClient FromServerMessage
msg = do
FromServerMessage -> IO ()
f <- forall config.
LanguageContextEnv config -> FromServerMessage -> IO ()
resSendMessage forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> forall config (m :: * -> *).
MonadLsp config m =>
m (LanguageContextEnv config)
getLspEnv
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO forall a b. (a -> b) -> a -> b
$ FromServerMessage -> IO ()
f FromServerMessage
msg
{-# INLINE sendToClient #-}
freshLspId :: MonadLsp config m => m Int32
freshLspId :: forall config (m :: * -> *). MonadLsp config m => m Int32
freshLspId = do
forall config (m :: * -> *) s a.
MonadLsp config m =>
(LanguageContextState config -> TVar s) -> (s -> (a, s)) -> m a
stateState forall config. LanguageContextState config -> TVar Int32
resLspId forall a b. (a -> b) -> a -> b
$ \Int32
cur ->
let !next :: Int32
next = Int32
cur forall a. Num a => a -> a -> a
+ Int32
1 in (Int32
cur, Int32
next)
{-# INLINE freshLspId #-}
getConfig :: MonadLsp config m => m config
getConfig :: forall config (m :: * -> *). MonadLsp config m => m config
getConfig = forall config (m :: * -> *) a.
MonadLsp config m =>
(LanguageContextState config -> TVar a) -> m a
getsState forall config. LanguageContextState config -> TVar config
resConfig
{-# INLINE getConfig #-}
setConfig :: MonadLsp config m => config -> m ()
setConfig :: forall config (m :: * -> *). MonadLsp config m => config -> m ()
setConfig config
config = forall config (m :: * -> *) s a.
MonadLsp config m =>
(LanguageContextState config -> TVar s) -> (s -> (a, s)) -> m a
stateState forall config. LanguageContextState config -> TVar config
resConfig (forall a b. a -> b -> a
const ((), config
config))
{-# INLINE setConfig #-}
getClientCapabilities :: MonadLsp config m => m L.ClientCapabilities
getClientCapabilities :: forall config (m :: * -> *).
MonadLsp config m =>
m ClientCapabilities
getClientCapabilities = forall config. LanguageContextEnv config -> ClientCapabilities
resClientCapabilities forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> forall config (m :: * -> *).
MonadLsp config m =>
m (LanguageContextEnv config)
getLspEnv
{-# INLINE getClientCapabilities #-}
getRootPath :: MonadLsp config m => m (Maybe FilePath)
getRootPath :: forall config (m :: * -> *). MonadLsp config m => m (Maybe String)
getRootPath = forall config. LanguageContextEnv config -> Maybe String
resRootPath forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> forall config (m :: * -> *).
MonadLsp config m =>
m (LanguageContextEnv config)
getLspEnv
{-# INLINE getRootPath #-}
getWorkspaceFolders :: MonadLsp config m => m (Maybe [WorkspaceFolder])
getWorkspaceFolders :: forall config (m :: * -> *).
MonadLsp config m =>
m (Maybe [WorkspaceFolder])
getWorkspaceFolders = do
ClientCapabilities
clientCaps <- forall config (m :: * -> *).
MonadLsp config m =>
m ClientCapabilities
getClientCapabilities
let clientSupportsWfs :: Bool
clientSupportsWfs = forall a. a -> Maybe a -> a
fromMaybe Bool
False forall a b. (a -> b) -> a -> b
$ ClientCapabilities
clientCaps forall s a. s -> Getting (First a) s a -> Maybe a
^? forall s a. HasWorkspace s a => Lens' s a
L.workspace forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a b. Prism (Maybe a) (Maybe b) a b
_Just forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall s a. HasWorkspaceFolders s a => Lens' s a
L.workspaceFolders forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a b. Prism (Maybe a) (Maybe b) a b
_Just
if Bool
clientSupportsWfs
then forall a. a -> Maybe a
Just forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> forall config (m :: * -> *) a.
MonadLsp config m =>
(LanguageContextState config -> TVar a) -> m a
getsState forall config.
LanguageContextState config -> TVar [WorkspaceFolder]
resWorkspaceFolders
else forall (f :: * -> *) a. Applicative f => a -> f a
pure forall a. Maybe a
Nothing
{-# INLINE getWorkspaceFolders #-}
registerCapability ::
forall f t (m :: Method ClientToServer t) config.
MonadLsp config f =>
SClientMethod m ->
RegistrationOptions m ->
Handler f m ->
f (Maybe (RegistrationToken m))
registerCapability :: forall (f :: * -> *) (t :: MessageKind)
(m :: Method 'ClientToServer t) config.
MonadLsp config f =>
SClientMethod @t m
-> RegistrationOptions @'ClientToServer @t m
-> Handler @'ClientToServer @t f m
-> f (Maybe (RegistrationToken @t m))
registerCapability SClientMethod @t m
method RegistrationOptions @'ClientToServer @t m
regOpts Handler @'ClientToServer @t f m
f = do
ClientCapabilities
clientCaps <- forall config. LanguageContextEnv config -> ClientCapabilities
resClientCapabilities forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> forall config (m :: * -> *).
MonadLsp config m =>
m (LanguageContextEnv config)
getLspEnv
Handlers IO
handlers <- forall config. LanguageContextEnv config -> Handlers IO
resHandlers forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> forall config (m :: * -> *).
MonadLsp config m =>
m (LanguageContextEnv config)
getLspEnv
let alreadyStaticallyRegistered :: Bool
alreadyStaticallyRegistered = case forall {t :: MessageKind} (m :: Method 'ClientToServer t).
SClientMethod @t m -> ClientNotOrReq @t m
splitClientMethod SClientMethod @t m
method of
ClientNotOrReq @t m
IsClientNot -> forall {f1 :: MessageDirection} {t1 :: MessageKind}
{f2 :: MessageDirection} {t2 :: MessageKind} (a :: Method f1 t1)
(v :: Method f2 t2 -> *).
SMethod @f1 @t1 a -> SMethodMap @f2 @t2 v -> Bool
SMethodMap.member SClientMethod @t m
method forall a b. (a -> b) -> a -> b
$ forall (m :: * -> *).
Handlers m
-> SMethodMap
@'ClientToServer
@'Notification
(ClientMessageHandler m 'Notification)
notHandlers Handlers IO
handlers
ClientNotOrReq @t m
IsClientReq -> forall {f1 :: MessageDirection} {t1 :: MessageKind}
{f2 :: MessageDirection} {t2 :: MessageKind} (a :: Method f1 t1)
(v :: Method f2 t2 -> *).
SMethod @f1 @t1 a -> SMethodMap @f2 @t2 v -> Bool
SMethodMap.member SClientMethod @t m
method forall a b. (a -> b) -> a -> b
$ forall (m :: * -> *).
Handlers m
-> SMethodMap
@'ClientToServer @'Request (ClientMessageHandler m 'Request)
reqHandlers Handlers IO
handlers
ClientNotOrReq @t m
IsClientEither -> forall a. HasCallStack => String -> a
error String
"Cannot register capability for custom methods"
ClientCapabilities -> Bool -> f (Maybe (RegistrationToken @t m))
go ClientCapabilities
clientCaps Bool
alreadyStaticallyRegistered
where
go :: ClientCapabilities -> Bool -> f (Maybe (RegistrationToken @t m))
go ClientCapabilities
_clientCaps Bool
True = forall (f :: * -> *) a. Applicative f => a -> f a
pure forall a. Maybe a
Nothing
go ClientCapabilities
clientCaps Bool
False
| forall {f :: MessageDirection} {t :: MessageKind}
(m :: Method f t).
SMethod @f @t m -> ClientCapabilities -> Bool
dynamicRegistrationSupported SClientMethod @t m
method ClientCapabilities
clientCaps = do
Text
uuid <- forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO forall a b. (a -> b) -> a -> b
$ UUID -> Text
UUID.toText forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> forall (m :: * -> *) a. MonadIO m => (StdGen -> (a, StdGen)) -> m a
getStdRandom forall a g. (Random a, RandomGen g) => g -> (a, g)
random
let registration :: TRegistration @t m
registration = forall (t :: MessageKind) (m :: Method 'ClientToServer t).
Text
-> SClientMethod @t m
-> Maybe (RegistrationOptions @'ClientToServer @t m)
-> TRegistration @t m
L.TRegistration Text
uuid SClientMethod @t m
method (forall a. a -> Maybe a
Just RegistrationOptions @'ClientToServer @t m
regOpts)
params :: RegistrationParams
params = [Registration] -> RegistrationParams
L.RegistrationParams [forall {t :: MessageKind} (m :: Method 'ClientToServer t).
TRegistration @t m -> Registration
toUntypedRegistration TRegistration @t m
registration]
regId :: RegistrationId @t m
regId = forall (t :: MessageKind) (m :: Method 'ClientToServer t).
Text -> RegistrationId @t m
RegistrationId Text
uuid
UnliftIO f
rio <- forall (m :: * -> *). MonadUnliftIO m => m (UnliftIO m)
askUnliftIO
~() <- case forall {t :: MessageKind} (m :: Method 'ClientToServer t).
SClientMethod @t m -> ClientNotOrReq @t m
splitClientMethod SClientMethod @t m
method of
ClientNotOrReq @t m
IsClientNot -> forall config (m :: * -> *) a.
MonadLsp config m =>
(LanguageContextState config -> TVar a) -> (a -> a) -> m ()
modifyState forall config.
LanguageContextState config -> TVar (RegistrationMap 'Notification)
resRegistrationsNot forall a b. (a -> b) -> a -> b
$ \RegistrationMap 'Notification
oldRegs ->
let pair :: Product
@(Method 'ClientToServer t)
(RegistrationId @t)
(ClientMessageHandler IO t)
m
pair = forall {k} (f :: k -> *) (g :: k -> *) (a :: k).
f a -> g a -> Product @k f g a
Pair RegistrationId @t m
regId (forall (f :: * -> *) (t :: MessageKind)
(m :: Method 'ClientToServer t).
Handler @'ClientToServer @t f m -> ClientMessageHandler f t m
ClientMessageHandler (forall (m :: * -> *). UnliftIO m -> forall a. m a -> IO a
unliftIO UnliftIO f
rio forall b c a. (b -> c) -> (a -> b) -> a -> c
. Handler @'ClientToServer @t f m
f))
in forall {f :: MessageDirection} {t :: MessageKind} (a :: Method f t)
(v :: Method f t -> *).
SMethod @f @t a -> v a -> SMethodMap @f @t v -> SMethodMap @f @t v
SMethodMap.insert SClientMethod @t m
method Product
@(Method 'ClientToServer t)
(RegistrationId @t)
(ClientMessageHandler IO t)
m
pair RegistrationMap 'Notification
oldRegs
ClientNotOrReq @t m
IsClientReq -> forall config (m :: * -> *) a.
MonadLsp config m =>
(LanguageContextState config -> TVar a) -> (a -> a) -> m ()
modifyState forall config.
LanguageContextState config -> TVar (RegistrationMap 'Request)
resRegistrationsReq forall a b. (a -> b) -> a -> b
$ \RegistrationMap 'Request
oldRegs ->
let pair :: Product
@(Method 'ClientToServer t)
(RegistrationId @t)
(ClientMessageHandler IO t)
m
pair = forall {k} (f :: k -> *) (g :: k -> *) (a :: k).
f a -> g a -> Product @k f g a
Pair RegistrationId @t m
regId (forall (f :: * -> *) (t :: MessageKind)
(m :: Method 'ClientToServer t).
Handler @'ClientToServer @t f m -> ClientMessageHandler f t m
ClientMessageHandler (\TRequestMessage @'ClientToServer m
msg Either ResponseError (MessageResult @'ClientToServer @'Request m)
-> IO ()
k -> forall (m :: * -> *). UnliftIO m -> forall a. m a -> IO a
unliftIO UnliftIO f
rio forall a b. (a -> b) -> a -> b
$ Handler @'ClientToServer @t f m
f TRequestMessage @'ClientToServer m
msg (forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO forall b c a. (b -> c) -> (a -> b) -> a -> c
. Either ResponseError (MessageResult @'ClientToServer @'Request m)
-> IO ()
k)))
in forall {f :: MessageDirection} {t :: MessageKind} (a :: Method f t)
(v :: Method f t -> *).
SMethod @f @t a -> v a -> SMethodMap @f @t v -> SMethodMap @f @t v
SMethodMap.insert SClientMethod @t m
method Product
@(Method 'ClientToServer t)
(RegistrationId @t)
(ClientMessageHandler IO t)
m
pair RegistrationMap 'Request
oldRegs
ClientNotOrReq @t m
IsClientEither -> forall a. HasCallStack => String -> a
error String
"Cannot register capability for custom methods"
LspId @'ServerToClient 'Method_ClientRegisterCapability
_ <- forall (m :: Method 'ServerToClient 'Request) (f :: * -> *) config.
MonadLsp config f =>
SServerMethod @'Request m
-> MessageParams @'ServerToClient @'Request m
-> (Either
ResponseError (MessageResult @'ServerToClient @'Request m)
-> f ())
-> f (LspId @'ServerToClient m)
sendRequest SMethod @'ServerToClient @'Request 'Method_ClientRegisterCapability
SMethod_ClientRegisterCapability RegistrationParams
params forall a b. (a -> b) -> a -> b
$ \Either
ResponseError
(MessageResult
@'ServerToClient @'Request 'Method_ClientRegisterCapability)
_res -> forall (f :: * -> *) a. Applicative f => a -> f a
pure ()
forall (f :: * -> *) a. Applicative f => a -> f a
pure (forall a. a -> Maybe a
Just (forall (t :: MessageKind) (m :: Method 'ClientToServer t).
SMethod @'ClientToServer @t m
-> RegistrationId @t m -> RegistrationToken @t m
RegistrationToken SClientMethod @t m
method RegistrationId @t m
regId))
| Bool
otherwise = forall (f :: * -> *) a. Applicative f => a -> f a
pure forall a. Maybe a
Nothing
unregisterCapability :: MonadLsp config f => RegistrationToken m -> f ()
unregisterCapability :: forall {t :: MessageKind} config (f :: * -> *)
(m :: Method 'ClientToServer t).
MonadLsp config f =>
RegistrationToken @t m -> f ()
unregisterCapability (RegistrationToken SMethod @'ClientToServer @t m
m (RegistrationId Text
uuid)) = do
~() <- case forall {t :: MessageKind} (m :: Method 'ClientToServer t).
SClientMethod @t m -> ClientNotOrReq @t m
splitClientMethod SMethod @'ClientToServer @t m
m of
ClientNotOrReq @t m
IsClientReq -> forall config (m :: * -> *) a.
MonadLsp config m =>
(LanguageContextState config -> TVar a) -> (a -> a) -> m ()
modifyState forall config.
LanguageContextState config -> TVar (RegistrationMap 'Request)
resRegistrationsReq forall a b. (a -> b) -> a -> b
$ forall {f1 :: MessageDirection} {t1 :: MessageKind}
{f2 :: MessageDirection} {t2 :: MessageKind} (a :: Method f1 t1)
(v :: Method f2 t2 -> *).
SMethod @f1 @t1 a -> SMethodMap @f2 @t2 v -> SMethodMap @f2 @t2 v
SMethodMap.delete SMethod @'ClientToServer @t m
m
ClientNotOrReq @t m
IsClientNot -> forall config (m :: * -> *) a.
MonadLsp config m =>
(LanguageContextState config -> TVar a) -> (a -> a) -> m ()
modifyState forall config.
LanguageContextState config -> TVar (RegistrationMap 'Notification)
resRegistrationsNot forall a b. (a -> b) -> a -> b
$ forall {f1 :: MessageDirection} {t1 :: MessageKind}
{f2 :: MessageDirection} {t2 :: MessageKind} (a :: Method f1 t1)
(v :: Method f2 t2 -> *).
SMethod @f1 @t1 a -> SMethodMap @f2 @t2 v -> SMethodMap @f2 @t2 v
SMethodMap.delete SMethod @'ClientToServer @t m
m
ClientNotOrReq @t m
IsClientEither -> forall a. HasCallStack => String -> a
error String
"Cannot unregister capability for custom methods"
let unregistration :: TUnregistration @t m
unregistration = forall (t :: MessageKind) (m :: Method 'ClientToServer t).
Text -> SMethod @'ClientToServer @t m -> TUnregistration @t m
L.TUnregistration Text
uuid SMethod @'ClientToServer @t m
m
params :: UnregistrationParams
params = [Unregistration] -> UnregistrationParams
L.UnregistrationParams [forall {t :: MessageKind} (m :: Method 'ClientToServer t).
TUnregistration @t m -> Unregistration
toUntypedUnregistration TUnregistration @t m
unregistration]
forall (f :: * -> *) a. Functor f => f a -> f ()
void forall a b. (a -> b) -> a -> b
$ forall (m :: Method 'ServerToClient 'Request) (f :: * -> *) config.
MonadLsp config f =>
SServerMethod @'Request m
-> MessageParams @'ServerToClient @'Request m
-> (Either
ResponseError (MessageResult @'ServerToClient @'Request m)
-> f ())
-> f (LspId @'ServerToClient m)
sendRequest SMethod
@'ServerToClient @'Request 'Method_ClientUnregisterCapability
SMethod_ClientUnregisterCapability UnregistrationParams
params forall a b. (a -> b) -> a -> b
$ \Either
ResponseError
(MessageResult
@'ServerToClient @'Request 'Method_ClientUnregisterCapability)
_res -> forall (f :: * -> *) a. Applicative f => a -> f a
pure ()
storeProgress :: MonadLsp config m => ProgressToken -> Async a -> m ()
storeProgress :: forall config (m :: * -> *) a.
MonadLsp config m =>
ProgressToken -> Async a -> m ()
storeProgress ProgressToken
n Async a
a = forall config (m :: * -> *) a.
MonadLsp config m =>
(LanguageContextState config -> TVar a) -> (a -> a) -> m ()
modifyState (ProgressData -> TVar (Map ProgressToken (IO ()))
progressCancel forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall config. LanguageContextState config -> ProgressData
resProgressData) forall a b. (a -> b) -> a -> b
$ forall k a. Ord k => k -> a -> Map k a -> Map k a
Map.insert ProgressToken
n (forall e a. Exception e => Async a -> e -> IO ()
cancelWith Async a
a ProgressCancelledException
ProgressCancelledException)
{-# INLINE storeProgress #-}
deleteProgress :: MonadLsp config m => ProgressToken -> m ()
deleteProgress :: forall config (m :: * -> *).
MonadLsp config m =>
ProgressToken -> m ()
deleteProgress ProgressToken
n = forall config (m :: * -> *) a.
MonadLsp config m =>
(LanguageContextState config -> TVar a) -> (a -> a) -> m ()
modifyState (ProgressData -> TVar (Map ProgressToken (IO ()))
progressCancel forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall config. LanguageContextState config -> ProgressData
resProgressData) forall a b. (a -> b) -> a -> b
$ forall k a. Ord k => k -> Map k a -> Map k a
Map.delete ProgressToken
n
{-# INLINE deleteProgress #-}
getNewProgressId :: MonadLsp config m => m ProgressToken
getNewProgressId :: forall config (m :: * -> *). MonadLsp config m => m ProgressToken
getNewProgressId = do
forall config (m :: * -> *) s a.
MonadLsp config m =>
(LanguageContextState config -> TVar s) -> (s -> (a, s)) -> m a
stateState (ProgressData -> TVar Int32
progressNextId forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall config. LanguageContextState config -> ProgressData
resProgressData) forall a b. (a -> b) -> a -> b
$ \Int32
cur ->
let !next :: Int32
next = Int32
cur forall a. Num a => a -> a -> a
+ Int32
1
in ((Int32 |? Text) -> ProgressToken
L.ProgressToken forall a b. (a -> b) -> a -> b
$ forall a b. a -> a |? b
L.InL Int32
cur, Int32
next)
{-# INLINE getNewProgressId #-}
withProgressBase :: MonadLsp c m => Bool -> Text -> ProgressCancellable -> ((ProgressAmount -> m ()) -> m a) -> m a
withProgressBase :: forall c (m :: * -> *) a.
MonadLsp c m =>
Bool
-> Text
-> ProgressCancellable
-> ((ProgressAmount -> m ()) -> m a)
-> m a
withProgressBase Bool
indefinite Text
title ProgressCancellable
cancellable (ProgressAmount -> m ()) -> m a
f = do
ProgressToken
progId <- forall config (m :: * -> *). MonadLsp config m => m ProgressToken
getNewProgressId
let initialPercentage :: Maybe UInt
initialPercentage
| Bool
indefinite = forall a. Maybe a
Nothing
| Bool
otherwise = forall a. a -> Maybe a
Just UInt
0
cancellable' :: Bool
cancellable' = case ProgressCancellable
cancellable of
ProgressCancellable
Cancellable -> Bool
True
ProgressCancellable
NotCancellable -> Bool
False
LspId @'ServerToClient 'Method_WindowWorkDoneProgressCreate
_ <- forall (m :: Method 'ServerToClient 'Request) (f :: * -> *) config.
MonadLsp config f =>
SServerMethod @'Request m
-> MessageParams @'ServerToClient @'Request m
-> (Either
ResponseError (MessageResult @'ServerToClient @'Request m)
-> f ())
-> f (LspId @'ServerToClient m)
sendRequest
SMethod
@'ServerToClient @'Request 'Method_WindowWorkDoneProgressCreate
SMethod_WindowWorkDoneProgressCreate
(ProgressToken -> WorkDoneProgressCreateParams
WorkDoneProgressCreateParams ProgressToken
progId)
forall a b. (a -> b) -> a -> b
$ \Either
ResponseError
(MessageResult
@'ServerToClient @'Request 'Method_WindowWorkDoneProgressCreate)
res -> do
case Either
ResponseError
(MessageResult
@'ServerToClient @'Request 'Method_WindowWorkDoneProgressCreate)
res of
Left ResponseError
_err -> forall (f :: * -> *) a. Applicative f => a -> f a
pure ()
Right MessageResult
@'ServerToClient @'Request 'Method_WindowWorkDoneProgressCreate
_ -> forall (f :: * -> *) a. Applicative f => a -> f a
pure ()
a
res <- forall (m :: * -> *) b.
MonadUnliftIO m =>
((forall a. m a -> IO a) -> IO b) -> m b
withRunInIO forall a b. (a -> b) -> a -> b
$ \forall a. m a -> IO a
runInBase ->
forall a b c. IO a -> IO b -> IO c -> IO c
E.bracket_
( forall a. m a -> IO a
runInBase forall a b. (a -> b) -> a -> b
$
forall (m :: Method 'ServerToClient 'Notification) (f :: * -> *)
config.
MonadLsp config f =>
SServerMethod @'Notification m
-> MessageParams @'ServerToClient @'Notification m -> f ()
sendNotification forall {f :: MessageDirection}.
SMethod @f @'Notification ('Method_Progress @f)
SMethod_Progress forall a b. (a -> b) -> a -> b
$
ProgressToken -> Value -> ProgressParams
ProgressParams ProgressToken
progId forall a b. (a -> b) -> a -> b
$
forall a. ToJSON a => a -> Value
J.toJSON forall a b. (a -> b) -> a -> b
$
AString "begin"
-> Text
-> Maybe Bool
-> Maybe Text
-> Maybe UInt
-> WorkDoneProgressBegin
WorkDoneProgressBegin forall (s :: Symbol). KnownSymbol s => AString s
L.AString Text
title (forall a. a -> Maybe a
Just Bool
cancellable') forall a. Maybe a
Nothing Maybe UInt
initialPercentage
)
( forall a. m a -> IO a
runInBase forall a b. (a -> b) -> a -> b
$
forall (m :: Method 'ServerToClient 'Notification) (f :: * -> *)
config.
MonadLsp config f =>
SServerMethod @'Notification m
-> MessageParams @'ServerToClient @'Notification m -> f ()
sendNotification forall {f :: MessageDirection}.
SMethod @f @'Notification ('Method_Progress @f)
SMethod_Progress forall a b. (a -> b) -> a -> b
$
ProgressToken -> Value -> ProgressParams
ProgressParams ProgressToken
progId forall a b. (a -> b) -> a -> b
$
forall a. ToJSON a => a -> Value
J.toJSON forall a b. (a -> b) -> a -> b
$
(AString "end" -> Maybe Text -> WorkDoneProgressEnd
WorkDoneProgressEnd forall (s :: Symbol). KnownSymbol s => AString s
L.AString forall a. Maybe a
Nothing)
)
forall a b. (a -> b) -> a -> b
$ do
Async a
aid <- forall a. IO a -> IO (Async a)
async forall a b. (a -> b) -> a -> b
$ forall a. m a -> IO a
runInBase forall a b. (a -> b) -> a -> b
$ (ProgressAmount -> m ()) -> m a
f (forall {config} {f :: * -> *}.
MonadLsp config f =>
ProgressToken -> ProgressAmount -> f ()
updater ProgressToken
progId)
forall a. m a -> IO a
runInBase forall a b. (a -> b) -> a -> b
$ forall config (m :: * -> *) a.
MonadLsp config m =>
ProgressToken -> Async a -> m ()
storeProgress ProgressToken
progId Async a
aid
forall a. Async a -> IO a
wait Async a
aid
forall config (m :: * -> *).
MonadLsp config m =>
ProgressToken -> m ()
deleteProgress ProgressToken
progId
forall (m :: * -> *) a. Monad m => a -> m a
return a
res
where
updater :: ProgressToken -> ProgressAmount -> f ()
updater ProgressToken
progId (ProgressAmount Maybe UInt
percentage Maybe Text
msg) = do
forall (m :: Method 'ServerToClient 'Notification) (f :: * -> *)
config.
MonadLsp config f =>
SServerMethod @'Notification m
-> MessageParams @'ServerToClient @'Notification m -> f ()
sendNotification forall {f :: MessageDirection}.
SMethod @f @'Notification ('Method_Progress @f)
SMethod_Progress forall a b. (a -> b) -> a -> b
$
ProgressToken -> Value -> ProgressParams
ProgressParams ProgressToken
progId forall a b. (a -> b) -> a -> b
$
forall a. ToJSON a => a -> Value
J.toJSON forall a b. (a -> b) -> a -> b
$
AString "report"
-> Maybe Bool -> Maybe Text -> Maybe UInt -> WorkDoneProgressReport
WorkDoneProgressReport forall (s :: Symbol). KnownSymbol s => AString s
L.AString forall a. Maybe a
Nothing Maybe Text
msg Maybe UInt
percentage
clientSupportsProgress :: L.ClientCapabilities -> Bool
clientSupportsProgress :: ClientCapabilities -> Bool
clientSupportsProgress ClientCapabilities
caps = forall a. a -> Maybe a -> a
fromMaybe Bool
False forall a b. (a -> b) -> a -> b
$ ClientCapabilities
caps forall s a. s -> Getting (First a) s a -> Maybe a
^? forall s a. HasWindow s a => Lens' s a
L.window forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a b. Prism (Maybe a) (Maybe b) a b
_Just forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall s a. HasWorkDoneProgress s a => Lens' s a
L.workDoneProgress forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a b. Prism (Maybe a) (Maybe b) a b
_Just
{-# INLINE clientSupportsProgress #-}
withProgress :: MonadLsp c m => Text -> ProgressCancellable -> ((ProgressAmount -> m ()) -> m a) -> m a
withProgress :: forall c (m :: * -> *) a.
MonadLsp c m =>
Text
-> ProgressCancellable -> ((ProgressAmount -> m ()) -> m a) -> m a
withProgress Text
title ProgressCancellable
cancellable (ProgressAmount -> m ()) -> m a
f = do
ClientCapabilities
clientCaps <- forall config (m :: * -> *).
MonadLsp config m =>
m ClientCapabilities
getClientCapabilities
if ClientCapabilities -> Bool
clientSupportsProgress ClientCapabilities
clientCaps
then forall c (m :: * -> *) a.
MonadLsp c m =>
Bool
-> Text
-> ProgressCancellable
-> ((ProgressAmount -> m ()) -> m a)
-> m a
withProgressBase Bool
False Text
title ProgressCancellable
cancellable (ProgressAmount -> m ()) -> m a
f
else (ProgressAmount -> m ()) -> m a
f (forall a b. a -> b -> a
const forall a b. (a -> b) -> a -> b
$ forall (m :: * -> *) a. Monad m => a -> m a
return ())
withIndefiniteProgress :: MonadLsp c m => Text -> ProgressCancellable -> m a -> m a
withIndefiniteProgress :: forall c (m :: * -> *) a.
MonadLsp c m =>
Text -> ProgressCancellable -> m a -> m a
withIndefiniteProgress Text
title ProgressCancellable
cancellable m a
f = do
ClientCapabilities
clientCaps <- forall config (m :: * -> *).
MonadLsp config m =>
m ClientCapabilities
getClientCapabilities
if ClientCapabilities -> Bool
clientSupportsProgress ClientCapabilities
clientCaps
then forall c (m :: * -> *) a.
MonadLsp c m =>
Bool
-> Text
-> ProgressCancellable
-> ((ProgressAmount -> m ()) -> m a)
-> m a
withProgressBase Bool
True Text
title ProgressCancellable
cancellable (forall a b. a -> b -> a
const m a
f)
else m a
f
publishDiagnostics :: MonadLsp config m => Int -> NormalizedUri -> Maybe L.Int32 -> DiagnosticsBySource -> m ()
publishDiagnostics :: forall config (m :: * -> *).
MonadLsp config m =>
Int -> NormalizedUri -> Maybe Int32 -> DiagnosticsBySource -> m ()
publishDiagnostics Int
maxDiagnosticCount NormalizedUri
uri Maybe Int32
version DiagnosticsBySource
diags = forall (m :: * -> *) a. Monad m => m (m a) -> m a
join forall a b. (a -> b) -> a -> b
$ forall config (m :: * -> *) s a.
MonadLsp config m =>
(LanguageContextState config -> TVar s) -> (s -> (a, s)) -> m a
stateState forall config. LanguageContextState config -> TVar DiagnosticStore
resDiagnostics forall a b. (a -> b) -> a -> b
$ \DiagnosticStore
oldDiags ->
let !newDiags :: DiagnosticStore
newDiags = DiagnosticStore
-> NormalizedUri
-> Maybe Int32
-> DiagnosticsBySource
-> DiagnosticStore
updateDiagnostics DiagnosticStore
oldDiags NormalizedUri
uri Maybe Int32
version DiagnosticsBySource
diags
mdp :: Maybe PublishDiagnosticsParams
mdp = Int
-> DiagnosticStore
-> NormalizedUri
-> Maybe PublishDiagnosticsParams
getDiagnosticParamsFor Int
maxDiagnosticCount DiagnosticStore
newDiags NormalizedUri
uri
act :: m ()
act = case Maybe PublishDiagnosticsParams
mdp of
Maybe PublishDiagnosticsParams
Nothing -> forall (m :: * -> *) a. Monad m => a -> m a
return ()
Just PublishDiagnosticsParams
params ->
forall config (m :: * -> *).
MonadLsp config m =>
FromServerMessage -> m ()
sendToClient forall a b. (a -> b) -> a -> b
$ forall (m :: Method 'ServerToClient 'Notification).
((TMessage @'ServerToClient @'Notification m :: *)
~ (TNotificationMessage @'ServerToClient m :: *)) =>
TNotificationMessage @'ServerToClient m -> FromServerMessage
L.fromServerNot forall a b. (a -> b) -> a -> b
$ forall (f :: MessageDirection) (m :: Method f 'Notification).
Text
-> SMethod @f @'Notification m
-> MessageParams @f @'Notification m
-> TNotificationMessage @f m
L.TNotificationMessage Text
"2.0" SMethod
@'ServerToClient
@'Notification
'Method_TextDocumentPublishDiagnostics
L.SMethod_TextDocumentPublishDiagnostics PublishDiagnosticsParams
params
in (m ()
act, DiagnosticStore
newDiags)
flushDiagnosticsBySource ::
MonadLsp config m =>
Int ->
Maybe Text ->
m ()
flushDiagnosticsBySource :: forall config (m :: * -> *).
MonadLsp config m =>
Int -> Maybe Text -> m ()
flushDiagnosticsBySource Int
maxDiagnosticCount Maybe Text
msource = forall (m :: * -> *) a. Monad m => m (m a) -> m a
join forall a b. (a -> b) -> a -> b
$ forall config (m :: * -> *) s a.
MonadLsp config m =>
(LanguageContextState config -> TVar s) -> (s -> (a, s)) -> m a
stateState forall config. LanguageContextState config -> TVar DiagnosticStore
resDiagnostics forall a b. (a -> b) -> a -> b
$ \DiagnosticStore
oldDiags ->
let !newDiags :: DiagnosticStore
newDiags = DiagnosticStore -> Maybe Text -> DiagnosticStore
flushBySource DiagnosticStore
oldDiags Maybe Text
msource
act :: m ()
act = forall (t :: * -> *) (m :: * -> *) a b.
(Foldable t, Monad m) =>
t a -> (a -> m b) -> m ()
forM_ (forall k v. HashMap k v -> [k]
HM.keys DiagnosticStore
newDiags) forall a b. (a -> b) -> a -> b
$ \NormalizedUri
uri -> do
let mdp :: Maybe PublishDiagnosticsParams
mdp = Int
-> DiagnosticStore
-> NormalizedUri
-> Maybe PublishDiagnosticsParams
getDiagnosticParamsFor Int
maxDiagnosticCount DiagnosticStore
newDiags NormalizedUri
uri
case Maybe PublishDiagnosticsParams
mdp of
Maybe PublishDiagnosticsParams
Nothing -> forall (m :: * -> *) a. Monad m => a -> m a
return ()
Just PublishDiagnosticsParams
params -> do
forall config (m :: * -> *).
MonadLsp config m =>
FromServerMessage -> m ()
sendToClient forall a b. (a -> b) -> a -> b
$ forall (m :: Method 'ServerToClient 'Notification).
((TMessage @'ServerToClient @'Notification m :: *)
~ (TNotificationMessage @'ServerToClient m :: *)) =>
TNotificationMessage @'ServerToClient m -> FromServerMessage
L.fromServerNot forall a b. (a -> b) -> a -> b
$ forall (f :: MessageDirection) (m :: Method f 'Notification).
Text
-> SMethod @f @'Notification m
-> MessageParams @f @'Notification m
-> TNotificationMessage @f m
L.TNotificationMessage Text
"2.0" SMethod
@'ServerToClient
@'Notification
'Method_TextDocumentPublishDiagnostics
L.SMethod_TextDocumentPublishDiagnostics PublishDiagnosticsParams
params
in (m ()
act, DiagnosticStore
newDiags)
reverseSortEdit :: L.WorkspaceEdit -> L.WorkspaceEdit
reverseSortEdit :: WorkspaceEdit -> WorkspaceEdit
reverseSortEdit (L.WorkspaceEdit Maybe (Map Uri [TextEdit])
cs Maybe
[TextDocumentEdit |? (CreateFile |? (RenameFile |? DeleteFile))]
dcs Maybe (Map ChangeAnnotationIdentifier ChangeAnnotation)
anns) = Maybe (Map Uri [TextEdit])
-> Maybe
[TextDocumentEdit |? (CreateFile |? (RenameFile |? DeleteFile))]
-> Maybe (Map ChangeAnnotationIdentifier ChangeAnnotation)
-> WorkspaceEdit
L.WorkspaceEdit Maybe (Map Uri [TextEdit])
cs' Maybe
[TextDocumentEdit |? (CreateFile |? (RenameFile |? DeleteFile))]
dcs' Maybe (Map ChangeAnnotationIdentifier ChangeAnnotation)
anns
where
cs' :: Maybe (Map.Map Uri [TextEdit])
cs' :: Maybe (Map Uri [TextEdit])
cs' = (forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap) [TextEdit] -> [TextEdit]
sortTextEdits Maybe (Map Uri [TextEdit])
cs
dcs' :: Maybe [L.DocumentChange]
dcs' :: Maybe
[TextDocumentEdit |? (CreateFile |? (RenameFile |? DeleteFile))]
dcs' = (forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap) (TextDocumentEdit |? (CreateFile |? (RenameFile |? DeleteFile)))
-> TextDocumentEdit |? (CreateFile |? (RenameFile |? DeleteFile))
sortOnlyTextDocumentEdits Maybe
[TextDocumentEdit |? (CreateFile |? (RenameFile |? DeleteFile))]
dcs
sortTextEdits :: [L.TextEdit] -> [L.TextEdit]
sortTextEdits :: [TextEdit] -> [TextEdit]
sortTextEdits [TextEdit]
edits = forall b a. Ord b => (a -> b) -> [a] -> [a]
L.sortOn (forall a. a -> Down a
Down forall b c a. (b -> c) -> (a -> b) -> a -> c
. (forall s a. s -> Getting a s a -> a
^. forall s a. HasRange s a => Lens' s a
L.range)) [TextEdit]
edits
sortOnlyTextDocumentEdits :: L.DocumentChange -> L.DocumentChange
sortOnlyTextDocumentEdits :: (TextDocumentEdit |? (CreateFile |? (RenameFile |? DeleteFile)))
-> TextDocumentEdit |? (CreateFile |? (RenameFile |? DeleteFile))
sortOnlyTextDocumentEdits (L.InL (L.TextDocumentEdit OptionalVersionedTextDocumentIdentifier
td [TextEdit |? AnnotatedTextEdit]
edits)) = forall a b. a -> a |? b
L.InL forall a b. (a -> b) -> a -> b
$ OptionalVersionedTextDocumentIdentifier
-> [TextEdit |? AnnotatedTextEdit] -> TextDocumentEdit
L.TextDocumentEdit OptionalVersionedTextDocumentIdentifier
td [TextEdit |? AnnotatedTextEdit]
edits'
where
edits' :: [TextEdit |? AnnotatedTextEdit]
edits' = forall b a. Ord b => (a -> b) -> [a] -> [a]
L.sortOn (forall a. a -> Down a
Down forall b c a. (b -> c) -> (a -> b) -> a -> c
. (TextEdit |? AnnotatedTextEdit) -> Range
editRange) [TextEdit |? AnnotatedTextEdit]
edits
sortOnlyTextDocumentEdits (L.InR CreateFile |? (RenameFile |? DeleteFile)
others) = forall a b. b -> a |? b
L.InR CreateFile |? (RenameFile |? DeleteFile)
others
editRange :: L.TextEdit L.|? L.AnnotatedTextEdit -> L.Range
editRange :: (TextEdit |? AnnotatedTextEdit) -> Range
editRange (L.InR AnnotatedTextEdit
e) = AnnotatedTextEdit
e forall s a. s -> Getting a s a -> a
^. forall s a. HasRange s a => Lens' s a
L.range
editRange (L.InL TextEdit
e) = TextEdit
e forall s a. s -> Getting a s a -> a
^. forall s a. HasRange s a => Lens' s a
L.range
tryChangeConfig :: (m ~ LspM config) => LogAction m (WithSeverity LspCoreLog) -> J.Value -> m ()
tryChangeConfig :: forall (m :: * -> *) config.
((m :: (* -> *)) ~ (LspM config :: (* -> *))) =>
LogAction m (WithSeverity LspCoreLog) -> Value -> m ()
tryChangeConfig LogAction m (WithSeverity LspCoreLog)
logger Value
newConfigObject = do
config -> Value -> Either Text config
parseCfg <- forall config (m :: * -> *) a.
ReaderT (LanguageContextEnv config) m a -> LspT config m a
LspT forall a b. (a -> b) -> a -> b
$ forall (m :: * -> *) r a. Monad m => (r -> a) -> ReaderT r m a
asks forall config.
LanguageContextEnv config -> config -> Value -> Either Text config
resParseConfig
Either Text config
res <- forall config (m :: * -> *) s a.
MonadLsp config m =>
(LanguageContextState config -> TVar s) -> (s -> (a, s)) -> m a
stateState forall config. LanguageContextState config -> TVar config
resConfig forall a b. (a -> b) -> a -> b
$ \config
oldConfig -> case config -> Value -> Either Text config
parseCfg config
oldConfig Value
newConfigObject of
Left Text
err -> (forall a b. a -> Either a b
Left Text
err, config
oldConfig)
Right config
newConfig -> (forall a b. b -> Either a b
Right config
newConfig, config
newConfig)
case Either Text config
res of
Left Text
err -> do
LogAction m (WithSeverity LspCoreLog)
logger forall (m :: * -> *) msg. LogAction m msg -> msg -> m ()
<& Value -> Text -> LspCoreLog
ConfigurationParseError Value
newConfigObject Text
err forall msg. msg -> Severity -> WithSeverity msg
`WithSeverity` Severity
Warning
Right config
newConfig -> do
LogAction m (WithSeverity LspCoreLog)
logger forall (m :: * -> *) msg. LogAction m msg -> msg -> m ()
<& Value -> LspCoreLog
NewConfig Value
newConfigObject forall msg. msg -> Severity -> WithSeverity msg
`WithSeverity` Severity
Debug
config -> IO ()
cb <- forall config (m :: * -> *) a.
ReaderT (LanguageContextEnv config) m a -> LspT config m a
LspT forall a b. (a -> b) -> a -> b
$ forall (m :: * -> *) r a. Monad m => (r -> a) -> ReaderT r m a
asks forall config. LanguageContextEnv config -> config -> IO ()
resOnConfigChange
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO forall a b. (a -> b) -> a -> b
$ config -> IO ()
cb config
newConfig
requestConfigUpdate :: (m ~ LspM config) => LogAction m (WithSeverity LspCoreLog) -> m ()
requestConfigUpdate :: forall (m :: * -> *) config.
((m :: (* -> *)) ~ (LspM config :: (* -> *))) =>
LogAction m (WithSeverity LspCoreLog) -> m ()
requestConfigUpdate LogAction m (WithSeverity LspCoreLog)
logger = do
ClientCapabilities
caps <- forall config (m :: * -> *) a.
ReaderT (LanguageContextEnv config) m a -> LspT config m a
LspT forall a b. (a -> b) -> a -> b
$ forall (m :: * -> *) r a. Monad m => (r -> a) -> ReaderT r m a
asks forall config. LanguageContextEnv config -> ClientCapabilities
resClientCapabilities
let supportsConfiguration :: Bool
supportsConfiguration = forall a. a -> Maybe a -> a
fromMaybe Bool
False forall a b. (a -> b) -> a -> b
$ ClientCapabilities
caps forall s a. s -> Getting (First a) s a -> Maybe a
^? forall s a. HasWorkspace s a => Lens' s a
L.workspace forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a b. Prism (Maybe a) (Maybe b) a b
_Just forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall s a. HasConfiguration s a => Lens' s a
L.configuration forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a b. Prism (Maybe a) (Maybe b) a b
_Just
if Bool
supportsConfiguration
then do
Text
section <- forall config (m :: * -> *) a.
ReaderT (LanguageContextEnv config) m a -> LspT config m a
LspT forall a b. (a -> b) -> a -> b
$ forall (m :: * -> *) r a. Monad m => (r -> a) -> ReaderT r m a
asks forall config. LanguageContextEnv config -> Text
resConfigSection
forall (f :: * -> *) a. Functor f => f a -> f ()
void forall a b. (a -> b) -> a -> b
$ forall (m :: Method 'ServerToClient 'Request) (f :: * -> *) config.
MonadLsp config f =>
SServerMethod @'Request m
-> MessageParams @'ServerToClient @'Request m
-> (Either
ResponseError (MessageResult @'ServerToClient @'Request m)
-> f ())
-> f (LspId @'ServerToClient m)
sendRequest SMethod @'ServerToClient @'Request 'Method_WorkspaceConfiguration
SMethod_WorkspaceConfiguration ([ConfigurationItem] -> ConfigurationParams
ConfigurationParams [Maybe Text -> Maybe Text -> ConfigurationItem
ConfigurationItem forall a. Maybe a
Nothing (forall a. a -> Maybe a
Just Text
section)]) forall a b. (a -> b) -> a -> b
$ \case
Right [Value
newConfigObject] -> forall (m :: * -> *) config.
((m :: (* -> *)) ~ (LspM config :: (* -> *))) =>
LogAction m (WithSeverity LspCoreLog) -> Value -> m ()
tryChangeConfig LogAction m (WithSeverity LspCoreLog)
logger Value
newConfigObject
Right MessageResult
@'ServerToClient @'Request 'Method_WorkspaceConfiguration
sections -> LogAction m (WithSeverity LspCoreLog)
logger forall (m :: * -> *) msg. LogAction m msg -> msg -> m ()
<& [Value] -> LspCoreLog
WrongConfigSections MessageResult
@'ServerToClient @'Request 'Method_WorkspaceConfiguration
sections forall msg. msg -> Severity -> WithSeverity msg
`WithSeverity` Severity
Error
Left ResponseError
err -> LogAction m (WithSeverity LspCoreLog)
logger forall (m :: * -> *) msg. LogAction m msg -> msg -> m ()
<& ResponseError -> LspCoreLog
BadConfigurationResponse ResponseError
err forall msg. msg -> Severity -> WithSeverity msg
`WithSeverity` Severity
Error
else LogAction m (WithSeverity LspCoreLog)
logger forall (m :: * -> *) msg. LogAction m msg -> msg -> m ()
<& LspCoreLog
ConfigurationNotSupported forall msg. msg -> Severity -> WithSeverity msg
`WithSeverity` Severity
Debug