Skip to content
This repository was archived by the owner on Oct 7, 2020. It is now read-only.

Commit 7ee36d6

Browse files
committed
Try to use configured formatter instead of brittany
1 parent 4c64789 commit 7ee36d6

File tree

6 files changed

+115
-35
lines changed

6 files changed

+115
-35
lines changed

hie-plugin-api/Haskell/Ide/Engine/PluginsIdeMonads.hs

Lines changed: 23 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,7 @@ module Haskell.Ide.Engine.PluginsIdeMonads
7575
, PublishDiagnosticsParams(..)
7676
, List(..)
7777
, FormattingOptions(..)
78+
, FormatCmdParams(..)
7879
)
7980
where
8081

@@ -208,9 +209,30 @@ type HoverProvider = Uri -> Position -> IdeM (IdeResult [Hover])
208209

209210
type SymbolProvider = Uri -> IdeDeferM (IdeResult [DocumentSymbol])
210211

212+
-- |Format Paramaters for Cmd.
213+
-- Turns the 'FormattingType' into a record.
214+
data FormatCmdParams = FormatCmdParams
215+
{ fmtUri :: Uri -- ^ Uri to the file to format
216+
, fmtType :: FormattingType -- ^ How much and what to format
217+
, fmtOptions :: FormattingOptions -- ^ Options for the formatter
218+
}
219+
deriving (Eq, Show, Generic, FromJSON, ToJSON)
220+
221+
-- | Format the document either as a whole or only a given Range of it.
211222
data FormattingType = FormatDocument
212223
| FormatRange Range
213-
type FormattingProvider = Uri -> FormattingType -> FormattingOptions -> IdeDeferM (IdeResult [TextEdit])
224+
deriving (Eq, Show, Generic, FromJSON, ToJSON)
225+
226+
-- |Formats the given Uri with the given options.
227+
-- A formatting type can be given to either format the whole documetn or only a Range.
228+
-- Fails if the formatter can not parse the source.
229+
-- Failing menas here that a IdeResultFail is returned.
230+
-- This can be used to display errors to the user, unless the error is an Internal one.
231+
-- The record 'IdeError' and 'IdeErrorCode' can be used to determine the type of error.
232+
type FormattingProvider = Uri -- ^ Uri to the file to format. Can be mapped to a file with `pluginGetFile`
233+
-> FormattingType -- ^ How much to format
234+
-> FormattingOptions -- ^ Options for the formatter
235+
-> IdeDeferM (IdeResult [TextEdit]) -- ^ Result of the formatting or the unchanged text.
214236

215237
data PluginDescriptor =
216238
PluginDescriptor { pluginId :: PluginId

src/Haskell/Ide/Engine/LSP/Reactor.hs

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,8 @@ data REnv = REnv
3737
, hoverProviders :: [HoverProvider]
3838
, symbolProviders :: [SymbolProvider]
3939
, formattingProviders :: Map.Map PluginId FormattingProvider
40+
-- | Ide Plugins that are available
41+
, idePlugins :: IdePlugins
4042
-- TODO: Add code action providers here
4143
}
4244

@@ -58,11 +60,12 @@ runReactor
5860
-> [HoverProvider]
5961
-> [SymbolProvider]
6062
-> Map.Map PluginId FormattingProvider
63+
-> IdePlugins
6164
-> R a
6265
-> IO a
63-
runReactor lf sc dps hps sps fps f = do
66+
runReactor lf sc dps hps sps fps plugins f = do
6467
pid <- getProcessID
65-
runReaderT f (REnv sc lf pid dps hps sps fps)
68+
runReaderT f (REnv sc lf pid dps hps sps fps plugins)
6669

6770
-- ---------------------------------------------------------------------
6871

src/Haskell/Ide/Engine/Plugin/Brittany.hs

Lines changed: 47 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -25,44 +25,75 @@ data FormatParams = FormatParams Int Uri (Maybe Range)
2525

