packages feed

fourmolu 0.0.6.0 → 0.1.0.0

raw patch · 27 files changed

+265/−102 lines, 27 filesdep +aesondep +directorydep +yamldep ~filepathnew-uploaderPVP ok

version bump matches the API change (PVP)

Dependencies added: aeson, directory, yaml

Dependency ranges changed: filepath

API changes (from Hackage documentation)

+ Ormolu: PrinterOpts :: Int -> PrinterOpts
+ Ormolu: [cfgPrinterOpts] :: Config region -> PrinterOpts
+ Ormolu: [poIndentStep] :: PrinterOpts -> Int
+ Ormolu: data PrinterOpts
+ Ormolu: defaultPrinterOpts :: PrinterOpts
+ Ormolu: loadConfigFile :: Bool -> Maybe FilePath -> PrinterOpts -> IO PrinterOpts
+ Ormolu.Config: PrinterOpts :: Int -> PrinterOpts
+ Ormolu.Config: [cfgPrinterOpts] :: Config region -> PrinterOpts
+ Ormolu.Config: [poIndentStep] :: PrinterOpts -> Int
+ Ormolu.Config: data PrinterOpts
+ Ormolu.Config: defaultPrinterOpts :: PrinterOpts
+ Ormolu.Config: instance Data.Aeson.Types.FromJSON.FromJSON Ormolu.Config.PrinterOptsPartial
+ Ormolu.Config: instance GHC.Classes.Eq Ormolu.Config.PrinterOpts
+ Ormolu.Config: instance GHC.Classes.Eq Ormolu.Config.PrinterOptsPartial
+ Ormolu.Config: instance GHC.Generics.Generic Ormolu.Config.PrinterOptsPartial
+ Ormolu.Config: instance GHC.Show.Show Ormolu.Config.PrinterOpts
+ Ormolu.Config: instance GHC.Show.Show Ormolu.Config.PrinterOptsPartial
+ Ormolu.Config: loadConfigFile :: Bool -> Maybe FilePath -> PrinterOpts -> IO PrinterOpts
+ Ormolu.Printer: PrinterOpts :: Int -> PrinterOpts
+ Ormolu.Printer: [poIndentStep] :: PrinterOpts -> Int
+ Ormolu.Printer: data PrinterOpts
+ Ormolu.Printer.Operators: instance GHC.Classes.Eq Ormolu.Printer.Operators.Score
+ Ormolu.Printer.Operators: instance GHC.Classes.Ord Ormolu.Printer.Operators.Score
- Ormolu: Config :: ![DynOption] -> !Bool -> !Bool -> !Bool -> !region -> Config region
+ Ormolu: Config :: ![DynOption] -> !Bool -> !Bool -> !Bool -> !region -> PrinterOpts -> Config region
- Ormolu.Config: Config :: ![DynOption] -> !Bool -> !Bool -> !Bool -> !region -> Config region
+ Ormolu.Config: Config :: ![DynOption] -> !Bool -> !Bool -> !Bool -> !region -> PrinterOpts -> Config region
- Ormolu.Printer: printModule :: ParseResult -> Text
+ Ormolu.Printer: printModule :: ParseResult -> PrinterOpts -> Text
- Ormolu.Printer.Combinators: runR :: R () -> SpanStream -> CommentStream -> Anns -> Bool -> Text
+ Ormolu.Printer.Combinators: runR :: R () -> SpanStream -> CommentStream -> Anns -> PrinterOpts -> Bool -> Text
- Ormolu.Printer.Internal: runR :: R () -> SpanStream -> CommentStream -> Anns -> Bool -> Text
+ Ormolu.Printer.Internal: runR :: R () -> SpanStream -> CommentStream -> Anns -> PrinterOpts -> Bool -> Text

Files

