2016-07-26 22:42:30 +03:00
|
|
|
/**
|
|
|
|
* Tae Won Ha - http://taewon.de - @hataewon
|
|
|
|
* See LICENSE
|
|
|
|
*/
|
|
|
|
|
2016-08-03 22:41:43 +03:00
|
|
|
import Cocoa
|
2016-07-26 22:42:30 +03:00
|
|
|
import RxSwift
|
|
|
|
|
|
|
|
private class PrefKeys {
|
|
|
|
|
2016-08-14 16:38:41 +03:00
|
|
|
static let openNewWindowWhenLaunching = "open-new-window-when-launching"
|
|
|
|
static let openNewWindowOnReactivation = "open-new-window-on-reactivation"
|
2016-09-11 11:53:15 +03:00
|
|
|
static let openQuicklyIgnorePatterns = "open-quickly-ignore-patterns"
|
2016-08-14 16:38:41 +03:00
|
|
|
|
2016-07-26 22:42:30 +03:00
|
|
|
static let editorFontName = "editor-font-name"
|
|
|
|
static let editorFontSize = "editor-font-size"
|
2016-07-30 23:06:42 +03:00
|
|
|
static let editorUsesLigatures = "editor-uses-ligatures"
|
2016-09-24 17:31:14 +03:00
|
|
|
|
|
|
|
static let useInteractiveZsh = "use-interactive-zsh"
|
2016-07-26 22:42:30 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
class PrefStore: Store {
|
|
|
|
|
2016-09-25 18:50:33 +03:00
|
|
|
fileprivate static let compatibleVersion = "38"
|
|
|
|
fileprivate static let defaultEditorFont = NeoVimView.defaultFont
|
2016-07-30 19:17:03 +03:00
|
|
|
static let minimumEditorFontSize = NeoVimView.minFontSize
|
|
|
|
static let maximumEditorFontSize = NeoVimView.maxFontSize
|
2016-07-26 22:42:30 +03:00
|
|
|
|
2016-09-25 18:50:33 +03:00
|
|
|
fileprivate let source: Observable<Any>
|
|
|
|
fileprivate let disposeBag = DisposeBag()
|
2016-07-26 22:42:30 +03:00
|
|
|
|
2016-09-25 18:50:33 +03:00
|
|
|
fileprivate let subject = PublishSubject<Any>()
|
2016-07-26 22:42:30 +03:00
|
|
|
var sink: Observable<Any> {
|
|
|
|
return self.subject.asObservable()
|
|
|
|
}
|
|
|
|
|
2016-09-25 18:50:33 +03:00
|
|
|
fileprivate let userDefaults = UserDefaults.standard
|
|
|
|
fileprivate let fontManager = NSFontManager.shared()
|
2016-07-26 22:42:30 +03:00
|
|
|
|
2016-08-14 15:29:50 +03:00
|
|
|
var data = PrefData(
|
2016-09-11 11:53:15 +03:00
|
|
|
general: GeneralPrefData(openNewWindowWhenLaunching: true,
|
|
|
|
openNewWindowOnReactivation: true,
|
|
|
|
ignorePatterns: Set([ "*/.git", "*.o", "*.d", "*.dia" ].map(FileItemIgnorePattern.init))),
|
2016-09-24 17:31:14 +03:00
|
|
|
appearance: AppearancePrefData(editorFont: PrefStore.defaultEditorFont, editorUsesLigatures: false),
|
|
|
|
advanced: AdvancedPrefData(useInteractiveZsh: false)
|
2016-08-14 15:29:50 +03:00
|
|
|
)
|
2016-07-26 22:42:30 +03:00
|
|
|
|
|
|
|
init(source: Observable<Any>) {
|
|
|
|
self.source = source
|
|
|
|
|
2016-09-25 18:50:33 +03:00
|
|
|
if let prefs = self.userDefaults.dictionary(forKey: PrefStore.compatibleVersion) {
|
2016-07-26 22:42:30 +03:00
|
|
|
self.data = self.prefDataFromDict(prefs)
|
|
|
|
} else {
|
|
|
|
self.userDefaults.setValue(self.prefsDict(self.data), forKey: PrefStore.compatibleVersion)
|
|
|
|
}
|
|
|
|
|
2016-07-26 23:51:05 +03:00
|
|
|
self.addReactions()
|
2016-07-26 22:42:30 +03:00
|
|
|
}
|
|
|
|
|
2016-07-27 00:40:20 +03:00
|
|
|
deinit {
|
|
|
|
self.subject.onCompleted()
|
|
|
|
}
|
|
|
|
|
2016-09-25 18:50:33 +03:00
|
|
|
fileprivate func prefDataFromDict(_ prefs: [String: Any]) -> PrefData {
|
2016-07-26 22:42:30 +03:00
|
|
|
|
|
|
|
let editorFontName = prefs[PrefKeys.editorFontName] as? String ?? PrefStore.defaultEditorFont.fontName
|
2016-08-14 00:01:31 +03:00
|
|
|
let editorFontSize = CGFloat(
|
|
|
|
(prefs[PrefKeys.editorFontSize] as? NSNumber)?.floatValue ?? Float(PrefStore.defaultEditorFont.pointSize)
|
|
|
|
)
|
|
|
|
let editorFont = self.saneFont(editorFontName, fontSize: editorFontSize)
|
|
|
|
|
|
|
|
let usesLigatures = (prefs[PrefKeys.editorUsesLigatures] as? NSNumber)?.boolValue ?? false
|
|
|
|
let openNewWindowWhenLaunching = (prefs[PrefKeys.openNewWindowWhenLaunching] as? NSNumber)?.boolValue ?? true
|
|
|
|
let openNewWindowOnReactivation = (prefs[PrefKeys.openNewWindowOnReactivation] as? NSNumber)?.boolValue ?? true
|
|
|
|
|
2016-09-11 11:53:15 +03:00
|
|
|
let ignorePatternsList = (prefs[PrefKeys.openQuicklyIgnorePatterns] as? String) ?? "*/.git, *.o, *.d, *.dia"
|
2016-09-11 15:28:56 +03:00
|
|
|
let ignorePatterns = PrefUtils.ignorePatterns(fromString: ignorePatternsList)
|
2016-09-11 11:53:15 +03:00
|
|
|
|
2016-09-24 17:31:14 +03:00
|
|
|
let useInteractiveZsh = (prefs[PrefKeys.useInteractiveZsh] as? NSNumber)?.boolValue ?? false
|
|
|
|
|
2016-08-14 15:29:50 +03:00
|
|
|
return PrefData(
|
|
|
|
general: GeneralPrefData(
|
|
|
|
openNewWindowWhenLaunching: openNewWindowWhenLaunching,
|
2016-09-11 11:53:15 +03:00
|
|
|
openNewWindowOnReactivation: openNewWindowOnReactivation,
|
|
|
|
ignorePatterns: ignorePatterns
|
2016-08-14 15:29:50 +03:00
|
|
|
),
|
2016-09-24 17:31:14 +03:00
|
|
|
appearance: AppearancePrefData(editorFont: editorFont, editorUsesLigatures: usesLigatures),
|
|
|
|
advanced: AdvancedPrefData(useInteractiveZsh: useInteractiveZsh)
|
2016-08-14 15:29:50 +03:00
|
|
|
)
|
2016-08-14 00:01:31 +03:00
|
|
|
}
|
2016-07-26 22:42:30 +03:00
|
|
|
|
2016-09-25 18:50:33 +03:00
|
|
|
fileprivate func saneFont(_ fontName: String, fontSize: CGFloat) -> NSFont {
|
2016-08-14 00:01:31 +03:00
|
|
|
var editorFont = NSFont(name: fontName, size: fontSize) ?? PrefStore.defaultEditorFont
|
2016-09-25 18:50:33 +03:00
|
|
|
if !editorFont.isFixedPitch {
|
|
|
|
editorFont = fontManager.convert(PrefStore.defaultEditorFont, toSize: editorFont.pointSize)
|
2016-07-26 22:42:30 +03:00
|
|
|
}
|
|
|
|
if editorFont.pointSize < PrefStore.minimumEditorFontSize
|
|
|
|
|| editorFont.pointSize > PrefStore.maximumEditorFontSize {
|
2016-09-25 18:50:33 +03:00
|
|
|
editorFont = fontManager.convert(editorFont, toSize: PrefStore.defaultEditorFont.pointSize)
|
2016-07-30 23:06:42 +03:00
|
|
|
}
|
2016-07-26 22:42:30 +03:00
|
|
|
|
2016-08-14 00:01:31 +03:00
|
|
|
return editorFont
|
2016-07-26 22:42:30 +03:00
|
|
|
}
|
|
|
|
|
2016-09-25 18:50:33 +03:00
|
|
|
fileprivate func prefsDict(_ prefData: PrefData) -> [String: AnyObject] {
|
2016-08-14 16:38:41 +03:00
|
|
|
let generalData = prefData.general
|
2016-07-26 22:42:30 +03:00
|
|
|
let appearanceData = prefData.appearance
|
2016-09-24 17:31:14 +03:00
|
|
|
let advancedData = prefData.advanced
|
2016-08-14 16:38:41 +03:00
|
|
|
|
2016-07-26 22:42:30 +03:00
|
|
|
let prefs: [String: AnyObject] = [
|
2016-08-14 16:38:41 +03:00
|
|
|
// General
|
2016-09-25 18:50:33 +03:00
|
|
|
PrefKeys.openNewWindowWhenLaunching: generalData.openNewWindowWhenLaunching as AnyObject,
|
|
|
|
PrefKeys.openNewWindowOnReactivation: generalData.openNewWindowOnReactivation as AnyObject,
|
|
|
|
PrefKeys.openQuicklyIgnorePatterns: PrefUtils.ignorePatternString(fromSet: generalData.ignorePatterns) as AnyObject,
|
2016-08-14 16:38:41 +03:00
|
|
|
|
|
|
|
// Appearance
|
2016-09-25 18:50:33 +03:00
|
|
|
PrefKeys.editorFontName: appearanceData.editorFont.fontName as AnyObject,
|
|
|
|
PrefKeys.editorFontSize: appearanceData.editorFont.pointSize as AnyObject,
|
|
|
|
PrefKeys.editorUsesLigatures: appearanceData.editorUsesLigatures as AnyObject,
|
2016-09-24 17:31:14 +03:00
|
|
|
|
|
|
|
// Advanced
|
2016-09-25 18:50:33 +03:00
|
|
|
PrefKeys.useInteractiveZsh: advancedData.useInteractiveZsh as AnyObject,
|
2016-07-26 22:42:30 +03:00
|
|
|
]
|
2016-08-14 16:38:41 +03:00
|
|
|
|
2016-07-26 22:42:30 +03:00
|
|
|
return prefs
|
|
|
|
}
|
|
|
|
|
2016-09-25 18:50:33 +03:00
|
|
|
fileprivate func addReactions() {
|
2016-07-26 22:42:30 +03:00
|
|
|
self.source
|
|
|
|
.filter { $0 is PrefData }
|
|
|
|
.map { $0 as! PrefData }
|
2016-09-25 19:10:07 +03:00
|
|
|
.subscribe(onNext: { [unowned self] prefData in
|
2016-07-26 22:42:30 +03:00
|
|
|
self.data = prefData
|
|
|
|
self.userDefaults.setValue(self.prefsDict(prefData), forKey: PrefStore.compatibleVersion)
|
|
|
|
self.subject.onNext(prefData)
|
2016-09-25 19:10:07 +03:00
|
|
|
})
|
2016-07-26 22:42:30 +03:00
|
|
|
.addDisposableTo(self.disposeBag)
|
|
|
|
}
|
|
|
|
}
|