diff --git a/src/Models/NumericSort.cs b/src/Models/NumericSort.cs new file mode 100644 index 00000000..052f538b --- /dev/null +++ b/src/Models/NumericSort.cs @@ -0,0 +1,72 @@ +namespace SourceGit.Models +{ + public static class NumericSort + { + public static int Compare(string s1, string s2) + { + int len1 = s1.Length; + int len2 = s2.Length; + + int marker1 = 0; + int marker2 = 0; + + while (marker1 < len1 && marker2 < len2) + { + char c1 = s1[marker1]; + char c2 = s2[marker2]; + + char[] space1 = new char[len1]; + char[] space2 = new char[len2]; + + int loc1 = 0; + int loc2 = 0; + + bool isDigit1 = char.IsDigit(c1); + do + { + space1[loc1] = c1; + loc1++; + marker1++; + + if (marker1 < len1) + c1 = s1[marker1]; + else + break; + } while (char.IsDigit(c1) == isDigit1); + + bool isDigit2 = char.IsDigit(c2); + do + { + space2[loc2] = c2; + loc2++; + marker2++; + + if (marker2 < len2) + c2 = s2[marker2]; + else + break; + } while (char.IsDigit(c2) == isDigit2); + + string sub1 = new string(space1, 0, loc1); + string sub2 = new string(space2, 0, loc2); + + int result; + if (isDigit1 && isDigit2) + { + int num1 = int.Parse(sub1); + int num2 = int.Parse(sub2); + result = num1 - num2; + } + else + { + result = string.Compare(sub1, sub2, System.StringComparison.Ordinal); + } + + if (result != 0) + return result; + } + + return len1 - len2; + } + } +} diff --git a/src/ViewModels/BranchTreeNode.cs b/src/ViewModels/BranchTreeNode.cs index cf04784e..7616e7c4 100644 --- a/src/ViewModels/BranchTreeNode.cs +++ b/src/ViewModels/BranchTreeNode.cs @@ -194,9 +194,9 @@ namespace SourceGit.ViewModels return -1; if (l.Backend is Models.Branch) - return r.Backend is Models.Branch ? string.Compare(l.Name, r.Name, StringComparison.Ordinal) : 1; + return r.Backend is Models.Branch ? Models.NumericSort.Compare(l.Name, r.Name) : 1; - return r.Backend is Models.Branch ? -1 : string.Compare(l.Name, r.Name, StringComparison.Ordinal); + return r.Backend is Models.Branch ? -1 : Models.NumericSort.Compare(l.Name, r.Name); }); foreach (var node in nodes) diff --git a/src/ViewModels/ChangeTreeNode.cs b/src/ViewModels/ChangeTreeNode.cs index 49494b2b..bb6944b0 100644 --- a/src/ViewModels/ChangeTreeNode.cs +++ b/src/ViewModels/ChangeTreeNode.cs @@ -114,9 +114,9 @@ namespace SourceGit.ViewModels nodes.Sort((l, r) => { - if (l.IsFolder) - return r.IsFolder ? string.Compare(l.FullPath, r.FullPath, StringComparison.Ordinal) : -1; - return r.IsFolder ? 1 : string.Compare(l.FullPath, r.FullPath, StringComparison.Ordinal); + if (l.IsFolder == r.IsFolder) + return Models.NumericSort.Compare(l.FullPath, r.FullPath); + return r.IsFolder ? -1 : 1; }); } diff --git a/src/Views/RevisionFileTreeView.axaml.cs b/src/Views/RevisionFileTreeView.axaml.cs index a6e8df41..e198f6f0 100644 --- a/src/Views/RevisionFileTreeView.axaml.cs +++ b/src/Views/RevisionFileTreeView.axaml.cs @@ -284,7 +284,7 @@ namespace SourceGit.Views node.Children.Sort((l, r) => { if (l.IsFolder == r.IsFolder) - return string.Compare(l.Name, r.Name, StringComparison.Ordinal); + return Models.NumericSort.Compare(l.Name, r.Name); return l.IsFolder ? -1 : 1; });