aboutsummaryrefslogtreecommitdiff
path: root/src/dotty/tools/dotc/repl/SyntaxHighlighter.scala
diff options
context:
space:
mode:
authorFelix Mulder <felix.mulder@gmail.com>2016-04-27 12:00:29 +0200
committerFelix Mulder <felix.mulder@gmail.com>2016-04-28 11:00:39 +0200
commitd04984596c6abfa27b217b12a42caca26f0c269f (patch)
tree5657a2a1da905954fbab71f49a9cb477f7a690e7 /src/dotty/tools/dotc/repl/SyntaxHighlighter.scala
parent96cedcdcd82148f091989836eb4959b2c3ec3382 (diff)
downloaddotty-d04984596c6abfa27b217b12a42caca26f0c269f.tar.gz
dotty-d04984596c6abfa27b217b12a42caca26f0c269f.tar.bz2
dotty-d04984596c6abfa27b217b12a42caca26f0c269f.zip
Add multiline support using ammonite multilineFilter
Diffstat (limited to 'src/dotty/tools/dotc/repl/SyntaxHighlighter.scala')
-rw-r--r--src/dotty/tools/dotc/repl/SyntaxHighlighter.scala116
1 files changed, 55 insertions, 61 deletions
diff --git a/src/dotty/tools/dotc/repl/SyntaxHighlighter.scala b/src/dotty/tools/dotc/repl/SyntaxHighlighter.scala
index 1988ea7ad..edb0ba040 100644
--- a/src/dotty/tools/dotc/repl/SyntaxHighlighter.scala
+++ b/src/dotty/tools/dotc/repl/SyntaxHighlighter.scala
@@ -40,9 +40,9 @@ object SyntaxHighlighting {
private val typeEnders =
'{' :: '}' :: ')' :: '(' :: '=' :: ' ' :: ',' :: '.' :: Nil
- def apply(buffer: Iterable[Char]): Vector[Char] = {
+ def apply(chars: Iterable[Char]): Vector[Char] = {
var prev: Char = 0
- var iter = buffer.toIterator
+ var remaining = chars.toStream
val newBuf = new StringBuilder
@inline def keywordStart =
@@ -51,18 +51,24 @@ object SyntaxHighlighting {
@inline def numberStart(c: Char) =
c.isDigit && (!prev.isLetter || prev == '.' || prev == ' ' || prev == '(' || prev == '\u0000')
- while (iter.hasNext) {
- val n = iter.next
+ def takeChar(): Char = takeChars(1).head
+ def takeChars(x: Int): Seq[Char] = {
+ val taken = remaining.take(x)
+ remaining = remaining.drop(x)
+ taken
+ }
+
+ while (remaining.nonEmpty) {
+ val n = takeChar()
if (interpolationPrefixes.contains(n)) {
// Interpolation prefixes are a superset of the keyword start chars
- val next = iter.take(3).mkString
+ val next = remaining.take(3).mkString
if (next.startsWith("\"")) {
newBuf += n
prev = n
- appendLiteral('"', next.toIterator.drop(1), next == "\"\"\"")
+ if (remaining.nonEmpty) takeChar() // drop 1 for appendLiteral
+ appendLiteral('"', next == "\"\"\"")
} else {
- val (dup, _ ) = iter.duplicate
- iter = next.toIterator ++ dup
if (n.isUpper && keywordStart) {
appendWhile(n, !typeEnders.contains(_), typeDef)
} else if (keywordStart) {
@@ -75,15 +81,11 @@ object SyntaxHighlighting {
} else {
(n: @switch) match {
case '/' =>
- if (iter.hasNext) {
- iter.next match {
+ if (remaining.nonEmpty) {
+ takeChar() match {
case '/' => eolComment()
case '*' => blockComment()
- case x => {
- newBuf += '/'
- val (dup, _) = iter.duplicate
- iter = List(x).toIterator ++ dup
- }
+ case x => newBuf += '/'; remaining = x #:: remaining
}
} else newBuf += '/'
case '=' =>
@@ -92,19 +94,17 @@ object SyntaxHighlighting {
append('<', { x => x == "<-" || x == "<:" || x == "<%" }, keyword)
case '>' =>
append('>', { x => x == ">:" }, keyword)
- case '#' =>
+ case '#' if prev != ' ' && prev != '.' =>
newBuf append keyword("#")
prev = '#'
case '@' =>
appendWhile('@', _ != ' ', annotation)
- case '\"' => iter.take(2).mkString match {
- case "\"\"" => appendLiteral('\"', Iterator.empty, multiline = true)
- case lit => appendLiteral('\"', lit.toIterator)
- }
+ case '\"' =>
+ appendLiteral('\"', multiline = remaining.take(2).mkString == "\"\"")
case '\'' =>
- appendLiteral('\'', Iterator.empty)
+ appendLiteral('\'')
case '`' =>
- appendUntil('`', _ == '`', none)
+ appendTo('`', _ == '`', none)
case c if c.isUpper && keywordStart =>
appendWhile(c, !typeEnders.contains(_), typeDef)
case c if numberStart(c) =>
@@ -118,8 +118,8 @@ object SyntaxHighlighting {
def eolComment() = {
newBuf append (CommentColor + "//")
var curr = '/'
- while (curr != '\n' && iter.hasNext) {
- curr = iter.next
+ while (curr != '\n' && remaining.nonEmpty) {
+ curr = takeChar()
newBuf += curr
}
prev = curr
@@ -130,16 +130,16 @@ object SyntaxHighlighting {
newBuf append (CommentColor + "/*")
var curr = '*'
var open = 1
- while (open > 0 && iter.hasNext) {
- curr = iter.next
+ while (open > 0 && remaining.nonEmpty) {
+ curr = takeChar()
newBuf += curr
- if (curr == '*' && iter.hasNext) {
- curr = iter.next
+ if (curr == '*' && remaining.nonEmpty) {
+ curr = takeChar()
newBuf += curr
if (curr == '/') open -= 1
- } else if (curr == '/' && iter.hasNext) {
- curr = iter.next
+ } else if (curr == '/' && remaining.nonEmpty) {
+ curr = takeChar()
newBuf += curr
if (curr == '*') open += 1
}
@@ -148,7 +148,7 @@ object SyntaxHighlighting {
newBuf append NoColor
}
- def appendLiteral(delim: Char, succ: Iterator[Char], multiline: Boolean = false) = {
+ def appendLiteral(delim: Char, multiline: Boolean = false) = {
var curr: Char = 0
var continue = true
var closing = 0
@@ -156,32 +156,31 @@ object SyntaxHighlighting {
newBuf append (LiteralColor + delim)
def shouldInterpolate =
- inInterpolation && curr == '$' && prev != '$' && (iter.hasNext || succ.hasNext)
+ inInterpolation && curr == '$' && prev != '$' && remaining.nonEmpty
def interpolate() = {
- val next: Char = if (succ.hasNext) succ.next else iter.next
+ val next = takeChar()
if (next == '$') {
newBuf += curr
newBuf += next
prev = '$'
} else if (next == '{') {
+ var open = 1 // keep track of open blocks
newBuf append (KeywordColor + curr)
newBuf += next
- if (iter.hasNext) {
- var c = iter.next
- while (iter.hasNext && c != '}') {
- newBuf += c
- c = iter.next
- }
+ while (remaining.nonEmpty && open > 0) {
+ var c = takeChar()
newBuf += c
- newBuf append LiteralColor
+ if (c == '}') open -= 1
+ else if (c == '{') open += 1
}
+ newBuf append LiteralColor
} else {
newBuf append (KeywordColor + curr)
newBuf += next
var c: Char = 'a'
- while (c.isLetterOrDigit && (iter.hasNext || succ.hasNext)) {
- c = if (succ.hasNext) succ.next else iter.next
+ while (c.isLetterOrDigit && remaining.nonEmpty) {
+ c = takeChar()
if (c != '"') newBuf += c
}
newBuf append LiteralColor
@@ -193,13 +192,13 @@ object SyntaxHighlighting {
closing = 0
}
- while (continue && (iter.hasNext || succ.hasNext)) {
- curr = if(succ.hasNext) succ.next else iter.next
- if (curr == '\\' && (iter.hasNext || succ.hasNext)) {
- val next = if (succ.hasNext) succ.next else iter.next
+ while (continue && remaining.nonEmpty) {
+ curr = takeChar()
+ if (curr == '\\' && remaining.nonEmpty) {
+ val next = takeChar()
newBuf append (KeywordColor + curr)
if (next == 'u') {
- val code = "u" + iter.take(4).mkString
+ val code = "u" + takeChars(4).mkString
newBuf append code
} else newBuf += next
newBuf append LiteralColor
@@ -220,18 +219,13 @@ object SyntaxHighlighting {
}
newBuf append NoColor
prev = curr
-
- if (succ.hasNext) {
- val (dup, _) = iter.duplicate
- iter = succ ++ dup
- }
}
- def append(c: Char, shouldHL: String => Boolean, highlight: String => String, pre: Iterator[Char] = Iterator.empty) = {
+ def append(c: Char, shouldHL: String => Boolean, highlight: String => String) = {
var curr: Char = 0
val sb = new StringBuilder(s"$c")
- while ((pre.hasNext || iter.hasNext) && curr != ' ' && curr != '(') {
- curr = if (pre.hasNext) pre.next else iter.next
+ while (remaining.nonEmpty && curr != ' ' && curr != '(') {
+ curr = takeChar()
if (curr != ' ') sb += curr
}
@@ -245,8 +239,8 @@ object SyntaxHighlighting {
def appendWhile(c: Char, pred: Char => Boolean, highlight: String => String) = {
var curr: Char = 0
val sb = new StringBuilder(s"$c")
- while (iter.hasNext && pred(curr)) {
- curr = iter.next
+ while (remaining.nonEmpty && pred(curr)) {
+ curr = takeChar()
if (pred(curr)) sb += curr
}
@@ -256,15 +250,15 @@ object SyntaxHighlighting {
prev = curr
}
- def appendUntil(c: Char, pred: Char => Boolean, highlight: String => String) = {
+ def appendTo(c: Char, pred: Char => Boolean, highlight: String => String) = {
var curr: Char = 0
val sb = new StringBuilder(s"$c")
- while (iter.hasNext && !pred(curr)) {
- curr = iter.next
+ while (remaining.nonEmpty && !pred(curr)) {
+ curr = takeChar()
sb += curr
}
- newBuf append (highlight(sb.toString))
+ newBuf append highlight(sb.toString)
prev = curr
}