From a97c7ab0792efee192a11d693cef69801c0fb280 Mon Sep 17 00:00:00 2001 From: Javier Sagredo Date: Thu, 1 Jun 2023 15:44:05 +0200 Subject: [PATCH] Use prettyprinter instead of ansi-wl-pprint --- src/Data/TreeDiff/Class.hs | 4 +- src/Data/TreeDiff/Golden.hs | 23 +++++--- src/Data/TreeDiff/List.hs | 4 +- src/Data/TreeDiff/OMap.hs | 10 ++-- src/Data/TreeDiff/Pretty.hs | 96 +++++++++++++++++---------------- src/Data/TreeDiff/QuickCheck.hs | 2 +- tests/Tests.hs | 20 +++---- tree-diff.cabal | 38 ++++++------- 8 files changed, 104 insertions(+), 93 deletions(-) diff --git a/src/Data/TreeDiff/Class.hs b/src/Data/TreeDiff/Class.hs index c22010b..95c1eb4 100644 --- a/src/Data/TreeDiff/Class.hs +++ b/src/Data/TreeDiff/Class.hs @@ -109,7 +109,7 @@ import Data.These (These (..)) -- primitive import qualified Data.Primitive as Prim -#if MIN_VERSION_base(4,9,0) +#if MIN_VERSION_base(4,17,0) import Data.Array.Byte (ByteArray (..)) #endif @@ -602,7 +602,7 @@ instance (ToExpr a, ToExpr b) => ToExpr (These a b) where instance ToExpr Prim.ByteArray where toExpr ba = App "Prim.byteArrayFromList" [toExpr (Prim.foldrByteArray (:) [] ba :: [Word8])] -#if !MIN_VERSION_primitive(0,8,0) && MIN_VERSION_base(4,9,0) +#if !MIN_VERSION_primitive(0,8,0) && MIN_VERSION_base(4,17,0) -- | @since 0.2.2 instance ToExpr ByteArray where toExpr (ByteArray ba) = App "byteArrayFromList" [toExpr (Prim.foldrByteArray (:) [] (Prim.ByteArray ba) :: [Word8])] diff --git a/src/Data/TreeDiff/Golden.hs b/src/Data/TreeDiff/Golden.hs index 52aa1f8..e050c2d 100644 --- a/src/Data/TreeDiff/Golden.hs +++ b/src/Data/TreeDiff/Golden.hs @@ -10,10 +10,12 @@ import System.Console.ANSI (SGR (Reset), setSGRCode) import Text.Parsec (eof, parse) import Text.Parsec.Text () -import qualified Data.ByteString as BS -import qualified Data.Text as T -import qualified Data.Text.Encoding as TE -import qualified Text.PrettyPrint.ANSI.Leijen as WL +import qualified Data.ByteString as BS +import qualified Data.Text as T +import qualified Data.Text.Encoding as TE +import qualified Data.Text.Lazy as TL +import qualified Prettyprinter as PP +import qualified Prettyprinter.Render.Terminal as PP -- | Make a golden tests. -- @@ -54,8 +56,13 @@ ediffGolden impl testName fp x = impl testName expect actual cmp wrt cmp a b | a == b = return Nothing | otherwise = return $ Just $ - setSGRCode [Reset] ++ showWL (ansiWlEditExprCompact $ ediff a b) - wrt expr = BS.writeFile fp $ TE.encodeUtf8 $ T.pack $ showWL (WL.plain (ansiWlExpr expr)) ++ "\n" + setSGRCode [Reset] ++ showPP (ansiEditExprCompact $ ediff a b) + wrt expr = BS.writeFile fp $ TE.encodeUtf8 $ T.pack $ showPP (PP.unAnnotate (ansiExpr expr)) ++ "\n" -showWL :: WL.Doc -> String -showWL doc = WL.displayS (WL.renderSmart 0.4 80 doc) "" +showPP :: PP.Doc PP.AnsiStyle -> String +showPP doc = TL.unpack + $ PP.renderLazy + $ PP.layoutSmart + PP.LayoutOptions + { PP.layoutPageWidth = PP.AvailablePerLine 80 (realToFrac (0.4 :: Float)) } + doc diff --git a/src/Data/TreeDiff/List.hs b/src/Data/TreeDiff/List.hs index 29ea48b..a0cc5ca 100644 --- a/src/Data/TreeDiff/List.hs +++ b/src/Data/TreeDiff/List.hs @@ -1,4 +1,4 @@ -{-# LANGUAGE BangPatterns #-} +{-# LANGUAGE BangPatterns #-} {-# LANGUAGE ScopedTypeVariables #-} -- | A list diff. module Data.TreeDiff.List ( @@ -6,7 +6,7 @@ module Data.TreeDiff.List ( Edit (..), ) where -import Control.DeepSeq (NFData (..)) +import Control.DeepSeq (NFData (..)) import Control.Monad.ST (ST, runST) import qualified Data.Primitive as P diff --git a/src/Data/TreeDiff/OMap.hs b/src/Data/TreeDiff/OMap.hs index 206b5e1..8f2a8fa 100644 --- a/src/Data/TreeDiff/OMap.hs +++ b/src/Data/TreeDiff/OMap.hs @@ -15,11 +15,11 @@ module Data.TreeDiff.OMap ( elems, ) where -import Data.List (sortBy) -import Data.Ord (comparing) -import Data.Semialign (Semialign (..)) -import Data.These (These (..)) -import Control.DeepSeq (NFData (..)) +import Control.DeepSeq (NFData (..)) +import Data.List (sortBy) +import Data.Ord (comparing) +import Data.Semialign (Semialign (..)) +import Data.These (These (..)) #if MIN_VERSION_containers(0,5,0) import qualified Data.Map.Strict as Map diff --git a/src/Data/TreeDiff/Pretty.hs b/src/Data/TreeDiff/Pretty.hs index ece312f..c9ab4d9 100644 --- a/src/Data/TreeDiff/Pretty.hs +++ b/src/Data/TreeDiff/Pretty.hs @@ -11,15 +11,15 @@ module Data.TreeDiff.Pretty ( prettyEditExpr, prettyEditExprCompact, -- * ansi-wl-pprint - ansiWlPretty, - ansiWlExpr, - ansiWlEditExpr, - ansiWlEditExprCompact, + ansiPretty, + ansiExpr, + ansiEditExpr, + ansiEditExprCompact, -- ** background - ansiWlBgPretty, - ansiWlBgExpr, - ansiWlBgEditExpr, - ansiWlBgEditExprCompact, + ansiBgPretty, + ansiBgExpr, + ansiBgEditExpr, + ansiBgEditExprCompact, -- * Utilities escapeName, ) where @@ -30,9 +30,11 @@ import Data.TreeDiff.Expr import Numeric (showHex) import Text.Read.Compat (readMaybe) -import qualified Data.TreeDiff.OMap as OMap -import qualified Text.PrettyPrint as HJ -import qualified Text.PrettyPrint.ANSI.Leijen as WL +import qualified Data.TreeDiff.OMap as OMap +import qualified Text.PrettyPrint as HJ + +import qualified Prettyprinter as PP +import qualified Prettyprinter.Render.Terminal as PP -- $setup -- >>> import qualified Data.TreeDiff.OMap as OMap @@ -212,59 +214,59 @@ prettyEditExprCompact :: Edit EditExpr -> HJ.Doc prettyEditExprCompact = ppEditExprCompact prettyPretty ------------------------------------------------------------------------------- --- ansi-wl-pprint +-- ansi printing via 'prettyprinter' ------------------------------------------------------------------------------- --- | 'Pretty' via @ansi-wl-pprint@ library (with colors). -ansiWlPretty :: Pretty WL.Doc -ansiWlPretty = Pretty - { ppCon = WL.text - , ppRec = \c xs -> ansiGroup (c WL.<+> WL.lbrace) WL.rbrace - $ map (\(fn, d) -> WL.text fn WL.<+> WL.equals WL. d) xs - , ppLst = ansiGroup WL.lbracket WL.rbracket - , ppCpy = WL.dullwhite - , ppIns = \d -> WL.green $ WL.plain $ WL.char '+' WL.<> d - , ppDel = \d -> WL.red $ WL.plain $ WL.char '-' WL.<> d - , ppApp = \f xs -> WL.group $ WL.nest 2 $ f WL.<$> WL.vsep xs - , ppEdits = WL.sep - , ppEllip = WL.text "..." - , ppParens = WL.parens +ansiPretty :: Pretty (PP.Doc PP.AnsiStyle) +ansiPretty = Pretty + { ppCon = PP.pretty + , ppRec = \c xs -> ansiGroup (c PP.<+> PP.lbrace) PP.rbrace + $ map (\(fn, d) -> PP.pretty fn PP.<+> PP.equals <> PP.softline <> d) xs + , ppLst = ansiGroup PP.lbracket PP.rbracket + , ppCpy = PP.annotate (PP.colorDull PP.White) + , ppIns = \d -> PP.annotate (PP.color PP.Green) $ PP.unAnnotate $ PP.pretty '+' <> d + , ppDel = \d -> PP.annotate (PP.color PP.Red) $ PP.unAnnotate $ PP.pretty '-' <> d + , ppApp = \f xs -> PP.group $ PP.nest 2 $ f <> PP.line <> PP.vsep xs + , ppEdits = PP.sep + , ppEllip = PP.pretty "..." + , ppParens = PP.parens } -ansiGroup :: WL.Doc -> WL.Doc -> [WL.Doc] -> WL.Doc -ansiGroup l r xs = WL.group $ WL.nest 2 (l WL.<$$> WL.vsep (WL.punctuate WL.comma xs) WL.<> r) + +ansiGroup :: PP.Doc PP.AnsiStyle -> PP.Doc PP.AnsiStyle -> [PP.Doc PP.AnsiStyle] -> PP.Doc PP.AnsiStyle +ansiGroup l r xs = PP.group $ PP.nest 2 (l <> PP.flatAlt PP.line mempty <> PP.vsep (PP.punctuate PP.comma xs) <> r) -- | Pretty print 'Expr' using @ansi-wl-pprint@. -ansiWlExpr :: Expr -> WL.Doc -ansiWlExpr = ppExpr ansiWlPretty +ansiExpr :: Expr -> PP.Doc PP.AnsiStyle +ansiExpr = ppExpr ansiPretty -- | Pretty print @'Edit' 'EditExpr'@ using @ansi-wl-pprint@. -ansiWlEditExpr :: Edit EditExpr -> WL.Doc -ansiWlEditExpr = ppEditExpr ansiWlPretty +ansiEditExpr :: Edit EditExpr -> PP.Doc PP.AnsiStyle +ansiEditExpr = ppEditExpr ansiPretty --- | Compact 'ansiWlEditExpr' -ansiWlEditExprCompact :: Edit EditExpr -> WL.Doc -ansiWlEditExprCompact = ppEditExprCompact ansiWlPretty +-- | Compact 'ansiEditExpr' +ansiEditExprCompact :: Edit EditExpr -> PP.Doc PP.AnsiStyle +ansiEditExprCompact = ppEditExprCompact ansiPretty ------------------------------------------------------------------------------- -- Background ------------------------------------------------------------------------------- --- | Like 'ansiWlPretty' but color the background. -ansiWlBgPretty :: Pretty WL.Doc -ansiWlBgPretty = ansiWlPretty - { ppIns = \d -> WL.ondullgreen $ WL.white $ WL.plain $ WL.char '+' WL.<> d - , ppDel = \d -> WL.ondullred $ WL.white $ WL.plain $ WL.char '-' WL.<> d +-- | Like 'ansiPretty' but color the background. +ansiBgPretty :: Pretty (PP.Doc PP.AnsiStyle) +ansiBgPretty = ansiPretty + { ppIns = \d -> PP.annotate (PP.colorDull PP.Green) $ PP.annotate (PP.color PP.White) $ PP.unAnnotate $ PP.pretty '+' <> d + , ppDel = \d -> PP.annotate (PP.colorDull PP.Red) $ PP.annotate (PP.color PP.White) $ PP.unAnnotate $ PP.pretty '-' <> d } -- | Pretty print 'Expr' using @ansi-wl-pprint@. -ansiWlBgExpr :: Expr -> WL.Doc -ansiWlBgExpr = ppExpr ansiWlBgPretty +ansiBgExpr :: Expr -> PP.Doc PP.AnsiStyle +ansiBgExpr = ppExpr ansiBgPretty -- | Pretty print @'Edit' 'EditExpr'@ using @ansi-wl-pprint@. -ansiWlBgEditExpr :: Edit EditExpr -> WL.Doc -ansiWlBgEditExpr = ppEditExpr ansiWlBgPretty +ansiBgEditExpr :: Edit EditExpr -> PP.Doc PP.AnsiStyle +ansiBgEditExpr = ppEditExpr ansiBgPretty --- | Compact 'ansiWlBgEditExpr'. -ansiWlBgEditExprCompact :: Edit EditExpr -> WL.Doc -ansiWlBgEditExprCompact = ppEditExprCompact ansiWlBgPretty +-- | Compact 'ansiBgEditExpr'. +ansiBgEditExprCompact :: Edit EditExpr -> PP.Doc PP.AnsiStyle +ansiBgEditExprCompact = ppEditExprCompact ansiBgPretty diff --git a/src/Data/TreeDiff/QuickCheck.hs b/src/Data/TreeDiff/QuickCheck.hs index 205dc8f..c1a8d95 100644 --- a/src/Data/TreeDiff/QuickCheck.hs +++ b/src/Data/TreeDiff/QuickCheck.hs @@ -10,5 +10,5 @@ import Test.QuickCheck (Property, counterexample) -- | A variant of '===', which outputs a diff when values are inequal. ediffEq :: (Eq a, ToExpr a) => a -> a -> Property ediffEq x y = counterexample - (setSGRCode [Reset] ++ show (ansiWlEditExpr $ ediff x y)) + (setSGRCode [Reset] ++ show (ansiEditExpr $ ediff x y)) (x == y) diff --git a/tests/Tests.hs b/tests/Tests.hs index 813388d..a571719 100644 --- a/tests/Tests.hs +++ b/tests/Tests.hs @@ -16,12 +16,12 @@ import Test.Tasty.QuickCheck (testProperty) import Data.Array.Byte (ByteArray (..)) #endif -import qualified Data.HashSet as HS -import qualified Data.Primitive as Prim -import qualified Text.Parsec as P -import qualified Text.PrettyPrint.ANSI.Leijen as WL -import qualified Text.Trifecta as T (eof, parseString) -import qualified Text.Trifecta.Result as T (ErrInfo (..), Result (..)) +import qualified Data.HashSet as HS +import qualified Data.Primitive as Prim +import qualified Prettyprinter as PP +import qualified Text.Parsec as P +import qualified Text.Trifecta as T (eof, parseString) +import qualified Text.Trifecta.Result as T (ErrInfo (..), Result (..)) import Data.TreeDiff import Data.TreeDiff.Golden @@ -33,7 +33,7 @@ import qualified RefDiffBy main :: IO () main = defaultMain $ testGroup "tests" [ testProperty "trifecta-pretty roundtrip" roundtripTrifectaPretty - , testProperty "parsec-ansi-wl-pprint roundtrip" roundtripParsecAnsiWl + , testProperty "parsec-ansi-wl-pprint roundtrip" roundtripParsecAnsi , testProperty "diffBy example1" $ diffByModel [7,1,6,0,0] [0,0,6,7,1,0,0] , testProperty "diffBy model" diffByModel , goldenTests @@ -76,10 +76,10 @@ roundtripTrifectaPretty e = counterexample info $ ediffEq (Just e) res' T.Success e' -> Just e' T.Failure _ -> Nothing -roundtripParsecAnsiWl :: Expr -> Property -roundtripParsecAnsiWl e = counterexample info $ ediffEq (Just e) res' +roundtripParsecAnsi :: Expr -> Property +roundtripParsecAnsi e = counterexample info $ ediffEq (Just e) res' where - doc = show (WL.plain (ansiWlExpr e)) + doc = show (PP.unAnnotate (ansiExpr e)) res = P.parse (exprParser <* P.eof) "" doc info = case res of diff --git a/tree-diff.cabal b/tree-diff.cabal index 8320bb5..d6ca5a9 100644 --- a/tree-diff.cabal +++ b/tree-diff.cabal @@ -97,23 +97,24 @@ library , time >=1.4 && <1.5 || >=1.5.0.1 && <1.6 || >=1.6.0.1 && <1.7 || >=1.8.0.2 && <1.9 || >=1.9.3 && <1.13 build-depends: - , aeson ^>=1.4.6.0 || ^>=1.5.6.0 || ^>=2.0.0.0 || ^>=2.1.0.0 - , ansi-terminal >=0.10 && <0.12 || ^>=1.0 - , ansi-wl-pprint ^>=0.6.8.2 || ^>=1.0.2 - , base-compat >=0 && <0.13 || ^>=0.13 - , bytestring-builder ^>=0.10.8.2.0 - , hashable ^>=1.2.7.0 || ^>=1.3.0.0 || ^>=1.4.0.1 - , parsers ^>=0.12.10 - , primitive >=0.7.1.0 && <0.8 || ^>=0.8 - , QuickCheck ^>=2.14.2 - , scientific ^>=0.3.6.2 - , semialign >=1.2.0.1 && <1.3 || ^>=1.3 - , strict >=0.4.0.1 && <0.5 || ^>=0.5 - , tagged ^>=0.8.6 - , these >=1.1.1.1 && <1.2 || ^>=1.2 - , unordered-containers ^>=0.2.8.0 - , uuid-types ^>=1.0.3 - , vector ^>=0.12.0.0 || ^>=0.13.0.0 + , aeson ^>=1.4.6.0 || ^>=1.5.6.0 || ^>=2.0.0.0 || ^>=2.1.0.0 + , ansi-terminal >=0.10 && <0.12 || ^>=1.0 + , base-compat >=0 && <0.13 || ^>=0.13 + , bytestring-builder ^>=0.10.8.2.0 + , hashable ^>=1.2.7.0 || ^>=1.3.0.0 || ^>=1.4.0.1 + , parsers ^>=0.12.10 + , prettyprinter ^>=1.7.1 + , prettyprinter-ansi-terminal ^>=1.1.3 + , primitive >=0.7.1.0 && <0.8 || ^>=0.8 + , QuickCheck ^>=2.14.2 + , scientific ^>=0.3.6.2 + , semialign >=1.2.0.1 && <1.3 || ^>=1.3 + , strict >=0.4.0.1 && <0.5 || ^>=0.5 + , tagged ^>=0.8.6 + , these >=1.1.1.1 && <1.2 || ^>=1.2 + , unordered-containers ^>=0.2.8.0 + , uuid-types ^>=1.0.3 + , vector ^>=0.12.0.0 || ^>=0.13.0.0 if impl(ghc <7.5) build-depends: ghc-prim @@ -157,10 +158,11 @@ test-suite tree-diff-test -- dependencies from library build-depends: , ansi-terminal - , ansi-wl-pprint , base , base-compat , parsec + , prettyprinter + , prettyprinter-ansi-terminal , primitive , QuickCheck , tagged