From b5072360edaeb3ef690e1a1acfe4461d216406a9 Mon Sep 17 00:00:00 2001 From: goran-w Date: Fri, 1 Nov 2024 20:45:06 +0100 Subject: [PATCH] Implemented new TextDiff feature "Show All Lines" (toggle) * Added new ToggleButton in DiffView toolbar, visible when IsTextDiff, disabling the buttons "Increase/Decrease Number of Visible Lines" when on. * Added new Preference property "UseFullTextDiff". * Added StyledProperty "UseFullTextDiffProperty" in TextDiffView, with a DataTemplate binding to the corresponding preference property. * When changed, UseFullTextDiffProperty is handled identically as UseSideBySideDiffProperty (via new helper method RefreshContent(), for unification with OnDataContextChanged()). * Added new method DiffContext.ToggleFullTextDiff() for changing the preference property and reloading the diff content. * Implemented the new feature by overriding the "unified" (number of context lines) for Commands.Diff() with a very high number. NOTE: The number used (~1 billion) is supposed to be the highest one working on Mac, according to this forum comment: https://stackoverflow.com/questions/28727424/for-git-diff-is-there-a-uinfinity-option-to-show-the-whole-file#comment135202820_28846576 --- src/ViewModels/DiffContext.cs | 13 +++++- src/ViewModels/Preference.cs | 7 ++++ src/Views/DiffView.axaml | 26 ++++++++++-- src/Views/TextDiffView.axaml.cs | 70 ++++++++++++++++++++------------- 4 files changed, 85 insertions(+), 31 deletions(-) diff --git a/src/ViewModels/DiffContext.cs b/src/ViewModels/DiffContext.cs index ccd667ee..cfb9fa79 100644 --- a/src/ViewModels/DiffContext.cs +++ b/src/ViewModels/DiffContext.cs @@ -78,6 +78,12 @@ namespace SourceGit.ViewModels LoadDiffContent(); } + public void ToggleFullTextDiff() + { + Preference.Instance.UseFullTextDiff = !Preference.Instance.UseFullTextDiff; + LoadDiffContent(); + } + public void IncrUnified() { UnifiedLines = _unifiedLines + 1; @@ -109,7 +115,12 @@ namespace SourceGit.ViewModels Task.Run(() => { - var latest = new Commands.Diff(_repo, _option, _unifiedLines, _ignoreWhitespace).Result(); + // NOTE: Here we override the UnifiedLines value (if UseFullTextDiff is on). + // There is no way to tell a git-diff to use "ALL lines of context", + // so instead we set a very high number for the "lines of context" parameter. + var numLines = Preference.Instance.UseFullTextDiff ? 999999999 : _unifiedLines; + + var latest = new Commands.Diff(_repo, _option, numLines, _ignoreWhitespace).Result(); var rs = null as object; if (latest.TextDiff != null) diff --git a/src/ViewModels/Preference.cs b/src/ViewModels/Preference.cs index 2741650c..efd31b72 100644 --- a/src/ViewModels/Preference.cs +++ b/src/ViewModels/Preference.cs @@ -186,6 +186,12 @@ namespace SourceGit.ViewModels set => SetProperty(ref _showHiddenSymbolsInDiffView, value); } + public bool UseFullTextDiff + { + get => _useFullTextDiff; + set => SetProperty(ref _useFullTextDiff, value); + } + public Models.ChangeViewMode UnstagedChangeViewMode { get => _unstagedChangeViewMode; @@ -591,6 +597,7 @@ namespace SourceGit.ViewModels private bool _useSyntaxHighlighting = false; private bool _enableDiffViewWordWrap = false; private bool _showHiddenSymbolsInDiffView = false; + private bool _useFullTextDiff = false; private Models.ChangeViewMode _unstagedChangeViewMode = Models.ChangeViewMode.List; private Models.ChangeViewMode _stagedChangeViewMode = Models.ChangeViewMode.List; diff --git a/src/Views/DiffView.axaml b/src/Views/DiffView.axaml index 8ccc25bb..9109e504 100644 --- a/src/Views/DiffView.axaml +++ b/src/Views/DiffView.axaml @@ -34,11 +34,24 @@ + + + @@ -46,8 +59,13 @@ Width="32" Command="{Binding DecrUnified}" IsVisible="{Binding IsTextDiff}" - ToolTip.Tip="{DynamicResource Text.Diff.VisualLines.Decr}" - IsEnabled="{Binding UnifiedLines, Converter={x:Static c:IntConverters.IsGreaterThanFour}}"> + ToolTip.Tip="{DynamicResource Text.Diff.VisualLines.Decr}"> + + + + + + @@ -211,7 +229,9 @@ - + diff --git a/src/Views/TextDiffView.axaml.cs b/src/Views/TextDiffView.axaml.cs index 3b940c0c..02b753ba 100644 --- a/src/Views/TextDiffView.axaml.cs +++ b/src/Views/TextDiffView.axaml.cs @@ -1205,6 +1205,15 @@ namespace SourceGit.Views set => SetValue(UseSideBySideDiffProperty, value); } + public static readonly StyledProperty UseFullTextDiffProperty = + AvaloniaProperty.Register(nameof(UseFullTextDiff)); + + public bool UseFullTextDiff + { + get => GetValue(UseFullTextDiffProperty); + set => SetValue(UseFullTextDiffProperty, value); + } + public static readonly StyledProperty SelectedChunkProperty = AvaloniaProperty.Register(nameof(SelectedChunk)); @@ -1232,19 +1241,44 @@ namespace SourceGit.Views set => SetValue(EnableChunkSelectionProperty, value); } + private void RefreshContent(Models.TextDiff diff, bool keepScrollOffset = true) + { + if (SelectedChunk != null) + SetCurrentValue(SelectedChunkProperty, null); + + if (diff == null) + { + Editor.Content = null; + GC.Collect(); + return; + } + + if (UseSideBySideDiff) + { + var previousContent = Editor.Content as ViewModels.TwoSideTextDiff; + Editor.Content = new ViewModels.TwoSideTextDiff(diff, keepScrollOffset ? previousContent : null); + } + else + { + if (!keepScrollOffset) + diff.ScrollOffset = Vector.Zero; + Editor.Content = diff; + } + + IsUnstagedChange = diff.Option.IsUnstaged; + EnableChunkSelection = diff.Option.WorkingCopyChange != null; + } + static TextDiffView() { UseSideBySideDiffProperty.Changed.AddClassHandler((v, _) => { - if (v.DataContext is Models.TextDiff diff) - { - diff.ScrollOffset = Vector.Zero; + v.RefreshContent(v.DataContext as Models.TextDiff, false); + }); - if (v.UseSideBySideDiff) - v.Editor.Content = new ViewModels.TwoSideTextDiff(diff); - else - v.Editor.Content = diff; - } + UseFullTextDiffProperty.Changed.AddClassHandler((v, _) => + { + v.RefreshContent(v.DataContext as Models.TextDiff, false); }); SelectedChunkProperty.Changed.AddClassHandler((v, _) => @@ -1271,25 +1305,7 @@ namespace SourceGit.Views protected override void OnDataContextChanged(EventArgs e) { base.OnDataContextChanged(e); - - if (SelectedChunk != null) - SetCurrentValue(SelectedChunkProperty, null); - - var diff = DataContext as Models.TextDiff; - if (diff == null) - { - Editor.Content = null; - GC.Collect(); - return; - } - - if (UseSideBySideDiff) - Editor.Content = new ViewModels.TwoSideTextDiff(diff, Editor.Content as ViewModels.TwoSideTextDiff); - else - Editor.Content = diff; - - IsUnstagedChange = diff.Option.IsUnstaged; - EnableChunkSelection = diff.Option.WorkingCopyChange != null; + RefreshContent(DataContext as Models.TextDiff, true); } protected override void OnPointerExited(PointerEventArgs e)