Skip to content

Commit 9dd6e93

Browse files
committed
fix(inspector): split CSV columns in one pass and keep column layout in sync
1 parent a66a661 commit 9dd6e93

2 files changed

Lines changed: 26 additions & 4 deletions

File tree

Plugins/CSVInspectorPlugin/CSVRowStore.swift

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -284,19 +284,22 @@ final class CSVRowStore {
284284
func splitColumn(at index: Int, spec: SplitSpec) {
285285
guard index >= 0, index < columnNames.count else { return }
286286
let baseName = columnNames[index]
287+
var rowCells: [[String]] = []
287288
var pieceRows: [[String]] = []
289+
rowCells.reserveCapacity(logicalRows.count)
288290
pieceRows.reserveCapacity(logicalRows.count)
289291
var pieceCount = 1
290292
for row in logicalRows.indices {
291293
let cells = cells(forRow: row)
292294
let value = index < cells.count ? cells[index] : ""
293295
let pieces = Self.split(value, spec: spec)
294296
pieceCount = max(pieceCount, pieces.count)
297+
rowCells.append(cells)
295298
pieceRows.append(pieces)
296299
}
297300
let newNames = (0..<pieceCount).map { "\(baseName) \($0 + 1)" }
298301
for row in logicalRows.indices {
299-
var cells = cells(forRow: row)
302+
var cells = rowCells[row]
300303
let pieces = pieceRows[row]
301304
let padded = (0..<pieceCount).map { $0 < pieces.count ? pieces[$0] : "" }
302305
if index < cells.count { cells.remove(at: index) }

TablePro/Views/Inspector/InspectorViewController.swift

Lines changed: 22 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -432,8 +432,10 @@ final class InspectorViewController: NSViewController, NSUserInterfaceValidation
432432
alert.accessoryView = accessoryStack(with: [field])
433433

434434
alert.beginSheetModal(for: window) { [weak self] response in
435-
guard response == .alertFirstButtonReturn else { return }
436-
self?.inspectorDocument?.mergeColumns(at: column, separator: field.stringValue)
435+
guard response == .alertFirstButtonReturn, let self, let inspector = self.inspectorDocument else { return }
436+
let removedName = column + 1 < inspector.columnNames.count ? inspector.columnNames[column + 1] : nil
437+
inspector.mergeColumns(at: column, separator: field.stringValue)
438+
if let removedName { self.removeLayoutKey(removedName) }
437439
}
438440
DispatchQueue.main.async { alert.window.makeFirstResponder(field) }
439441
}
@@ -444,7 +446,15 @@ final class InspectorViewController: NSViewController, NSUserInterfaceValidation
444446
presentInvalidPattern()
445447
return
446448
}
447-
inspectorDocument?.splitColumn(at: column, separator: separator, isRegex: isRegex)
449+
guard let inspector = inspectorDocument else { return }
450+
let oldName = column < inspector.columnNames.count ? inspector.columnNames[column] : nil
451+
let oldCount = inspector.columnNames.count
452+
inspector.splitColumn(at: column, separator: separator, isRegex: isRegex)
453+
guard let oldName else { return }
454+
let pieceCount = inspector.columnNames.count - oldCount + 1
455+
let upper = min(column + max(pieceCount, 0), inspector.columnNames.count)
456+
let newNames = column < upper ? Array(inspector.columnNames[column..<upper]) : []
457+
replaceLayoutKey(oldName, with: newNames)
448458
}
449459

450460
private func presentInvalidPattern() {
@@ -521,6 +531,15 @@ final class InspectorViewController: NSViewController, NSUserInterfaceValidation
521531
state.columnLayout.columnOrder = order
522532
}
523533

534+
private func replaceLayoutKey(_ oldName: String, with newNames: [String]) {
535+
if var order = state.columnLayout.columnOrder, let position = order.firstIndex(of: oldName) {
536+
order.replaceSubrange(position...position, with: newNames)
537+
state.columnLayout.columnOrder = order
538+
}
539+
state.columnLayout.columnWidths.removeValue(forKey: oldName)
540+
state.columnLayout.hiddenColumns.remove(oldName)
541+
}
542+
524543
private func promptForColumnName(
525544
title: String,
526545
initial: String,

0 commit comments

Comments
 (0)