Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion src/Commands/CompareRevisions.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
using System;
using System.Collections.Generic;
using System.Text.RegularExpressions;
using SourceGit.ViewModels;

namespace SourceGit.Commands
{
Expand Down Expand Up @@ -39,7 +40,8 @@ public CompareRevisions(string repo, string start, string end, string path)
foreach (var line in lines)
ParseLine(line);

_changes.Sort((l, r) => string.Compare(l.Path, r.Path, StringComparison.Ordinal));
_changes.Sort((l, r) => string.Compare(l.Path, r.Path,
Preferences.Instance.GetPreferredListComparisonType()));
return _changes;
}

Expand Down
2 changes: 2 additions & 0 deletions src/Commands/QueryLocalChanges.cs
Original file line number Diff line number Diff line change
Expand Up @@ -159,6 +159,8 @@ public QueryLocalChanges(string repo, bool includeUntracked = true)
outs.Add(change);
}

outs.Sort((l, r) => string.Compare(l.Path, r.Path,
ViewModels.Preferences.Instance.GetPreferredListComparisonType()));
return outs;
}
}
Expand Down
3 changes: 2 additions & 1 deletion src/Models/Commit.cs
Original file line number Diff line number Diff line change
Expand Up @@ -113,7 +113,8 @@ public void ParseDecorators(string data)
if (l.Type != r.Type)
return (int)l.Type - (int)r.Type;
else
return string.Compare(l.Name, r.Name, StringComparison.Ordinal);
return string.Compare(l.Name, r.Name,
ViewModels.Preferences.Instance.GetPreferredListComparisonType());
});
}
}
Expand Down
57 changes: 26 additions & 31 deletions src/Models/NumericSort.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
namespace SourceGit.Models
using System;

namespace SourceGit.Models
{
public static class NumericSort
{
Expand All @@ -10,58 +12,51 @@ public static int Compare(string s1, string s2)
int marker1 = 0;
int marker2 = 0;

char[] tmp1 = new char[len1];
char[] tmp2 = new char[len2];
char[] tmp = new char[Math.Max(len1, len2)];

while (marker1 < len1 && marker2 < len2)
{
char c1 = s1[marker1];
char c2 = s2[marker2];
int loc1 = 0;
int loc2 = 0;

bool isDigit1 = char.IsDigit(c1);
bool isDigit2 = char.IsDigit(c2);
if (isDigit1 != isDigit2)
return c1.CompareTo(c2);

do
{
tmp1[loc1] = c1;
loc1++;
marker1++;
int subLen1 = GetCoherentSubstringLength(s1, len1, marker1, isDigit1, ref tmp);
int subLen2 = GetCoherentSubstringLength(s2, len2, marker2, isDigit2, ref tmp);

if (marker1 < len1)
c1 = s1[marker1];
else
break;
} while (char.IsDigit(c1) == isDigit1);
string sub1 = s1.Substring(marker1, subLen1);
string sub2 = s2.Substring(marker2, subLen2);

do
{
tmp2[loc2] = c2;
loc2++;
marker2++;
marker1 += subLen1;
marker2 += subLen2;

if (marker2 < len2)
c2 = s2[marker2];
else
break;
} while (char.IsDigit(c2) == isDigit2);

string sub1 = new string(tmp1, 0, loc1);
string sub2 = new string(tmp2, 0, loc2);
int result;
if (isDigit1)
result = loc1 == loc2 ? string.CompareOrdinal(sub1, sub2) : loc1 - loc2;
{
// NOTE: We don't strip leading zeroes before comparing substring digits/lengths - should we?
result = (subLen1 == subLen2) ? string.CompareOrdinal(sub1, sub2) : (subLen1 - subLen2);
}
else
result = string.CompareOrdinal(sub1, sub2);

{
result = string.Compare(sub1, sub2,
ViewModels.Preferences.Instance.GetPreferredListComparisonType());
}
if (result != 0)
return result;
}

return len1 - len2;
}

private static int GetCoherentSubstringLength(string s, int len, int start, bool isDigit, ref char[] tmp)
{
int num = 1;
while (start + num < len && char.IsDigit(s[start + num]) == isDigit)
num++;
return num;
}
}
}
1 change: 1 addition & 0 deletions src/Resources/Locales/en_US.axaml
Original file line number Diff line number Diff line change
Expand Up @@ -491,6 +491,7 @@
<x:String x:Key="Text.Preferences.Appearance.OnlyUseMonoFontInEditor" xml:space="preserve">Use monospace font only in text editor</x:String>
<x:String x:Key="Text.Preferences.Appearance.Theme" xml:space="preserve">Theme</x:String>
<x:String x:Key="Text.Preferences.Appearance.ThemeOverrides" xml:space="preserve">Theme Overrides</x:String>
<x:String x:Key="Text.Preferences.Appearance.UseCaseInsensitiveSortingInLists" xml:space="preserve">Use case-insensitive sorting in lists</x:String>
<x:String x:Key="Text.Preferences.Appearance.UseFixedTabWidth" xml:space="preserve">Use fixed tab width in titlebar</x:String>
<x:String x:Key="Text.Preferences.Appearance.UseNativeWindowFrame" xml:space="preserve">Use native window frame</x:String>
<x:String x:Key="Text.Preferences.DiffMerge" xml:space="preserve">DIFF/MERGE TOOL</x:String>
Expand Down
23 changes: 22 additions & 1 deletion src/ViewModels/Preferences.cs
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,20 @@ public bool OnlyUseMonoFontInEditor
}
}

