Created
October 13, 2018 14:27
-
-
Save martinpi/3fe7e73363d8076f3ded1d90a55d8fba to your computer and use it in GitHub Desktop.
A simple Swift 4.0 class for syntax highlighting in an NSTextView
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// | |
// SyntaxHighlighter.swift | |
// CardsCardsCards | |
// | |
// Created by Martin Pichlmair on 12/10/2018. | |
// | |
// Based on https://raw.githubusercontent.com/kuyawa/Macaw/master/Macaw/Macaw.swift | |
import Cocoa | |
import Foundation | |
class SyntaxHighlighter { | |
struct color { | |
static let normal = [NSAttributedString.Key.foregroundColor: NSColor(red: 0.95, green: 0.95, blue: 0.95, alpha: 1.0)] // light grey | |
static let ruleName = [NSAttributedString.Key.foregroundColor: NSColor(red: 0.40, green: 0.60, blue: 0.90, alpha: 1.0)] // cyan | |
static let number = [NSAttributedString.Key.foregroundColor: NSColor(red: 0.60, green: 0.60, blue: 0.90, alpha: 1.0)] // blue | |
static let keyword = [NSAttributedString.Key.foregroundColor: NSColor(red: 0.75, green: 0.20, blue: 0.75, alpha: 1.0)] // magenta | |
static let expression = [NSAttributedString.Key.foregroundColor: NSColor(red: 0.95, green: 0.75, blue: 0.10, alpha: 1.0)] // yellow | |
static let modifier = [NSAttributedString.Key.foregroundColor: NSColor(red: 0.95, green: 0.50, blue: 0.20, alpha: 1.0)] // orange | |
static let comment = [NSAttributedString.Key.foregroundColor: NSColor(red: 0.20, green: 0.60, blue: 0.20, alpha: 1.0)] // green | |
} | |
struct regex { | |
static let keywords = "\\b(origin)\\b" | |
static let ruleName = "(\\[.*\\])" | |
static let expression = "(\\#[a-zA-Z][a-zA-Z0-9,\\.\\(\\)]*\\#)" | |
static let modifier = "\\#.*\\.([a-zA-Z][a-zA-Z0-9,]*\\(.*\\))\\#" | |
static let numberLiteral = "\\b([0-9]*(\\.[0-9]*)?)\\b" | |
static let symbols = "(\\+|-|\\*|/|=|\\{|\\}|\\[|\\]|\\(|\\))" | |
static let commentLine = "(^\\\\.*)" | |
} | |
let patterns = [ | |
regex.commentLine : color.comment, | |
regex.ruleName : color.keyword, | |
regex.numberLiteral : color.number, | |
regex.keywords : color.keyword, | |
regex.expression : color.expression, | |
regex.modifier : color.modifier | |
] | |
init() { | |
} | |
// Colorize all | |
func colorize(_ textView: NSTextView) { | |
let all = textView.string | |
let range = NSString(string: textView.string).range(of: all) | |
colorize(textView, range: range) | |
} | |
// Colorize range | |
func colorize(_ textView: NSTextView, range: NSRange) { | |
var extended = NSUnionRange(range, NSString(string: textView.string).lineRange(for: NSMakeRange(range.location, 0))) | |
extended = NSUnionRange(range, NSString(string: textView.string).lineRange(for: NSMakeRange(NSMaxRange(range), 0))) | |
for (pattern, attribute) in patterns { | |
applyStyles(textView, range: extended, pattern: pattern, attribute: attribute) | |
} | |
} | |
func applyStyles(_ textView: NSTextView, range: NSRange, pattern: String, attribute: [NSAttributedString.Key: Any]) { | |
let regex = try? NSRegularExpression(pattern: pattern, options: [NSRegularExpression.Options.anchorsMatchLines]) | |
regex?.enumerateMatches(in: textView.string, options: [], range: range) { | |
match, flags, stop in | |
let matchRange = match?.range(at: 1) | |
textView.textStorage?.addAttributes(attribute, range: matchRange!) | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment