extend Cordial syntax highlighting with types, booleans, functions, and missing keywords

This commit is contained in:
jess 2026-04-06 11:45:22 -07:00
parent 8b3e780817
commit ae398e7316
2 changed files with 36 additions and 4 deletions

View File

@ -1032,10 +1032,17 @@ func updateBlockRanges(for textView: NSTextView) {
// MARK: - Syntax Highlighting
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) {
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 identChars = identStart.union(.decimalDigits)
var prevIdent: String? = nil
while !scanner.isAtEnd {
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)
textStorage.addAttribute(.foregroundColor, value: syn.string, range: absRange)
prevIdent = nil
continue
}
@ -1308,6 +1318,7 @@ private func highlightCodeTokens(_ line: NSString, inRange range: NSRange, lineO
let startIdx = sub.distance(from: sub.startIndex, to: pos)
let absRange = NSRange(location: lineOffset + range.location + startIdx, length: numStr.count)
textStorage.addAttribute(.foregroundColor, value: syn.number, range: absRange)
prevIdent = nil
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)
if syntaxKeywords.contains(ident) {
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
}
@ -1328,10 +1353,13 @@ private func highlightCodeTokens(_ line: NSString, inRange range: NSRange, lineO
let startIdx = sub.distance(from: sub.startIndex, to: pos)
let absRange = NSRange(location: lineOffset + range.location + startIdx, length: op.count)
textStorage.addAttribute(.foregroundColor, value: syn.operator, range: absRange)
prevIdent = nil
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)
}
}

View File

@ -122,6 +122,8 @@ struct Theme {
let `operator`: NSColor
let function: NSColor
let result: NSColor
let type: NSColor
let boolean: NSColor
}
static var syntax: SyntaxColors {
@ -133,7 +135,9 @@ struct Theme {
comment: p.overlay1,
operator: p.sky,
function: p.blue,
result: p.teal
result: p.teal,
type: p.yellow,
boolean: p.peach
)
}
}