Commit c69e5c90 authored by Camil Staps's avatar Camil Staps 🐧

Implement Changed DiffStatus; pretty diffToConsole output

parent 3e8125e3
Pipeline #9548 passed with stage
in 1 minute and 53 seconds
......@@ -11,10 +11,14 @@ import StdGeneric
, children :: ![Diff] //* Diffs on the childrens of this node.
}
/**
* The status of a node head in a {{`Diff`}}.
*/
:: DiffStatus
= Common
| Added
| Removed
= Common //* The complete node is common to both values
| Changed //* The node head is common, but there are diffs in the children
| Added //* The node is added
| Removed //* The node is removed
/**
* Compute the {{`Diff`}} between two values.
......@@ -26,4 +30,4 @@ derive gDiff []
/**
* A String representation of a {{`Diff`}} using ANSI escape codes.
*/
diffToConsole :: ([Diff] -> String)
diffToConsole :: [Diff] -> String
implementation module Data.Generics.GenDiff
import StdBool
from StdFunc import o
from StdFunc import flip, o
import StdGeneric
import StdInt
import StdList
import StdString
import Control.Applicative
import Control.Monad
import Control.Monad.Identity
import Control.Monad.State
import Data.List
import Data.Maybe
from Text import class Text(concat), instance Text String
......@@ -23,7 +27,11 @@ gDiff{|Int|} x y
gDiff{|UNIT|} UNIT UNIT = []
gDiff{|PAIR|} fx fy (PAIR x1 y1) (PAIR x2 y2) = fx x1 x2 ++ fy y1 y2
gDiff{|OBJECT|} fx (OBJECT x) (OBJECT y) = fx x y
gDiff{|CONS of d|} fx (CONS x) (CONS y) = [{status=Common, value=d.gcd_name, children=fx x y}]
gDiff{|CONS of d|} fx (CONS x) (CONS y) =
[{ status = if (all (\d -> d.status=:Common) children) Common Changed
, value = d.gcd_name
, children = children
}] where children = fx x y
gDiff{|EITHER|} fl fr (LEFT x) (LEFT y) = fl x y
gDiff{|EITHER|} fl fr (RIGHT x) (RIGHT y) = fr x y
gDiff{|EITHER|} fl fr (LEFT x) (RIGHT y) = map (setStatus Removed) (fl x x) ++ map (setStatus Added) (fr y y)
......@@ -31,23 +39,60 @@ gDiff{|EITHER|} fl fr (RIGHT x) (LEFT y) = map (setStatus Removed) (fr x x) ++
derive gDiff []
diffToConsole :: ([Diff] -> String)
diffToConsole = concat o intersperse " " o map (display False)
:: PrState =
{ indent :: !Int
, output :: ![String]
}
print :: a -> State PrState () | toString a
print s = modify \st -> {st & output=[toString s:st.output]}
newline :: DiffStatus -> State PrState ()
newline ds =
gets (\s -> s.indent) >>=
print o flip repeatn '\t' >>|
print head >>|
print "\n"
where
display :: Bool Diff -> String
head = case ds of
Common -> ""
Changed -> "\033[0;33m~"
Added -> "\033[0;32m+"
Removed -> "\033[0;31m-"
indent :: DiffStatus (State PrState a) -> State PrState ()
indent ds st =
modify (\st -> {st & indent=st.indent+1}) >>|
st >>|
newline ds >>|
modify (\st -> {st & indent=st.indent-1})
diffToConsole :: [Diff] -> String
diffToConsole ds = concat (dropWhile isSpace (execState (display False diff) {indent= -1,output=[]}).output)
where
diff = {status=Common, value="", children=ds}
display :: Bool Diff -> State PrState ()
display p d =
color +++
if p` "(" "" +++
d.value +++
reset +++
concat (map ((+++) " " o display True) d.children) +++
color +++
if p` ")" "" +++
reset
print reset >>|
if p` (print ")" >>| newline d.status) (pure ()) >>|
print color >>|
sequence [indent c.status (display True c) \\ c <- reverse d.children] >>|
print reset >>|
print d.value >>|
print (if p` "(" "") >>|
print color
where
color = case d.status of
Common -> reset
Changed -> "\033[0;33m"
Added -> "\033[0;32m"
Removed -> "\033[0;31m"
reset = "\033[0m"
p` = p && not (isEmpty d.children)
isSpace :: String -> Bool
isSpace "\033[0m" = True
isSpace "\n" = True
isSpace "" = True
isSpace _ = False
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment