@@ -34,12 +34,6 @@ object SyntaxHighlighting {
34
34
index <- IF to ERASED // All alpha keywords
35
35
} yield tokenString(index)
36
36
37
- private val interpolationPrefixes =
38
- 'A' :: 'B' :: 'C' :: 'D' :: 'E' :: 'F' :: 'G' :: 'H' :: 'I' :: 'J' :: 'K' ::
39
- 'L' :: 'M' :: 'N' :: 'O' :: 'P' :: 'Q' :: 'R' :: 'S' :: 'T' :: 'U' :: 'V' ::
40
- 'W' :: 'X' :: 'Y' :: 'Z' :: '$' :: '_' :: 'a' :: 'b' :: 'c' :: 'd' :: 'e' ::
41
- 'f' :: 'g' :: 'h' :: 'i' :: 'j' :: 'k' :: 'l' :: 'm' :: 'n' :: 'o' :: 'p' ::
42
- 'q' :: 'r' :: 's' :: 't' :: 'u' :: 'v' :: 'w' :: 'x' :: 'y' :: 'z' :: Nil
43
37
44
38
private val typeEnders =
45
39
'{' :: '}' :: ')' :: '(' :: '[' :: ']' :: '=' :: ' ' :: ',' :: '.' :: '|' ::
@@ -66,16 +60,44 @@ object SyntaxHighlighting {
66
60
taken
67
61
}
68
62
63
+ def isUpper (c : Char ) = c.isUpper || c == '_' || c == '$'
64
+
65
+ def opChar (c: Char ) = (c : @ switch) match {
66
+ case '~' | '!' | '@' | '#' | '%' |
67
+ '^' | '*' | '+' | '-' | '<' |
68
+ '>' | '?' | ':' | '=' | '&' |
69
+ '|' | '\\ ' | '/' => true
70
+ case _ => false
71
+ }
72
+
73
+ def tryInterpolatorPrefix (n : Char , remaining : Stream [Char ]): Option [String ] = {
74
+ if (isUpper(n) || n.isLower) {
75
+ val beforeUnderscore = remaining.takeWhile(c =>
76
+ c.isUpper || c.isLower || c.isDigit
77
+ )
78
+ val suffix = remaining.drop(beforeUnderscore.length) match {
79
+ case '_' +: afterUnderscore => '_' +: afterUnderscore.drop(1 ).takeWhile(opChar)
80
+ case _ => Seq .empty
81
+ }
82
+ Some (((n +: beforeUnderscore) ++ suffix).mkString)
83
+ } else {
84
+ None
85
+ }
86
+ }
87
+
88
+
69
89
while (remaining.nonEmpty) {
70
90
val n = takeChar()
71
- if (interpolationPrefixes.contains(n)) {
72
- // Interpolation prefixes are a superset of the keyword start chars
73
- val next = remaining.take(3 ).mkString
74
- if (next.startsWith(" \" " )) {
75
- newBuf += n
76
- prev = n
77
- if (remaining.nonEmpty) takeChar() // drop 1 for appendLiteral
78
- appendString('"' , next == " \"\"\" " )
91
+
92
+ val optInterpPrefix = tryInterpolatorPrefix(n, remaining)
93
+ if (optInterpPrefix.isDefined) {
94
+ val interpPrefix : String = optInterpPrefix.get
95
+ val after = remaining.drop(interpPrefix.length - 1 ).take(3 ).mkString
96
+ if (after.startsWith(" \" " )) {
97
+ newBuf ++= interpPrefix
98
+ prev = interpPrefix.last
99
+ if (remaining.nonEmpty) takeChars(interpPrefix.length)
100
+ appendString('"' , after == " \"\"\" " , inInterpolation = true )
79
101
} else {
80
102
if (n.isUpper && (keywordStart || prev == '.' )) {
81
103
appendWhile(n, ! typeEnders.contains(_), typeDef)
@@ -116,7 +138,7 @@ object SyntaxHighlighting {
116
138
case '@' =>
117
139
appendWhile('@' , ! typeEnders.contains(_), annotation)
118
140
case '\" ' =>
119
- appendString('\" ' , multiline = remaining.take(2 ).mkString == " \"\" " )
141
+ appendString('\" ' , multiline = remaining.take(2 ).mkString == " \"\" " , false )
120
142
case '\' ' =>
121
143
appendSingleQuote('\' ' )
122
144
case '`' =>
@@ -181,11 +203,10 @@ object SyntaxHighlighting {
181
203
newBuf append NoColor
182
204
}
183
205
184
- def appendString (delim : Char , multiline : Boolean = false ) = {
206
+ def appendString (delim : Char , multiline : Boolean = false , inInterpolation : Boolean ) = {
185
207
var curr : Char = 0
186
208
var continue = true
187
209
var closing = 0
188
- val inInterpolation = interpolationPrefixes.contains(prev)
189
210
newBuf append (LiteralColor + delim)
190
211
191
212
def shouldInterpolate =
0 commit comments