feature: allow user to control whether or not to enable syntax highlighting in DiffView.

This commit is contained in:
leo 2024-03-20 20:17:20 +08:00
parent 8fc25e312d
commit 635db8b3b3
9 changed files with 123 additions and 11 deletions

View file

@ -85,4 +85,5 @@
<StreamGeometry x:Key="Icons.Statistics">M296 912H120c-4.4 0-8-3.6-8-8V520c0-4.4 3.6-8 8-8h176c4.4 0 8 3.6 8 8v384c0 4.4-3.6 8-8 8zM600 912H424c-4.4 0-8-3.6-8-8V121c0-4.4 3.6-8 8-8h176c4.4 0 8 3.6 8 8v783c0 4.4-3.6 8-8 8zM904 912H728c-4.4 0-8-3.6-8-8V280c0-4.4 3.6-8 8-8h176c4.4 0 8 3.6 8 8v624c0 4.4-3.6 8-8 8z</StreamGeometry> <StreamGeometry x:Key="Icons.Statistics">M296 912H120c-4.4 0-8-3.6-8-8V520c0-4.4 3.6-8 8-8h176c4.4 0 8 3.6 8 8v384c0 4.4-3.6 8-8 8zM600 912H424c-4.4 0-8-3.6-8-8V121c0-4.4 3.6-8 8-8h176c4.4 0 8 3.6 8 8v783c0 4.4-3.6 8-8 8zM904 912H728c-4.4 0-8-3.6-8-8V280c0-4.4 3.6-8 8-8h176c4.4 0 8 3.6 8 8v624c0 4.4-3.6 8-8 8z</StreamGeometry>
<StreamGeometry x:Key="Icons.Hotkeys">M512 0C229.216 0 0 229.216 0 512c0 282.752 229.216 512 512 512s512-229.248 512-512c0-282.784-229.216-512-512-512z m0 957.92C266.112 957.92 66.08 757.888 66.08 512S266.112 66.08 512 66.08 957.92 266.112 957.92 512 757.888 957.92 512 957.92zM192 416h96a32 32 0 0 0 32-32v-32a32 32 0 0 0-32-32H192a32 32 0 0 0-32 32v32a32 32 0 0 0 32 32zM384 416h96a32 32 0 0 0 32-32v-32a32 32 0 0 0-32-32h-96a32 32 0 0 0-32 32v32a32 32 0 0 0 32 32zM576 416h96a32 32 0 0 0 32-32v-32a32 32 0 0 0-32-32h-96a32 32 0 0 0-32 32v32a32 32 0 0 0 32 32zM832 320h-64a32 32 0 0 0-32 32v128h-160a32 32 0 0 0-32 32v32a32 32 0 0 0 32 32h256a32 32 0 0 0 32-32v-192a32 32 0 0 0-32-32zM320 544v-32a32 32 0 0 0-32-32H192a32 32 0 0 0-32 32v32a32 32 0 0 0 32 32h96a32 32 0 0 0 32-32zM384 576h96a32 32 0 0 0 32-32v-32a32 32 0 0 0-32-32h-96a32 32 0 0 0-32 32v32a32 32 0 0 0 32 32zM800 640H256a32 32 0 0 0-32 32v32a32 32 0 0 0 32 32h544a32 32 0 0 0 32-32v-32a32 32 0 0 0-32-32z</StreamGeometry> <StreamGeometry x:Key="Icons.Hotkeys">M512 0C229.216 0 0 229.216 0 512c0 282.752 229.216 512 512 512s512-229.248 512-512c0-282.784-229.216-512-512-512z m0 957.92C266.112 957.92 66.08 757.888 66.08 512S266.112 66.08 512 66.08 957.92 266.112 957.92 512 757.888 957.92 512 957.92zM192 416h96a32 32 0 0 0 32-32v-32a32 32 0 0 0-32-32H192a32 32 0 0 0-32 32v32a32 32 0 0 0 32 32zM384 416h96a32 32 0 0 0 32-32v-32a32 32 0 0 0-32-32h-96a32 32 0 0 0-32 32v32a32 32 0 0 0 32 32zM576 416h96a32 32 0 0 0 32-32v-32a32 32 0 0 0-32-32h-96a32 32 0 0 0-32 32v32a32 32 0 0 0 32 32zM832 320h-64a32 32 0 0 0-32 32v128h-160a32 32 0 0 0-32 32v32a32 32 0 0 0 32 32h256a32 32 0 0 0 32-32v-192a32 32 0 0 0-32-32zM320 544v-32a32 32 0 0 0-32-32H192a32 32 0 0 0-32 32v32a32 32 0 0 0 32 32h96a32 32 0 0 0 32-32zM384 576h96a32 32 0 0 0 32-32v-32a32 32 0 0 0-32-32h-96a32 32 0 0 0-32 32v32a32 32 0 0 0 32 32zM800 640H256a32 32 0 0 0-32 32v32a32 32 0 0 0 32 32h544a32 32 0 0 0 32-32v-32a32 32 0 0 0-32-32z</StreamGeometry>
<StreamGeometry x:Key="Icons.SideBySide">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</StreamGeometry> <StreamGeometry x:Key="Icons.SideBySide">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</StreamGeometry>
<StreamGeometry x:Key="Icons.SyntaxHighlight">M875 128h-725A107 107 0 0043 235v555A107 107 0 00149 896h725a107 107 0 00107-107v-555A107 107 0 00875 128zm-115 640h-183v-58l25-3c15 0 19-8 14-24l-22-61H419l-28 82 39 2V768h-166v-58l18-3c18-2 22-11 26-24l125-363-40-4V256h168l160 448 39 3zM506 340l-72 218h145l-71-218h-2z</StreamGeometry>
</ResourceDictionary> </ResourceDictionary>

