macOS: Refactor syntax highlighting

Signed-off-by: Roopesh Chander <roop@roopc.net>
This commit is contained in:
Roopesh Chander 2019-01-22 01:05:10 +05:30
parent f6c9ce2d71
commit 15517c4c3d
4 changed files with 89 additions and 86 deletions

View File

@ -140,6 +140,7 @@
6FE1765A21C90E87002690EA /* LocalizationHelper.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6FE1765921C90E87002690EA /* LocalizationHelper.swift */; }; 6FE1765A21C90E87002690EA /* LocalizationHelper.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6FE1765921C90E87002690EA /* LocalizationHelper.swift */; };
6FE254FB219C10800028284D /* ZipImporter.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6FE254FA219C10800028284D /* ZipImporter.swift */; }; 6FE254FB219C10800028284D /* ZipImporter.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6FE254FA219C10800028284D /* ZipImporter.swift */; };
6FE254FF219C60290028284D /* ZipExporter.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6FE254FE219C60290028284D /* ZipExporter.swift */; }; 6FE254FF219C60290028284D /* ZipExporter.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6FE254FE219C60290028284D /* ZipExporter.swift */; };
6FE3661D21F64F6B00F78C7D /* ConfTextColorTheme.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6FE3661C21F64F6B00F78C7D /* ConfTextColorTheme.swift */; };
6FF3527021C240160008484E /* ringlogger.c in Sources */ = {isa = PBXBuildFile; fileRef = 6FF3526C21C23F960008484E /* ringlogger.c */; }; 6FF3527021C240160008484E /* ringlogger.c in Sources */ = {isa = PBXBuildFile; fileRef = 6FF3526C21C23F960008484E /* ringlogger.c */; };
6FF3527121C240160008484E /* Logger.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6FF3526E21C23FA10008484E /* Logger.swift */; }; 6FF3527121C240160008484E /* Logger.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6FF3526E21C23FA10008484E /* Logger.swift */; };
6FF3527221C2616C0008484E /* ringlogger.c in Sources */ = {isa = PBXBuildFile; fileRef = 6FF3526C21C23F960008484E /* ringlogger.c */; }; 6FF3527221C2616C0008484E /* ringlogger.c in Sources */ = {isa = PBXBuildFile; fileRef = 6FF3526C21C23F960008484E /* ringlogger.c */; };
@ -307,6 +308,7 @@
6FE1765921C90E87002690EA /* LocalizationHelper.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LocalizationHelper.swift; sourceTree = "<group>"; }; 6FE1765921C90E87002690EA /* LocalizationHelper.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LocalizationHelper.swift; sourceTree = "<group>"; };
6FE254FA219C10800028284D /* ZipImporter.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ZipImporter.swift; sourceTree = "<group>"; }; 6FE254FA219C10800028284D /* ZipImporter.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ZipImporter.swift; sourceTree = "<group>"; };
6FE254FE219C60290028284D /* ZipExporter.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ZipExporter.swift; sourceTree = "<group>"; }; 6FE254FE219C60290028284D /* ZipExporter.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ZipExporter.swift; sourceTree = "<group>"; };
6FE3661C21F64F6B00F78C7D /* ConfTextColorTheme.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ConfTextColorTheme.swift; sourceTree = "<group>"; };
6FF3526B21C23F960008484E /* ringlogger.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ringlogger.h; sourceTree = "<group>"; }; 6FF3526B21C23F960008484E /* ringlogger.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ringlogger.h; sourceTree = "<group>"; };
6FF3526C21C23F960008484E /* ringlogger.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = ringlogger.c; sourceTree = "<group>"; }; 6FF3526C21C23F960008484E /* ringlogger.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = ringlogger.c; sourceTree = "<group>"; };
6FF3526E21C23FA10008484E /* Logger.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Logger.swift; sourceTree = "<group>"; }; 6FF3526E21C23FA10008484E /* Logger.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Logger.swift; sourceTree = "<group>"; };
@ -394,6 +396,7 @@
5F52D0BA21E3781B00283CEA /* ConfTextView.swift */, 5F52D0BA21E3781B00283CEA /* ConfTextView.swift */,
5F52D0BC21E3785C00283CEA /* ConfTextStorage.swift */, 5F52D0BC21E3785C00283CEA /* ConfTextStorage.swift */,
6F9B582721E8CD4300544D02 /* PopupRow.swift */, 6F9B582721E8CD4300544D02 /* PopupRow.swift */,
6FE3661C21F64F6B00F78C7D /* ConfTextColorTheme.swift */,
); );
path = View; path = View;
sourceTree = "<group>"; sourceTree = "<group>";
@ -1120,6 +1123,7 @@
6FBA103F21D6B6FF0051C35F /* TunnelImporter.swift in Sources */, 6FBA103F21D6B6FF0051C35F /* TunnelImporter.swift in Sources */,
6F89E17A21EDEB0E00C97BB9 /* StatusItemController.swift in Sources */, 6F89E17A21EDEB0E00C97BB9 /* StatusItemController.swift in Sources */,
6F4DD16B21DA558800690EAE /* TunnelListRow.swift in Sources */, 6F4DD16B21DA558800690EAE /* TunnelListRow.swift in Sources */,
6FE3661D21F64F6B00F78C7D /* ConfTextColorTheme.swift in Sources */,
5F52D0BF21E3788900283CEA /* NSColor+Hex.swift in Sources */, 5F52D0BF21E3788900283CEA /* NSColor+Hex.swift in Sources */,
6FB1BDBE21D50F0200A991BF /* Logger.swift in Sources */, 6FB1BDBE21D50F0200A991BF /* Logger.swift in Sources */,
6FB1BDBF21D50F0200A991BF /* TunnelConfiguration+WgQuickConfig.swift in Sources */, 6FB1BDBF21D50F0200A991BF /* TunnelConfiguration+WgQuickConfig.swift in Sources */,

