Skip to content

Commit 330c4c7

Browse files
macmadeclaude
andcommitted
refactor: Use a consistent ascending config sort and cache decoded configs
The menu rendered configurations ascending by name, but did so with a descending comparator combined with insert-at-zero, which read as the opposite of the configurations window's ascending sort descriptor. Sort ascending and insert the items as an ordered block so the comparator matches the window while the rendered order is unchanged. Cache the decoded configurations array in Preferences and invalidate it on the defaultsChanged distributed notification, instead of decoding the full plist on every access. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
1 parent abcb6a3 commit 330c4c7

2 files changed

Lines changed: 32 additions & 7 deletions

File tree

Shared/Preferences.swift

Lines changed: 23 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,10 @@ public class Preferences: NSObject
4646
return
4747
}
4848

49+
// A change elsewhere (or in another process) invalidates the cache
50+
// so the next read re-decodes the stored plist.
51+
self.cachedConfigurations = nil
52+
4953
self.willChangeValue( for: \.configurations )
5054
self.didChangeValue( for: \.configurations )
5155

@@ -54,23 +58,39 @@ public class Preferences: NSObject
5458
}
5559
}
5660

61+
private var cachedConfigurations: [ Configuration ]?
62+
5763
@objc public dynamic var configurations: [ Configuration ]
5864
{
5965
get
6066
{
67+
if let cached = self.cachedConfigurations
68+
{
69+
return cached
70+
}
71+
72+
let decoded: [ Configuration ]
73+
6174
if let data = self.defaults?.object( forKey: "configurations" ) as? Data,
62-
let decoded = try? PropertyListDecoder().decode( [ Configuration ].self, from: data )
75+
let stored = try? PropertyListDecoder().decode( [ Configuration ].self, from: data )
6376
{
64-
return decoded
77+
decoded = stored
6578
}
79+
else
80+
{
81+
decoded = []
82+
}
83+
84+
self.cachedConfigurations = decoded
6685

67-
return []
86+
return decoded
6887
}
6988

7089
set( value )
7190
{
7291
if let data = try? PropertyListEncoder().encode( value )
7392
{
93+
self.cachedConfigurations = value
7494
self.defaults?.setValue( data, forKey: "configurations" )
7595
DistributedNotificationCenter.default().post( name: Preferences.defaultsChanged, object: nil )
7696
}

XcodeFormat/Classes/ApplicationDelegate.swift

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -175,11 +175,14 @@ public class ApplicationDelegate: NSObject, NSApplicationDelegate
175175
let imageOn = image?.withSymbolConfiguration( NSImage.SymbolConfiguration( hierarchicalColor: colorOn ) )
176176
let imageOff = image?.withSymbolConfiguration( NSImage.SymbolConfiguration( hierarchicalColor: colorOff ) )
177177

178-
Preferences.shared.configurations.sorted
178+
// Ascending by name, matching the configurations window's sort. The
179+
// items are inserted as a block at the top so the rendered order is the
180+
// ascending sort order.
181+
let configurationItems: [ NSMenuItem ] = Preferences.shared.configurations.sorted
179182
{
180-
$0.name > $1.name
183+
$0.name < $1.name
181184
}
182-
.forEach
185+
.map
183186
{
184187
let item = NSMenuItem( title: $0.name, action: #selector( self.selectConfiguration( _: ) ), keyEquivalent: "" )
185188
item.target = self
@@ -198,9 +201,11 @@ public class ApplicationDelegate: NSObject, NSApplicationDelegate
198201
item.attributedTitle = NSAttributedString( string: item.title, attributes: [ .font: fontOff, .foregroundColor: colorOff ] )
199202
}
200203

201-
items.insert( item, at: 0 )
204+
return item
202205
}
203206

207+
items.insert( contentsOf: configurationItems, at: 0 )
208+
204209
self.menu.items = items
205210
}
206211

0 commit comments

Comments
 (0)