Skip to content

Commit d74d111

Browse files
authored
Merge pull request haskell#264 from georgefst/fourmolu
Add fourmolu plugin (attempt 2) and add Brittany for ghc-8.10.1
2 parents cb430d3 + 3df2bbc commit d74d111

18 files changed

+232
-60
lines changed

cabal.project

+8-1
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,11 @@ packages:
22
./
33
ghcide
44

5+
source-repository-package
6+
type: git
7+
location: https://github.com/bubba/brittany.git
8+
tag: c59655f10d5ad295c2481537fc8abf0a297d9d1c
9+
510
tests: true
611

712
package *
@@ -14,4 +19,6 @@ package ghcide
1419

1520
write-ghc-environment-files: never
1621

17-
index-state: 2020-07-27T12:40:45Z
22+
index-state: 2020-08-07T11:45:57Z
23+
24+
allow-newer: data-tree-print:base

exe/Main.hs

+3-3
Original file line numberDiff line numberDiff line change
@@ -67,10 +67,11 @@ import Ide.Plugin.Example as Example
6767
import Ide.Plugin.Example2 as Example2
6868
import Ide.Plugin.GhcIde as GhcIde
6969
import Ide.Plugin.Floskell as Floskell
70+
import Ide.Plugin.Fourmolu as Fourmolu
7071
import Ide.Plugin.Ormolu as Ormolu
7172
import Ide.Plugin.StylishHaskell as StylishHaskell
7273
import Ide.Plugin.Retrie as Retrie
73-
#if AGPL && !MIN_VERSION_ghc(8,10,1)
74+
#if AGPL
7475
import Ide.Plugin.Brittany as Brittany
7576
#endif
7677
import Ide.Plugin.Pragmas as Pragmas
@@ -102,15 +103,14 @@ idePlugins includeExamples = pluginDescToIdePlugins allPlugins
102103
GhcIde.descriptor "ghcide"
103104
, Pragmas.descriptor "pragmas"
104105
, Floskell.descriptor "floskell"
106+
, Fourmolu.descriptor "fourmolu"
105107
-- , genericDescriptor "generic"
106108
-- , ghcmodDescriptor "ghcmod"
107109
, Ormolu.descriptor "ormolu"
108110
, StylishHaskell.descriptor "stylish-haskell"
109111
, Retrie.descriptor "retrie"
110112
#if AGPL
111-
#if !MIN_VERSION_ghc(8,10,1)
112113
, Brittany.descriptor "brittany"
113-
#endif
114114
#endif
115115
, Eval.descriptor "eval"
116116
]

haskell-language-server.cabal

+8-7
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@ library
4545
Ide.Plugin.Eval
4646
Ide.Plugin.Example
4747
Ide.Plugin.Example2
48+
Ide.Plugin.Fourmolu
4849
Ide.Plugin.GhcIde
4950
Ide.Plugin.Ormolu
5051
Ide.Plugin.Pragmas
@@ -72,6 +73,7 @@ library
7273
, extra
7374
, filepath
7475
, floskell == 0.10.*
76+
, fourmolu ^>= 0.1
7577
, ghc
7678
, ghc-boot-th
7779
, ghcide >= 0.1
@@ -101,11 +103,10 @@ library
101103
else
102104
build-depends: unix
103105
if flag(agpl)
104-
if impl(ghc < 8.10)
105-
build-depends:
106-
brittany
107-
exposed-modules:
108-
Ide.Plugin.Brittany
106+
build-depends:
107+
brittany
108+
exposed-modules:
109+
Ide.Plugin.Brittany
109110

110111
ghc-options:
111112
-Wall
@@ -223,7 +224,7 @@ common hls-test-utils
223224
, hslogger
224225
, hspec
225226
, hspec-core
226-
, lsp-test >= 0.11.0.3
227+
, lsp-test >= 0.11.0.4
227228
, stm
228229
, tasty-hunit
229230
, temporary
@@ -252,7 +253,7 @@ test-suite func-test
252253
, haskell-lsp
253254
, haskell-lsp-types
254255
, lens
255-
, lsp-test >= 0.11.0.3
256+
, lsp-test >= 0.11.0.4
256257
, tasty
257258
, tasty-ant-xml >= 1.1.6
258259
, tasty-expected-failure