View File

@ -0,0 +1,58 @@
// SPDX-License-Identifier: MIT
// Copyright © 2018-2019 WireGuard LLC. All Rights Reserved.
import Cocoa
protocol ConfTextColorTheme {
func color(for: highlight_type) -> NSColor
}
struct ConfTextAquaColorTheme: ConfTextColorTheme {
func color(for highlightType: highlight_type) -> NSColor {
switch highlightType.rawValue {
case HighlightSection.rawValue:
return NSColor(hex: "#326D74") // Class name in Xcode
case HighlightField.rawValue:
return NSColor(hex: "#9B2393") // Keywords in Xcode
case HighlightPublicKey.rawValue, HighlightPrivateKey.rawValue, HighlightPresharedKey.rawValue:
return NSColor(hex: "#643820") // Preprocessor directives in Xcode
case HighlightIP.rawValue, HighlightHost.rawValue:
return NSColor(hex: "#0E0EFF") // URLs in Xcode
case HighlightCidr.rawValue, HighlightPort.rawValue:
return NSColor(hex: "#815F03") // Attributes in Xcode
case HighlightMTU.rawValue, HighlightKeepalive.rawValue:
return NSColor(hex: "#1C00CF") // Numbers in Xcode
case HighlightComment.rawValue:
return NSColor(hex: "#536579") // Comments in Xcode
case HighlightError.rawValue:
return NSColor(hex: "#C41A16") // Strings in Xcode
default:
return NSColor(hex: "#000000") // Plain text in Xcode
}
}
}
struct ConfTextDarkAquaColorTheme: ConfTextColorTheme {
func color(for highlightType: highlight_type) -> NSColor {
switch highlightType.rawValue {
case HighlightSection.rawValue:
return NSColor(hex: "#91D462") // Class name in Xcode
case HighlightField.rawValue:
return NSColor(hex: "#FC5FA3") // Keywords in Xcode
case HighlightPublicKey.rawValue, HighlightPrivateKey.rawValue, HighlightPresharedKey.rawValue:
return NSColor(hex: "#FD8F3F") // Preprocessor directives in Xcode
case HighlightIP.rawValue, HighlightHost.rawValue:
return NSColor(hex: "#53A5FB") // URLs in Xcode
case HighlightCidr.rawValue, HighlightPort.rawValue:
return NSColor(hex: "#75B492") // Attributes in Xcode
case HighlightMTU.rawValue, HighlightKeepalive.rawValue:
return NSColor(hex: "#9686F5") // Numbers in Xcode
case HighlightComment.rawValue:
return NSColor(hex: "#6C7986") // Comments in Xcode
case HighlightError.rawValue:
return NSColor(hex: "#FF4C4C") // Strings in Xcode
default:
return NSColor(hex: "#FFFFFF") // Plain text in Xcode
}
}
}

