@@ -5,31 +5,27 @@ import scala.collection.mutable
55
66object DiffUtil {
77
8- private final val ANSI_DEFAULT = " \u001B [0m"
9- private final val ANSI_RED = " \u001B [31m"
10- private final val ANSI_GREEN = " \u001B [32m"
11- private final val ANSI_EOF = " \u001B [2m"
12-
13- private final val DELETION_COLOR = ANSI_RED
14- private final val ADDITION_COLOR = ANSI_GREEN
15-
168 val EOF = new String (" EOF" ) // Unique string up to reference
179
1810 @ tailrec private def splitTokens (str : String , acc : List [String ] = Nil ): List [String ] = {
1911 if (str == " " ) {
2012 acc.reverse
2113 } else {
2214 val head = str.charAt(0 )
23- val (token, rest) = if (Character .isAlphabetic(head) || Character .isDigit(head)) {
24- str.span(c => Character .isAlphabetic(c) || Character .isDigit(c))
25- } else if (Character .isMirrored(head) || Character .isWhitespace(head)) {
26- str.splitAt(1 )
27- } else {
28- str.span { c =>
29- ! Character .isAlphabetic(c) && ! Character .isDigit(c) &&
30- ! Character .isMirrored(c) && ! Character .isWhitespace(c)
15+ val (token, rest) =
16+ if (head == '\u001b ' ) { // ansi color token
17+ val splitIndex = str.indexOf('m' ) + 1
18+ (str.substring(0 , splitIndex), str.substring(splitIndex))
19+ } else if (Character .isAlphabetic(head) || Character .isDigit(head)) {
20+ str.span(c => Character .isAlphabetic(c) || Character .isDigit(c) && c != '\u001b ' )
21+ } else if (Character .isMirrored(head) || Character .isWhitespace(head)) {
22+ str.splitAt(1 )
23+ } else {
24+ str.span { c =>
25+ ! Character .isAlphabetic(c) && ! Character .isDigit(c) &&
26+ ! Character .isMirrored(c) && ! Character .isWhitespace(c) && c != '\u001b '
27+ }
3128 }
32- }
3329 splitTokens(rest, token :: acc)
3430 }
3531 }
@@ -48,14 +44,14 @@ object DiffUtil {
4844 case Unmodified (str) => str
4945 case Inserted (str) =>
5046 totalChange += str.length
51- ADDITION_COLOR + str + ANSI_DEFAULT
47+ added( str)
5248 }.mkString
5349
5450 val fnd = diffAct.collect {
5551 case Unmodified (str) => str
5652 case Inserted (str) =>
5753 totalChange += str.length
58- DELETION_COLOR + str + ANSI_DEFAULT
54+ deleted( str)
5955 }.mkString
6056
6157 (fnd, exp, totalChange.toDouble / (expected.length + found.length))
@@ -69,25 +65,21 @@ object DiffUtil {
6965 }
7066
7167 val expectedDiff =
72- if (expected eq EOF ) ANSI_EOF + expected + ANSI_DEFAULT
68+ if (expected eq EOF ) eof()
7369 else diff.collect {
7470 case Unmodified (str) => str
75- case Inserted (str) =>
76- ADDITION_COLOR + str + ANSI_DEFAULT
77- case Modified (_, str) =>
78- ADDITION_COLOR + str + ANSI_DEFAULT
71+ case Inserted (str) => added(str)
72+ case Modified (_, str) => added(str)
7973 case Deleted (_) => " "
8074 }.mkString
8175
8276 val actualDiff =
83- if (actual eq EOF ) ANSI_EOF + actual + ANSI_DEFAULT
77+ if (actual eq EOF ) eof()
8478 else diff.collect {
8579 case Unmodified (str) => str
8680 case Inserted (_) => " "
87- case Modified (str, _) =>
88- DELETION_COLOR + str + ANSI_DEFAULT
89- case Deleted (str) =>
90- DELETION_COLOR + str + ANSI_DEFAULT
81+ case Modified (str, _) => deleted(str)
82+ case Deleted (str) => deleted(str)
9183 }.mkString
9284
9385 val pad = " " * 0 .max(expectedSize - expected.length)
@@ -103,13 +95,27 @@ object DiffUtil {
10395
10496 diff.collect {
10597 case Unmodified (str) => str
106- case Inserted (str) => ADDITION_COLOR + str + ANSI_DEFAULT
107- case Modified (old, str) if printDiffDel => DELETION_COLOR + old + ADDITION_COLOR + str + ANSI_DEFAULT
108- case Modified (_, str) => ADDITION_COLOR + str + ANSI_DEFAULT
109- case Deleted (str) if printDiffDel => DELETION_COLOR + str + ANSI_DEFAULT
98+ case Inserted (str) => added( str)
99+ case Modified (old, str) if printDiffDel => deleted( str) + added(str)
100+ case Modified (_, str) => added( str)
101+ case Deleted (str) if printDiffDel => deleted( str)
110102 }.mkString
111103 }
112104
105+ private def added (str : String ): String = bgColored(str, Console .GREEN_B )
106+ private def deleted (str : String ) = bgColored(str, Console .RED_B )
107+ private def bgColored (str : String , color : String ): String = {
108+ if (str.isEmpty) " "
109+ else {
110+ val (spaces, rest) = str.span(_ == '\n ' )
111+ if (spaces.isEmpty) {
112+ val (text, rest2) = str.span(_ != '\n ' )
113+ color + text + Console .RESET + bgColored(rest2, color)
114+ } else spaces + bgColored(rest, color)
115+ }
116+ }
117+ private def eof () = " \u001B [51m" + " EOF" + Console .RESET
118+
113119 private sealed trait Patch
114120 private final case class Unmodified (str : String ) extends Patch
115121 private final case class Modified (original : String , str : String ) extends Patch
0 commit comments