From 5c33198fc71c1ee163f174ffb0b6b22096da2d1e Mon Sep 17 00:00:00 2001 From: leo Date: Mon, 18 Aug 2025 11:53:58 +0800 Subject: [PATCH 01/31] enhance: remove unnecessary code for moving window on macOS This has been fix in`AvaloniaUI`. See https://github.com/AvaloniaUI/Avalonia/pull/19447 Signed-off-by: leo --- src/Views/ChromelessWindow.cs | 5 ----- 1 file changed, 5 deletions(-) diff --git a/src/Views/ChromelessWindow.cs b/src/Views/ChromelessWindow.cs index 1abb06c9..24c652dc 100644 --- a/src/Views/ChromelessWindow.cs +++ b/src/Views/ChromelessWindow.cs @@ -30,12 +30,7 @@ namespace SourceGit.Views public void BeginMoveWindow(object _, PointerPressedEventArgs e) { if (e.ClickCount == 1) - { - if (OperatingSystem.IsMacOS()) - e.Pointer.Capture(this); - BeginMoveDrag(e); - } e.Handled = true; } From 6511d15c01ca77fb7e477428e058397421dc4e4e Mon Sep 17 00:00:00 2001 From: leo Date: Mon, 18 Aug 2025 18:12:13 +0800 Subject: [PATCH 02/31] refactor: rewrite text diff view - Move some data-only code from `Views` to `ViewModels` - Remove unnecessary attributes - This commit also contains a feature request #1722 Signed-off-by: leo --- src/Commands/Diff.cs | 6 +- src/Models/DiffResult.cs | 9 +- src/ViewModels/BlockNavigation.cs | 44 ++- src/ViewModels/DiffContext.cs | 115 +++++-- src/ViewModels/TextDiffContext.cs | 291 +++++++++++++++++ src/ViewModels/TwoSideTextDiff.cs | 109 ------ src/Views/DiffView.axaml | 40 ++- src/Views/DiffView.axaml.cs | 40 +-- src/Views/TextDiffView.axaml | 36 +- src/Views/TextDiffView.axaml.cs | 527 +++++++----------------------- 10 files changed, 588 insertions(+), 629 deletions(-) create mode 100644 src/ViewModels/TextDiffContext.cs delete mode 100644 src/ViewModels/TwoSideTextDiff.cs diff --git a/src/Commands/Diff.cs b/src/Commands/Diff.cs index 3eae1b54..ee5433ac 100644 --- a/src/Commands/Diff.cs +++ b/src/Commands/Diff.cs @@ -20,11 +20,7 @@ namespace SourceGit.Commands public Diff(string repo, Models.DiffOption opt, int unified, bool ignoreWhitespace) { - _result.TextDiff = new Models.TextDiff() - { - Repo = repo, - Option = opt, - }; + _result.TextDiff = new Models.TextDiff() { Option = opt }; WorkingDirectory = repo; Context = repo; diff --git a/src/Models/DiffResult.cs b/src/Models/DiffResult.cs index d80fa136..9b21e6c9 100644 --- a/src/Models/DiffResult.cs +++ b/src/Models/DiffResult.cs @@ -1,8 +1,6 @@ using System.Collections.Generic; using System.IO; using System.Text.RegularExpressions; - -using Avalonia; using Avalonia.Media.Imaging; namespace SourceGit.Models @@ -62,12 +60,9 @@ namespace SourceGit.Models public partial class TextDiff { public string File { get; set; } = string.Empty; - public List Lines { get; set; } = new List(); - public Vector ScrollOffset { get; set; } = Vector.Zero; - public int MaxLineNumber = 0; - - public string Repo { get; set; } = null; public DiffOption Option { get; set; } = null; + public List Lines { get; set; } = new List(); + public int MaxLineNumber = 0; public TextDiffSelection MakeSelection(int startLine, int endLine, bool isCombined, bool isOldSide) { diff --git a/src/ViewModels/BlockNavigation.cs b/src/ViewModels/BlockNavigation.cs index 4a51244c..bf5e2314 100644 --- a/src/ViewModels/BlockNavigation.cs +++ b/src/ViewModels/BlockNavigation.cs @@ -48,17 +48,11 @@ namespace SourceGit.ViewModels } } - public BlockNavigation(object context) + public BlockNavigation(List lines) { Blocks.Clear(); Current = -1; - var lines = new List(); - if (context is Models.TextDiff combined) - lines = combined.Lines; - else if (context is TwoSideTextDiff twoSide) - lines = twoSide.Old; - if (lines.Count == 0) return; @@ -96,7 +90,10 @@ namespace SourceGit.ViewModels public Block GetCurrentBlock() { - return (_current >= 0 && _current < Blocks.Count) ? Blocks[_current] : null; + if (_current >= 0 && _current < Blocks.Count) + return Blocks[_current]; + + return Blocks.Count > 0 ? Blocks[0] : null; } public Block GotoFirst() @@ -105,6 +102,7 @@ namespace SourceGit.ViewModels return null; Current = 0; + OnPropertyChanged(nameof(Indicator)); return Blocks[_current]; } @@ -117,6 +115,8 @@ namespace SourceGit.ViewModels Current = 0; else if (_current > 0) Current = _current - 1; + + OnPropertyChanged(nameof(Indicator)); return Blocks[_current]; } @@ -127,6 +127,8 @@ namespace SourceGit.ViewModels if (_current < Blocks.Count - 1) Current = _current + 1; + + OnPropertyChanged(nameof(Indicator)); return Blocks[_current]; } @@ -136,9 +138,35 @@ namespace SourceGit.ViewModels return null; Current = Blocks.Count - 1; + OnPropertyChanged(nameof(Indicator)); return Blocks[_current]; } + public void AutoUpdate(int start, int end) + { + if (_current >= 0 && _current < Blocks.Count) + { + var block = Blocks[_current]; + if ((block.Start >= start && block.Start <= end) || + (block.End >= start && block.End <= end) || + (block.Start <= start && block.End >= end)) + return; + } + + for (var i = 0; i < Blocks.Count; i++) + { + var block = Blocks[i]; + if ((block.Start >= start && block.Start <= end) || + (block.End >= start && block.End <= end) || + (block.Start <= start && block.End >= end)) + { + Current = i; + OnPropertyChanged(nameof(Indicator)); + return; + } + } + } + private int _current = -1; } } diff --git a/src/ViewModels/DiffContext.cs b/src/ViewModels/DiffContext.cs index e5ee18ca..f499654b 100644 --- a/src/ViewModels/DiffContext.cs +++ b/src/ViewModels/DiffContext.cs @@ -1,9 +1,7 @@ using System; using System.IO; using System.Threading.Tasks; - using Avalonia.Threading; - using CommunityToolkit.Mvvm.ComponentModel; namespace SourceGit.ViewModels @@ -24,7 +22,58 @@ namespace SourceGit.ViewModels { Preferences.Instance.IgnoreWhitespaceChangesInDiff = value; OnPropertyChanged(); - LoadDiffContent(); + + if (_isTextDiff) + LoadContent(); + } + } + } + + public bool ShowEntireFile + { + get => Preferences.Instance.UseFullTextDiff; + set + { + if (value != Preferences.Instance.UseFullTextDiff) + { + Preferences.Instance.UseFullTextDiff = value; + OnPropertyChanged(); + + if (Content is TextDiffContext ctx) + { + ctx.Data.File = string.Empty; // Just to ignore both previous `ScrollOffset` and `BlockNavigation` + LoadContent(); + } + } + } + } + + public bool UseBlockNavigation + { + get => Preferences.Instance.UseBlockNavigationInDiffView; + set + { + if (value != Preferences.Instance.UseBlockNavigationInDiffView) + { + Preferences.Instance.UseBlockNavigationInDiffView = value; + OnPropertyChanged(); + (Content as TextDiffContext)?.ResetBlockNavigation(value); + } + } + } + + public bool UseSideBySide + { + get => Preferences.Instance.UseSideBySideDiff; + set + { + if (value != Preferences.Instance.UseSideBySideDiff) + { + Preferences.Instance.UseSideBySideDiff = value; + OnPropertyChanged(); + + if (Content is TextDiffContext ctx && ctx.IsSideBySide() != value) + Content = ctx.SwitchMode(); } } } @@ -72,25 +121,19 @@ namespace SourceGit.ViewModels else Title = $"{_option.OrgPath} → {_option.Path}"; - LoadDiffContent(); - } - - public void ToggleFullTextDiff() - { - Preferences.Instance.UseFullTextDiff = !Preferences.Instance.UseFullTextDiff; - LoadDiffContent(); + LoadContent(); } public void IncrUnified() { UnifiedLines = _unifiedLines + 1; - LoadDiffContent(); + LoadContent(); } public void DecrUnified() { UnifiedLines = Math.Max(4, _unifiedLines - 1); - LoadDiffContent(); + LoadContent(); } public void OpenExternalMergeTool() @@ -98,7 +141,29 @@ namespace SourceGit.ViewModels new Commands.DiffTool(_repo, _option).Open(); } - private void LoadDiffContent() + public void CheckSettings() + { + if (Content is TextDiffContext ctx) + { + if ((ShowEntireFile && _info.UnifiedLines != _entireFileLine) || + (!ShowEntireFile && _info.UnifiedLines == _entireFileLine) || + (IgnoreWhitespace != _info.IgnoreWhitespace)) + { + LoadContent(); + return; + } + + if (ctx.IsSideBySide() != UseSideBySide) + { + ctx = ctx.SwitchMode(); + Content = ctx; + } + + ctx.ResetBlockNavigation(UseBlockNavigation); + } + } + + private void LoadContent() { if (_option.Path.EndsWith('/')) { @@ -109,7 +174,7 @@ namespace SourceGit.ViewModels Task.Run(async () => { - var numLines = Preferences.Instance.UseFullTextDiff ? 999999999 : _unifiedLines; + var numLines = Preferences.Instance.UseFullTextDiff ? _entireFileLine : _unifiedLines; var ignoreWhitespace = Preferences.Instance.IgnoreWhitespaceChangesInDiff; var latest = await new Commands.Diff(_repo, _option, numLines, ignoreWhitespace) @@ -228,12 +293,23 @@ namespace SourceGit.ViewModels Dispatcher.UIThread.Post(() => { - if (_content is Models.TextDiff old && rs is Models.TextDiff cur && old.File == cur.File) - cur.ScrollOffset = old.ScrollOffset; - FileModeChange = latest.FileModeChange; - Content = rs; - IsTextDiff = rs is Models.TextDiff; + + if (rs is Models.TextDiff cur) + { + IsTextDiff = true; + + var hasBlockNavigation = Preferences.Instance.UseBlockNavigationInDiffView; + if (Preferences.Instance.UseSideBySideDiff) + Content = new TwoSideTextDiff(cur, hasBlockNavigation, _content as TwoSideTextDiff); + else + Content = new CombinedTextDiff(cur, hasBlockNavigation, _content as CombinedTextDiff); + } + else + { + IsTextDiff = false; + Content = rs; + } }); }); } @@ -279,6 +355,7 @@ namespace SourceGit.ViewModels } } + private readonly int _entireFileLine = 999999999; private readonly string _repo; private readonly Models.DiffOption _option = null; private string _fileModeChange = string.Empty; diff --git a/src/ViewModels/TextDiffContext.cs b/src/ViewModels/TextDiffContext.cs new file mode 100644 index 00000000..97aed9d3 --- /dev/null +++ b/src/ViewModels/TextDiffContext.cs @@ -0,0 +1,291 @@ +using System; +using System.Collections.Generic; +using Avalonia; +using CommunityToolkit.Mvvm.ComponentModel; + +namespace SourceGit.ViewModels +{ + public record TextDiffSelectedChunk(double y, double h, int start, int end, bool combined, bool isOldSide) + { + public double Y { get; set; } = y; + public double Height { get; set; } = h; + public int StartIdx { get; set; } = start; + public int EndIdx { get; set; } = end; + public bool Combined { get; set; } = combined; + public bool IsOldSide { get; set; } = isOldSide; + + public static bool IsChanged(TextDiffSelectedChunk oldValue, TextDiffSelectedChunk newValue) + { + if (newValue == null) + return oldValue != null; + + if (oldValue == null) + return true; + + return Math.Abs(newValue.Y - oldValue.Y) > 0.001 || + Math.Abs(newValue.Height - oldValue.Height) > 0.001 || + newValue.StartIdx != oldValue.StartIdx || + newValue.EndIdx != oldValue.EndIdx || + newValue.Combined != oldValue.Combined || + newValue.IsOldSide != oldValue.IsOldSide; + } + } + + public record TextDiffDisplayRange(int start, int end) + { + public int Start { get; set; } = start; + public int End { get; set; } = end; + } + + public class TextDiffContext : ObservableObject + { + public Models.TextDiff Data => _data; + public string File => _data.File; + public bool IsUnstaged => _data.Option.IsUnstaged; + public bool EnableChunkOption => _data.Option.WorkingCopyChange != null; + + public Vector ScrollOffset + { + get => _scrollOffset; + set => SetProperty(ref _scrollOffset, value); + } + + public BlockNavigation BlockNavigation + { + get => _blockNavigation; + set => SetProperty(ref _blockNavigation, value); + } + + public TextDiffDisplayRange DisplayRange + { + get => _displayRange; + set => SetProperty(ref _displayRange, value); + } + + public TextDiffSelectedChunk SelectedChunk + { + get => _selectedChunk; + set => SetProperty(ref _selectedChunk, value); + } + + public void ResetBlockNavigation(bool enabled) + { + if (!enabled) + BlockNavigation = null; + else if (_blockNavigation == null) + BlockNavigation = CreateBlockNavigation(); + } + + public (int, int) FindRangeByIndex(List lines, int lineIdx) + { + var startIdx = -1; + var endIdx = -1; + + var normalLineCount = 0; + var modifiedLineCount = 0; + + for (int i = lineIdx; i >= 0; i--) + { + var line = lines[i]; + if (line.Type == Models.TextDiffLineType.Indicator) + { + startIdx = i; + break; + } + + if (line.Type == Models.TextDiffLineType.Normal) + { + normalLineCount++; + if (normalLineCount >= 2) + { + startIdx = i; + break; + } + } + else + { + normalLineCount = 0; + modifiedLineCount++; + } + } + + normalLineCount = lines[lineIdx].Type == Models.TextDiffLineType.Normal ? 1 : 0; + for (int i = lineIdx + 1; i < lines.Count; i++) + { + var line = lines[i]; + if (line.Type == Models.TextDiffLineType.Indicator) + { + endIdx = i; + break; + } + + if (line.Type == Models.TextDiffLineType.Normal) + { + normalLineCount++; + if (normalLineCount >= 2) + { + endIdx = i; + break; + } + } + else + { + normalLineCount = 0; + modifiedLineCount++; + } + } + + if (endIdx == -1) + endIdx = lines.Count - 1; + + return modifiedLineCount > 0 ? (startIdx, endIdx) : (-1, -1); + } + + public virtual bool IsSideBySide() + { + return false; + } + + public virtual TextDiffContext SwitchMode() + { + return null; + } + + public virtual BlockNavigation CreateBlockNavigation() + { + return new BlockNavigation(_data.Lines); + } + + protected Models.TextDiff _data = null; + protected Vector _scrollOffset = Vector.Zero; + protected BlockNavigation _blockNavigation = null; + protected TextDiffDisplayRange _displayRange = null; + protected TextDiffSelectedChunk _selectedChunk = null; + } + + public class CombinedTextDiff : TextDiffContext + { + public CombinedTextDiff(Models.TextDiff diff, bool hasBlockNavigation, CombinedTextDiff previous = null) + { + _data = diff; + + if (previous != null && previous.File.Equals(File, StringComparison.Ordinal)) + _scrollOffset = previous.ScrollOffset; + + if (hasBlockNavigation) + _blockNavigation = CreateBlockNavigation(); + } + + public override TextDiffContext SwitchMode() + { + return new TwoSideTextDiff(_data, _blockNavigation != null); + } + } + + public class TwoSideTextDiff : TextDiffContext + { + public List Old { get; } = new List(); + public List New { get; } = new List(); + + public TwoSideTextDiff(Models.TextDiff diff, bool hasBlockNavigation, TwoSideTextDiff previous = null) + { + _data = diff; + + foreach (var line in diff.Lines) + { + switch (line.Type) + { + case Models.TextDiffLineType.Added: + New.Add(line); + break; + case Models.TextDiffLineType.Deleted: + Old.Add(line); + break; + default: + FillEmptyLines(); + Old.Add(line); + New.Add(line); + break; + } + } + + FillEmptyLines(); + + if (previous != null && previous.File.Equals(File, StringComparison.Ordinal)) + _scrollOffset = previous._scrollOffset; + + if (hasBlockNavigation) + _blockNavigation = CreateBlockNavigation(); + } + + public override bool IsSideBySide() + { + return true; + } + + public override TextDiffContext SwitchMode() + { + return new CombinedTextDiff(_data, _blockNavigation != null); + } + + public override BlockNavigation CreateBlockNavigation() + { + return new BlockNavigation(Old); + } + + public void ConvertsToCombinedRange(ref int startLine, ref int endLine, bool isOldSide) + { + endLine = Math.Min(endLine, _data.Lines.Count - 1); + + var oneSide = isOldSide ? Old : New; + var firstContentLine = -1; + for (int i = startLine; i <= endLine; i++) + { + var line = oneSide[i]; + if (line.Type != Models.TextDiffLineType.None) + { + firstContentLine = i; + break; + } + } + + if (firstContentLine < 0) + return; + + var endContentLine = -1; + for (int i = Math.Min(endLine, oneSide.Count - 1); i >= startLine; i--) + { + var line = oneSide[i]; + if (line.Type != Models.TextDiffLineType.None) + { + endContentLine = i; + break; + } + } + + if (endContentLine < 0) + return; + + var firstContent = oneSide[firstContentLine]; + var endContent = oneSide[endContentLine]; + startLine = _data.Lines.IndexOf(firstContent); + endLine = _data.Lines.IndexOf(endContent); + } + + private void FillEmptyLines() + { + if (Old.Count < New.Count) + { + int diff = New.Count - Old.Count; + for (int i = 0; i < diff; i++) + Old.Add(new Models.TextDiffLine()); + } + else if (Old.Count > New.Count) + { + int diff = Old.Count - New.Count; + for (int i = 0; i < diff; i++) + New.Add(new Models.TextDiffLine()); + } + } + } +} diff --git a/src/ViewModels/TwoSideTextDiff.cs b/src/ViewModels/TwoSideTextDiff.cs deleted file mode 100644 index 3fb1e63b..00000000 --- a/src/ViewModels/TwoSideTextDiff.cs +++ /dev/null @@ -1,109 +0,0 @@ -using System; -using System.Collections.Generic; - -using Avalonia; - -using CommunityToolkit.Mvvm.ComponentModel; - -namespace SourceGit.ViewModels -{ - public class TwoSideTextDiff : ObservableObject - { - public string File { get; set; } - public List Old { get; set; } = new List(); - public List New { get; set; } = new List(); - public int MaxLineNumber = 0; - - public Vector SyncScrollOffset - { - get => _syncScrollOffset; - set => SetProperty(ref _syncScrollOffset, value); - } - - public TwoSideTextDiff(Models.TextDiff diff, TwoSideTextDiff previous = null) - { - File = diff.File; - MaxLineNumber = diff.MaxLineNumber; - - foreach (var line in diff.Lines) - { - switch (line.Type) - { - case Models.TextDiffLineType.Added: - New.Add(line); - break; - case Models.TextDiffLineType.Deleted: - Old.Add(line); - break; - default: - FillEmptyLines(); - Old.Add(line); - New.Add(line); - break; - } - } - - FillEmptyLines(); - - if (previous != null && previous.File == File) - _syncScrollOffset = previous._syncScrollOffset; - } - - public void ConvertsToCombinedRange(Models.TextDiff combined, ref int startLine, ref int endLine, bool isOldSide) - { - endLine = Math.Min(endLine, combined.Lines.Count - 1); - - var oneSide = isOldSide ? Old : New; - var firstContentLine = -1; - for (int i = startLine; i <= endLine; i++) - { - var line = oneSide[i]; - if (line.Type != Models.TextDiffLineType.None) - { - firstContentLine = i; - break; - } - } - - if (firstContentLine < 0) - return; - - var endContentLine = -1; - for (int i = Math.Min(endLine, oneSide.Count - 1); i >= startLine; i--) - { - var line = oneSide[i]; - if (line.Type != Models.TextDiffLineType.None) - { - endContentLine = i; - break; - } - } - - if (endContentLine < 0) - return; - - var firstContent = oneSide[firstContentLine]; - var endContent = oneSide[endContentLine]; - startLine = combined.Lines.IndexOf(firstContent); - endLine = combined.Lines.IndexOf(endContent); - } - - private void FillEmptyLines() - { - if (Old.Count < New.Count) - { - int diff = New.Count - Old.Count; - for (int i = 0; i < diff; i++) - Old.Add(new Models.TextDiffLine()); - } - else if (Old.Count > New.Count) - { - int diff = Old.Count - New.Count; - for (int i = 0; i < diff; i++) - New.Add(new Models.TextDiffLine()); - } - } - - private Vector _syncScrollOffset = Vector.Zero; - } -} diff --git a/src/Views/DiffView.axaml b/src/Views/DiffView.axaml index ee8070f9..25a6dc87 100644 --- a/src/Views/DiffView.axaml +++ b/src/Views/DiffView.axaml @@ -48,7 +48,7 @@ - + @@ -73,11 +73,20 @@ - + - + + + + + + + + + + @@ -142,7 +149,7 @@ - + @@ -150,8 +157,7 @@ @@ -172,8 +178,8 @@ ToolTip.Tip="{DynamicResource Text.Diff.ToggleWordWrap}"> - - + + @@ -197,7 +203,7 @@ @@ -361,10 +367,8 @@ - - + + diff --git a/src/Views/DiffView.axaml.cs b/src/Views/DiffView.axaml.cs index 53fe0803..b67a6f2d 100644 --- a/src/Views/DiffView.axaml.cs +++ b/src/Views/DiffView.axaml.cs @@ -1,4 +1,3 @@ -using Avalonia; using Avalonia.Controls; using Avalonia.Interactivity; using Avalonia.VisualTree; @@ -12,50 +11,35 @@ namespace SourceGit.Views InitializeComponent(); } + protected override void OnLoaded(RoutedEventArgs e) + { + base.OnLoaded(e); + + if (DataContext is ViewModels.DiffContext vm) + vm.CheckSettings(); + } + private void OnGotoFirstChange(object _, RoutedEventArgs e) { - this.FindDescendantOfType()?.GotoFirstChange(); + this.FindDescendantOfType()?.GotoFirstChange(); e.Handled = true; } private void OnGotoPrevChange(object _, RoutedEventArgs e) { - this.FindDescendantOfType()?.GotoPrevChange(); + this.FindDescendantOfType()?.GotoPrevChange(); e.Handled = true; } private void OnGotoNextChange(object _, RoutedEventArgs e) { - this.FindDescendantOfType()?.GotoNextChange(); + this.FindDescendantOfType()?.GotoNextChange(); e.Handled = true; } private void OnGotoLastChange(object _, RoutedEventArgs e) { - this.FindDescendantOfType()?.GotoLastChange(); - e.Handled = true; - } - - private void OnBlockNavigationChanged(object sender, RoutedEventArgs e) - { - if (sender is TextDiffView textDiff) - BlockNavigationIndicator.Text = textDiff.BlockNavigation?.Indicator ?? string.Empty; - } - - private void OnUseFullTextDiffClicked(object sender, RoutedEventArgs e) - { - var textDiffView = this.FindDescendantOfType(); - - var presenter = textDiffView?.FindDescendantOfType(); - if (presenter == null) - return; - - if (presenter.DataContext is Models.TextDiff combined) - combined.ScrollOffset = Vector.Zero; - else if (presenter.DataContext is ViewModels.TwoSideTextDiff twoSides) - twoSides.File = string.Empty; // Just to reset `SyncScrollOffset` without affect UI refresh. - - (DataContext as ViewModels.DiffContext)?.ToggleFullTextDiff(); + this.FindDescendantOfType()?.GotoLastChange(); e.Handled = true; } } diff --git a/src/Views/TextDiffView.axaml b/src/Views/TextDiffView.axaml index 45745d38..135d5711 100644 --- a/src/Views/TextDiffView.axaml +++ b/src/Views/TextDiffView.axaml @@ -7,15 +7,14 @@ xmlns:v="using:SourceGit.Views" mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="450" x:Class="SourceGit.Views.TextDiffView" - x:Name="ThisControl" + x:DataType="vm:TextDiffContext" Background="{DynamicResource Brush.Contents}"> - + - + + EnableChunkSelection="{Binding EnableChunkOption}" + SelectedChunk="{Binding SelectedChunk, Mode=TwoWay}" + BlockNavigation="{Binding BlockNavigation, Mode=OneWay}"/> @@ -47,7 +46,6 @@ + EnableChunkSelection="{Binding EnableChunkOption, Mode=OneWay}" + SelectedChunk="{Binding SelectedChunk, Mode=TwoWay}" + BlockNavigation="{Binding BlockNavigation, Mode=OneWay}"/> @@ -87,14 +85,14 @@ UseSyntaxHighlighting="{Binding Source={x:Static vm:Preferences.Instance}, Path=UseSyntaxHighlighting}" WordWrap="False" ShowHiddenSymbols="{Binding Source={x:Static vm:Preferences.Instance}, Path=ShowHiddenSymbolsInDiffView}" - EnableChunkSelection="{Binding #ThisControl.EnableChunkSelection}" - SelectedChunk="{Binding #ThisControl.SelectedChunk, Mode=TwoWay}" - BlockNavigation="{Binding #ThisControl.BlockNavigation, Mode=TwoWay}"/> + EnableChunkSelection="{Binding EnableChunkOption, Mode=OneWay}" + SelectedChunk="{Binding SelectedChunk, Mode=TwoWay}" + BlockNavigation="{Binding BlockNavigation, Mode=OneWay}"/> @@ -103,7 +101,7 @@ - - -