@@ -8,15 +8,6 @@ extension PseudoTerminal {
88 return mutableTabGroups as! [ iTermTabGroup ]
99 }
1010
11- private var mutableTabGroups : NSMutableArray {
12- if let existing = objc_getAssociatedObject ( self , & AssociatedKeys. tabGroups) as? NSMutableArray {
13- return existing
14- }
15- let array = NSMutableArray ( )
16- objc_setAssociatedObject ( self , & AssociatedKeys. tabGroups, array, . OBJC_ASSOCIATION_RETAIN_NONATOMIC)
17- return array
18- }
19-
2011 @objc @discardableResult
2112 func createTabGroup( name: String , color: NSColor , forTab tab: PTYTab ) -> iTermTabGroup {
2213 let group = iTermTabGroup ( name: name, color: color)
@@ -45,13 +36,31 @@ extension PseudoTerminal {
4536
4637 @objc func deleteTabGroup( _ group: iTermTabGroup ) {
4738 if group. isCollapsed {
48- toggleCollapseGroup ( group)
39+ unstashItems ( for : group)
4940 }
5041 group. memberTabIDs. removeAll ( )
5142 mutableTabGroups. remove ( group)
5243 updateTabGroupDecorations ( )
5344 }
5445
46+ private func unstashItems( for group: iTermTabGroup ) {
47+ guard let representativeID = group. memberTabIDs. first,
48+ let representativeTab = tabs ( ) ? . first ( where: { Int ( $0. uniqueId) == representativeID } ) ,
49+ let representativeItem = representativeTab. tabViewItem else { return }
50+
51+ let tabView = contentView. tabView
52+ let baseIndex = tabView. indexOfTabViewItem ( representativeItem)
53+ guard baseIndex != NSNotFound else { return }
54+
55+ for (offset, item) in group. stashedTabViewItems. enumerated ( ) {
56+ let targetIndex = baseIndex + 1 + offset
57+ let safeIndex = min ( targetIndex, tabView. numberOfTabViewItems)
58+ tabView. insertTabViewItem ( item, at: safeIndex)
59+ }
60+ group. stashedTabViewItems. removeAll ( )
61+ group. isCollapsed = false
62+ }
63+
5564 @objc func toggleCollapseGroup( _ group: iTermTabGroup ) {
5665 if group. isCollapsed {
5766 expandGroup ( group)
@@ -104,18 +113,20 @@ extension PseudoTerminal {
104113 }
105114
106115 @objc func encodeTabGroupsForArrangement( ) -> [ [ String : Any ] ] {
107- return tabGroups. map { $0. toDictionary ( ) }
116+ let allTabs = tabs ( ) ?? [ ]
117+ return tabGroups. map { $0. toDictionary ( allTabs: allTabs) }
108118 }
109119
110120 @objc func restoreTabGroupsFromArrangement( _ arrangement: [ [ String : Any ] ] ) {
111- let allTabs = tabs ( )
121+ let allTabs = tabs ( ) ?? [ ]
112122 for dict in arrangement {
113123 guard let group = iTermTabGroup ( dictionary: dict) else { continue }
114- let validIDs = group. memberTabIDs. filter { id in
115- allTabs. contains { Int ( $0. uniqueId) == id }
124+ let resolvedIDs = group. memberTabIDs. compactMap { index -> Int ? in
125+ guard index >= 0 , index < allTabs. count else { return nil }
126+ return Int ( allTabs [ index] . uniqueId)
116127 }
117- guard !validIDs . isEmpty else { continue }
118- group. memberTabIDs = validIDs
128+ guard !resolvedIDs . isEmpty else { continue }
129+ group. memberTabIDs = resolvedIDs
119130 mutableTabGroups. add ( group)
120131 }
121132 updateTabGroupDecorations ( )
@@ -168,7 +179,7 @@ extension PseudoTerminal {
168179 }
169180
170181 private func collapseGroup( _ group: iTermTabGroup ) {
171- let allTabs = tabs ( )
182+ let allTabs = tabs ( ) ?? [ ]
172183 let memberTabs = group. memberTabIDs. compactMap { id in allTabs. first { Int ( $0. uniqueId) == id } }
173184 guard let representative = memberTabs. first else { return }
174185
@@ -189,7 +200,7 @@ extension PseudoTerminal {
189200
190201 private func expandGroup( _ group: iTermTabGroup ) {
191202 guard let representativeID = group. memberTabIDs. first,
192- let representativeTab = tabs ( ) . first ( where: { Int ( $0. uniqueId) == representativeID } ) ,
203+ let representativeTab = ( tabs ( ) ?? [ ] ) . first ( where: { Int ( $0. uniqueId) == representativeID } ) ,
193204 let representativeItem = representativeTab. tabViewItem else { return }
194205
195206 let tabView = contentView. tabView
@@ -208,7 +219,7 @@ extension PseudoTerminal {
208219
209220 private func enforceContiguity( of group: iTermTabGroup ) {
210221 guard group. memberTabIDs. count > 1 else { return }
211- let allTabs = tabs ( )
222+ let allTabs = tabs ( ) ?? [ ]
212223 let memberTabs = group. memberTabIDs. compactMap { id in allTabs. first { Int ( $0. uniqueId) == id } }
213224 guard let representativeItem = memberTabs. first? . tabViewItem else { return }
214225
@@ -228,7 +239,3 @@ extension PseudoTerminal {
228239 }
229240 }
230241}
231-
232- private enum AssociatedKeys {
233- static var tabGroups = " iTermTabGroupsKey "
234- }
0 commit comments