1313{-# LANGUAGE TypeFamilies #-}
1414{-# LANGUAGE DeriveAnyClass #-}
1515{-# LANGUAGE DeriveGeneric #-}
16+ {-# LANGUAGE ConstraintKinds #-}
1617
1718module Ide.Types
1819 where
@@ -26,7 +27,7 @@ import Development.Shake hiding (command)
2627import Ide.Plugin.Config
2728import Language.LSP.Types
2829import Language.LSP.VFS
29- import Language.LSP.Types.Lens hiding (id )
30+ import Language.LSP.Types.Lens as J hiding (id )
3031import Language.LSP.Types.Capabilities
3132import Language.LSP.Server (LspM , getVirtualFile )
3233import Text.Regex.TDFA.Text ()
@@ -60,16 +61,6 @@ data PluginDescriptor ideState =
6061-- Only methods for which we know how to combine responses can be instances of 'PluginMethod'
6162class PluginMethod m where
6263
63- -- | Extra data associated with requests of this type, to be passed to the handler
64- type ExtraParams m :: *
65- type ExtraParams m = () -- no extra data by default
66-
67- -- | How to generate the extra data
68- getExtraParams :: SMethod m -> MessageParams m -> LspM Config (Either ResponseError (ExtraParams m ))
69-
70- default getExtraParams :: (ExtraParams m ~ () ) => SMethod m -> MessageParams m -> LspM Config (Either ResponseError (ExtraParams m ))
71- getExtraParams _ _ = pure $ Right ()
72-
7364 -- | Parse the configuration to check if this plugin is enabled
7465 pluginEnabled :: SMethod m -> PluginId -> Config -> Bool
7566
@@ -88,7 +79,7 @@ class PluginMethod m where
8879
8980instance PluginMethod TextDocumentCodeAction where
9081 pluginEnabled _ = pluginEnabledConfig plcCodeActionsOn
91- combineResponses _method pid _config (ClientCapabilities _ textDocCaps _ _) (CodeActionParams _ _ docId range context) resps =
82+ combineResponses _method pid _config (ClientCapabilities _ textDocCaps _ _) (CodeActionParams _ _ _ _ context) resps =
9283 fmap compat $ List $ filter wasRequested $ (\ (List x) -> x) $ sconcat resps
9384 where
9485
@@ -175,24 +166,10 @@ instance PluginMethod TextDocumentCompletion where
175166 consumeCompletionResponse n (InR (CompletionList isCompleteResponse (List xx)))
176167
177168instance PluginMethod TextDocumentFormatting where
178- type ExtraParams TextDocumentFormatting = (FormattingType , T. Text )
179- getExtraParams _ (DocumentFormattingParams _ (TextDocumentIdentifier uri) params) = do
180- mf <- getVirtualFile $ toNormalizedUri uri
181- case mf of
182- Just vf -> pure $ Right (FormatText , virtualFileText vf)
183- Nothing -> pure $ Left $ responseError $ T. pack $ " Formatter plugin: could not get file contents for " ++ show uri
184-
185169 pluginEnabled _ pid conf = (PluginId $ formattingProvider conf) == pid
186170 combineResponses _ _ _ _ _ (x :| _) = x
187171
188172instance PluginMethod TextDocumentRangeFormatting where
189- type ExtraParams TextDocumentRangeFormatting = (FormattingType , T. Text )
190- getExtraParams _ (DocumentRangeFormattingParams _ (TextDocumentIdentifier uri) range params) = do
191- mf <- getVirtualFile $ toNormalizedUri uri
192- case mf of
193- Just vf -> pure $ Right (FormatRange range, virtualFileText vf)
194- Nothing -> pure $ Left $ responseError $ T. pack $ " Formatter plugin: could not get file contents for " ++ show uri
195-
196173 pluginEnabled _ pid conf = (PluginId $ formattingProvider conf) == pid
197174 combineResponses _ _ _ _ _ (x :| _) = x
198175
@@ -205,39 +182,30 @@ instance GCompare IdeMethod where
205182
206183-- | Combine handlers for the
207184newtype PluginHandler a (m :: Method FromClient Request )
208- = PluginHandler (PluginId -> a -> ExtraParams m -> MessageParams m -> LspM Config (NonEmpty (Either ResponseError (ResponseResult m ))))
185+ = PluginHandler (PluginId -> a -> MessageParams m -> LspM Config (NonEmpty (Either ResponseError (ResponseResult m ))))
209186
210187newtype PluginHandlers a = PluginHandlers (DMap IdeMethod (PluginHandler a ))
211188
212189instance Semigroup (PluginHandlers a ) where
213190 (PluginHandlers a) <> (PluginHandlers b) = PluginHandlers $ DMap. unionWithKey go a b
214191 where
215- go _ (PluginHandler f) (PluginHandler g) = PluginHandler $ \ pid ide extra params ->
216- (<>) <$> f pid ide extra params <*> g pid ide extra params
192+ go _ (PluginHandler f) (PluginHandler g) = PluginHandler $ \ pid ide params ->
193+ (<>) <$> f pid ide params <*> g pid ide params
217194
218195instance Monoid (PluginHandlers a ) where
219196 mempty = PluginHandlers mempty
220197
221- type SimpleHandler a m = a -> PluginId -> MessageParams m -> LspM Config (Either ResponseError (ResponseResult m ))
198+ type PluginMethodHandler a m = a -> PluginId -> MessageParams m -> LspM Config (Either ResponseError (ResponseResult m ))
222199
223200-- | Make a handler for plugins with no extra data
224201mkPluginHandler
225202 :: PluginMethod m
226203 => SClientMethod m
227- -> SimpleHandler ideState m
204+ -> PluginMethodHandler ideState m
228205 -> PluginHandlers ideState
229206mkPluginHandler m f = PluginHandlers $ DMap. singleton (IdeMethod m) (PluginHandler f')
230207 where
231- f' pid ide _ params = pure <$> f ide pid params
232-
233- mkPluginHandlerExtra
234- :: PluginMethod m
235- => SClientMethod m
236- -> (ideState -> PluginId -> ExtraParams m -> MessageParams m -> LspM Config (Either ResponseError (ResponseResult m )))
237- -> PluginHandlers ideState
238- mkPluginHandlerExtra m f = PluginHandlers $ DMap. singleton (IdeMethod m) (PluginHandler f')
239- where
240- f' pid ide extra params = pure <$> f ide pid extra params
208+ f' pid ide params = pure <$> f ide pid params
241209
242210defaultPluginDescriptor :: PluginId -> PluginDescriptor ideState
243211defaultPluginDescriptor plId =
@@ -294,6 +262,45 @@ pluginEnabledConfig f pid config = plcGlobalOn pluginConfig && f pluginConfig
294262data FormattingType = FormatText
295263 | FormatRange Range
296264
265+
266+ type FormattingMethod m =
267+ ( J. HasOptions (MessageParams m ) FormattingOptions
268+ , J. HasTextDocument (MessageParams m ) TextDocumentIdentifier
269+ , ResponseResult m ~ List TextEdit
270+ )
271+
272+ type FormattingHandler a
273+ = a
274+ -> FormattingType
275+ -> T. Text
276+ -> NormalizedFilePath
277+ -> FormattingOptions
278+ -> LspM Config (Either ResponseError (List TextEdit ))
279+
280+ mkFormattingHandlers :: forall a . FormattingHandler a -> PluginHandlers a
281+ mkFormattingHandlers f = mkPluginHandler STextDocumentFormatting (provider STextDocumentFormatting )
282+ <> mkPluginHandler STextDocumentRangeFormatting (provider STextDocumentRangeFormatting )
283+ where
284+ provider :: forall m . FormattingMethod m => SMethod m -> PluginMethodHandler a m
285+ provider m ide _pid params
286+ | Just nfp <- uriToNormalizedFilePath $ toNormalizedUri uri = do
287+ mf <- getVirtualFile $ toNormalizedUri uri
288+ case mf of
289+ Just vf -> do
290+ let typ = case m of
291+ STextDocumentFormatting -> FormatText
292+ STextDocumentRangeFormatting -> FormatRange (params ^. J. range)
293+ _ -> error " mkFormattingHandlers: impossible"
294+ f ide typ (virtualFileText vf) nfp opts
295+ Nothing -> pure $ Left $ responseError $ T. pack $ " Formatter plugin: could not get file contents for " ++ show uri
296+
297+ | otherwise = pure $ Left $ responseError $ T. pack $ " Formatter plugin: uriToFilePath failed for: " ++ show uri
298+ where
299+ uri = params ^. J. textDocument . J. uri
300+ opts = params ^. J. options
301+
302+ -- ---------------------------------------------------------------------
303+
297304responseError :: T. Text -> ResponseError
298305responseError txt = ResponseError InvalidParams txt Nothing
299306
0 commit comments