@@ -112,6 +112,7 @@ instance Show (IdeCommand st) where show _ = "<ide command>"
112
112
113
113
data PluginDescriptor (ideState :: * ) =
114
114
PluginDescriptor { pluginId :: ! PluginId
115
+ -- ^ Unique identifier of the plugin.
115
116
, pluginRules :: ! (Rules () )
116
117
, pluginCommands :: ! [PluginCommand ideState ]
117
118
, pluginHandlers :: PluginHandlers ideState
@@ -126,11 +127,23 @@ data PluginDescriptor (ideState :: *) =
126
127
-- The file extension must have a leading '.'.
127
128
}
128
129
130
+ -- | Check whether the given plugin descriptor is responsible for the file with the given path.
131
+ -- Compares the file extension of the file at the given path with the file extension
132
+ -- the plugin is responsible for.
133
+ pluginResponsible :: Uri -> PluginDescriptor c -> Bool
134
+ pluginResponsible uri pluginDesc
135
+ | Just fp <- mfp
136
+ , T. pack (takeExtension fp) `elem` pluginFileType pluginDesc = True
137
+ | otherwise = False
138
+ where
139
+ mfp = uriToFilePath uri
140
+
129
141
-- | An existential wrapper of 'Properties'
130
142
data CustomConfig = forall r . CustomConfig (Properties r )
131
143
132
144
-- | Describes the configuration a plugin.
133
145
-- A plugin may be configurable in such form:
146
+ --
134
147
-- @
135
148
-- {
136
149
-- "plugin-id": {
@@ -143,6 +156,7 @@ data CustomConfig = forall r. CustomConfig (Properties r)
143
156
-- }
144
157
-- }
145
158
-- @
159
+ --
146
160
-- @globalOn@, @codeActionsOn@, and @codeLensOn@ etc. are called generic configs,
147
161
-- which can be inferred from handlers registered by the plugin.
148
162
-- @config@ is called custom config, which is defined using 'Properties'.
@@ -168,24 +182,65 @@ defaultConfigDescriptor = ConfigDescriptor True False (mkCustomConfig emptyPrope
168
182
-- Only methods for which we know how to combine responses can be instances of 'PluginMethod'
169
183
class HasTracing (MessageParams m ) => PluginMethod (k :: MethodType ) (m :: Method FromClient k ) where
170
184
171
- -- | Parse the configuration to check if this plugin is enabled
185
+ -- | Parse the configuration to check if this plugin is enabled.
186
+ -- Perform sanity checks on the message to see whether plugin is enabled
187
+ -- for this message in particular.
188
+ -- If a plugin is not enabled, its handlers, commands, etc... will not be
189
+ -- run for the given message.
190
+ --
191
+ -- Semantically, this method described whether a Plugin is enabled configuration wise
192
+ -- and is allowed to respond to the message. This might depend on the URI that is
193
+ -- associated to the Message Parameters, but doesn't have to. There are requests
194
+ -- with no associated URI that, consequentially, can't inspect the URI.
195
+ --
196
+ -- Common reason why a plugin might not be allowed to respond although it is enabled:
197
+ -- * Plugin can not handle requests associated to the specific URI
198
+ -- * Since the implementation of [cabal plugins](https://github.com/haskell/haskell-language-server/issues/2940)
199
+ -- HLS knows plugins specific for Haskell and specific for [Cabal file descriptions](https://cabal.readthedocs.io/en/3.6/cabal-package.html)
200
+ --
201
+ -- Strictly speaking, we are conflating two concepts here:
202
+ -- * Dynamically enabled (e.g. enabled on a per-message basis)
203
+ -- * Statically enabled (e.g. by configuration in the lsp-client)
204
+ -- * Strictly speaking, this might also change dynamically
205
+ --
206
+ -- But there is no use to split it up currently into two different methods for now.
172
207
pluginEnabled
173
208
:: SMethod m
209
+ -- ^ Method type.
174
210
-> MessageParams m
175
211
-- ^ Whether a plugin is enabled might depend on the message parameters
176
212
-- eg 'pluginFileType' specifies what file extension a plugin is allowed to handle
177
213
-> PluginDescriptor c
214
+ -- ^ Contains meta information such as PluginId and what file types this
215
+ -- plugin is able to handle.
178
216
-> Config
217
+ -- ^ Generic config description, expected to hold 'PluginConfig' configuration
218
+ -- for this plugin
179
219
-> Bool
220
+ -- ^ Is this plugin enabled and allowed to respond to the given request
221
+ -- with the given parameters?
180
222
181
223
default pluginEnabled :: (HasTextDocument (MessageParams m ) doc , HasUri doc Uri )
182
224
=> SMethod m -> MessageParams m -> PluginDescriptor c -> Config -> Bool
183
225
pluginEnabled _ params desc conf = pluginResponsible uri desc && plcGlobalOn (configForPlugin conf (pluginId desc))
184
226
where
185
227
uri = params ^. J. textDocument . J. uri
186
228
229
+ -- ---------------------------------------------------------------------
230
+ -- Plugin Requests
231
+ -- ---------------------------------------------------------------------
232
+
187
233
class PluginMethod Request m => PluginRequestMethod (m :: Method FromClient Request ) where
188
- -- | How to combine responses from different plugins
234
+ -- | How to combine responses from different plugins.
235
+ --
236
+ -- For example, for Hover requests, we might have multiple producers of
237
+ -- Hover information, we do not want to decide which one to display to the user
238
+ -- but allow here to define how to merge two hover request responses into one
239
+ -- glorious hover box.
240
+ --
241
+ -- However, sometimes only one handler of a request can realistically exist,
242
+ -- such as TextDocumentFormatting, it is safe to just unconditionally report
243
+ -- back one arbitrary result (arbitrary since it should only be one anyway).
189
244
combineResponses
190
245
:: SMethod m
191
246
-> Config -- ^ IDE Configuration
@@ -197,7 +252,6 @@ class PluginMethod Request m => PluginRequestMethod (m :: Method FromClient Requ
197
252
=> SMethod m -> Config -> ClientCapabilities -> MessageParams m -> NonEmpty (ResponseResult m) -> ResponseResult m
198
253
combineResponses _method _config _caps _params = sconcat
199
254
200
-
201
255
instance PluginMethod Request TextDocumentCodeAction where
202
256
pluginEnabled _ msgParams pluginDesc config =
203
257
pluginResponsible uri pluginDesc && pluginEnabledConfig plcCodeActionsOn (pluginId pluginDesc) config
@@ -231,36 +285,6 @@ instance PluginRequestMethod TextDocumentCodeAction where
231
285
, Just caKind <- ca ^. kind = any (\ k -> k `codeActionKindSubsumes` caKind) allowed
232
286
| otherwise = False
233
287
234
- instance PluginMethod TextDocumentDefinition where
235
- pluginEnabled _ _ _ = True
236
- combineResponses _ _ _ _ (x :| _) = x
237
-
238
- instance PluginMethod TextDocumentTypeDefinition where
239
- pluginEnabled _ _ _ = True
240
- combineResponses _ _ _ _ (x :| _) = x
241
-
242
- instance PluginMethod TextDocumentDocumentHighlight where
243
- pluginEnabled _ _ _ = True
244
- combineResponses _ _ _ _ (x :| _) = x
245
-
246
- instance PluginMethod TextDocumentReferences where
247
- pluginEnabled _ _ _ = True
248
- combineResponses _ _ _ _ (x :| _) = x
249
-
250
- instance PluginMethod WorkspaceSymbol where
251
- pluginEnabled _ _ _ = True
252
-
253
- -- | Check whether the given plugin descriptor is responsible for the file with the given path.
254
- -- Compares the file extension of the file at the given path with the file extension
255
- -- the plugin is responsible for.
256
- pluginResponsible :: Uri -> PluginDescriptor c -> Bool
257
- pluginResponsible uri pluginDesc
258
- | Just fp <- mfp
259
- , T. pack (takeExtension fp) `elem` pluginFileType pluginDesc = True
260
- | otherwise = False
261
- where
262
- mfp = uriToFilePath uri
263
-
264
288
instance PluginMethod Request TextDocumentDefinition where
265
289
pluginEnabled _ msgParams pluginDesc _ =
266
290
pluginResponsible uri pluginDesc
@@ -286,34 +310,34 @@ instance PluginMethod Request TextDocumentReferences where
286
310
uri = msgParams ^. J. textDocument . J. uri
287
311
288
312
instance PluginMethod Request WorkspaceSymbol where
313
+ -- Unconditionally enabled, but should it really be?
289
314
pluginEnabled _ _ _ _ = True
290
315
291
316
instance PluginMethod Request TextDocumentCodeLens where
292
- pluginEnabled _ msgParams pluginDesc config =
293
- pluginResponsible uri pluginDesc
317
+ pluginEnabled _ msgParams pluginDesc config = pluginResponsible uri pluginDesc
294
318
&& pluginEnabledConfig plcCodeLensOn (pluginId pluginDesc) config
295
319
where
296
320
uri = msgParams ^. J. textDocument . J. uri
297
321
298
322
instance PluginMethod Request TextDocumentRename where
299
- pluginEnabled _ msgParams pluginDesc config = pluginResponsible uri pluginDesc
323
+ pluginEnabled _ msgParams pluginDesc config = pluginResponsible uri pluginDesc
300
324
&& pluginEnabledConfig plcRenameOn (pluginId pluginDesc) config
301
325
where
302
326
uri = msgParams ^. J. textDocument . J. uri
303
327
instance PluginMethod Request TextDocumentHover where
304
- pluginEnabled _ msgParams pluginDesc config = pluginResponsible uri pluginDesc
328
+ pluginEnabled _ msgParams pluginDesc config = pluginResponsible uri pluginDesc
305
329
&& pluginEnabledConfig plcHoverOn (pluginId pluginDesc) config
306
330
where
307
331
uri = msgParams ^. J. textDocument . J. uri
308
332
309
333
instance PluginMethod Request TextDocumentDocumentSymbol where
310
- pluginEnabled _ msgParams pluginDesc config = pluginResponsible uri pluginDesc
334
+ pluginEnabled _ msgParams pluginDesc config = pluginResponsible uri pluginDesc
311
335
&& pluginEnabledConfig plcSymbolsOn (pluginId pluginDesc) config
312
336
where
313
337
uri = msgParams ^. J. textDocument . J. uri
314
338
315
339
instance PluginMethod Request TextDocumentCompletion where
316
- pluginEnabled _ msgParams pluginDesc config = pluginResponsible uri pluginDesc
340
+ pluginEnabled _ msgParams pluginDesc config = pluginResponsible uri pluginDesc
317
341
&& pluginEnabledConfig plcCompletionOn (pluginId pluginDesc) config
318
342
where
319
343
uri = msgParams ^. J. textDocument . J. uri
@@ -340,17 +364,20 @@ instance PluginMethod Request TextDocumentPrepareCallHierarchy where
340
364
pid = pluginId pluginDesc
341
365
342
366
instance PluginMethod Request TextDocumentSelectionRange where
343
- pluginEnabled _ msgParams pluginDesc conf = pluginResponsible uri pluginDesc && pluginEnabledConfig plcSelectionRangeOn pid conf
367
+ pluginEnabled _ msgParams pluginDesc conf = pluginResponsible uri pluginDesc
368
+ && pluginEnabledConfig plcSelectionRangeOn pid conf
344
369
where
345
370
uri = msgParams ^. J. textDocument . J. uri
346
371
pid = pluginId pluginDesc
347
372
348
373
instance PluginMethod Request CallHierarchyIncomingCalls where
374
+ -- This method has no URI parameter, thus no call to 'pluginResponsible'
349
375
pluginEnabled _ _ pluginDesc conf = pluginEnabledConfig plcCallHierarchyOn pid conf
350
376
where
351
377
pid = pluginId pluginDesc
352
378
353
379
instance PluginMethod Request CallHierarchyOutgoingCalls where
380
+ -- This method has no URI parameter, thus no call to 'pluginResponsible'
354
381
pluginEnabled _ _ pluginDesc conf = pluginEnabledConfig plcCallHierarchyOn pid conf
355
382
where
356
383
pid = pluginId pluginDesc
@@ -449,8 +476,13 @@ instance PluginRequestMethod CallHierarchyOutgoingCalls where
449
476
450
477
instance PluginRequestMethod CustomMethod where
451
478
combineResponses _ _ _ _ (x :| _) = x
479
+
480
+ -- ---------------------------------------------------------------------
481
+ -- Plugin Notifications
452
482
-- ---------------------------------------------------------------------
453
483
484
+ -- | Plugin Notification methods. No specific methods at the moment, but
485
+ -- might contain more in the future.
454
486
class PluginMethod Notification m => PluginNotificationMethod (m :: Method FromClient Notification ) where
455
487
456
488
@@ -462,27 +494,31 @@ instance PluginMethod Notification TextDocumentDidSave where
462
494
463
495
instance PluginMethod Notification TextDocumentDidClose where
464
496
465
-
466
- instance PluginNotificationMethod TextDocumentDidOpen where
467
-
468
- instance PluginNotificationMethod TextDocumentDidChange where
469
-
470
- instance PluginNotificationMethod TextDocumentDidSave where
471
-
472
- instance PluginNotificationMethod TextDocumentDidClose where
473
-
474
497
instance PluginMethod Notification WorkspaceDidChangeWatchedFiles where
498
+ -- This method has no URI parameter, thus no call to 'pluginResponsible'.
475
499
pluginEnabled _ _ desc conf = plcGlobalOn $ configForPlugin conf (pluginId desc)
476
500
477
501
instance PluginMethod Notification WorkspaceDidChangeWorkspaceFolders where
502
+ -- This method has no URI parameter, thus no call to 'pluginResponsible'.
478
503
pluginEnabled _ _ desc conf = plcGlobalOn $ configForPlugin conf (pluginId desc)
479
504
480
505
instance PluginMethod Notification WorkspaceDidChangeConfiguration where
506
+ -- This method has no URI parameter, thus no call to 'pluginResponsible'.
481
507
pluginEnabled _ _ desc conf = plcGlobalOn $ configForPlugin conf (pluginId desc)
482
508
483
509
instance PluginMethod Notification Initialized where
510
+ -- This method has no URI parameter, thus no call to 'pluginResponsible'.
484
511
pluginEnabled _ _ desc conf = plcGlobalOn $ configForPlugin conf (pluginId desc)
485
512
513
+
514
+ instance PluginNotificationMethod TextDocumentDidOpen where
515
+
516
+ instance PluginNotificationMethod TextDocumentDidChange where
517
+
518
+ instance PluginNotificationMethod TextDocumentDidSave where
519
+
520
+ instance PluginNotificationMethod TextDocumentDidClose where
521
+
486
522
instance PluginNotificationMethod WorkspaceDidChangeWatchedFiles where
487
523
488
524
instance PluginNotificationMethod WorkspaceDidChangeWorkspaceFolders where
@@ -559,6 +595,15 @@ mkPluginNotificationHandler m f
559
595
where
560
596
f' pid ide vfs = f ide vfs pid
561
597
598
+ -- | Set up a plugin descriptor, initialized with default values.
599
+ -- This is plugin descriptor is prepared for @haskell@ files, such as
600
+ --
601
+ -- * @.hs@
602
+ -- * @.lhs@
603
+ -- * @.hs-boot@
604
+ --
605
+ -- and handlers will be enabled for files with the appropriate file
606
+ -- extensions.
562
607
defaultPluginDescriptor :: PluginId -> PluginDescriptor ideState
563
608
defaultPluginDescriptor plId =
564
609
PluginDescriptor
@@ -572,6 +617,12 @@ defaultPluginDescriptor plId =
572
617
Nothing
573
618
[" .hs" , " .lhs" , " .hs-boot" ]
574
619
620
+ -- | Set up a plugin descriptor, initialized with default values.
621
+ -- This is plugin descriptor is prepared for @.cabal@ files and as such,
622
+ -- will only respond / run when @.cabal@ files are currently in scope.
623
+ --
624
+ -- Handles files with the following extensions:
625
+ -- * @.cabal@
575
626
defaultCabalPluginDescriptor :: PluginId -> PluginDescriptor ideState
576
627
defaultCabalPluginDescriptor plId =
577
628
PluginDescriptor
0 commit comments