Skip to content

Commit

Permalink
Refactor ScriptManager
Browse files Browse the repository at this point in the history
  • Loading branch information
1024jp committed Mar 6, 2025
1 parent 46605e8 commit 1a62162
Show file tree
Hide file tree
Showing 2 changed files with 18 additions and 37 deletions.
4 changes: 1 addition & 3 deletions CotEditor/Sources/Application/AppDelegate.swift
Original file line number Diff line number Diff line change
Expand Up @@ -204,7 +204,7 @@ private enum BundleIdentifier {

SnippetManager.shared.menu = self.snippetMenu!

ScriptManager.shared.observeScriptsDirectory()
ScriptManager.shared.menu = NSApp.mainMenu?.item(at: MainMenu.script.rawValue)?.submenu

// build Unicode normalization menu items
self.normalizationMenu?.items = (UnicodeNormalizationForm.standardForms + [nil] +
Expand Down Expand Up @@ -290,8 +290,6 @@ private enum BundleIdentifier {

func applicationWillTerminate(_ notification: Notification) {

ScriptManager.shared.cancelScriptsDirectoryObservation()

if self.needsRelaunch {
NSApp.relaunch()
}
Expand Down
51 changes: 17 additions & 34 deletions CotEditor/Sources/Setting Managers/ScriptManager.swift
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ final class ScriptManager: NSObject, NSFilePresenter, @unchecked Sendable {

static let shared = ScriptManager()

@MainActor var menu: NSMenu? { didSet { Task { await self.updateMenu() } } }
@MainActor private(set) var currentScriptName: String?


Expand Down Expand Up @@ -68,9 +69,11 @@ final class ScriptManager: NSObject, NSFilePresenter, @unchecked Sendable {

super.init()

guard self.presentedItemURL != nil else { return }

NSFileCoordinator.addFilePresenter(self)

Task { @MainActor in
await self.buildScriptMenu()

let scopes = (DocumentController.shared as! DocumentController).$currentSyntaxName.values
for await scope in scopes where scope != self.scope {
self.scope = scope
Expand All @@ -80,6 +83,13 @@ final class ScriptManager: NSObject, NSFilePresenter, @unchecked Sendable {
}


deinit {
if self.presentedItemURL != nil {
NSFileCoordinator.removeFilePresenter(self)
}
}



// MARK: File Presenter Protocol

Expand All @@ -95,10 +105,10 @@ final class ScriptManager: NSObject, NSFilePresenter, @unchecked Sendable {
self.menuUpdateTask = Task {
if await NSApp.isActive {
try await Task.sleep(for: .seconds(0.2), tolerance: .seconds(0.1))
await self.buildScriptMenu()
await self.updateMenu()
} else {
for await _ in NotificationCenter.default.notifications(named: NSApplication.didBecomeActiveNotification) {
await self.buildScriptMenu()
await self.updateMenu()
return
}
}
Expand All @@ -109,26 +119,6 @@ final class ScriptManager: NSObject, NSFilePresenter, @unchecked Sendable {

// MARK: Public Methods

/// Starts observing the scripts directory.
///
/// This method should be called only once.
func observeScriptsDirectory() {

if self.presentedItemURL != nil {
NSFileCoordinator.addFilePresenter(self)
}
}


/// Stops the observation on the user scripts directory.
func cancelScriptsDirectoryObservation() {

if self.presentedItemURL != nil {
NSFileCoordinator.removeFilePresenter(self)
}
}


/// Dispatches an Apple event that notifies the given document was opened.
///
/// - Parameters:
Expand Down Expand Up @@ -200,15 +190,8 @@ final class ScriptManager: NSObject, NSFilePresenter, @unchecked Sendable {

// MARK: Private Methods

/// The Scripts menu in the main menu.
@MainActor private var scriptMenu: NSMenu? {

NSApp.mainMenu?.item(at: MainMenu.script.rawValue)?.submenu
}


/// Builds the Script menu and scan script handlers.
@MainActor private func buildScriptMenu() async {
@MainActor private func updateMenu() async {

self.menuUpdateTask?.cancel()
self.menuUpdateTask = nil
Expand All @@ -231,7 +214,7 @@ final class ScriptManager: NSObject, NSFilePresenter, @unchecked Sendable {
action: #selector(openScriptFolder), keyEquivalent: "")
openMenuItem.target = self

self.scriptMenu?.items = menuItems + [.separator(), openMenuItem]
self.menu?.items = menuItems + [.separator(), openMenuItem]
self.applyShortcuts()
}

Expand Down Expand Up @@ -312,7 +295,7 @@ final class ScriptManager: NSObject, NSFilePresenter, @unchecked Sendable {
/// Applies the keyboard shortcuts to the Script menu items.
@MainActor private func applyShortcuts() {
guard let menu = self.scriptMenu else { return assertionFailure() }
guard let menu else { return assertionFailure() }
// clear all shortcuts
menu.items.forEach { $0.removeAllShortcuts() }
Expand Down

0 comments on commit 1a62162

Please sign in to comment.