CHANGELOG.md view
@@ -1,14 +1,18 @@-## Fourmolu 0.0.6.0+## Fourmolu 0.1.0.0 -* The project was fourked to provide four space indent.+* Allow configuration of indentation size via `fourmolu.yaml` config files. +* An operator on a new line is no longer indented when its left operand is a do-block. This prevents the AST from potentially changing when indenting by more than two spaces.++Upstream changes:+ * Fixed rendering of type signatures concerning several identifiers. [Issue   566](https://github.com/tweag/ormolu/issues/566).  * Fixed an idempotence issue with inline comments in tuples and parentheses.   [Issue 450](https://github.com/tweag/ormolu/issues/450). -* Fixed an idempotence issue when certain comments where picked up as+* Fixed an idempotence issue when certain comments were picked up as   “continuation” of a series of comments [Issue   449](https://github.com/tweag/ormolu/issues/449). @@ -27,7 +31,7 @@   multiple blank lines in a row. [Issue   518](https://github.com/tweag/ormolu/issues/518). -* Fixed rendering of comment around if expressions. [Issue+* Fixed rendering of comments around if expressions. [Issue   458](https://github.com/tweag/ormolu/issues/458).  * Unnamed fields of data constructors are now documented using the `-- ^`@@ -37,8 +41,15 @@ * Fixed non-idempotent transformation of partly documented data definition.   [Issue 590](https://github.com/tweag/ormolu/issues/590). +* Fixed an idempotence issue related to operators. [Issue+  522](https://github.com/tweag/ormolu/issues/522).+ * Renamed the `--check-idempotency` flag to `--check-idempotence`.   Apparently only the latter is correct.++## Fourmolu 0.0.6.0++* The project was fourked to provide four space indent.  ## Ormolu 0.0.5.0 
app/Main.hs view
@@ -25,7 +25,10 @@ main :: IO () main = withPrettyOrmoluExceptions $ do   Opts {..} <- execParser optsParserInfo-  let formatOne' = formatOne optMode optConfig+  let formatOne' path = do+        printerOpts <-+          loadConfigFile (cfgDebug optConfig) path $ cfgPrinterOpts optConfig+        formatOne optMode optConfig {cfgPrinterOpts = printerOpts} path   case optInputFiles of     [] -> formatOne' Nothing     ["-"] -> formatOne' Nothing@@ -183,6 +186,7 @@                 help "End line of the region to format (inclusive)"               ]         )+    <*> pure defaultPrinterOpts  ---------------------------------------------------------------------------- -- Helpers
data/examples/declaration/value/function/infix/do-out.hs view
@@ -1,7 +1,7 @@ main =   do stuff-    `finally` do-      recover+  `finally` do+    recover  main = do stuff `finally` recover 
+ data/examples/declaration/value/function/operators-0-out.hs view
@@ -0,0 +1,5 @@+a =+  b & c .~ d+    & e+      %~ f+        g
+ data/examples/declaration/value/function/operators-0.hs view
@@ -0,0 +1,4 @@+a =+  b & c .~ d+    & e %~ f+            g
+ data/examples/declaration/value/function/operators-1-out.hs view
@@ -0,0 +1,4 @@+foo =+  f+    . g+    =<< h . i
+ data/examples/declaration/value/function/operators-1.hs view
@@ -0,0 +1,3 @@+foo = f+    . g+  =<< h . i
+ data/examples/declaration/value/function/operators-2-out.hs view
@@ -0,0 +1,4 @@+foo n+  | x || y && z || n ** x+      || x && n =+    42
+ data/examples/declaration/value/function/operators-2.hs view
@@ -0,0 +1,4 @@+foo n+  | x || y && z || n ** x+      || x && n =+        42
+ data/examples/declaration/value/function/operators-3-out.hs view
@@ -0,0 +1,3 @@+foo =+  op <> n <+> colon <+> prettySe <+> text "="+    <+> prettySe <> text sc
+ data/examples/declaration/value/function/operators-3.hs view
@@ -0,0 +1,3 @@+foo =+  op <> n <+> colon <+> prettySe <+> text "=" <+>+    prettySe <> text sc
+ data/examples/declaration/value/function/operators-4-out.hs view
@@ -0,0 +1,3 @@+foo =+  line <> bindingOf <+> text "=" <+> tPretty <+> colon+    <+> align <> prettyPs
+ data/examples/declaration/value/function/operators-4.hs view
@@ -0,0 +1,3 @@+foo =+  line <> bindingOf <+> text "=" <+> tPretty <+> colon <+>+    align <> prettyPs
+ data/examples/declaration/value/function/operators-5-out.hs view
@@ -0,0 +1,5 @@+foo =+  map bar $+    [ baz+    ]+      ++ quux
+ data/examples/declaration/value/function/operators-5.hs view
@@ -0,0 +1,4 @@+foo =+  map bar $+    [ baz+    ] ++ quux
+ data/examples/declaration/value/function/operators-6-out.hs view
@@ -0,0 +1,9 @@+type PermuteRef =+  "a"+    :> ( "b" :> "c" :> End+           :<|> "c" :> "b" :> End+       )+    :<|> "b"+      :> ( "a" :> "c" :> End+             :<|> "c" :> "a" :> End+         )
+ data/examples/declaration/value/function/operators-6.hs view
@@ -0,0 +1,7 @@+type PermuteRef =+       "a" :> (    "b" :> "c" :> End+              :<|> "c" :> "b" :> End+              )+  :<|> "b" :> (    "a" :> "c" :> End+              :<|> "c" :> "a" :> End+              )
− data/examples/declaration/value/function/operators-out.hs
@@ -1,5 +0,0 @@-a =-  b & c .~ d-    & e-      %~ f-        g
− data/examples/declaration/value/function/operators.hs
@@ -1,4 +0,0 @@-a =-  b & c .~ d-    & e %~ f-            g
fourmolu.cabal view
@@ -1,9 +1,9 @@ cabal-version:   1.18 name:            fourmolu-version:         0.0.6.0+version:         0.1.0.0 license:         BSD3 license-file:    LICENSE.md-maintainer:      Matt Parsons <parsonsmatt@gmail.com>+maintainer:      Matt Parsons <parsonsmatt@gmail.com>, George Thomas <georgefsthomas@gmail.com> tested-with:     ghc ==8.6.5 ghc ==8.8.3 ghc ==8.10.1 homepage:        https://github.com/parsonsmatt/fourmolu bug-reports:     https://github.com/parsonsmatt/fourmolu/issues@@ -116,15 +116,19 @@      default-language: Haskell2010     build-depends:+        aeson >=1.5.2 && <1.6,         base >=4.12 && <5.0,         bytestring >=0.2 && <0.11,         containers >=0.5 && <0.7,+        directory >= 1.3.5 && <1.4,         dlist >=0.8 && <0.9,         exceptions >=0.6 && <0.11,+        filepath >=1.4.2.1 && <1.5,         ghc-lib-parser >=8.10 && <8.11,         mtl >=2.0 && <3.0,         syb >=0.7 && <0.8,-        text >=0.2 && <1.3+        text >=0.2 && <1.3,+        yaml >=0.11.2 && <0.12      if flag(dev)         ghc-options:
src/Ormolu.hs view
@@ -9,6 +9,9 @@     RegionIndices (..),     defaultConfig,     DynOption (..),+    PrinterOpts (..),+    defaultPrinterOpts,+    loadConfigFile,     OrmoluException (..),     withPrettyOrmoluExceptions,   )@@ -62,7 +65,7 @@   -- about not-yet-supported functionality) will be thrown later 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 !txt = printModule result0+  let !txt = printModule result0 $ cfgPrinterOpts cfgWithIndices   when (not (cfgUnsafe cfg) || cfgCheckIdempotence cfg) $ do     let pathRendered = path ++ "<rendered>"     -- Parse the result of pretty-printing again and make sure that AST@@ -80,7 +83,7 @@     -- Try re-formatting the formatted result to check if we get exactly     -- the same output.     when (cfgCheckIdempotence cfg) $-      let txt2 = printModule result1+      let txt2 = printModule result1 $ cfgPrinterOpts cfgWithIndices        in case diffText txt txt2 pathRendered of             Nothing -> return ()             Just (loc, l, r) ->
src/Ormolu/Config.hs view
@@ -1,4 +1,6 @@ {-# LANGUAGE DeriveFunctor #-}+{-# LANGUAGE DeriveGeneric #-}+{-# LANGUAGE LambdaCase #-} {-# LANGUAGE RecordWildCards #-}  -- | Configuration options used by the tool.@@ -7,13 +9,38 @@     RegionIndices (..),     RegionDeltas (..),     defaultConfig,+    PrinterOpts (..),+    defaultPrinterOpts,+    loadConfigFile,     regionIndicesToDeltas,     DynOption (..),     dynOptionToLocatedStr,   ) where +import Control.Monad (when)+import Data.Aeson+  ( FromJSON (..),+    camelTo2,+    defaultOptions,+    fieldLabelModifier,+    genericParseJSON,+    rejectUnknownFields,+  )+import Data.List (stripPrefix)+import Data.Maybe (fromMaybe)+import Data.Yaml (decodeFileEither, prettyPrintParseException)+import GHC.Generics (Generic) import qualified SrcLoc as GHC+import System.Directory+  ( XdgDirectory (XdgConfig),+    findFile,+    getCurrentDirectory,+    getXdgDirectory,+    makeAbsolute,+  )+import System.FilePath ((</>), splitPath)+import System.IO (hPutStrLn, stderr)  -- | Ormolu configuration. data Config region = Config@@ -26,7 +53,8 @@     -- | Checks if re-formatting the result is idempotent     cfgCheckIdempotence :: !Bool,     -- | Region selection-    cfgRegion :: !region+    cfgRegion :: !region,+    cfgPrinterOpts :: PrinterOpts   }   deriving (Eq, Show, Functor) @@ -61,9 +89,20 @@         RegionIndices           { regionStartLine = Nothing,             regionEndLine = Nothing-          }+          },+      cfgPrinterOpts = defaultPrinterOpts     } +-- | Options controlling formatting output+data PrinterOpts = PrinterOpts+  { -- | Number of spaces to use for indentation+    poIndentStep :: Int+  }+  deriving (Eq, Show)++defaultPrinterOpts :: PrinterOpts+defaultPrinterOpts = PrinterOpts {poIndentStep = 4}+ -- | Convert 'RegionIndices' into 'RegionDeltas'. regionIndicesToDeltas ::   -- | Total number of lines in the input@@ -87,3 +126,55 @@ -- | Convert 'DynOption' to @'GHC.Located' 'String'@. dynOptionToLocatedStr :: DynOption -> GHC.Located String dynOptionToLocatedStr (DynOption o) = GHC.L GHC.noSrcSpan o++-- | A version of 'PrinterOpts' where any field can be empty.+-- This corresponds to the information in a config file.+data PrinterOptsPartial = PrinterOptsPartial+  { popIndentation :: Maybe Int+  }+  deriving (Eq, Show, Generic)++instance FromJSON PrinterOptsPartial where+  parseJSON =+    genericParseJSON+      defaultOptions+        { rejectUnknownFields = True,+          fieldLabelModifier = camelTo2 '_' . fromMaybe "" . stripPrefix "pop"+        }++-- | Replace fields with those from a config file, if found.+-- Looks recursively in parent folders, then in 'XdgConfig',+-- for a file matching /fourmolu.yaml/'.+loadConfigFile :: Bool -> Maybe FilePath -> PrinterOpts -> IO PrinterOpts+loadConfigFile debug maybePath PrinterOpts {..} = do+  root <- maybe getCurrentDirectory makeAbsolute maybePath+  xdg <- getXdgDirectory XdgConfig ""+  PrinterOptsPartial {..} <-+    optsFromFile debug $ reverse $ xdg : scanl1 (</>) (splitPath root)+  return $+    PrinterOpts+      { poIndentStep = fromMaybe poIndentStep popIndentation+      }++-- | Search the directories, in order, for a config file.+optsFromFile :: Bool -> [FilePath] -> IO PrinterOptsPartial+optsFromFile debug dirs =+  findFile dirs configFileName >>= \case+    Nothing -> do+      printDebug $+        "No " ++ show configFileName ++ " found in any of:\n"+          ++ unlines (map ("  " ++) dirs)+      return def+    Just file -> do+      printDebug $ "Found " ++ show file ++ ""+      decodeFileEither file >>= \case+        Left e -> do+          printDebug $ prettyPrintParseException e+          return def+        Right x -> return x+  where+    def = PrinterOptsPartial Nothing+    printDebug = when debug . hPutStrLn stderr++configFileName :: FilePath+configFileName = "fourmolu.yaml"
src/Ormolu/Printer.hs view
@@ -3,10 +3,12 @@ -- | Pretty-printer for Haskell AST. module Ormolu.Printer   ( printModule,+    PrinterOpts (..),   ) where  import Data.Text (Text)+import Ormolu.Config import Ormolu.Parser.Result import Ormolu.Printer.Combinators import Ormolu.Printer.Meat.Module@@ -17,9 +19,10 @@ printModule ::   -- | Result of parsing   ParseResult ->+  PrinterOpts ->   -- | Resulting rendition   Text-printModule ParseResult {..} =+printModule ParseResult {..} printerOpts =   prLiteralPrefix <> region <> prLiteralSuffix   where     region =@@ -35,4 +38,5 @@           (mkSpanStream prParsedSource)           prCommentStream           prAnns+          printerOpts           prUseRecordDot
src/Ormolu/Printer/Internal.hs view
@@ -63,6 +63,7 @@ import qualified Data.Text.Lazy as TL import Data.Text.Lazy.Builder import GHC+import Ormolu.Config import Ormolu.Parser.Anns import Ormolu.Parser.CommentStream import Ormolu.Printer.SpanStream@@ -92,7 +93,8 @@     -- | Whether the last expression in the layout can use braces     rcCanUseBraces :: Bool,     -- | Whether the source could have used the record dot preprocessor-    rcUseRecDot :: Bool+    rcUseRecDot :: Bool,+    rcPrinterOpts :: PrinterOpts   }  -- | State context of 'R'.@@ -158,11 +160,12 @@   CommentStream ->   -- | Annotations   Anns ->+  PrinterOpts ->   -- | Use Record Dot Syntax   Bool ->   -- | Resulting rendition   Text-runR (R m) sstream cstream anns recDot =+runR (R m) sstream cstream anns printerOpts recDot =   TL.toStrict . toLazyText . scBuilder $ execState (runReaderT m rc) sc   where     rc =@@ -172,7 +175,8 @@           rcEnclosingSpans = [],           rcAnns = anns,           rcCanUseBraces = False,-          rcUseRecDot = recDot+          rcUseRecDot = recDot,+          rcPrinterOpts = printerOpts         }     sc =       SC@@ -373,12 +377,13 @@ -- to be valid Haskell. When layout is single-line there is no obvious -- effect, but with multi-line layout correct indentation levels matter. inci :: R () -> R ()-inci (R m) = R (local modRC m)-  where-    modRC rc =-      rc-        { rcIndent = rcIndent rc + indentStep-        }+inci (R m) = do+  indentStep <- R (asks (poIndentStep . rcPrinterOpts))+  let modRC rc =+        rc+          { rcIndent = rcIndent rc + indentStep+          }+  R (local modRC m)  -- | Set indentation level for the inner computation equal to current -- column. This makes sure that the entire inner block is uniformly@@ -566,10 +571,3 @@ -- | Return 'True' if we can use braces in this context. canUseBraces :: R Bool canUseBraces = R (asks rcCanUseBraces)--------------------------------------------------------------------------------- Constants---- | Indentation step.-indentStep :: Int-indentStep = 4
src/Ormolu/Printer/Meat/Declaration/Value.hs view
@@ -2,6 +2,7 @@ {-# LANGUAGE OverloadedStrings #-} {-# LANGUAGE RecordWildCards #-} {-# LANGUAGE TypeApplications #-}+{-# LANGUAGE ViewPatterns #-}  module Ormolu.Printer.Meat.Declaration.Value   ( p_valDecl,@@ -1324,10 +1325,17 @@           inci p_y         else do           ub lhs-          placeHanging placement $ do-            p_op-            space-            p_y+          let opAndRhs = do+                p_op+                space+                p_y+          case x of+            -- This case prevents an operator from being indented past the start of a `do` block+            -- constituting its left operand, thus altering the AST.+            -- This is only relevant when the `do` block is on one line, as otherwise we will+            -- insert a newline after `do` anyway.+            OpNode (unLoc -> HsDo _ _ _) | isOneLineSpan (opTreeLoc x) -> breakpoint >> opAndRhs+            _ -> placeHanging placement opAndRhs  -- | Return 'True' if given expression is a record-dot operator expression. isRecordDot ::
src/Ormolu/Printer/Operators.hs view
@@ -12,8 +12,9 @@  import Data.Function (on) import qualified Data.List as L+import Data.Map.Strict (Map)+import qualified Data.Map.Strict as M import Data.Maybe (fromMaybe, mapMaybe)-import Data.Ord (Down (Down), comparing) import GHC import OccName (mkVarOcc) import Ormolu.Utils (unSrcSpan)@@ -56,7 +57,7 @@ reassociateOpTreeWith ::   forall ty op.   -- | Fixity map for operators-  [(RdrName, Fixity)] ->+  Map RdrName Fixity ->   -- | How to get the name of an operator   (op -> Maybe RdrName) ->   -- | Original 'OpTree'@@ -68,12 +69,12 @@     fixityOf :: op -> Fixity     fixityOf op = fromMaybe defaultFixity $ do       opName <- getOpName op-      lookup opName fixityMap+      M.lookup opName fixityMap     -- Here, left branch is already associated and the root alongside with     -- the right branch is right-associated. This function picks up one item     -- from the right and inserts it correctly to the left.     ---    -- Also, we are using the 'compareFixity' function which returns if the+    -- Also, we are using the 'compareFixity' function which tells if the     -- expression should associate to right.     go :: OpTree ty op -> OpTree ty op     -- base cases@@ -93,6 +94,16 @@         then go $ OpBranch (OpBranch l op (go $ OpBranch r op' l')) op'' r'         else go $ OpBranch (OpBranch (OpBranch l op r) op' l') op'' r' +-- | A score assigned to an operator.+data Score+  = -- | The operator was placed at the beginning of a line+    AtBeginning Int+  | -- | The operator was placed at the end of a line+    AtEnd+  | -- | The operator was placed in between arguments on a single line+    InBetween+  deriving (Eq, Ord)+ -- | Build a map of inferred 'Fixity's from an 'OpTree'. buildFixityMap ::   forall ty op.@@ -101,23 +112,26 @@   -- | Operator tree   OpTree (Located ty) (Located op) ->   -- | Fixity map-  [(RdrName, Fixity)]+  Map RdrName Fixity buildFixityMap getOpName opTree =-  concatMap (\(i, ns) -> map (\(n, _) -> (n, fixity i InfixL)) ns)-    . zip [0 ..]-    . L.groupBy (doubleWithinEps 0.00001 `on` snd)-    . (overrides ++)-    . modeScores+  addOverrides+    . M.fromList+    . concatMap (\(i, ns) -> map (\(n, _) -> (n, fixity i InfixL)) ns)+    . zip [1 ..]+    . L.groupBy ((==) `on` snd)+    . selectScores     $ score opTree   where-    -- Add a special case for ($), since it is pretty unlikely for someone-    -- to override it.-    overrides :: [(RdrName, Double)]-    overrides =-      [ (mkRdrUnqual $ mkVarOcc "$", -1)-      ]-    -- Assign scores to operators based on their location in the source.-    score :: OpTree (Located ty) (Located op) -> [(RdrName, Double)]+    addOverrides :: Map RdrName Fixity -> Map RdrName Fixity+    addOverrides m =+      let mk k v = (mkRdrUnqual (mkVarOcc k), fixity v InfixL)+       in M.fromList+            [ mk "$" 0,+              mk "." 9+            ]+            `M.union` m+    fixity = Fixity NoSourceText+    score :: OpTree (Located ty) (Located op) -> [(RdrName, Score)]     score (OpNode _) = []     score (OpBranch l o r) = fromMaybe (score r) $ do       -- If we fail to get any of these, 'defaultFixity' will be used by@@ -129,46 +143,25 @@       oc <- srcSpanStartCol <$> unSrcSpan (getLoc o) -- operator column       opName <- getOpName (unLoc o)       let s-            | le < ob =-              -- if the operator is in the beginning of a line, assign-              -- a score relative to its column within range [0, 1).-              fromIntegral oc / fromIntegral (maxCol + 1)-            | oe < rb =-              -- if the operator is in the end of the line, assign the-              -- score 1.-              1-            | otherwise =-              2 -- otherwise, assign a high score.+            | le < ob = AtBeginning oc+            | oe < rb = AtEnd+            | otherwise = InBetween       return $ (opName, s) : score r-    -- Pick the most common score per 'RdrName'.-    modeScores :: [(RdrName, Double)] -> [(RdrName, Double)]-    modeScores =+    selectScores :: [(RdrName, Score)] -> [(RdrName, Score)]+    selectScores =       L.sortOn snd         . mapMaybe           ( \case               [] -> Nothing-              xs@((n, _) : _) -> Just (n, mode $ map snd xs)+              xs@((n, _) : _) -> Just (n, selectScore $ map snd xs)           )         . L.groupBy ((==) `on` fst)         . L.sort-    -- Return the most common number, leaning to the smaller-    -- one in case of a tie.-    mode :: [Double] -> Double-    mode =-      head-        . L.minimumBy (comparing (Down . length))-        . L.groupBy (doubleWithinEps 0.0001)-        . L.sort-    -- The start column of the rightmost operator.-    maxCol = go opTree-      where-        go (OpNode (L _ _)) = 0-        go (OpBranch l (L o _) r) =-          maximum-            [ go l,-              maybe 0 srcSpanStartCol (unSrcSpan o),-              go r-            ]+    selectScore :: [Score] -> Score+    selectScore xs =+      case filter (/= InBetween) xs of+        [] -> InBetween+        xs' -> maximum xs'  ---------------------------------------------------------------------------- -- Helpers@@ -182,9 +175,3 @@   OpBranch (OpNode l) lop (normalizeOpTree r) normalizeOpTree (OpBranch (OpBranch l' lop' r') lop r) =   normalizeOpTree (OpBranch l' lop' (OpBranch r' lop r))--fixity :: Int -> FixityDirection -> Fixity-fixity = Fixity NoSourceText--doubleWithinEps :: Double -> Double -> Double -> Bool-doubleWithinEps eps a b = abs (a - b) < eps
tests/Ormolu/PrinterSpec.hs view
@@ -24,12 +24,13 @@ checkExample :: Path Rel File -> Spec checkExample srcPath' = it (fromRelFile srcPath' ++ " works") . withNiceExceptions $ do   let srcPath = examplesDir </> srcPath'+      cfg = defaultConfig {cfgPrinterOpts = PrinterOpts {poIndentStep = 2}}   expectedOutputPath <- deriveOutput srcPath   -- 1. Given input snippet of source code parse it and pretty print it.   -- 2. Parse the result of pretty-printing again and make sure that AST   -- is the same as AST of the original snippet. (This happens in   -- 'ormoluFile' automatically.)-  formatted0 <- ormoluFile defaultConfig (fromRelFile srcPath)+  formatted0 <- ormoluFile cfg (fromRelFile srcPath)   -- 3. Check the output against expected output. Thus all tests should   -- include two files: input and expected output.   -- T.writeFile (fromRelFile expectedOutputPath) formatted0@@ -37,7 +38,7 @@   shouldMatch False formatted0 expected   -- 4. Check that running the formatter on the output produces the same   -- output again (the transformation is idempotent).-  formatted1 <- ormolu defaultConfig "<formatted>" (T.unpack formatted0)+  formatted1 <- ormolu cfg "<formatted>" (T.unpack formatted0)   shouldMatch True formatted1 formatted0  -- | Build list of examples for testing.