13
13
{-# LANGUAGE TypeFamilies #-}
14
14
{-# LANGUAGE DeriveAnyClass #-}
15
15
{-# LANGUAGE DeriveGeneric #-}
16
+ {-# LANGUAGE ConstraintKinds #-}
16
17
17
18
module Ide.Types
18
19
where
@@ -26,7 +27,7 @@ import Development.Shake hiding (command)
26
27
import Ide.Plugin.Config
27
28
import Language.LSP.Types
28
29
import Language.LSP.VFS
29
- import Language.LSP.Types.Lens hiding (id )
30
+ import Language.LSP.Types.Lens as J hiding (id )
30
31
import Language.LSP.Types.Capabilities
31
32
import Language.LSP.Server (LspM , getVirtualFile )
32
33
import Text.Regex.TDFA.Text ()
@@ -60,16 +61,6 @@ data PluginDescriptor ideState =
60
61
-- Only methods for which we know how to combine responses can be instances of 'PluginMethod'
61
62
class PluginMethod m where
62
63
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
-
73
64
-- | Parse the configuration to check if this plugin is enabled
74
65
pluginEnabled :: SMethod m -> PluginId -> Config -> Bool
75
66
@@ -88,7 +79,7 @@ class PluginMethod m where
88
79
89
80
instance PluginMethod TextDocumentCodeAction where
90
81
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 =
92
83
fmap compat $ List $ filter wasRequested $ (\ (List x) -> x) $ sconcat resps
93
84
where
94
85
@@ -175,24 +166,10 @@ instance PluginMethod TextDocumentCompletion where
175
166
consumeCompletionResponse n (InR (CompletionList isCompleteResponse (List xx)))
176
167
177
168
instance 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
-
185
169
pluginEnabled _ pid conf = (PluginId $ formattingProvider conf) == pid
186
170
combineResponses _ _ _ _ _ (x :| _) = x
187
171
188
172
instance 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
-
196
173
pluginEnabled _ pid conf = (PluginId $ formattingProvider conf) == pid
197
174
combineResponses _ _ _ _ _ (x :| _) = x
198
175
@@ -205,39 +182,30 @@ instance GCompare IdeMethod where
205
182
206
183
-- | Combine handlers for the
207
184
newtype 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 ))))
209
186
210
187
newtype PluginHandlers a = PluginHandlers (DMap IdeMethod (PluginHandler a ))
211
188
212
189
instance Semigroup (PluginHandlers a ) where
213
190
(PluginHandlers a) <> (PluginHandlers b) = PluginHandlers $ DMap. unionWithKey go a b
214
191
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
217
194
218
195
instance Monoid (PluginHandlers a ) where
219
196
mempty = PluginHandlers mempty
220
197
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 ))
222
199
223
200
-- | Make a handler for plugins with no extra data
224
201
mkPluginHandler
225
202
:: PluginMethod m
226
203
=> SClientMethod m
227
- -> SimpleHandler ideState m
204
+ -> PluginMethodHandler ideState m
228
205
-> PluginHandlers ideState
229
206
mkPluginHandler m f = PluginHandlers $ DMap. singleton (IdeMethod m) (PluginHandler f')
230
207
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
241
209
242
210
defaultPluginDescriptor :: PluginId -> PluginDescriptor ideState
243
211
defaultPluginDescriptor plId =
@@ -294,6 +262,45 @@ pluginEnabledConfig f pid config = plcGlobalOn pluginConfig && f pluginConfig
294
262
data FormattingType = FormatText
295
263
| FormatRange Range
296
264
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
+
297
304
responseError :: T. Text -> ResponseError
298
305
responseError txt = ResponseError InvalidParams txt Nothing
299
306
0 commit comments