diff --git a/src/Models/DiffResult.cs b/src/Models/DiffResult.cs index e7cecaa3..61255ae9 100644 --- a/src/Models/DiffResult.cs +++ b/src/Models/DiffResult.cs @@ -63,7 +63,7 @@ namespace SourceGit.Models { public string File { get; set; } = string.Empty; public List Lines { get; set; } = new List(); - public Vector SyncScrollOffset { get; set; } = Vector.Zero; + public Vector ScrollOffset { get; set; } = Vector.Zero; public int MaxLineNumber = 0; public string Repo { get; set; } = null; diff --git a/src/Resources/Icons.axaml b/src/Resources/Icons.axaml index 6cf53d96..bd2e551b 100644 --- a/src/Resources/Icons.axaml +++ b/src/Resources/Icons.axaml @@ -65,6 +65,7 @@ M875 117H149C109 117 75 151 75 192v640c0 41 34 75 75 75h725c41 0 75-34 75-75V192c0-41-34-75-75-75zM139 832V192c0-6 4-11 11-11h331v661H149c-6 0-11-4-11-11zm747 0c0 6-4 11-11 11H544v-661H875c6 0 11 4 11 11v640z M875 117H149C109 117 75 151 75 192v640c0 41 34 75 75 75h725c41 0 75-34 75-75V192c0-41-34-75-75-75zm-725 64h725c6 0 11 4 11 11v288h-747V192c0-6 4-11 11-11zm725 661H149c-6 0-11-4-11-11V544h747V832c0 6-4 11-11 11z M40 9 15 23 15 31 9 28 9 20 34 5 24 0 0 14 0 34 25 48 25 28 49 14zM26 29 26 48 49 34 49 15z + M19,13 C19.4142,13 19.75,13.3358 19.75,13.75 L19.75,18.4393 L20.4697,17.7197 C20.7626,17.4268 21.2374,17.4268 21.5303,17.7197 C21.8232,18.0126 21.8232,18.4874 21.5303,18.7803 L19.5303,20.7803 C19.4584,20.8522 19.3755,20.9065 19.2871,20.9431 C19.2099,20.9751 19.1262,20.9946 19.0386,20.999 L19,21 L19,21 C18.8983,21 18.8013,20.9798 18.7129,20.9431 C18.6245,20.9065 18.5416,20.8522 18.4697,20.7803 L16.4697,18.7803 C16.1768,18.4874 16.1768,18.0126 16.4697,17.7197 C16.7626,17.4268 17.2374,17.4268 17.5303,17.7197 L18.25,18.4393 L18.25,13.75 C18.25,13.3358 18.5858,13 19,13 Z M11.25,18 C11.6642,18 12,18.3358 12,18.75 C12,19.1296833 11.7178347,19.4434889 11.3517677,19.4931531 L11.25,19.5 L2.75,19.5 C2.33579,19.5 2,19.1642 2,18.75 C2,18.3703167 2.28215688,18.0565111 2.64823019,18.0068469 L2.75,18 L11.25,18 Z M14.25,11.5 C14.6642,11.5 15,11.8358 15,12.25 C15,12.6642 14.6642,13 14.25,13 L2.75,13 C2.33579,13 2,12.6642 2,12.25 C2,11.8358 2.33579,11.5 2.75,11.5 L14.25,11.5 Z M19.0022,3 C19.1031,3.0003 19.1993,3.02051 19.2871,3.05691 C19.3755,3.09351 19.4584,3.14776 19.5303,3.21967 L21.5303,5.21967 C21.8232,5.51256 21.8232,5.98744 21.5303,6.28033 C21.2374,6.57322 20.7626,6.57322 20.4697,6.28033 L19.75,5.56066 L19.75,10.25 C19.75,10.6642 19.4142,11 19,11 C18.5858,11 18.25,10.6642 18.25,10.25 L18.25,5.56066 L17.5303,6.28033 C17.2374,6.57322 16.7626,6.57322 16.4697,6.28033 C16.1768,5.98744 16.1768,5.51256 16.4697,5.21967 L18.4697,3.21967 C18.58634,3.102974 18.731972,3.0327676 18.8834536,3.00906104 L19.0022,3 Z M11.25,5 C11.6642,5 12,5.33579 12,5.75 C12,6.16421 11.6642,6.5 11.25,6.5 L2.75,6.5 C2.33579,6.5 2,6.16421 2,5.75 C2,5.33579 2.33579,5 2.75,5 L11.25,5 Z M408 232C408 210 426 192 448 192h416a40 40 0 110 80H448a40 40 0 01-40-40zM408 512c0-22 18-40 40-40h416a40 40 0 110 80H448A40 40 0 01408 512zM448 752A40 40 0 00448 832h416a40 40 0 100-80H448zM32 480l132 0 0-128 64 0 0 128 132 0 0 64-132 0 0 128-64 0 0-128-132 0Z M408 232C408 210 426 192 448 192h416a40 40 0 110 80H448a40 40 0 01-40-40zM408 512c0-22 18-40 40-40h416a40 40 0 110 80H448A40 40 0 01408 512zM448 752A40 40 0 00448 832h416a40 40 0 100-80H448zM32 480l328 0 0 64-328 0Z M 968 418 l -95 94 c -59 59 -146 71 -218 37 L 874 331 a 64 64 0 0 0 0 -90 L 783 150 a 64 64 0 0 0 -90 0 L 475 368 c -34 -71 -22 -159 37 -218 l 94 -94 c 75 -75 196 -75 271 0 l 90 90 c 75 75 75 196 0 271 z M 332 693 a 64 64 0 0 1 0 -90 l 271 -271 c 25 -25 65 -25 90 0 s 25 65 0 90 L 422 693 a 64 64 0 0 1 -90 0 z M 151 783 l 90 90 a 64 64 0 0 0 90 0 l 218 -218 c 34 71 22 159 -37 218 l -86 94 a 192 192 0 0 1 -271 0 l -98 -98 a 192 192 0 0 1 0 -271 l 94 -86 c 59 -59 146 -71 218 -37 L 151 693 a 64 64 0 0 0 0 90 z diff --git a/src/Resources/Locales/en_US.axaml b/src/Resources/Locales/en_US.axaml index bed03b0a..eb1c6de3 100644 --- a/src/Resources/Locales/en_US.axaml +++ b/src/Resources/Locales/en_US.axaml @@ -246,6 +246,7 @@ Syntax Highlighting Line Word Wrap Open in Merge Tool + Show All Lines Decrease Number of Visible Lines Increase Number of Visible Lines SELECT FILE TO VIEW CHANGES diff --git a/src/ViewModels/DiffContext.cs b/src/ViewModels/DiffContext.cs index 1a48c8e0..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) @@ -203,7 +214,7 @@ namespace SourceGit.ViewModels Dispatcher.UIThread.Post(() => { if (_content is Models.TextDiff old && rs is Models.TextDiff cur && old.File == cur.File) - cur.SyncScrollOffset = old.SyncScrollOffset; + cur.ScrollOffset = old.ScrollOffset; FileModeChange = latest.FileModeChange; Content = rs; 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 99e499b0..02b753ba 100644 --- a/src/Views/TextDiffView.axaml.cs +++ b/src/Views/TextDiffView.axaml.cs @@ -902,7 +902,7 @@ namespace SourceGit.Views var scroller = this.FindDescendantOfType(); if (scroller != null) { - scroller.Bind(ScrollViewer.OffsetProperty, new Binding("SyncScrollOffset", BindingMode.TwoWay)); + scroller.Bind(ScrollViewer.OffsetProperty, new Binding("ScrollOffset", BindingMode.TwoWay)); scroller.GotFocus += OnTextViewScrollGotFocus; } } @@ -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.SyncScrollOffset = 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)