public bool UseCaseInsensitiveSortingInLists
{
get => _useCaseInsensitiveSortingInLists;
set
{
if (SetProperty(ref _useCaseInsensitiveSortingInLists, value) && !_isLoading)
{
var launcher = App.GetLauncher();
if (launcher.ActivePage.Data is ViewModels.Repository repo)
repo.RefreshAll();
}
}
}

public bool UseSystemWindowFrame
{
get => Native.OS.UseSystemWindowFrame;
Expand Down Expand Up @@ -432,6 +446,12 @@ public Workspace GetActiveWorkspace()
return first;
}

public StringComparison GetPreferredListComparisonType()
{
return Preferences.Instance.UseCaseInsensitiveSortingInLists ?
StringComparison.OrdinalIgnoreCase : StringComparison.Ordinal;
}

public void AddNode(RepositoryNode node, RepositoryNode to, bool save)
{
var collection = to == null ? RepositoryNodes : to.SubNodes;
Expand All @@ -449,7 +469,7 @@ public void SortNodes(List<RepositoryNode> collection)
if (l.IsRepository != r.IsRepository)
return l.IsRepository ? 1 : -1;

return string.Compare(l.Name, r.Name, StringComparison.Ordinal);
return string.Compare(l.Name, r.Name, GetPreferredListComparisonType());
});
}

Expand Down Expand Up @@ -669,6 +689,7 @@ private bool RemoveInvalidRepositoriesRecursive(List<RepositoryNode> collection)
private string _defaultFontFamily = string.Empty;
private string _monospaceFontFamily = string.Empty;
private bool _onlyUseMonoFontInEditor = true;
private bool _useCaseInsensitiveSortingInLists = false;
private double _defaultFontSize = 13;
private double _editorFontSize = 13;
private int _editorTabWidth = 4;
Expand Down
3 changes: 2 additions & 1 deletion src/ViewModels/StashesPage.cs
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,8 @@ public Models.Stash SelectedStash
changes.Add(c);

if (needSort)
changes.Sort((l, r) => string.Compare(l.Path, r.Path, StringComparison.Ordinal));
changes.Sort((l, r) => string.Compare(l.Path, r.Path,
Preferences.Instance.GetPreferredListComparisonType()));
}

