From 06869279c083951af25966e0f2389a31ebe3defb Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Wed, 1 Apr 2026 15:12:44 +0000 Subject: [PATCH 1/2] Add intelligent numeric vs. alphabetic column sorting Agent-Logs-Url: https://github.com/danaspiegel/TableTool/sessions/439bb429-ad07-41ab-bbaf-16f1b6482d82 Co-authored-by: danaspiegel <6631+danaspiegel@users.noreply.github.com> --- Table Tool/Document.m | 31 ++++++++++++++++++++++++++++--- 1 file changed, 28 insertions(+), 3 deletions(-) diff --git a/Table Tool/Document.m b/Table Tool/Document.m index 06a57ba..e4f77b9 100644 --- a/Table Tool/Document.m +++ b/Table Tool/Document.m @@ -1268,12 +1268,37 @@ -(void)tableView:(NSTableView *)tableView sortDescriptorsDidChange:(NSArray *)ol NSSortDescriptor *sd = tableView.sortDescriptors.firstObject; if (!sd) return; NSInteger colIndex = sd.key.integerValue; + + // Determine whether all non-empty values in the column are numeric so we + // can choose between a numeric and an alphabetic sort. + BOOL sortNumerically = YES; + for (NSMutableArray *row in _data) { + id val = colIndex < (NSInteger)row.count ? row[colIndex] : @""; + if ([val isKindOfClass:[NSDecimalNumber class]]) continue; + NSString *str = (NSString *)val; + if (str.length == 0) continue; + NSDecimalNumber *num = [NSDecimalNumber decimalNumberWithString:str]; + if ([num isEqual:[NSDecimalNumber notANumber]]) { + sortNumerically = NO; + break; + } + } + [_data sortUsingComparator:^NSComparisonResult(NSMutableArray *row1, NSMutableArray *row2) { id val1 = colIndex < (NSInteger)row1.count ? row1[colIndex] : @""; id val2 = colIndex < (NSInteger)row2.count ? row2[colIndex] : @""; - NSString *str1 = [val1 isKindOfClass:[NSDecimalNumber class]] ? [(NSDecimalNumber *)val1 description] : (NSString *)val1; - NSString *str2 = [val2 isKindOfClass:[NSDecimalNumber class]] ? [(NSDecimalNumber *)val2 description] : (NSString *)val2; - NSComparisonResult result = [str1 localizedCaseInsensitiveCompare:str2]; + NSComparisonResult result; + if (sortNumerically) { + NSDecimalNumber *num1 = [val1 isKindOfClass:[NSDecimalNumber class]] ? val1 : + ([(NSString *)val1 length] > 0 ? [NSDecimalNumber decimalNumberWithString:(NSString *)val1] : [NSDecimalNumber zero]); + NSDecimalNumber *num2 = [val2 isKindOfClass:[NSDecimalNumber class]] ? val2 : + ([(NSString *)val2 length] > 0 ? [NSDecimalNumber decimalNumberWithString:(NSString *)val2] : [NSDecimalNumber zero]); + result = [num1 compare:num2]; + } else { + NSString *str1 = [val1 isKindOfClass:[NSDecimalNumber class]] ? [(NSDecimalNumber *)val1 description] : (NSString *)val1; + NSString *str2 = [val2 isKindOfClass:[NSDecimalNumber class]] ? [(NSDecimalNumber *)val2 description] : (NSString *)val2; + result = [str1 localizedCaseInsensitiveCompare:str2]; + } return sd.ascending ? result : -result; }]; [self.tableView reloadData]; From a71d11fada7617930fc6d042d53d1d685d2842cb Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Wed, 1 Apr 2026 16:00:25 +0000 Subject: [PATCH 2/2] Use locale-aware decimal parsing in column sort (honour csvConfig.decimalMark) Agent-Logs-Url: https://github.com/danaspiegel/TableTool/sessions/782cff10-6a6d-4393-86ad-4f9d85454516 Co-authored-by: danaspiegel <6631+danaspiegel@users.noreply.github.com> --- Table Tool/Document.m | 19 +++++++++++++------ 1 file changed, 13 insertions(+), 6 deletions(-) diff --git a/Table Tool/Document.m b/Table Tool/Document.m index e4f77b9..b926e79 100644 --- a/Table Tool/Document.m +++ b/Table Tool/Document.m @@ -1269,6 +1269,14 @@ -(void)tableView:(NSTableView *)tableView sortDescriptorsDidChange:(NSArray *)ol if (!sd) return; NSInteger colIndex = sd.key.integerValue; + // Use the same regex the editor uses for numeric detection, so that the + // configured decimal separator (e.g. ',' for European locales) is honoured. + NSString *decimalMark = self.csvConfig.decimalMark; + NSDictionary *locale = @{NSLocaleDecimalSeparator: decimalMark}; + NSRegularExpression *numberRegex = [NSRegularExpression regularExpressionWithPattern: + [NSString stringWithFormat:@"^\\s*[+-]?(\\d+\\%@?\\d*|\\d*\\%@?\\d+)([eE][+-]?\\d+)?\\s*$", decimalMark, decimalMark] + options:0 error:NULL]; + // Determine whether all non-empty values in the column are numeric so we // can choose between a numeric and an alphabetic sort. BOOL sortNumerically = YES; @@ -1277,8 +1285,7 @@ -(void)tableView:(NSTableView *)tableView sortDescriptorsDidChange:(NSArray *)ol if ([val isKindOfClass:[NSDecimalNumber class]]) continue; NSString *str = (NSString *)val; if (str.length == 0) continue; - NSDecimalNumber *num = [NSDecimalNumber decimalNumberWithString:str]; - if ([num isEqual:[NSDecimalNumber notANumber]]) { + if ([numberRegex numberOfMatchesInString:str options:0 range:NSMakeRange(0, str.length)] != 1) { sortNumerically = NO; break; } @@ -1290,13 +1297,13 @@ -(void)tableView:(NSTableView *)tableView sortDescriptorsDidChange:(NSArray *)ol NSComparisonResult result; if (sortNumerically) { NSDecimalNumber *num1 = [val1 isKindOfClass:[NSDecimalNumber class]] ? val1 : - ([(NSString *)val1 length] > 0 ? [NSDecimalNumber decimalNumberWithString:(NSString *)val1] : [NSDecimalNumber zero]); + ([(NSString *)val1 length] > 0 ? [NSDecimalNumber decimalNumberWithString:(NSString *)val1 locale:locale] : [NSDecimalNumber zero]); NSDecimalNumber *num2 = [val2 isKindOfClass:[NSDecimalNumber class]] ? val2 : - ([(NSString *)val2 length] > 0 ? [NSDecimalNumber decimalNumberWithString:(NSString *)val2] : [NSDecimalNumber zero]); + ([(NSString *)val2 length] > 0 ? [NSDecimalNumber decimalNumberWithString:(NSString *)val2 locale:locale] : [NSDecimalNumber zero]); result = [num1 compare:num2]; } else { - NSString *str1 = [val1 isKindOfClass:[NSDecimalNumber class]] ? [(NSDecimalNumber *)val1 description] : (NSString *)val1; - NSString *str2 = [val2 isKindOfClass:[NSDecimalNumber class]] ? [(NSDecimalNumber *)val2 description] : (NSString *)val2; + NSString *str1 = [val1 isKindOfClass:[NSDecimalNumber class]] ? [(NSDecimalNumber *)val1 descriptionWithLocale:locale] : (NSString *)val1; + NSString *str2 = [val2 isKindOfClass:[NSDecimalNumber class]] ? [(NSDecimalNumber *)val2 descriptionWithLocale:locale] : (NSString *)val2; result = [str1 localizedCaseInsensitiveCompare:str2]; } return sd.ascending ? result : -result;