2626
brittanyDescriptor :: PluginId -> PluginDescriptor
2727
brittanyDescriptor plId = PluginDescriptor
28-
{ pluginId = plId
29-
, pluginName = "Brittany"
30-
, pluginDesc = "Brittany is a tool to format source code."
31-
, pluginCommands = []
28+
{ pluginId = plId
29+
, pluginName = "Brittany"
30+
, pluginDesc = "Brittany is a tool to format source code."
31+
, pluginCommands = [PluginCommand "format" "Format the document" formatCmd]
3232
, pluginCodeActionProvider = Nothing
3333
, pluginDiagnosticProvider = Nothing
3434
, pluginHoverProvider = Nothing
3535
, pluginSymbolProvider = Nothing
3636
, pluginFormattingProvider = Just provider
3737
}
3838

39+
-- |Formatter provider of Brittany.
40+
-- Results can be deferred, e.g. the file is reformatted when it is loaded and type checked.
41+
-- If the provider fails an error is returned.
3942
provider :: FormattingProvider
40-
provider uri formatType opts = pluginGetFile "brittanyCmd: " uri $ \file -> do
41-
confFile <- liftIO $ getConfFile file
43+
provider = format
44+
45+
-- |Formatter of Brittany.
46+
-- Formats the given source in either a given Range or the whole Document.
47+
-- If the provider fails an error is returned that can be displayed to the user.
48+
format :: (MonadIO m, MonadIde m)
49+
=> Uri
50+
-> FormattingType
51+
-> FormattingOptions
52+
-> m (IdeResult [TextEdit])
53+
format uri formatType opts = pluginGetFile "brittanyCmd: " uri $ \fp -> do
54+
confFile <- liftIO $ getConfFile fp
4255
mtext <- readVFS uri
4356
case mtext of
44-
Nothing -> return $ IdeResultFail (IdeError InternalError "File was not open" Null)
57+
Nothing -> return
58+
$ IdeResultFail (IdeError InternalError "File was not open" Null)
4559
Just text -> case formatType of
46-
FormatRange r -> do
60+
FormatRange r -> do
4761
res <- liftIO $ runBrittany tabSize confFile $ extractRange r text
4862
case res of
49-
Left err -> return $ IdeResultFail (IdeError PluginError
50-
(T.pack $ "brittanyCmd: " ++ unlines (map showErr err)) Null)
63+
Left err -> return
64+
$ IdeResultFail
65+
(IdeError
66+
PluginError
67+
(T.pack $ "brittanyCmd: " ++ unlines (map showErr err))
68+
Null)
5169
Right newText -> do
5270
let textEdit = J.TextEdit (normalize r) newText
5371
return $ IdeResultOk [textEdit]
5472
FormatDocument -> do
5573
res <- liftIO $ runBrittany tabSize confFile text
5674
case res of
57-
Left err -> return $ IdeResultFail (IdeError PluginError
58-
(T.pack $ "brittanyCmd: " ++ unlines (map showErr err)) Null)
59-
Right newText ->
60-
return $ IdeResultOk [J.TextEdit (fullRange text) newText]
61-
where tabSize = opts ^. J.tabSize
75+
Left err -> return
76+
$ IdeResultFail
77+
(IdeError
78+
PluginError
79+
(T.pack $ "brittanyCmd: " ++ unlines (map showErr err))
80+
Null)
81+
Right newText -> return
82+
$ IdeResultOk [J.TextEdit (fullRange text) newText]
83+
where
84+
tabSize = opts ^. J.tabSize
85+
86+
-- | Format a source with the given options.
87+
-- Synchronized command.
88+
-- Other plugins can use this Command it to execute formatters.
89+
-- Command can be run by ``
90+
formatCmd :: CommandFunc FormatCmdParams [TextEdit]
91+
formatCmd = CmdSync $ \fmtParam ->
92+
format (fmtUri fmtParam) (fmtType fmtParam) (fmtOptions fmtParam)
6293

94+
-- | Extend to the line below to replace newline character, as above.
6395
normalize :: Range -> Range
6496
normalize (Range (Position sl _) (Position el _)) =
65-
-- Extend to the line below to replace newline character, as above
6697
Range (Position sl 0) (Position (el + 1) 0)
6798

6899
getConfFile :: FilePath -> IO (Maybe FilePath)

src/Haskell/Ide/Engine/Plugin/HsImport.hs

Lines changed: 20 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ import qualified GhcMod.Utils as GM
2121
import HsImport
2222
import Haskell.Ide.Engine.Config
2323
import Haskell.Ide.Engine.MonadTypes
24+
import qualified Haskell.Ide.Engine.Support.HieExtras as Hie
2425
import qualified Language.Haskell.LSP.Types as J
2526
import qualified Language.Haskell.LSP.Types.Lens as J
2627
import Haskell.Ide.Engine.PluginUtils
@@ -83,14 +84,25 @@ importModule uri modName =
8384

8485
if shouldFormat
8586
then do
86-
-- Format the import with Brittany
87-
confFile <- liftIO $ Brittany.getConfFile origInput
88-
newChanges <- forM mChanges $ mapM $ mapM (formatTextEdit confFile)
89-
newDocChanges <- forM mDocChanges $ mapM $ \(J.TextDocumentEdit vDocId tes) -> do
90-
ftes <- forM tes (formatTextEdit confFile)
91-
return (J.TextDocumentEdit vDocId ftes)
92-
93-
return $ IdeResultOk (J.WorkspaceEdit newChanges newDocChanges)
87+
config <- getConfig
88+
plugins <- getPlugins
89+
let mprovider = Hie.getFormattingPlugin config plugins
90+
case mprovider of
91+
Nothing -> return $ IdeResultOk (J.WorkspaceEdit mChanges mDocChanges)
92+
Just (plugin, _) -> do
93+
let fmtCmd = J.Command "unused"
94+
results <- forM mChanges $ mapM $ mapM $ (runPluginCommand (pluginId plugin) "format" . dynToJSON . toDynJSON)
95+
96+
97+
98+
-- -- Format the import with Brittany
99+
-- confFile <- liftIO $ Brittany.getConfFile origInput
100+
-- newChanges <- forM mChanges $ mapM $ mapM (formatTextEdit confFile)
101+
-- newDocChanges <- forM mDocChanges $ mapM $ \(J.TextDocumentEdit vDocId tes) -> do
102+
-- ftes <- forM tes (formatTextEdit confFile)
103+
-- return (J.TextDocumentEdit vDocId ftes)
104+
105+
return $ IdeResultOk (J.WorkspaceEdit mChanges mDocChanges) -- (J.WorkspaceEdit newChanges newDocChanges)
94106
else
95107
return $ IdeResultOk (J.WorkspaceEdit mChanges mDocChanges)
96108

src/Haskell/Ide/Engine/Support/HieExtras.hs

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ module Haskell.Ide.Engine.Support.HieExtras
2020
, runGhcModCommand
2121
, splitCaseCmd'
2222
, splitCaseCmd
23+
, getFormattingPlugin
2324
) where
2425

