extend Cordial syntax highlighting with types, booleans, functions, and missing keywords
This commit is contained in:
parent
8b3e780817
commit
ae398e7316
|
|
@ -1032,10 +1032,17 @@ func updateBlockRanges(for textView: NSTextView) {
|
||||||
// MARK: - Syntax Highlighting
|
// MARK: - Syntax Highlighting
|
||||||
|
|
||||||
private let syntaxKeywords: Set<String> = [
|
private let syntaxKeywords: Set<String> = [
|
||||||
"let", "fn", "if", "else", "for", "map", "cast", "plot", "sch"
|
"let", "fn", "if", "else", "for", "while", "return", "mut", "in",
|
||||||
|
"map", "cast", "plot", "sch"
|
||||||
]
|
]
|
||||||
|
|
||||||
private let syntaxOperatorChars = CharacterSet(charactersIn: "+-*/=^<>!(){}[]:,")
|
private let syntaxTypes: Set<String> = [
|
||||||
|
"bool", "int", "float", "str", "i32", "f64", "Vec", "String"
|
||||||
|
]
|
||||||
|
|
||||||
|
private let syntaxBooleans: Set<String> = ["true", "false"]
|
||||||
|
|
||||||
|
private let syntaxOperatorChars = CharacterSet(charactersIn: "+-*/=^<>!(){}[]:,.&|%")
|
||||||
|
|
||||||
func applySyntaxHighlighting(to textStorage: NSTextStorage) {
|
func applySyntaxHighlighting(to textStorage: NSTextStorage) {
|
||||||
let text = textStorage.string
|
let text = textStorage.string
|
||||||
|
|
@ -1279,6 +1286,8 @@ private func highlightCodeTokens(_ line: NSString, inRange range: NSRange, lineO
|
||||||
let identStart = CharacterSet.letters.union(CharacterSet(charactersIn: "_"))
|
let identStart = CharacterSet.letters.union(CharacterSet(charactersIn: "_"))
|
||||||
let identChars = identStart.union(.decimalDigits)
|
let identChars = identStart.union(.decimalDigits)
|
||||||
|
|
||||||
|
var prevIdent: String? = nil
|
||||||
|
|
||||||
while !scanner.isAtEnd {
|
while !scanner.isAtEnd {
|
||||||
let pos = scanner.currentIndex
|
let pos = scanner.currentIndex
|
||||||
|
|
||||||
|
|
@ -1300,6 +1309,7 @@ private func highlightCodeTokens(_ line: NSString, inRange range: NSRange, lineO
|
||||||
}
|
}
|
||||||
let absRange = NSRange(location: lineOffset + range.location + startIdx, length: strContent.count)
|
let absRange = NSRange(location: lineOffset + range.location + startIdx, length: strContent.count)
|
||||||
textStorage.addAttribute(.foregroundColor, value: syn.string, range: absRange)
|
textStorage.addAttribute(.foregroundColor, value: syn.string, range: absRange)
|
||||||
|
prevIdent = nil
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1308,6 +1318,7 @@ private func highlightCodeTokens(_ line: NSString, inRange range: NSRange, lineO
|
||||||
let startIdx = sub.distance(from: sub.startIndex, to: pos)
|
let startIdx = sub.distance(from: sub.startIndex, to: pos)
|
||||||
let absRange = NSRange(location: lineOffset + range.location + startIdx, length: numStr.count)
|
let absRange = NSRange(location: lineOffset + range.location + startIdx, length: numStr.count)
|
||||||
textStorage.addAttribute(.foregroundColor, value: syn.number, range: absRange)
|
textStorage.addAttribute(.foregroundColor, value: syn.number, range: absRange)
|
||||||
|
prevIdent = nil
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1318,8 +1329,22 @@ private func highlightCodeTokens(_ line: NSString, inRange range: NSRange, lineO
|
||||||
let absRange = NSRange(location: lineOffset + range.location + startIdx, length: ident.count)
|
let absRange = NSRange(location: lineOffset + range.location + startIdx, length: ident.count)
|
||||||
if syntaxKeywords.contains(ident) {
|
if syntaxKeywords.contains(ident) {
|
||||||
textStorage.addAttribute(.foregroundColor, value: syn.keyword, range: absRange)
|
textStorage.addAttribute(.foregroundColor, value: syn.keyword, range: absRange)
|
||||||
|
} else if syntaxBooleans.contains(ident) {
|
||||||
|
textStorage.addAttribute(.foregroundColor, value: syn.boolean, range: absRange)
|
||||||
|
} else if syntaxTypes.contains(ident) {
|
||||||
|
textStorage.addAttribute(.foregroundColor, value: syn.type, range: absRange)
|
||||||
|
} else if prevIdent == "fn" {
|
||||||
|
textStorage.addAttribute(.foregroundColor, value: syn.function, range: absRange)
|
||||||
|
} else {
|
||||||
|
// Check if followed by '(' -> function call
|
||||||
|
let remaining = sub[scanner.currentIndex...]
|
||||||
|
let trimmedRest = remaining.drop(while: { $0 == " " })
|
||||||
|
if trimmedRest.first == "(" {
|
||||||
|
textStorage.addAttribute(.foregroundColor, value: syn.function, range: absRange)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
prevIdent = ident
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1328,10 +1353,13 @@ private func highlightCodeTokens(_ line: NSString, inRange range: NSRange, lineO
|
||||||
let startIdx = sub.distance(from: sub.startIndex, to: pos)
|
let startIdx = sub.distance(from: sub.startIndex, to: pos)
|
||||||
let absRange = NSRange(location: lineOffset + range.location + startIdx, length: op.count)
|
let absRange = NSRange(location: lineOffset + range.location + startIdx, length: op.count)
|
||||||
textStorage.addAttribute(.foregroundColor, value: syn.operator, range: absRange)
|
textStorage.addAttribute(.foregroundColor, value: syn.operator, range: absRange)
|
||||||
|
prevIdent = nil
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
// Skip unrecognized character
|
// Skip unrecognized character (preserve prevIdent across whitespace)
|
||||||
|
let ch = sub[scanner.currentIndex]
|
||||||
|
if !ch.isWhitespace { prevIdent = nil }
|
||||||
scanner.currentIndex = sub.index(after: scanner.currentIndex)
|
scanner.currentIndex = sub.index(after: scanner.currentIndex)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -122,6 +122,8 @@ struct Theme {
|
||||||
let `operator`: NSColor
|
let `operator`: NSColor
|
||||||
let function: NSColor
|
let function: NSColor
|
||||||
let result: NSColor
|
let result: NSColor
|
||||||
|
let type: NSColor
|
||||||
|
let boolean: NSColor
|
||||||
}
|
}
|
||||||
|
|
||||||
static var syntax: SyntaxColors {
|
static var syntax: SyntaxColors {
|
||||||
|
|
@ -133,7 +135,9 @@ struct Theme {
|
||||||
comment: p.overlay1,
|
comment: p.overlay1,
|
||||||
operator: p.sky,
|
operator: p.sky,
|
||||||
function: p.blue,
|
function: p.blue,
|
||||||
result: p.teal
|
result: p.teal,
|
||||||
|
type: p.yellow,
|
||||||
|
boolean: p.peach
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue