Skip to content

Commit 90aae36

Browse files
committed
WIP. Using plugin descriptors, and combining them.
Proof of concept, seems to work in big pieces, needs huge amount of cleanup.
1 parent 5bae0dd commit 90aae36

File tree

9 files changed

+170
-41
lines changed

9 files changed

+170
-41
lines changed

exe/Main.hs

Lines changed: 43 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,7 @@ import HIE.Bios.Cradle
5252
import HIE.Bios.Environment
5353
import HIE.Bios.Types
5454
import Ide.Plugin
55+
-- import Ide.PluginDescriptors
5556
import Ide.Plugin.Config
5657
-- import Ide.Plugin.Formatter
5758
import Language.Haskell.LSP.Messages
@@ -79,12 +80,16 @@ import Ide.Plugin.Pragmas as Pragmas
7980

8081
-- ---------------------------------------------------------------------
8182

82-
-- The plugins configured for use in this instance of the language
83+
-- | TODO: these should come out of something like asGhcIdePlugin
84+
commandIds :: T.Text -> [T.Text]
85+
commandIds pid = "typesignature.add" : allLspCmdIds pid [("pragmas", Pragmas.commands)]
86+
87+
-- | The plugins configured for use in this instance of the language
8388
-- server.
8489
-- These can be freely added or removed to tailor the available
8590
-- features of the server.
86-
idePlugins :: Bool -> Plugin Config
87-
idePlugins includeExample
91+
_idePlugins :: Bool -> Plugin Config
92+
_idePlugins includeExample
8893
= Completions.plugin <>
8994
CodeAction.plugin <>
9095
formatterPlugins [("ormolu", Ormolu.provider)
@@ -93,12 +98,44 @@ idePlugins includeExample
9398
,("eg2", Example2.codeAction)
9499
,("pragmas", Pragmas.codeAction)] <>
95100
executeCommandPlugins [("pragmas", Pragmas.commands)] <>
96-
hoverPlugins [Example.hover, Example2.hover] <>
101+
hoverPlugins [("eg", Example.hover)
102+
,("eg2", Example2.hover)] <>
97103
if includeExample then Example.plugin <> Example2.plugin
98104
else mempty
99105

100-
commandIds :: T.Text -> [T.Text]
101-
commandIds pid = "typesignature.add" : allLspCmdIds pid [("pragmas", Pragmas.commands)]
106+
107+
-- | The plugins configured for use in this instance of the language
108+
-- server.
109+
-- These can be freely added or removed to tailor the available
110+
-- features of the server.
111+
idePlugins :: Bool -> Plugin Config
112+
idePlugins includeExamples
113+
= asGhcIdePlugin $ pluginDescToIdePlugins allPlugins
114+
where
115+
allPlugins = if includeExamples
116+
then basePlugins ++ examplePlugins
117+
else basePlugins
118+
basePlugins =
119+
[
120+
-- applyRefactDescriptor "applyrefact"
121+
-- , brittanyDescriptor "brittany"
122+
-- , haddockDescriptor "haddock"
123+
-- -- , hareDescriptor "hare"
124+
-- , hsimportDescriptor "hsimport"
125+
-- , liquidDescriptor "liquid"
126+
-- , packageDescriptor "package"
127+
-- , pragmasDescriptor "pragmas"
128+
Floskell.descriptor "floskell"
129+
-- , genericDescriptor "generic"
130+
-- , ghcmodDescriptor "ghcmod"
131+
, Ormolu.descriptor "ormolu"
132+
]
133+
examplePlugins =
134+
[Example.descriptor "eg"
135+
,Example2.descriptor "eg2"
136+
-- ,hfaAlignDescriptor "hfaa"
137+
]
138+
102139

103140
-- ---------------------------------------------------------------------
104141
-- Prefix for the cache path

src/Ide/Plugin.hs