View File

@ -7,24 +7,11 @@ private let fontSize: CGFloat = 15
class ConfTextStorage: NSTextStorage { class ConfTextStorage: NSTextStorage {
struct TextColorTheme {
let plainText: NSColor
let sections: NSColor
let keyType: NSColor
let key: NSColor
let url: NSColor
let urlAttribute: NSColor
let comments: NSColor
let number: NSColor
let error: NSColor
}
let defaultFont = NSFontManager.shared.convertWeight(true, of: NSFont.systemFont(ofSize: fontSize)) let defaultFont = NSFontManager.shared.convertWeight(true, of: NSFont.systemFont(ofSize: fontSize))
private let boldFont = NSFont.boldSystemFont(ofSize: fontSize) private let boldFont = NSFont.boldSystemFont(ofSize: fontSize)
private lazy var italicFont = NSFontManager.shared.convert(defaultFont, toHaveTrait: .italicFontMask) private lazy var italicFont = NSFontManager.shared.convert(defaultFont, toHaveTrait: .italicFontMask)
private var defaultAttributes: [NSAttributedString.Key: Any]! //swiftlint:disable:this implicitly_unwrapped_optional private var textColorTheme: ConfTextColorTheme?
private var highlightAttributes: [UInt32: [NSAttributedString.Key: Any]]! //swiftlint:disable:this implicitly_unwrapped_optional
private let backingStore: NSMutableAttributedString private let backingStore: NSMutableAttributedString
private(set) var hasError = false private(set) var hasError = false
@ -43,73 +30,25 @@ class ConfTextStorage: NSTextStorage {
fatalError("init(pasteboardPropertyList:ofType:) has not been implemented") fatalError("init(pasteboardPropertyList:ofType:) has not been implemented")
} }
//swiftlint:disable:next function_body_length func nonColorAttributes(for highlightType: highlight_type) -> [NSAttributedString.Key: Any] {
func updateAttributes(for theme: TextColorTheme) { switch highlightType.rawValue {
self.defaultAttributes = [ case HighlightSection.rawValue, HighlightField.rawValue:
.foregroundColor: theme.plainText, return [.font: boldFont]
.font: defaultFont case HighlightPublicKey.rawValue, HighlightPrivateKey.rawValue, HighlightPresharedKey.rawValue,
] HighlightIP.rawValue, HighlightCidr.rawValue, HighlightHost.rawValue, HighlightPort.rawValue,
HighlightMTU.rawValue, HighlightKeepalive.rawValue, HighlightDelimiter.rawValue:
self.highlightAttributes = [ return [.font: defaultFont]
HighlightSection.rawValue: [ case HighlightComment.rawValue:
.foregroundColor: theme.sections, return [.font: italicFont]
.font: boldFont case HighlightError.rawValue:
], return [.font: defaultFont, .underlineStyle: 1]
HighlightField.rawValue: [ default:
.foregroundColor: theme.keyType, return [:]
.font: boldFont }
], }
HighlightPublicKey.rawValue: [
.foregroundColor: theme.key,
.font: defaultFont
],
HighlightPrivateKey.rawValue: [
.foregroundColor: theme.key,
.font: defaultFont
],
HighlightPresharedKey.rawValue: [
.foregroundColor: theme.key,
.font: defaultFont
],
HighlightIP.rawValue: [
.foregroundColor: theme.url,
.font: defaultFont
],
HighlightCidr.rawValue: [
.foregroundColor: theme.urlAttribute,
.font: defaultFont
],
HighlightHost.rawValue: [
.foregroundColor: theme.url,
.font: defaultFont
],
HighlightPort.rawValue: [
.foregroundColor: theme.urlAttribute,
.font: defaultFont
],
HighlightMTU.rawValue: [
.foregroundColor: theme.number,
.font: defaultFont
],
HighlightKeepalive.rawValue: [
.foregroundColor: theme.number,
.font: defaultFont
],
HighlightComment.rawValue: [
.foregroundColor: theme.comments,
.font: italicFont
],
HighlightDelimiter.rawValue: [
.foregroundColor: theme.plainText,
.font: defaultFont
],
HighlightError.rawValue: [
.foregroundColor: theme.error,
.font: defaultFont,
.underlineStyle: 1
]
]
func updateAttributes(for textColorTheme: ConfTextColorTheme) {
self.textColorTheme = textColorTheme
highlightSyntax() highlightSyntax()
} }
@ -152,8 +91,12 @@ class ConfTextStorage: NSTextStorage {
while spans.pointee.type != HighlightEnd { while spans.pointee.type != HighlightEnd {
let span = spans.pointee let span = spans.pointee
let attributes = self.highlightAttributes[span.type.rawValue] ?? defaultAttributes let range = NSRange(location: span.start, length: span.len)
backingStore.setAttributes(attributes, range: NSRange(location: span.start, length: span.len)) backingStore.setAttributes(nonColorAttributes(for: span.type), range: range)
if let textColorTheme = textColorTheme {
let color = textColorTheme.color(for: span.type)
backingStore.addAttribute(.foregroundColor, value: color, range: range)
}
if span.type == HighlightError { if span.type == HighlightError {
hasError = true hasError = true

View File

@ -44,14 +44,12 @@ class ConfTextView: NSTextView {
} }
private func updateTheme() { private func updateTheme() {
let theme: ConfTextStorage.TextColorTheme
switch effectiveAppearance.bestMatch(from: [.aqua, .darkAqua]) ?? .aqua { switch effectiveAppearance.bestMatch(from: [.aqua, .darkAqua]) ?? .aqua {
case .darkAqua: case .darkAqua:
theme = ConfTextStorage.TextColorTheme(plainText: NSColor(hex: "#FFFFFF"), sections: NSColor(hex: "#91D462"), keyType: NSColor(hex: "#FC5FA3"), key: NSColor(hex: "#FD8F3F"), url: NSColor(hex: "#53A5FB"), urlAttribute: NSColor(hex: "#75B492"), comments: NSColor(hex: "#6C7986"), number: NSColor(hex: "#9686F5"), error: NSColor(hex: "#FF4C4C")) confTextStorage.updateAttributes(for: ConfTextDarkAquaColorTheme())
default: default:
theme = ConfTextStorage.TextColorTheme(plainText: NSColor(hex: "#000000"), sections: NSColor(hex: "#326D74"), keyType: NSColor(hex: "#9B2393"), key: NSColor(hex: "#643820"), url: NSColor(hex: "#0E0EFF"), urlAttribute: NSColor(hex: "#815F03"), comments: NSColor(hex: "#536579"), number: NSColor(hex: "#1C00CF"), error: NSColor(hex: "#C41A16")) confTextStorage.updateAttributes(for: ConfTextAquaColorTheme())
} }
confTextStorage.updateAttributes(for: theme)
} }
} }