Skip to content

Commit

Permalink
- Adds 5 new code themes
Browse files Browse the repository at this point in the history
- Fixes freezes when app starts
- Fixes golang code highlighting
- Improves themes in edit mode

#1269
  • Loading branch information
glushchenko committed Jan 9, 2022
1 parent af5c3c8 commit 39cd1a1
Show file tree
Hide file tree
Showing 11 changed files with 1,325 additions and 36 deletions.
16 changes: 16 additions & 0 deletions FSNotes.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -862,6 +862,13 @@
D7EDEDFB219203C9000B8C1A /* NoteCellView+.swift in Sources */ = {isa = PBXBuildFile; fileRef = D7EDEDFA219203C9000B8C1A /* NoteCellView+.swift */; };
D7EDEDFC219203C9000B8C1A /* NoteCellView+.swift in Sources */ = {isa = PBXBuildFile; fileRef = D7EDEDFA219203C9000B8C1A /* NoteCellView+.swift */; };
D7EDEDFD21920402000B8C1A /* NoteCellView+.swift in Sources */ = {isa = PBXBuildFile; fileRef = D7EDEDFA219203C9000B8C1A /* NoteCellView+.swift */; };
D7EFAF68278B310300175A2F /* HighlighterTheme.swift in Sources */ = {isa = PBXBuildFile; fileRef = D7EFAF67278B310300175A2F /* HighlighterTheme.swift */; };
D7EFAF69278B310300175A2F /* HighlighterTheme.swift in Sources */ = {isa = PBXBuildFile; fileRef = D7EFAF67278B310300175A2F /* HighlighterTheme.swift */; };
D7EFAF6A278B310300175A2F /* HighlighterTheme.swift in Sources */ = {isa = PBXBuildFile; fileRef = D7EFAF67278B310300175A2F /* HighlighterTheme.swift */; };
D7EFAF6B278B310300175A2F /* HighlighterTheme.swift in Sources */ = {isa = PBXBuildFile; fileRef = D7EFAF67278B310300175A2F /* HighlighterTheme.swift */; };
D7EFAF6C278B310300175A2F /* HighlighterTheme.swift in Sources */ = {isa = PBXBuildFile; fileRef = D7EFAF67278B310300175A2F /* HighlighterTheme.swift */; };
D7EFAF6D278B310300175A2F /* HighlighterTheme.swift in Sources */ = {isa = PBXBuildFile; fileRef = D7EFAF67278B310300175A2F /* HighlighterTheme.swift */; };
D7EFAF6E278B310300175A2F /* HighlighterTheme.swift in Sources */ = {isa = PBXBuildFile; fileRef = D7EFAF67278B310300175A2F /* HighlighterTheme.swift */; };
D7F2F19721C503F000E41811 /* AvenirNext-MediumItalic.ttf in Resources */ = {isa = PBXBuildFile; fileRef = D7F2F18721C503EF00E41811 /* AvenirNext-MediumItalic.ttf */; };
D7F2F19821C503F000E41811 /* AvenirNext-MediumItalic.ttf in Resources */ = {isa = PBXBuildFile; fileRef = D7F2F18721C503EF00E41811 /* AvenirNext-MediumItalic.ttf */; };
D7F2F19921C503F000E41811 /* AvenirNext-MediumItalic.ttf in Resources */ = {isa = PBXBuildFile; fileRef = D7F2F18721C503EF00E41811 /* AvenirNext-MediumItalic.ttf */; };
Expand Down Expand Up @@ -1508,6 +1515,7 @@
D7EA59EE213EAD8700582BD9 /* image.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = image.png; sourceTree = "<group>"; };
D7ED6891200F87BD00FF975A /* Initial */ = {isa = PBXFileReference; lastKnownFileType = folder; path = Initial; sourceTree = "<group>"; };
D7EDEDFA219203C9000B8C1A /* NoteCellView+.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "NoteCellView+.swift"; sourceTree = "<group>"; };
D7EFAF67278B310300175A2F /* HighlighterTheme.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = HighlighterTheme.swift; sourceTree = "<group>"; };
D7F272F7228C96C300974FE2 /* es */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = es; path = es.lproj/Main.strings; sourceTree = "<group>"; };
D7F272F9228C96C300974FE2 /* es */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = es; path = es.lproj/Localizable.strings; sourceTree = "<group>"; };
D7F2F18721C503EF00E41811 /* AvenirNext-MediumItalic.ttf */ = {isa = PBXFileReference; lastKnownFileType = file; path = "AvenirNext-MediumItalic.ttf"; sourceTree = "<group>"; };
Expand Down Expand Up @@ -1848,6 +1856,7 @@
D7B34F9625195D7E0007877E /* PreviewState.swift */,
D79651B02517741400333AD4 /* ProgressState.swift */,
D75627CD26D1165A000AF6EA /* ImageFormat.swift */,
D7EFAF67278B310300175A2F /* HighlighterTheme.swift */,
);
path = Business;
sourceTree = "<group>";
Expand Down Expand Up @@ -3489,6 +3498,7 @@
D79651B62517741400333AD4 /* ProgressState.swift in Sources */,
D7B4AC632471253100F3888A /* NoteMeta.swift in Sources */,
D7B2B6E8245EEA5F0084B78D /* LanguageType.swift in Sources */,
D7EFAF6D278B310300175A2F /* HighlighterTheme.swift in Sources */,
D7B34F9C25195D7E0007877E /* PreviewState.swift in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
Expand Down Expand Up @@ -3530,6 +3540,7 @@
D77E05312463128A00AD7772 /* StorageType.swift in Sources */,
6F13BB6F20FEE04F0005E120 /* URL+.swift in Sources */,
6F13BB6B20FEE0460005E120 /* DateFormatter+.swift in Sources */,
D7EFAF6E278B310300175A2F /* HighlighterTheme.swift in Sources */,
D768D756245E854D0028F344 /* NSAttributedString+.swift in Sources */,
D75627D426D1165A000AF6EA /* ImageFormat.swift in Sources */,
);
Expand Down Expand Up @@ -3641,6 +3652,7 @@
D75E33BB22462442006AD1C1 /* MainWindowController.swift in Sources */,
D768D757245E86660028F344 /* NSAttributedString+.swift in Sources */,
D73CEC6B2278EC4200D549F7 /* AttributedBox.swift in Sources */,
D7EFAF6A278B310300175A2F /* HighlighterTheme.swift in Sources */,
D75E33BC22462442006AD1C1 /* PreferencesEditorViewController.swift in Sources */,
D75E33BD22462442006AD1C1 /* MasterPasswordViewController.swift in Sources */,
D7C1C99C235606CB0021A32D /* SidebarHeaderCellView.swift in Sources */,
Expand Down Expand Up @@ -3701,6 +3713,7 @@
D7CD5CC6218209960009D63B /* Project.swift in Sources */,
D7CD5CC8218209D10009D63B /* Note.swift in Sources */,
D7CD5CD421820D640009D63B /* NSAttributedStringKey+.swift in Sources */,
D7EFAF6C278B310300175A2F /* HighlighterTheme.swift in Sources */,
D730BD3F222DB9FC00E69C93 /* NameHelper.swift in Sources */,
D7737393223D59CF00154B9E /* KeychainConfiguration.swift in Sources */,
D7CD5CDC21832C190009D63B /* UserDefaultsManagement+.swift in Sources */,
Expand Down Expand Up @@ -3797,6 +3810,7 @@
D7BAC62F249D11F8008D29AA /* SettingsFilesNaming.swift in Sources */,
D77E0538246312B400AD7772 /* StorageType.swift in Sources */,
D7B34F9A25195D7E0007877E /* PreviewState.swift in Sources */,
D7EFAF6B278B310300175A2F /* HighlighterTheme.swift in Sources */,
D7D00E79248FBFF7009AE455 /* UIView+.swift in Sources */,
D7CD5CDB21832C190009D63B /* UserDefaultsManagement+.swift in Sources */,
D7679389201F21F5000F7BBF /* AppDelegate.swift in Sources */,
Expand Down Expand Up @@ -3908,6 +3922,7 @@
D7F5C0F2223ED0C00038F172 /* PreferencesUserInterfaceViewController.swift in Sources */,
D768D759245E86680028F344 /* NSAttributedString+.swift in Sources */,
275592971F3AE9B5006B8988 /* MainWindowController.swift in Sources */,
D7EFAF68278B310300175A2F /* HighlighterTheme.swift in Sources */,
D7F5C0F5223ED5620038F172 /* PreferencesEditorViewController.swift in Sources */,
D738356D2242871400B260DD /* MasterPasswordViewController.swift in Sources */,
D7C1C99A235606CB0021A32D /* SidebarHeaderCellView.swift in Sources */,
Expand Down Expand Up @@ -4023,6 +4038,7 @@
D7F5C0F3223ED0C00038F172 /* PreferencesUserInterfaceViewController.swift in Sources */,
D768D758245E86670028F344 /* NSAttributedString+.swift in Sources */,
D7E81C421F925B5F00416A91 /* MainWindowController.swift in Sources */,
D7EFAF69278B310300175A2F /* HighlighterTheme.swift in Sources */,
D7F5C0F6223ED5620038F172 /* PreferencesEditorViewController.swift in Sources */,
D738356E2242871400B260DD /* MasterPasswordViewController.swift in Sources */,
D7C1C99B235606CB0021A32D /* SidebarHeaderCellView.swift in Sources */,
Expand Down
15 changes: 15 additions & 0 deletions FSNotes/Base.lproj/Main.storyboard
Original file line number Diff line number Diff line change
Expand Up @@ -3045,9 +3045,24 @@ Will Pazner (github.com/pazner)</string>
<menuItem title="atom-one-light" id="ME1-My-h4q">
<modifierMask key="keyEquivalentModifierMask"/>
</menuItem>
<menuItem title="atom-one-dark" id="Rog-4H-qth">
<modifierMask key="keyEquivalentModifierMask"/>
</menuItem>
<menuItem title="monokai-sublime" id="AaQ-hp-VpR">
<modifierMask key="keyEquivalentModifierMask"/>
</menuItem>
<menuItem title="xcode" id="1Tz-tN-qVO">
<modifierMask key="keyEquivalentModifierMask"/>
</menuItem>
<menuItem title="zenburn" id="FCZ-jz-Xb0">
<modifierMask key="keyEquivalentModifierMask"/>
</menuItem>
<menuItem title="tomorrow" id="g18-hs-VcA">
<modifierMask key="keyEquivalentModifierMask"/>
</menuItem>
<menuItem title="agate" id="xpl-3U-eFW">
<modifierMask key="keyEquivalentModifierMask"/>
</menuItem>
</items>
</menu>
</popUpButtonCell>
Expand Down
4 changes: 2 additions & 2 deletions FSNotes/Business/Note.swift
Original file line number Diff line number Diff line change
Expand Up @@ -1983,7 +1983,7 @@ public class Note: NSObject {
save()
}

