Compare commits

..

No commits in common. "5b9f59ec098fe31ed4fcd511067ae5c8610164d4" and "6e4cbfdb6ddbdc7770a1fe25f13f227b6e8118bf" have entirely different histories.

2 changed files with 17 additions and 60 deletions

View File

@ -77,25 +77,8 @@ class JavaScriptHighlighter {
return attributed return attributed
} }
private func emit(token: TokenType, range: NSRange) {
let color: NSColor
switch token {
case .string:
color = .systemRed
case .number:
color = .systemBlue
case .punctuation:
color = .systemTeal
case .identifier:
return
}
attributed.addAttribute(.foregroundColor, value: color, range: range)
}
private func consumeExpression() { private func consumeExpression() {
consumeWhitespace()
guard let char = peek() else { return } guard let char = peek() else { return }
if identifierStarts.contains(char) { if identifierStarts.contains(char) {
@ -119,15 +102,6 @@ class JavaScriptHighlighter {
} else { } else {
consume() consume()
} }
consumeWhitespace()
}
private func consumeWhitespace(newlines: Bool = true) {
let charSet = newlines ? CharacterSet.whitespacesAndNewlines : .whitespaces
while let char = peek(), charSet.contains(char) {
consume()
}
} }
private func consumeIdentifier() { private func consumeIdentifier() {
@ -150,7 +124,7 @@ class JavaScriptHighlighter {
} }
} }
print("Number: \(text[numberStart..<currentIndex])") print("Number: \(text[numberStart..<currentIndex])")
emit(token: .number, range: range(from: numberStart, to: currentIndex)) attributed.addAttribute(.foregroundColor, value: NSColor.systemBlue, range: range(from: numberStart, to: currentIndex))
} }
private func consumeString() { private func consumeString() {
@ -163,7 +137,7 @@ class JavaScriptHighlighter {
consume() // string closing quote consume() // string closing quote
} }
print("String: \(text[stringStart..<currentIndex])") print("String: \(text[stringStart..<currentIndex])")
emit(token: .string, range: range(from: stringStart, to: currentIndex)) attributed.addAttribute(.foregroundColor, value: NSColor.systemRed, range: range(from: stringStart, to: currentIndex))
} }
private func consumeTemplateString() { private func consumeTemplateString() {
@ -174,7 +148,7 @@ class JavaScriptHighlighter {
consume() // $ consume() // $
consume() // { consume() // {
print("Template string fragment: '\(text[stringFragmentStart!..<currentIndex])'") print("Template string fragment: '\(text[stringFragmentStart!..<currentIndex])'")
emit(token: .string, range: range(from: stringFragmentStart!, to: currentIndex)) attributed.addAttribute(.foregroundColor, value: NSColor.systemRed, range: range(from: stringFragmentStart!, to: currentIndex))
consumeTemplateStringExpression() consumeTemplateStringExpression()
stringFragmentStart = currentIndex stringFragmentStart = currentIndex
if currentIndex < text.endIndex && peek() == "}" { if currentIndex < text.endIndex && peek() == "}" {
@ -184,7 +158,7 @@ class JavaScriptHighlighter {
stringFragmentStart = stringFragmentStart ?? currentIndex stringFragmentStart = stringFragmentStart ?? currentIndex
consume() // ` consume() // `
print("Template string fragment: '\(text[stringFragmentStart!..<currentIndex])'") print("Template string fragment: '\(text[stringFragmentStart!..<currentIndex])'")
emit(token: .string, range: range(from: stringFragmentStart!, to: currentIndex)) attributed.addAttribute(.foregroundColor, value: NSColor.systemRed, range: range(from: stringFragmentStart!, to: currentIndex))
stringFragmentStart = nil stringFragmentStart = nil
break break
} else { } else {
@ -193,7 +167,7 @@ class JavaScriptHighlighter {
} }
if let start = stringFragmentStart { if let start = stringFragmentStart {
print("Template string fragment: '\(text[start..<currentIndex])'") print("Template string fragment: '\(text[start..<currentIndex])'")
emit(token: .string, range: range(from: start, to: currentIndex)) attributed.addAttribute(.foregroundColor, value: NSColor.systemRed, range: range(from: start, to: currentIndex))
} }
} }
@ -213,7 +187,7 @@ class JavaScriptHighlighter {
private func consumeFunctionCallOrGrouping() { private func consumeFunctionCallOrGrouping() {
consume() // ( consume() // (
print("Opening (") print("Opening (")
emit(token: .punctuation, range: prevCharRange()) attributed.addAttribute(.foregroundColor, value: NSColor.systemTeal, range: prevCharRange())
indent += " " indent += " "
while currentIndex < text.endIndex && peek() != ")" { while currentIndex < text.endIndex && peek() != ")" {
consumeExpression() consumeExpression()
@ -222,31 +196,27 @@ class JavaScriptHighlighter {
if currentIndex < text.endIndex { if currentIndex < text.endIndex {
consume() // ) consume() // )
print("Closing )") print("Closing )")
emit(token: .punctuation, range: prevCharRange()) attributed.addAttribute(.foregroundColor, value: NSColor.systemTeal, range: prevCharRange())
} }
} }
private func consumeObject() { private func consumeObject() {
consume() // { consume() // {
print("Opening {") print("Opening {")
emit(token: .punctuation, range: prevCharRange()) attributed.addAttribute(.foregroundColor, value: NSColor.systemTeal, range: prevCharRange())
indent += " " indent += " "
object: object:
while currentIndex < text.endIndex && peek() != "}" { while currentIndex < text.endIndex && peek() != "}" {
consumeObjectKey() consumeObjectKey()
if peek() == ":" { if peek() == ":" {
consume() // : consume() // :
emit(token: .punctuation, range: prevCharRange())
consumeWhitespace()
while currentIndex < text.endIndex && peek() != "," && peek() != "}" { while currentIndex < text.endIndex && peek() != "," && peek() != "}" {
consumeExpression() consumeExpression()
} }
} if currentIndex < text.endIndex {
consumeWhitespace() break object
}
if peek() == "," { } else if peek() == "," {
consume() // ,
emit(token: .punctuation, range: prevCharRange())
continue continue
} else { } else {
break break
@ -256,12 +226,11 @@ class JavaScriptHighlighter {
if currentIndex < text.endIndex { if currentIndex < text.endIndex {
consume() // } consume() // }
print("Closing }") print("Closing }")
emit(token: .punctuation, range: prevCharRange()) attributed.addAttribute(.foregroundColor, value: NSColor.systemTeal, range: prevCharRange())
} }
} }
private func consumeObjectKey() { private func consumeObjectKey() {
consumeWhitespace()
guard let char = peek() else { return } guard let char = peek() else { return }
let keyStart = currentIndex! let keyStart = currentIndex!
if identifierStarts.contains(char) { if identifierStarts.contains(char) {
@ -270,19 +239,18 @@ class JavaScriptHighlighter {
consumeString() consumeString()
} }
print("Object key: '\(text[keyStart..<currentIndex])'") print("Object key: '\(text[keyStart..<currentIndex])'")
consumeWhitespace()
} }
private func consumeDotLookup() { private func consumeDotLookup() {
consume() // . consume() // .
print("Dot lookup") print("Dot lookup")
emit(token: .punctuation, range: prevCharRange()) attributed.addAttribute(.foregroundColor, value: NSColor.systemTeal, range: prevCharRange())
} }
private func consumeArray() { private func consumeArray() {
consume() // [ consume() // [
print("Opening [") print("Opening [")
emit(token: .punctuation, range: prevCharRange()) attributed.addAttribute(.foregroundColor, value: NSColor.systemTeal, range: prevCharRange())
indent += " " indent += " "
array: array:
while currentIndex < text.endIndex && peek() != "]" { while currentIndex < text.endIndex && peek() != "]" {
@ -290,8 +258,6 @@ class JavaScriptHighlighter {
while currentIndex < text.endIndex { while currentIndex < text.endIndex {
if peek() == "," { if peek() == "," {
consume() // , consume() // ,
print("Array separator")
emit(token: .punctuation, range: prevCharRange())
break break
} else if peek() == "]" { } else if peek() == "]" {
break array break array
@ -306,17 +272,8 @@ class JavaScriptHighlighter {
if currentIndex < text.endIndex { if currentIndex < text.endIndex {
consume() // ] consume() // ]
print("Closing ]") print("Closing ]")
emit(token: .punctuation, range: prevCharRange()) attributed.addAttribute(.foregroundColor, value: NSColor.systemTeal, range: prevCharRange())
} }
} }
} }
extension JavaScriptHighlighter {
enum TokenType {
case identifier
case punctuation
case number
case string
}
}

View File

@ -8,6 +8,6 @@
import Foundation import Foundation
let source = "{a: 1234 , 'b': 'blah', foo}" let source = "`+`${{a:3}}`"
_ = JavaScriptHighlighter(text: source).highlight() _ = JavaScriptHighlighter(text: source).highlight()