@@ -23,6 +23,7 @@ import qualified Data.List as List
23
23
import Data.List.NonEmpty (NonEmpty , nonEmpty , toList )
24
24
import qualified Data.List.NonEmpty as NE
25
25
import qualified Data.Map as Map
26
+ import Data.Maybe (mapMaybe )
26
27
import Data.Some
27
28
import Data.String
28
29
import Data.Text (Text )
@@ -36,6 +37,7 @@ import qualified Development.IDE.Plugin as P
36
37
import Ide.Logger
37
38
import Ide.Plugin.Config
38
39
import Ide.Plugin.Error
40
+ import Ide.Plugin.HandleRequestTypes
39
41
import Ide.PluginUtils (getClientConfig )
40
42
import Ide.Types as HLS
41
43
import Language.LSP.Protocol.Message
@@ -65,23 +67,29 @@ instance Pretty Log where
65
67
LogResponseError (PluginId pId) err ->
66
68
pretty pId <> " :" <+> pretty err
67
69
LogNoPluginForMethod (Some method) ->
68
- " No plugin enabled for " <> pretty method
70
+ " No plugin handles this " <> pretty method <> " request. "
69
71
LogInvalidCommandIdentifier -> " Invalid command identifier"
70
72
ExceptionInPlugin plId (Some method) exception ->
71
73
" Exception in plugin " <> viaShow plId <> " while processing "
72
74
<> pretty method <> " : " <> viaShow exception
73
75
instance Show Log where show = renderString . layoutCompact . pretty
74
76
75
- noPluginEnabled :: Recorder (WithPriority Log ) -> SMethod m -> [PluginId ] -> IO (Either ResponseError c )
76
- noPluginEnabled recorder m fs' = do
77
+ noPluginHandles :: Recorder (WithPriority Log ) -> SMethod m -> [( PluginId , HandleRequestResult ) ] -> IO (Either ResponseError c )
78
+ noPluginHandles recorder m fs' = do
77
79
logWith recorder Warning (LogNoPluginForMethod $ Some m)
78
80
let err = ResponseError (InR ErrorCodes_MethodNotFound ) msg Nothing
79
- msg = pluginNotEnabled m fs'
81
+ msg = noPluginHandlesMsg m fs'
80
82
return $ Left err
81
- where pluginNotEnabled :: SMethod m -> [PluginId ] -> Text
82
- pluginNotEnabled method availPlugins =
83
- " No plugin enabled for " <> T. pack (show method) <> " , potentially available: "
84
- <> (T. intercalate " , " $ map (\ (PluginId plid) -> plid) availPlugins)
83
+ where noPluginHandlesMsg :: SMethod m -> [(PluginId , HandleRequestResult )] -> Text
84
+ noPluginHandlesMsg method [] = " No plugins are available to handle this " <> T. pack (show method) <> " request."
85
+ noPluginHandlesMsg method availPlugins =
86
+ " No plugins are available to handle this " <> T. pack (show method) <> " request.\n Plugins installed for this method, but not available to handle this request are:\n "
87
+ <> (T. intercalate " \n " $
88
+ map (\ (PluginId plid, pluginStatus) ->
89
+ plid
90
+ <> " "
91
+ <> (renderStrict . layoutCompact . pretty) pluginStatus)
92
+ availPlugins)
85
93
86
94
pluginDoesntExist :: PluginId -> Text
87
95
pluginDoesntExist (PluginId pid) = " Plugin " <> pid <> " doesn't exist"
@@ -213,8 +221,8 @@ executeCommandHandlers recorder ecs = requestHandler SMethod_WorkspaceExecuteCom
213
221
res <- runExceptT (f ide a) `catchAny` -- See Note [Exception handling in plugins]
214
222
(\ e -> pure $ Left $ PluginInternalError (exceptionInPlugin p SMethod_WorkspaceExecuteCommand e))
215
223
case res of
216
- (Left (PluginRequestRefused _ )) ->
217
- liftIO $ noPluginEnabled recorder SMethod_WorkspaceExecuteCommand ( fst <$> ecs)
224
+ (Left (PluginRequestRefused r )) ->
225
+ liftIO $ noPluginHandles recorder SMethod_WorkspaceExecuteCommand [(p, DoesNotHandleRequest r)]
218
226
(Left pluginErr) -> do
219
227
liftIO $ logErrors recorder [(p, pluginErr)]
220
228
pure $ Left $ toResponseError (p, pluginErr)
@@ -236,11 +244,13 @@ extensiblePlugins recorder plugins = mempty { P.pluginHandlers = handlers }
236
244
(IdeMethod m :=> IdeHandler fs') <- DMap. assocs handlers'
237
245
pure $ requestHandler m $ \ ide params -> do
238
246
config <- Ide.PluginUtils. getClientConfig
239
- -- Only run plugins that are allowed to run on this request
240
- let fs = filter (\ (_, desc, _) -> pluginEnabled m params desc config) fs'
247
+ -- Only run plugins that are allowed to run on this request, save the
248
+ -- list of disabled plugins incase that's all we have
249
+ let (fs, dfs) = List. partition (\ (_, desc, _) -> handlesRequest m params desc config == HandlesRequest ) fs'
250
+ let disabledPluginsReason = (\ (x, desc, _) -> (x, handlesRequest m params desc config)) <$> dfs
241
251
-- Clients generally don't display ResponseErrors so instead we log any that we come across
242
252
case nonEmpty fs of
243
- Nothing -> liftIO $ noPluginEnabled recorder m (( \ (x, _, _) -> x) <$> fs')
253
+ Nothing -> liftIO $ noPluginHandles recorder m disabledPluginsReason
244
254
Just neFs -> do
245
255
let plidsAndHandlers = fmap (\ (plid,_,handler) -> (plid,handler)) neFs
246
256
es <- runConcurrently exceptionInPlugin m plidsAndHandlers ide params
@@ -251,9 +261,12 @@ extensiblePlugins recorder plugins = mempty { P.pluginHandlers = handlers }
251
261
Nothing -> do
252
262
let noRefused (_, PluginRequestRefused _) = False
253
263
noRefused (_, _) = True
254
- filteredErrs = filter noRefused errs
255
- case nonEmpty filteredErrs of
256
- Nothing -> liftIO $ noPluginEnabled recorder m ((\ (x, _, _) -> x) <$> fs')
264
+ (asErrors, asRefused) = List. partition noRefused errs
265
+ convertPRR (pId, PluginRequestRefused r) = Just (pId, DoesNotHandleRequest r)
266
+ convertPRR _ = Nothing
267
+ asRefusedReason = mapMaybe convertPRR asRefused
268
+ case nonEmpty asErrors of
269
+ Nothing -> liftIO $ noPluginHandles recorder m (disabledPluginsReason <> asRefusedReason)
257
270
Just xs -> pure $ Left $ combineErrors xs
258
271
Just xs -> do
259
272
pure $ Right $ combineResponses m config caps params xs
@@ -274,8 +287,8 @@ extensibleNotificationPlugins recorder xs = mempty { P.pluginHandlers = handlers
274
287
(IdeNotification m :=> IdeNotificationHandler fs') <- DMap. assocs handlers'
275
288
pure $ notificationHandler m $ \ ide vfs params -> do
276
289
config <- Ide.PluginUtils. getClientConfig
277
- -- Only run plugins that are allowed to run on this request
278
- let fs = filter (\ (_, desc, _) -> pluginEnabled m params desc config) fs'
290
+ -- Only run plugins that are enabled for this request
291
+ let fs = filter (\ (_, desc, _) -> handlesRequest m params desc config == HandlesRequest ) fs'
279
292
case nonEmpty fs of
280
293
Nothing -> do
281
294
logWith recorder Warning (LogNoPluginForMethod $ Some m)
0 commit comments