hls-plugin-api 2.9.0.1 → 2.10.0.0
raw patch · 6 files changed
+60/−50 lines, 6 filesdep ~hls-graphPVP ok
version bump matches the API change (PVP)
Dependency ranges changed: hls-graph
API changes (from Hackage documentation)
- Ide.Types: mkFormattingHandlers :: forall a. FormattingHandler a -> PluginHandlers a
- Ide.Types: pluginGetVersionedTextDoc :: TextDocumentIdentifier -> HandlerM config VersionedTextDocumentIdentifier
- Ide.Types: pluginGetVirtualFile :: NormalizedUri -> HandlerM config (Maybe VirtualFile)
+ Ide.Plugin.Config: [$sel:plcInlayHintsOn:PluginConfig] :: PluginConfig -> !Bool
+ Ide.Plugin.RangeMap: elementsInRange :: Range -> RangeMap a -> [a]
+ Ide.PluginUtils: rangesOverlap :: Range -> Range -> Bool
+ Ide.Types: [$sel:plcInlayHintsOn:PluginConfig] :: PluginConfig -> !Bool
+ Ide.Types: instance Ide.Types.PluginMethod 'Language.LSP.Protocol.Message.Meta.Request 'Language.LSP.Protocol.Internal.Method.Method_InlayHintResolve
+ Ide.Types: instance Ide.Types.PluginMethod 'Language.LSP.Protocol.Message.Meta.Request 'Language.LSP.Protocol.Internal.Method.Method_TextDocumentImplementation
+ Ide.Types: instance Ide.Types.PluginMethod 'Language.LSP.Protocol.Message.Meta.Request 'Language.LSP.Protocol.Internal.Method.Method_TextDocumentInlayHint
+ Ide.Types: instance Ide.Types.PluginRequestMethod 'Language.LSP.Protocol.Internal.Method.Method_TextDocumentImplementation
+ Ide.Types: instance Ide.Types.PluginRequestMethod 'Language.LSP.Protocol.Internal.Method.Method_TextDocumentInlayHint
- Ide.Plugin.Config: PluginConfig :: !Bool -> !Bool -> !Bool -> !Bool -> !Bool -> !Bool -> !Bool -> !Bool -> !Bool -> !Bool -> !Bool -> !Bool -> !Object -> PluginConfig
+ Ide.Plugin.Config: PluginConfig :: !Bool -> !Bool -> !Bool -> !Bool -> !Bool -> !Bool -> !Bool -> !Bool -> !Bool -> !Bool -> !Bool -> !Bool -> !Bool -> !Object -> PluginConfig
- Ide.Types: PluginConfig :: !Bool -> !Bool -> !Bool -> !Bool -> !Bool -> !Bool -> !Bool -> !Bool -> !Bool -> !Bool -> !Bool -> !Bool -> !Object -> PluginConfig
+ Ide.Types: PluginConfig :: !Bool -> !Bool -> !Bool -> !Bool -> !Bool -> !Bool -> !Bool -> !Bool -> !Bool -> !Bool -> !Bool -> !Bool -> !Bool -> !Object -> PluginConfig
Files
- hls-plugin-api.cabal +2/−2
- src/Ide/Plugin/Config.hs +4/−3
- src/Ide/Plugin/ConfigUtils.hs +2/−0
- src/Ide/Plugin/RangeMap.hs +9/−0
- src/Ide/PluginUtils.hs +16/−0
- src/Ide/Types.hs +27/−45
hls-plugin-api.cabal view
@@ -1,6 +1,6 @@ cabal-version: 2.4 name: hls-plugin-api-version: 2.9.0.1+version: 2.10.0.0 synopsis: Haskell Language Server API for plugin communication description: Please see the README on GitHub at <https://github.com/haskell/haskell-language-server#readme>@@ -66,7 +66,7 @@ , filepath , ghc , hashable- , hls-graph == 2.9.0.1+ , hls-graph == 2.10.0.0 , lens , lens-aeson , lsp ^>=2.7
src/Ide/Plugin/Config.hs view
@@ -63,19 +63,20 @@ -- --------------------------------------------------------------------- parsePluginConfig :: PluginConfig -> Value -> A.Parser PluginConfig-parsePluginConfig def = A.withObject "PluginConfig" $ \o -> PluginConfig+parsePluginConfig def = A.withObject "PluginConfig" $ \o -> PluginConfig <$> o .:? "globalOn" .!= plcGlobalOn def <*> o .:? "callHierarchyOn" .!= plcCallHierarchyOn def- <*> o .:? "semanticTokensOn" .!= plcSemanticTokensOn def <*> o .:? "codeActionsOn" .!= plcCodeActionsOn def <*> o .:? "codeLensOn" .!= plcCodeLensOn def+ <*> o .:? "inlayHintsOn" .!= plcInlayHintsOn def <*> o .:? "diagnosticsOn" .!= plcDiagnosticsOn def -- AZ <*> o .:? "hoverOn" .!= plcHoverOn def <*> o .:? "symbolsOn" .!= plcSymbolsOn def <*> o .:? "completionOn" .!= plcCompletionOn def <*> o .:? "renameOn" .!= plcRenameOn def <*> o .:? "selectionRangeOn" .!= plcSelectionRangeOn def- <*> o .:? "foldingRangeOn" .!= plcFoldingRangeOn def+ <*> o .:? "foldingRangeOn" .!= plcFoldingRangeOn def+ <*> o .:? "semanticTokensOn" .!= plcSemanticTokensOn def <*> o .:? "config" .!= plcConfig def -- ---------------------------------------------------------------------
src/Ide/Plugin/ConfigUtils.hs view
@@ -88,6 +88,7 @@ handlersToGenericDefaultConfig PluginConfig{..} (IdeMethod m DSum.:=> _) = case m of SMethod_TextDocumentCodeAction -> ["codeActionsOn" A..= plcCodeActionsOn] SMethod_TextDocumentCodeLens -> ["codeLensOn" A..= plcCodeLensOn]+ SMethod_TextDocumentInlayHint -> ["inlayHintsOn" A..= plcInlayHintsOn] SMethod_TextDocumentRename -> ["renameOn" A..= plcRenameOn] SMethod_TextDocumentHover -> ["hoverOn" A..= plcHoverOn] SMethod_TextDocumentDocumentSymbol -> ["symbolsOn" A..= plcSymbolsOn]@@ -120,6 +121,7 @@ handlersToGenericSchema PluginConfig{..} (IdeMethod m DSum.:=> _) = case m of SMethod_TextDocumentCodeAction -> [toKey' "codeActionsOn" A..= schemaEntry "code actions" plcCodeActionsOn] SMethod_TextDocumentCodeLens -> [toKey' "codeLensOn" A..= schemaEntry "code lenses" plcCodeLensOn]+ SMethod_TextDocumentInlayHint -> [toKey' "inlayHintsOn" A..= schemaEntry "inlay hints" plcInlayHintsOn] SMethod_TextDocumentRename -> [toKey' "renameOn" A..= schemaEntry "rename" plcRenameOn] SMethod_TextDocumentHover -> [toKey' "hoverOn" A..= schemaEntry "hover" plcHoverOn] SMethod_TextDocumentDocumentSymbol -> [toKey' "symbolsOn" A..= schemaEntry "symbols" plcSymbolsOn]
src/Ide/Plugin/RangeMap.hs view
@@ -13,6 +13,7 @@ fromList, fromList', filterByRange,+ elementsInRange, ) where import Development.IDE.Graph.Classes (NFData)@@ -65,6 +66,14 @@ filterByRange range = map snd . IM.dominators (rangeToInterval range) . unRangeMap #else filterByRange range = map snd . filter (isSubrangeOf range . fst) . unRangeMap+#endif++-- | Extracts all elements from a 'RangeMap' that fall within a given 'Range'.+elementsInRange :: Range -> RangeMap a -> [a]+#ifdef USE_FINGERTREE+elementsInRange range = map snd . IM.intersections (rangeToInterval range) . unRangeMap+#else+elementsInRange range = map snd . filter (flip isSubrangeOf range . fst) . unRangeMap #endif #ifdef USE_FINGERTREE
src/Ide/PluginUtils.hs view
@@ -28,6 +28,7 @@ allLspCmdIds', installSigUsr1Handler, subRange,+ rangesOverlap, positionInRange, usePropertyLsp, -- * Escape@@ -276,6 +277,21 @@ subRange :: Range -> Range -> Bool subRange = isSubrangeOf+++-- | Check whether the two 'Range's overlap in any way.+--+-- >>> rangesOverlap (mkRange 1 0 1 4) (mkRange 1 2 1 5)+-- True+-- >>> rangesOverlap (mkRange 1 2 1 5) (mkRange 1 0 1 4)+-- True+-- >>> rangesOverlap (mkRange 1 0 1 6) (mkRange 1 2 1 4)+-- True+-- >>> rangesOverlap (mkRange 1 2 1 4) (mkRange 1 0 1 6)+-- True+rangesOverlap :: Range -> Range -> Bool+rangesOverlap r1 r2 =+ r1 ^. L.start <= r2 ^. L.end && r2 ^. L.start <= r1 ^. L.end -- ---------------------------------------------------------------------
src/Ide/Types.hs view
@@ -26,12 +26,12 @@ , ConfigDescriptor(..), defaultConfigDescriptor, configForPlugin , CustomConfig(..), mkCustomConfig , FallbackCodeActionParams(..)-, FormattingType(..), FormattingMethod, FormattingHandler, mkFormattingHandlers+, FormattingType(..), FormattingMethod, FormattingHandler , HasTracing(..) , PluginCommand(..), CommandId(..), CommandFunction, mkLspCommand, mkLspCmdId , PluginId(..) , PluginHandler(..), mkPluginHandler-, HandlerM, runHandlerM, pluginGetClientCapabilities, pluginGetVirtualFile, pluginGetVersionedTextDoc, pluginSendNotification, pluginSendRequest, pluginWithIndefiniteProgress+, HandlerM, runHandlerM, pluginGetClientCapabilities, pluginSendNotification, pluginSendRequest, pluginWithIndefiniteProgress , PluginHandlers(..) , PluginMethod(..) , PluginMethodHandler@@ -64,7 +64,6 @@ import Control.Monad (void) import Control.Monad.Error.Class (MonadError (throwError)) import Control.Monad.IO.Class (MonadIO)-import Control.Monad.Trans.Class (MonadTrans (lift)) import Control.Monad.Trans.Except (ExceptT, runExceptT) import Data.Aeson hiding (Null, defaultOptions) import qualified Data.Aeson.Types as A@@ -260,6 +259,7 @@ , plcCallHierarchyOn :: !Bool , plcCodeActionsOn :: !Bool , plcCodeLensOn :: !Bool+ , plcInlayHintsOn :: !Bool , plcDiagnosticsOn :: !Bool , plcHoverOn :: !Bool , plcSymbolsOn :: !Bool@@ -277,6 +277,7 @@ , plcCallHierarchyOn = True , plcCodeActionsOn = True , plcCodeLensOn = True+ , plcInlayHintsOn = True , plcDiagnosticsOn = True , plcHoverOn = True , plcSymbolsOn = True@@ -289,12 +290,13 @@ } instance ToJSON PluginConfig where- toJSON (PluginConfig g ch ca cl d h s c rn sr fr st cfg) = r+ toJSON (PluginConfig g ch ca ih cl d h s c rn sr fr st cfg) = r where r = object [ "globalOn" .= g , "callHierarchyOn" .= ch , "codeActionsOn" .= ca , "codeLensOn" .= cl+ , "inlayHintsOn" .= ih , "diagnosticsOn" .= d , "hoverOn" .= h , "symbolsOn" .= s@@ -501,6 +503,9 @@ instance PluginMethod Request Method_TextDocumentTypeDefinition where handlesRequest _ msgParams pluginDesc _ = pluginSupportsFileType msgParams pluginDesc +instance PluginMethod Request Method_TextDocumentImplementation where+ handlesRequest _ msgParams pluginDesc _ = pluginSupportsFileType msgParams pluginDesc+ instance PluginMethod Request Method_TextDocumentDocumentHighlight where handlesRequest _ msgParams pluginDesc _ = pluginSupportsFileType msgParams pluginDesc @@ -511,6 +516,12 @@ -- Unconditionally enabled, but should it really be? handlesRequest _ _ _ _ = HandlesRequest +instance PluginMethod Request Method_TextDocumentInlayHint where+ handlesRequest = pluginEnabledWithFeature plcInlayHintsOn++instance PluginMethod Request Method_InlayHintResolve where+ handlesRequest = pluginEnabledResolve plcInlayHintsOn+ instance PluginMethod Request Method_TextDocumentCodeLens where handlesRequest = pluginEnabledWithFeature plcCodeLensOn @@ -688,6 +699,11 @@ | Just (Just True) <- caps ^? (L.textDocument . _Just . L.typeDefinition . _Just . L.linkSupport) = foldl' mergeDefinitions x xs | otherwise = downgradeLinks $ foldl' mergeDefinitions x xs +instance PluginRequestMethod Method_TextDocumentImplementation where+ combineResponses _ _ caps _ (x :| xs)+ | Just (Just True) <- caps ^? (L.textDocument . _Just . L.implementation . _Just . L.linkSupport) = foldl' mergeDefinitions x xs+ | otherwise = downgradeLinks $ foldl' mergeDefinitions x xs+ instance PluginRequestMethod Method_TextDocumentDocumentHighlight where instance PluginRequestMethod Method_TextDocumentReferences where@@ -711,7 +727,7 @@ combineResponses _ _ _ _ (x :| _) = x instance PluginRequestMethod Method_TextDocumentHover where- combineResponses _ _ _ _ (mapMaybe nullToMaybe . toList -> hs :: [Hover]) =+ combineResponses _ _ _ _ (mapMaybe nullToMaybe . toList -> (hs :: [Hover])) = if null hs then InR Null else InL $ Hover (InL mcontent) r@@ -810,6 +826,9 @@ instance PluginRequestMethod Method_TextDocumentSemanticTokensFullDelta where combineResponses _ _ _ _ (x :| _) = x +instance PluginRequestMethod Method_TextDocumentInlayHint where+ combineResponses _ _ _ _ x = sconcat x+ takeLefts :: [a |? b] -> [a] takeLefts = mapMaybe (\x -> [res | (InL res) <- Just x]) @@ -899,29 +918,15 @@ -- | Restricted version of 'LspM' specific to plugins. ----- We plan to use this monad for running plugins instead of 'LspM', since there--- are parts of the LSP server state which plugins should not access directly,--- but instead only via the build system. Note that this restriction of the LSP--- server state has not yet been implemented. See 'pluginGetVirtualFile'.+-- We use this monad for running plugins instead of 'LspM', since there are+-- parts of the LSP server state which plugins should not access directly, but+-- instead only via the build system. newtype HandlerM config a = HandlerM { _runHandlerM :: LspM config a } deriving newtype (Applicative, Functor, Monad, MonadIO, MonadUnliftIO) runHandlerM :: HandlerM config a -> LspM config a runHandlerM = _runHandlerM --- | Wrapper of 'getVirtualFile' for HandlerM------ TODO: To be replaced by a lookup of the Shake build graph-pluginGetVirtualFile :: NormalizedUri -> HandlerM config (Maybe VirtualFile)-pluginGetVirtualFile uri = HandlerM $ getVirtualFile uri---- | Version of 'getVersionedTextDoc' for HandlerM------ TODO: Should use 'pluginGetVirtualFile' instead of wrapping 'getVersionedTextDoc'.--- At the time of writing, 'getVersionedTextDoc' of the "lsp" package is implemented with 'getVirtualFile'.-pluginGetVersionedTextDoc :: TextDocumentIdentifier -> HandlerM config VersionedTextDocumentIdentifier-pluginGetVersionedTextDoc = HandlerM . getVersionedTextDoc- -- | Wrapper of 'getClientCapabilities' for HandlerM pluginGetClientCapabilities :: HandlerM config ClientCapabilities pluginGetClientCapabilities = HandlerM getClientCapabilities@@ -1183,30 +1188,7 @@ -> FormattingOptions -> ExceptT PluginError (HandlerM Config) ([TextEdit] |? Null) -mkFormattingHandlers :: forall a. FormattingHandler a -> PluginHandlers a-mkFormattingHandlers f = mkPluginHandler SMethod_TextDocumentFormatting ( provider SMethod_TextDocumentFormatting)- <> mkPluginHandler SMethod_TextDocumentRangeFormatting (provider SMethod_TextDocumentRangeFormatting)- where- provider :: forall m. FormattingMethod m => SMethod m -> PluginMethodHandler a m- provider m ide _pid params- | Just nfp <- uriToNormalizedFilePath $ toNormalizedUri uri = do- mf <- lift $ pluginGetVirtualFile $ toNormalizedUri uri- case mf of- Just vf -> do- let (typ, mtoken) = case m of- SMethod_TextDocumentFormatting -> (FormatText, params ^. L.workDoneToken)- SMethod_TextDocumentRangeFormatting -> (FormatRange (params ^. L.range), params ^. L.workDoneToken)- _ -> Prelude.error "mkFormattingHandlers: impossible"- f ide mtoken typ (virtualFileText vf) nfp opts- Nothing -> throwError $ PluginInvalidParams $ T.pack $ "Formatter plugin: could not get file contents for " ++ show uri-- | otherwise = throwError $ PluginInvalidParams $ T.pack $ "Formatter plugin: uriToFilePath failed for: " ++ show uri- where- uri = params ^. L.textDocument . L.uri- opts = params ^. L.options- -- ---------------------------------------------------------------------- data FallbackCodeActionParams = FallbackCodeActionParams