View file

@ -1284,6 +1284,15 @@ namespace SourceGit.Resources {
} }
} }
/// <summary>
/// Looks up a localized string similar to Syntax Highlighting.
/// </summary>
public static string Text_Diff_SyntaxHighlight {
get {
return ResourceManager.GetString("Text.Diff.SyntaxHighlight", resourceCulture);
}
}
/// <summary> /// <summary>
/// Looks up a localized string similar to Open With Merge Tool. /// Looks up a localized string similar to Open With Merge Tool.
/// </summary> /// </summary>

View file

@ -1287,4 +1287,7 @@
<data name="Text.Cut" xml:space="preserve"> <data name="Text.Cut" xml:space="preserve">
<value>Cut</value> <value>Cut</value>
</data> </data>
<data name="Text.Diff.SyntaxHighlight" xml:space="preserve">
<value>Syntax Highlighting</value>
</data>
</root> </root>

View file

@ -1287,4 +1287,7 @@
<data name="Text.Cut" xml:space="preserve"> <data name="Text.Cut" xml:space="preserve">
<value>Cut</value> <value>Cut</value>
</data> </data>
<data name="Text.Diff.SyntaxHighlight" xml:space="preserve">
<value>Syntax Highlighting</value>
</data>
</root> </root>

View file

@ -1287,4 +1287,7 @@
<data name="Text.Cut" xml:space="preserve"> <data name="Text.Cut" xml:space="preserve">
<value>剪切</value> <value>剪切</value>
</data> </data>
<data name="Text.Diff.SyntaxHighlight" xml:space="preserve">
<value>语法高亮</value>
</data>
</root> </root>

View file

