diff --git a/CHANGELOG.md b/CHANGELOG.md
index 5fcce16e9c..fbd503e3c8 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -11,6 +11,15 @@ develop
+3.1.5
+--------------------------
+
+### Fixes
+
+- Fix an issue where the application could crash by auto-completion on OS X 10.10.
+
+
+
3.1.4 (182)
--------------------------
diff --git a/CotEditor/CotEditor -AppStore-Info.plist b/CotEditor/CotEditor -AppStore-Info.plist
index 36f51756b9..b2781396b8 100644
--- a/CotEditor/CotEditor -AppStore-Info.plist
+++ b/CotEditor/CotEditor -AppStore-Info.plist
@@ -945,11 +945,11 @@
CFBundlePackageType
APPL
CFBundleShortVersionString
- 3.1.4
+ 3.1.5
CFBundleSignature
cEd1
CFBundleVersion
- 182
+ 184
LSApplicationCategoryType
public.app-category.productivity
LSMinimumSystemVersion
diff --git a/CotEditor/CotEditor-Info.plist b/CotEditor/CotEditor-Info.plist
index 1e02acd343..94d4930ff5 100644
--- a/CotEditor/CotEditor-Info.plist
+++ b/CotEditor/CotEditor-Info.plist
@@ -945,11 +945,11 @@
CFBundlePackageType
APPL
CFBundleShortVersionString
- 3.1.4
+ 3.1.5
CFBundleSignature
cEd1
CFBundleVersion
- 182
+ 184
LSApplicationCategoryType
public.app-category.productivity
LSMinimumSystemVersion
diff --git a/CotEditor/CotEditor.help/Contents/Resources/en.lproj/pgs/releasenotes.html b/CotEditor/CotEditor.help/Contents/Resources/en.lproj/pgs/releasenotes.html
index 1fd69928a9..0e4641f04a 100644
--- a/CotEditor/CotEditor.help/Contents/Resources/en.lproj/pgs/releasenotes.html
+++ b/CotEditor/CotEditor.help/Contents/Resources/en.lproj/pgs/releasenotes.html
@@ -22,16 +22,27 @@
Release Notes
-
+
+
+ CotEditor 3.1.5
+ release:
+
+
+
+
+Fixes
+
+
+ - Fix an issue where the application could crash by auto-completion on OS X 10.10.
+
+
+
CotEditor 3.1.4
- release:
+ release:
diff --git a/CotEditor/CotEditor.help/Contents/Resources/ja.lproj/pgs/releasenotes.html b/CotEditor/CotEditor.help/Contents/Resources/ja.lproj/pgs/releasenotes.html
index 595680c302..466e3f223b 100644
--- a/CotEditor/CotEditor.help/Contents/Resources/ja.lproj/pgs/releasenotes.html
+++ b/CotEditor/CotEditor.help/Contents/Resources/ja.lproj/pgs/releasenotes.html
@@ -24,11 +24,28 @@ リリースノート
- CotEditor 3.1.4
+ CotEditor 3.1.5
リリース:
+
+修正
+
+
+ - OS X 10.10 で自動補完をするとアプリケーションアイコンがクラッシュすることがある不具合を修正
+
+
+
+
+
+
+
+ CotEditor 3.1.4
+ リリース:
+
+
+
新機能
diff --git a/CotEditor/Sources/EditorTextView.swift b/CotEditor/Sources/EditorTextView.swift
index b400af7b5c..686a32ae3c 100644
--- a/CotEditor/Sources/EditorTextView.swift
+++ b/CotEditor/Sources/EditorTextView.swift
@@ -67,7 +67,9 @@ final class EditorTextView: NSTextView, Themable {
var initialMagnificationScale: CGFloat = 0
var deferredMagnification: CGFloat = 0
- private(set) lazy var completionTask: Debouncer = Debouncer { [weak self] in self?.performCompletion() }
+ private(set) lazy var completionTask: Debouncer = Debouncer { [weak container = self.textContainer] in // NSTextView cannot be weak
+ (container?.textView as? EditorTextView)?.performCompletion()
+ }
// MARK: Private Properties
diff --git a/CotEditor/Sources/SyntaxManager.swift b/CotEditor/Sources/SyntaxManager.swift
index 5ccd4073c1..0be05d7b2e 100644
--- a/CotEditor/Sources/SyntaxManager.swift
+++ b/CotEditor/Sources/SyntaxManager.swift
@@ -256,7 +256,7 @@ final class SyntaxManager: SettingFileManager {
// load from file
if let url = self.urlForUsedSetting(name: name),
- let style = self.styleDictionary(fileURL: url) {
+ let style = try? self.styleDictionary(fileURL: url) {
// store newly loaded style
self.styleCaches[name] = style
@@ -273,7 +273,7 @@ final class SyntaxManager: SettingFileManager {
guard let url = self.urlForBundledSetting(name: name) else { return nil }
- return self.styleDictionary(fileURL: url)
+ return try? self.styleDictionary(fileURL: url)
}
@@ -412,15 +412,21 @@ final class SyntaxManager: SettingFileManager {
// MARK: Private Methods
- /// return style dictionary at file URL
- private func styleDictionary(fileURL: URL) -> StyleDictionary? {
+ /// Return style dictionary at file URL.
+ ///
+ /// - parameter fileURL: URL to a style file.
+ /// - throws: CocoaError
+ private func styleDictionary(fileURL: URL) throws -> StyleDictionary {
- guard
- let yamlData = try? Data(contentsOf: fileURL),
- let yaml = try? YAMLSerialization.object(withYAMLData: yamlData,
- options: kYAMLReadOptionMutableContainersAndLeaves) else { return nil }
+ let yamlData = try Data(contentsOf: fileURL)
+ let yaml = try YAMLSerialization.object(withYAMLData: yamlData,
+ options: kYAMLReadOptionMutableContainersAndLeaves)
+
+ guard let styleDictionary = yaml as? StyleDictionary else {
+ throw CocoaError(.fileReadCorruptFile)
+ }
- return yaml as? StyleDictionary
+ return styleDictionary
}
@@ -459,14 +465,14 @@ final class SyntaxManager: SettingFileManager {
let directoryURL = self.userSettingDirectoryURL
var map = self.bundledMap
- // load user styles
+ // load user styles if exists
if let enumerator = FileManager.default.enumerator(at: directoryURL, includingPropertiesForKeys: nil,
options: [.skipsSubdirectoryDescendants, .skipsHiddenFiles]) {
for case let url as URL in enumerator {
guard [self.filePathExtension, "yml"].contains(url.pathExtension) else { continue }
+ guard let style = try? self.styleDictionary(fileURL: url) else { continue }
let styleName = self.settingName(from: url)
- guard let style = self.styleDictionary(fileURL: url) else { continue }
map[styleName] = [SyntaxKey.extensions.rawValue: type(of: self).keyStrings(in: style, key: .extensions),
SyntaxKey.filenames.rawValue: type(of: self).keyStrings(in: style, key: .filenames),
diff --git a/CotEditor/Sources/ThemeManager.swift b/CotEditor/Sources/ThemeManager.swift
index 0829625f87..d971f0424e 100644
--- a/CotEditor/Sources/ThemeManager.swift
+++ b/CotEditor/Sources/ThemeManager.swift
@@ -9,7 +9,7 @@
------------------------------------------------------------------------------
- © 2014-2016 1024jp
+ © 2014-2017 1024jp
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
@@ -246,12 +246,20 @@ final class ThemeManager: SettingFileManager {
// MARK: Private Methods
- /// create ThemeDictionary from a file at the URL
- private func themeDictionary(fileURL: URL) -> ThemeDictionary? {
+ /// Create ThemeDictionary from a file at the URL.
+ ///
+ /// - parameter fileURL: URL to a theme file.
+ /// - throws: CocoaError
+ private func themeDictionary(fileURL: URL) throws -> ThemeDictionary {
- guard let data = try? Data(contentsOf: fileURL) else { return nil }
+ let data = try Data(contentsOf: fileURL)
+ let json = try JSONSerialization.jsonObject(with: data, options: .mutableContainers)
- return (try? JSONSerialization.jsonObject(with: data, options: .mutableContainers)) as? ThemeDictionary
+ guard let themeDictionry = json as? ThemeDictionary else {
+ throw CocoaError(.fileReadCorruptFile)
+ }
+
+ return themeDictionry
}
@@ -265,9 +273,8 @@ final class ThemeManager: SettingFileManager {
let themeNameSet = NSMutableOrderedSet(array: strongSelf.bundledThemeNames)
// load user themes if exists
- if userDirURL.isReachable {
- let fileURLs = (try? FileManager.default.contentsOfDirectory(at: userDirURL, includingPropertiesForKeys: nil,
- options: [.skipsSubdirectoryDescendants, .skipsHiddenFiles])) ?? []
+ if let fileURLs = try? FileManager.default.contentsOfDirectory(at: userDirURL, includingPropertiesForKeys: nil,
+ options: [.skipsSubdirectoryDescendants, .skipsHiddenFiles]) {
let userThemeNames = fileURLs
.filter { $0.pathExtension == strongSelf.filePathExtension }
.map { strongSelf.settingName(from: $0) }
@@ -280,10 +287,13 @@ final class ThemeManager: SettingFileManager {
// cache definitions
strongSelf.archivedThemes = (themeNameSet.array as! [String]).reduce([:]) { (dict, name) in
- guard let themeURL = strongSelf.urlForUsedSetting(name: name) else { return dict }
+ guard
+ let themeURL = strongSelf.urlForUsedSetting(name: name),
+ let themeDictionary = try? strongSelf.themeDictionary(fileURL: themeURL)
+ else { return dict }
var dict = dict
- dict[name] = strongSelf.themeDictionary(fileURL: themeURL)
+ dict[name] = themeDictionary
return dict
}
@@ -310,7 +320,7 @@ final class ThemeManager: SettingFileManager {
let url = self.urlForBundledSetting(name: "_Plain")!
- return self.themeDictionary(fileURL: url)!
+ return try! self.themeDictionary(fileURL: url)
}
}