packages feed

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 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