fourmolu 0.2.0.0 → 0.3.0.0
raw patch · 11 files changed
+152/−60 lines, 11 filesdep ~aesondep ~pathPVP ok
version bump matches the API change (PVP)
Dependency ranges changed: aeson, path
API changes (from Hackage documentation)
+ Ormolu: [poNewlinesBetweenDecls] :: PrinterOpts f -> f Int
+ Ormolu.Config: [poNewlinesBetweenDecls] :: PrinterOpts f -> f Int
+ Ormolu.Config: instance GHC.Enum.Bounded Ormolu.Config.CommaStyle
+ Ormolu.Config: instance GHC.Enum.Bounded Ormolu.Config.HaddockPrintStyle
+ Ormolu.Config: instance GHC.Enum.Enum Ormolu.Config.CommaStyle
+ Ormolu.Config: instance GHC.Enum.Enum Ormolu.Config.HaddockPrintStyle
+ Ormolu.Printer: [poNewlinesBetweenDecls] :: PrinterOpts f -> f Int
+ Ormolu.Printer.Combinators: declNewline :: R ()
+ Ormolu.Printer.Internal: declNewline :: R ()
- Ormolu: PrinterOpts :: f Int -> f CommaStyle -> f Bool -> f Bool -> f Bool -> f Bool -> f HaddockPrintStyle -> PrinterOpts f
+ Ormolu: PrinterOpts :: f Int -> f CommaStyle -> f Bool -> f Bool -> f Bool -> f Bool -> f HaddockPrintStyle -> f Int -> PrinterOpts f
- Ormolu.Config: PrinterOpts :: f Int -> f CommaStyle -> f Bool -> f Bool -> f Bool -> f Bool -> f HaddockPrintStyle -> PrinterOpts f
+ Ormolu.Config: PrinterOpts :: f Int -> f CommaStyle -> f Bool -> f Bool -> f Bool -> f Bool -> f HaddockPrintStyle -> f Int -> PrinterOpts f
- Ormolu.Printer: PrinterOpts :: f Int -> f CommaStyle -> f Bool -> f Bool -> f Bool -> f Bool -> f HaddockPrintStyle -> PrinterOpts f
+ Ormolu.Printer: PrinterOpts :: f Int -> f CommaStyle -> f Bool -> f Bool -> f Bool -> f Bool -> f HaddockPrintStyle -> f Int -> PrinterOpts f
Files
- CHANGELOG.md +5/−0
- README.md +1/−0
- app/Main.hs +110/−41
- fourmolu.cabal +1/−1
- src/Ormolu/Config.hs +10/−6
- src/Ormolu/Printer/Combinators.hs +1/−0
- src/Ormolu/Printer/Internal.hs +15/−6
- src/Ormolu/Printer/Meat/Declaration.hs +2/−2
- src/Ormolu/Printer/Meat/Module.hs +1/−1
- src/Ormolu/Utils.hs +4/−2
- tests/Ormolu/PrinterSpec.hs +2/−1
CHANGELOG.md view
@@ -1,3 +1,8 @@+## Fourmolu 0.3.0.0++* New config option `newlines-between-decls`, to choose the number of blank lines between top-level declarations.+* Minor CLI improvements. In particular, the set of valid values for each option is communicated more consistently.+ ## Fourmolu 0.2.0.0 * More consistent indentation. Previously, with indentation set to n, some constructs such as nested lists and tuples would use an ugly mix of n-space and 2-space indentation.
README.md view
@@ -37,6 +37,7 @@ diff-friendly-import-export: true # 'false' uses Ormolu-style lists respectful: true # don't be too opinionated about newlines etc. haddock-style: multi-line # '--' vs. '{-'+newlines-between-decls: 1 # number of newlines between top-level declarations ``` See [here](fourmolu.yaml) for a config to simulate the behaviour of Ormolu.
app/Main.hs view
@@ -1,7 +1,10 @@+{-# LANGUAGE AllowAmbiguousTypes #-} {-# LANGUAGE ApplicativeDo #-} {-# LANGUAGE CPP #-} {-# LANGUAGE LambdaCase #-}+{-# LANGUAGE RankNTypes #-} {-# LANGUAGE RecordWildCards #-}+{-# LANGUAGE ScopedTypeVariables #-} {-# LANGUAGE TemplateHaskell #-} {-# LANGUAGE TypeApplications #-} @@ -10,8 +13,8 @@ import Control.Exception (SomeException, displayException, try) import Control.Monad import Data.Bool (bool)-import Data.Char (toLower) import Data.Either (lefts)+import Data.Functor.Identity (Identity (..)) import Data.List (intercalate, sort) import Data.Maybe (fromMaybe) import qualified Data.Text.IO as TIO@@ -114,7 +117,7 @@ | -- | Exit with non-zero status code if -- source is not already formatted Check- deriving (Eq, Show)+ deriving (Eq, Show, Bounded, Enum) optsParserInfo :: ParserInfo Opts optsParserInfo =@@ -157,7 +160,7 @@ [ short 'i', help "A shortcut for --mode inplace" ]- <|> (option parseMode . mconcat)+ <|> (option parseBoundedEnum . mconcat) [ long "mode", short 'm', metavar "MODE",@@ -216,81 +219,147 @@ (optional . option auto . mconcat) [ long "indentation", metavar "WIDTH",- help "Number of spaces per indentation step (default 4)"+ help $+ "Number of spaces per indentation step"+ <> showDefaultValue poIndentation ] poCommaStyle <-- (optional . option parseCommaStyle . mconcat)+ (optional . option parseBoundedEnum . mconcat) [ long "comma-style", metavar "STYLE",- help "How to place commas in multi-line lists, records etc: 'leading' (default) or 'trailing'"+ help $+ "How to place commas in multi-line lists, records etc: "+ <> showAllValues @CommaStyle+ <> showDefaultValue poCommaStyle ] poIndentWheres <-- (optional . option parseBool . mconcat)+ (optional . option parseBoundedEnum . mconcat) [ long "indent-wheres", metavar "BOOL", help $ "Whether to indent 'where' bindings past the preceding body"- <> " (rather than half-indenting the 'where' keyword) (default 'false')"+ <> " (rather than half-indenting the 'where' keyword)"+ <> showDefaultValue poIndentWheres ] poRecordBraceSpace <-- (optional . option parseBool . mconcat)+ (optional . option parseBoundedEnum . mconcat) [ long "record-brace-space", metavar "BOOL",- help "Whether to leave a space before an opening record brace (default 'false')"+ help $+ "Whether to leave a space before an opening record brace"+ <> showDefaultValue poRecordBraceSpace ] poDiffFriendlyImportExport <-- (optional . option parseBool . mconcat)+ (optional . option parseBoundedEnum . mconcat) [ long "diff-friendly-import-export", metavar "BOOL", help $ "Whether to make use of extra commas in import/export lists"- <> " (as opposed to Ormolu's style) (default 'true')"+ <> " (as opposed to Ormolu's style)"+ <> showDefaultValue poDiffFriendlyImportExport ] poRespectful <-- (optional . option parseBool . mconcat)+ (optional . option parseBoundedEnum . mconcat) [ long "respectful", metavar "BOOL",- help "Give the programmer more choice on where to insert blank lines (default 'true')"+ help $+ "Give the programmer more choice on where to insert blank lines"+ <> showDefaultValue poRespectful ] poHaddockStyle <-- (optional . option parseHaddockStyle . mconcat)+ (optional . option parseBoundedEnum . mconcat) [ long "haddock-style", metavar "STYLE",- help "How to print Haddock comments (default 'multi-line')"+ help $+ "How to print Haddock comments: "+ <> showAllValues @HaddockPrintStyle+ <> showDefaultValue poHaddockStyle ]+ poNewlinesBetweenDecls <-+ (optional . option auto . mconcat)+ [ long "newlines-between-decls",+ metavar "HEIGHT",+ help "Number of spaces between top-level declarations (default 1)"+ ] pure PrinterOpts {..} ---------------------------------------------------------------------------- -- Helpers --- | Parse 'Mode'.-parseMode :: ReadM Mode-parseMode = eitherReader $ \case- "stdout" -> Right Stdout- "inplace" -> Right InPlace- "check" -> Right Check- s -> Left $ "unknown mode: " ++ s+-- | A standard parser of CLI option arguments, applicable to arguments that+-- have a finite (preferably small) number of possible values. (Basically an+-- inverse of 'toCLIArgument'.)+parseBoundedEnum ::+ forall a.+ (Enum a, Bounded a, ToCLIArgument a) =>+ ReadM a+parseBoundedEnum =+ eitherReader+ ( \s ->+ case lookup s argumentToValue of+ Just v -> Right v+ Nothing ->+ Left $+ "unknown value: '"+ <> s+ <> "'\nValid values are: "+ <> showAllValues @a+ <> "."+ )+ where+ argumentToValue = map (\x -> (toCLIArgument x, x)) [minBound ..] --- | Parse 'CommaStyle'.-parseCommaStyle :: ReadM CommaStyle-parseCommaStyle = eitherReader $ \case- "leading" -> Right Leading- "trailing" -> Right Trailing- s -> Left $ "unknown comma style: " ++ s+-- | Values that appear as arguments of CLI options and thus have+-- a corresponding textual representation.+class ToCLIArgument a where+ -- | Convert a value to its representation as a CLI option argument.+ toCLIArgument :: a -> String --- | Parse 'HaddockStyle'.-parseHaddockStyle :: ReadM HaddockPrintStyle-parseHaddockStyle = eitherReader $ \case- "single-line" -> Right HaddockSingleLine- "multi-line" -> Right HaddockMultiLine- s -> Left $ "unknown haddock style: " ++ s+ -- | Convert a value to its representation as a CLI option argument wrapped+ -- in apostrophes.+ toCLIArgument' :: a -> String+ toCLIArgument' x = "'" <> toCLIArgument x <> "'" --- | Parse a 'Bool'. Unlike 'auto', this is not case sensitive.-parseBool :: ReadM Bool-parseBool = eitherReader $ \x -> case map toLower x of- "false" -> Right False- "true" -> Right True- s -> Left $ "not a boolean value: " ++ s+instance ToCLIArgument Bool where+ toCLIArgument True = "true"+ toCLIArgument False = "false"++instance ToCLIArgument CommaStyle where+ toCLIArgument Leading = "leading"+ toCLIArgument Trailing = "trailing"++instance ToCLIArgument Int where+ toCLIArgument = show++instance ToCLIArgument HaddockPrintStyle where+ toCLIArgument HaddockSingleLine = "single-line"+ toCLIArgument HaddockMultiLine = "multi-line"++instance ToCLIArgument Mode where+ toCLIArgument Stdout = "stdout"+ toCLIArgument InPlace = "inplace"+ toCLIArgument Check = "check"++showAllValues :: forall a. (Enum a, Bounded a, ToCLIArgument a) => String+showAllValues = format (map toCLIArgument' [(minBound :: a) ..])+ where+ format [] = []+ format [x] = x+ format [x1, x2] = x1 <> " or " <> x2+ format (x : xs) = x <> ", " <> format xs++-- | CLI representation of the default value of an option, formatted for+-- inclusion in the help text.+showDefaultValue ::+ ToCLIArgument a =>+ (PrinterOptsTotal -> Identity a) ->+ String+showDefaultValue =+ (" (default " <>)+ . (<> ")")+ . toCLIArgument'+ . runIdentity+ . ($ defaultPrinterOpts) -- | Build the full config, by adding 'PrinterOpts' from a file, if found. mkConfig :: FilePath -> Opts -> IO (Config RegionIndices)
fourmolu.cabal view
@@ -1,6 +1,6 @@ cabal-version: 1.18 name: fourmolu-version: 0.2.0.0+version: 0.3.0.0 license: BSD3 license-file: LICENSE.md maintainer:
src/Ormolu/Config.hs view
@@ -118,7 +118,9 @@ -- | Be less opinionated about spaces/newlines etc. poRespectful :: f Bool, -- | How to print doc comments- poHaddockStyle :: f HaddockPrintStyle+ poHaddockStyle :: f HaddockPrintStyle,+ -- | Number of newlines between top-level decls+ poNewlinesBetweenDecls :: f Int } deriving (Generic) @@ -134,7 +136,7 @@ (<>) = fillMissingPrinterOpts instance Monoid PrinterOptsPartial where- mempty = PrinterOpts Nothing Nothing Nothing Nothing Nothing Nothing Nothing+ mempty = PrinterOpts Nothing Nothing Nothing Nothing Nothing Nothing Nothing Nothing -- | A version of 'PrinterOpts' without empty fields. type PrinterOptsTotal = PrinterOpts Identity@@ -152,7 +154,8 @@ poRecordBraceSpace = pure False, poDiffFriendlyImportExport = pure True, poRespectful = pure True,- poHaddockStyle = pure HaddockMultiLine+ poHaddockStyle = pure HaddockMultiLine,+ poNewlinesBetweenDecls = pure 1 } -- | Fill the field values that are 'Nothing' in the first argument@@ -171,7 +174,8 @@ poRecordBraceSpace = fillField poRecordBraceSpace, poDiffFriendlyImportExport = fillField poDiffFriendlyImportExport, poRespectful = fillField poRespectful,- poHaddockStyle = fillField poHaddockStyle+ poHaddockStyle = fillField poHaddockStyle,+ poNewlinesBetweenDecls = fillField poNewlinesBetweenDecls } where fillField :: (forall g. PrinterOpts g -> g a) -> f a@@ -180,7 +184,7 @@ data CommaStyle = Leading | Trailing- deriving (Eq, Ord, Show, Generic)+ deriving (Eq, Ord, Show, Generic, Bounded, Enum) instance FromJSON CommaStyle where parseJSON =@@ -192,7 +196,7 @@ data HaddockPrintStyle = HaddockSingleLine | HaddockMultiLine- deriving (Eq, Ord, Show, Generic)+ deriving (Eq, Ord, Show, Generic, Bounded, Enum) instance FromJSON HaddockPrintStyle where parseJSON =
src/Ormolu/Printer/Combinators.hs view
@@ -20,6 +20,7 @@ atom, space, newline,+ declNewline, inci, inciIf, inciBy,
src/Ormolu/Printer/Internal.hs view
@@ -18,6 +18,7 @@ atom, space, newline,+ declNewline, useRecordDot, inci, inciBy,@@ -316,6 +317,9 @@ other -> other } +declNewline :: R ()+declNewline = newlineRawN =<< getPrinterOpt poNewlinesBetweenDecls+ -- | Output a newline. First time 'newline' is used after some non-'newline' -- output it gets inserted immediately. Second use of 'newline' does not -- output anything but makes sure that the next non-white space output will@@ -353,15 +357,20 @@ -- | Low-level newline primitive. This one always just inserts a newline, no -- hooks can be attached. newlineRaw :: R ()-newlineRaw = R . modify $ \sc ->+newlineRaw = newlineRawN 1++-- | Low-level newline primitive. This always inserts 'n' newlines.+newlineRawN :: Int -> R ()+newlineRawN n = R . modify $ \sc -> let requestedDel = scRequestedDelimiter sc builderSoFar = scBuilder sc+ n' = case requestedDel of+ AfterNewline -> n - 1+ RequestedNewline -> n - 1+ VeryBeginning -> n - 1+ _ -> n in sc- { scBuilder = case requestedDel of- AfterNewline -> builderSoFar- RequestedNewline -> builderSoFar- VeryBeginning -> builderSoFar- _ -> builderSoFar <> "\n",+ { scBuilder = builderSoFar <> mconcat (replicate n' "\n"), scColumn = 0, scIndent = 0, scThisLineSpans = [],
src/Ormolu/Printer/Meat/Declaration.hs view
@@ -68,12 +68,12 @@ -- ensure we always add blank lines around documented declarations case grouping of Disregard ->- breakpoint : renderGroup curr+ declNewline : renderGroup curr Respect -> if separatedByBlankNE getLoc prev curr || isDocumented prev || isDocumented curr- then breakpoint : renderGroup curr+ then declNewline : renderGroup curr else renderGroup curr -- | Is a declaration group documented?
src/Ormolu/Printer/Meat/Module.hs view
@@ -79,7 +79,7 @@ forM_ (normalizeImports preserveGroups hsmodImports) $ \importGroup -> do forM_ importGroup (located' (p_hsmodImport qualifiedPost)) newline- newline+ declNewline switchLayout (getLoc <$> hsmodDecls) $ do preserveSpacing <- getPrinterOpt poRespectful (if preserveSpacing then p_hsDeclsRespectGrouping else p_hsDecls) Free hsmodDecls
src/Ormolu/Utils.hs view
@@ -23,7 +23,7 @@ import Data.Char (isSpace) import Data.List (dropWhileEnd)-import Data.List.NonEmpty (NonEmpty (..))+import Data.List.NonEmpty (NonEmpty (..), nonEmpty) import qualified Data.List.NonEmpty as NE import Data.Maybe (fromMaybe) import Data.Text (Text)@@ -135,7 +135,9 @@ removeIndentation :: String -> (String, Int) removeIndentation (lines -> xs) = (unlines (drop n <$> xs), n) where- n = minimum (getIndent <$> xs)+ n = case nonEmpty xs of+ Nothing -> 0+ Just l -> minimum (getIndent <$> l) getIndent y = if all isSpace y then 0
tests/Ormolu/PrinterSpec.hs view
@@ -27,7 +27,8 @@ poRecordBraceSpace = pure True, poDiffFriendlyImportExport = pure False, poRespectful = pure False,- poHaddockStyle = pure HaddockSingleLine+ poHaddockStyle = pure HaddockSingleLine,+ poNewlinesBetweenDecls = pure 1 } sequence_ $ uncurry checkExample <$> [(ormoluOpts, ""), (defaultPrinterOpts, "-four")] <*> es