Dispatcher.UIThread.Invoke(() =>
Expand Down
13 changes: 4 additions & 9 deletions src/ViewModels/WorkingCopy.cs
Original file line number Diff line number Diff line change
Expand Up @@ -1778,16 +1778,11 @@ private bool IsChanged(List<Models.Change> old, List<Models.Change> cur)
if (old.Count != cur.Count)
return true;

var oldMap = new Dictionary<string, Models.Change>();
foreach (var c in old)
oldMap.Add(c.Path, c);

foreach (var c in cur)
for (int idx = 0; idx < old.Count; idx++)
{
if (!oldMap.TryGetValue(c.Path, out var o))
return true;

if (o.Index != c.Index || o.WorkTree != c.WorkTree)
var o = old[idx];
var c = cur[idx];
if (o.Path != c.Path || o.Index != c.Index || o.WorkTree != c.WorkTree)
return true;
}

Expand Down
7 changes: 6 additions & 1 deletion src/Views/Preferences.axaml
Original file line number Diff line number Diff line change
Expand Up @@ -153,7 +153,7 @@
<TabItem.Header>
<TextBlock Classes="tab_header" Text="{DynamicResource Text.Preferences.Appearance}"/>
</TabItem.Header>
<Grid Margin="8" RowDefinitions="32,32,32,32,32,32,32,32,Auto" ColumnDefinitions="Auto,*">
<Grid Margin="8" RowDefinitions="32,32,32,32,32,32,32,32,32,Auto" ColumnDefinitions="Auto,*">
<TextBlock Grid.Row="0" Grid.Column="0"
Text="{DynamicResource Text.Preferences.Appearance.Theme}"
HorizontalAlignment="Right"
Expand Down Expand Up @@ -260,6 +260,11 @@
IsChecked="{Binding UseFixedTabWidth, Mode=TwoWay}"/>

<CheckBox Grid.Row="8" Grid.Column="1"
Height="32"
Content="{DynamicResource Text.Preferences.Appearance.UseCaseInsensitiveSortingInLists}"
IsChecked="{Binding UseCaseInsensitiveSortingInLists, Mode=TwoWay}"/>

<CheckBox Grid.Row="9" Grid.Column="1"
Height="32"
Content="{DynamicResource Text.Preferences.Appearance.UseNativeWindowFrame}"
IsChecked="{Binding UseSystemWindowFrame, Mode=OneTime}"
Expand Down
24 changes: 12 additions & 12 deletions src/Views/RevisionFileTreeView.axaml.cs
Original file line number Diff line number Diff line change
Expand Up @@ -270,12 +270,7 @@ protected override void OnPropertyChanged(AvaloniaPropertyChangedEventArgs chang
foreach (var obj in objects)
_tree.Add(new ViewModels.RevisionFileTreeNode { Backend = obj });

_tree.Sort((l, r) =>
{
if (l.IsFolder == r.IsFolder)
return string.Compare(l.Name, r.Name, StringComparison.Ordinal);
return l.IsFolder ? -1 : 1;
});
SortNodes(_tree);

var topTree = new List<ViewModels.RevisionFileTreeNode>();
MakeRows(topTree, _tree, 0);
Expand Down Expand Up @@ -341,12 +336,7 @@ private void OnRowsSelectionChanged(object sender, SelectionChangedEventArgs _)
foreach (var obj in objects)
node.Children.Add(new ViewModels.RevisionFileTreeNode() { Backend = obj });

node.Children.Sort((l, r) =>
{
if (l.IsFolder == r.IsFolder)
return Models.NumericSort.Compare(l.Name, r.Name);
return l.IsFolder ? -1 : 1;
});
SortNodes(node.Children);

return node.Children;
}
Expand All @@ -365,6 +355,16 @@ private void MakeRows(List<ViewModels.RevisionFileTreeNode> rows, List<ViewModel
}
}

private void SortNodes(List<ViewModels.RevisionFileTreeNode> nodes)
{
nodes.Sort((l, r) =>
{
if (l.IsFolder == r.IsFolder)
return Models.NumericSort.Compare(l.Name, r.Name);
return l.IsFolder ? -1 : 1;
});
}

private List<ViewModels.RevisionFileTreeNode> _tree = [];
private AvaloniaList<ViewModels.RevisionFileTreeNode> _rows = [];
private bool _disableSelectionChangingEvent = false;
Expand Down
Loading