Lines changed: 32 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
module Ide.Plugin
1111
(
1212
asGhcIdePlugin
13+
, pluginDescToIdePlugins
1314
, formatterPlugins
1415
, hoverPlugins
1516
, codeActionPlugins
@@ -29,7 +30,7 @@ import Data.Maybe
2930
import qualified Data.Text as T
3031
import Development.IDE.Core.Rules
3132
import Development.IDE.LSP.Server
32-
import Development.IDE.Plugin
33+
import Development.IDE.Plugin hiding (pluginCommands)
3334
import Development.IDE.Types.Diagnostics as D
3435
import Development.Shake hiding ( Diagnostic, command )
3536
import GHC.Generics
@@ -42,7 +43,6 @@ import Language.Haskell.LSP.Messages
4243
import Language.Haskell.LSP.Types
4344
import qualified Language.Haskell.LSP.Types as J
4445
import qualified Language.Haskell.LSP.Types.Capabilities as C
45-
-- import qualified Language.Haskell.LSP.Types.Lens as J
4646
import Language.Haskell.LSP.Types.Lens as L hiding (formatting, rangeFormatting)
4747
import Text.Regex.TDFA.Text()
4848

@@ -52,32 +52,50 @@ import Text.Regex.TDFA.Text()
5252
-- IdePlugins are arranged by kind of operation, 'Plugin' is arranged by message
5353
-- category ('Notifaction', 'Request' etc).
5454
asGhcIdePlugin :: IdePlugins -> Plugin Config
55-
asGhcIdePlugin _ = Plugin mempty mempty mempty
55+
asGhcIdePlugin mp =
56+
mkPlugin executeCommandPlugins (Just . pluginCommands) <>
57+
mkPlugin codeActionPlugins pluginCodeActionProvider <>
58+
-- diagnostics from pluginDiagnosticProvider
59+
mkPlugin hoverPlugins pluginHoverProvider <>
60+
-- symbols via pluginSymbolProvider
61+
mkPlugin formatterPlugins pluginFormattingProvider
62+
-- completions
63+
where
64+
justs (p, Just x) = [(p, x)]
65+
justs (_, Nothing) = []
5666

57-
-- First strp will be to bring the machinery from Ide.Plugin.Formatter over.
67+
ls = Map.toList (ipMap mp)
68+
69+
mkPlugin :: ([(PluginId, b)] -> t) -> (PluginDescriptor -> Maybe b) -> t
70+
mkPlugin maker selector
71+
= maker $ concatMap (\(pid, p) -> justs (pid, selector p)) ls
72+
73+
74+
pluginDescToIdePlugins :: [PluginDescriptor] -> IdePlugins
75+
pluginDescToIdePlugins plugins = IdePlugins $ Map.fromList $ map (\p -> (pluginId p, p)) plugins
5876

5977
-- ---------------------------------------------------------------------
6078

61-
codeActionPlugins :: [(T.Text, CodeActionProvider)] -> Plugin Config
79+
codeActionPlugins :: [(PluginId, CodeActionProvider)] -> Plugin Config
6280
codeActionPlugins cas = Plugin mempty codeActionRules (codeActionHandlers cas)
6381

6482
codeActionRules :: Rules ()
6583
codeActionRules = mempty
6684

67-
codeActionHandlers :: [(T.Text, CodeActionProvider)] -> PartialHandlers Config
85+
codeActionHandlers :: [(PluginId, CodeActionProvider)] -> PartialHandlers Config
6886
codeActionHandlers cas = PartialHandlers $ \WithMessage{..} x -> return x
6987
{ LSP.codeActionHandler
7088
= withResponse RspCodeAction (makeCodeAction cas)
7189
}
7290

73-
makeCodeAction :: [(T.Text, CodeActionProvider)]
91+
makeCodeAction :: [(PluginId, CodeActionProvider)]
7492
-> LSP.LspFuncs Config -> IdeState
7593
-> CodeActionParams
7694
-> IO (Either ResponseError (List CAResult))
7795
makeCodeAction cas lf ideState (CodeActionParams docId range context _) = do
7896
let caps = LSP.clientCapabilities lf
7997
unL (List ls) = ls
80-
r <- mapM (\(pid,provider) -> provider ideState (PluginId pid) docId range context) cas
98+
r <- mapM (\(pid,provider) -> provider ideState pid docId range context) cas
8199
let actions = filter wasRequested . concat $ map unL $ rights r
82100
res <- send caps actions
83101
return $ Right res
@@ -295,23 +313,23 @@ allLspCmdIds pid commands = concat $ map go commands
295313

296314
-- ---------------------------------------------------------------------
297315

298-
hoverPlugins :: [HoverProvider] -> Plugin Config
316+
hoverPlugins :: [(PluginId, HoverProvider)] -> Plugin Config
299317
hoverPlugins hs = Plugin mempty hoverRules (hoverHandlers hs)
300318

301319
hoverRules :: Rules ()
302320
hoverRules = mempty
303321

304-
hoverHandlers :: [HoverProvider] -> PartialHandlers Config
322+
hoverHandlers :: [(PluginId, HoverProvider)] -> PartialHandlers Config
305323
hoverHandlers hps = PartialHandlers $ \WithMessage{..} x ->
306324
return x{LSP.hoverHandler = withResponse RspHover (makeHover hps)}
307325

308-
makeHover :: [HoverProvider]
326+
makeHover :: [(PluginId, HoverProvider)]
309327
-> LSP.LspFuncs Config -> IdeState
310328
-> TextDocumentPositionParams
311329
-> IO (Either ResponseError (Maybe Hover))
312330
makeHover hps _lf ideState params
313331
= do
314-
mhs <- mapM (\p -> p ideState params) hps
332+
mhs <- mapM (\(_,p) -> p ideState params) hps
315333
-- TODO: We should support ServerCapabilities and declare that
316334
-- we don't support hover requests during initialization if we
317335
-- don't have any hover providers
@@ -327,7 +345,7 @@ makeHover hps _lf ideState params
327345
-- ---------------------------------------------------------------------
328346
-- ---------------------------------------------------------------------
329347

330-
formatterPlugins :: [(T.Text, FormattingProvider IO)] -> Plugin Config
348+
formatterPlugins :: [(PluginId, FormattingProvider IO)] -> Plugin Config
331349
formatterPlugins providers
332350
= Plugin mempty
333351
formatterRules
@@ -336,7 +354,7 @@ formatterPlugins providers
336354
formatterRules :: Rules ()
337355
formatterRules = mempty
338356

339-
formatterHandlers :: Map.Map T.Text (FormattingProvider IO) -> PartialHandlers Config
357+
formatterHandlers :: Map.Map PluginId (FormattingProvider IO) -> PartialHandlers Config
340358
formatterHandlers providers = PartialHandlers $ \WithMessage{..} x -> return x
341359
{ LSP.documentFormattingHandler
342360
= withResponse RspDocumentFormatting (formatting providers)

src/Ide/Plugin/Example.hs

Lines changed: 20 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,8 @@
1010

1111
module Ide.Plugin.Example
1212
(
13-
plugin
13+
descriptor
14+
, plugin
1415
, hover
1516
, codeAction
1617
) where
@@ -21,13 +22,13 @@ import Data.Aeson.Types (toJSON, fromJSON, Value(..), Result(..))
2122
import Data.Binary
2223
import Data.Functor
2324
import qualified Data.HashMap.Strict as Map
24-
import Data.Hashable
2525
import qualified Data.HashSet as HashSet
26+
import Data.Hashable
2627
import qualified Data.Text as T
2728
import Data.Typeable
2829
import Development.IDE.Core.OfInterest
29-
import Development.IDE.Core.Rules
3030
import Development.IDE.Core.RuleTypes
31+
import Development.IDE.Core.Rules
3132
import Development.IDE.Core.Service
3233
import Development.IDE.Core.Shake
3334
import Development.IDE.LSP.Server
@@ -36,15 +37,30 @@ import Development.IDE.Types.Diagnostics as D
3637
import Development.IDE.Types.Location
3738
import Development.IDE.Types.Logger
3839
import Development.Shake hiding ( Diagnostic )
39-
import Ide.Types
4040
import GHC.Generics
41+
import Ide.Types
4142
import qualified Language.Haskell.LSP.Core as LSP
4243
import Language.Haskell.LSP.Messages
4344
import Language.Haskell.LSP.Types
4445
import Text.Regex.TDFA.Text()
4546

4647
-- ---------------------------------------------------------------------
4748

49+
descriptor :: PluginId -> PluginDescriptor
50+
descriptor plId = PluginDescriptor
51+
{ pluginId = plId
52+
, pluginRules = exampleRules
53+
, pluginCommands = []
54+
, pluginCodeActionProvider = Just codeAction
55+
, pluginDiagnosticProvider = Nothing
56+
, pluginHoverProvider = Just hover
57+
, pluginSymbolProvider = Nothing
58+
, pluginFormattingProvider = Nothing
59+
, pluginCompletionProvider = Nothing
60+
}
61+
62+
-- ---------------------------------------------------------------------
63+
4864
plugin :: Plugin c
4965
plugin = Plugin mempty exampleRules handlersExample
5066
-- <> codeActionPlugin codeAction

src/Ide/Plugin/Example2.hs

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,8 @@
1010

1111
module Ide.Plugin.Example2
1212
(
13-
plugin
13+
descriptor
14+
, plugin
1415
, hover
1516
, codeAction
1617
) where
@@ -45,6 +46,21 @@ import Text.Regex.TDFA.Text()
4546

4647
-- ---------------------------------------------------------------------
4748

49+
descriptor :: PluginId -> PluginDescriptor
50+
descriptor plId = PluginDescriptor
51+
{ pluginId = plId
52+
, pluginRules = exampleRules
53+
, pluginCommands = []
54+
, pluginCodeActionProvider = Just codeAction
55+
, pluginDiagnosticProvider = Nothing
56+
, pluginHoverProvider = Just hover
57+
, pluginSymbolProvider = Nothing
58+
, pluginFormattingProvider = Nothing
59+
, pluginCompletionProvider = Nothing
60+
}
61+
62+
-- ---------------------------------------------------------------------
63+
4864
plugin :: Plugin c
4965
plugin = Plugin mempty exampleRules handlersExample2
5066
-- <> codeActionPlugin codeAction

src/Ide/Plugin/Floskell.hs

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,8 @@
77

88
module Ide.Plugin.Floskell
99
(
10-
provider
10+
descriptor
11+
, provider
1112
)
1213
where
1314

@@ -24,6 +25,21 @@ import Text.Regex.TDFA.Text()
2425

2526
-- ---------------------------------------------------------------------
2627

28+
descriptor :: PluginId -> PluginDescriptor
29+
descriptor plId = PluginDescriptor
30+
{ pluginId = plId
31+
, pluginRules = mempty
32+
, pluginCommands = []
33+
, pluginCodeActionProvider = Nothing
34+
, pluginDiagnosticProvider = Nothing
35+
, pluginHoverProvider = Nothing
36+
, pluginSymbolProvider = Nothing
37+
, pluginFormattingProvider = Just provider
38+
, pluginCompletionProvider = Nothing
39+
}
40+
41+
-- ---------------------------------------------------------------------
42+
2743
-- | Format provider of Floskell.
2844
-- Formats the given source in either a given Range or the whole Document.
2945
-- If the provider fails an error is returned that can be displayed to the user.

src/Ide/Plugin/Formatter.hs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ import Text.Regex.TDFA.Text()
3434

3535
-- ---------------------------------------------------------------------
3636

37-
formatting :: Map.Map T.Text (FormattingProvider IO)
37+
formatting :: Map.Map PluginId (FormattingProvider IO)
3838
-> LSP.LspFuncs Config -> IdeState -> DocumentFormattingParams
3939
-> IO (Either ResponseError (List TextEdit))
4040
formatting providers lf ideState
@@ -43,7 +43,7 @@ formatting providers lf ideState
4343

4444
-- ---------------------------------------------------------------------
4545

46-
rangeFormatting :: Map.Map T.Text (FormattingProvider IO)
46+
rangeFormatting :: Map.Map PluginId (FormattingProvider IO)
4747
-> LSP.LspFuncs Config -> IdeState -> DocumentRangeFormattingParams
4848
-> IO (Either ResponseError (List TextEdit))
4949
rangeFormatting providers lf ideState
@@ -52,13 +52,13 @@ rangeFormatting providers lf ideState
5252

5353
-- ---------------------------------------------------------------------
5454

55-
doFormatting :: LSP.LspFuncs Config -> Map.Map T.Text (FormattingProvider IO)
55+
doFormatting :: LSP.LspFuncs Config -> Map.Map PluginId (FormattingProvider IO)
5656
-> IdeState -> FormattingType -> Uri -> FormattingOptions
5757
-> IO (Either ResponseError (List TextEdit))
5858
doFormatting lf providers ideState ft uri params = do
5959
mc <- LSP.config lf
6060
let mf = maybe "none" formattingProvider mc
61-
case Map.lookup mf providers of
61+
case Map.lookup (PluginId mf) providers of
6262
Just provider ->
6363
case uriToFilePath uri of
6464
Just (toNormalizedFilePath -> fp) -> do

src/Ide/Plugin/Ormolu.hs

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,8 @@
77

88
module Ide.Plugin.Ormolu
99
(
10-
provider
10+
descriptor
11+
, provider
1112
)
1213
where
1314

@@ -32,6 +33,21 @@ import Text.Regex.TDFA.Text()
3233

3334
-- ---------------------------------------------------------------------
3435

36+
descriptor :: PluginId -> PluginDescriptor
37+
descriptor plId = PluginDescriptor
38+
{ pluginId = plId
39+
, pluginRules = mempty
40+
, pluginCommands = []
41+
, pluginCodeActionProvider = Nothing
42+
, pluginDiagnosticProvider = Nothing
43+
, pluginHoverProvider = Nothing
44+
, pluginSymbolProvider = Nothing
45+
, pluginFormattingProvider = Just provider
46+
, pluginCompletionProvider = Nothing
47+
}
48+
49+
-- ---------------------------------------------------------------------
50+
3551
provider :: FormattingProvider IO
3652
#if __GLASGOW_HASKELL__ >= 806
3753
provider ideState typ contents fp _ = do

0 commit comments

Comments
 (0)