shell.nix

+1
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@ let defaultCompiler = "ghc" + lib.replaceStrings ["."] [""] haskellPackages.ghc.
4242
data-default-instances-old-locale
4343
extra
4444
floskell
45+
fourmolu
4546
fuzzy
4647
generic-deriving
4748
ghc-check

src/Ide/Plugin/Fourmolu.hs

+95
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,95 @@
1+
{-# LANGUAGE OverloadedStrings #-}
2+
{-# LANGUAGE PackageImports #-}
3+
{-# LANGUAGE RecordWildCards #-}
4+
{-# LANGUAGE ScopedTypeVariables #-}
5+
{-# LANGUAGE TypeApplications #-}
6+
7+
module Ide.Plugin.Fourmolu
8+
(
9+
descriptor
10+
, provider
11+
)
12+
where
13+
14+
import Control.Exception
15+
import qualified Data.Text as T
16+
import Development.IDE.Core.Rules
17+
import Development.IDE.Core.RuleTypes (GhcSession (GhcSession))
18+
import Development.IDE.Core.Shake (use)
19+
import Development.IDE.GHC.Util (hscEnv)
20+
import Development.IDE.Types.Diagnostics as D
21+
import Development.IDE.Types.Location
22+
import qualified DynFlags as D
23+
import qualified EnumSet as S
24+
import GHC
25+
import GHC.LanguageExtensions.Type
26+
import GhcPlugins (HscEnv (hsc_dflags))
27+
import Ide.Plugin.Formatter
28+
import Ide.PluginUtils
29+
import Ide.Types
30+
import Language.Haskell.LSP.Core (LspFuncs (withIndefiniteProgress),
31+
ProgressCancellable (Cancellable))
32+
import Language.Haskell.LSP.Types
33+
import "fourmolu" Ormolu
34+
import System.FilePath (takeFileName)
35+
import Text.Regex.TDFA.Text ()
36+
37+
-- ---------------------------------------------------------------------
38+
39+
descriptor :: PluginId -> PluginDescriptor
40+
descriptor plId = (defaultPluginDescriptor plId)
41+
{ pluginFormattingProvider = Just provider
42+
}
43+
44+
-- ---------------------------------------------------------------------
45+
46+
provider :: FormattingProvider IO
47+
provider lf ideState typ contents fp _ = withIndefiniteProgress lf title Cancellable $ do
48+
let
49+
fromDyn :: DynFlags -> IO [DynOption]
50+
fromDyn df =
51+
let
52+
pp =
53+
let p = D.sPgm_F $ D.settings df
54+
in if null p then [] else ["-pgmF=" <> p]
55+
pm = map (("-fplugin=" <>) . moduleNameString) $ D.pluginModNames df
56+
ex = map showExtension $ S.toList $ D.extensionFlags df
57+
in
58+
return $ map DynOption $ pp <> pm <> ex
59+
60+
ghc <- runAction "Fourmolu" ideState $ use GhcSession fp
61+
let df = hsc_dflags . hscEnv <$> ghc
62+
fileOpts <- case df of
63+
Nothing -> return []
64+
Just df -> fromDyn df
65+
66+
let
67+
fullRegion = RegionIndices Nothing Nothing
68+
rangeRegion s e = RegionIndices (Just $ s + 1) (Just $ e + 1)
69+
mkConf o region = do
70+
printerOpts <- loadConfigFile True (Just fp') defaultPrinterOpts
71+
return $ defaultConfig
72+
{ cfgDynOptions = o
73+
, cfgRegion = region
74+
, cfgDebug = True
75+
, cfgPrinterOpts = printerOpts
76+
}
77+
fmt :: T.Text -> Config RegionIndices -> IO (Either OrmoluException T.Text)
78+
fmt cont conf =
79+
try @OrmoluException (ormolu conf fp' $ T.unpack cont)
80+
fp' = fromNormalizedFilePath fp
81+
82+
case typ of
83+
FormatText -> ret <$> (fmt contents =<< mkConf fileOpts fullRegion)
84+
FormatRange (Range (Position sl _) (Position el _)) ->
85+
ret <$> (fmt contents =<< mkConf fileOpts (rangeRegion sl el))
86+
where
87+
title = T.pack $ "Formatting " <> takeFileName (fromNormalizedFilePath fp)
88+
ret :: Either OrmoluException T.Text -> Either ResponseError (List TextEdit)
89+
ret (Left err) = Left
90+
(responseError (T.pack $ "fourmoluCmd: " ++ show err) )
91+
ret (Right new) = Right (makeDiffTextEdit contents new)
92+
93+
showExtension :: Extension -> String
94+
showExtension Cpp = "-XCPP"
95+
showExtension other = "-X" ++ show other

src/Ide/Plugin/Ormolu.hs

+2-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
{-# LANGUAGE OverloadedStrings #-}
2+
{-# LANGUAGE PackageImports #-}
23
{-# LANGUAGE RecordWildCards #-}
34
{-# LANGUAGE ScopedTypeVariables #-}
45
{-# LANGUAGE TypeApplications #-}
@@ -29,7 +30,7 @@ import Ide.Types
2930
import Language.Haskell.LSP.Core (LspFuncs (withIndefiniteProgress),
3031
ProgressCancellable (Cancellable))
3132
import Language.Haskell.LSP.Types
32-
import Ormolu
33+
import "ormolu" Ormolu
3334
import System.FilePath (takeFileName)
3435
import Text.Regex.TDFA.Text ()
3536

stack-8.10.1.yaml

+11-8
Original file line numberDiff line numberDiff line change
@@ -8,34 +8,37 @@ ghc-options:
88
"$everything": -haddock
99

1010
extra-deps:
11+
- aeson-1.5.2.0
12+
- github: bubba/brittany
13+
commit: c59655f10d5ad295c2481537fc8abf0a297d9d1c
1114
- Cabal-3.0.2.0
1215
- hie-bios-0.6.1
1316
- cabal-plan-0.7.0.0
1417
- clock-0.7.2
15-
- floskell-0.10.3
18+
- data-tree-print-0.1.0.2
19+
- floskell-0.10.4
20+
- fourmolu-0.1.0.0@rev:1
1621
- ghc-exactprint-0.6.3
22+
- HsYAML-aeson-0.2.0.0@rev:2
1723
- lens-4.19.1
18-
- lsp-test-0.11.0.3
24+
- lsp-test-0.11.0.4
1925
- monad-dijkstra-0.1.1.2
2026
- optics-core-0.3
2127
- ormolu-0.1.2.0
2228
- retrie-0.1.1.1
23-
- stylish-haskell-0.11.0.0
29+
- stylish-haskell-0.11.0.3
2430
- semigroups-0.18.5
2531
- temporary-1.2.1.1
2632
- these-1.1
2733

2834
flags:
2935
haskell-language-server:
3036
pedantic: true
31-
# We want to let agpl be the default value in .cabal (True)
32-
# but brittany is not usable with ghc-8.10.1
33-
# see https://github.com/lspitzner/brittany/issues/269
34-
agpl: false
3537
retrie:
3638
BuildExecutable: false
3739

38-
# allow-newer: true
40+
# for data-tree-print's bounds on base (>=4.8 && <4.14); using base-4.14.0.0.
41+
allow-newer: true
3942

4043
nix:
4144
packages: [ icu libcxx zlib ]

stack-8.6.4.yaml

+11-6
Original file line numberDiff line numberDiff line change
@@ -9,15 +9,18 @@ ghc-options:
99
"$everything": -haddock
1010

1111
extra-deps:
12+
- aeson-1.5.2.0
1213
- ansi-terminal-0.10.3
13-
- base-compat-0.11.0
14-
- brittany-0.12.1.1@rev:2
14+
- base-compat-0.10.5
15+
- github: bubba/brittany
16+
commit: c59655f10d5ad295c2481537fc8abf0a297d9d1c
1517
- butcher-1.3.3.1
1618
- Cabal-3.0.2.0
1719
- cabal-plan-0.6.2.0
1820
- clock-0.7.2
1921
- extra-1.7.3
20-
- floskell-0.10.3
22+
- floskell-0.10.4
23+
- fourmolu-0.1.0.0@rev:1
2124
- fuzzy-0.1.0.0
2225
# - ghcide-0.1.0
2326
- ghc-check-0.5.0.1
@@ -30,26 +33,28 @@ extra-deps:
3033
- haskell-lsp-types-0.22.0.0
3134
- hie-bios-0.6.1
3235
- HsYAML-0.2.1.0@rev:1
33-
- HsYAML-aeson-0.2.0.0@rev:1
36+
- HsYAML-aeson-0.2.0.0@rev:2
3437
- indexed-profunctors-0.1
3538
- lens-4.18
36-
- lsp-test-0.11.0.3
39+
- lsp-test-0.11.0.4
3740
- monad-dijkstra-0.1.1.2
3841
- opentelemetry-0.4.2
3942
- optics-core-0.2
4043
- optparse-applicative-0.15.1.0
4144
- ormolu-0.1.2.0
4245
- parser-combinators-1.2.1
46+
- primitive-0.7.1.0
4347
- regex-base-0.94.0.0
4448
- regex-pcre-builtin-0.95.1.1.8.43
4549
- regex-tdfa-1.3.1.0
4650
- retrie-0.1.1.1
4751
- semialign-1.1
4852
# - github: wz1000/shake
4953
# commit: fb3859dca2e54d1bbb2c873e68ed225fa179fbef
50-
- stylish-haskell-0.11.0.0
54+
- stylish-haskell-0.11.0.3
5155
- tasty-rerun-1.1.17
5256
- temporary-1.2.1.1
57+
- these-1.1.1.1
5358
- type-equality-1
5459
- topograph-1
5560

stack-8.6.5.yaml

+11-6
Original file line numberDiff line numberDiff line change
@@ -8,15 +8,18 @@ ghc-options:
88
"$everything": -haddock
99

1010
extra-deps:
11+
- aeson-1.5.2.0
1112
- ansi-terminal-0.10.3
12-
- base-compat-0.11.0
13-
- brittany-0.12.1.1@rev:2
13+
- base-compat-0.10.5
14+
- github: bubba/brittany
15+
commit: c59655f10d5ad295c2481537fc8abf0a297d9d1c
1416
- butcher-1.3.3.1
1517
- Cabal-3.0.2.0
1618
- cabal-plan-0.6.2.0
1719
- clock-0.7.2
1820
- extra-1.7.3
19-
- floskell-0.10.3
21+
- floskell-0.10.4
22+
- fourmolu-0.1.0.0@rev:1
2023
- fuzzy-0.1.0.0
2124
# - ghcide-0.1.0
2225
- ghc-check-0.5.0.1
@@ -29,26 +32,28 @@ extra-deps:
2932
- haskell-lsp-types-0.22.0.0
3033
- hie-bios-0.6.1
3134
- HsYAML-0.2.1.0@rev:1
32-
- HsYAML-aeson-0.2.0.0@rev:1
35+
- HsYAML-aeson-0.2.0.0@rev:2
3336
- indexed-profunctors-0.1
3437
- lens-4.18
35-
- lsp-test-0.11.0.3
38+
- lsp-test-0.11.0.4
3639
- monad-dijkstra-0.1.1.2
3740
- opentelemetry-0.4.2
3841
- optics-core-0.2
3942
- optparse-applicative-0.15.1.0
4043
- ormolu-0.1.2.0
4144
- parser-combinators-1.2.1
45+
- primitive-0.7.1.0
4246
- regex-base-0.94.0.0
4347
- regex-pcre-builtin-0.95.1.1.8.43
4448
- regex-tdfa-1.3.1.0
4549
- retrie-0.1.1.1
4650
- semialign-1.1
4751
# - github: wz1000/shake
4852
# commit: fb3859dca2e54d1bbb2c873e68ed225fa179fbef
49-
- stylish-haskell-0.11.0.0
53+
- stylish-haskell-0.11.0.3
5054
- tasty-rerun-1.1.17
5155
- temporary-1.2.1.1
56+
- these-1.1.1.1
5257
- type-equality-1
5358
- topograph-1
5459

0 commit comments

Comments
 (0)