mirror of
https://github.com/coteditor/CotEditor.git
synced 2024-08-16 14:50:30 +03:00
Merge branch 'main' into 4.9.0
This commit is contained in:
commit
4fe75d48b9
@ -68,6 +68,7 @@ disabled_rules:
|
||||
- force_cast
|
||||
- force_try
|
||||
- opening_brace
|
||||
- static_over_final_class
|
||||
- switch_case_alignment
|
||||
- trailing_comma
|
||||
- unneeded_override
|
||||
|
@ -30,6 +30,10 @@
|
||||
4.8.6 (unreleased)
|
||||
--------------------------
|
||||
|
||||
### Fixes
|
||||
|
||||
- Fix a trivial memory leak in the line ending menu (thanks to Yoshimasa Niwa).
|
||||
|
||||
|
||||
|
||||
4.8.5 (653)
|
||||
|
@ -8,7 +8,7 @@
|
||||
//
|
||||
// ---------------------------------------------------------------------------
|
||||
//
|
||||
// © 2016-2023 1024jp
|
||||
// © 2016-2024 1024jp
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
@ -31,7 +31,7 @@ extension DispatchQueue {
|
||||
/// Synchronously but thread-safely invokes passed-in block on main thread to avoid deadlock.
|
||||
///
|
||||
/// - Parameter block: The block that contains the work to perform.
|
||||
final class func syncOnMain(execute block: () -> Void) {
|
||||
static func syncOnMain(execute block: () -> Void) {
|
||||
|
||||
if Thread.isMainThread {
|
||||
block()
|
||||
@ -46,7 +46,7 @@ extension DispatchQueue {
|
||||
///
|
||||
/// - Parameter work: The work item containing the work to perform.
|
||||
/// - Returns: The return value of the item in the work parameter.
|
||||
final class func syncOnMain<T>(execute work: () throws -> T) rethrows -> T {
|
||||
static func syncOnMain<T>(execute work: () throws -> T) rethrows -> T {
|
||||
|
||||
if Thread.isMainThread {
|
||||
try work()
|
||||
|
@ -398,6 +398,8 @@ final class DocumentViewController: NSSplitViewController, ThemeChanging, NSTool
|
||||
/// Invoked when the text was edited (invoked right **before** notifying layout managers).
|
||||
override func textStorageDidProcessEditing(_ notification: Notification) {
|
||||
|
||||
assert(Thread.isMainThread)
|
||||
|
||||
let textStorage = notification.object as! NSTextStorage
|
||||
|
||||
guard
|
||||
|
@ -274,7 +274,7 @@ final class KeyBindingManager {
|
||||
///
|
||||
/// - Parameter menu: The menu where to collect key bindings.
|
||||
/// - Returns: An array of KeyBindings.
|
||||
private class func scanKeyBindings(in menu: NSMenu) -> [KeyBinding] {
|
||||
private static func scanKeyBindings(in menu: NSMenu) -> [KeyBinding] {
|
||||
|
||||
menu.items
|
||||
.filter(Self.allowsModifying)
|
||||
|
@ -8,7 +8,7 @@
|
||||
//
|
||||
// ---------------------------------------------------------------------------
|
||||
//
|
||||
// © 2022-2023 1024jp
|
||||
// © 2022-2024 1024jp
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
@ -59,9 +59,11 @@ final class OptionalMenu: NSMenu, NSMenuDelegate {
|
||||
func menuWillOpen(_ menu: NSMenu) {
|
||||
|
||||
self.update() // UI validation is performed here
|
||||
self.validateKeyEvent(force: true)
|
||||
self.validateKeyEvent(forcibly: true)
|
||||
|
||||
let timer = Timer.scheduledTimer(timeInterval: 0.1, target: self, selector: #selector(validateKeyEvent), userInfo: nil, repeats: true)
|
||||
let timer = Timer.scheduledTimer(withTimeInterval: 0.1, repeats: true) { [weak self] _ in
|
||||
self?.validateKeyEvent()
|
||||
}
|
||||
RunLoop.current.add(timer, forMode: .eventTracking)
|
||||
self.trackingTimer = timer
|
||||
}
|
||||
@ -78,12 +80,12 @@ final class OptionalMenu: NSMenu, NSMenuDelegate {
|
||||
|
||||
/// Checks the state of the modifier key press and update the item visibility.
|
||||
///
|
||||
/// - Parameter force: Whether forcing to update the item visibility.
|
||||
@objc private func validateKeyEvent(force: Bool = false) {
|
||||
/// - Parameter forcibly: Whether forcing to update the item visibility.
|
||||
@objc private func validateKeyEvent(forcibly: Bool = false) {
|
||||
|
||||
let shows = NSEvent.modifierFlags.contains(.option)
|
||||
|
||||
guard force || shows != self.isShowingOptionalItems else { return }
|
||||
guard forcibly || shows != self.isShowingOptionalItems else { return }
|
||||
|
||||
self.updateOptionalItems(shows: shows)
|
||||
}
|
||||
|
@ -480,7 +480,7 @@ private extension PrintInfoType {
|
||||
|
||||
let item = NSMenuItem()
|
||||
item.title = self.label
|
||||
item.tag = Self.allCases.enumerated().first { $0.element == self }?.offset ?? 0
|
||||
item.tag = Self.allCases.firstIndex(of: self) ?? 0
|
||||
return item
|
||||
}
|
||||
}
|
||||
|
@ -121,7 +121,7 @@ enum UnicodeNormalizationForm: String, CaseIterable {
|
||||
/// Unique identifier for menu item.
|
||||
var tag: Int {
|
||||
|
||||
Self.allCases.enumerated().first { $0.element == self }!.offset
|
||||
Self.allCases.firstIndex(of: self)!
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -64,7 +64,7 @@ struct SyntaxEditView: View {
|
||||
weak var parent: NSHostingController<Self>?
|
||||
|
||||
|
||||
@MainActor private static var viewSize = CGSize(width: 680, height: 500)
|
||||
@MainActor private static var viewSize = CGSize(width: 680, height: 525)
|
||||
|
||||
@State private var name: String = ""
|
||||
@State private var message: String?
|
||||
@ -184,7 +184,7 @@ struct SyntaxEditView: View {
|
||||
}
|
||||
}
|
||||
}
|
||||
.frame(idealWidth: Self.viewSize.width, minHeight: 500, idealHeight: Self.viewSize.height)
|
||||
.frame(idealWidth: Self.viewSize.width, minHeight: 525, idealHeight: Self.viewSize.height)
|
||||
}
|
||||
|
||||
|
||||
|
@ -98,7 +98,7 @@ actor UserUnixTask {
|
||||
|
||||
async let data = buffer.reduce(into: Data()) { $0 += $1 }
|
||||
|
||||
return String(data: await data, encoding: .utf8)
|
||||
return String(decoding: await data, as: UTF8.self)
|
||||
}
|
||||
}
|
||||
|
||||
@ -106,13 +106,11 @@ actor UserUnixTask {
|
||||
/// The standard error.
|
||||
var error: String? {
|
||||
|
||||
guard
|
||||
let data = try? self.errorPipe.fileHandleForReading.readToEnd(),
|
||||
let string = String(data: data, encoding: .utf8),
|
||||
!string.isEmpty
|
||||
else { return nil }
|
||||
guard let data = try? self.errorPipe.fileHandleForReading.readToEnd() else { return nil }
|
||||
|
||||
return string
|
||||
let string = String(decoding: data, as: UTF8.self)
|
||||
|
||||
return string.isEmpty ? nil : string
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -37,7 +37,7 @@ final class EncodingDetectionTests: XCTestCase {
|
||||
// -> String(data:encoding:) preserves BOM since Swift 5 (2019-03)
|
||||
// cf. https://bugs.swift.org/browse/SR-10173
|
||||
let data = try self.dataForFileName("UTF-8 BOM")
|
||||
XCTAssertEqual(String(data: data, encoding: .utf8), "\u{FEFF}0")
|
||||
XCTAssertEqual(String(decoding: data, as: UTF8.self), "\u{FEFF}0")
|
||||
XCTAssertEqual(String(bomCapableData: data, encoding: .utf8), "0")
|
||||
|
||||
var encoding: String.Encoding?
|
||||
|
Loading…
Reference in New Issue
Block a user