packages feed

fourmolu 0.14.1.0 → 0.15.0.0

raw patch · 83 files changed

+739/−224 lines, 83 filesdep ~ansi-terminal

Dependency ranges changed: ansi-terminal

Files

CHANGELOG.md view
@@ -1,3 +1,27 @@+## Fourmolu 0.15.0.0++* Add `single-deriving-parens` configuration option to determine if `deriving` clauses of a single type should be parenthesized ([#386](https://github.com/fourmolu/fourmolu/pull/386))++* Fix the order in which the configurations are applied ([#390](https://github.com/fourmolu/fourmolu/issues/390))++### Upstream changes:++#### Ormolu 0.7.4.0++* Don't error when the `JavaScriptFFI` language pragma is present. [Issue+  1087](https://github.com/tweag/ormolu/issues/1087).+* Improve comment placement in if-then-else blocks. [Issue+  998](https://github.com/tweag/ormolu/issues/998).+* Now command line options for fixity overrides and module re-exports+  overwrite information from `.ormolu` files. [Issue+  1030](https://github.com/tweag/ormolu/issues/1030).+* Respect newlines in data declarations in more cases. [Issue+  1077](https://github.com/tweag/ormolu/issues/1077) and [issue+  947](https://github.com/tweag/ormolu/issues/947).+* The `-d / --debug` command line option now makes Ormolu print out debug+  information regarding operator fixity inference. [Issue+  1060](https://github.com/tweag/ormolu/issues/1060).+ ## Fourmolu 0.14.1.0  * Fix `single-constraint-parens: never` for nested quantified constraints ([#374](https://github.com/fourmolu/fourmolu/issues/374))
README.md view
@@ -15,6 +15,8 @@     * [Regions](#regions)     * [Exit codes](#exit-codes)     * [Using as a library](#using-as-a-library)+* [Troubleshooting](#troubleshooting)+    * [Operators are being formatted weirdly!](#operators-are-being-formatted-weirdly) * [Limitations](#limitations) * [Contributing](#contributing) * [License](#license)@@ -229,6 +231,32 @@ For these purposes only the top `Ormolu` module should be considered stable. It follows [PVP](https://pvp.haskell.org/) starting from the version 0.10.2.0. Rely on other modules at your own risk.++## Troubleshooting++### Operators are being formatted weirdly!++This can happen when Ormolu doesn't know or can't determine the fixity of an+operator.++* If this is a custom operator, see the instructions in the [Language+  extensions, dependencies, and+  fixities](#language-extensions-dependencies-and-fixities) section to+  specify the correct fixities in a `.ormolu` file.++* If this is a third-party operator (e.g. from `base` or some other package+  from Hackage), Ormolu probably doesn't recognize that the operator is the+  same as the third-party one.++  Some reasons this might be the case:++    * You might have a custom Prelude that re-exports things from Prelude+    * You might have `-XNoImplicitPrelude` turned on++  If any of these are true, make sure to specify the reexports correctly in+  a `.ormolu` file.++You can see how Ormolu decides the fixity of operators if you use `--debug`.  ## Limitations 
app/Main.hs view
@@ -100,8 +100,8 @@     cliConfig       { cfgPrinterOpts =           resolvePrinterOpts-            [ cliPrinterOpts,-              cfgFilePrinterOpts fourmoluConfig+            [ cfgFilePrinterOpts fourmoluConfig,+              cliPrinterOpts             ],         cfgFixityOverrides =           FixityOverrides . mconcat . map unFixityOverrides $@@ -242,15 +242,17 @@             fromMaybe               ModuleSource               (reqSourceType <|> mdetectedSourceType)-      let mfixityOverrides = fst <$> mdotOrmolu-          mmoduleReexports = snd <$> mdotOrmolu       return $         refineConfig           sourceType           mcabalInfo-          mfixityOverrides-          mmoduleReexports-          rawConfig+          (Just (cfgFixityOverrides rawConfig))+          (Just (cfgModuleReexports rawConfig))+          ( rawConfig+              { cfgFixityOverrides = maybe defaultFixityOverrides fst mdotOrmolu,+                cfgModuleReexports = maybe defaultModuleReexports snd mdotOrmolu+              }+          )     handleDiff originalInput formattedInput fileRepr =       case diffText originalInput formattedInput fileRepr of         Nothing -> return ExitSuccess
+ data/examples/declaration/data/ctype-0-four-out.hs view
@@ -0,0 +1,1 @@+data {-# CTYPE "unistd.h" "useconds_t" #-} T
+ data/examples/declaration/data/ctype-0-out.hs view
@@ -0,0 +1,1 @@+data {-# CTYPE "unistd.h" "useconds_t" #-} T
+ data/examples/declaration/data/ctype-0.hs view
@@ -0,0 +1,1 @@+data    {-# CTYPE "unistd.h" "useconds_t" #-} T
+ data/examples/declaration/data/ctype-1-four-out.hs view
@@ -0,0 +1,6 @@+data+    {-# CTYPE "header.h" "an-ffi-type-with-along-name" #-}+    AnFFITypeWithAlongName = AnFFITypeWithAlongName+    { a :: X+    , b :: Y+    }
+ data/examples/declaration/data/ctype-1-out.hs view
@@ -0,0 +1,6 @@+data+  {-# CTYPE "header.h" "an-ffi-type-with-along-name" #-}+  AnFFITypeWithAlongName = AnFFITypeWithAlongName+  { a :: X,+    b :: Y+  }
+ data/examples/declaration/data/ctype-1.hs view
@@ -0,0 +1,6 @@+data+  {-# CTYPE "header.h" "an-ffi-type-with-along-name"  #-}+  AnFFITypeWithAlongName = AnFFITypeWithAlongName+  { a :: X,+    b :: Y+  }
− data/examples/declaration/data/ctype-four-out.hs
@@ -1,1 +0,0 @@-data {-# CTYPE "unistd.h" "useconds_t" #-} T
− data/examples/declaration/data/ctype-out.hs
@@ -1,1 +0,0 @@-data {-# CTYPE "unistd.h" "useconds_t" #-} T
− data/examples/declaration/data/ctype.hs
@@ -1,1 +0,0 @@-data    {-# CTYPE "unistd.h" "useconds_t" #-} T
+ data/examples/declaration/data/field-layout/record-0-four-out.hs view
@@ -0,0 +1,10 @@+-- | Foo.+data Foo = Foo+    { foo :: Foo Int Int+    -- ^ Something+    , bar ::+        Bar+            Char+            Char+    -- ^ Something else+    }
+ data/examples/declaration/data/field-layout/record-0-out.hs view
@@ -0,0 +1,10 @@+-- | Foo.+data Foo = Foo+  { -- | Something+    foo :: Foo Int Int,+    -- | Something else+    bar ::+      Bar+        Char+        Char+  }
+ data/examples/declaration/data/field-layout/record-0.hs view
@@ -0,0 +1,9 @@+-- | Foo.++data Foo = Foo+  { foo :: Foo Int Int+    -- ^ Something+  , bar :: Bar Char+           Char+    -- ^ Something else+  }
+ data/examples/declaration/data/field-layout/record-1-four-out.hs view
@@ -0,0 +1,11 @@+-- | Foo.+data Foo+    = Foo+    { foo :: Foo Int Int+    -- ^ Something+    , bar ::+        Bar+            Char+            Char+    -- ^ Something else+    }
+ data/examples/declaration/data/field-layout/record-1-out.hs view
@@ -0,0 +1,11 @@+-- | Foo.+data Foo+  = Foo+  { -- | Something+    foo :: Foo Int Int,+    -- | Something else+    bar ::+      Bar+        Char+        Char+  }
+ data/examples/declaration/data/field-layout/record-1.hs view
@@ -0,0 +1,10 @@+-- | Foo.++data Foo =+  Foo+  { foo :: Foo Int Int+    -- ^ Something+  , bar :: Bar Char+           Char+    -- ^ Something else+  }
+ data/examples/declaration/data/field-layout/record-2-four-out.hs view
@@ -0,0 +1,7 @@+data IndexWithInfo schema+    = forall x.+      IndexWithInfo+    { checkedIndex :: Index schema x+    , checkedIndexName :: U.Variable+    , checkedIndexType :: Type x+    }
+ data/examples/declaration/data/field-layout/record-2-out.hs view
@@ -0,0 +1,7 @@+data IndexWithInfo schema+  = forall x.+  IndexWithInfo+  { checkedIndex :: Index schema x,+    checkedIndexName :: U.Variable,+    checkedIndexType :: Type x+  }
+ data/examples/declaration/data/field-layout/record-2.hs view
@@ -0,0 +1,7 @@+data IndexWithInfo schema =+  forall x.+  IndexWithInfo+    { checkedIndex :: Index schema x+    , checkedIndexName :: U.Variable+    , checkedIndexType :: Type x+    }
− data/examples/declaration/data/field-layout/record-four-out.hs
@@ -1,12 +0,0 @@-module Main where---- | Foo.-data Foo = Foo-    { foo :: Foo Int Int-    -- ^ Something-    , bar ::-        Bar-            Char-            Char-    -- ^ Something else-    }
− data/examples/declaration/data/field-layout/record-out.hs
@@ -1,12 +0,0 @@-module Main where---- | Foo.-data Foo = Foo-  { -- | Something-    foo :: Foo Int Int,-    -- | Something else-    bar ::-      Bar-        Char-        Char-  }
− data/examples/declaration/data/field-layout/record.hs
@@ -1,11 +0,0 @@-module Main where---- | Foo.--data Foo = Foo-  { foo :: Foo Int Int-    -- ^ Something-  , bar :: Bar Char-           Char-    -- ^ Something else-  }
+ data/examples/declaration/data/record-fancy-existential-four-out.hs view
@@ -0,0 +1,6 @@+{-# LANGUAGE ExistentialQuantification #-}++data Foo = forall a b. (Show a, Eq b) => Bar+    { foo :: a+    , bars :: b+    }
+ data/examples/declaration/data/record-fancy-existential-out.hs view
@@ -0,0 +1,6 @@+{-# LANGUAGE ExistentialQuantification #-}++data Foo = forall a b. (Show a, Eq b) => Bar+  { foo :: a,+    bars :: b+  }
+ data/examples/declaration/data/record-fancy-existential.hs view
@@ -0,0 +1,5 @@+{-# LANGUAGE ExistentialQuantification #-}+data Foo = forall a b . (Show a, Eq b) => Bar+  { foo  :: a+  , bars :: b+  }
data/examples/declaration/data/simple-broken-four-out.hs view
@@ -1,7 +1,8 @@ module Main where  -- | Here we go.-data Foo = Foo {unFoo :: Int}+data Foo+    = Foo {unFoo :: Int}     deriving (Eq)  -- | And once again.
data/examples/declaration/data/simple-broken-out.hs view
@@ -1,7 +1,8 @@ module Main where  -- | Here we go.-data Foo = Foo {unFoo :: Int}+data Foo+  = Foo {unFoo :: Int}   deriving (Eq)  -- | And once again.
+ data/examples/declaration/value/function/if-single-line-functions-do-four-out.hs view
@@ -0,0 +1,5 @@+foo x = do+    y <- quux+    if x > 2+        then bar x+        else baz y
+ data/examples/declaration/value/function/if-single-line-functions-do-out.hs view
@@ -0,0 +1,5 @@+foo x = do+  y <- quux+  if x > 2+    then bar x+    else baz y
+ data/examples/declaration/value/function/if-single-line-functions-do.hs view
@@ -0,0 +1,5 @@+foo x = do+  y <- quux+  if x > 2+    then bar x+    else baz y
+ data/examples/declaration/value/function/if-single-line-functions-four-out.hs view
@@ -0,0 +1,4 @@+foo x =+    if x > 2+        then bar x+        else baz x
+ data/examples/declaration/value/function/if-single-line-functions-out.hs view
@@ -0,0 +1,4 @@+foo x =+  if x > 2+    then bar x+    else baz x
+ data/examples/declaration/value/function/if-single-line-functions.hs view
@@ -0,0 +1,4 @@+foo x =+  if x > 2+    then bar x+    else baz x
+ data/examples/declaration/value/function/if-with-comment-above-branches-four-out.hs view
@@ -0,0 +1,7 @@+foo =+    if undefined+        -- then comment+        then undefined+        -- else comment+        else do+            undefined
+ data/examples/declaration/value/function/if-with-comment-above-branches-out.hs view
@@ -0,0 +1,7 @@+foo =+  if undefined+    -- then comment+    then undefined+    -- else comment+    else do+      undefined
+ data/examples/declaration/value/function/if-with-comment-above-branches.hs view
@@ -0,0 +1,8 @@+foo =+  if undefined+    -- then comment+    then undefined+    -- else comment+    else+      do+        undefined
+ data/examples/declaration/value/function/if-with-comment-before-do-blocks-four-out.hs view
@@ -0,0 +1,10 @@+foo =+    if something+        -- then comment+        then do+            stuff+            stuff+        -- else comment+        else do+            stuff+            stuff
+ data/examples/declaration/value/function/if-with-comment-before-do-blocks-out.hs view
@@ -0,0 +1,10 @@+foo =+  if something+    -- then comment+    then do+      stuff+      stuff+    -- else comment+    else do+      stuff+      stuff
+ data/examples/declaration/value/function/if-with-comment-before-do-blocks.hs view
@@ -0,0 +1,10 @@+foo =+  if something+    -- then comment+    then do+      stuff+      stuff+    -- else comment+    else do+      stuff+      stuff
− data/examples/declaration/value/function/if-with-comment-four-out.hs
@@ -1,8 +0,0 @@-foo =-    if undefined-        then -- then comment-            undefined-        else -- else comment--        do-            undefined
+ data/examples/declaration/value/function/if-with-comment-in-branches-four-out.hs view
@@ -0,0 +1,14 @@+foo =+    if x+        then+            -- comment 1+            -- comment 2+            case a of+                Just b -> _+                Nothing -> _+        else+            -- comment 3+            -- comment 4+            case a of+                Just b -> _+                Nothing -> _
+ data/examples/declaration/value/function/if-with-comment-in-branches-out.hs view
@@ -0,0 +1,14 @@+foo =+  if x+    then+      -- comment 1+      -- comment 2+      case a of+        Just b -> _+        Nothing -> _+    else+      -- comment 3+      -- comment 4+      case a of+        Just b -> _+        Nothing -> _
+ data/examples/declaration/value/function/if-with-comment-in-branches-with-functions-four-out.hs view
@@ -0,0 +1,12 @@+foo =+    if x+        then+            -- comment 1+            -- comment 2+            foo 1 2 3+        else+            -- comment 3+            -- comment 4+            foo+                "here"+                "there"
+ data/examples/declaration/value/function/if-with-comment-in-branches-with-functions-out.hs view
@@ -0,0 +1,12 @@+foo =+  if x+    then+      -- comment 1+      -- comment 2+      foo 1 2 3+    else+      -- comment 3+      -- comment 4+      foo+        "here"+        "there"
+ data/examples/declaration/value/function/if-with-comment-in-branches-with-functions.hs view
@@ -0,0 +1,12 @@+foo =+  if x+    then+      -- comment 1+      -- comment 2+      foo 1 2 3+    else+      -- comment 3+      -- comment 4+      foo+        "here"+        "there"
+ data/examples/declaration/value/function/if-with-comment-in-branches.hs view
@@ -0,0 +1,14 @@+foo =+  if x+    then+      -- comment 1+      -- comment 2+      case a of+        Just b -> _+        Nothing -> _+    else+      -- comment 3+      -- comment 4+      case a of+        Just b -> _+        Nothing -> _
+ data/examples/declaration/value/function/if-with-comment-next-to-keyword-four-out.hs view
@@ -0,0 +1,10 @@+foo =+    if x+        then -- comment 1+        -- comment 2+            foo 1 2 3+        else -- comment 3+        -- comment 4+            foo+                "here"+                "there"
+ data/examples/declaration/value/function/if-with-comment-next-to-keyword-out.hs view
@@ -0,0 +1,10 @@+foo =+  if x+    then -- comment 1+    -- comment 2+      foo 1 2 3+    else -- comment 3+    -- comment 4+      foo+        "here"+        "there"
+ data/examples/declaration/value/function/if-with-comment-next-to-keyword.hs view
@@ -0,0 +1,10 @@+foo =+  if x+    then -- comment 1+      -- comment 2+      foo 1 2 3+    else -- comment 3+      -- comment 4+      foo+        "here"+        "there"
− data/examples/declaration/value/function/if-with-comment-out.hs
@@ -1,8 +0,0 @@-foo =-  if undefined-    then -- then comment-      undefined-    else -- else comment--    do-      undefined
− data/examples/declaration/value/function/if-with-comment.hs
@@ -1,8 +0,0 @@-foo =-  if undefined-    -- then comment-    then undefined-    -- else comment-    else-      do-        undefined
+ data/examples/other/jsffi-four-out.hs view
@@ -0,0 +1,1 @@+{-# LANGUAGE JavaScriptFFI #-}
+ data/examples/other/jsffi-out.hs view
@@ -0,0 +1,1 @@+{-# LANGUAGE JavaScriptFFI #-}
+ data/examples/other/jsffi.hs view
@@ -0,0 +1,1 @@+{-# language JavaScriptFFI #-}
+ data/fourmolu/single-deriving-parens/input.hs view
@@ -0,0 +1,10 @@+module Main where++data Foo = Foo+    deriving stock Show++data Bar = Bar+    deriving stock (Show, Eq)++data Bat = Bat+    deriving stock (Show)
+ data/fourmolu/single-deriving-parens/output-DerivingAlways.hs view
@@ -0,0 +1,10 @@+module Main where++data Foo = Foo+    deriving stock (Show)++data Bar = Bar+    deriving stock (Show, Eq)++data Bat = Bat+    deriving stock (Show)
+ data/fourmolu/single-deriving-parens/output-DerivingAuto.hs view
@@ -0,0 +1,10 @@+module Main where++data Foo = Foo+    deriving stock Show++data Bar = Bar+    deriving stock (Show, Eq)++data Bat = Bat+    deriving stock (Show)
+ data/fourmolu/single-deriving-parens/output-DerivingNever.hs view
@@ -0,0 +1,10 @@+module Main where++data Foo = Foo+    deriving stock Show++data Bar = Bar+    deriving stock (Show, Eq)++data Bat = Bat+    deriving stock Show
− fixity-tests/test-0-no-extra-info-expected.hs
@@ -1,10 +0,0 @@-instance A.ToJSON UpdateTable where-  toJSON a =-    A.object $-      "TableName"-        .= updateTableName a-        :> "ProvisionedThroughput"-        .= updateProvisionedThroughput a-        :> case updateGlobalSecondaryIndexUpdates a of-          [] -> []-          l -> ["GlobalSecondaryIndexUpdates" .= l]
+ fixity-tests/test-0-ugly-expected.hs view
@@ -0,0 +1,10 @@+instance A.ToJSON UpdateTable where+  toJSON a =+    A.object $+      "TableName"+        .= updateTableName a+        :> "ProvisionedThroughput"+        .= updateProvisionedThroughput a+        :> case updateGlobalSecondaryIndexUpdates a of+          [] -> []+          l -> ["GlobalSecondaryIndexUpdates" .= l]
fourmolu.cabal view
@@ -1,6 +1,6 @@ cabal-version:      2.4 name:               fourmolu-version:            0.14.1.0+version:            0.15.0.0 license:            BSD-3-Clause license-file:       LICENSE.md maintainer:@@ -213,7 +213,7 @@         Ormolu.Integration.Utils     build-depends:         bytestring,-        Diff >=0.3 && <0.5,+        Diff >=0.3 && <1,         pretty >=1.0 && <2.0,         process >=1.6 && <2.0,         yaml,
fourmolu.yaml view
@@ -14,6 +14,7 @@ let-style: inline in-style: right-align single-constraint-parens: always+single-deriving-parens: always unicode: never respectful: false fixities: []
src/GHC/DynFlags.hs view
@@ -26,7 +26,8 @@         Platform           { platformArchOS =               ArchOS-                { archOS_arch = ArchUnknown,+                { -- see https://github.com/tweag/ormolu/issues/1087+                  archOS_arch = ArchJavaScript,                   archOS_OS = OSUnknown                 },             platformWordSize = PW8,
src/Ormolu.hs view
@@ -118,7 +118,7 @@   -- when we try to parse the rendered code back, inside of GHC monad   -- wrapper which will lead to error messages presenting the exceptions as   -- GHC bugs.-  let !formattedText = printSnippets result0 $ cfgPrinterOpts cfgWithIndices+  let !formattedText = printSnippets (cfgDebug cfg) result0 $ cfgPrinterOpts cfgWithIndices   when (not (cfgUnsafe cfg) || cfgCheckIdempotence cfg) $ do     -- Parse the result of pretty-printing again and make sure that AST     -- is the same as AST of original snippet module span positions.@@ -144,7 +144,7 @@     -- Try re-formatting the formatted result to check if we get exactly     -- the same output.     when (cfgCheckIdempotence cfg) . liftIO $-      let reformattedText = printSnippets result1 $ cfgPrinterOpts cfgWithIndices+      let reformattedText = printSnippets (cfgDebug cfg) result1 $ cfgPrinterOpts cfgWithIndices        in case diffText formattedText reformattedText path of             Nothing -> return ()             Just diff -> throwIO (OrmoluNonIdempotentOutput diff)
src/Ormolu/Config.hs view
@@ -42,6 +42,7 @@     InStyle (..),     Unicode (..),     ColumnLimit (..),+    SingleDerivingParens (..),     parsePrinterOptsCLI,     parsePrinterOptType, @@ -58,6 +59,7 @@ import Data.Aeson ((.!=), (.:?)) import Data.Aeson qualified as Aeson import Data.Aeson.Types qualified as Aeson+import Data.Foldable (foldl') import Data.Functor.Identity (Identity (..)) import Data.Map.Strict qualified as Map import Data.Set (Set)@@ -230,7 +232,7 @@  -- | Apply the given configuration in order (later options override earlier). resolvePrinterOpts :: [PrinterOptsPartial] -> PrinterOptsTotal-resolvePrinterOpts = foldr fillMissingPrinterOpts defaultPrinterOpts+resolvePrinterOpts = foldl' (flip fillMissingPrinterOpts) defaultPrinterOpts  ---------------------------------------------------------------------------- -- Loading Fourmolu configuration
src/Ormolu/Config/Gen.hs view
@@ -18,6 +18,7 @@   , Unicode (..)   , SingleConstraintParens (..)   , ColumnLimit (..)+  , SingleDerivingParens (..)   , emptyPrinterOpts   , defaultPrinterOpts   , defaultPrinterOptsYaml@@ -65,6 +66,8 @@       poInStyle :: f InStyle     , -- | Whether to put parentheses around a single constraint       poSingleConstraintParens :: f SingleConstraintParens+    , -- | Whether to put parentheses around a single deriving class+      poSingleDerivingParens :: f SingleDerivingParens     , -- | Output Unicode syntax       poUnicode :: f Unicode     , -- | Give the programmer more choice on where to insert blank lines@@ -88,6 +91,7 @@     , poLetStyle = Nothing     , poInStyle = Nothing     , poSingleConstraintParens = Nothing+    , poSingleDerivingParens = Nothing     , poUnicode = Nothing     , poRespectful = Nothing     }@@ -108,6 +112,7 @@     , poLetStyle = pure LetAuto     , poInStyle = pure InRightAlign     , poSingleConstraintParens = pure ConstraintAlways+    , poSingleDerivingParens = pure DerivingAlways     , poUnicode = pure UnicodeNever     , poRespectful = pure True     }@@ -135,6 +140,7 @@     , poLetStyle = maybe (poLetStyle p2) pure (poLetStyle p1)     , poInStyle = maybe (poInStyle p2) pure (poInStyle p1)     , poSingleConstraintParens = maybe (poSingleConstraintParens p2) pure (poSingleConstraintParens p1)+    , poSingleDerivingParens = maybe (poSingleDerivingParens p2) pure (poSingleDerivingParens p1)     , poUnicode = maybe (poUnicode p2) pure (poUnicode p1)     , poRespectful = maybe (poRespectful p2) pure (poRespectful p1)     }@@ -198,6 +204,10 @@       "Whether to put parentheses around a single constraint (choices: \"auto\", \"always\", or \"never\") (default: always)"       "OPTION"     <*> f+      "single-deriving-parens"+      "Whether to put parentheses around a single deriving class (choices: \"auto\", \"always\", or \"never\") (default: always)"+      "OPTION"+    <*> f       "unicode"       "Output Unicode syntax (choices: \"detect\", \"always\", or \"never\") (default: never)"       "OPTION"@@ -225,6 +235,7 @@     <*> f "let-style"     <*> f "in-style"     <*> f "single-constraint-parens"+    <*> f "single-deriving-parens"     <*> f "unicode"     <*> f "respectful" @@ -305,6 +316,12 @@   | ColumnLimit Int   deriving (Eq, Show) +data SingleDerivingParens+  = DerivingAuto+  | DerivingAlways+  | DerivingNever+  deriving (Eq, Show, Enum, Bounded)+ instance Aeson.FromJSON CommaStyle where   parseJSON =     Aeson.withText "CommaStyle" $ \s ->@@ -490,6 +507,24 @@               "Valid values are: \"none\", or an integer"             ] +instance Aeson.FromJSON SingleDerivingParens where+  parseJSON =+    Aeson.withText "SingleDerivingParens" $ \s ->+      either Aeson.parseFail pure $+        parsePrinterOptType (Text.unpack s)++instance PrinterOptsFieldType SingleDerivingParens where+  parsePrinterOptType s =+    case s of+      "auto" -> Right DerivingAuto+      "always" -> Right DerivingAlways+      "never" -> Right DerivingNever+      _ ->+        Left . unlines $+          [ "unknown value: " <> show s+          , "Valid values are: \"auto\", \"always\", or \"never\""+          ]+ defaultPrinterOptsYaml :: String defaultPrinterOptsYaml =   unlines@@ -531,6 +566,9 @@     , ""     , "# Whether to put parentheses around a single constraint (choices: auto, always, or never)"     , "single-constraint-parens: always"+    , ""+    , "# Whether to put parentheses around a single deriving class (choices: auto, always, or never)"+    , "single-deriving-parens: always"     , ""     , "# Output Unicode syntax (choices: detect, always, or never)"     , "unicode: never"
src/Ormolu/Diff/ParseResult.hs view
@@ -1,5 +1,6 @@ {-# LANGUAGE DataKinds #-} {-# LANGUAGE DeepSubsumption #-}+{-# LANGUAGE LambdaCase #-} {-# LANGUAGE RecordWildCards #-} {-# LANGUAGE ViewPatterns #-} @@ -160,5 +161,7 @@     classDeclCtxEq tc tc' = genericQuery tc tc'      derivedTyClsParensEq :: DerivClauseTys GhcPs -> GenericQ ParseResultDiff-    derivedTyClsParensEq (DctSingle NoExtField sigTy) dct' = genericQuery (DctMulti NoExtField [sigTy]) dct'-    derivedTyClsParensEq dct dct' = genericQuery dct dct'+    derivedTyClsParensEq = considerEqualVia $ curry $ \case+      (DctSingle _ ty, DctMulti _ [ty']) -> genericQuery ty ty'+      (DctMulti _ [ty], DctSingle _ ty') -> genericQuery ty ty'+      (x, y) -> genericQuery x y
src/Ormolu/Fixity/Internal.hs view
@@ -42,6 +42,7 @@ import Data.Text (Text) import Data.Text qualified as T import Data.Text.Encoding qualified as T+import Debug.Trace (trace) import Distribution.ModuleName (ModuleName) import Distribution.Types.PackageName import GHC.Data.FastString (fs_sbs)@@ -256,24 +257,62 @@   deriving stock (Eq, Show)  -- | Get a 'FixityApproximation' of an operator.-inferFixity :: RdrName -> ModuleFixityMap -> FixityApproximation-inferFixity rdrName (ModuleFixityMap m) =-  case Map.lookup opName m of-    Nothing -> defaultFixityApproximation-    Just (Given fixityInfo) ->-      fixityInfoToApproximation fixityInfo-    Just (FromModuleImports xs) ->-      let isMatching (provenance, _fixityInfo) =-            case provenance of-              UnqualifiedAndQualified mn ->-                maybe True (== mn) moduleName-              OnlyQualified mn ->-                maybe False (== mn) moduleName-       in fromMaybe defaultFixityApproximation-            . foldMap (Just . fixityInfoToApproximation . snd)-            $ NE.filter isMatching xs+inferFixity ::+  -- | Whether to print debug info regarding fixity inference+  Bool ->+  -- | Operator name+  RdrName ->+  -- | Module fixity map+  ModuleFixityMap ->+  -- | The resulting fixity approximation+  FixityApproximation+inferFixity debug rdrName (ModuleFixityMap m) =+  if debug+    then+      trace+        (renderFixityJustification opName moduleName m result)+        result+    else result   where+    result =+      case Map.lookup opName m of+        Nothing -> defaultFixityApproximation+        Just (Given fixityInfo) ->+          fixityInfoToApproximation fixityInfo+        Just (FromModuleImports xs) ->+          let isMatching (provenance, _fixityInfo) =+                case provenance of+                  UnqualifiedAndQualified mn ->+                    maybe True (== mn) moduleName+                  OnlyQualified mn ->+                    maybe False (== mn) moduleName+           in fromMaybe defaultFixityApproximation+                . foldMap (Just . fixityInfoToApproximation . snd)+                $ NE.filter isMatching xs     opName = occOpName (rdrNameOcc rdrName)     moduleName = case rdrName of       Qual x _ -> Just (ghcModuleNameToCabal x)       _ -> Nothing++-- | Render a human-readable account of why a certain 'FixityApproximation'+-- was chosen for an operator.+renderFixityJustification ::+  -- | Operator name+  OpName ->+  -- | Qualification of the operator name+  Maybe ModuleName ->+  -- | Module fixity map+  Map OpName FixityProvenance ->+  -- | The chosen fixity approximation+  FixityApproximation ->+  String+renderFixityJustification opName mqualification m approximation =+  concat+    [ "FIXITY analysis of ",+      show opName,+      case mqualification of+        Nothing -> ""+        Just mn -> " qualified in " ++ show mn,+      "\n  Provenance: " ++ show (Map.lookup opName m),+      "\n  Inferred: " ++ show approximation+    ]
src/Ormolu/Printer.hs view
@@ -19,12 +19,14 @@  -- | Render several source snippets. printSnippets ::+  -- | Whether to print out debug information during printing+  Bool ->   -- | Result of parsing   [SourceSnippet] ->   PrinterOptsTotal ->   -- | Resulting rendition   Text-printSnippets snippets printerOpts = T.concat . fmap printSnippet $ snippets+printSnippets debug snippets printerOpts = T.concat . fmap printSnippet $ snippets   where     printSnippet = \case       ParsedSnippet ParseResult {..} ->@@ -41,4 +43,5 @@             prSourceType             prExtensions             prModuleFixityMap+            debug       RawSnippet r -> r
src/Ormolu/Printer/Combinators.hs view
@@ -27,6 +27,7 @@     inciByFrac,     askSourceType,     askModuleFixityMap,+    askDebug,     located,     encloseLocated,     located',
src/Ormolu/Printer/Internal.hs view
@@ -19,6 +19,7 @@     declNewline,     askSourceType,     askModuleFixityMap,+    askDebug,     inci,     inciBy,     inciByFrac,@@ -107,7 +108,9 @@     -- | Whether the source is a signature or a regular module     rcSourceType :: SourceType,     -- | Module fixity map-    rcModuleFixityMap :: ModuleFixityMap+    rcModuleFixityMap :: ModuleFixityMap,+    -- | Whether to print out debug information during printing+    rcDebug :: !Bool   }  -- | State context of 'R'.@@ -179,8 +182,9 @@   -- | Module fixity map   ModuleFixityMap ->   -- | Resulting rendition+  Bool ->   Text-runR (R m) sstream cstream printerOpts sourceType extensions moduleFixityMap =+runR (R m) sstream cstream printerOpts sourceType extensions moduleFixityMap debug =   TL.toStrict . toLazyText . scBuilder $ execState (runReaderT m rc) sc   where     rc =@@ -192,7 +196,8 @@           rcPrinterOpts = printerOpts,           rcExtensions = extensions,           rcSourceType = sourceType,-          rcModuleFixityMap = moduleFixityMap+          rcModuleFixityMap = moduleFixityMap,+          rcDebug = debug         }     sc =       SC@@ -400,6 +405,11 @@ -- | Retrieve the module fixity map. askModuleFixityMap :: R ModuleFixityMap askModuleFixityMap = R (asks rcModuleFixityMap)++-- | Retrieve whether we should print out certain debug information while+-- printing.+askDebug :: R Bool+askDebug = R (asks rcDebug)  -- | Like 'inci', but indents by exactly the given number of steps. inciBy :: Int -> R () -> R ()
src/Ormolu/Printer/Meat/Declaration/Data.hs view
@@ -52,74 +52,78 @@   txt $ case style of     Associated -> mempty     Free -> " instance"-  case unLoc <$> dd_cType of-    Nothing -> pure ()-    Just (CType prag header (type_, _)) -> do-      space-      p_sourceText prag-      case header of-        Nothing -> pure ()-        Just (Header h _) -> space *> p_sourceText h-      space-      p_sourceText type_-      txt " #-}"   let constructorSpans = getLocA name : fmap getTyVarLoc tyVars       sigSpans = maybeToList . fmap getLocA $ dd_kindSig+      contextSpans = maybeToList . fmap getLocA $ dd_ctxt+      ctypeSpans = maybeToList . fmap getLocA $ dd_cType       declHeaderSpans =-        maybeToList (getLocA <$> dd_ctxt) ++ constructorSpans ++ sigSpans-  switchLayout declHeaderSpans $ do-    breakpoint-    inci $ do-      case dd_ctxt of-        Nothing -> pure ()-        Just ctxt -> do-          located ctxt p_hsContext-          space-          txt "=>"-          breakpoint-      switchLayout constructorSpans $-        p_infixDefHelper-          (isInfix fixity)-          True-          (p_rdrName name)-          (p_tyVar <$> tyVars)-      forM_ dd_kindSig $ \k -> do-        space-        token'dcolon+        constructorSpans ++ sigSpans ++ contextSpans ++ ctypeSpans+  switchLayout declHeaderSpans . inci $ do+    case unLoc <$> dd_cType of+      Nothing -> pure ()+      Just (CType prag header (type_, _)) -> do         breakpoint-        inci $ located k p_hsType+        p_sourceText prag+        case header of+          Nothing -> pure ()+          Just (Header h _) -> space *> p_sourceText h+        space+        p_sourceText type_+        txt " #-}"+    breakpoint+    forM_ dd_ctxt p_lhsContext+    switchLayout constructorSpans $+      p_infixDefHelper+        (isInfix fixity)+        True+        (p_rdrName name)+        (p_tyVar <$> tyVars)+    forM_ dd_kindSig $ \k -> do+      space+      token'dcolon+      breakpoint+      inci $ located k p_hsType   let dd_cons' = case dd_cons of         NewTypeCon a -> [a]         DataTypeCons _ as -> as       gadt = isJust dd_kindSig || any (isGadt . unLoc) dd_cons'-  unless (null dd_cons') $-    if gadt-      then inci $ do-        switchLayout declHeaderSpans $ do+  case dd_cons' of+    [] -> pure ()+    first_dd_cons : _ ->+      if gadt+        then inci $ do+          switchLayout declHeaderSpans $ do+            breakpoint+            txt "where"           breakpoint-          txt "where"-        breakpoint-        sepSemi (located' (p_conDecl False)) dd_cons'-      else switchLayout (getLocA name : (getLocA <$> dd_cons')) . inci $ do-        let singleConstRec = isSingleConstRec dd_cons'-        if hasHaddocks dd_cons'-          then newline-          else-            if singleConstRec-              then space-              else breakpoint-        equals-        space-        layout <- getLayout-        let s =-              if layout == MultiLine || hasHaddocks dd_cons'-                then newline >> txt "|" >> space-                else space >> txt "|" >> space-            sitcc' =-              if hasHaddocks dd_cons' || not singleConstRec-                then sitcc-                else id-        sep s (sitcc' . located' (p_conDecl singleConstRec)) dd_cons'+          sepSemi (located' (p_conDecl False)) dd_cons'+        else switchLayout (getLocA name : (getLocA <$> dd_cons')) . inci $ do+          let singleConstRec = isSingleConstRec dd_cons'+              compactLayoutAroundEquals =+                onTheSameLine+                  (getLocA name)+                  (combineSrcSpans' (conDeclConsSpans (unLoc first_dd_cons)))+              conDeclConsSpans = \case+                ConDeclGADT {..} -> getLocA <$> con_names+                ConDeclH98 {..} -> getLocA con_name :| []+          if hasHaddocks dd_cons'+            then newline+            else+              if singleConstRec && compactLayoutAroundEquals+                then space+                else breakpoint+          equals+          space+          layout <- getLayout+          let s =+                if layout == MultiLine || hasHaddocks dd_cons'+                  then newline >> txt "|" >> space+                  else space >> txt "|" >> space+              sitcc' =+                if hasHaddocks dd_cons' || not singleConstRec+                  then sitcc+                  else id+          sep s (sitcc' . located' (p_conDecl singleConstRec)) dd_cons'   unless (null dd_derivs) breakpoint   inci $ sep newline (located' p_hsDerivingClause) dd_derivs @@ -168,48 +172,49 @@         startTypeAnnotationDecl quantifiedTy id p_hsType   ConDeclH98 {..} -> do     mapM_ (p_hsDoc Pipe True) con_doc-    let conDeclWithContextSpn =+    let conNameSpn = getLocA con_name+        conNameWithContextSpn =           [ RealSrcSpan real Strict.Nothing             | Just (EpaSpan real _) <- matchAddEpAnn AnnForall <$> epAnnAnns con_ext           ]             <> fmap getLocA con_ex_tvs             <> maybeToList (fmap getLocA con_mb_cxt)-            <> conDeclSpn-        conDeclSpn = getLocA con_name : conArgsSpans+            <> [conNameSpn]+        conDeclSpn = conNameSpn : conArgsSpans           where             conArgsSpans = case con_args of               PrefixCon [] xs -> getLocA . hsScaledThing <$> xs               PrefixCon (v : _) _ -> absurd v               RecCon l -> [getLocA l]               InfixCon x y -> getLocA . hsScaledThing <$> [x, y]-    switchLayout conDeclWithContextSpn $ do+    switchLayout conNameWithContextSpn $ do       when con_forall $ do         p_forallBndrs ForAllInvis p_hsTyVarBndr con_ex_tvs         breakpoint         indent <- getPrinterOpt poIndentation         vlayout (pure ()) . txt $ Text.replicate (indent - 2) " "       forM_ con_mb_cxt p_lhsContext-      switchLayout conDeclSpn $ case con_args of-        PrefixCon [] xs -> do-          p_rdrName con_name-          let args = hsScaledThing <$> xs-              argsHaveDocs = conArgsHaveHaddocks args-              delimiter = if argsHaveDocs then newline else breakpoint-          unless (null xs) delimiter-          inci . sitcc $-            sep delimiter (sitcc . located' p_hsType) args-        PrefixCon (v : _) _ -> absurd v-        RecCon l -> do+    switchLayout conDeclSpn $ case con_args of+      PrefixCon [] xs -> do+        p_rdrName con_name+        let args = hsScaledThing <$> xs+            argsHaveDocs = conArgsHaveHaddocks args+            delimiter = if argsHaveDocs then newline else breakpoint+        unless (null xs) delimiter+        inci . sitcc $+          sep delimiter (sitcc . located' p_hsType) args+      PrefixCon (v : _) _ -> absurd v+      RecCon l -> do+        p_rdrName con_name+        breakpoint+        inciIf (not singleConstRec) (located l p_conDeclFields)+      InfixCon (HsScaled _ x) (HsScaled _ y) -> do+        located x p_hsType+        breakpoint+        inci $ do           p_rdrName con_name-          breakpoint-          inciIf (not singleConstRec) (located l p_conDeclFields)-        InfixCon (HsScaled _ x) (HsScaled _ y) -> do-          located x p_hsType-          breakpoint-          inci $ do-            p_rdrName con_name-            space-            located y p_hsType+          space+          located y p_hsType  p_lhsContext ::   LHsContext GhcPs ->@@ -231,15 +236,23 @@   HsDerivingClause GhcPs ->   R () p_hsDerivingClause HsDerivingClause {..} = do+  singleDerivingParens <- getPrinterOpt poSingleDerivingParens+   txt "deriving"   let derivingWhat = located deriv_clause_tys $ \case-        DctSingle NoExtField sigTy -> parens N $ located sigTy p_hsSigType-        DctMulti NoExtField sigTys ->-          parens N $-            sep-              commaDel-              (sitcc . located' p_hsSigType)-              sigTys+        DctSingle NoExtField sigTy+          | DerivingAlways <- singleDerivingParens -> parens N $ located sigTy p_hsSigType+          | otherwise -> located sigTy p_hsSigType+        DctMulti NoExtField sigTys+          | [sigTy] <- sigTys,+            DerivingNever <- singleDerivingParens ->+              located sigTy p_hsSigType+          | otherwise ->+              parens N $+                sep+                  commaDel+                  (sitcc . located' p_hsSigType)+                  sigTys   space   case deriv_clause_strategy of     Nothing -> do
src/Ormolu/Printer/Meat/Declaration/Value.hs view
@@ -353,10 +353,11 @@       inci (sequence_ (intersperse breakpoint (located' (p_hsCmdTop N) <$> cmds)))   HsCmdArrForm _ form Infix _ [left, right] -> do     modFixityMap <- askModuleFixityMap+    debug <- askDebug     let opTree = BinaryOpBranches (cmdOpTree left) form (cmdOpTree right)     p_cmdOpTree       s-      (reassociateOpTree (getOpName . unLoc) modFixityMap opTree)+      (reassociateOpTree debug (getOpName . unLoc) modFixityMap opTree)   HsCmdArrForm _ _ Infix _ _ -> notImplemented "HsCmdArrForm"   HsCmdApp _ cmd expr -> do     located cmd (p_hsCmd' Applicand s)@@ -368,8 +369,8 @@     p_case isApp cmdPlacement p_hsCmd e mgroup   HsCmdLamCase _ variant mgroup ->     p_lamcase isApp variant cmdPlacement p_hsCmd mgroup-  HsCmdIf _ _ if' then' else' ->-    p_if cmdPlacement p_hsCmd if' then' else'+  HsCmdIf anns _ if' then' else' ->+    p_if cmdPlacement p_hsCmd anns if' then' else'   HsCmdLet _ letToken localBinds _ c ->     p_let (s == S) p_hsCmd letToken localBinds c   HsCmdDo _ es -> do@@ -699,10 +700,11 @@       located (hswc_body a) p_hsType   OpApp _ x op y -> do     modFixityMap <- askModuleFixityMap+    debug <- askDebug     let opTree = BinaryOpBranches (exprOpTree x) op (exprOpTree y)     p_exprOpTree       s-      (reassociateOpTree (getOpName . unLoc) modFixityMap opTree)+      (reassociateOpTree debug (getOpName . unLoc) modFixityMap opTree)   NegApp _ e _ -> do     negativeLiterals <- isExtensionEnabled NegativeLiterals     let isLiteral = case unLoc e of@@ -751,8 +753,8 @@     p_unboxedSum N tag arity (located e p_hsExpr)   HsCase _ e mgroup ->     p_case isApp exprPlacement p_hsExpr e mgroup-  HsIf _ if' then' else' ->-    p_if exprPlacement p_hsExpr if' then' else'+  HsIf anns if' then' else' ->+    p_if exprPlacement p_hsExpr anns if' then' else'   HsMultiIf _ guards -> do     txt "if"     breakpoint@@ -988,6 +990,8 @@   (body -> Placement) ->   -- | Render   (body -> R ()) ->+  -- | Annotations+  EpAnn AnnsIf ->   -- | If   LHsExpr GhcPs ->   -- | Then@@ -995,21 +999,47 @@   -- | Else   LocatedA body ->   R ()-p_if placer render if' then' else' = do+p_if placer render epAnn if' then' else' = do   txt "if"   space   located if' p_hsExpr   breakpoint   inci $ do-    txt "then"+    locatedToken thenSpan "then"     space-    located then' $ \x ->-      placeHanging (placer x) (render x)+    placeHangingLocated thenSpan then'     breakpoint-    txt "else"+    locatedToken elseSpan "else"     space-    located else' $ \x ->-      placeHanging (placer x) (render x)+    placeHangingLocated elseSpan else'+  where+    (thenSpan, elseSpan, commentSpans) =+      case epAnn of+        EpAnn {anns = AnnsIf {aiThen, aiElse}, comments} ->+          ( loc' $ epaLocationRealSrcSpan aiThen,+            loc' $ epaLocationRealSrcSpan aiElse,+            map (anchor . getLoc) $+              case comments of+                EpaComments cs -> cs+                EpaCommentsBalanced pre post -> pre <> post+          )+        EpAnnNotUsed ->+          (noSrcSpan, noSrcSpan, [])++    locatedToken tokenSpan token =+      located (L tokenSpan ()) $ \_ -> txt token++    betweenSpans spanA spanB s = spanA < s && s < spanB++    placeHangingLocated tokenSpan bodyLoc@(L _ body) = do+      let bodySpan = getLoc' bodyLoc+          hasComments = fromMaybe False $ do+            tokenRealSpan <- srcSpanToRealSrcSpan tokenSpan+            bodyRealSpan <- srcSpanToRealSrcSpan bodySpan+            pure $ any (betweenSpans tokenRealSpan bodyRealSpan) commentSpans+          placement = if hasComments then Normal else placer body+      switchLayout [tokenSpan, bodySpan] $+        placeHanging placement (located bodyLoc render)  p_let ::   -- | True if in do-block
src/Ormolu/Printer/Meat/Type.hs view
@@ -121,9 +121,10 @@       sep (space >> txt "|" >> breakpoint) (sitcc . located' p_hsType) xs   HsOpTy _ _ x op y -> do     modFixityMap <- askModuleFixityMap+    debug <- askDebug     let opTree = BinaryOpBranches (tyOpTree x) op (tyOpTree y)     p_tyOpTree-      (reassociateOpTree (Just . unLoc) modFixityMap opTree)+      (reassociateOpTree debug (Just . unLoc) modFixityMap opTree)   HsParTy _ t ->     parens N $ sitcc $ located t p_hsType   HsIParamTy _ n t -> sitcc $ do
src/Ormolu/Printer/Operators.hs view
@@ -90,6 +90,8 @@ -- Users are expected to first construct an initial 'OpTree', then -- re-associate it using this function before printing. reassociateOpTree ::+  -- | Whether to print debug info regarding fixity inference+  Bool ->   -- | How to get name of an operator   (op -> Maybe RdrName) ->   -- | Fixity Map@@ -98,14 +100,16 @@   OpTree ty op ->   -- | Re-associated 'OpTree', with added context and info around operators   OpTree ty (OpInfo op)-reassociateOpTree getOpName modFixityMap =+reassociateOpTree debug getOpName modFixityMap =   reassociateFlatOpTree     . makeFlatOpTree-    . addFixityInfo modFixityMap getOpName+    . addFixityInfo debug modFixityMap getOpName  -- | Wrap every operator of the tree with 'OpInfo' to carry the information -- about its fixity (extracted from the specified fixity map). addFixityInfo ::+  -- | Whether to print debug info regarding fixity inference+  Bool ->   -- | Fixity map for operators   ModuleFixityMap ->   -- | How to get the name of an operator@@ -114,10 +118,10 @@   OpTree ty op ->   -- | 'OpTree', with fixity info wrapped around each operator   OpTree ty (OpInfo op)-addFixityInfo _ _ (OpNode n) = OpNode n-addFixityInfo modFixityMap getOpName (OpBranches exprs ops) =+addFixityInfo _ _ _ (OpNode n) = OpNode n+addFixityInfo debug modFixityMap getOpName (OpBranches exprs ops) =   OpBranches-    (addFixityInfo modFixityMap getOpName <$> exprs)+    (addFixityInfo debug modFixityMap getOpName <$> exprs)     (toOpInfo <$> ops)   where     toOpInfo o = OpInfo o mrdrName fixityApproximation@@ -125,7 +129,7 @@         mrdrName = getOpName o         fixityApproximation = case mrdrName of           Nothing -> defaultFixityApproximation-          Just rdrName -> inferFixity rdrName modFixityMap+          Just rdrName -> inferFixity debug rdrName modFixityMap  -- | Given a 'OpTree' of any shape, produce a flat 'OpTree', where every -- node and operator is directly connected to the root.
src/Ormolu/Utils.hs view
@@ -172,6 +172,9 @@ instance HasSrcSpan SrcSpan where   loc' = id +instance HasSrcSpan RealSrcSpan where+  loc' l = RealSrcSpan l Strict.Nothing+ instance HasSrcSpan (SrcSpanAnn' ann) where   loc' = locA 
tests/Ormolu/Config/PrinterOptsSpec.hs view
@@ -50,7 +50,8 @@ import Text.PrettyPrint qualified as Doc import Text.Printf (printf) -data TestGroup = forall a.+data TestGroup+  = forall a.   TestGroup   { label :: String,     -- | When True, takes input from 'input-multi.hs' instead of 'input.hs', where sections@@ -195,6 +196,15 @@           isMulti = False,           testCases = allOptions,           updateConfig = \parens opts -> opts {poSingleConstraintParens = pure parens},+          showTestCase = show,+          testCaseSuffix = suffix1,+          checkIdempotence = True+        },+      TestGroup+        { label = "single-deriving-parens",+          isMulti = False,+          testCases = allOptions,+          updateConfig = \parens opts -> opts {poSingleDerivingParens = pure parens},           showTestCase = show,           testCaseSuffix = suffix1,           checkIdempotence = True
tests/Ormolu/ConfigSpec.hs view
@@ -7,7 +7,7 @@ import Data.List.NonEmpty qualified as NonEmpty import Data.Map qualified as Map import Data.Yaml qualified as Yaml-import Ormolu.Config (FourmoluConfig (..))+import Ormolu.Config (FourmoluConfig (..), poIndentation, resolvePrinterOpts) import Ormolu.Fixity (ModuleReexports (..)) import Test.Hspec @@ -26,3 +26,8 @@               [ ("Foo", NonEmpty.fromList [(Nothing, "Bar2"), (Nothing, "Bar1")])               ]       cfgFileReexports config `shouldBe` ModuleReexports expected+    it "applies configurations in correct order" $ do+      let opts1 = mempty {poIndentation = Just 2}+          opts2 = mempty {poIndentation = Just 4}+          configs = [opts1, opts2]+      poIndentation (resolvePrinterOpts configs) `shouldBe` 4
tests/Ormolu/FixitySpec.hs view
@@ -261,7 +261,7 @@   where     actualResult =       fmap-        (\(k, _) -> (k, inferFixity k resultMap))+        (\(k, _) -> (k, inferFixity False k resultMap))         expectedResult     resultMap =       moduleFixityMap
tests/Ormolu/Integration/FixitySpec.hs view
@@ -61,7 +61,7 @@         testInputFileName = "test-0-input.hs",         testArgs = [],         testUseConfig = False,-        testExpectedFileName = "test-0-no-extra-info-expected.hs"+        testExpectedFileName = "test-0-ugly-expected.hs"       },     Test       { testLabel = "File #0 works with manual fixity info",@@ -76,6 +76,13 @@         testArgs = ["--package", "base"],         testUseConfig = True,         testExpectedFileName = "test-0-with-fixity-info-expected.hs"+      },+    Test+      { testLabel = "File #0 works when CLI overrides .ormolu",+        testInputFileName = "test-0-input.hs",+        testArgs = ["--package", "base", "--fixity", "infixr 5 .=", "--no-cabal"],+        testUseConfig = True,+        testExpectedFileName = "test-0-ugly-expected.hs"       },     Test       { testLabel = "File #1 works with no extra info",
tests/Ormolu/OpTreeSpec.hs view
@@ -31,7 +31,7 @@     removeOpInfo (OpNode x) = OpNode x     removeOpInfo (OpBranches exprs ops) =       OpBranches (removeOpInfo <$> exprs) (opiOp <$> ops)-    actualOutputTree = reassociateOpTree convertName modFixityMap inputTree+    actualOutputTree = reassociateOpTree False convertName modFixityMap inputTree     modFixityMap = ModuleFixityMap (Map.map Given (Map.fromList fixities))     convertName = Just . mkRdrUnqual . mkOccName varName . T.unpack . unOpName