{-# LANGUAGE DeriveAnyClass #-}
module Development.IDE.Plugin.HLS
(
asGhcIdePlugin
) where
import Control.Exception(SomeException, catch)
import Control.Lens ((^.))
import Control.Monad
import qualified Data.Aeson as J
import qualified Data.DList as DList
import Data.Either
import qualified Data.List as List
import qualified Data.Map as Map
import Data.Maybe
import qualified Data.Text as T
import Development.IDE.Core.Shake
import Development.IDE.LSP.Server
import Development.IDE.Plugin
import Development.IDE.Plugin.HLS.Formatter
import GHC.Generics
import Ide.Plugin.Config
import Ide.Types as HLS
import qualified Language.Haskell.LSP.Core as LSP
import Language.Haskell.LSP.Messages
import Language.Haskell.LSP.Types
import qualified Language.Haskell.LSP.Types as J
import qualified Language.Haskell.LSP.Types.Capabilities as C
import Language.Haskell.LSP.Types.Lens as L hiding (formatting, rangeFormatting)
import qualified Language.Haskell.LSP.VFS as VFS
import Text.Regex.TDFA.Text()
import Development.Shake (Rules)
import Ide.PluginUtils (getClientConfig, pluginEnabled, getPluginConfig, responseError, getProcessID)
import Development.IDE.Core.Tracing
import Development.IDE.Types.Logger (logDebug)
import Control.Concurrent.Async (mapConcurrently)
asGhcIdePlugin :: IdePlugins IdeState -> Plugin Config
asGhcIdePlugin :: IdePlugins IdeState -> Plugin Config
asGhcIdePlugin IdePlugins IdeState
mp =
([(PluginId, Rules ())] -> Plugin Config)
-> (PluginDescriptor IdeState -> Maybe (Rules ())) -> Plugin Config
forall b.
([(PluginId, b)] -> Plugin Config)
-> (PluginDescriptor IdeState -> Maybe b) -> Plugin Config
mkPlugin [(PluginId, Rules ())] -> Plugin Config
rulesPlugins (Rules () -> Maybe (Rules ())
forall a. a -> Maybe a
Just (Rules () -> Maybe (Rules ()))
-> (PluginDescriptor IdeState -> Rules ())
-> PluginDescriptor IdeState
-> Maybe (Rules ())
forall b c a. (b -> c) -> (a -> b) -> a -> c
. PluginDescriptor IdeState -> Rules ()
forall ideState. PluginDescriptor ideState -> Rules ()
HLS.pluginRules) Plugin Config -> Plugin Config -> Plugin Config
forall a. Semigroup a => a -> a -> a
<>
([(PluginId, [PluginCommand IdeState])] -> Plugin Config)
-> (PluginDescriptor IdeState -> Maybe [PluginCommand IdeState])
-> Plugin Config
forall b.
([(PluginId, b)] -> Plugin Config)
-> (PluginDescriptor IdeState -> Maybe b) -> Plugin Config
mkPlugin [(PluginId, [PluginCommand IdeState])] -> Plugin Config
executeCommandPlugins ([PluginCommand IdeState] -> Maybe [PluginCommand IdeState]
forall a. a -> Maybe a
Just ([PluginCommand IdeState] -> Maybe [PluginCommand IdeState])
-> (PluginDescriptor IdeState -> [PluginCommand IdeState])
-> PluginDescriptor IdeState
-> Maybe [PluginCommand IdeState]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. PluginDescriptor IdeState -> [PluginCommand IdeState]
forall ideState.
PluginDescriptor ideState -> [PluginCommand ideState]
pluginCommands) Plugin Config -> Plugin Config -> Plugin Config
forall a. Semigroup a => a -> a -> a
<>
([(PluginId, CodeActionProvider IdeState)] -> Plugin Config)
-> (PluginDescriptor IdeState
-> Maybe (CodeActionProvider IdeState))
-> Plugin Config
forall b.
([(PluginId, b)] -> Plugin Config)
-> (PluginDescriptor IdeState -> Maybe b) -> Plugin Config
mkPlugin [(PluginId, CodeActionProvider IdeState)] -> Plugin Config
codeActionPlugins PluginDescriptor IdeState -> Maybe (CodeActionProvider IdeState)
forall ideState.
PluginDescriptor ideState -> Maybe (CodeActionProvider ideState)
pluginCodeActionProvider Plugin Config -> Plugin Config -> Plugin Config
forall a. Semigroup a => a -> a -> a
<>
([(PluginId, CodeLensProvider IdeState)] -> Plugin Config)
-> (PluginDescriptor IdeState -> Maybe (CodeLensProvider IdeState))
-> Plugin Config
forall b.
([(PluginId, b)] -> Plugin Config)
-> (PluginDescriptor IdeState -> Maybe b) -> Plugin Config
mkPlugin [(PluginId, CodeLensProvider IdeState)] -> Plugin Config
codeLensPlugins PluginDescriptor IdeState -> Maybe (CodeLensProvider IdeState)
forall ideState.
PluginDescriptor ideState -> Maybe (CodeLensProvider ideState)
pluginCodeLensProvider Plugin Config -> Plugin Config -> Plugin Config
forall a. Semigroup a => a -> a -> a
<>
([(PluginId, HoverProvider IdeState)] -> Plugin Config)
-> (PluginDescriptor IdeState -> Maybe (HoverProvider IdeState))
-> Plugin Config
forall b.
([(PluginId, b)] -> Plugin Config)
-> (PluginDescriptor IdeState -> Maybe b) -> Plugin Config
mkPlugin [(PluginId, HoverProvider IdeState)] -> Plugin Config
hoverPlugins PluginDescriptor IdeState -> Maybe (HoverProvider IdeState)
forall ideState.
PluginDescriptor ideState -> Maybe (HoverProvider ideState)
pluginHoverProvider Plugin Config -> Plugin Config -> Plugin Config
forall a. Semigroup a => a -> a -> a
<>
([(PluginId, SymbolsProvider IdeState)] -> Plugin Config)
-> (PluginDescriptor IdeState -> Maybe (SymbolsProvider IdeState))
-> Plugin Config
forall b.
([(PluginId, b)] -> Plugin Config)
-> (PluginDescriptor IdeState -> Maybe b) -> Plugin Config
mkPlugin [(PluginId, SymbolsProvider IdeState)] -> Plugin Config
symbolsPlugins PluginDescriptor IdeState -> Maybe (SymbolsProvider IdeState)
forall ideState.
PluginDescriptor ideState -> Maybe (SymbolsProvider ideState)
pluginSymbolsProvider Plugin Config -> Plugin Config -> Plugin Config
forall a. Semigroup a => a -> a -> a
<>
([(PluginId, FormattingProvider IdeState IO)] -> Plugin Config)
-> (PluginDescriptor IdeState
-> Maybe (FormattingProvider IdeState IO))
-> Plugin Config
forall b.
([(PluginId, b)] -> Plugin Config)
-> (PluginDescriptor IdeState -> Maybe b) -> Plugin Config
mkPlugin [(PluginId, FormattingProvider IdeState IO)] -> Plugin Config
formatterPlugins PluginDescriptor IdeState -> Maybe (FormattingProvider IdeState IO)
forall ideState.
PluginDescriptor ideState -> Maybe (FormattingProvider ideState IO)
pluginFormattingProvider Plugin Config -> Plugin Config -> Plugin Config
forall a. Semigroup a => a -> a -> a
<>
([(PluginId, CompletionProvider IdeState)] -> Plugin Config)
-> (PluginDescriptor IdeState
-> Maybe (CompletionProvider IdeState))
-> Plugin Config
forall b.
([(PluginId, b)] -> Plugin Config)
-> (PluginDescriptor IdeState -> Maybe b) -> Plugin Config
mkPlugin [(PluginId, CompletionProvider IdeState)] -> Plugin Config
completionsPlugins PluginDescriptor IdeState -> Maybe (CompletionProvider IdeState)
forall ideState.
PluginDescriptor ideState -> Maybe (CompletionProvider ideState)
pluginCompletionProvider Plugin Config -> Plugin Config -> Plugin Config
forall a. Semigroup a => a -> a -> a
<>
([(PluginId, RenameProvider IdeState)] -> Plugin Config)
-> (PluginDescriptor IdeState -> Maybe (RenameProvider IdeState))
-> Plugin Config
forall b.
([(PluginId, b)] -> Plugin Config)
-> (PluginDescriptor IdeState -> Maybe b) -> Plugin Config
mkPlugin [(PluginId, RenameProvider IdeState)] -> Plugin Config
renamePlugins PluginDescriptor IdeState -> Maybe (RenameProvider IdeState)
forall ideState.
PluginDescriptor ideState -> Maybe (RenameProvider ideState)
pluginRenameProvider
where
justs :: (a, Maybe b) -> [(a, b)]
justs (a
p, Just b
x) = [(a
p, b
x)]
justs (a
_, Maybe b
Nothing) = []
ls :: [(PluginId, PluginDescriptor IdeState)]
ls = Map PluginId (PluginDescriptor IdeState)
-> [(PluginId, PluginDescriptor IdeState)]
forall k a. Map k a -> [(k, a)]
Map.toList (IdePlugins IdeState -> Map PluginId (PluginDescriptor IdeState)
forall ideState.
IdePlugins ideState -> Map PluginId (PluginDescriptor ideState)
ipMap IdePlugins IdeState
mp)
mkPlugin :: ([(PluginId, b)] -> Plugin Config) -> (PluginDescriptor IdeState -> Maybe b) -> Plugin Config
mkPlugin :: ([(PluginId, b)] -> Plugin Config)
-> (PluginDescriptor IdeState -> Maybe b) -> Plugin Config
mkPlugin [(PluginId, b)] -> Plugin Config
maker PluginDescriptor IdeState -> Maybe b
selector =
case ((PluginId, PluginDescriptor IdeState) -> [(PluginId, b)])
-> [(PluginId, PluginDescriptor IdeState)] -> [(PluginId, b)]
forall (t :: * -> *) a b. Foldable t => (a -> [b]) -> t a -> [b]
concatMap (\(PluginId
pid, PluginDescriptor IdeState
p) -> (PluginId, Maybe b) -> [(PluginId, b)]
forall a b. (a, Maybe b) -> [(a, b)]
justs (PluginId
pid, PluginDescriptor IdeState -> Maybe b
selector PluginDescriptor IdeState
p)) [(PluginId, PluginDescriptor IdeState)]
ls of
[] -> Plugin Config
forall a. Monoid a => a
mempty
[(PluginId, b)]
xs -> [(PluginId, b)] -> Plugin Config
maker [(PluginId, b)]
xs
rulesPlugins :: [(PluginId, Rules ())] -> Plugin Config
rulesPlugins :: [(PluginId, Rules ())] -> Plugin Config
rulesPlugins [(PluginId, Rules ())]
rs = Rules () -> PartialHandlers Config -> Plugin Config
forall c. Rules () -> PartialHandlers c -> Plugin c
Plugin Rules ()
rules PartialHandlers Config
forall a. Monoid a => a
mempty
where
rules :: Rules ()
rules = ((PluginId, Rules ()) -> Rules ())
-> [(PluginId, Rules ())] -> Rules ()
forall (t :: * -> *) m a.
(Foldable t, Monoid m) =>
(a -> m) -> t a -> m
foldMap (PluginId, Rules ()) -> Rules ()
forall a b. (a, b) -> b
snd [(PluginId, Rules ())]
rs
codeActionPlugins :: [(PluginId, CodeActionProvider IdeState)] -> Plugin Config
codeActionPlugins :: [(PluginId, CodeActionProvider IdeState)] -> Plugin Config
codeActionPlugins [(PluginId, CodeActionProvider IdeState)]
cas = Rules () -> PartialHandlers Config -> Plugin Config
forall c. Rules () -> PartialHandlers c -> Plugin c
Plugin Rules ()
codeActionRules ([(PluginId, CodeActionProvider IdeState)] -> PartialHandlers Config
codeActionHandlers [(PluginId, CodeActionProvider IdeState)]
cas)
codeActionRules :: Rules ()
codeActionRules :: Rules ()
codeActionRules = Rules ()
forall a. Monoid a => a
mempty
codeActionHandlers :: [(PluginId, CodeActionProvider IdeState)] -> PartialHandlers Config
codeActionHandlers :: [(PluginId, CodeActionProvider IdeState)] -> PartialHandlers Config
codeActionHandlers [(PluginId, CodeActionProvider IdeState)]
cas = (WithMessage Config -> Handlers -> IO Handlers)
-> PartialHandlers Config
forall c.
(WithMessage c -> Handlers -> IO Handlers) -> PartialHandlers c
PartialHandlers ((WithMessage Config -> Handlers -> IO Handlers)
-> PartialHandlers Config)
-> (WithMessage Config -> Handlers -> IO Handlers)
-> PartialHandlers Config
forall a b. (a -> b) -> a -> b
$ \WithMessage{(LspFuncs Config -> IdeState -> InitializeParams -> IO ())
-> Maybe (Handler InitializeRequest)
forall m req.
(Show m, Show req, HasTracing req) =>
Maybe (Handler (NotificationMessage m req))
-> (LspFuncs Config -> IdeState -> req -> IO ())
-> Maybe (Handler (NotificationMessage m req))
forall m req resp.
(Show m, Show req, HasTracing req) =>
(ResponseMessage resp -> FromServerMessage)
-> (LspFuncs Config
-> IdeState -> req -> IO (Either ResponseError resp))
-> Maybe (Handler (RequestMessage m req resp))
forall m rm req resp newReqParams newReqBody.
(Show m, Show rm, Show req, Show newReqParams, Show newReqBody,
HasTracing req) =>
(ResponseMessage resp -> FromServerMessage)
-> (RequestMessage rm newReqParams newReqBody -> FromServerMessage)
-> (LspFuncs Config
-> IdeState
-> req
-> IO (Either ResponseError resp, Maybe (rm, newReqParams)))
-> Maybe (Handler (RequestMessage m req resp))
$sel:withInitialize:WithMessage :: forall c.
WithMessage c
-> (LspFuncs c -> IdeState -> InitializeParams -> IO ())
-> Maybe (Handler InitializeRequest)
$sel:withResponseAndRequest:WithMessage :: forall c.
WithMessage c
-> forall m rm req resp newReqParams newReqBody.
(Show m, Show rm, Show req, Show newReqParams, Show newReqBody,
HasTracing req) =>
(ResponseMessage resp -> FromServerMessage)
-> (RequestMessage rm newReqParams newReqBody -> FromServerMessage)
-> (LspFuncs c
-> IdeState
-> req
-> IO (Either ResponseError resp, Maybe (rm, newReqParams)))
-> Maybe (Handler (RequestMessage m req resp))
$sel:withNotification:WithMessage :: forall c.
WithMessage c
-> forall m req.
(Show m, Show req, HasTracing req) =>
Maybe (Handler (NotificationMessage m req))
-> (LspFuncs c -> IdeState -> req -> IO ())
-> Maybe (Handler (NotificationMessage m req))
$sel:withResponse:WithMessage :: forall c.
WithMessage c
-> forall m req resp.
(Show m, Show req, HasTracing req) =>
(ResponseMessage resp -> FromServerMessage)
-> (LspFuncs c
-> IdeState -> req -> IO (Either ResponseError resp))
-> Maybe (Handler (RequestMessage m req resp))
withInitialize :: (LspFuncs Config -> IdeState -> InitializeParams -> IO ())
-> Maybe (Handler InitializeRequest)
withResponseAndRequest :: forall m rm req resp newReqParams newReqBody.
(Show m, Show rm, Show req, Show newReqParams, Show newReqBody,
HasTracing req) =>
(ResponseMessage resp -> FromServerMessage)
-> (RequestMessage rm newReqParams newReqBody -> FromServerMessage)
-> (LspFuncs Config
-> IdeState
-> req
-> IO (Either ResponseError resp, Maybe (rm, newReqParams)))
-> Maybe (Handler (RequestMessage m req resp))
withNotification :: forall m req.
(Show m, Show req, HasTracing req) =>
Maybe (Handler (NotificationMessage m req))
-> (LspFuncs Config -> IdeState -> req -> IO ())
-> Maybe (Handler (NotificationMessage m req))
withResponse :: forall m req resp.
(Show m, Show req, HasTracing req) =>
(ResponseMessage resp -> FromServerMessage)
-> (LspFuncs Config
-> IdeState -> req -> IO (Either ResponseError resp))
-> Maybe (Handler (RequestMessage m req resp))
..} Handlers
x -> Handlers -> IO Handlers
forall (m :: * -> *) a. Monad m => a -> m a
return Handlers
x
{ codeActionHandler :: Maybe (Handler CodeActionRequest)
LSP.codeActionHandler
= (ResponseMessage (List CAResult) -> FromServerMessage)
-> (LspFuncs Config
-> IdeState
-> CodeActionParams
-> IO (Either ResponseError (List CAResult)))
-> Maybe (Handler CodeActionRequest)
forall m req resp.
(Show m, Show req, HasTracing req) =>
(ResponseMessage resp -> FromServerMessage)
-> (LspFuncs Config
-> IdeState -> req -> IO (Either ResponseError resp))
-> Maybe (Handler (RequestMessage m req resp))
withResponse ResponseMessage (List CAResult) -> FromServerMessage
RspCodeAction ([(PluginId, CodeActionProvider IdeState)]
-> LspFuncs Config
-> IdeState
-> CodeActionParams
-> IO (Either ResponseError (List CAResult))
makeCodeAction [(PluginId, CodeActionProvider IdeState)]
cas)
}
makeCodeAction :: [(PluginId, CodeActionProvider IdeState)]
-> LSP.LspFuncs Config -> IdeState
-> CodeActionParams
-> IO (Either ResponseError (List CAResult))
makeCodeAction :: [(PluginId, CodeActionProvider IdeState)]
-> LspFuncs Config
-> IdeState
-> CodeActionParams
-> IO (Either ResponseError (List CAResult))
makeCodeAction [(PluginId, CodeActionProvider IdeState)]
cas LspFuncs Config
lf IdeState
ideState (CodeActionParams TextDocumentIdentifier
docId Range
range CodeActionContext
context Maybe ProgressToken
_) = do
let caps :: ClientCapabilities
caps = LspFuncs Config -> ClientCapabilities
forall c. LspFuncs c -> ClientCapabilities
LSP.clientCapabilities LspFuncs Config
lf
unL :: List a -> [a]
unL (List [a]
ls) = [a]
ls
makeAction :: (PluginId,
LspFuncs Config
-> IdeState
-> PluginId
-> TextDocumentIdentifier
-> Range
-> CodeActionContext
-> IO (Either a (List a)))
-> IO (Either a (List a))
makeAction (PluginId
pid,LspFuncs Config
-> IdeState
-> PluginId
-> TextDocumentIdentifier
-> Range
-> CodeActionContext
-> IO (Either a (List a))
provider) = do
PluginConfig
pluginConfig <- LspFuncs Config -> PluginId -> IO PluginConfig
getPluginConfig LspFuncs Config
lf PluginId
pid
if PluginConfig -> (PluginConfig -> Bool) -> Bool
pluginEnabled PluginConfig
pluginConfig PluginConfig -> Bool
plcCodeActionsOn
then PluginId
-> ByteString -> IO (Either a (List a)) -> IO (Either a (List a))
forall a. PluginId -> ByteString -> IO a -> IO a
otTracedProvider PluginId
pid ByteString
"codeAction" (IO (Either a (List a)) -> IO (Either a (List a)))
-> IO (Either a (List a)) -> IO (Either a (List a))
forall a b. (a -> b) -> a -> b
$ LspFuncs Config
-> IdeState
-> PluginId
-> TextDocumentIdentifier
-> Range
-> CodeActionContext
-> IO (Either a (List a))
provider LspFuncs Config
lf IdeState
ideState PluginId
pid TextDocumentIdentifier
docId Range
range CodeActionContext
context
else Either a (List a) -> IO (Either a (List a))
forall (m :: * -> *) a. Monad m => a -> m a
return (Either a (List a) -> IO (Either a (List a)))
-> Either a (List a) -> IO (Either a (List a))
forall a b. (a -> b) -> a -> b
$ List a -> Either a (List a)
forall a b. b -> Either a b
Right ([a] -> List a
forall a. [a] -> List a
List [])
[Either ResponseError (List CAResult)]
r <- ((PluginId, CodeActionProvider IdeState)
-> IO (Either ResponseError (List CAResult)))
-> [(PluginId, CodeActionProvider IdeState)]
-> IO [Either ResponseError (List CAResult)]
forall (t :: * -> *) a b.
Traversable t =>
(a -> IO b) -> t a -> IO (t b)
mapConcurrently (PluginId, CodeActionProvider IdeState)
-> IO (Either ResponseError (List CAResult))
forall a a.
(PluginId,
LspFuncs Config
-> IdeState
-> PluginId
-> TextDocumentIdentifier
-> Range
-> CodeActionContext
-> IO (Either a (List a)))
-> IO (Either a (List a))
makeAction [(PluginId, CodeActionProvider IdeState)]
cas
let actions :: [CAResult]
actions = (CAResult -> Bool) -> [CAResult] -> [CAResult]
forall a. (a -> Bool) -> [a] -> [a]
filter CAResult -> Bool
wasRequested ([CAResult] -> [CAResult])
-> ([List CAResult] -> [CAResult]) -> [List CAResult] -> [CAResult]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (List CAResult -> [CAResult]) -> [List CAResult] -> [CAResult]
forall (t :: * -> *) m a.
(Foldable t, Monoid m) =>
(a -> m) -> t a -> m
foldMap List CAResult -> [CAResult]
forall a. List a -> [a]
unL ([List CAResult] -> [CAResult]) -> [List CAResult] -> [CAResult]
forall a b. (a -> b) -> a -> b
$ [Either ResponseError (List CAResult)] -> [List CAResult]
forall a b. [Either a b] -> [b]
rights [Either ResponseError (List CAResult)]
r
List CAResult
res <- ClientCapabilities -> [CAResult] -> IO (List CAResult)
send ClientCapabilities
caps [CAResult]
actions
Either ResponseError (List CAResult)
-> IO (Either ResponseError (List CAResult))
forall (m :: * -> *) a. Monad m => a -> m a
return (Either ResponseError (List CAResult)
-> IO (Either ResponseError (List CAResult)))
-> Either ResponseError (List CAResult)
-> IO (Either ResponseError (List CAResult))
forall a b. (a -> b) -> a -> b
$ List CAResult -> Either ResponseError (List CAResult)
forall a b. b -> Either a b
Right List CAResult
res
where
wasRequested :: CAResult -> Bool
wasRequested :: CAResult -> Bool
wasRequested (CACommand Command
_) = Bool
True
wasRequested (CACodeAction CodeAction
ca)
| Maybe (List CodeActionKind)
Nothing <- CodeActionContext -> Maybe (List CodeActionKind)
only CodeActionContext
context = Bool
True
| Just (List [CodeActionKind]
allowed) <- CodeActionContext -> Maybe (List CodeActionKind)
only CodeActionContext
context
, Just CodeActionKind
caKind <- CodeAction
ca CodeAction
-> Getting (Maybe CodeActionKind) CodeAction (Maybe CodeActionKind)
-> Maybe CodeActionKind
forall s a. s -> Getting a s a -> a
^. Getting (Maybe CodeActionKind) CodeAction (Maybe CodeActionKind)
forall s a. HasKind s a => Lens' s a
kind = CodeActionKind
caKind CodeActionKind -> [CodeActionKind] -> Bool
forall (t :: * -> *) a. (Foldable t, Eq a) => a -> t a -> Bool
`elem` [CodeActionKind]
allowed
| Bool
otherwise = Bool
False
wrapCodeAction :: C.ClientCapabilities -> CAResult -> IO (Maybe CAResult)
wrapCodeAction :: ClientCapabilities -> CAResult -> IO (Maybe CAResult)
wrapCodeAction ClientCapabilities
_ (CACommand Command
cmd) = Maybe CAResult -> IO (Maybe CAResult)
forall (m :: * -> *) a. Monad m => a -> m a
return (Maybe CAResult -> IO (Maybe CAResult))
-> Maybe CAResult -> IO (Maybe CAResult)
forall a b. (a -> b) -> a -> b
$ CAResult -> Maybe CAResult
forall a. a -> Maybe a
Just (Command -> CAResult
CACommand Command
cmd)
wrapCodeAction ClientCapabilities
caps (CACodeAction CodeAction
action) = do
let (C.ClientCapabilities Maybe WorkspaceClientCapabilities
_ Maybe TextDocumentClientCapabilities
textDocCaps Maybe WindowClientCapabilities
_ Maybe Object
_) = ClientCapabilities
caps
let literalSupport :: Maybe CodeActionLiteralSupport
literalSupport = Maybe TextDocumentClientCapabilities
textDocCaps Maybe TextDocumentClientCapabilities
-> (TextDocumentClientCapabilities
-> Maybe CodeActionClientCapabilities)
-> Maybe CodeActionClientCapabilities
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= TextDocumentClientCapabilities
-> Maybe CodeActionClientCapabilities
C._codeAction Maybe CodeActionClientCapabilities
-> (CodeActionClientCapabilities -> Maybe CodeActionLiteralSupport)
-> Maybe CodeActionLiteralSupport
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= CodeActionClientCapabilities -> Maybe CodeActionLiteralSupport
C._codeActionLiteralSupport
case Maybe CodeActionLiteralSupport
literalSupport of
Maybe CodeActionLiteralSupport
Nothing -> do
let cmdParams :: [Value]
cmdParams = [FallbackCodeActionParams -> Value
forall a. ToJSON a => a -> Value
J.toJSON (Maybe WorkspaceEdit -> Maybe Command -> FallbackCodeActionParams
FallbackCodeActionParams (CodeAction
action CodeAction
-> Getting (Maybe WorkspaceEdit) CodeAction (Maybe WorkspaceEdit)
-> Maybe WorkspaceEdit
forall s a. s -> Getting a s a -> a
^. Getting (Maybe WorkspaceEdit) CodeAction (Maybe WorkspaceEdit)
forall s a. HasEdit s a => Lens' s a
edit) (CodeAction
action CodeAction
-> Getting (Maybe Command) CodeAction (Maybe Command)
-> Maybe Command
forall s a. s -> Getting a s a -> a
^. Getting (Maybe Command) CodeAction (Maybe Command)
forall s a. HasCommand s a => Lens' s a
command))]
Command
cmd <- PluginId -> CommandId -> Text -> Maybe [Value] -> IO Command
mkLspCommand PluginId
"hls" CommandId
"fallbackCodeAction" (CodeAction
action CodeAction -> Getting Text CodeAction Text -> Text
forall s a. s -> Getting a s a -> a
^. Getting Text CodeAction Text
forall s a. HasTitle s a => Lens' s a
title) ([Value] -> Maybe [Value]
forall a. a -> Maybe a
Just [Value]
cmdParams)
Maybe CAResult -> IO (Maybe CAResult)
forall (m :: * -> *) a. Monad m => a -> m a
return (Maybe CAResult -> IO (Maybe CAResult))
-> Maybe CAResult -> IO (Maybe CAResult)
forall a b. (a -> b) -> a -> b
$ CAResult -> Maybe CAResult
forall a. a -> Maybe a
Just (Command -> CAResult
CACommand Command
cmd)
Just CodeActionLiteralSupport
_ -> Maybe CAResult -> IO (Maybe CAResult)
forall (m :: * -> *) a. Monad m => a -> m a
return (Maybe CAResult -> IO (Maybe CAResult))
-> Maybe CAResult -> IO (Maybe CAResult)
forall a b. (a -> b) -> a -> b
$ CAResult -> Maybe CAResult
forall a. a -> Maybe a
Just (CodeAction -> CAResult
CACodeAction CodeAction
action)
send :: C.ClientCapabilities -> [CAResult] -> IO (List CAResult)
send :: ClientCapabilities -> [CAResult] -> IO (List CAResult)
send ClientCapabilities
caps [CAResult]
codeActions = [CAResult] -> List CAResult
forall a. [a] -> List a
List ([CAResult] -> List CAResult)
-> ([Maybe CAResult] -> [CAResult])
-> [Maybe CAResult]
-> List CAResult
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [Maybe CAResult] -> [CAResult]
forall a. [Maybe a] -> [a]
catMaybes ([Maybe CAResult] -> List CAResult)
-> IO [Maybe CAResult] -> IO (List CAResult)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> (CAResult -> IO (Maybe CAResult))
-> [CAResult] -> IO [Maybe CAResult]
forall (t :: * -> *) (m :: * -> *) a b.
(Traversable t, Monad m) =>
(a -> m b) -> t a -> m (t b)
mapM (ClientCapabilities -> CAResult -> IO (Maybe CAResult)
wrapCodeAction ClientCapabilities
caps) [CAResult]
codeActions
data FallbackCodeActionParams =
FallbackCodeActionParams
{ FallbackCodeActionParams -> Maybe WorkspaceEdit
fallbackWorkspaceEdit :: Maybe WorkspaceEdit
, FallbackCodeActionParams -> Maybe Command
fallbackCommand :: Maybe Command
}
deriving ((forall x.
FallbackCodeActionParams -> Rep FallbackCodeActionParams x)
-> (forall x.
Rep FallbackCodeActionParams x -> FallbackCodeActionParams)
-> Generic FallbackCodeActionParams
forall x.
Rep FallbackCodeActionParams x -> FallbackCodeActionParams
forall x.
FallbackCodeActionParams -> Rep FallbackCodeActionParams x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
$cto :: forall x.
Rep FallbackCodeActionParams x -> FallbackCodeActionParams
$cfrom :: forall x.
FallbackCodeActionParams -> Rep FallbackCodeActionParams x
Generic, [FallbackCodeActionParams] -> Encoding
[FallbackCodeActionParams] -> Value
FallbackCodeActionParams -> Encoding
FallbackCodeActionParams -> Value
(FallbackCodeActionParams -> Value)
-> (FallbackCodeActionParams -> Encoding)
-> ([FallbackCodeActionParams] -> Value)
-> ([FallbackCodeActionParams] -> Encoding)
-> ToJSON FallbackCodeActionParams
forall a.
(a -> Value)
-> (a -> Encoding)
-> ([a] -> Value)
-> ([a] -> Encoding)
-> ToJSON a
toEncodingList :: [FallbackCodeActionParams] -> Encoding
$ctoEncodingList :: [FallbackCodeActionParams] -> Encoding
toJSONList :: [FallbackCodeActionParams] -> Value
$ctoJSONList :: [FallbackCodeActionParams] -> Value
toEncoding :: FallbackCodeActionParams -> Encoding
$ctoEncoding :: FallbackCodeActionParams -> Encoding
toJSON :: FallbackCodeActionParams -> Value
$ctoJSON :: FallbackCodeActionParams -> Value
J.ToJSON, Value -> Parser [FallbackCodeActionParams]
Value -> Parser FallbackCodeActionParams
(Value -> Parser FallbackCodeActionParams)
-> (Value -> Parser [FallbackCodeActionParams])
-> FromJSON FallbackCodeActionParams
forall a.
(Value -> Parser a) -> (Value -> Parser [a]) -> FromJSON a
parseJSONList :: Value -> Parser [FallbackCodeActionParams]
$cparseJSONList :: Value -> Parser [FallbackCodeActionParams]
parseJSON :: Value -> Parser FallbackCodeActionParams
$cparseJSON :: Value -> Parser FallbackCodeActionParams
J.FromJSON)
codeLensPlugins :: [(PluginId, CodeLensProvider IdeState)] -> Plugin Config
codeLensPlugins :: [(PluginId, CodeLensProvider IdeState)] -> Plugin Config
codeLensPlugins [(PluginId, CodeLensProvider IdeState)]
cas = Rules () -> PartialHandlers Config -> Plugin Config
forall c. Rules () -> PartialHandlers c -> Plugin c
Plugin Rules ()
codeLensRules ([(PluginId, CodeLensProvider IdeState)] -> PartialHandlers Config
codeLensHandlers [(PluginId, CodeLensProvider IdeState)]
cas)
codeLensRules :: Rules ()
codeLensRules :: Rules ()
codeLensRules = Rules ()
forall a. Monoid a => a
mempty
codeLensHandlers :: [(PluginId, CodeLensProvider IdeState)] -> PartialHandlers Config
codeLensHandlers :: [(PluginId, CodeLensProvider IdeState)] -> PartialHandlers Config
codeLensHandlers [(PluginId, CodeLensProvider IdeState)]
cas = (WithMessage Config -> Handlers -> IO Handlers)
-> PartialHandlers Config
forall c.
(WithMessage c -> Handlers -> IO Handlers) -> PartialHandlers c
PartialHandlers ((WithMessage Config -> Handlers -> IO Handlers)
-> PartialHandlers Config)
-> (WithMessage Config -> Handlers -> IO Handlers)
-> PartialHandlers Config
forall a b. (a -> b) -> a -> b
$ \WithMessage{(LspFuncs Config -> IdeState -> InitializeParams -> IO ())
-> Maybe (Handler InitializeRequest)
forall m req.
(Show m, Show req, HasTracing req) =>
Maybe (Handler (NotificationMessage m req))
-> (LspFuncs Config -> IdeState -> req -> IO ())
-> Maybe (Handler (NotificationMessage m req))
forall m req resp.
(Show m, Show req, HasTracing req) =>
(ResponseMessage resp -> FromServerMessage)
-> (LspFuncs Config
-> IdeState -> req -> IO (Either ResponseError resp))
-> Maybe (Handler (RequestMessage m req resp))
forall m rm req resp newReqParams newReqBody.
(Show m, Show rm, Show req, Show newReqParams, Show newReqBody,
HasTracing req) =>
(ResponseMessage resp -> FromServerMessage)
-> (RequestMessage rm newReqParams newReqBody -> FromServerMessage)
-> (LspFuncs Config
-> IdeState
-> req
-> IO (Either ResponseError resp, Maybe (rm, newReqParams)))
-> Maybe (Handler (RequestMessage m req resp))
withInitialize :: (LspFuncs Config -> IdeState -> InitializeParams -> IO ())
-> Maybe (Handler InitializeRequest)
withResponseAndRequest :: forall m rm req resp newReqParams newReqBody.
(Show m, Show rm, Show req, Show newReqParams, Show newReqBody,
HasTracing req) =>
(ResponseMessage resp -> FromServerMessage)
-> (RequestMessage rm newReqParams newReqBody -> FromServerMessage)
-> (LspFuncs Config
-> IdeState
-> req
-> IO (Either ResponseError resp, Maybe (rm, newReqParams)))
-> Maybe (Handler (RequestMessage m req resp))
withNotification :: forall m req.
(Show m, Show req, HasTracing req) =>
Maybe (Handler (NotificationMessage m req))
-> (LspFuncs Config -> IdeState -> req -> IO ())
-> Maybe (Handler (NotificationMessage m req))
withResponse :: forall m req resp.
(Show m, Show req, HasTracing req) =>
(ResponseMessage resp -> FromServerMessage)
-> (LspFuncs Config
-> IdeState -> req -> IO (Either ResponseError resp))
-> Maybe (Handler (RequestMessage m req resp))
$sel:withInitialize:WithMessage :: forall c.
WithMessage c
-> (LspFuncs c -> IdeState -> InitializeParams -> IO ())
-> Maybe (Handler InitializeRequest)
$sel:withResponseAndRequest:WithMessage :: forall c.
WithMessage c
-> forall m rm req resp newReqParams newReqBody.
(Show m, Show rm, Show req, Show newReqParams, Show newReqBody,
HasTracing req) =>
(ResponseMessage resp -> FromServerMessage)
-> (RequestMessage rm newReqParams newReqBody -> FromServerMessage)
-> (LspFuncs c
-> IdeState
-> req
-> IO (Either ResponseError resp, Maybe (rm, newReqParams)))
-> Maybe (Handler (RequestMessage m req resp))
$sel:withNotification:WithMessage :: forall c.
WithMessage c
-> forall m req.
(Show m, Show req, HasTracing req) =>
Maybe (Handler (NotificationMessage m req))
-> (LspFuncs c -> IdeState -> req -> IO ())
-> Maybe (Handler (NotificationMessage m req))
$sel:withResponse:WithMessage :: forall c.
WithMessage c
-> forall m req resp.
(Show m, Show req, HasTracing req) =>
(ResponseMessage resp -> FromServerMessage)
-> (LspFuncs c
-> IdeState -> req -> IO (Either ResponseError resp))
-> Maybe (Handler (RequestMessage m req resp))
..} Handlers
x -> Handlers -> IO Handlers
forall (m :: * -> *) a. Monad m => a -> m a
return Handlers
x
{ codeLensHandler :: Maybe (Handler CodeLensRequest)
LSP.codeLensHandler
= (ResponseMessage (List CodeLens) -> FromServerMessage)
-> (LspFuncs Config
-> IdeState
-> CodeLensParams
-> IO (Either ResponseError (List CodeLens)))
-> Maybe (Handler CodeLensRequest)
forall m req resp.
(Show m, Show req, HasTracing req) =>
(ResponseMessage resp -> FromServerMessage)
-> (LspFuncs Config
-> IdeState -> req -> IO (Either ResponseError resp))
-> Maybe (Handler (RequestMessage m req resp))
withResponse ResponseMessage (List CodeLens) -> FromServerMessage
RspCodeLens ([(PluginId, CodeLensProvider IdeState)]
-> LspFuncs Config
-> IdeState
-> CodeLensParams
-> IO (Either ResponseError (List CodeLens))
makeCodeLens [(PluginId, CodeLensProvider IdeState)]
cas)
}
makeCodeLens :: [(PluginId, CodeLensProvider IdeState)]
-> LSP.LspFuncs Config
-> IdeState
-> CodeLensParams
-> IO (Either ResponseError (List CodeLens))
makeCodeLens :: [(PluginId, CodeLensProvider IdeState)]
-> LspFuncs Config
-> IdeState
-> CodeLensParams
-> IO (Either ResponseError (List CodeLens))
makeCodeLens [(PluginId, CodeLensProvider IdeState)]
cas LspFuncs Config
lf IdeState
ideState CodeLensParams
params = do
Logger -> Text -> IO ()
logDebug (IdeState -> Logger
ideLogger IdeState
ideState) Text
"Plugin.makeCodeLens (ideLogger)"
let
makeLens :: (PluginId,
LspFuncs Config
-> IdeState
-> PluginId
-> CodeLensParams
-> IO (Either a (List a)))
-> IO (PluginId, Either a (List a))
makeLens (PluginId
pid, LspFuncs Config
-> IdeState -> PluginId -> CodeLensParams -> IO (Either a (List a))
provider) = do
PluginConfig
pluginConfig <- LspFuncs Config -> PluginId -> IO PluginConfig
getPluginConfig LspFuncs Config
lf PluginId
pid
Either a (List a)
r <- if PluginConfig -> (PluginConfig -> Bool) -> Bool
pluginEnabled PluginConfig
pluginConfig PluginConfig -> Bool
plcCodeLensOn
then PluginId
-> ByteString -> IO (Either a (List a)) -> IO (Either a (List a))
forall a. PluginId -> ByteString -> IO a -> IO a
otTracedProvider PluginId
pid ByteString
"codeLens" (IO (Either a (List a)) -> IO (Either a (List a)))
-> IO (Either a (List a)) -> IO (Either a (List a))
forall a b. (a -> b) -> a -> b
$ LspFuncs Config
-> IdeState -> PluginId -> CodeLensParams -> IO (Either a (List a))
provider LspFuncs Config
lf IdeState
ideState PluginId
pid CodeLensParams
params
else Either a (List a) -> IO (Either a (List a))
forall (m :: * -> *) a. Monad m => a -> m a
return (Either a (List a) -> IO (Either a (List a)))
-> Either a (List a) -> IO (Either a (List a))
forall a b. (a -> b) -> a -> b
$ List a -> Either a (List a)
forall a b. b -> Either a b
Right ([a] -> List a
forall a. [a] -> List a
List [])
(PluginId, Either a (List a)) -> IO (PluginId, Either a (List a))
forall (m :: * -> *) a. Monad m => a -> m a
return (PluginId
pid, Either a (List a)
r)
breakdown :: [(PluginId, Either ResponseError a)] -> ([(PluginId, ResponseError)], [(PluginId, a)])
breakdown :: [(PluginId, Either ResponseError a)]
-> ([(PluginId, ResponseError)], [(PluginId, a)])
breakdown [(PluginId, Either ResponseError a)]
ls = (((PluginId, Either ResponseError a) -> [(PluginId, ResponseError)])
-> [(PluginId, Either ResponseError a)]
-> [(PluginId, ResponseError)]
forall (t :: * -> *) a b. Foldable t => (a -> [b]) -> t a -> [b]
concatMap (PluginId, Either ResponseError a) -> [(PluginId, ResponseError)]
forall a b b. (a, Either b b) -> [(a, b)]
doOneLeft [(PluginId, Either ResponseError a)]
ls, ((PluginId, Either ResponseError a) -> [(PluginId, a)])
-> [(PluginId, Either ResponseError a)] -> [(PluginId, a)]
forall (t :: * -> *) a b. Foldable t => (a -> [b]) -> t a -> [b]
concatMap (PluginId, Either ResponseError a) -> [(PluginId, a)]
forall a a b. (a, Either a b) -> [(a, b)]
doOneRight [(PluginId, Either ResponseError a)]
ls)
where
doOneLeft :: (a, Either b b) -> [(a, b)]
doOneLeft (a
pid, Left b
err) = [(a
pid,b
err)]
doOneLeft (a
_, Right b
_) = []
doOneRight :: (a, Either a b) -> [(a, b)]
doOneRight (a
pid, Right b
a) = [(a
pid,b
a)]
doOneRight (a
_, Left a
_) = []
[(PluginId, Either ResponseError (List CodeLens))]
r <- ((PluginId, CodeLensProvider IdeState)
-> IO (PluginId, Either ResponseError (List CodeLens)))
-> [(PluginId, CodeLensProvider IdeState)]
-> IO [(PluginId, Either ResponseError (List CodeLens))]
forall (t :: * -> *) a b.
Traversable t =>
(a -> IO b) -> t a -> IO (t b)
mapConcurrently (PluginId, CodeLensProvider IdeState)
-> IO (PluginId, Either ResponseError (List CodeLens))
forall a a.
(PluginId,
LspFuncs Config
-> IdeState
-> PluginId
-> CodeLensParams
-> IO (Either a (List a)))
-> IO (PluginId, Either a (List a))
makeLens [(PluginId, CodeLensProvider IdeState)]
cas
case [(PluginId, Either ResponseError (List CodeLens))]
-> ([(PluginId, ResponseError)], [(PluginId, List CodeLens)])
forall a.
[(PluginId, Either ResponseError a)]
-> ([(PluginId, ResponseError)], [(PluginId, a)])
breakdown [(PluginId, Either ResponseError (List CodeLens))]
r of
([],[]) -> Either ResponseError (List CodeLens)
-> IO (Either ResponseError (List CodeLens))
forall (m :: * -> *) a. Monad m => a -> m a
return (Either ResponseError (List CodeLens)
-> IO (Either ResponseError (List CodeLens)))
-> Either ResponseError (List CodeLens)
-> IO (Either ResponseError (List CodeLens))
forall a b. (a -> b) -> a -> b
$ List CodeLens -> Either ResponseError (List CodeLens)
forall a b. b -> Either a b
Right (List CodeLens -> Either ResponseError (List CodeLens))
-> List CodeLens -> Either ResponseError (List CodeLens)
forall a b. (a -> b) -> a -> b
$ [CodeLens] -> List CodeLens
forall a. [a] -> List a
List []
([(PluginId, ResponseError)]
es,[]) -> Either ResponseError (List CodeLens)
-> IO (Either ResponseError (List CodeLens))
forall (m :: * -> *) a. Monad m => a -> m a
return (Either ResponseError (List CodeLens)
-> IO (Either ResponseError (List CodeLens)))
-> Either ResponseError (List CodeLens)
-> IO (Either ResponseError (List CodeLens))
forall a b. (a -> b) -> a -> b
$ ResponseError -> Either ResponseError (List CodeLens)
forall a b. a -> Either a b
Left (ResponseError -> Either ResponseError (List CodeLens))
-> ResponseError -> Either ResponseError (List CodeLens)
forall a b. (a -> b) -> a -> b
$ ErrorCode -> Text -> Maybe Value -> ResponseError
ResponseError ErrorCode
InternalError (String -> Text
T.pack (String -> Text) -> String -> Text
forall a b. (a -> b) -> a -> b
$ String
"codeLens failed:" String -> String -> String
forall a. [a] -> [a] -> [a]
++ [(PluginId, ResponseError)] -> String
forall a. Show a => a -> String
show [(PluginId, ResponseError)]
es) Maybe Value
forall a. Maybe a
Nothing
([(PluginId, ResponseError)]
_,[(PluginId, List CodeLens)]
rs) -> Either ResponseError (List CodeLens)
-> IO (Either ResponseError (List CodeLens))
forall (m :: * -> *) a. Monad m => a -> m a
return (Either ResponseError (List CodeLens)
-> IO (Either ResponseError (List CodeLens)))
-> Either ResponseError (List CodeLens)
-> IO (Either ResponseError (List CodeLens))
forall a b. (a -> b) -> a -> b
$ List CodeLens -> Either ResponseError (List CodeLens)
forall a b. b -> Either a b
Right (List CodeLens -> Either ResponseError (List CodeLens))
-> List CodeLens -> Either ResponseError (List CodeLens)
forall a b. (a -> b) -> a -> b
$ [CodeLens] -> List CodeLens
forall a. [a] -> List a
List (((PluginId, List CodeLens) -> [CodeLens])
-> [(PluginId, List CodeLens)] -> [CodeLens]
forall (t :: * -> *) a b. Foldable t => (a -> [b]) -> t a -> [b]
concatMap (\(PluginId
_,List [CodeLens]
cs) -> [CodeLens]
cs) [(PluginId, List CodeLens)]
rs)
executeCommandPlugins :: [(PluginId, [PluginCommand IdeState])] -> Plugin Config
executeCommandPlugins :: [(PluginId, [PluginCommand IdeState])] -> Plugin Config
executeCommandPlugins [(PluginId, [PluginCommand IdeState])]
ecs = Rules () -> PartialHandlers Config -> Plugin Config
forall c. Rules () -> PartialHandlers c -> Plugin c
Plugin Rules ()
forall a. Monoid a => a
mempty ([(PluginId, [PluginCommand IdeState])] -> PartialHandlers Config
executeCommandHandlers [(PluginId, [PluginCommand IdeState])]
ecs)
executeCommandHandlers :: [(PluginId, [PluginCommand IdeState])] -> PartialHandlers Config
executeCommandHandlers :: [(PluginId, [PluginCommand IdeState])] -> PartialHandlers Config
executeCommandHandlers [(PluginId, [PluginCommand IdeState])]
ecs = (WithMessage Config -> Handlers -> IO Handlers)
-> PartialHandlers Config
forall c.
(WithMessage c -> Handlers -> IO Handlers) -> PartialHandlers c
PartialHandlers ((WithMessage Config -> Handlers -> IO Handlers)
-> PartialHandlers Config)
-> (WithMessage Config -> Handlers -> IO Handlers)
-> PartialHandlers Config
forall a b. (a -> b) -> a -> b
$ \WithMessage{(LspFuncs Config -> IdeState -> InitializeParams -> IO ())
-> Maybe (Handler InitializeRequest)
forall m req.
(Show m, Show req, HasTracing req) =>
Maybe (Handler (NotificationMessage m req))
-> (LspFuncs Config -> IdeState -> req -> IO ())
-> Maybe (Handler (NotificationMessage m req))
forall m req resp.
(Show m, Show req, HasTracing req) =>
(ResponseMessage resp -> FromServerMessage)
-> (LspFuncs Config
-> IdeState -> req -> IO (Either ResponseError resp))
-> Maybe (Handler (RequestMessage m req resp))
forall m rm req resp newReqParams newReqBody.
(Show m, Show rm, Show req, Show newReqParams, Show newReqBody,
HasTracing req) =>
(ResponseMessage resp -> FromServerMessage)
-> (RequestMessage rm newReqParams newReqBody -> FromServerMessage)
-> (LspFuncs Config
-> IdeState
-> req
-> IO (Either ResponseError resp, Maybe (rm, newReqParams)))
-> Maybe (Handler (RequestMessage m req resp))
withInitialize :: (LspFuncs Config -> IdeState -> InitializeParams -> IO ())
-> Maybe (Handler InitializeRequest)
withResponseAndRequest :: forall m rm req resp newReqParams newReqBody.
(Show m, Show rm, Show req, Show newReqParams, Show newReqBody,
HasTracing req) =>
(ResponseMessage resp -> FromServerMessage)
-> (RequestMessage rm newReqParams newReqBody -> FromServerMessage)
-> (LspFuncs Config
-> IdeState
-> req
-> IO (Either ResponseError resp, Maybe (rm, newReqParams)))
-> Maybe (Handler (RequestMessage m req resp))
withNotification :: forall m req.
(Show m, Show req, HasTracing req) =>
Maybe (Handler (NotificationMessage m req))
-> (LspFuncs Config -> IdeState -> req -> IO ())
-> Maybe (Handler (NotificationMessage m req))
withResponse :: forall m req resp.
(Show m, Show req, HasTracing req) =>
(ResponseMessage resp -> FromServerMessage)
-> (LspFuncs Config
-> IdeState -> req -> IO (Either ResponseError resp))
-> Maybe (Handler (RequestMessage m req resp))
$sel:withInitialize:WithMessage :: forall c.
WithMessage c
-> (LspFuncs c -> IdeState -> InitializeParams -> IO ())
-> Maybe (Handler InitializeRequest)
$sel:withResponseAndRequest:WithMessage :: forall c.
WithMessage c
-> forall m rm req resp newReqParams newReqBody.
(Show m, Show rm, Show req, Show newReqParams, Show newReqBody,
HasTracing req) =>
(ResponseMessage resp -> FromServerMessage)
-> (RequestMessage rm newReqParams newReqBody -> FromServerMessage)
-> (LspFuncs c
-> IdeState
-> req
-> IO (Either ResponseError resp, Maybe (rm, newReqParams)))
-> Maybe (Handler (RequestMessage m req resp))
$sel:withNotification:WithMessage :: forall c.
WithMessage c
-> forall m req.
(Show m, Show req, HasTracing req) =>
Maybe (Handler (NotificationMessage m req))
-> (LspFuncs c -> IdeState -> req -> IO ())
-> Maybe (Handler (NotificationMessage m req))
$sel:withResponse:WithMessage :: forall c.
WithMessage c
-> forall m req resp.
(Show m, Show req, HasTracing req) =>
(ResponseMessage resp -> FromServerMessage)
-> (LspFuncs c
-> IdeState -> req -> IO (Either ResponseError resp))
-> Maybe (Handler (RequestMessage m req resp))
..} Handlers
x -> Handlers -> IO Handlers
forall (m :: * -> *) a. Monad m => a -> m a
return Handlers
x{
executeCommandHandler :: Maybe (Handler ExecuteCommandRequest)
LSP.executeCommandHandler = (ResponseMessage Value -> FromServerMessage)
-> (RequestMessage
ServerMethod
ApplyWorkspaceEditParams
ApplyWorkspaceEditResponseBody
-> FromServerMessage)
-> (LspFuncs Config
-> IdeState
-> ExecuteCommandParams
-> IO
(Either ResponseError Value,
Maybe (ServerMethod, ApplyWorkspaceEditParams)))
-> Maybe (Handler ExecuteCommandRequest)
forall m rm req resp newReqParams newReqBody.
(Show m, Show rm, Show req, Show newReqParams, Show newReqBody,
HasTracing req) =>
(ResponseMessage resp -> FromServerMessage)
-> (RequestMessage rm newReqParams newReqBody -> FromServerMessage)
-> (LspFuncs Config
-> IdeState
-> req
-> IO (Either ResponseError resp, Maybe (rm, newReqParams)))
-> Maybe (Handler (RequestMessage m req resp))
withResponseAndRequest ResponseMessage Value -> FromServerMessage
RspExecuteCommand RequestMessage
ServerMethod
ApplyWorkspaceEditParams
ApplyWorkspaceEditResponseBody
-> FromServerMessage
ReqApplyWorkspaceEdit ([(PluginId, [PluginCommand IdeState])]
-> LspFuncs Config
-> IdeState
-> ExecuteCommandParams
-> IO
(Either ResponseError Value,
Maybe (ServerMethod, ApplyWorkspaceEditParams))
makeExecuteCommands [(PluginId, [PluginCommand IdeState])]
ecs)
}
makeExecuteCommands :: [(PluginId, [PluginCommand IdeState])] -> LSP.LspFuncs Config -> ExecuteCommandProvider IdeState
makeExecuteCommands :: [(PluginId, [PluginCommand IdeState])]
-> LspFuncs Config
-> IdeState
-> ExecuteCommandParams
-> IO
(Either ResponseError Value,
Maybe (ServerMethod, ApplyWorkspaceEditParams))
makeExecuteCommands [(PluginId, [PluginCommand IdeState])]
ecs LspFuncs Config
lf IdeState
ide = (ExecuteCommandParams
-> IO
(Either ResponseError Value,
Maybe (ServerMethod, ApplyWorkspaceEditParams)))
-> ExecuteCommandParams
-> IO
(Either ResponseError Value,
Maybe (ServerMethod, ApplyWorkspaceEditParams))
forall a b.
(a -> IO (Either ResponseError Value, Maybe b))
-> a -> IO (Either ResponseError Value, Maybe b)
wrapUnhandledExceptions ((ExecuteCommandParams
-> IO
(Either ResponseError Value,
Maybe (ServerMethod, ApplyWorkspaceEditParams)))
-> ExecuteCommandParams
-> IO
(Either ResponseError Value,
Maybe (ServerMethod, ApplyWorkspaceEditParams)))
-> (ExecuteCommandParams
-> IO
(Either ResponseError Value,
Maybe (ServerMethod, ApplyWorkspaceEditParams)))
-> ExecuteCommandParams
-> IO
(Either ResponseError Value,
Maybe (ServerMethod, ApplyWorkspaceEditParams))
forall a b. (a -> b) -> a -> b
$ do
let
pluginMap :: Map PluginId [PluginCommand IdeState]
pluginMap = [(PluginId, [PluginCommand IdeState])]
-> Map PluginId [PluginCommand IdeState]
forall k a. Ord k => [(k, a)] -> Map k a
Map.fromList [(PluginId, [PluginCommand IdeState])]
ecs
parseCmdId :: T.Text -> Maybe (PluginId, CommandId)
parseCmdId :: Text -> Maybe (PluginId, CommandId)
parseCmdId Text
x = case Text -> Text -> [Text]
T.splitOn Text
":" Text
x of
[Text
plugin, Text
command] -> (PluginId, CommandId) -> Maybe (PluginId, CommandId)
forall a. a -> Maybe a
Just (Text -> PluginId
PluginId Text
plugin, Text -> CommandId
CommandId Text
command)
[Text
_, Text
plugin, Text
command] -> (PluginId, CommandId) -> Maybe (PluginId, CommandId)
forall a. a -> Maybe a
Just (Text -> PluginId
PluginId Text
plugin, Text -> CommandId
CommandId Text
command)
[Text]
_ -> Maybe (PluginId, CommandId)
forall a. Maybe a
Nothing
execCmd :: ExecuteCommandParams -> IO (Either ResponseError J.Value, Maybe (ServerMethod, ApplyWorkspaceEditParams))
execCmd :: ExecuteCommandParams
-> IO
(Either ResponseError Value,
Maybe (ServerMethod, ApplyWorkspaceEditParams))
execCmd (ExecuteCommandParams Text
cmdId Maybe (List Value)
args Maybe ProgressToken
_) = do
let cmdParams :: J.Value
cmdParams :: Value
cmdParams = case Maybe (List Value)
args of
Just (J.List (Value
x:[Value]
_)) -> Value
x
Maybe (List Value)
_ -> Value
J.Null
case Text -> Maybe (PluginId, CommandId)
parseCmdId Text
cmdId of
Just (PluginId
"hls", CommandId
"fallbackCodeAction") ->
case Value -> Result FallbackCodeActionParams
forall a. FromJSON a => Value -> Result a
J.fromJSON Value
cmdParams of
J.Success (FallbackCodeActionParams Maybe WorkspaceEdit
mEdit Maybe Command
mCmd) -> do
Maybe WorkspaceEdit -> (WorkspaceEdit -> IO ()) -> IO ()
forall (t :: * -> *) (m :: * -> *) a b.
(Foldable t, Monad m) =>
t a -> (a -> m b) -> m ()
forM_ Maybe WorkspaceEdit
mEdit ((WorkspaceEdit -> IO ()) -> IO ())
-> (WorkspaceEdit -> IO ()) -> IO ()
forall a b. (a -> b) -> a -> b
$ \WorkspaceEdit
edit -> do
let eParams :: ApplyWorkspaceEditParams
eParams = WorkspaceEdit -> ApplyWorkspaceEditParams
J.ApplyWorkspaceEditParams WorkspaceEdit
edit
LspId
reqId <- LspFuncs Config -> IO LspId
forall c. LspFuncs c -> IO LspId
LSP.getNextReqId LspFuncs Config
lf
LspFuncs Config -> SendFunc
forall c. LspFuncs c -> SendFunc
LSP.sendFunc LspFuncs Config
lf SendFunc -> SendFunc
forall a b. (a -> b) -> a -> b
$ RequestMessage
ServerMethod
ApplyWorkspaceEditParams
ApplyWorkspaceEditResponseBody
-> FromServerMessage
ReqApplyWorkspaceEdit (RequestMessage
ServerMethod
ApplyWorkspaceEditParams
ApplyWorkspaceEditResponseBody
-> FromServerMessage)
-> RequestMessage
ServerMethod
ApplyWorkspaceEditParams
ApplyWorkspaceEditResponseBody
-> FromServerMessage
forall a b. (a -> b) -> a -> b
$ Text
-> LspId
-> ServerMethod
-> ApplyWorkspaceEditParams
-> RequestMessage
ServerMethod
ApplyWorkspaceEditParams
ApplyWorkspaceEditResponseBody
forall m req resp.
Text -> LspId -> m -> req -> RequestMessage m req resp
RequestMessage Text
"2.0" LspId
reqId ServerMethod
WorkspaceApplyEdit ApplyWorkspaceEditParams
eParams
case Maybe Command
mCmd of
Just (J.Command Text
_ Text
innerCmdId Maybe (List Value)
innerArgs)
-> ExecuteCommandParams
-> IO
(Either ResponseError Value,
Maybe (ServerMethod, ApplyWorkspaceEditParams))
execCmd (Text
-> Maybe (List Value)
-> Maybe ProgressToken
-> ExecuteCommandParams
ExecuteCommandParams Text
innerCmdId Maybe (List Value)
innerArgs Maybe ProgressToken
forall a. Maybe a
Nothing)
Maybe Command
Nothing -> (Either ResponseError Value,
Maybe (ServerMethod, ApplyWorkspaceEditParams))
-> IO
(Either ResponseError Value,
Maybe (ServerMethod, ApplyWorkspaceEditParams))
forall (m :: * -> *) a. Monad m => a -> m a
return (Value -> Either ResponseError Value
forall a b. b -> Either a b
Right Value
J.Null, Maybe (ServerMethod, ApplyWorkspaceEditParams)
forall a. Maybe a
Nothing)
J.Error String
_str -> (Either ResponseError Value,
Maybe (ServerMethod, ApplyWorkspaceEditParams))
-> IO
(Either ResponseError Value,
Maybe (ServerMethod, ApplyWorkspaceEditParams))
forall (m :: * -> *) a. Monad m => a -> m a
return (Value -> Either ResponseError Value
forall a b. b -> Either a b
Right Value
J.Null, Maybe (ServerMethod, ApplyWorkspaceEditParams)
forall a. Maybe a
Nothing)
Just (PluginId
plugin, CommandId
cmd) -> Map PluginId [PluginCommand IdeState]
-> LspFuncs Config
-> IdeState
-> PluginId
-> CommandId
-> Value
-> IO
(Either ResponseError Value,
Maybe (ServerMethod, ApplyWorkspaceEditParams))
runPluginCommand Map PluginId [PluginCommand IdeState]
pluginMap LspFuncs Config
lf IdeState
ide PluginId
plugin CommandId
cmd Value
cmdParams
Maybe (PluginId, CommandId)
_ -> (Either ResponseError Value,
Maybe (ServerMethod, ApplyWorkspaceEditParams))
-> IO
(Either ResponseError Value,
Maybe (ServerMethod, ApplyWorkspaceEditParams))
forall (m :: * -> *) a. Monad m => a -> m a
return (ResponseError -> Either ResponseError Value
forall a b. a -> Either a b
Left (ResponseError -> Either ResponseError Value)
-> ResponseError -> Either ResponseError Value
forall a b. (a -> b) -> a -> b
$ ErrorCode -> Text -> Maybe Value -> ResponseError
ResponseError ErrorCode
InvalidParams Text
"Invalid command identifier" Maybe Value
forall a. Maybe a
Nothing, Maybe (ServerMethod, ApplyWorkspaceEditParams)
forall a. Maybe a
Nothing)
ExecuteCommandParams
-> IO
(Either ResponseError Value,
Maybe (ServerMethod, ApplyWorkspaceEditParams))
execCmd
wrapUnhandledExceptions ::
(a -> IO (Either ResponseError J.Value, Maybe b)) ->
a -> IO (Either ResponseError J.Value, Maybe b)
wrapUnhandledExceptions :: (a -> IO (Either ResponseError Value, Maybe b))
-> a -> IO (Either ResponseError Value, Maybe b)
wrapUnhandledExceptions a -> IO (Either ResponseError Value, Maybe b)
action a
input =
IO (Either ResponseError Value, Maybe b)
-> (SomeException -> IO (Either ResponseError Value, Maybe b))
-> IO (Either ResponseError Value, Maybe b)
forall e a. Exception e => IO a -> (e -> IO a) -> IO a
catch (a -> IO (Either ResponseError Value, Maybe b)
action a
input) ((SomeException -> IO (Either ResponseError Value, Maybe b))
-> IO (Either ResponseError Value, Maybe b))
-> (SomeException -> IO (Either ResponseError Value, Maybe b))
-> IO (Either ResponseError Value, Maybe b)
forall a b. (a -> b) -> a -> b
$ \(SomeException
e::SomeException) -> do
let resp :: ResponseError
resp = ErrorCode -> Text -> Maybe Value -> ResponseError
ResponseError ErrorCode
InternalError (String -> Text
T.pack (String -> Text) -> String -> Text
forall a b. (a -> b) -> a -> b
$ SomeException -> String
forall a. Show a => a -> String
show SomeException
e) Maybe Value
forall a. Maybe a
Nothing
(Either ResponseError Value, Maybe b)
-> IO (Either ResponseError Value, Maybe b)
forall (m :: * -> *) a. Monad m => a -> m a
return (ResponseError -> Either ResponseError Value
forall a b. a -> Either a b
Left ResponseError
resp, Maybe b
forall a. Maybe a
Nothing)
runPluginCommand :: Map.Map PluginId [PluginCommand IdeState]
-> LSP.LspFuncs Config
-> IdeState
-> PluginId
-> CommandId
-> J.Value
-> IO (Either ResponseError J.Value,
Maybe (ServerMethod, ApplyWorkspaceEditParams))
runPluginCommand :: Map PluginId [PluginCommand IdeState]
-> LspFuncs Config
-> IdeState
-> PluginId
-> CommandId
-> Value
-> IO
(Either ResponseError Value,
Maybe (ServerMethod, ApplyWorkspaceEditParams))
runPluginCommand Map PluginId [PluginCommand IdeState]
m LspFuncs Config
lf IdeState
ide p :: PluginId
p@(PluginId Text
p') com :: CommandId
com@(CommandId Text
com') Value
arg =
case PluginId
-> Map PluginId [PluginCommand IdeState]
-> Maybe [PluginCommand IdeState]
forall k a. Ord k => k -> Map k a -> Maybe a
Map.lookup PluginId
p Map PluginId [PluginCommand IdeState]
m of
Maybe [PluginCommand IdeState]
Nothing -> (Either ResponseError Value,
Maybe (ServerMethod, ApplyWorkspaceEditParams))
-> IO
(Either ResponseError Value,
Maybe (ServerMethod, ApplyWorkspaceEditParams))
forall (m :: * -> *) a. Monad m => a -> m a
return
(ResponseError -> Either ResponseError Value
forall a b. a -> Either a b
Left (ResponseError -> Either ResponseError Value)
-> ResponseError -> Either ResponseError Value
forall a b. (a -> b) -> a -> b
$ ErrorCode -> Text -> Maybe Value -> ResponseError
ResponseError ErrorCode
InvalidRequest (Text
"Plugin " Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
p' Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
" doesn't exist") Maybe Value
forall a. Maybe a
Nothing, Maybe (ServerMethod, ApplyWorkspaceEditParams)
forall a. Maybe a
Nothing)
Just [PluginCommand IdeState]
xs -> case (PluginCommand IdeState -> Bool)
-> [PluginCommand IdeState] -> Maybe (PluginCommand IdeState)
forall (t :: * -> *) a. Foldable t => (a -> Bool) -> t a -> Maybe a
List.find ((CommandId
com CommandId -> CommandId -> Bool
forall a. Eq a => a -> a -> Bool
==) (CommandId -> Bool)
-> (PluginCommand IdeState -> CommandId)
-> PluginCommand IdeState
-> Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. PluginCommand IdeState -> CommandId
forall ideState. PluginCommand ideState -> CommandId
commandId) [PluginCommand IdeState]
xs of
Maybe (PluginCommand IdeState)
Nothing -> (Either ResponseError Value,
Maybe (ServerMethod, ApplyWorkspaceEditParams))
-> IO
(Either ResponseError Value,
Maybe (ServerMethod, ApplyWorkspaceEditParams))
forall (m :: * -> *) a. Monad m => a -> m a
return (ResponseError -> Either ResponseError Value
forall a b. a -> Either a b
Left (ResponseError -> Either ResponseError Value)
-> ResponseError -> Either ResponseError Value
forall a b. (a -> b) -> a -> b
$
ErrorCode -> Text -> Maybe Value -> ResponseError
ResponseError ErrorCode
InvalidRequest (Text
"Command " Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
com' Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
" isn't defined for plugin " Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
p'
Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
". Legal commands are: " Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> String -> Text
T.pack([CommandId] -> String
forall a. Show a => a -> String
show ([CommandId] -> String) -> [CommandId] -> String
forall a b. (a -> b) -> a -> b
$ (PluginCommand IdeState -> CommandId)
-> [PluginCommand IdeState] -> [CommandId]
forall a b. (a -> b) -> [a] -> [b]
map PluginCommand IdeState -> CommandId
forall ideState. PluginCommand ideState -> CommandId
commandId [PluginCommand IdeState]
xs)) Maybe Value
forall a. Maybe a
Nothing, Maybe (ServerMethod, ApplyWorkspaceEditParams)
forall a. Maybe a
Nothing)
Just (PluginCommand CommandId
_ Text
_ CommandFunction IdeState a
f) -> case Value -> Result a
forall a. FromJSON a => Value -> Result a
J.fromJSON Value
arg of
J.Error String
err -> (Either ResponseError Value,
Maybe (ServerMethod, ApplyWorkspaceEditParams))
-> IO
(Either ResponseError Value,
Maybe (ServerMethod, ApplyWorkspaceEditParams))
forall (m :: * -> *) a. Monad m => a -> m a
return (ResponseError -> Either ResponseError Value
forall a b. a -> Either a b
Left (ResponseError -> Either ResponseError Value)
-> ResponseError -> Either ResponseError Value
forall a b. (a -> b) -> a -> b
$
ErrorCode -> Text -> Maybe Value -> ResponseError
ResponseError ErrorCode
InvalidParams (Text
"error while parsing args for " Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
com' Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
" in plugin " Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
p'
Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
": " Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> String -> Text
T.pack String
err
Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
"\narg = " Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> String -> Text
T.pack (Value -> String
forall a. Show a => a -> String
show Value
arg)) Maybe Value
forall a. Maybe a
Nothing, Maybe (ServerMethod, ApplyWorkspaceEditParams)
forall a. Maybe a
Nothing)
J.Success a
a -> CommandFunction IdeState a
f LspFuncs Config
lf IdeState
ide a
a
mkLspCommand :: PluginId -> CommandId -> T.Text -> Maybe [J.Value] -> IO Command
mkLspCommand :: PluginId -> CommandId -> Text -> Maybe [Value] -> IO Command
mkLspCommand PluginId
plid CommandId
cn Text
title Maybe [Value]
args' = do
Text
pid <- String -> Text
T.pack (String -> Text) -> (Int -> String) -> Int -> Text
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Int -> String
forall a. Show a => a -> String
show (Int -> Text) -> IO Int -> IO Text
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> IO Int
getProcessID
let cmdId :: Text
cmdId = Text -> PluginId -> CommandId -> Text
mkLspCmdId Text
pid PluginId
plid CommandId
cn
let args :: Maybe (List Value)
args = [Value] -> List Value
forall a. [a] -> List a
List ([Value] -> List Value) -> Maybe [Value] -> Maybe (List Value)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Maybe [Value]
args'
Command -> IO Command
forall (m :: * -> *) a. Monad m => a -> m a
return (Command -> IO Command) -> Command -> IO Command
forall a b. (a -> b) -> a -> b
$ Text -> Text -> Maybe (List Value) -> Command
Command Text
title Text
cmdId Maybe (List Value)
args
mkLspCmdId :: T.Text -> PluginId -> CommandId -> T.Text
mkLspCmdId :: Text -> PluginId -> CommandId -> Text
mkLspCmdId Text
pid (PluginId Text
plid) (CommandId Text
cid)
= Text
pid Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
":" Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
plid Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
":" Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
cid
hoverPlugins :: [(PluginId, HoverProvider IdeState)] -> Plugin Config
hoverPlugins :: [(PluginId, HoverProvider IdeState)] -> Plugin Config
hoverPlugins [(PluginId, HoverProvider IdeState)]
hs = Rules () -> PartialHandlers Config -> Plugin Config
forall c. Rules () -> PartialHandlers c -> Plugin c
Plugin Rules ()
hoverRules ([(PluginId, HoverProvider IdeState)] -> PartialHandlers Config
hoverHandlers [(PluginId, HoverProvider IdeState)]
hs)
hoverRules :: Rules ()
hoverRules :: Rules ()
hoverRules = Rules ()
forall a. Monoid a => a
mempty
hoverHandlers :: [(PluginId, HoverProvider IdeState)] -> PartialHandlers Config
hoverHandlers :: [(PluginId, HoverProvider IdeState)] -> PartialHandlers Config
hoverHandlers [(PluginId, HoverProvider IdeState)]
hps = (WithMessage Config -> Handlers -> IO Handlers)
-> PartialHandlers Config
forall c.
(WithMessage c -> Handlers -> IO Handlers) -> PartialHandlers c
PartialHandlers ((WithMessage Config -> Handlers -> IO Handlers)
-> PartialHandlers Config)
-> (WithMessage Config -> Handlers -> IO Handlers)
-> PartialHandlers Config
forall a b. (a -> b) -> a -> b
$ \WithMessage{(LspFuncs Config -> IdeState -> InitializeParams -> IO ())
-> Maybe (Handler InitializeRequest)
forall m req.
(Show m, Show req, HasTracing req) =>
Maybe (Handler (NotificationMessage m req))
-> (LspFuncs Config -> IdeState -> req -> IO ())
-> Maybe (Handler (NotificationMessage m req))
forall m req resp.
(Show m, Show req, HasTracing req) =>
(ResponseMessage resp -> FromServerMessage)
-> (LspFuncs Config
-> IdeState -> req -> IO (Either ResponseError resp))
-> Maybe (Handler (RequestMessage m req resp))
forall m rm req resp newReqParams newReqBody.
(Show m, Show rm, Show req, Show newReqParams, Show newReqBody,
HasTracing req) =>
(ResponseMessage resp -> FromServerMessage)
-> (RequestMessage rm newReqParams newReqBody -> FromServerMessage)
-> (LspFuncs Config
-> IdeState
-> req
-> IO (Either ResponseError resp, Maybe (rm, newReqParams)))
-> Maybe (Handler (RequestMessage m req resp))
withInitialize :: (LspFuncs Config -> IdeState -> InitializeParams -> IO ())
-> Maybe (Handler InitializeRequest)
withResponseAndRequest :: forall m rm req resp newReqParams newReqBody.
(Show m, Show rm, Show req, Show newReqParams, Show newReqBody,
HasTracing req) =>
(ResponseMessage resp -> FromServerMessage)
-> (RequestMessage rm newReqParams newReqBody -> FromServerMessage)
-> (LspFuncs Config
-> IdeState
-> req
-> IO (Either ResponseError resp, Maybe (rm, newReqParams)))
-> Maybe (Handler (RequestMessage m req resp))
withNotification :: forall m req.
(Show m, Show req, HasTracing req) =>
Maybe (Handler (NotificationMessage m req))
-> (LspFuncs Config -> IdeState -> req -> IO ())
-> Maybe (Handler (NotificationMessage m req))
withResponse :: forall m req resp.
(Show m, Show req, HasTracing req) =>
(ResponseMessage resp -> FromServerMessage)
-> (LspFuncs Config
-> IdeState -> req -> IO (Either ResponseError resp))
-> Maybe (Handler (RequestMessage m req resp))
$sel:withInitialize:WithMessage :: forall c.
WithMessage c
-> (LspFuncs c -> IdeState -> InitializeParams -> IO ())
-> Maybe (Handler InitializeRequest)
$sel:withResponseAndRequest:WithMessage :: forall c.
WithMessage c
-> forall m rm req resp newReqParams newReqBody.
(Show m, Show rm, Show req, Show newReqParams, Show newReqBody,
HasTracing req) =>
(ResponseMessage resp -> FromServerMessage)
-> (RequestMessage rm newReqParams newReqBody -> FromServerMessage)
-> (LspFuncs c
-> IdeState
-> req
-> IO (Either ResponseError resp, Maybe (rm, newReqParams)))
-> Maybe (Handler (RequestMessage m req resp))
$sel:withNotification:WithMessage :: forall c.
WithMessage c
-> forall m req.
(Show m, Show req, HasTracing req) =>
Maybe (Handler (NotificationMessage m req))
-> (LspFuncs c -> IdeState -> req -> IO ())
-> Maybe (Handler (NotificationMessage m req))
$sel:withResponse:WithMessage :: forall c.
WithMessage c
-> forall m req resp.
(Show m, Show req, HasTracing req) =>
(ResponseMessage resp -> FromServerMessage)
-> (LspFuncs c
-> IdeState -> req -> IO (Either ResponseError resp))
-> Maybe (Handler (RequestMessage m req resp))
..} Handlers
x ->
Handlers -> IO Handlers
forall (m :: * -> *) a. Monad m => a -> m a
return Handlers
x{hoverHandler :: Maybe (Handler HoverRequest)
LSP.hoverHandler = (ResponseMessage (Maybe Hover) -> FromServerMessage)
-> (LspFuncs Config -> HoverProvider IdeState)
-> Maybe (Handler HoverRequest)
forall m req resp.
(Show m, Show req, HasTracing req) =>
(ResponseMessage resp -> FromServerMessage)
-> (LspFuncs Config
-> IdeState -> req -> IO (Either ResponseError resp))
-> Maybe (Handler (RequestMessage m req resp))
withResponse ResponseMessage (Maybe Hover) -> FromServerMessage
RspHover ([(PluginId, HoverProvider IdeState)]
-> LspFuncs Config -> HoverProvider IdeState
makeHover [(PluginId, HoverProvider IdeState)]
hps)}
makeHover :: [(PluginId, HoverProvider IdeState)]
-> LSP.LspFuncs Config -> IdeState
-> TextDocumentPositionParams
-> IO (Either ResponseError (Maybe Hover))
makeHover :: [(PluginId, HoverProvider IdeState)]
-> LspFuncs Config -> HoverProvider IdeState
makeHover [(PluginId, HoverProvider IdeState)]
hps LspFuncs Config
lf IdeState
ideState TextDocumentPositionParams
params
= do
let
makeHover :: (PluginId,
IdeState -> TextDocumentPositionParams -> IO (Either a (Maybe a)))
-> IO (Either a (Maybe a))
makeHover(PluginId
pid,IdeState -> TextDocumentPositionParams -> IO (Either a (Maybe a))
p) = do
PluginConfig
pluginConfig <- LspFuncs Config -> PluginId -> IO PluginConfig
getPluginConfig LspFuncs Config
lf PluginId
pid
if PluginConfig -> (PluginConfig -> Bool) -> Bool
pluginEnabled PluginConfig
pluginConfig PluginConfig -> Bool
plcHoverOn
then PluginId
-> ByteString -> IO (Either a (Maybe a)) -> IO (Either a (Maybe a))
forall a. PluginId -> ByteString -> IO a -> IO a
otTracedProvider PluginId
pid ByteString
"hover" (IO (Either a (Maybe a)) -> IO (Either a (Maybe a)))
-> IO (Either a (Maybe a)) -> IO (Either a (Maybe a))
forall a b. (a -> b) -> a -> b
$ IdeState -> TextDocumentPositionParams -> IO (Either a (Maybe a))
p IdeState
ideState TextDocumentPositionParams
params
else Either a (Maybe a) -> IO (Either a (Maybe a))
forall (m :: * -> *) a. Monad m => a -> m a
return (Either a (Maybe a) -> IO (Either a (Maybe a)))
-> Either a (Maybe a) -> IO (Either a (Maybe a))
forall a b. (a -> b) -> a -> b
$ Maybe a -> Either a (Maybe a)
forall a b. b -> Either a b
Right Maybe a
forall a. Maybe a
Nothing
[Either ResponseError (Maybe Hover)]
mhs <- ((PluginId, HoverProvider IdeState)
-> IO (Either ResponseError (Maybe Hover)))
-> [(PluginId, HoverProvider IdeState)]
-> IO [Either ResponseError (Maybe Hover)]
forall (t :: * -> *) a b.
Traversable t =>
(a -> IO b) -> t a -> IO (t b)
mapConcurrently (PluginId, HoverProvider IdeState)
-> IO (Either ResponseError (Maybe Hover))
forall a a.
(PluginId,
IdeState -> TextDocumentPositionParams -> IO (Either a (Maybe a)))
-> IO (Either a (Maybe a))
makeHover [(PluginId, HoverProvider IdeState)]
hps
let hs :: [Hover]
hs = [Maybe Hover] -> [Hover]
forall a. [Maybe a] -> [a]
catMaybes ([Either ResponseError (Maybe Hover)] -> [Maybe Hover]
forall a b. [Either a b] -> [b]
rights [Either ResponseError (Maybe Hover)]
mhs)
r :: Maybe Range
r = [Range] -> Maybe Range
forall a. [a] -> Maybe a
listToMaybe ([Range] -> Maybe Range) -> [Range] -> Maybe Range
forall a b. (a -> b) -> a -> b
$ (Hover -> Maybe Range) -> [Hover] -> [Range]
forall a b. (a -> Maybe b) -> [a] -> [b]
mapMaybe (Hover -> Getting (Maybe Range) Hover (Maybe Range) -> Maybe Range
forall s a. s -> Getting a s a -> a
^. Getting (Maybe Range) Hover (Maybe Range)
forall s a. HasRange s a => Lens' s a
range) [Hover]
hs
h :: Maybe Hover
h = case (Hover -> HoverContents) -> [Hover] -> HoverContents
forall (t :: * -> *) m a.
(Foldable t, Monoid m) =>
(a -> m) -> t a -> m
foldMap (Hover -> Getting HoverContents Hover HoverContents -> HoverContents
forall s a. s -> Getting a s a -> a
^. Getting HoverContents Hover HoverContents
forall s a. HasContents s a => Lens' s a
contents) [Hover]
hs of
HoverContentsMS (List []) -> Maybe Hover
forall a. Maybe a
Nothing
HoverContents
hh -> Hover -> Maybe Hover
forall a. a -> Maybe a
Just (Hover -> Maybe Hover) -> Hover -> Maybe Hover
forall a b. (a -> b) -> a -> b
$ HoverContents -> Maybe Range -> Hover
Hover HoverContents
hh Maybe Range
r
Either ResponseError (Maybe Hover)
-> IO (Either ResponseError (Maybe Hover))
forall (m :: * -> *) a. Monad m => a -> m a
return (Either ResponseError (Maybe Hover)
-> IO (Either ResponseError (Maybe Hover)))
-> Either ResponseError (Maybe Hover)
-> IO (Either ResponseError (Maybe Hover))
forall a b. (a -> b) -> a -> b
$ Maybe Hover -> Either ResponseError (Maybe Hover)
forall a b. b -> Either a b
Right Maybe Hover
h
symbolsPlugins :: [(PluginId, SymbolsProvider IdeState)] -> Plugin Config
symbolsPlugins :: [(PluginId, SymbolsProvider IdeState)] -> Plugin Config
symbolsPlugins [(PluginId, SymbolsProvider IdeState)]
hs = Rules () -> PartialHandlers Config -> Plugin Config
forall c. Rules () -> PartialHandlers c -> Plugin c
Plugin Rules ()
symbolsRules ([(PluginId, SymbolsProvider IdeState)] -> PartialHandlers Config
symbolsHandlers [(PluginId, SymbolsProvider IdeState)]
hs)
symbolsRules :: Rules ()
symbolsRules :: Rules ()
symbolsRules = Rules ()
forall a. Monoid a => a
mempty
symbolsHandlers :: [(PluginId, SymbolsProvider IdeState)] -> PartialHandlers Config
symbolsHandlers :: [(PluginId, SymbolsProvider IdeState)] -> PartialHandlers Config
symbolsHandlers [(PluginId, SymbolsProvider IdeState)]
hps = (WithMessage Config -> Handlers -> IO Handlers)
-> PartialHandlers Config
forall c.
(WithMessage c -> Handlers -> IO Handlers) -> PartialHandlers c
PartialHandlers ((WithMessage Config -> Handlers -> IO Handlers)
-> PartialHandlers Config)
-> (WithMessage Config -> Handlers -> IO Handlers)
-> PartialHandlers Config
forall a b. (a -> b) -> a -> b
$ \WithMessage{(LspFuncs Config -> IdeState -> InitializeParams -> IO ())
-> Maybe (Handler InitializeRequest)
forall m req.
(Show m, Show req, HasTracing req) =>
Maybe (Handler (NotificationMessage m req))
-> (LspFuncs Config -> IdeState -> req -> IO ())
-> Maybe (Handler (NotificationMessage m req))
forall m req resp.
(Show m, Show req, HasTracing req) =>
(ResponseMessage resp -> FromServerMessage)
-> (LspFuncs Config
-> IdeState -> req -> IO (Either ResponseError resp))
-> Maybe (Handler (RequestMessage m req resp))
forall m rm req resp newReqParams newReqBody.
(Show m, Show rm, Show req, Show newReqParams, Show newReqBody,
HasTracing req) =>
(ResponseMessage resp -> FromServerMessage)
-> (RequestMessage rm newReqParams newReqBody -> FromServerMessage)
-> (LspFuncs Config
-> IdeState
-> req
-> IO (Either ResponseError resp, Maybe (rm, newReqParams)))
-> Maybe (Handler (RequestMessage m req resp))
withInitialize :: (LspFuncs Config -> IdeState -> InitializeParams -> IO ())
-> Maybe (Handler InitializeRequest)
withResponseAndRequest :: forall m rm req resp newReqParams newReqBody.
(Show m, Show rm, Show req, Show newReqParams, Show newReqBody,
HasTracing req) =>
(ResponseMessage resp -> FromServerMessage)
-> (RequestMessage rm newReqParams newReqBody -> FromServerMessage)
-> (LspFuncs Config
-> IdeState
-> req
-> IO (Either ResponseError resp, Maybe (rm, newReqParams)))
-> Maybe (Handler (RequestMessage m req resp))
withNotification :: forall m req.
(Show m, Show req, HasTracing req) =>
Maybe (Handler (NotificationMessage m req))
-> (LspFuncs Config -> IdeState -> req -> IO ())
-> Maybe (Handler (NotificationMessage m req))
withResponse :: forall m req resp.
(Show m, Show req, HasTracing req) =>
(ResponseMessage resp -> FromServerMessage)
-> (LspFuncs Config
-> IdeState -> req -> IO (Either ResponseError resp))
-> Maybe (Handler (RequestMessage m req resp))
$sel:withInitialize:WithMessage :: forall c.
WithMessage c
-> (LspFuncs c -> IdeState -> InitializeParams -> IO ())
-> Maybe (Handler InitializeRequest)
$sel:withResponseAndRequest:WithMessage :: forall c.
WithMessage c
-> forall m rm req resp newReqParams newReqBody.
(Show m, Show rm, Show req, Show newReqParams, Show newReqBody,
HasTracing req) =>
(ResponseMessage resp -> FromServerMessage)
-> (RequestMessage rm newReqParams newReqBody -> FromServerMessage)
-> (LspFuncs c
-> IdeState
-> req
-> IO (Either ResponseError resp, Maybe (rm, newReqParams)))
-> Maybe (Handler (RequestMessage m req resp))
$sel:withNotification:WithMessage :: forall c.
WithMessage c
-> forall m req.
(Show m, Show req, HasTracing req) =>
Maybe (Handler (NotificationMessage m req))
-> (LspFuncs c -> IdeState -> req -> IO ())
-> Maybe (Handler (NotificationMessage m req))
$sel:withResponse:WithMessage :: forall c.
WithMessage c
-> forall m req resp.
(Show m, Show req, HasTracing req) =>
(ResponseMessage resp -> FromServerMessage)
-> (LspFuncs c
-> IdeState -> req -> IO (Either ResponseError resp))
-> Maybe (Handler (RequestMessage m req resp))
..} Handlers
x ->
Handlers -> IO Handlers
forall (m :: * -> *) a. Monad m => a -> m a
return Handlers
x {documentSymbolHandler :: Maybe (Handler DocumentSymbolRequest)
LSP.documentSymbolHandler = (ResponseMessage DSResult -> FromServerMessage)
-> (LspFuncs Config
-> IdeState
-> DocumentSymbolParams
-> IO (Either ResponseError DSResult))
-> Maybe (Handler DocumentSymbolRequest)
forall m req resp.
(Show m, Show req, HasTracing req) =>
(ResponseMessage resp -> FromServerMessage)
-> (LspFuncs Config
-> IdeState -> req -> IO (Either ResponseError resp))
-> Maybe (Handler (RequestMessage m req resp))
withResponse ResponseMessage DSResult -> FromServerMessage
RspDocumentSymbols ([(PluginId, SymbolsProvider IdeState)]
-> LspFuncs Config
-> IdeState
-> DocumentSymbolParams
-> IO (Either ResponseError DSResult)
makeSymbols [(PluginId, SymbolsProvider IdeState)]
hps)}
makeSymbols :: [(PluginId, SymbolsProvider IdeState)]
-> LSP.LspFuncs Config
-> IdeState
-> DocumentSymbolParams
-> IO (Either ResponseError DSResult)
makeSymbols :: [(PluginId, SymbolsProvider IdeState)]
-> LspFuncs Config
-> IdeState
-> DocumentSymbolParams
-> IO (Either ResponseError DSResult)
makeSymbols [(PluginId, SymbolsProvider IdeState)]
sps LspFuncs Config
lf IdeState
ideState DocumentSymbolParams
params
= do
let uri' :: Uri
uri' = DocumentSymbolParams
params DocumentSymbolParams -> Getting Uri DocumentSymbolParams Uri -> Uri
forall s a. s -> Getting a s a -> a
^. (TextDocumentIdentifier -> Const Uri TextDocumentIdentifier)
-> DocumentSymbolParams -> Const Uri DocumentSymbolParams
forall s a. HasTextDocument s a => Lens' s a
textDocument ((TextDocumentIdentifier -> Const Uri TextDocumentIdentifier)
-> DocumentSymbolParams -> Const Uri DocumentSymbolParams)
-> ((Uri -> Const Uri Uri)
-> TextDocumentIdentifier -> Const Uri TextDocumentIdentifier)
-> Getting Uri DocumentSymbolParams Uri
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Uri -> Const Uri Uri)
-> TextDocumentIdentifier -> Const Uri TextDocumentIdentifier
forall s a. HasUri s a => Lens' s a
uri
(C.ClientCapabilities Maybe WorkspaceClientCapabilities
_ Maybe TextDocumentClientCapabilities
tdc Maybe WindowClientCapabilities
_ Maybe Object
_) = LspFuncs Config -> ClientCapabilities
forall c. LspFuncs c -> ClientCapabilities
LSP.clientCapabilities LspFuncs Config
lf
supportsHierarchy :: Bool
supportsHierarchy = Bool -> Maybe Bool
forall a. a -> Maybe a
Just Bool
True Maybe Bool -> Maybe Bool -> Bool
forall a. Eq a => a -> a -> Bool
== (Maybe TextDocumentClientCapabilities
tdc Maybe TextDocumentClientCapabilities
-> (TextDocumentClientCapabilities
-> Maybe DocumentSymbolClientCapabilities)
-> Maybe DocumentSymbolClientCapabilities
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= TextDocumentClientCapabilities
-> Maybe DocumentSymbolClientCapabilities
C._documentSymbol Maybe DocumentSymbolClientCapabilities
-> (DocumentSymbolClientCapabilities -> Maybe Bool) -> Maybe Bool
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= DocumentSymbolClientCapabilities -> Maybe Bool
C._hierarchicalDocumentSymbolSupport)
convertSymbols :: [DocumentSymbol] -> DSResult
convertSymbols :: [DocumentSymbol] -> DSResult
convertSymbols [DocumentSymbol]
symbs
| Bool
supportsHierarchy = List DocumentSymbol -> DSResult
DSDocumentSymbols (List DocumentSymbol -> DSResult)
-> List DocumentSymbol -> DSResult
forall a b. (a -> b) -> a -> b
$ [DocumentSymbol] -> List DocumentSymbol
forall a. [a] -> List a
List [DocumentSymbol]
symbs
| Bool
otherwise = List SymbolInformation -> DSResult
DSSymbolInformation ([SymbolInformation] -> List SymbolInformation
forall a. [a] -> List a
List ([SymbolInformation] -> List SymbolInformation)
-> [SymbolInformation] -> List SymbolInformation
forall a b. (a -> b) -> a -> b
$ (DocumentSymbol -> [SymbolInformation])
-> [DocumentSymbol] -> [SymbolInformation]
forall (t :: * -> *) a b. Foldable t => (a -> [b]) -> t a -> [b]
concatMap (Maybe Text -> DocumentSymbol -> [SymbolInformation]
go Maybe Text
forall a. Maybe a
Nothing) [DocumentSymbol]
symbs)
where
go :: Maybe T.Text -> DocumentSymbol -> [SymbolInformation]
go :: Maybe Text -> DocumentSymbol -> [SymbolInformation]
go Maybe Text
parent DocumentSymbol
ds =
let children' :: [SymbolInformation]
children' :: [SymbolInformation]
children' = (DocumentSymbol -> [SymbolInformation])
-> List DocumentSymbol -> [SymbolInformation]
forall (t :: * -> *) a b. Foldable t => (a -> [b]) -> t a -> [b]
concatMap (Maybe Text -> DocumentSymbol -> [SymbolInformation]
go (Text -> Maybe Text
forall a. a -> Maybe a
Just Text
name')) (List DocumentSymbol
-> Maybe (List DocumentSymbol) -> List DocumentSymbol
forall a. a -> Maybe a -> a
fromMaybe List DocumentSymbol
forall a. Monoid a => a
mempty (DocumentSymbol
ds DocumentSymbol
-> Getting
(Maybe (List DocumentSymbol))
DocumentSymbol
(Maybe (List DocumentSymbol))
-> Maybe (List DocumentSymbol)
forall s a. s -> Getting a s a -> a
^. Getting
(Maybe (List DocumentSymbol))
DocumentSymbol
(Maybe (List DocumentSymbol))
forall s a. HasChildren s a => Lens' s a
children))
loc :: Location
loc = Uri -> Range -> Location
Location Uri
uri' (DocumentSymbol
ds DocumentSymbol -> Getting Range DocumentSymbol Range -> Range
forall s a. s -> Getting a s a -> a
^. Getting Range DocumentSymbol Range
forall s a. HasRange s a => Lens' s a
range)
name' :: Text
name' = DocumentSymbol
ds DocumentSymbol -> Getting Text DocumentSymbol Text -> Text
forall s a. s -> Getting a s a -> a
^. Getting Text DocumentSymbol Text
forall s a. HasName s a => Lens' s a
name
si :: SymbolInformation
si = Text
-> SymbolKind
-> Maybe Bool
-> Location
-> Maybe Text
-> SymbolInformation
SymbolInformation Text
name' (DocumentSymbol
ds DocumentSymbol
-> Getting SymbolKind DocumentSymbol SymbolKind -> SymbolKind
forall s a. s -> Getting a s a -> a
^. Getting SymbolKind DocumentSymbol SymbolKind
forall s a. HasKind s a => Lens' s a
kind) (DocumentSymbol
ds DocumentSymbol
-> Getting (Maybe Bool) DocumentSymbol (Maybe Bool) -> Maybe Bool
forall s a. s -> Getting a s a -> a
^. Getting (Maybe Bool) DocumentSymbol (Maybe Bool)
forall s a. HasDeprecated s a => Lens' s a
deprecated) Location
loc Maybe Text
parent
in [SymbolInformation
si] [SymbolInformation] -> [SymbolInformation] -> [SymbolInformation]
forall a. Semigroup a => a -> a -> a
<> [SymbolInformation]
children'
makeSymbols :: (PluginId,
LspFuncs Config
-> IdeState -> DocumentSymbolParams -> IO (Either a [a]))
-> IO (Either a [a])
makeSymbols (PluginId
pid,LspFuncs Config
-> IdeState -> DocumentSymbolParams -> IO (Either a [a])
p) = do
PluginConfig
pluginConfig <- LspFuncs Config -> PluginId -> IO PluginConfig
getPluginConfig LspFuncs Config
lf PluginId
pid
if PluginConfig -> (PluginConfig -> Bool) -> Bool
pluginEnabled PluginConfig
pluginConfig PluginConfig -> Bool
plcSymbolsOn
then PluginId -> ByteString -> IO (Either a [a]) -> IO (Either a [a])
forall a. PluginId -> ByteString -> IO a -> IO a
otTracedProvider PluginId
pid ByteString
"symbols" (IO (Either a [a]) -> IO (Either a [a]))
-> IO (Either a [a]) -> IO (Either a [a])
forall a b. (a -> b) -> a -> b
$ LspFuncs Config
-> IdeState -> DocumentSymbolParams -> IO (Either a [a])
p LspFuncs Config
lf IdeState
ideState DocumentSymbolParams
params
else Either a [a] -> IO (Either a [a])
forall (m :: * -> *) a. Monad m => a -> m a
return (Either a [a] -> IO (Either a [a]))
-> Either a [a] -> IO (Either a [a])
forall a b. (a -> b) -> a -> b
$ [a] -> Either a [a]
forall a b. b -> Either a b
Right []
[Either ResponseError [DocumentSymbol]]
mhs <- ((PluginId, SymbolsProvider IdeState)
-> IO (Either ResponseError [DocumentSymbol]))
-> [(PluginId, SymbolsProvider IdeState)]
-> IO [Either ResponseError [DocumentSymbol]]
forall (t :: * -> *) a b.
Traversable t =>
(a -> IO b) -> t a -> IO (t b)
mapConcurrently (PluginId, SymbolsProvider IdeState)
-> IO (Either ResponseError [DocumentSymbol])
forall a a.
(PluginId,
LspFuncs Config
-> IdeState -> DocumentSymbolParams -> IO (Either a [a]))
-> IO (Either a [a])
makeSymbols [(PluginId, SymbolsProvider IdeState)]
sps
case [Either ResponseError [DocumentSymbol]] -> [[DocumentSymbol]]
forall a b. [Either a b] -> [b]
rights [Either ResponseError [DocumentSymbol]]
mhs of
[] -> Either ResponseError DSResult -> IO (Either ResponseError DSResult)
forall (m :: * -> *) a. Monad m => a -> m a
return (Either ResponseError DSResult
-> IO (Either ResponseError DSResult))
-> Either ResponseError DSResult
-> IO (Either ResponseError DSResult)
forall a b. (a -> b) -> a -> b
$ ResponseError -> Either ResponseError DSResult
forall a b. a -> Either a b
Left (ResponseError -> Either ResponseError DSResult)
-> ResponseError -> Either ResponseError DSResult
forall a b. (a -> b) -> a -> b
$ Text -> ResponseError
responseError (Text -> ResponseError) -> Text -> ResponseError
forall a b. (a -> b) -> a -> b
$ String -> Text
T.pack (String -> Text) -> String -> Text
forall a b. (a -> b) -> a -> b
$ [ResponseError] -> String
forall a. Show a => a -> String
show ([ResponseError] -> String) -> [ResponseError] -> String
forall a b. (a -> b) -> a -> b
$ [Either ResponseError [DocumentSymbol]] -> [ResponseError]
forall a b. [Either a b] -> [a]
lefts [Either ResponseError [DocumentSymbol]]
mhs
[[DocumentSymbol]]
hs -> Either ResponseError DSResult -> IO (Either ResponseError DSResult)
forall (m :: * -> *) a. Monad m => a -> m a
return (Either ResponseError DSResult
-> IO (Either ResponseError DSResult))
-> Either ResponseError DSResult
-> IO (Either ResponseError DSResult)
forall a b. (a -> b) -> a -> b
$ DSResult -> Either ResponseError DSResult
forall a b. b -> Either a b
Right (DSResult -> Either ResponseError DSResult)
-> DSResult -> Either ResponseError DSResult
forall a b. (a -> b) -> a -> b
$ [DocumentSymbol] -> DSResult
convertSymbols ([DocumentSymbol] -> DSResult) -> [DocumentSymbol] -> DSResult
forall a b. (a -> b) -> a -> b
$ [[DocumentSymbol]] -> [DocumentSymbol]
forall (t :: * -> *) a. Foldable t => t [a] -> [a]
concat [[DocumentSymbol]]
hs
renamePlugins :: [(PluginId, RenameProvider IdeState)] -> Plugin Config
renamePlugins :: [(PluginId, RenameProvider IdeState)] -> Plugin Config
renamePlugins [(PluginId, RenameProvider IdeState)]
providers = Rules () -> PartialHandlers Config -> Plugin Config
forall c. Rules () -> PartialHandlers c -> Plugin c
Plugin Rules ()
rules PartialHandlers Config
handlers
where
rules :: Rules ()
rules = Rules ()
forall a. Monoid a => a
mempty
handlers :: PartialHandlers Config
handlers = (WithMessage Config -> Handlers -> IO Handlers)
-> PartialHandlers Config
forall c.
(WithMessage c -> Handlers -> IO Handlers) -> PartialHandlers c
PartialHandlers ((WithMessage Config -> Handlers -> IO Handlers)
-> PartialHandlers Config)
-> (WithMessage Config -> Handlers -> IO Handlers)
-> PartialHandlers Config
forall a b. (a -> b) -> a -> b
$ \WithMessage{(LspFuncs Config -> IdeState -> InitializeParams -> IO ())
-> Maybe (Handler InitializeRequest)
forall m req.
(Show m, Show req, HasTracing req) =>
Maybe (Handler (NotificationMessage m req))
-> (LspFuncs Config -> IdeState -> req -> IO ())
-> Maybe (Handler (NotificationMessage m req))
forall m req resp.
(Show m, Show req, HasTracing req) =>
(ResponseMessage resp -> FromServerMessage)
-> (LspFuncs Config
-> IdeState -> req -> IO (Either ResponseError resp))
-> Maybe (Handler (RequestMessage m req resp))
forall m rm req resp newReqParams newReqBody.
(Show m, Show rm, Show req, Show newReqParams, Show newReqBody,
HasTracing req) =>
(ResponseMessage resp -> FromServerMessage)
-> (RequestMessage rm newReqParams newReqBody -> FromServerMessage)
-> (LspFuncs Config
-> IdeState
-> req
-> IO (Either ResponseError resp, Maybe (rm, newReqParams)))
-> Maybe (Handler (RequestMessage m req resp))
withInitialize :: (LspFuncs Config -> IdeState -> InitializeParams -> IO ())
-> Maybe (Handler InitializeRequest)
withResponseAndRequest :: forall m rm req resp newReqParams newReqBody.
(Show m, Show rm, Show req, Show newReqParams, Show newReqBody,
HasTracing req) =>
(ResponseMessage resp -> FromServerMessage)
-> (RequestMessage rm newReqParams newReqBody -> FromServerMessage)
-> (LspFuncs Config
-> IdeState
-> req
-> IO (Either ResponseError resp, Maybe (rm, newReqParams)))
-> Maybe (Handler (RequestMessage m req resp))
withNotification :: forall m req.
(Show m, Show req, HasTracing req) =>
Maybe (Handler (NotificationMessage m req))
-> (LspFuncs Config -> IdeState -> req -> IO ())
-> Maybe (Handler (NotificationMessage m req))
withResponse :: forall m req resp.
(Show m, Show req, HasTracing req) =>
(ResponseMessage resp -> FromServerMessage)
-> (LspFuncs Config
-> IdeState -> req -> IO (Either ResponseError resp))
-> Maybe (Handler (RequestMessage m req resp))
$sel:withInitialize:WithMessage :: forall c.
WithMessage c
-> (LspFuncs c -> IdeState -> InitializeParams -> IO ())
-> Maybe (Handler InitializeRequest)
$sel:withResponseAndRequest:WithMessage :: forall c.
WithMessage c
-> forall m rm req resp newReqParams newReqBody.
(Show m, Show rm, Show req, Show newReqParams, Show newReqBody,
HasTracing req) =>
(ResponseMessage resp -> FromServerMessage)
-> (RequestMessage rm newReqParams newReqBody -> FromServerMessage)
-> (LspFuncs c
-> IdeState
-> req
-> IO (Either ResponseError resp, Maybe (rm, newReqParams)))
-> Maybe (Handler (RequestMessage m req resp))
$sel:withNotification:WithMessage :: forall c.
WithMessage c
-> forall m req.
(Show m, Show req, HasTracing req) =>
Maybe (Handler (NotificationMessage m req))
-> (LspFuncs c -> IdeState -> req -> IO ())
-> Maybe (Handler (NotificationMessage m req))
$sel:withResponse:WithMessage :: forall c.
WithMessage c
-> forall m req resp.
(Show m, Show req, HasTracing req) =>
(ResponseMessage resp -> FromServerMessage)
-> (LspFuncs c
-> IdeState -> req -> IO (Either ResponseError resp))
-> Maybe (Handler (RequestMessage m req resp))
..} Handlers
x -> Handlers -> IO Handlers
forall (m :: * -> *) a. Monad m => a -> m a
return Handlers
x
{ renameHandler :: Maybe (Handler RenameRequest)
LSP.renameHandler = (ResponseMessage WorkspaceEdit -> FromServerMessage)
-> RenameProvider IdeState -> Maybe (Handler RenameRequest)
forall m req resp.
(Show m, Show req, HasTracing req) =>
(ResponseMessage resp -> FromServerMessage)
-> (LspFuncs Config
-> IdeState -> req -> IO (Either ResponseError resp))
-> Maybe (Handler (RequestMessage m req resp))
withResponse ResponseMessage WorkspaceEdit -> FromServerMessage
RspRename ([(PluginId, RenameProvider IdeState)] -> RenameProvider IdeState
renameWith [(PluginId, RenameProvider IdeState)]
providers)}
renameWith ::
[(PluginId, RenameProvider IdeState)] ->
LSP.LspFuncs Config ->
IdeState ->
RenameParams ->
IO (Either ResponseError WorkspaceEdit)
renameWith :: [(PluginId, RenameProvider IdeState)] -> RenameProvider IdeState
renameWith [(PluginId, RenameProvider IdeState)]
providers LspFuncs Config
lspFuncs IdeState
state RenameParams
params = do
let
makeAction :: (PluginId,
LspFuncs Config
-> IdeState -> RenameParams -> IO (Either a WorkspaceEdit))
-> IO (Either a WorkspaceEdit)
makeAction (PluginId
pid,LspFuncs Config
-> IdeState -> RenameParams -> IO (Either a WorkspaceEdit)
p) = do
PluginConfig
pluginConfig <- LspFuncs Config -> PluginId -> IO PluginConfig
getPluginConfig LspFuncs Config
lspFuncs PluginId
pid
if PluginConfig -> (PluginConfig -> Bool) -> Bool
pluginEnabled PluginConfig
pluginConfig PluginConfig -> Bool
plcRenameOn
then PluginId
-> ByteString
-> IO (Either a WorkspaceEdit)
-> IO (Either a WorkspaceEdit)
forall a. PluginId -> ByteString -> IO a -> IO a
otTracedProvider PluginId
pid ByteString
"rename" (IO (Either a WorkspaceEdit) -> IO (Either a WorkspaceEdit))
-> IO (Either a WorkspaceEdit) -> IO (Either a WorkspaceEdit)
forall a b. (a -> b) -> a -> b
$ LspFuncs Config
-> IdeState -> RenameParams -> IO (Either a WorkspaceEdit)
p LspFuncs Config
lspFuncs IdeState
state RenameParams
params
else Either a WorkspaceEdit -> IO (Either a WorkspaceEdit)
forall (m :: * -> *) a. Monad m => a -> m a
return (Either a WorkspaceEdit -> IO (Either a WorkspaceEdit))
-> Either a WorkspaceEdit -> IO (Either a WorkspaceEdit)
forall a b. (a -> b) -> a -> b
$ WorkspaceEdit -> Either a WorkspaceEdit
forall a b. b -> Either a b
Right (WorkspaceEdit -> Either a WorkspaceEdit)
-> WorkspaceEdit -> Either a WorkspaceEdit
forall a b. (a -> b) -> a -> b
$ Maybe WorkspaceEditMap
-> Maybe (List TextDocumentEdit) -> WorkspaceEdit
WorkspaceEdit Maybe WorkspaceEditMap
forall a. Maybe a
Nothing Maybe (List TextDocumentEdit)
forall a. Maybe a
Nothing
[Either ResponseError WorkspaceEdit]
results <- ((PluginId, RenameProvider IdeState)
-> IO (Either ResponseError WorkspaceEdit))
-> [(PluginId, RenameProvider IdeState)]
-> IO [Either ResponseError WorkspaceEdit]
forall (t :: * -> *) a b.
Traversable t =>
(a -> IO b) -> t a -> IO (t b)
mapConcurrently (PluginId, RenameProvider IdeState)
-> IO (Either ResponseError WorkspaceEdit)
forall a.
(PluginId,
LspFuncs Config
-> IdeState -> RenameParams -> IO (Either a WorkspaceEdit))
-> IO (Either a WorkspaceEdit)
makeAction [(PluginId, RenameProvider IdeState)]
providers
case [Either ResponseError WorkspaceEdit]
-> ([ResponseError], [WorkspaceEdit])
forall a b. [Either a b] -> ([a], [b])
partitionEithers [Either ResponseError WorkspaceEdit]
results of
([ResponseError]
errors, []) -> Either ResponseError WorkspaceEdit
-> IO (Either ResponseError WorkspaceEdit)
forall (m :: * -> *) a. Monad m => a -> m a
return (Either ResponseError WorkspaceEdit
-> IO (Either ResponseError WorkspaceEdit))
-> Either ResponseError WorkspaceEdit
-> IO (Either ResponseError WorkspaceEdit)
forall a b. (a -> b) -> a -> b
$ ResponseError -> Either ResponseError WorkspaceEdit
forall a b. a -> Either a b
Left (ResponseError -> Either ResponseError WorkspaceEdit)
-> ResponseError -> Either ResponseError WorkspaceEdit
forall a b. (a -> b) -> a -> b
$ Text -> ResponseError
responseError (Text -> ResponseError) -> Text -> ResponseError
forall a b. (a -> b) -> a -> b
$ String -> Text
T.pack (String -> Text) -> String -> Text
forall a b. (a -> b) -> a -> b
$ [ResponseError] -> String
forall a. Show a => a -> String
show [ResponseError]
errors
([ResponseError]
_, [WorkspaceEdit]
edits) -> Either ResponseError WorkspaceEdit
-> IO (Either ResponseError WorkspaceEdit)
forall (m :: * -> *) a. Monad m => a -> m a
return (Either ResponseError WorkspaceEdit
-> IO (Either ResponseError WorkspaceEdit))
-> Either ResponseError WorkspaceEdit
-> IO (Either ResponseError WorkspaceEdit)
forall a b. (a -> b) -> a -> b
$ WorkspaceEdit -> Either ResponseError WorkspaceEdit
forall a b. b -> Either a b
Right (WorkspaceEdit -> Either ResponseError WorkspaceEdit)
-> WorkspaceEdit -> Either ResponseError WorkspaceEdit
forall a b. (a -> b) -> a -> b
$ [WorkspaceEdit] -> WorkspaceEdit
forall a. Monoid a => [a] -> a
mconcat [WorkspaceEdit]
edits
formatterPlugins :: [(PluginId, FormattingProvider IdeState IO)] -> Plugin Config
formatterPlugins :: [(PluginId, FormattingProvider IdeState IO)] -> Plugin Config
formatterPlugins [(PluginId, FormattingProvider IdeState IO)]
providers
= Rules () -> PartialHandlers Config -> Plugin Config
forall c. Rules () -> PartialHandlers c -> Plugin c
Plugin Rules ()
formatterRules
(Map PluginId (FormattingProvider IdeState IO)
-> PartialHandlers Config
formatterHandlers ([(PluginId, FormattingProvider IdeState IO)]
-> Map PluginId (FormattingProvider IdeState IO)
forall k a. Ord k => [(k, a)] -> Map k a
Map.fromList ((PluginId
"none",FormattingProvider IdeState IO
forall ideState. FormattingProvider ideState IO
noneProvider)(PluginId, FormattingProvider IdeState IO)
-> [(PluginId, FormattingProvider IdeState IO)]
-> [(PluginId, FormattingProvider IdeState IO)]
forall a. a -> [a] -> [a]
:[(PluginId, FormattingProvider IdeState IO)]
providers)))
formatterRules :: Rules ()
formatterRules :: Rules ()
formatterRules = Rules ()
forall a. Monoid a => a
mempty
formatterHandlers :: Map.Map PluginId (FormattingProvider IdeState IO) -> PartialHandlers Config
formatterHandlers :: Map PluginId (FormattingProvider IdeState IO)
-> PartialHandlers Config
formatterHandlers Map PluginId (FormattingProvider IdeState IO)
providers = (WithMessage Config -> Handlers -> IO Handlers)
-> PartialHandlers Config
forall c.
(WithMessage c -> Handlers -> IO Handlers) -> PartialHandlers c
PartialHandlers ((WithMessage Config -> Handlers -> IO Handlers)
-> PartialHandlers Config)
-> (WithMessage Config -> Handlers -> IO Handlers)
-> PartialHandlers Config
forall a b. (a -> b) -> a -> b
$ \WithMessage{(LspFuncs Config -> IdeState -> InitializeParams -> IO ())
-> Maybe (Handler InitializeRequest)
forall m req.
(Show m, Show req, HasTracing req) =>
Maybe (Handler (NotificationMessage m req))
-> (LspFuncs Config -> IdeState -> req -> IO ())
-> Maybe (Handler (NotificationMessage m req))
forall m req resp.
(Show m, Show req, HasTracing req) =>
(ResponseMessage resp -> FromServerMessage)
-> (LspFuncs Config
-> IdeState -> req -> IO (Either ResponseError resp))
-> Maybe (Handler (RequestMessage m req resp))
forall m rm req resp newReqParams newReqBody.
(Show m, Show rm, Show req, Show newReqParams, Show newReqBody,
HasTracing req) =>
(ResponseMessage resp -> FromServerMessage)
-> (RequestMessage rm newReqParams newReqBody -> FromServerMessage)
-> (LspFuncs Config
-> IdeState
-> req
-> IO (Either ResponseError resp, Maybe (rm, newReqParams)))
-> Maybe (Handler (RequestMessage m req resp))
withInitialize :: (LspFuncs Config -> IdeState -> InitializeParams -> IO ())
-> Maybe (Handler InitializeRequest)
withResponseAndRequest :: forall m rm req resp newReqParams newReqBody.
(Show m, Show rm, Show req, Show newReqParams, Show newReqBody,
HasTracing req) =>
(ResponseMessage resp -> FromServerMessage)
-> (RequestMessage rm newReqParams newReqBody -> FromServerMessage)
-> (LspFuncs Config
-> IdeState
-> req
-> IO (Either ResponseError resp, Maybe (rm, newReqParams)))
-> Maybe (Handler (RequestMessage m req resp))
withNotification :: forall m req.
(Show m, Show req, HasTracing req) =>
Maybe (Handler (NotificationMessage m req))
-> (LspFuncs Config -> IdeState -> req -> IO ())
-> Maybe (Handler (NotificationMessage m req))
withResponse :: forall m req resp.
(Show m, Show req, HasTracing req) =>
(ResponseMessage resp -> FromServerMessage)
-> (LspFuncs Config
-> IdeState -> req -> IO (Either ResponseError resp))
-> Maybe (Handler (RequestMessage m req resp))
$sel:withInitialize:WithMessage :: forall c.
WithMessage c
-> (LspFuncs c -> IdeState -> InitializeParams -> IO ())
-> Maybe (Handler InitializeRequest)
$sel:withResponseAndRequest:WithMessage :: forall c.
WithMessage c
-> forall m rm req resp newReqParams newReqBody.
(Show m, Show rm, Show req, Show newReqParams, Show newReqBody,
HasTracing req) =>
(ResponseMessage resp -> FromServerMessage)
-> (RequestMessage rm newReqParams newReqBody -> FromServerMessage)
-> (LspFuncs c
-> IdeState
-> req
-> IO (Either ResponseError resp, Maybe (rm, newReqParams)))
-> Maybe (Handler (RequestMessage m req resp))
$sel:withNotification:WithMessage :: forall c.
WithMessage c
-> forall m req.
(Show m, Show req, HasTracing req) =>
Maybe (Handler (NotificationMessage m req))
-> (LspFuncs c -> IdeState -> req -> IO ())
-> Maybe (Handler (NotificationMessage m req))
$sel:withResponse:WithMessage :: forall c.
WithMessage c
-> forall m req resp.
(Show m, Show req, HasTracing req) =>
(ResponseMessage resp -> FromServerMessage)
-> (LspFuncs c
-> IdeState -> req -> IO (Either ResponseError resp))
-> Maybe (Handler (RequestMessage m req resp))
..} Handlers
x -> Handlers -> IO Handlers
forall (m :: * -> *) a. Monad m => a -> m a
return Handlers
x
{ documentFormattingHandler :: Maybe (Handler DocumentFormattingRequest)
LSP.documentFormattingHandler
= (ResponseMessage (List TextEdit) -> FromServerMessage)
-> (LspFuncs Config
-> IdeState
-> DocumentFormattingParams
-> IO (Either ResponseError (List TextEdit)))
-> Maybe (Handler DocumentFormattingRequest)
forall m req resp.
(Show m, Show req, HasTracing req) =>
(ResponseMessage resp -> FromServerMessage)
-> (LspFuncs Config
-> IdeState -> req -> IO (Either ResponseError resp))
-> Maybe (Handler (RequestMessage m req resp))
withResponse ResponseMessage (List TextEdit) -> FromServerMessage
RspDocumentFormatting (Map PluginId (FormattingProvider IdeState IO)
-> LspFuncs Config
-> IdeState
-> DocumentFormattingParams
-> IO (Either ResponseError (List TextEdit))
formatting Map PluginId (FormattingProvider IdeState IO)
providers)
, documentRangeFormattingHandler :: Maybe (Handler DocumentRangeFormattingRequest)
LSP.documentRangeFormattingHandler
= (ResponseMessage (List TextEdit) -> FromServerMessage)
-> (LspFuncs Config
-> IdeState
-> DocumentRangeFormattingParams
-> IO (Either ResponseError (List TextEdit)))
-> Maybe (Handler DocumentRangeFormattingRequest)
forall m req resp.
(Show m, Show req, HasTracing req) =>
(ResponseMessage resp -> FromServerMessage)
-> (LspFuncs Config
-> IdeState -> req -> IO (Either ResponseError resp))
-> Maybe (Handler (RequestMessage m req resp))
withResponse ResponseMessage (List TextEdit) -> FromServerMessage
RspDocumentRangeFormatting (Map PluginId (FormattingProvider IdeState IO)
-> LspFuncs Config
-> IdeState
-> DocumentRangeFormattingParams
-> IO (Either ResponseError (List TextEdit))
rangeFormatting Map PluginId (FormattingProvider IdeState IO)
providers)
}
completionsPlugins :: [(PluginId, CompletionProvider IdeState)] -> Plugin Config
completionsPlugins :: [(PluginId, CompletionProvider IdeState)] -> Plugin Config
completionsPlugins [(PluginId, CompletionProvider IdeState)]
cs = Rules () -> PartialHandlers Config -> Plugin Config
forall c. Rules () -> PartialHandlers c -> Plugin c
Plugin Rules ()
completionsRules ([(PluginId, CompletionProvider IdeState)] -> PartialHandlers Config
completionsHandlers [(PluginId, CompletionProvider IdeState)]
cs)
completionsRules :: Rules ()
completionsRules :: Rules ()
completionsRules = Rules ()
forall a. Monoid a => a
mempty
completionsHandlers :: [(PluginId, CompletionProvider IdeState)] -> PartialHandlers Config
completionsHandlers :: [(PluginId, CompletionProvider IdeState)] -> PartialHandlers Config
completionsHandlers [(PluginId, CompletionProvider IdeState)]
cps = (WithMessage Config -> Handlers -> IO Handlers)
-> PartialHandlers Config
forall c.
(WithMessage c -> Handlers -> IO Handlers) -> PartialHandlers c
PartialHandlers ((WithMessage Config -> Handlers -> IO Handlers)
-> PartialHandlers Config)
-> (WithMessage Config -> Handlers -> IO Handlers)
-> PartialHandlers Config
forall a b. (a -> b) -> a -> b
$ \WithMessage{(LspFuncs Config -> IdeState -> InitializeParams -> IO ())
-> Maybe (Handler InitializeRequest)
forall m req.
(Show m, Show req, HasTracing req) =>
Maybe (Handler (NotificationMessage m req))
-> (LspFuncs Config -> IdeState -> req -> IO ())
-> Maybe (Handler (NotificationMessage m req))
forall m req resp.
(Show m, Show req, HasTracing req) =>
(ResponseMessage resp -> FromServerMessage)
-> (LspFuncs Config
-> IdeState -> req -> IO (Either ResponseError resp))
-> Maybe (Handler (RequestMessage m req resp))
forall m rm req resp newReqParams newReqBody.
(Show m, Show rm, Show req, Show newReqParams, Show newReqBody,
HasTracing req) =>
(ResponseMessage resp -> FromServerMessage)
-> (RequestMessage rm newReqParams newReqBody -> FromServerMessage)
-> (LspFuncs Config
-> IdeState
-> req
-> IO (Either ResponseError resp, Maybe (rm, newReqParams)))
-> Maybe (Handler (RequestMessage m req resp))
withInitialize :: (LspFuncs Config -> IdeState -> InitializeParams -> IO ())
-> Maybe (Handler InitializeRequest)
withResponseAndRequest :: forall m rm req resp newReqParams newReqBody.
(Show m, Show rm, Show req, Show newReqParams, Show newReqBody,
HasTracing req) =>
(ResponseMessage resp -> FromServerMessage)
-> (RequestMessage rm newReqParams newReqBody -> FromServerMessage)
-> (LspFuncs Config
-> IdeState
-> req
-> IO (Either ResponseError resp, Maybe (rm, newReqParams)))
-> Maybe (Handler (RequestMessage m req resp))
withNotification :: forall m req.
(Show m, Show req, HasTracing req) =>
Maybe (Handler (NotificationMessage m req))
-> (LspFuncs Config -> IdeState -> req -> IO ())
-> Maybe (Handler (NotificationMessage m req))
withResponse :: forall m req resp.
(Show m, Show req, HasTracing req) =>
(ResponseMessage resp -> FromServerMessage)
-> (LspFuncs Config
-> IdeState -> req -> IO (Either ResponseError resp))
-> Maybe (Handler (RequestMessage m req resp))
$sel:withInitialize:WithMessage :: forall c.
WithMessage c
-> (LspFuncs c -> IdeState -> InitializeParams -> IO ())
-> Maybe (Handler InitializeRequest)
$sel:withResponseAndRequest:WithMessage :: forall c.
WithMessage c
-> forall m rm req resp newReqParams newReqBody.
(Show m, Show rm, Show req, Show newReqParams, Show newReqBody,
HasTracing req) =>
(ResponseMessage resp -> FromServerMessage)
-> (RequestMessage rm newReqParams newReqBody -> FromServerMessage)
-> (LspFuncs c
-> IdeState
-> req
-> IO (Either ResponseError resp, Maybe (rm, newReqParams)))
-> Maybe (Handler (RequestMessage m req resp))
$sel:withNotification:WithMessage :: forall c.
WithMessage c
-> forall m req.
(Show m, Show req, HasTracing req) =>
Maybe (Handler (NotificationMessage m req))
-> (LspFuncs c -> IdeState -> req -> IO ())
-> Maybe (Handler (NotificationMessage m req))
$sel:withResponse:WithMessage :: forall c.
WithMessage c
-> forall m req resp.
(Show m, Show req, HasTracing req) =>
(ResponseMessage resp -> FromServerMessage)
-> (LspFuncs c
-> IdeState -> req -> IO (Either ResponseError resp))
-> Maybe (Handler (RequestMessage m req resp))
..} Handlers
x ->
Handlers -> IO Handlers
forall (m :: * -> *) a. Monad m => a -> m a
return Handlers
x {completionHandler :: Maybe (Handler CompletionRequest)
LSP.completionHandler = (ResponseMessage CompletionResponseResult -> FromServerMessage)
-> CompletionProvider IdeState -> Maybe (Handler CompletionRequest)
forall m req resp.
(Show m, Show req, HasTracing req) =>
(ResponseMessage resp -> FromServerMessage)
-> (LspFuncs Config
-> IdeState -> req -> IO (Either ResponseError resp))
-> Maybe (Handler (RequestMessage m req resp))
withResponse ResponseMessage CompletionResponseResult -> FromServerMessage
RspCompletion ([(PluginId, CompletionProvider IdeState)]
-> CompletionProvider IdeState
makeCompletions [(PluginId, CompletionProvider IdeState)]
cps)}
makeCompletions :: [(PluginId, CompletionProvider IdeState)]
-> LSP.LspFuncs Config
-> IdeState
-> CompletionParams
-> IO (Either ResponseError CompletionResponseResult)
makeCompletions :: [(PluginId, CompletionProvider IdeState)]
-> CompletionProvider IdeState
makeCompletions [(PluginId, CompletionProvider IdeState)]
sps LspFuncs Config
lf IdeState
ideState params :: CompletionParams
params@(CompletionParams (TextDocumentIdentifier Uri
doc) Position
pos Maybe CompletionContext
_context Maybe ProgressToken
_mt)
= do
Maybe PosPrefixInfo
mprefix <- LspFuncs Config -> Uri -> Position -> IO (Maybe PosPrefixInfo)
getPrefixAtPos LspFuncs Config
lf Uri
doc Position
pos
Int
maxCompletions <- Config -> Int
maxCompletions (Config -> Int) -> IO Config -> IO Int
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> LspFuncs Config -> IO Config
getClientConfig LspFuncs Config
lf
let
combine :: [CompletionResponseResult] -> CompletionResponseResult
combine :: [CompletionResponseResult] -> CompletionResponseResult
combine [CompletionResponseResult]
cs = Bool
-> DList CompletionItem
-> [CompletionResponseResult]
-> CompletionResponseResult
go Bool
True DList CompletionItem
forall a. Monoid a => a
mempty [CompletionResponseResult]
cs
go :: Bool
-> DList CompletionItem
-> [CompletionResponseResult]
-> CompletionResponseResult
go !Bool
comp DList CompletionItem
acc [] =
CompletionListType -> CompletionResponseResult
CompletionList (Bool -> List CompletionItem -> CompletionListType
CompletionListType Bool
comp ([CompletionItem] -> List CompletionItem
forall a. [a] -> List a
List ([CompletionItem] -> List CompletionItem)
-> [CompletionItem] -> List CompletionItem
forall a b. (a -> b) -> a -> b
$ DList CompletionItem -> [CompletionItem]
forall a. DList a -> [a]
DList.toList DList CompletionItem
acc))
go Bool
comp DList CompletionItem
acc (Completions (List [CompletionItem]
ls) : [CompletionResponseResult]
rest) =
Bool
-> DList CompletionItem
-> [CompletionResponseResult]
-> CompletionResponseResult
go Bool
comp (DList CompletionItem
acc DList CompletionItem
-> DList CompletionItem -> DList CompletionItem
forall a. Semigroup a => a -> a -> a
<> [CompletionItem] -> DList CompletionItem
forall a. [a] -> DList a
DList.fromList [CompletionItem]
ls) [CompletionResponseResult]
rest
go Bool
comp DList CompletionItem
acc (CompletionList (CompletionListType Bool
comp' (List [CompletionItem]
ls)) : [CompletionResponseResult]
rest) =
Bool
-> DList CompletionItem
-> [CompletionResponseResult]
-> CompletionResponseResult
go (Bool
comp Bool -> Bool -> Bool
&& Bool
comp') (DList CompletionItem
acc DList CompletionItem
-> DList CompletionItem -> DList CompletionItem
forall a. Semigroup a => a -> a -> a
<> [CompletionItem] -> DList CompletionItem
forall a. [a] -> DList a
DList.fromList [CompletionItem]
ls) [CompletionResponseResult]
rest
makeAction ::
(PluginId, CompletionProvider IdeState) ->
IO (Either ResponseError CompletionResponseResult)
makeAction :: (PluginId, CompletionProvider IdeState)
-> IO (Either ResponseError CompletionResponseResult)
makeAction (PluginId
pid, CompletionProvider IdeState
p) = do
PluginConfig
pluginConfig <- LspFuncs Config -> PluginId -> IO PluginConfig
getPluginConfig LspFuncs Config
lf PluginId
pid
if PluginConfig -> (PluginConfig -> Bool) -> Bool
pluginEnabled PluginConfig
pluginConfig PluginConfig -> Bool
plcCompletionOn
then PluginId
-> ByteString
-> IO (Either ResponseError CompletionResponseResult)
-> IO (Either ResponseError CompletionResponseResult)
forall a. PluginId -> ByteString -> IO a -> IO a
otTracedProvider PluginId
pid ByteString
"completions" (IO (Either ResponseError CompletionResponseResult)
-> IO (Either ResponseError CompletionResponseResult))
-> IO (Either ResponseError CompletionResponseResult)
-> IO (Either ResponseError CompletionResponseResult)
forall a b. (a -> b) -> a -> b
$ CompletionProvider IdeState
p LspFuncs Config
lf IdeState
ideState CompletionParams
params
else Either ResponseError CompletionResponseResult
-> IO (Either ResponseError CompletionResponseResult)
forall (m :: * -> *) a. Monad m => a -> m a
return (Either ResponseError CompletionResponseResult
-> IO (Either ResponseError CompletionResponseResult))
-> Either ResponseError CompletionResponseResult
-> IO (Either ResponseError CompletionResponseResult)
forall a b. (a -> b) -> a -> b
$ CompletionResponseResult
-> Either ResponseError CompletionResponseResult
forall a b. b -> Either a b
Right (CompletionResponseResult
-> Either ResponseError CompletionResponseResult)
-> CompletionResponseResult
-> Either ResponseError CompletionResponseResult
forall a b. (a -> b) -> a -> b
$ List CompletionItem -> CompletionResponseResult
Completions (List CompletionItem -> CompletionResponseResult)
-> List CompletionItem -> CompletionResponseResult
forall a b. (a -> b) -> a -> b
$ [CompletionItem] -> List CompletionItem
forall a. [a] -> List a
List []
case Maybe PosPrefixInfo
mprefix of
Maybe PosPrefixInfo
Nothing -> Either ResponseError CompletionResponseResult
-> IO (Either ResponseError CompletionResponseResult)
forall (m :: * -> *) a. Monad m => a -> m a
return (Either ResponseError CompletionResponseResult
-> IO (Either ResponseError CompletionResponseResult))
-> Either ResponseError CompletionResponseResult
-> IO (Either ResponseError CompletionResponseResult)
forall a b. (a -> b) -> a -> b
$ CompletionResponseResult
-> Either ResponseError CompletionResponseResult
forall a b. b -> Either a b
Right (CompletionResponseResult
-> Either ResponseError CompletionResponseResult)
-> CompletionResponseResult
-> Either ResponseError CompletionResponseResult
forall a b. (a -> b) -> a -> b
$ List CompletionItem -> CompletionResponseResult
Completions (List CompletionItem -> CompletionResponseResult)
-> List CompletionItem -> CompletionResponseResult
forall a b. (a -> b) -> a -> b
$ [CompletionItem] -> List CompletionItem
forall a. [a] -> List a
List []
Just PosPrefixInfo
_prefix -> do
[Either ResponseError CompletionResponseResult]
mhs <- ((PluginId, CompletionProvider IdeState)
-> IO (Either ResponseError CompletionResponseResult))
-> [(PluginId, CompletionProvider IdeState)]
-> IO [Either ResponseError CompletionResponseResult]
forall (t :: * -> *) a b.
Traversable t =>
(a -> IO b) -> t a -> IO (t b)
mapConcurrently (PluginId, CompletionProvider IdeState)
-> IO (Either ResponseError CompletionResponseResult)
makeAction [(PluginId, CompletionProvider IdeState)]
sps
case [Either ResponseError CompletionResponseResult]
-> [CompletionResponseResult]
forall a b. [Either a b] -> [b]
rights [Either ResponseError CompletionResponseResult]
mhs of
[] -> Either ResponseError CompletionResponseResult
-> IO (Either ResponseError CompletionResponseResult)
forall (m :: * -> *) a. Monad m => a -> m a
return (Either ResponseError CompletionResponseResult
-> IO (Either ResponseError CompletionResponseResult))
-> Either ResponseError CompletionResponseResult
-> IO (Either ResponseError CompletionResponseResult)
forall a b. (a -> b) -> a -> b
$ ResponseError -> Either ResponseError CompletionResponseResult
forall a b. a -> Either a b
Left (ResponseError -> Either ResponseError CompletionResponseResult)
-> ResponseError -> Either ResponseError CompletionResponseResult
forall a b. (a -> b) -> a -> b
$ Text -> ResponseError
responseError (Text -> ResponseError) -> Text -> ResponseError
forall a b. (a -> b) -> a -> b
$ String -> Text
T.pack (String -> Text) -> String -> Text
forall a b. (a -> b) -> a -> b
$ [ResponseError] -> String
forall a. Show a => a -> String
show ([ResponseError] -> String) -> [ResponseError] -> String
forall a b. (a -> b) -> a -> b
$ [Either ResponseError CompletionResponseResult] -> [ResponseError]
forall a b. [Either a b] -> [a]
lefts [Either ResponseError CompletionResponseResult]
mhs
[CompletionResponseResult]
hs -> Either ResponseError CompletionResponseResult
-> IO (Either ResponseError CompletionResponseResult)
forall (m :: * -> *) a. Monad m => a -> m a
return (Either ResponseError CompletionResponseResult
-> IO (Either ResponseError CompletionResponseResult))
-> Either ResponseError CompletionResponseResult
-> IO (Either ResponseError CompletionResponseResult)
forall a b. (a -> b) -> a -> b
$ CompletionResponseResult
-> Either ResponseError CompletionResponseResult
forall a b. b -> Either a b
Right (CompletionResponseResult
-> Either ResponseError CompletionResponseResult)
-> CompletionResponseResult
-> Either ResponseError CompletionResponseResult
forall a b. (a -> b) -> a -> b
$ (Int, CompletionResponseResult) -> CompletionResponseResult
forall a b. (a, b) -> b
snd ((Int, CompletionResponseResult) -> CompletionResponseResult)
-> (Int, CompletionResponseResult) -> CompletionResponseResult
forall a b. (a -> b) -> a -> b
$ Int -> CompletionResponseResult -> (Int, CompletionResponseResult)
consumeCompletionResponse Int
maxCompletions (CompletionResponseResult -> (Int, CompletionResponseResult))
-> CompletionResponseResult -> (Int, CompletionResponseResult)
forall a b. (a -> b) -> a -> b
$ [CompletionResponseResult] -> CompletionResponseResult
combine [CompletionResponseResult]
hs
consumeCompletionResponse :: Int -> CompletionResponseResult -> (Int, CompletionResponseResult)
consumeCompletionResponse :: Int -> CompletionResponseResult -> (Int, CompletionResponseResult)
consumeCompletionResponse Int
limit it :: CompletionResponseResult
it@(CompletionList (CompletionListType Bool
_ (List [CompletionItem]
xx))) =
case Int -> [CompletionItem] -> ([CompletionItem], [CompletionItem])
forall a. Int -> [a] -> ([a], [a])
splitAt Int
limit [CompletionItem]
xx of
([CompletionItem]
_, []) -> (Int
limit Int -> Int -> Int
forall a. Num a => a -> a -> a
- [CompletionItem] -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length [CompletionItem]
xx, CompletionResponseResult
it)
([CompletionItem]
xx', [CompletionItem]
_) -> (Int
0, CompletionListType -> CompletionResponseResult
CompletionList (Bool -> List CompletionItem -> CompletionListType
CompletionListType Bool
isIncompleteResponse ([CompletionItem] -> List CompletionItem
forall a. [a] -> List a
List [CompletionItem]
xx')))
consumeCompletionResponse Int
n (Completions (List [CompletionItem]
xx)) =
Int -> CompletionResponseResult -> (Int, CompletionResponseResult)
consumeCompletionResponse Int
n (CompletionListType -> CompletionResponseResult
CompletionList (Bool -> List CompletionItem -> CompletionListType
CompletionListType Bool
isCompleteResponse ([CompletionItem] -> List CompletionItem
forall a. [a] -> List a
List [CompletionItem]
xx)))
isCompleteResponse, isIncompleteResponse :: Bool
isIncompleteResponse :: Bool
isIncompleteResponse = Bool
True
isCompleteResponse :: Bool
isCompleteResponse = Bool
False
getPrefixAtPos :: LSP.LspFuncs Config -> Uri -> Position -> IO (Maybe VFS.PosPrefixInfo)
getPrefixAtPos :: LspFuncs Config -> Uri -> Position -> IO (Maybe PosPrefixInfo)
getPrefixAtPos LspFuncs Config
lf Uri
uri Position
pos = do
Maybe VirtualFile
mvf <- LspFuncs Config -> NormalizedUri -> IO (Maybe VirtualFile)
forall c. LspFuncs c -> NormalizedUri -> IO (Maybe VirtualFile)
LSP.getVirtualFileFunc LspFuncs Config
lf (Uri -> NormalizedUri
J.toNormalizedUri Uri
uri)
case Maybe VirtualFile
mvf of
Just VirtualFile
vf -> Position -> VirtualFile -> IO (Maybe PosPrefixInfo)
forall (m :: * -> *).
Monad m =>
Position -> VirtualFile -> m (Maybe PosPrefixInfo)
VFS.getCompletionPrefix Position
pos VirtualFile
vf
Maybe VirtualFile
Nothing -> Maybe PosPrefixInfo -> IO (Maybe PosPrefixInfo)
forall (m :: * -> *) a. Monad m => a -> m a
return Maybe PosPrefixInfo
forall a. Maybe a
Nothing