2015-11-27 20:49:46 +03:00
|
|
|
module Unified (unified, substring) where
|
2015-11-20 01:36:32 +03:00
|
|
|
|
|
|
|
import Diff
|
2015-11-20 01:37:07 +03:00
|
|
|
import Patch
|
|
|
|
import Syntax
|
|
|
|
import Term
|
2015-11-20 02:53:23 +03:00
|
|
|
import Control.Arrow
|
2015-11-20 01:37:07 +03:00
|
|
|
import Control.Monad.Free
|
2015-11-20 02:53:23 +03:00
|
|
|
import Control.Comonad.Cofree
|
2015-11-20 04:23:06 +03:00
|
|
|
import Data.List hiding (foldl)
|
2015-11-20 04:22:55 +03:00
|
|
|
import qualified Data.Map as Map
|
2015-11-27 18:36:59 +03:00
|
|
|
import Rainbow
|
2015-11-20 01:36:32 +03:00
|
|
|
|
2015-11-27 19:31:03 +03:00
|
|
|
unified :: Diff a Info -> String -> String -> IO ByteString
|
|
|
|
unified diff before after = do
|
|
|
|
renderer <- byteStringMakerFromEnvironment
|
2015-11-27 22:28:06 +03:00
|
|
|
return . mconcat . chunksToByteStrings renderer . fst $ iter g mapped where
|
2015-11-20 02:53:23 +03:00
|
|
|
mapped = fmap (unifiedPatch &&& range) diff
|
2015-12-01 02:50:08 +03:00
|
|
|
g (Annotated (_, info) syntax) = annotationAndSyntaxToChunks after info syntax
|
2015-12-01 22:51:21 +03:00
|
|
|
annotationAndSyntaxToChunks source (Info range _ _) (Leaf _) = (pure . chunk $ substring range source, Just range)
|
|
|
|
annotationAndSyntaxToChunks source (Info range _ _) (Indexed i) = (unifiedRange range i source, Just range)
|
|
|
|
annotationAndSyntaxToChunks source (Info range _ _) (Fixed f) = (unifiedRange range f source, Just range)
|
|
|
|
annotationAndSyntaxToChunks source (Info range _ _) (Keyed k) = (unifiedRange range (sort $ snd <$> Map.toList k) source, Just range)
|
2015-11-20 02:53:23 +03:00
|
|
|
|
2015-11-27 22:28:06 +03:00
|
|
|
unifiedPatch :: Patch (Term a Info) -> [Chunk String]
|
|
|
|
unifiedPatch patch = (fore red . bold <$> beforeChunk) <> (fore green . bold <$> afterChunk) where
|
|
|
|
beforeChunk = maybe [] (change "-" . unifiedTerm before) $ Patch.before patch
|
|
|
|
afterChunk = maybe [] (change "+" . unifiedTerm after) $ Patch.after patch
|
2015-11-20 19:06:44 +03:00
|
|
|
|
2015-11-27 22:28:06 +03:00
|
|
|
unifiedTerm :: String -> Term a Info -> [Chunk String]
|
2015-12-01 02:50:08 +03:00
|
|
|
unifiedTerm source term = fst $ cata (annotationAndSyntaxToChunks source) term
|
2015-11-20 03:27:31 +03:00
|
|
|
|
2015-11-27 22:28:06 +03:00
|
|
|
unifiedRange :: Range -> [([Chunk String], Maybe Range)] -> String -> [Chunk String]
|
2015-12-01 18:24:36 +03:00
|
|
|
unifiedRange range children source = out <> (pure . chunk $ substring Range { start = previous, end = end range } source) where
|
2015-11-27 22:28:06 +03:00
|
|
|
(out, previous) = foldl accumulateContext ([], start range) children
|
|
|
|
accumulateContext (out, previous) (child, Just range) = (mconcat [ out, pure . chunk $ substring Range { start = previous, end = start range } source, child ], end range)
|
2015-11-27 19:32:31 +03:00
|
|
|
accumulateContext (out, previous) (child, _) = (out <> child, previous)
|
2015-11-20 02:05:33 +03:00
|
|
|
|
2015-11-27 20:49:40 +03:00
|
|
|
substring :: Range -> String -> String
|
2015-11-27 20:50:08 +03:00
|
|
|
substring range = take (end range - start range) . drop (start range)
|
2015-11-20 02:30:37 +03:00
|
|
|
|
|
|
|
range :: Patch (Term a Info) -> Maybe Range
|
|
|
|
range patch = range . extract <$> after patch where
|
|
|
|
extract (annotation :< _) = annotation
|
2015-12-01 22:51:21 +03:00
|
|
|
range (Info range _ _) = range
|
2015-11-20 03:07:30 +03:00
|
|
|
|
2015-11-27 22:28:06 +03:00
|
|
|
change :: String -> [Chunk String] -> [Chunk String]
|
|
|
|
change bound content = [ chunk "{", chunk bound ] ++ content ++ [ chunk bound, chunk "}" ]
|
2015-11-20 04:36:38 +03:00
|
|
|
|
2015-11-20 03:23:18 +03:00
|
|
|
instance Ord Range where
|
|
|
|
a <= b = start a <= start b
|