fourmolu 0.7.0.1 → 0.8.0.0
raw patch · 42 files changed
+438/−241 lines, 42 filesPVP ok
version bump matches the API change (PVP)
API changes (from Hackage documentation)
- Ormolu: [poDiffFriendlyImportExport] :: PrinterOpts f -> f Bool
- Ormolu: [poImportExportCommaStyle] :: PrinterOpts f -> f CommaStyle
- Ormolu.Config: [poDiffFriendlyImportExport] :: PrinterOpts f -> f Bool
- Ormolu.Config: [poImportExportCommaStyle] :: PrinterOpts f -> f CommaStyle
- Ormolu.Printer: [poDiffFriendlyImportExport] :: PrinterOpts f -> f Bool
- Ormolu.Printer: [poImportExportCommaStyle] :: PrinterOpts f -> f CommaStyle
+ Ormolu: [poImportExportStyle] :: PrinterOpts f -> f ImportExportStyle
+ Ormolu.Config: ImportExportDiffFriendly :: ImportExportStyle
+ Ormolu.Config: ImportExportLeading :: ImportExportStyle
+ Ormolu.Config: ImportExportTrailing :: ImportExportStyle
+ Ormolu.Config: [poImportExportStyle] :: PrinterOpts f -> f ImportExportStyle
+ Ormolu.Config: data ImportExportStyle
+ Ormolu.Config: instance Ormolu.Config.PrinterOptsFieldType Ormolu.Config.Types.ImportExportStyle
+ Ormolu.Diff.Text: instance GHC.Show.Show Ormolu.Diff.Text.Hunk
+ Ormolu.Printer: [poImportExportStyle] :: PrinterOpts f -> f ImportExportStyle
+ Ormolu.Utils.Cabal: instance GHC.Show.Show Ormolu.Utils.Cabal.CachedCabalFile
- Ormolu: PrinterOpts :: f Int -> f CommaStyle -> f CommaStyle -> f Bool -> f Bool -> f Bool -> f Bool -> f HaddockPrintStyle -> f Int -> PrinterOpts f
+ Ormolu: PrinterOpts :: f Int -> f CommaStyle -> f ImportExportStyle -> f Bool -> f Bool -> f Bool -> f HaddockPrintStyle -> f Int -> PrinterOpts f
- Ormolu.Config: PrinterOpts :: f Int -> f CommaStyle -> f CommaStyle -> f Bool -> f Bool -> f Bool -> f Bool -> f HaddockPrintStyle -> f Int -> PrinterOpts f
+ Ormolu.Config: PrinterOpts :: f Int -> f CommaStyle -> f ImportExportStyle -> f Bool -> f Bool -> f Bool -> f HaddockPrintStyle -> f Int -> PrinterOpts f
- Ormolu.Config: [PrinterOptsFieldMeta] :: PrinterOptsFieldType a => {metaName :: String, metaGetField :: forall f. PrinterOpts f -> f a, metaPlaceholder :: String, metaHelp :: String, metaDefault :: a} -> PrinterOptsFieldMeta a
+ Ormolu.Config: [PrinterOptsFieldMeta] :: PrinterOptsFieldType a => String -> (forall f. PrinterOpts f -> f a) -> String -> String -> a -> PrinterOptsFieldMeta a
- Ormolu.Printer: PrinterOpts :: f Int -> f CommaStyle -> f CommaStyle -> f Bool -> f Bool -> f Bool -> f Bool -> f HaddockPrintStyle -> f Int -> PrinterOpts f
+ Ormolu.Printer: PrinterOpts :: f Int -> f CommaStyle -> f ImportExportStyle -> f Bool -> f Bool -> f Bool -> f HaddockPrintStyle -> f Int -> PrinterOpts f
Files
- CHANGELOG.md +28/−0
- README.md +8/−6
- app/Main.hs +33/−17
- data/cabal-tests/Bar.hs +3/−0
- data/cabal-tests/Foo.hs +3/−0
- data/cabal-tests/test.cabal +13/−0
- data/diff-tests/inputs/applicative-after.hs +8/−0
- data/diff-tests/inputs/applicative-before.hs +7/−0
- data/diff-tests/inputs/longer-v2.hs +16/−0
- data/diff-tests/inputs/longer.hs +16/−0
- data/diff-tests/outputs/no-preceding.txt +2/−1
- data/diff-tests/outputs/simple-hunk.txt +2/−1
- data/diff-tests/outputs/trimming-trailing-both-eof.txt +10/−0
- data/diff-tests/outputs/trimming-trailing-both-out-of-margin.txt +13/−0
- data/examples/declaration/type-families/closed-type-family/with-comments-four-out.hs +10/−0
- data/examples/declaration/type-families/closed-type-family/with-comments-out.hs +10/−0
- data/examples/declaration/type-families/closed-type-family/with-comments.hs +12/−0
- data/examples/declaration/value/function/list-comprehensions-four-out.hs +5/−0
- data/examples/declaration/value/function/list-comprehensions-out.hs +5/−0
- data/examples/declaration/value/function/list-comprehensions.hs +4/−0
- data/fourmolu/import-export/output-ImportExportDiffFriendly.hs +32/−0
- data/fourmolu/import-export/output-ImportExportLeading.hs +33/−0
- data/fourmolu/import-export/output-ImportExportTrailing.hs +33/−0
- data/fourmolu/import-export/output-Leading-diff_friendly.hs +0/−32
- data/fourmolu/import-export/output-Leading.hs +0/−33
- data/fourmolu/import-export/output-Trailing-diff_friendly.hs +0/−32
- data/fourmolu/import-export/output-Trailing.hs +0/−33
- fourmolu.cabal +2/−1
- fourmolu.yaml +1/−2
- src/Ormolu/Config.hs +21/−22
- src/Ormolu/Config/TH.hs +7/−1
- src/Ormolu/Config/Types.hs +10/−6
- src/Ormolu/Diff/Text.hs +8/−10
- src/Ormolu/Printer/Combinators.hs +5/−1
- src/Ormolu/Printer/Meat/Declaration/TypeFamily.hs +1/−1
- src/Ormolu/Printer/Meat/Declaration/Value.hs +1/−1
- src/Ormolu/Printer/Meat/ImportExport.hs +17/−12
- src/Ormolu/Printer/Meat/Module.hs +1/−1
- src/Ormolu/Utils/Cabal.hs +41/−18
- tests/Ormolu/CabalInfoSpec.hs +10/−0
- tests/Ormolu/Config/PrinterOptsSpec.hs +5/−10
- tests/Ormolu/Diff/TextSpec.hs +2/−0
CHANGELOG.md view
@@ -1,3 +1,29 @@+## Fourmolu 0.8.0.0++* Consolidate `import-export-comma-style` and `diff-friendly-import-export` into a new option `import-export-style` ([#201](https://github.com/fourmolu/fourmolu/pull/207))+* Accept folders as input ([#213](https://github.com/fourmolu/fourmolu/issues/213))++### Upstream changes:++#### Ormolu 0.5.0.1++* Fixed a bug in the diff printing functionality. [Issue+ 886](https://github.com/tweag/ormolu/issues/886).++* Indent closing bracket for list comprehensions in `do` blocks.+ [Issue 893](https://github.com/tweag/ormolu/issues/893).++* Fix `hs-source-dirs: .` resulting in failing to find a `.cabal` file for a+ Haskell source file. [Issue 909](https://github.com/tweag/ormolu/issues/909).++* Comments in closed type family declarations are now indented correctly.+ [Issue 913](https://github.com/tweag/ormolu/issues/913).++* Cache `.cabal` file parsing and processing when given multiple input files in+ the same project. This results in dramatic speedups on projects which have+ both huge `.cabal` files and a large number of individual modules. [Issue+ 897](https://github.com/tweag/ormolu/issues/897).+ ## Fourmolu 0.7.0.1 * Fix bad copy/paste where parsing errors for `haddock-style` would mention `CommaStyle`@@ -17,6 +43,8 @@ ``` * Fixed issue with `import-export-comma-style` for multiline import/export elements ([#187](https://github.com/fourmolu/fourmolu/pull/187)) * Multiline haddock comments with consecutive empty newlines will no longer report an "AST differs" error ([#172](https://github.com/fourmolu/fourmolu/issues/172))++### Upstream changes: #### Ormolu 0.5.0.0
README.md view
@@ -45,10 +45,9 @@ |----------------------|---------------|-------------| | `indentation` | any integer | Number of spaces to use as indentation | | `comma-style` | `leading`, `trailing` | Where to put the comma in lists, tuples, etc. |-| `import-export-comma-style` | `leading`, `trailing` | Where to put the comma in import/export lists |+| `import-export-style` | `leading`, `trailing`, `diff-friendly` | How to format multiline import/export lists (`diff-friendly` lists have trailing commas but keep the open-parentheses on the same line as the `import` line) | | `indent-wheres` | `true`, `false` | `false` means save space by only half-indenting the `where` keyword | | `record-brace-space` | `true`, `false` | `rec {x = 1}` vs `rec{x = 1}` |-| `diff-friendly-import-export` | `true`, `false` | Make multiline import/export lists as diff-friendly as possible (keeping the open-parentheses on the same line as the `import` line or not) | | `respectful` | `true`, `false` | Whether to respect user-specified newlines, e.g. in import groupings | | `haddock-style` | `multi-line`, `single-line` | Whether multiline haddocks should use `{-` or `--` | | `newlines-between-decls` | any integer | number of newlines between top-level declarations |@@ -65,10 +64,9 @@ ```yaml indentation: 4 comma-style: leading-import-export-comma-style: leading+import-export-style: diff-friendly indent-wheres: false record-brace-space: false-diff-friendly-import-export: true respectful: true haddock-style: multi-line newlines-between-decls: 1@@ -80,10 +78,9 @@ ```yaml indentation: 2 comma-style: trailing-import-export-comma-style: trailing+import-export-style: trailing indent-wheres: true record-brace-space: true-diff-friendly-import-export: false respectful: false haddock-style: single-line newlines-between-decls: 1@@ -134,6 +131,11 @@ ```console $ fourmolu --mode inplace $(git ls-files '*.hs')+```++Or directly specify a directory (will recursively process all *.hs files)+```console+$ fourmolu -i src ``` To check if files are are already formatted (useful on CI):
app/Main.hs view
@@ -14,7 +14,7 @@ import Control.Monad import Data.Bool (bool) import Data.Functor.Identity (Identity (..))-import Data.List (intercalate, sort)+import Data.List (intercalate, isSuffixOf, sort) import qualified Data.Map as Map import Data.Maybe (fromMaybe, mapMaybe) import qualified Data.Set as Set@@ -38,7 +38,7 @@ ) import Ormolu.Utils.IO import Paths_fourmolu (version)-import System.Directory (getCurrentDirectory)+import System.Directory (doesDirectoryExist, getCurrentDirectory, listDirectory) import System.Exit (ExitCode (..), exitWith) import qualified System.FilePath as FP import System.IO (hPutStrLn, stderr)@@ -61,24 +61,40 @@ optSourceType cfg + getHaskellFiles input = do+ isDir <- doesDirectoryExist input+ if isDir+ then filter (".hs" `isSuffixOf`) <$> listDirectoryRecursive input+ else return [input] -- plain file+ listDirectoryRecursive fp = fmap concat . mapM (go . (fp FP.</>)) =<< listDirectory fp+ where+ go child = do+ isDir <- doesDirectoryExist child+ if isDir+ then listDirectoryRecursive child+ else pure [child]++ selectFailure = \case+ ExitSuccess -> Nothing+ ExitFailure n -> Just n++ formatInputs inputs = do+ files <- Set.toAscList . Set.fromList . concat <$> mapM getHaskellFiles inputs+ errorCodes <- mapMaybe selectFailure <$> mapM (formatOne' . Just) files+ return $+ if null errorCodes+ then ExitSuccess+ else+ ExitFailure $+ if all (== 100) errorCodes+ then 100+ else 102+ exitCode <- case optInputFiles of [] -> formatOne' Nothing ["-"] -> formatOne' Nothing- [x] -> formatOne' (Just x)- xs -> do- let selectFailure = \case- ExitSuccess -> Nothing- ExitFailure n -> Just n- errorCodes <-- mapMaybe selectFailure <$> mapM (formatOne' . Just) (sort xs)- return $- if null errorCodes- then ExitSuccess- else- ExitFailure $- if all (== 100) errorCodes- then 100- else 102+ xs -> formatInputs xs+ exitWith exitCode -- | Build the full config, by adding 'PrinterOpts' from a file, if found.
+ data/cabal-tests/Bar.hs view
@@ -0,0 +1,3 @@+module Foo where++import Data.List qualified as List
+ data/cabal-tests/Foo.hs view
@@ -0,0 +1,3 @@+module Foo where++import Data.List qualified as List
+ data/cabal-tests/test.cabal view
@@ -0,0 +1,13 @@+cabal-version: 2.4+name: test+version: 0++library+ exposed-modules: Foo+ hs-source-dirs: .+ default-extensions: ImportQualifiedPost++executable app+ main-is: Main+ other-modules: Bar+ default-extensions: ImportQualifiedPost
+ data/diff-tests/inputs/applicative-after.hs view
@@ -0,0 +1,8 @@+testPermParser :: Permutation Parser String+testPermParser =+ f+ <$> toPermutationWithDefault 'x' (char 'a')+ <*> toPermutationWithDefault 'y' (char 'b')+ <*> toPermutationWithDefault 'z' (char 'c')+ where+ f a b c = [a, b, c]
+ data/diff-tests/inputs/applicative-before.hs view
@@ -0,0 +1,7 @@+testPermParser :: Permutation Parser String+testPermParser =+ f <$> toPermutationWithDefault 'x' (char 'a')+ <*> toPermutationWithDefault 'y' (char 'b')+ <*> toPermutationWithDefault 'z' (char 'c')+ where+ f a b c = [a, b, c]
+ data/diff-tests/inputs/longer-v2.hs view
@@ -0,0 +1,16 @@+module Main (foo) where++a+b+c++main :: IO ()+main = return ()++d+e+f+g++foo :: Int+foo = 6
+ data/diff-tests/inputs/longer.hs view
@@ -0,0 +1,16 @@+module Main (main) where++a+b+c++main :: IO ()+main = return ()++d+e+f+g++foo :: Int+foo = 5
data/diff-tests/outputs/no-preceding.txt view
@@ -1,6 +1,7 @@ TEST-@@ -1,3 +1,3 @@+@@ -1,4 +1,4 @@ - module Main (foo) where + module Main (main) where+ main :: IO () main = return ()
data/diff-tests/outputs/simple-hunk.txt view
@@ -1,9 +1,10 @@ TEST-@@ -1,6 +1,6 @@+@@ -1,7 +1,7 @@ module Main (main) where main :: IO () - main = return () + main = pure ()+ foo :: Int foo = 5
+ data/diff-tests/outputs/trimming-trailing-both-eof.txt view
@@ -0,0 +1,10 @@+TEST+@@ -1,6 +1,7 @@+ testPermParser :: Permutation Parser String+ testPermParser =+- f <$> toPermutationWithDefault 'x' (char 'a')++ f++ <$> toPermutationWithDefault 'x' (char 'a')+ <*> toPermutationWithDefault 'y' (char 'b')+ <*> toPermutationWithDefault 'z' (char 'c')+ where
+ data/diff-tests/outputs/trimming-trailing-both-out-of-margin.txt view
@@ -0,0 +1,13 @@+TEST+@@ -1,4 +1,4 @@+- module Main (main) where++ module Main (foo) where++ a+ b+@@ -13,4 +13,4 @@+ g++ foo :: Int+- foo = 5++ foo = 6
+ data/examples/declaration/type-families/closed-type-family/with-comments-four-out.hs view
@@ -0,0 +1,10 @@+type family LT a b where+ -- 0+ LT 0 _ = True+ -- 1+ LT 1 0 = False+ LT 1 _ = True+ -- 2+ LT 2 0 = False+ LT 2 1 = False+ LT 2 _ = True
+ data/examples/declaration/type-families/closed-type-family/with-comments-out.hs view
@@ -0,0 +1,10 @@+type family LT a b where+ -- 0+ LT 0 _ = True+ -- 1+ LT 1 0 = False+ LT 1 _ = True+ -- 2+ LT 2 0 = False+ LT 2 1 = False+ LT 2 _ = True
+ data/examples/declaration/type-families/closed-type-family/with-comments.hs view
@@ -0,0 +1,12 @@+type family LT a b where+ -- 0+ LT 0 _ = True++ -- 1+ LT 1 0 = False+ LT 1 _ = True++ -- 2+ LT 2 0 = False+ LT 2 1 = False+ LT 2 _ = True
data/examples/declaration/value/function/list-comprehensions-four-out.hs view
@@ -22,3 +22,8 @@ , d ] ]++a = do+ [ c+ | c <- d+ ]
data/examples/declaration/value/function/list-comprehensions-out.hs view
@@ -22,3 +22,8 @@ d ] ]++a = do+ [ c+ | c <- d+ ]
data/examples/declaration/value/function/list-comprehensions.hs view
@@ -20,3 +20,7 @@ c, d ] ]++a = do+ [ c+ | c <- d ]
+ data/fourmolu/import-export/output-ImportExportDiffFriendly.hs view
@@ -0,0 +1,32 @@+module Foo (+ foo,++ -- * Something+ bar,+ -- | A multiline+ -- comment here+ baz,++ -- * Another thing+ MyClass (+ class1,+ class2+ ),+) where++import qualified MegaModule as M (+ Either,+ Maybe (Just, Nothing),+ MaybeT (..),+ Monad (+ return,+ (>>),+ (>>=)+ ),+ MonadBaseControl,+ join,+ liftIO,+ void,+ (<<<),+ (>>>),+ )
+ data/fourmolu/import-export/output-ImportExportLeading.hs view
@@ -0,0 +1,33 @@+module Foo+ ( foo++ -- * Something+ , bar+ -- | A multiline+ -- comment here+ , baz++ -- * Another thing+ , MyClass+ ( class1+ , class2+ )+ )+where++import qualified MegaModule as M+ ( Either+ , Maybe (Just, Nothing)+ , MaybeT (..)+ , Monad+ ( return+ , (>>)+ , (>>=)+ )+ , MonadBaseControl+ , join+ , liftIO+ , void+ , (<<<)+ , (>>>)+ )
+ data/fourmolu/import-export/output-ImportExportTrailing.hs view
@@ -0,0 +1,33 @@+module Foo+ ( foo,++ -- * Something+ bar,+ -- | A multiline+ -- comment here+ baz,++ -- * Another thing+ MyClass+ ( class1,+ class2+ ),+ )+where++import qualified MegaModule as M+ ( Either,+ Maybe (Just, Nothing),+ MaybeT (..),+ Monad+ ( return,+ (>>),+ (>>=)+ ),+ MonadBaseControl,+ join,+ liftIO,+ void,+ (<<<),+ (>>>),+ )
− data/fourmolu/import-export/output-Leading-diff_friendly.hs
@@ -1,32 +0,0 @@-module Foo (- foo-- -- * Something- , bar- -- | A multiline- -- comment here- , baz-- -- * Another thing- , MyClass (- class1- , class2- )-) where--import qualified MegaModule as M (- Either- , Maybe (Just, Nothing)- , MaybeT (..)- , Monad (- return- , (>>)- , (>>=)- )- , MonadBaseControl- , join- , liftIO- , void- , (<<<)- , (>>>)- )
− data/fourmolu/import-export/output-Leading.hs
@@ -1,33 +0,0 @@-module Foo- ( foo-- -- * Something- , bar- -- | A multiline- -- comment here- , baz-- -- * Another thing- , MyClass- ( class1- , class2- )- )-where--import qualified MegaModule as M- ( Either- , Maybe (Just, Nothing)- , MaybeT (..)- , Monad- ( return- , (>>)- , (>>=)- )- , MonadBaseControl- , join- , liftIO- , void- , (<<<)- , (>>>)- )
− data/fourmolu/import-export/output-Trailing-diff_friendly.hs
@@ -1,32 +0,0 @@-module Foo (- foo,-- -- * Something- bar,- -- | A multiline- -- comment here- baz,-- -- * Another thing- MyClass (- class1,- class2- ),-) where--import qualified MegaModule as M (- Either,- Maybe (Just, Nothing),- MaybeT (..),- Monad (- return,- (>>),- (>>=)- ),- MonadBaseControl,- join,- liftIO,- void,- (<<<),- (>>>),- )
− data/fourmolu/import-export/output-Trailing.hs
@@ -1,33 +0,0 @@-module Foo- ( foo,-- -- * Something- bar,- -- | A multiline- -- comment here- baz,-- -- * Another thing- MyClass- ( class1,- class2- ),- )-where--import qualified MegaModule as M- ( Either,- Maybe (Just, Nothing),- MaybeT (..),- Monad- ( return,- (>>),- (>>=)- ),- MonadBaseControl,- join,- liftIO,- void,- (<<<),- (>>>),- )
fourmolu.cabal view
@@ -1,6 +1,6 @@ cabal-version: 2.4 name: fourmolu-version: 0.7.0.1+version: 0.8.0.0 license: BSD-3-Clause license-file: LICENSE.md maintainer:@@ -17,6 +17,7 @@ extra-source-files: data/**/*.hs data/**/*.txt+ data/**/*.cabal extract-hackage-info/hackage-info.json -- needed for integration tests fixity-tests/*.hs
fourmolu.yaml view
@@ -1,10 +1,9 @@ # Options should imitate Ormolu's style indentation: 2 comma-style: trailing-import-export-comma-style: trailing+import-export-style: trailing indent-wheres: true record-brace-space: true-diff-friendly-import-export: false respectful: false haddock-style: single-line newlines-between-decls: 1
src/Ormolu/Config.hs view
@@ -34,6 +34,7 @@ fillMissingPrinterOpts, CommaStyle (..), HaddockPrintStyle (..),+ ImportExportStyle (..), -- ** Loading Fourmolu configuration loadConfigFile,@@ -217,10 +218,9 @@ overFieldsM f $(unpackFieldsWithSuffix 'PrinterOpts "0") = do poIndentation <- f poIndentation0 poCommaStyle <- f poCommaStyle0- poImportExportCommaStyle <- f poImportExportCommaStyle0+ poImportExportStyle <- f poImportExportStyle0 poIndentWheres <- f poIndentWheres0 poRecordBraceSpace <- f poRecordBraceSpace0- poDiffFriendlyImportExport <- f poDiffFriendlyImportExport0 poRespectful <- f poRespectful0 poHaddockStyle <- f poHaddockStyle0 poNewlinesBetweenDecls <- f poNewlinesBetweenDecls0@@ -279,16 +279,13 @@ (showAllValues commaStyleMap), metaDefault = Leading },- poImportExportCommaStyle =+ poImportExportStyle = PrinterOptsFieldMeta- { metaName = "import-export-comma-style",- metaGetField = poImportExportCommaStyle,+ { metaName = "import-export-style",+ metaGetField = poImportExportStyle, metaPlaceholder = "STYLE",- metaHelp =- printf- "How to place commas in multi-line import and export lists (choices: %s)"- (showAllValues commaStyleMap),- metaDefault = Trailing+ metaHelp = "Styling of import/export lists",+ metaDefault = ImportExportDiffFriendly }, poIndentWheres = PrinterOptsFieldMeta@@ -310,18 +307,6 @@ metaHelp = "Whether to leave a space before an opening record brace", metaDefault = False },- poDiffFriendlyImportExport =- PrinterOptsFieldMeta- { metaName = "diff-friendly-import-export",- metaGetField = poDiffFriendlyImportExport,- metaPlaceholder = "BOOL",- metaHelp =- unwords- [ "Whether to make use of extra commas in import/export lists",- "(as opposed to Ormolu's style)"- ],- metaDefault = True- }, poRespectful = PrinterOptsFieldMeta { metaName = "respectful",@@ -392,6 +377,15 @@ ] ) +importExportStyleMap :: BijectiveMap ImportExportStyle+importExportStyleMap =+ $( mkBijectiveMap+ [ ('ImportExportLeading, "leading"),+ ('ImportExportTrailing, "trailing"),+ ('ImportExportDiffFriendly, "diff-friendly")+ ]+ )+ instance PrinterOptsFieldType CommaStyle where parseJSON = parseJSONWith commaStyleMap "CommaStyle" parseText = parseTextWith commaStyleMap@@ -401,6 +395,11 @@ parseJSON = parseJSONWith haddockPrintStyleMap "HaddockPrintStyle" parseText = parseTextWith haddockPrintStyleMap showText = show . showTextWith haddockPrintStyleMap++instance PrinterOptsFieldType ImportExportStyle where+ parseJSON = parseJSONWith importExportStyleMap "ImportExportStyle"+ parseText = parseTextWith importExportStyleMap+ showText = show . showTextWith importExportStyleMap ---------------------------------------------------------------------------- -- BijectiveMap helpers
src/Ormolu/Config/TH.hs view
@@ -15,7 +15,8 @@ ) where -import Control.Monad (forM, (>=>))+import Control.Monad (forM, when, (>=>))+import Data.Containers.ListUtils (nubOrd) import Data.List (intercalate, nub) import Language.Haskell.TH import Language.Haskell.TH.Syntax (lift)@@ -69,6 +70,7 @@ -- * all Names in given list refer to a constructor of type `a` -- * all Names in given list refer to a 0-arity constructor -- * all constructors in type `a` are accounted for.+-- * each constructor in type `a` must be provided only once. mkBijectiveMap :: [(Name, String)] -> Q Exp mkBijectiveMap mapping = do let (conNames, allOptions) = unzip mapping@@ -103,6 +105,10 @@ case filter (`notElem` conNames) (concatMap getConstructorNames allConsInType) of [] -> return () missing -> fail $ "Missing constructors: " ++ show missing++ -- check for duplicate constructors+ when (nubOrd conNames /= conNames) $+ fail "mkBijectiveMap requires each constructor to be provided only once" unknown <- newName "unknown" let parser =
src/Ormolu/Config/Types.hs view
@@ -1,11 +1,11 @@ {-# LANGUAGE DeriveGeneric #-} --- | This module only defines PrinterOpts, needed to be separate because of--- Template Haskell staging restrictions.+-- | This module defines PrinterOpts and related types module Ormolu.Config.Types ( PrinterOpts (..), CommaStyle (..), HaddockPrintStyle (..),+ ImportExportStyle (..), ) where @@ -17,14 +17,12 @@ poIndentation :: f Int, -- | Whether to place commas at start or end of lines poCommaStyle :: f CommaStyle,- -- | Whether to place commas at start or end of import-export lines- poImportExportCommaStyle :: f CommaStyle,+ -- | Styling of import/export lists+ poImportExportStyle :: f ImportExportStyle, -- | Whether to indent `where` blocks poIndentWheres :: f Bool, -- | Leave space before opening record brace poRecordBraceSpace :: f Bool,- -- | Trailing commas with parentheses on separate lines- poDiffFriendlyImportExport :: f Bool, -- | Be less opinionated about spaces/newlines etc. poRespectful :: f Bool, -- | How to print doc comments@@ -42,4 +40,10 @@ data HaddockPrintStyle = HaddockSingleLine | HaddockMultiLine+ deriving (Eq, Show, Enum, Bounded)++data ImportExportStyle+ = ImportExportLeading+ | ImportExportTrailing+ | ImportExportDiffFriendly deriving (Eq, Show, Enum, Bounded)
src/Ormolu/Diff/Text.hs view
@@ -38,10 +38,7 @@ -- whole diff will be displayed. textDiffSelectedLines :: IntSet }- deriving (Eq)--instance Show TextDiff where- show (TextDiff path _ _) = "TextDiff " ++ show path ++ " _ _"+ deriving (Eq, Show) -- | List of lines tagged by 'D.Both', 'D.First', or 'D.Second'. type DiffList = [D.Diff [Text]]@@ -57,6 +54,7 @@ hunkSecondLength :: Int, hunkDiff :: DiffList }+ deriving (Show) ---------------------------------------------------------------------------- -- API@@ -211,8 +209,8 @@ [] -> if gotChanges then- let p = reverse (take margin bothHistory)- currentAcc' = addBothAfter p currentAcc+ let currentAcc' = addBothAfter p currentAcc+ p = take margin (reverse bothHistory) in case formHunk (currentAcc' []) of Nothing -> hunksAcc [] Just hunk -> hunksAcc [hunk]@@ -235,12 +233,12 @@ piece -> if gotChanges then- let p = reverse bothHistory- currentAcc' = currentAcc . addBothBefore p (piece :)+ let currentAcc' = currentAcc . addBothBefore p (piece :)+ p = reverse bothHistory in go 0 True hunksAcc currentAcc' [] xs else- let p = reverse (take margin bothHistory)- currentAcc' = addBothBefore p (piece :)+ let currentAcc' = addBothBefore p (piece :)+ p = reverse (take margin bothHistory) in go 0 True hunksAcc currentAcc' [] xs addBothBefore [] acc = acc addBothBefore p acc = (D.Both p p :) . acc
src/Ormolu/Printer/Combinators.hs view
@@ -321,7 +321,11 @@ -- | Delimiting combination with 'comma' for import-export lists. -- To be used with `sep`. commaDelImportExport :: R ()-commaDelImportExport = getPrinterOpt poImportExportCommaStyle >>= commaDel'+commaDelImportExport =+ getPrinterOpt poImportExportStyle >>= \case+ ImportExportLeading -> commaDel' Leading+ ImportExportTrailing -> commaDel' Trailing+ ImportExportDiffFriendly -> commaDel' Trailing commaDel' :: CommaStyle -> R () commaDel' = \case
src/Ormolu/Printer/Meat/Declaration/TypeFamily.hs view
@@ -55,7 +55,7 @@ txt ".." Just eqs -> do newline- sep newline (located' (inci . p_tyFamInstEqn)) eqs+ inci (sep newline (located' p_tyFamInstEqn) eqs) p_familyResultSigL :: Located (FamilyResultSig GhcPs) ->
src/Ormolu/Printer/Meat/Declaration/Value.hs view
@@ -751,7 +751,7 @@ forM_ moduleName $ \m -> atom m *> txt "." txt header p_stmts exprPlacement (p_hsExpr' S) es- compBody = brackets N . located es $ \xs -> do+ compBody = brackets s . located es $ \xs -> do let p_parBody = sep (breakpoint >> txt "|" >> space)
src/Ormolu/Printer/Meat/ImportExport.hs view
@@ -16,13 +16,11 @@ import GHC.LanguageExtensions.Type import GHC.Types.SrcLoc import GHC.Unit.Types-import Ormolu.Config (CommaStyle (..), PrinterOpts (poImportExportCommaStyle), poDiffFriendlyImportExport)+import Ormolu.Config import Ormolu.Printer.Combinators import Ormolu.Printer.Meat.Common import Ormolu.Utils (RelativePos (..), attachRelativePos) -{- HLINT ignore "Use camelCase" -}- p_hsmodExports :: [LIE GhcPs] -> R () p_hsmodExports [] = do txt "("@@ -132,7 +130,7 @@ LastPos -> void m FirstAfterDocPos -> m >> comma MultiLine -> do- commaStyle <- getPrinterOpt poImportExportCommaStyle+ commaStyle <- getCommaStyle case commaStyle of Leading -> case relativePos of@@ -142,7 +140,7 @@ _ -> comma >> space >> m Trailing -> m >> comma indentDoc m = do- commaStyle <- getPrinterOpt poImportExportCommaStyle+ commaStyle <- getCommaStyle case commaStyle of Trailing -> m Leading ->@@ -181,13 +179,13 @@ -- | Surround given entity by parentheses @(@ and @)@. parens' :: Bool -> R () -> R () parens' topLevelImport m =- getPrinterOpt poDiffFriendlyImportExport >>= \case- True -> do+ getPrinterOpt poImportExportStyle >>= \case+ ImportExportDiffFriendly -> do txt "(" breakpoint' sitcc body vlayout (txt ")") (inciByFrac (-1) trailingParen)- False -> sitcc $ do+ _ -> sitcc $ do txt "(" body txt ")"@@ -195,7 +193,7 @@ body = vlayout singleLine multiLine singleLine = m multiLine = do- commaStyle <- getPrinterOpt poImportExportCommaStyle+ commaStyle <- getCommaStyle case commaStyle of -- On leading commas, list elements are inline with the enclosing parentheses Leading -> do@@ -209,8 +207,15 @@ newline trailingParen = if topLevelImport then txt " )" else txt ")" +getCommaStyle :: R CommaStyle+getCommaStyle =+ getPrinterOpt poImportExportStyle >>= \case+ ImportExportLeading -> pure Leading+ ImportExportTrailing -> pure Trailing+ ImportExportDiffFriendly -> pure Trailing+ breakIfNotDiffFriendly :: R () breakIfNotDiffFriendly =- getPrinterOpt poDiffFriendlyImportExport >>= \case- True -> space- False -> breakpoint+ getPrinterOpt poImportExportStyle >>= \case+ ImportExportDiffFriendly -> space+ _ -> breakpoint
src/Ormolu/Printer/Meat/Module.hs view
@@ -55,7 +55,7 @@ breakIfNotDiffFriendly -- This works around an awkward idempotency bug with deprecation messages.- diffFriendly <- getPrinterOpt poDiffFriendlyImportExport+ diffFriendly <- (==) ImportExportDiffFriendly <$> getPrinterOpt poImportExportStyle when (diffFriendly && not (null hsmodDeprecMessage)) newline case hsmodExports of
src/Ormolu/Utils/Cabal.hs view
@@ -18,6 +18,7 @@ import Control.Exception import Control.Monad.IO.Class import qualified Data.ByteString as B+import Data.IORef import Data.Map.Lazy (Map) import qualified Data.Map.Lazy as M import Data.Maybe (maybeToList)@@ -35,6 +36,7 @@ import System.FilePath import System.IO (hPutStrLn, stderr) import System.IO.Error (isDoesNotExistError)+import System.IO.Unsafe (unsafePerformIO) -- | Cabal information of interest to Ormolu. data CabalInfo = CabalInfo@@ -103,6 +105,21 @@ then pure Nothing else findCabalFile parentDir +-- | Parsed cabal file information to be shared across multiple source files.+data CachedCabalFile = CachedCabalFile+ { -- | Parsed generic package description.+ genericPackageDescription :: GenericPackageDescription,+ -- | Map from Haskell source file paths (without any extensions) to the+ -- corresponding 'DynOption's and dependencies.+ extensionsAndDeps :: Map FilePath ([DynOption], [String])+ }+ deriving (Show)++-- | Cache ref that stores 'CachedCabalFile' per cabal file.+cabalCacheRef :: IORef (Map FilePath CachedCabalFile)+cabalCacheRef = unsafePerformIO $ newIORef M.empty+{-# NOINLINE cabalCacheRef #-}+ -- | Parse 'CabalInfo' from a .cabal file at the given 'FilePath'. parseCabalInfo :: MonadIO m =>@@ -115,23 +132,26 @@ parseCabalInfo cabalFileAsGiven sourceFileAsGiven = liftIO $ do cabalFile <- makeAbsolute cabalFileAsGiven sourceFileAbs <- makeAbsolute sourceFileAsGiven- cabalFileBs <- B.readFile cabalFile- genericPackageDescription <-- case parseGenericPackageDescriptionMaybe cabalFileBs of- Just gpd -> pure gpd- Nothing -> throwIO (OrmoluCabalFileParsingFailed cabalFile)- (dynOpts, dependencies) <- do- let extMap = getExtensionAndDepsMap cabalFile genericPackageDescription- case M.lookup (dropExtensions sourceFileAbs) extMap of- Just exts -> pure exts- Nothing -> do- relativeCabalFile <- makeRelativeToCurrentDirectory cabalFile- hPutStrLn stderr $- "Found .cabal file "- <> relativeCabalFile- <> ", but it did not mention "- <> sourceFileAsGiven- return ([], [])+ cabalCache <- readIORef cabalCacheRef+ CachedCabalFile {..} <- whenNothing (M.lookup cabalFile cabalCache) $ do+ cabalFileBs <- B.readFile cabalFile+ genericPackageDescription <-+ whenNothing (parseGenericPackageDescriptionMaybe cabalFileBs) $+ throwIO (OrmoluCabalFileParsingFailed cabalFile)+ let extensionsAndDeps =+ getExtensionAndDepsMap cabalFile genericPackageDescription+ cachedCabalFile = CachedCabalFile {..}+ atomicModifyIORef cabalCacheRef $+ (,cachedCabalFile) . M.insert cabalFile cachedCabalFile+ (dynOpts, dependencies) <-+ whenNothing (M.lookup (dropExtensions sourceFileAbs) extensionsAndDeps) $ do+ relativeCabalFile <- makeRelativeToCurrentDirectory cabalFile+ hPutStrLn stderr $+ "Found .cabal file "+ <> relativeCabalFile+ <> ", but it did not mention "+ <> sourceFileAsGiven+ return ([], []) let pdesc = packageDescription genericPackageDescription packageName = (unPackageName . pkgName . package) pdesc return@@ -141,6 +161,9 @@ ciDependencies = Set.fromList dependencies, ciCabalFilePath = Just cabalFile }+ where+ whenNothing :: Monad m => Maybe a -> m a -> m a+ whenNothing maya ma = maybe ma pure maya -- | Get a map from Haskell source file paths (without any extensions) to -- the corresponding 'DynOption's and dependencies.@@ -168,7 +191,7 @@ extractFromBuildInfo extraModules BuildInfo {..} = (,(exts, deps)) $ do m <- extraModules ++ (ModuleName.toFilePath <$> otherModules)- (takeDirectory cabalFile </>) <$> prependSrcDirs (dropExtensions m)+ normalise . (takeDirectory cabalFile </>) <$> prependSrcDirs (dropExtensions m) where prependSrcDirs f | null hsSourceDirs = [f]
tests/Ormolu/CabalInfoSpec.hs view
@@ -42,3 +42,13 @@ it "extracts correct dependencies from fourmolu.cabal (tests/Ormolu/PrinterSpec.hs)" $ do CabalInfo {..} <- parseCabalInfo "fourmolu.cabal" "tests/Ormolu/PrinterSpec.hs" ciDependencies `shouldBe` Set.fromList ["Diff", "QuickCheck", "base", "containers", "directory", "filepath", "ghc-lib-parser", "hspec", "hspec-megaparsec", "megaparsec", "fourmolu", "path", "path-io", "pretty", "temporary", "text"]++ it "handles `hs-source-dirs: .`" $ do+ CabalInfo {..} <- parseTestCabalInfo "Foo.hs"+ ciDynOpts `shouldContain` [DynOption "-XImportQualifiedPost"]+ it "handles empty hs-source-dirs" $ do+ CabalInfo {..} <- parseTestCabalInfo "Bar.hs"+ ciDynOpts `shouldContain` [DynOption "-XImportQualifiedPost"]+ where+ parseTestCabalInfo f =+ parseCabalInfo "data/cabal-tests/test.cabal" ("data/cabal-tests" </> f)
tests/Ormolu/Config/PrinterOptsSpec.hs view
@@ -74,16 +74,11 @@ }, TestGroup { label = "import-export",- testCases = (,) <$> allOptions <*> allOptions,- updateConfig = \(commaStyle, diffFriendly) opts ->- opts- { poImportExportCommaStyle = pure commaStyle,- poDiffFriendlyImportExport = pure diffFriendly- },- showTestCase = \(commaStyle, diffFriendly) ->- show commaStyle ++ if diffFriendly then " + diff friendly" else "",- testCaseSuffix = \(commaStyle, diffFriendly) ->- suffixWith [show commaStyle, if diffFriendly then "diff_friendly" else ""]+ testCases = allOptions,+ updateConfig = \commaStyle opts ->+ opts {poImportExportStyle = pure commaStyle},+ showTestCase = show,+ testCaseSuffix = suffix1 }, TestGroup { label = "record-brace-space",
tests/Ormolu/Diff/TextSpec.hs view
@@ -24,6 +24,8 @@ stdTest "two-hunks" "main-and-baz" "main-and-baz-v2" stdTest "trimming" "spaced" "spaced-v2" stdTest "trailing-blank-line" "no-trailing-blank-line" "with-trailing-blank-line"+ stdTest "trimming-trailing-both-eof" "applicative-before" "applicative-after"+ stdTest "trimming-trailing-both-out-of-margin" "longer" "longer-v2" -- | Test diff printing. stdTest ::