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

Commit 08e2bb0

Browse files
authored
Merge pull request #1481 from DavSanchez/plugin/ormolu_support
Ormolu formatter support
2 parents 9e9432a + 3978177 commit 08e2bb0

File tree

11 files changed

+140
-0
lines changed

11 files changed

+140
-0
lines changed

app/MainHie.hs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@ import Haskell.Ide.Engine.Plugin.Haddock
4545
import Haskell.Ide.Engine.Plugin.HfaAlign
4646
import Haskell.Ide.Engine.Plugin.HsImport
4747
import Haskell.Ide.Engine.Plugin.Liquid
48+
import Haskell.Ide.Engine.Plugin.Ormolu
4849
import Haskell.Ide.Engine.Plugin.Package
4950
import Haskell.Ide.Engine.Plugin.Pragmas
5051

@@ -69,6 +70,7 @@ plugins includeExamples = pluginDescToIdePlugins allPlugins
6970
, floskellDescriptor "floskell"
7071
, genericDescriptor "generic"
7172
, ghcmodDescriptor "ghcmod"
73+
, ormoluDescriptor "ormolu"
7274
]
7375
examplePlugins =
7476
[example2Descriptor "eg2"

haskell-ide-engine.cabal

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ library
3434
Haskell.Ide.Engine.Plugin.HfaAlign
3535
Haskell.Ide.Engine.Plugin.HsImport
3636
Haskell.Ide.Engine.Plugin.Liquid
37+
Haskell.Ide.Engine.Plugin.Ormolu
3738
Haskell.Ide.Engine.Plugin.Package
3839
Haskell.Ide.Engine.Plugin.Package.Compat
3940
Haskell.Ide.Engine.Plugin.Pragmas
@@ -47,6 +48,7 @@ library
4748
Haskell.Ide.Engine.Server
4849
Haskell.Ide.Engine.Types
4950
Haskell.Ide.Engine.Version
51+
5052
other-modules: Paths_haskell_ide_engine
5153
autogen-modules: Paths_haskell_ide_engine
5254
build-depends: Cabal >= 1.22
@@ -101,6 +103,8 @@ library
101103
, bytestring-trie
102104
, unliftio
103105
, hlint >= 2.2.2
106+
if impl(ghc >= 8.6)
107+
build-depends: ormolu
104108

105109
ghc-options: -Wall -Wredundant-constraints
106110
if flag(pedantic)
Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
{-# LANGUAGE TypeApplications #-}
2+
{-# LANGUAGE OverloadedStrings #-}
3+
{-# LANGUAGE CPP #-}
4+
5+
module Haskell.Ide.Engine.Plugin.Ormolu ( ormoluDescriptor ) where
6+
7+
import Haskell.Ide.Engine.MonadTypes
8+
9+
#if __GLASGOW_HASKELL__ >= 806
10+
import Control.Exception
11+
import Control.Monad.IO.Class ( liftIO , MonadIO(..) )
12+
import Data.Aeson ( Value ( Null ) )
13+
import Data.Text
14+
import Ormolu
15+
import Ormolu.Config (defaultConfig)
16+
import Ormolu.Exception (OrmoluException)
17+
import Haskell.Ide.Engine.PluginUtils
18+
#endif
19+
20+
ormoluDescriptor :: PluginId -> PluginDescriptor
21+
ormoluDescriptor plId = PluginDescriptor
22+
{ pluginId = plId
23+
, pluginName = "Ormolu"
24+
, pluginDesc = "A formatter for Haskell source code."
25+
, pluginCommands = []
26+
, pluginCodeActionProvider = Nothing
27+
, pluginDiagnosticProvider = Nothing
28+
, pluginHoverProvider = Nothing
29+
, pluginSymbolProvider = Nothing
30+
, pluginFormattingProvider = Just provider
31+
}
32+
33+
34+
provider :: FormattingProvider
35+
provider _contents _uri _typ _opts =
36+
#if __GLASGOW_HASKELL__ >= 806
37+
case _typ of
38+
FormatRange _ -> return $ IdeResultFail (IdeError PluginError (pack "Selection formatting for Ormolu is not currently supported.") Null)
39+
FormatText -> pluginGetFile _contents _uri $ \file -> do
40+
result <- liftIO $ try @OrmoluException (ormolu defaultConfig file (unpack _contents))
41+
case result of
42+
Left err -> return $ IdeResultFail (IdeError PluginError (pack $ "ormoluCmd: " ++ show err) Null)
43+
Right new -> return $ IdeResultOk [TextEdit (fullRange _contents) new]
44+
#else
45+
return $ IdeResultOk [] -- NOP formatter
46+
#endif

stack-8.6.1.yaml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@ extra-deps:
3838
- monoid-subclasses-0.4.6.1
3939
- multistate-0.8.0.1
4040
- parser-combinators-1.2.1
41+
- ormolu-0.0.2.0
4142
- primes-0.2.1.0
4243
- resolv-0.1.1.2
4344
- rope-utf16-splay-0.3.1.0

stack-8.6.2.yaml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ extra-deps:
3333
- monad-memo-0.4.1
3434
- multistate-0.8.0.1
3535
- parser-combinators-1.2.1
36+
- ormolu-0.0.2.0
3637
- rope-utf16-splay-0.3.1.0
3738
- strict-list-0.1.5
3839
- syz-0.2.0.0

stack-8.6.3.yaml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ extra-deps:
3131
- multistate-0.8.0.1
3232
- optparse-simple-0.1.0
3333
- parser-combinators-1.2.1
34+
- ormolu-0.0.2.0
3435
- rope-utf16-splay-0.3.1.0
3536
- syz-0.2.0.0
3637
- temporary-1.2.1.1

stack-8.6.4.yaml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ extra-deps:
2929
- monad-memo-0.4.1
3030
- multistate-0.8.0.1
3131
- parser-combinators-1.2.1
32+
- ormolu-0.0.2.0
3233
- rope-utf16-splay-0.3.1.0
3334
- syz-0.2.0.0
3435
- temporary-1.2.1.1

stack-8.6.5.yaml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ extra-deps:
2727
- lsp-test-0.10.0.0
2828
- monad-dijkstra-0.1.1.2@rev:1
2929
- parser-combinators-1.2.1
30+
- ormolu-0.0.2.0
3031
- syz-0.2.0.0
3132
- temporary-1.2.1.1
3233

stack.yaml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ extra-deps:
2828
- lsp-test-0.10.0.0
2929
- monad-dijkstra-0.1.1.2@rev:1
3030
- parser-combinators-1.2.1
31+
- ormolu-0.0.2.0
3132
- syz-0.2.0.0
3233
- temporary-1.2.1.1
3334
- unix-compat-0.5.2

test/functional/FormatSpec.hs

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -92,6 +92,19 @@ spec = do
9292
liftIO $ edits `shouldBe` [TextEdit (Range (Position 1 0) (Position 3 0))
9393
"foo x y = do\n print x\n return 42\n"]
9494

95+
describe "ormolu" $ do
96+
let formatLspConfig provider =
97+
object [ "languageServerHaskell" .= object ["formattingProvider" .= (provider :: Value)] ]
98+
99+
it "formats correctly" $ runSession hieCommand fullCaps "test/testdata" $ do
100+
sendNotification WorkspaceDidChangeConfiguration (DidChangeConfigurationParams (formatLspConfig "ormolu"))
101+
doc <- openDoc "Format.hs" "haskell"
102+
formatDoc doc (FormattingOptions 2 True)
103+
docContent <- documentContents doc
104+
case ghcVersion of
105+
GHC86 -> liftIO $ docContent `shouldBe` formattedOrmolu
106+
_ -> liftIO $ docContent `shouldBe` unchangedOrmolu
107+
95108

96109
formattedDocTabSize2 :: T.Text
97110
formattedDocTabSize2 =
@@ -165,3 +178,28 @@ formattedBrittanyPostFloskell =
165178
\bar s = do\n\
166179
\ x <- return \"hello\"\n\
167180
\ return \"asdf\"\n\n"
181+
182+
formattedOrmolu :: T.Text
183+
formattedOrmolu =
184+
"module Format where\n\
185+
\\n\
186+
\foo :: Int -> Int\n\
187+
\foo 3 = 2\n\
188+
\foo x = x\n\
189+
\\n\
190+
\bar :: String -> IO String\n\
191+
\bar s = do\n\
192+
\ x <- return \"hello\"\n\
193+
\ return \"asdf\"\n"
194+
195+
unchangedOrmolu :: T.Text
196+
unchangedOrmolu =
197+
"module Format where\n\
198+
\foo :: Int -> Int\n\
199+
\foo 3 = 2\n\
200+
\foo x = x\n\
201+
\bar :: String -> IO String\n\
202+
\bar s = do\n\
203+
\ x <- return \"hello\"\n\
204+
\ return \"asdf\"\n\
205+
\ \n"

0 commit comments

Comments
 (0)