public func cache() {
public func cache(backgroundThread: Bool = false) {
if cachingInProgress {
return
}
Expand All @@ -1995,7 +1995,7 @@ public class Note: NSObject {
copy.removeAttribute(.backgroundColor, range: NSRange(0..<copy.length))

NotesTextProcessor.highlightMarkdown(attributedString: copy, paragraphRange: NSRange(location: 0, length: copy.length), note: self)
NotesTextProcessor.highlightFencedAndIndentCodeBlocks(attributedString: copy)
NotesTextProcessor.highlightFencedAndIndentCodeBlocks(attributedString: copy, backgroundThread: backgroundThread)

if content.string.md5 == copy.string.md5 {
content = copy
Expand Down
2 changes: 1 addition & 1 deletion FSNotes/Business/Storage.swift
Original file line number Diff line number Diff line change
Expand Up @@ -520,7 +520,7 @@ class Storage {
DispatchQueue.global(qos: .background).async {
for note in self.noteList {
if note.type == .Markdown {
note.cache()
note.cache(backgroundThread: true)
}
}

Expand Down
19 changes: 19 additions & 0 deletions FSNotes/Extensions/NSFont+.swift
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,25 @@ extension NSFont {

return UserDefaultsManagement.noteFont
}

func codeBold() -> NSFont {
guard let family = UserDefaultsManagement.codeFont.familyName else {
return UserDefaultsManagement.codeFont
}

var mask = 0
if (isItalic) {
mask = NSFontBoldTrait|NSFontItalicTrait
} else {
mask = NSFontBoldTrait
}

if let font = NSFontManager().font(withFamily: family, traits: NSFontTraitMask(rawValue: NSFontTraitMask.RawValue(mask)), weight: 5, size: CGFloat(UserDefaultsManagement.fontSize)) {
return font
}

return UserDefaultsManagement.codeFont
}

func unBold() -> NSFont {
guard let family = UserDefaultsManagement.noteFont.familyName else {
Expand Down
46 changes: 30 additions & 16 deletions FSNotes/Helpers/NotesTextProcessor.swift
Original file line number Diff line number Diff line change
Expand Up @@ -52,11 +52,11 @@ public class NotesTextProcessor {

public static var codeBackground: NSColor {
get {
if UserDefaultsManagement.appearanceType != AppearanceType.Custom, #available(OSX 10.13, *) {
return NSColor(named: "code")!
} else {
return NSColor(red:0.97, green:0.97, blue:0.97, alpha:1.0)
if let theme = HighlighterTheme(rawValue: UserDefaultsManagement.codeTheme) {
return NSColor(hex: theme.backgroundHex)
}

return NSColor(named: "code") ?? NSColor(red:0.97, green:0.97, blue:0.97, alpha:1.0)
}
}

Expand Down Expand Up @@ -227,9 +227,12 @@ public class NotesTextProcessor {
}

public static var hl: Highlightr? = nil
public static var backgroundHl: Highlightr? = nil

public static func getHighlighter() -> Highlightr? {
if let instance = self.hl {
public static func getHighlighter(backgroundThread: Bool = false) -> Highlightr? {
if backgroundThread, let instance = self.backgroundHl {
return instance
} else if let instance = self.hl, !backgroundThread {
return instance
}

Expand All @@ -240,7 +243,11 @@ public class NotesTextProcessor {
highlightr.setTheme(to: UserDefaultsManagement.codeTheme)
highlightr.theme.codeFont = UserDefaultsManagement.codeFont

self.hl = highlightr
if backgroundThread {
self.backgroundHl = highlightr
} else {
self.hl = highlightr
}

return highlightr
}
Expand All @@ -258,8 +265,8 @@ public class NotesTextProcessor {
}
#endif

public static func highlightCode(attributedString: NSMutableAttributedString, range: NSRange, language: String? = nil) {
guard let highlighter = NotesTextProcessor.getHighlighter() else { return }
public static func highlightCode(attributedString: NSMutableAttributedString, range: NSRange, language: String? = nil, backgroundThread: Bool = false) {
guard let highlighter = NotesTextProcessor.getHighlighter(backgroundThread: backgroundThread) else { return }

let codeString = attributedString.mutableString.substring(with: range)
let preDefinedLanguage = language ?? getLanguage(codeString)
Expand Down Expand Up @@ -436,7 +443,7 @@ public class NotesTextProcessor {
highlightFencedAndIndentCodeBlocks(attributedString: note.content)
}

public static func highlightFencedAndIndentCodeBlocks(attributedString: NSMutableAttributedString) {
public static func highlightFencedAndIndentCodeBlocks(attributedString: NSMutableAttributedString, backgroundThread: Bool = false) {
let range = NSRange(0..<attributedString.length)

if UserDefaultsManagement.codeBlockHighlight {
Expand All @@ -454,10 +461,12 @@ public class NotesTextProcessor {
range: range,
using: { (result, matchingFlags, stop) -> Void in
guard let r = result else { return }
fencedRanges.append(r.range)
fencedRanges.append(r.range(at: 2))

NotesTextProcessor.highlightCode(attributedString: attributedString, range: r.range)
let fullCode = attributedString.mutableString.substring(with: r.range)
let preDefinedLanguage = getLanguage(fullCode)

NotesTextProcessor.highlightCode(attributedString: attributedString, range: r.range(at: 2), language: preDefinedLanguage, backgroundThread: backgroundThread)
NotesTextProcessor.highlightFencedBackTick(range: r.range, attributedString: attributedString)
})

Expand All @@ -478,9 +487,9 @@ public class NotesTextProcessor {
}
}

public static func highlightFencedBackTick(range: NSRange, attributedString: NSMutableAttributedString) {
public static func highlightFencedBackTick(range: NSRange, attributedString: NSMutableAttributedString, language: String? = nil) {
let code = attributedString.mutableString.substring(with: range)
let language = NotesTextProcessor.getLanguage(code)
let language = language ?? NotesTextProcessor.getLanguage(code)

var length = 3
if let langLength = language?.count {
Expand All @@ -490,9 +499,14 @@ public class NotesTextProcessor {
let openRange = NSRange(location: range.location, length: length)
attributedString.addAttribute(.foregroundColor, value: NotesTextProcessor.syntaxColor, range: openRange)

let closeRange = NSRange(location: range.upperBound - 4, length: 3)
let closeRange = NSRange(location: range.upperBound - 4, length: 4)
attributedString.addAttribute(.foregroundColor, value: NotesTextProcessor.syntaxColor, range: closeRange)

// Colorize last new line
let lastParRange = attributedString.mutableString.paragraphRange(for: NSRange(location: range.location + range.length - 1, length: 0))
attributedString.addAttribute(.backgroundColor, value: NotesTextProcessor.codeBackground, range: lastParRange)

// Colorize language name
if let langLength = language?.count {
let color = Color.init(red: 0.18, green: 0.61, blue: 0.25, alpha: 1.00)
let range = NSRange(location: range.location + 3, length: langLength)
Expand Down Expand Up @@ -1357,7 +1371,7 @@ public class NotesTextProcessor {
*/
public static let _codeQuoteBlockPattern = [
"(?<=\\n|\\A)",
"(^```[\\S\\ \\(\\)]*\\n[\\s\\S]*?\\n```(?:\\n|\\Z))"
"(^```[\\S\\ \\(\\)]*\\n([\\s\\S]*?)\\n```(?:\\n|\\Z))"
].joined(separator: "\n")

fileprivate static let codeSpanPattern = [
Expand Down
2 changes: 1 addition & 1 deletion FSNotes/Helpers/UserDefaultsManagement.swift
Original file line number Diff line number Diff line change
Expand Up @@ -196,7 +196,7 @@ public class UserDefaultsManagement {
set {
guard let newValue = newValue else {return}

self.codeFontName = newValue.fontName
self.codeFontName = newValue.familyName ?? "Source Code Pro"
self.codeFontSize = Int(newValue.pointSize)
}
}
Expand Down
26 changes: 26 additions & 0 deletions FSNotesCore/Core macOS/Extensions/NSColor+.swift
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,32 @@
import Cocoa

public extension NSColor {
convenience init(hex: String) {
let trimHex = hex.trimmingCharacters(in: .whitespacesAndNewlines)
let dropHash = String(trimHex.dropFirst()).trimmingCharacters(in: .whitespacesAndNewlines)
let hexString = trimHex.starts(with: "#") ? dropHash : trimHex
let ui64 = UInt64(hexString, radix: 16)
let value = ui64 != nil ? Int(ui64!) : 0
// #RRGGBB
var components = (
R: CGFloat((value >> 16) & 0xff) / 255,
G: CGFloat((value >> 08) & 0xff) / 255,
B: CGFloat((value >> 00) & 0xff) / 255,
a: CGFloat(1)
)
if String(hexString).count == 8 {
// #RRGGBBAA
components = (
R: CGFloat((value >> 24) & 0xff) / 255,
G: CGFloat((value >> 16) & 0xff) / 255,
B: CGFloat((value >> 08) & 0xff) / 255,
a: CGFloat((value >> 00) & 0xff) / 255
)
}

self.init(red: components.R, green: components.G, blue: components.B, alpha: components.a)
}

static var tagColor: NSColor {
get {
let accentColor = UserDefaults.standard.value(forKey: "AppleAccentColor")
Expand Down
54 changes: 54 additions & 0 deletions FSNotesCore/Shared/Business/HighlighterTheme.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
//
// HighlighterTheme.swift
// FSNotes
//
// Created by Александр on 09.01.2022.
// Copyright © 2022 Oleksandr Glushchenko. All rights reserved.
//

enum HighlighterTheme: String {
case github = "github"
case solarizedLight = "solarized-light"
case solarizedDark = "solarized-dark"
case visualStudio = "vs"
case atomOneLight = "atom-one-light"
case atomOneDark = "atom-one-dark"
case monokaiSublime = "monokai-sublime"
case xcode = "xcode"
case zenburn = "zenburn"
case tomorrow = "tomorrow"
case agate = "agate"

static func named(rawValue: String) -> HighlighterTheme {
switch rawValue {
case "github": return .github
case "solarized-light": return .solarizedLight
case "solarized-dark": return .solarizedDark
case "vs": return .visualStudio
case "atom-one-light": return .atomOneLight
case "atom-one-dark": return .atomOneDark
case "monokai-sublime": return .monokaiSublime
case "xcode": return .xcode
case "zendburn": return .zenburn
case "tomorrow": return .tomorrow
case "agate": return .agate
default: return .github
}
}

public var backgroundHex: String {
switch self {
case .github: return "#f8f8f8"
case .solarizedLight: return "#fdf6e3"
case .solarizedDark: return "#002b36"
case .visualStudio: return "#f8f8f8"
case .atomOneLight: return "#fafafa"
case .atomOneDark: return "#282c34"
case .monokaiSublime: return "#23241f"
case .xcode: return "#f8f8f8"
case .zenburn: return "#3f3f3f"
case .tomorrow: return "#f8f8f8"
case .agate: return "#333333"
}
}
}
Loading

0 comments on commit 39cd1a1

Please sign in to comment.