2526
import ConLike
@@ -52,6 +53,7 @@ import qualified GhcMod.Gap as GM
5253
import qualified GhcMod.LightGhc as GM
5354
import qualified GhcMod.Utils as GM
5455
import Haskell.Ide.Engine.ArtifactMap
56+
import Haskell.Ide.Engine.Config
5557
import Haskell.Ide.Engine.Context
5658
import Haskell.Ide.Engine.MonadFunctions
5759
import Haskell.Ide.Engine.MonadTypes
@@ -741,3 +743,12 @@ prefixes =
741743
, "$c"
742744
, "$m"
743745
]
746+
747+
-- ---------------------------------------------------------------------
748+
749+
getFormattingPlugin :: Config -> IdePlugins -> Maybe (PluginDescriptor, FormattingProvider)
750+
getFormattingPlugin config plugins = do
751+
let providerName = formattingProvider config
752+
fmtPlugin <- Map.lookup providerName (ipMap plugins)
753+
fmtProvider <- pluginFormattingProvider fmtPlugin
754+
return (fmtPlugin, fmtProvider)

src/Haskell/Ide/Engine/Transport/LspStdio.hs

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -122,7 +122,7 @@ run scheduler _origDir plugins captureFp = flip E.catches handlers $ do
122122

123123
let dp lf = do
124124
diagIn <- atomically newTChan
125-
let react = runReactor lf scheduler diagnosticProviders hps sps fps
125+
let react = runReactor lf scheduler diagnosticProviders hps sps fps plugins
126126
reactorFunc = react $ reactor rin diagIn
127127

128128
let errorHandler :: Scheduler.ErrorHandler
@@ -797,21 +797,22 @@ reactor inp diagIn = do
797797

798798
getFormattingProvider :: R FormattingProvider
799799
getFormattingProvider = do
800-
providers <- asks formattingProviders
800+
plugins <- asks idePlugins
801801
lf <- asks lspFuncs
802802
mc <- liftIO $ Core.config lf
803-
-- LL: Is this overengineered? Do we need a pluginFormattingProvider
804-
-- or should we just call plugins straight from here based on the providerType?
805-
let providerName = formattingProvider (fromMaybe def mc)
806-
mProvider = Map.lookup providerName providers
807-
case mProvider of
803+
let config = fromMaybe def mc
804+
-- LL: Is this overengineered? Do we need a pluginFormattingProvider
805+
-- or should we just call plugins straight from here based on the providerType?
806+
providerName = formattingProvider config
807+
mprovider = Hie.getFormattingPlugin config plugins
808+
case mprovider of
808809
Nothing -> do
809810
unless (providerName == "none") $ do
810811
let msg = providerName <> " is not a recognised plugin for formatting. Check your config"
811812
reactorSend $ NotShowMessage $ fmServerShowMessageNotification J.MtWarning msg
812813
reactorSend $ NotLogMessage $ fmServerLogMessageNotification J.MtWarning msg
813814
return (\_ _ _ -> return (IdeResultOk [])) -- nop formatter
814-
Just provider -> return provider
815+
Just (_, provider) -> return provider
815816

816817
-- ---------------------------------------------------------------------
817818

0 commit comments

Comments
 (0)