@ -114,6 +114,12 @@ namespace SourceGit.ViewModels
set => SetProperty(ref _useSideBySideDiff, value); set => SetProperty(ref _useSideBySideDiff, value);
} }
public bool UseSyntaxHighlighting
{
get => _useSyntaxHighlighting;
set => SetProperty(ref _useSyntaxHighlighting, value);
}
public Models.ChangeViewMode UnstagedChangeViewMode public Models.ChangeViewMode UnstagedChangeViewMode
{ {
get => _unstagedChangeViewMode; get => _unstagedChangeViewMode;
@ -351,6 +357,7 @@ namespace SourceGit.ViewModels
private bool _useFixedTabWidth = true; private bool _useFixedTabWidth = true;
private bool _useTwoColumnsLayoutInHistories = false; private bool _useTwoColumnsLayoutInHistories = false;
private bool _useSideBySideDiff = false; private bool _useSideBySideDiff = false;
private bool _useSyntaxHighlighting = false;
private Models.ChangeViewMode _unstagedChangeViewMode = Models.ChangeViewMode.List; private Models.ChangeViewMode _unstagedChangeViewMode = Models.ChangeViewMode.List;
private Models.ChangeViewMode _stagedChangeViewMode = Models.ChangeViewMode.List; private Models.ChangeViewMode _stagedChangeViewMode = Models.ChangeViewMode.List;

View file

@ -27,13 +27,22 @@
</StackPanel> </StackPanel>
<StackPanel Grid.Column="2" Margin="32,0,0,0" Orientation="Horizontal" IsVisible="{Binding IsTextDiff}" VerticalAlignment="Center"> <StackPanel Grid.Column="2" Margin="32,0,0,0" Orientation="Horizontal" IsVisible="{Binding IsTextDiff}" VerticalAlignment="Center">
<ToggleButton Classes="line_path"
Width="32" Height="18"
Background="Transparent"
Padding="9,6"
IsChecked="{Binding Source={x:Static vm:Preference.Instance}, Path=UseSyntaxHighlighting, Mode=TwoWay}"
ToolTip.Tip="{DynamicResource Text.Diff.SyntaxHighlight}">
<Path Width="13" Height="13" Data="{StaticResource Icons.SyntaxHighlight}" Margin="0,3,0,0"/>
</ToggleButton>
<ToggleButton Classes="line_path" <ToggleButton Classes="line_path"
Width="32" Height="18" Width="32" Height="18"
Background="Transparent" Background="Transparent"
Padding="9,6" Padding="9,6"
IsChecked="{Binding Source={x:Static vm:Preference.Instance}, Path=UseSideBySideDiff, Mode=TwoWay}" IsChecked="{Binding Source={x:Static vm:Preference.Instance}, Path=UseSideBySideDiff, Mode=TwoWay}"
ToolTip.Tip="{DynamicResource Text.Diff.SideBySide}"> ToolTip.Tip="{DynamicResource Text.Diff.SideBySide}">
<Path Width="12" Height="12" Data="{StaticResource Icons.SideBySide}"/> <Path Width="12" Height="12" Data="{StaticResource Icons.SideBySide}" Margin="0,2,0,0"/>
</ToggleButton> </ToggleButton>
<Button Classes="icon_button" Width="32" Command="{Binding OpenExternalMergeTool}" ToolTip.Tip="{DynamicResource Text.Diff.UseMerger}"> <Button Classes="icon_button" Width="32" Command="{Binding OpenExternalMergeTool}" ToolTip.Tip="{DynamicResource Text.Diff.UseMerger}">

View file

@ -20,13 +20,15 @@
FontFamily="fonts:SourceGit#JetBrains Mono" FontFamily="fonts:SourceGit#JetBrains Mono"
FontSize="12" FontSize="12"
DiffData="{Binding}" DiffData="{Binding}"
SyncScrollOffset="{Binding $parent[v:DiffView].DataContext.(vm:DiffContext).SyncScrollOffset, Mode=TwoWay}"/> SyncScrollOffset="{Binding $parent[v:DiffView].DataContext.(vm:DiffContext).SyncScrollOffset, Mode=TwoWay}"
UseSyntaxHighlighting="{Binding Source={x:Static vm:Preference.Instance}, Path=UseSyntaxHighlighting, Mode=TwoWay}"/>
</DataTemplate> </DataTemplate>
<DataTemplate DataType="vm:TwoSideTextDiff"> <DataTemplate DataType="vm:TwoSideTextDiff">
<Grid ColumnDefinitions="*,1,*"> <Grid ColumnDefinitions="*,1,*">
<v:SingleSideTextDiffPresenter Grid.Column="0" <v:SingleSideTextDiffPresenter Grid.Column="0"
SyncScrollOffset="{Binding $parent[v:DiffView].DataContext.(vm:DiffContext).SyncScrollOffset, Mode=TwoWay}" SyncScrollOffset="{Binding $parent[v:DiffView].DataContext.(vm:DiffContext).SyncScrollOffset, Mode=TwoWay}"
UseSyntaxHighlighting="{Binding Source={x:Static vm:Preference.Instance}, Path=UseSyntaxHighlighting, Mode=TwoWay}"
IsOld="True" IsOld="True"
HorizontalScrollBarVisibility="Auto" HorizontalScrollBarVisibility="Auto"
VerticalScrollBarVisibility="Auto" VerticalScrollBarVisibility="Auto"
@ -42,6 +44,7 @@
<v:SingleSideTextDiffPresenter Grid.Column="2" <v:SingleSideTextDiffPresenter Grid.Column="2"
SyncScrollOffset="{Binding $parent[v:DiffView].DataContext.(vm:DiffContext).SyncScrollOffset, Mode=TwoWay}" SyncScrollOffset="{Binding $parent[v:DiffView].DataContext.(vm:DiffContext).SyncScrollOffset, Mode=TwoWay}"
UseSyntaxHighlighting="{Binding Source={x:Static vm:Preference.Instance}, Path=UseSyntaxHighlighting, Mode=TwoWay}"
IsOld="False" IsOld="False"
HorizontalScrollBarVisibility="Auto" HorizontalScrollBarVisibility="Auto"
VerticalScrollBarVisibility="Auto" VerticalScrollBarVisibility="Auto"

View file

@ -224,6 +224,15 @@ namespace SourceGit.Views
set => SetValue(SyncScrollOffsetProperty, value); set => SetValue(SyncScrollOffsetProperty, value);
} }
public static readonly StyledProperty<bool> UseSyntaxHighlightingProperty =
AvaloniaProperty.Register<SingleSideTextDiffPresenter, bool>(nameof(UseSyntaxHighlighting), false);
public bool UseSyntaxHighlighting
{
get => GetValue(UseSyntaxHighlightingProperty);
set => SetValue(UseSyntaxHighlightingProperty, value);
}
protected override Type StyleKeyOverride => typeof(TextEditor); protected override Type StyleKeyOverride => typeof(TextEditor);
public CombinedTextDiffPresenter() : base(new TextArea(), new TextDocument()) public CombinedTextDiffPresenter() : base(new TextArea(), new TextDocument())
@ -241,16 +250,15 @@ namespace SourceGit.Views
TextArea.TextView.Margin = new Thickness(4, 0); TextArea.TextView.Margin = new Thickness(4, 0);
TextArea.TextView.BackgroundRenderers.Add(new LineBackgroundRenderer(this)); TextArea.TextView.BackgroundRenderers.Add(new LineBackgroundRenderer(this));
TextArea.TextView.LineTransformers.Add(_lineStyleTransformer);
} }
protected override void OnLoaded(RoutedEventArgs e) protected override void OnLoaded(RoutedEventArgs e)
{ {
base.OnLoaded(e); base.OnLoaded(e);
_textMate = Models.TextMateHelper.CreateForEditor(this); UpdateTextMate();
if (DiffData != null) Models.TextMateHelper.SetGrammarByFileName(_textMate, DiffData.File);
TextArea.TextView.LineTransformers.Add(_lineStyleTransformer);
TextArea.TextView.ContextRequested += OnTextViewContextRequested; TextArea.TextView.ContextRequested += OnTextViewContextRequested;
TextArea.TextView.ScrollOffsetChanged += OnTextViewScrollOffsetChanged; TextArea.TextView.ScrollOffsetChanged += OnTextViewScrollOffsetChanged;
} }
@ -259,7 +267,6 @@ namespace SourceGit.Views
{ {
base.OnUnloaded(e); base.OnUnloaded(e);
TextArea.TextView.LineTransformers.Remove(_lineStyleTransformer);
TextArea.TextView.ContextRequested -= OnTextViewContextRequested; TextArea.TextView.ContextRequested -= OnTextViewContextRequested;
TextArea.TextView.ScrollOffsetChanged -= OnTextViewScrollOffsetChanged; TextArea.TextView.ScrollOffsetChanged -= OnTextViewScrollOffsetChanged;
@ -333,12 +340,42 @@ namespace SourceGit.Views
scrollable.Offset = SyncScrollOffset; scrollable.Offset = SyncScrollOffset;
} }
} }
else if (change.Property == UseSyntaxHighlightingProperty)
{
UpdateTextMate();
}
else if (change.Property.Name == "ActualThemeVariant" && change.NewValue != null) else if (change.Property.Name == "ActualThemeVariant" && change.NewValue != null)
{ {
Models.TextMateHelper.SetThemeByApp(_textMate); Models.TextMateHelper.SetThemeByApp(_textMate);
} }
} }
private void UpdateTextMate()
{
if (UseSyntaxHighlighting)
{
if (_textMate == null)
{
TextArea.TextView.LineTransformers.Remove(_lineStyleTransformer);
_textMate = Models.TextMateHelper.CreateForEditor(this);
TextArea.TextView.LineTransformers.Add(_lineStyleTransformer);
if (DiffData != null) Models.TextMateHelper.SetGrammarByFileName(_textMate, DiffData.File);
}
}
else
{
if (_textMate != null)
{
_textMate.Dispose();
_textMate = null;
GC.Collect();
TextArea.TextView.Redraw();
}
}
}
private TextMate.Installation _textMate; private TextMate.Installation _textMate;
private LineStyleTransformer _lineStyleTransformer = null; private LineStyleTransformer _lineStyleTransformer = null;
} }
@ -557,6 +594,15 @@ namespace SourceGit.Views
set => SetValue(SyncScrollOffsetProperty, value); set => SetValue(SyncScrollOffsetProperty, value);
} }
public static readonly StyledProperty<bool> UseSyntaxHighlightingProperty =
AvaloniaProperty.Register<SingleSideTextDiffPresenter, bool>(nameof(UseSyntaxHighlighting), false);
public bool UseSyntaxHighlighting
{
get => GetValue(UseSyntaxHighlightingProperty);
set => SetValue(UseSyntaxHighlightingProperty, value);
}
protected override Type StyleKeyOverride => typeof(TextEditor); protected override Type StyleKeyOverride => typeof(TextEditor);
public SingleSideTextDiffPresenter() : base(new TextArea(), new TextDocument()) public SingleSideTextDiffPresenter() : base(new TextArea(), new TextDocument())
@ -571,6 +617,7 @@ namespace SourceGit.Views
TextArea.LeftMargins.Add(new VerticalSeperatorMargin(this)); TextArea.LeftMargins.Add(new VerticalSeperatorMargin(this));
TextArea.TextView.Margin = new Thickness(4, 0); TextArea.TextView.Margin = new Thickness(4, 0);
TextArea.TextView.BackgroundRenderers.Add(new LineBackgroundRenderer(this)); TextArea.TextView.BackgroundRenderers.Add(new LineBackgroundRenderer(this));
TextArea.TextView.LineTransformers.Add(_lineStyleTransformer);
} }
protected override void OnLoaded(RoutedEventArgs e) protected override void OnLoaded(RoutedEventArgs e)
@ -584,10 +631,8 @@ namespace SourceGit.Views
_scrollViewer.ScrollChanged += OnTextViewScrollChanged; _scrollViewer.ScrollChanged += OnTextViewScrollChanged;
} }
_textMate = Models.TextMateHelper.CreateForEditor(this); UpdateTextMate();
if (DiffData != null) Models.TextMateHelper.SetGrammarByFileName(_textMate, DiffData.File);
TextArea.TextView.LineTransformers.Add(_lineStyleTransformer);
TextArea.TextView.ContextRequested += OnTextViewContextRequested; TextArea.TextView.ContextRequested += OnTextViewContextRequested;
} }
@ -607,7 +652,6 @@ namespace SourceGit.Views
_textMate = null; _textMate = null;
} }
TextArea.TextView.LineTransformers.Remove(_lineStyleTransformer);
TextArea.TextView.ContextRequested -= OnTextViewContextRequested; TextArea.TextView.ContextRequested -= OnTextViewContextRequested;
GC.Collect(); GC.Collect();
@ -703,12 +747,42 @@ namespace SourceGit.Views
} }
} }
} }
else if (change.Property == UseSyntaxHighlightingProperty)
{
UpdateTextMate();
}
else if (change.Property.Name == "ActualThemeVariant" && change.NewValue != null) else if (change.Property.Name == "ActualThemeVariant" && change.NewValue != null)
{ {
Models.TextMateHelper.SetThemeByApp(_textMate); Models.TextMateHelper.SetThemeByApp(_textMate);
} }
} }
private void UpdateTextMate()
{
if (UseSyntaxHighlighting)
{
if (_textMate == null)
{
TextArea.TextView.LineTransformers.Remove(_lineStyleTransformer);
_textMate = Models.TextMateHelper.CreateForEditor(this);
TextArea.TextView.LineTransformers.Add(_lineStyleTransformer);
if (DiffData != null) Models.TextMateHelper.SetGrammarByFileName(_textMate, DiffData.File);
}
}
else
{
if (_textMate != null)
{
_textMate.Dispose();
_textMate = null;
GC.Collect();
TextArea.TextView.Redraw();
}
}
}
private TextMate.Installation _textMate; private TextMate.Installation _textMate;
private LineStyleTransformer _lineStyleTransformer = null; private LineStyleTransformer _lineStyleTransformer = null;
private ScrollViewer _scrollViewer = null; private ScrollViewer _scrollViewer = null;