mirror of
https://github.com/sourcegit-scm/sourcegit
synced 2025-06-26 21:04:59 +00:00
Merge branch 'sourcegit-scm:develop' into develop
This commit is contained in:
commit
3668d4904c
11 changed files with 211 additions and 172 deletions
6
.github/workflows/ci.yml
vendored
6
.github/workflows/ci.yml
vendored
|
@ -9,7 +9,7 @@ on:
|
||||||
jobs:
|
jobs:
|
||||||
build-windows:
|
build-windows:
|
||||||
name: Build Windows x64
|
name: Build Windows x64
|
||||||
runs-on: windows-latest
|
runs-on: windows-2019
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout sources
|
- name: Checkout sources
|
||||||
uses: actions/checkout@v4
|
uses: actions/checkout@v4
|
||||||
|
@ -30,7 +30,7 @@ jobs:
|
||||||
path: publish
|
path: publish
|
||||||
build-macos-intel:
|
build-macos-intel:
|
||||||
name: Build macOS (Intel)
|
name: Build macOS (Intel)
|
||||||
runs-on: macos-latest
|
runs-on: macos-13
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout sources
|
- name: Checkout sources
|
||||||
uses: actions/checkout@v4
|
uses: actions/checkout@v4
|
||||||
|
@ -76,7 +76,7 @@ jobs:
|
||||||
path: sourcegit.osx-arm64.tar
|
path: sourcegit.osx-arm64.tar
|
||||||
build-linux:
|
build-linux:
|
||||||
name: Build Linux
|
name: Build Linux
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-20.04
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout sources
|
- name: Checkout sources
|
||||||
uses: actions/checkout@v4
|
uses: actions/checkout@v4
|
||||||
|
|
|
@ -188,6 +188,8 @@ namespace SourceGit
|
||||||
else
|
else
|
||||||
Models.CommitGraph.SetDefaultPens(overrides.GraphPenThickness);
|
Models.CommitGraph.SetDefaultPens(overrides.GraphPenThickness);
|
||||||
|
|
||||||
|
Models.Commit.OpacityForNotMerged = overrides.OpacityForNotMergedCommits;
|
||||||
|
|
||||||
app.Resources.MergedDictionaries.Add(resDic);
|
app.Resources.MergedDictionaries.Add(resDic);
|
||||||
app._themeOverrides = resDic;
|
app._themeOverrides = resDic;
|
||||||
}
|
}
|
||||||
|
|
|
@ -14,7 +14,14 @@ namespace SourceGit.Commands
|
||||||
_findFirstMerged = needFindHead;
|
_findFirstMerged = needFindHead;
|
||||||
}
|
}
|
||||||
|
|
||||||
public QueryCommits(string repo, int maxCount, string messageFilter)
|
public QueryCommits(string repo, int maxCount, string messageFilter, bool isFile)
|
||||||
|
{
|
||||||
|
string search;
|
||||||
|
if (isFile)
|
||||||
|
{
|
||||||
|
search = $"-- \"{messageFilter}\"";
|
||||||
|
}
|
||||||
|
else
|
||||||
{
|
{
|
||||||
var argsBuilder = new StringBuilder();
|
var argsBuilder = new StringBuilder();
|
||||||
var words = messageFilter.Split(new[] { ' ', '\t', '\r' }, StringSplitOptions.RemoveEmptyEntries);
|
var words = messageFilter.Split(new[] { ' ', '\t', '\r' }, StringSplitOptions.RemoveEmptyEntries);
|
||||||
|
@ -23,11 +30,14 @@ namespace SourceGit.Commands
|
||||||
var escaped = word.Trim().Replace("\"", "\\\"", StringComparison.Ordinal);
|
var escaped = word.Trim().Replace("\"", "\\\"", StringComparison.Ordinal);
|
||||||
argsBuilder.Append($"--grep=\"{escaped}\" ");
|
argsBuilder.Append($"--grep=\"{escaped}\" ");
|
||||||
}
|
}
|
||||||
argsBuilder.Append("--all-match");
|
argsBuilder.Append("--all-match -i");
|
||||||
|
search = argsBuilder.ToString();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
WorkingDirectory = repo;
|
WorkingDirectory = repo;
|
||||||
Context = repo;
|
Context = repo;
|
||||||
Args = $"log -{maxCount} --date-order --no-show-signature --decorate=full --pretty=format:%H%n%P%n%D%n%aN±%aE%n%at%n%cN±%cE%n%ct%n%s " + argsBuilder.ToString();
|
Args = $"log -{maxCount} --date-order --no-show-signature --decorate=full --pretty=format:%H%n%P%n%D%n%aN±%aE%n%at%n%cN±%cE%n%ct%n%s --branches --remotes " + search;
|
||||||
_findFirstMerged = false;
|
_findFirstMerged = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,4 @@
|
||||||
using Avalonia.Data.Converters;
|
using Avalonia.Data.Converters;
|
||||||
using Avalonia.Media;
|
|
||||||
|
|
||||||
namespace SourceGit.Converters
|
namespace SourceGit.Converters
|
||||||
{
|
{
|
||||||
|
@ -7,11 +6,5 @@ namespace SourceGit.Converters
|
||||||
{
|
{
|
||||||
public static readonly FuncValueConverter<bool, double> ToPageTabWidth =
|
public static readonly FuncValueConverter<bool, double> ToPageTabWidth =
|
||||||
new FuncValueConverter<bool, double>(x => x ? 200 : double.NaN);
|
new FuncValueConverter<bool, double>(x => x ? 200 : double.NaN);
|
||||||
|
|
||||||
public static readonly FuncValueConverter<bool, double> HalfIfFalse =
|
|
||||||
new FuncValueConverter<bool, double>(x => x ? 1 : 0.5);
|
|
||||||
|
|
||||||
public static readonly FuncValueConverter<bool, FontWeight> BoldIfTrue =
|
|
||||||
new FuncValueConverter<bool, FontWeight>(x => x ? FontWeight.Bold : FontWeight.Regular);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,11 +2,18 @@
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
|
||||||
using Avalonia;
|
using Avalonia;
|
||||||
|
using Avalonia.Media;
|
||||||
|
|
||||||
namespace SourceGit.Models
|
namespace SourceGit.Models
|
||||||
{
|
{
|
||||||
public class Commit
|
public class Commit
|
||||||
{
|
{
|
||||||
|
public static double OpacityForNotMerged
|
||||||
|
{
|
||||||
|
get;
|
||||||
|
set;
|
||||||
|
} = 0.5;
|
||||||
|
|
||||||
public string SHA { get; set; } = string.Empty;
|
public string SHA { get; set; } = string.Empty;
|
||||||
public User Author { get; set; } = User.Invalid;
|
public User Author { get; set; } = User.Invalid;
|
||||||
public ulong AuthorTime { get; set; } = 0;
|
public ulong AuthorTime { get; set; } = 0;
|
||||||
|
@ -25,5 +32,8 @@ namespace SourceGit.Models
|
||||||
|
|
||||||
public bool IsCommitterVisible => !Author.Equals(Committer) || AuthorTime != CommitterTime;
|
public bool IsCommitterVisible => !Author.Equals(Committer) || AuthorTime != CommitterTime;
|
||||||
public bool IsCurrentHead => Decorators.Find(x => x.Type is DecoratorType.CurrentBranchHead or DecoratorType.CurrentCommitHead) != null;
|
public bool IsCurrentHead => Decorators.Find(x => x.Type is DecoratorType.CurrentBranchHead or DecoratorType.CurrentCommitHead) != null;
|
||||||
|
|
||||||
|
public double Opacity => IsMerged ? 1 : OpacityForNotMerged;
|
||||||
|
public FontWeight FontWeight => IsCurrentHead ? FontWeight.Bold : FontWeight.Regular;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -69,6 +69,80 @@ namespace SourceGit.Models
|
||||||
public string Repo { get; set; } = null;
|
public string Repo { get; set; } = null;
|
||||||
public DiffOption Option { get; set; } = null;
|
public DiffOption Option { get; set; } = null;
|
||||||
|
|
||||||
|
public TextDiffSelection MakeSelection(int startLine, int endLine, bool isSideBySide, bool isOldSide)
|
||||||
|
{
|
||||||
|
var rs = new TextDiffSelection();
|
||||||
|
rs.StartLine = startLine;
|
||||||
|
rs.EndLine = endLine;
|
||||||
|
|
||||||
|
for (int i = 0; i < startLine - 1; i++)
|
||||||
|
{
|
||||||
|
var line = Lines[i];
|
||||||
|
if (line.Type == TextDiffLineType.Added)
|
||||||
|
{
|
||||||
|
rs.HasLeftChanges = true;
|
||||||
|
rs.IgnoredAdds++;
|
||||||
|
}
|
||||||
|
else if (line.Type == TextDiffLineType.Deleted)
|
||||||
|
{
|
||||||
|
rs.HasLeftChanges = true;
|
||||||
|
rs.IgnoredDeletes++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int i = startLine - 1; i < endLine; i++)
|
||||||
|
{
|
||||||
|
var line = Lines[i];
|
||||||
|
if (line.Type == TextDiffLineType.Added)
|
||||||
|
{
|
||||||
|
if (!isSideBySide)
|
||||||
|
{
|
||||||
|
rs.HasChanges = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
else if (isOldSide)
|
||||||
|
{
|
||||||
|
rs.HasLeftChanges = true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
rs.HasChanges = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (line.Type == TextDiffLineType.Deleted)
|
||||||
|
{
|
||||||
|
if (!isSideBySide)
|
||||||
|
{
|
||||||
|
rs.HasChanges = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
else if (isOldSide)
|
||||||
|
{
|
||||||
|
rs.HasChanges = true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
rs.HasLeftChanges = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!rs.HasLeftChanges)
|
||||||
|
{
|
||||||
|
for (int i = endLine; i < Lines.Count; i++)
|
||||||
|
{
|
||||||
|
var line = Lines[i];
|
||||||
|
if (line.Type == TextDiffLineType.Added || line.Type == TextDiffLineType.Deleted)
|
||||||
|
{
|
||||||
|
rs.HasLeftChanges = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return rs;
|
||||||
|
}
|
||||||
|
|
||||||
public void GenerateNewPatchFromSelection(Change change, string fileBlobGuid, TextDiffSelection selection, bool revert, string output)
|
public void GenerateNewPatchFromSelection(Change change, string fileBlobGuid, TextDiffSelection selection, bool revert, string output)
|
||||||
{
|
{
|
||||||
var isTracked = !string.IsNullOrEmpty(fileBlobGuid);
|
var isTracked = !string.IsNullOrEmpty(fileBlobGuid);
|
||||||
|
@ -392,9 +466,6 @@ namespace SourceGit.Models
|
||||||
System.IO.File.WriteAllText(output, builder.ToString());
|
System.IO.File.WriteAllText(output, builder.ToString());
|
||||||
}
|
}
|
||||||
|
|
||||||
[GeneratedRegex(@"^@@ \-(\d+),?\d* \+(\d+),?\d* @@")]
|
|
||||||
private static partial Regex REG_INDICATOR();
|
|
||||||
|
|
||||||
private bool ProcessIndicatorForPatch(StringBuilder builder, TextDiffLine indicator, int idx, int start, int end, int ignoreRemoves, int ignoreAdds, bool revert, bool tailed)
|
private bool ProcessIndicatorForPatch(StringBuilder builder, TextDiffLine indicator, int idx, int start, int end, int ignoreRemoves, int ignoreAdds, bool revert, bool tailed)
|
||||||
{
|
{
|
||||||
var match = REG_INDICATOR().Match(indicator.Content);
|
var match = REG_INDICATOR().Match(indicator.Content);
|
||||||
|
@ -554,6 +625,9 @@ namespace SourceGit.Models
|
||||||
builder.Append($"\n@@ -{oldStart},{oldCount} +{newStart},{newCount} @@");
|
builder.Append($"\n@@ -{oldStart},{oldCount} +{newStart},{newCount} @@");
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[GeneratedRegex(@"^@@ \-(\d+),?\d* \+(\d+),?\d* @@")]
|
||||||
|
private static partial Regex REG_INDICATOR();
|
||||||
}
|
}
|
||||||
|
|
||||||
public class LFSDiff
|
public class LFSDiff
|
||||||
|
|
|
@ -8,6 +8,7 @@ namespace SourceGit.Models
|
||||||
{
|
{
|
||||||
public Dictionary<string, Color> BasicColors { get; set; } = new Dictionary<string, Color>();
|
public Dictionary<string, Color> BasicColors { get; set; } = new Dictionary<string, Color>();
|
||||||
public double GraphPenThickness { get; set; } = 2;
|
public double GraphPenThickness { get; set; } = 2;
|
||||||
|
public double OpacityForNotMergedCommits { get; set; } = 0.5;
|
||||||
public List<Color> GraphColors { get; set; } = new List<Color>();
|
public List<Color> GraphColors { get; set; } = new List<Color>();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -566,10 +566,10 @@ namespace SourceGit.ViewModels
|
||||||
|
|
||||||
break;
|
break;
|
||||||
case 2:
|
case 2:
|
||||||
visible = new Commands.QueryCommits(FullPath, 1000, _searchCommitFilter).Result();
|
visible = new Commands.QueryCommits(FullPath, 1000, _searchCommitFilter, false).Result();
|
||||||
break;
|
break;
|
||||||
case 3:
|
case 3:
|
||||||
visible = new Commands.QueryCommits(FullPath, $"-1000 -- \"{_searchCommitFilter}\"", false).Result();
|
visible = new Commands.QueryCommits(FullPath, 1000, _searchCommitFilter, true).Result();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,8 @@
|
||||||
using System.Collections.Generic;
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
|
||||||
using Avalonia;
|
using Avalonia;
|
||||||
|
|
||||||
using CommunityToolkit.Mvvm.ComponentModel;
|
using CommunityToolkit.Mvvm.ComponentModel;
|
||||||
|
|
||||||
namespace SourceGit.ViewModels
|
namespace SourceGit.ViewModels
|
||||||
|
@ -53,6 +56,45 @@ namespace SourceGit.ViewModels
|
||||||
_syncScrollOffset = previous._syncScrollOffset;
|
_syncScrollOffset = previous._syncScrollOffset;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void ConvertsToCombinedRange(Models.TextDiff combined, ref int startLine, ref int endLine, bool isOldSide)
|
||||||
|
{
|
||||||
|
endLine = Math.Min(endLine, combined.Lines.Count);
|
||||||
|
|
||||||
|
var oneSide = isOldSide ? Old : New;
|
||||||
|
var firstContentLine = -1;
|
||||||
|
for (int i = startLine - 1; 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 - 1, oneSide.Count - 1); i >= startLine - 1; 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) + 1;
|
||||||
|
endLine = combined.Lines.IndexOf(endContent) + 1;
|
||||||
|
}
|
||||||
|
|
||||||
private void FillEmptyLines()
|
private void FillEmptyLines()
|
||||||
{
|
{
|
||||||
if (Old.Count < New.Count)
|
if (Old.Count < New.Count)
|
||||||
|
|
|
@ -103,8 +103,8 @@
|
||||||
|
|
||||||
<TextBlock Classes="monospace"
|
<TextBlock Classes="monospace"
|
||||||
Text="{Binding Subject}"
|
Text="{Binding Subject}"
|
||||||
Opacity="{Binding IsMerged, Converter={x:Static c:BoolConverters.HalfIfFalse}}"
|
Opacity="{Binding Opacity}"
|
||||||
FontWeight="{Binding IsCurrentHead, Converter={x:Static c:BoolConverters.BoldIfTrue}}"/>
|
FontWeight="{Binding FontWeight}"/>
|
||||||
</StackPanel>
|
</StackPanel>
|
||||||
</Border>
|
</Border>
|
||||||
</DataTemplate>
|
</DataTemplate>
|
||||||
|
@ -124,13 +124,13 @@
|
||||||
VerticalAlignment="Center"
|
VerticalAlignment="Center"
|
||||||
IsHitTestVisible="False"
|
IsHitTestVisible="False"
|
||||||
User="{Binding Author}"
|
User="{Binding Author}"
|
||||||
Opacity="{Binding IsMerged, Converter={x:Static c:BoolConverters.HalfIfFalse}}"/>
|
Opacity="{Binding Opacity}"/>
|
||||||
<TextBlock Grid.Column="1"
|
<TextBlock Grid.Column="1"
|
||||||
Classes="monospace"
|
Classes="monospace"
|
||||||
Text="{Binding Author.Name}"
|
Text="{Binding Author.Name}"
|
||||||
Margin="8,0,0,0"
|
Margin="8,0,0,0"
|
||||||
Opacity="{Binding IsMerged, Converter={x:Static c:BoolConverters.HalfIfFalse}}"
|
Opacity="{Binding Opacity}"
|
||||||
FontWeight="{Binding IsCurrentHead, Converter={x:Static c:BoolConverters.BoldIfTrue}}"/>
|
FontWeight="{Binding FontWeight}"/>
|
||||||
</Grid>
|
</Grid>
|
||||||
</DataTemplate>
|
</DataTemplate>
|
||||||
</DataGridTemplateColumn.CellTemplate>
|
</DataGridTemplateColumn.CellTemplate>
|
||||||
|
@ -147,8 +147,8 @@
|
||||||
Text="{Binding SHA, Converter={x:Static c:StringConverters.ToShortSHA}}"
|
Text="{Binding SHA, Converter={x:Static c:StringConverters.ToShortSHA}}"
|
||||||
Margin="8,0"
|
Margin="8,0"
|
||||||
HorizontalAlignment="Center"
|
HorizontalAlignment="Center"
|
||||||
Opacity="{Binding IsMerged, Converter={x:Static c:BoolConverters.HalfIfFalse}}"
|
Opacity="{Binding Opacity}"
|
||||||
FontWeight="{Binding IsCurrentHead, Converter={x:Static c:BoolConverters.BoldIfTrue}}"/>
|
FontWeight="{Binding FontWeight}"/>
|
||||||
</DataTemplate>
|
</DataTemplate>
|
||||||
</DataGridTemplateColumn.CellTemplate>
|
</DataGridTemplateColumn.CellTemplate>
|
||||||
</DataGridTemplateColumn>
|
</DataGridTemplateColumn>
|
||||||
|
@ -169,8 +169,8 @@
|
||||||
<v:CommitTimeTextBlock Classes="monospace"
|
<v:CommitTimeTextBlock Classes="monospace"
|
||||||
Margin="8,0"
|
Margin="8,0"
|
||||||
HorizontalAlignment="Center"
|
HorizontalAlignment="Center"
|
||||||
Opacity="{Binding IsMerged, Converter={x:Static c:BoolConverters.HalfIfFalse}}"
|
Opacity="{Binding Opacity}"
|
||||||
FontWeight="{Binding IsCurrentHead, Converter={x:Static c:BoolConverters.BoldIfTrue}}"
|
FontWeight="{Binding FontWeight}"
|
||||||
Timestamp="{Binding CommitterTime}"
|
Timestamp="{Binding CommitterTime}"
|
||||||
ShowAsDateTime="{Binding Source={x:Static vm:Preference.Instance}, Path=!DisplayTimeAsPeriodInHistories}"/>
|
ShowAsDateTime="{Binding Source={x:Static vm:Preference.Instance}, Path=!DisplayTimeAsPeriodInHistories}"/>
|
||||||
</DataTemplate>
|
</DataTemplate>
|
||||||
|
|
|
@ -29,6 +29,17 @@ namespace SourceGit.Views
|
||||||
public double Height { get; set; } = 0.0;
|
public double Height { get; set; } = 0.0;
|
||||||
public int StartIdx { get; set; } = 0;
|
public int StartIdx { get; set; } = 0;
|
||||||
public int EndIdx { get; set; } = 0;
|
public int EndIdx { get; set; } = 0;
|
||||||
|
|
||||||
|
public bool ShouldReplace(TextViewHighlightChunk old)
|
||||||
|
{
|
||||||
|
if (old == null)
|
||||||
|
return true;
|
||||||
|
|
||||||
|
return Math.Abs(Y - old.Y) > 0.001 ||
|
||||||
|
Math.Abs(Height - old.Height) > 0.001 ||
|
||||||
|
StartIdx != old.StartIdx ||
|
||||||
|
EndIdx != old.EndIdx;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public class ThemedTextDiffPresenter : TextEditor
|
public class ThemedTextDiffPresenter : TextEditor
|
||||||
|
@ -158,11 +169,11 @@ namespace SourceGit.Views
|
||||||
return;
|
return;
|
||||||
|
|
||||||
var color = (Color)this.FindResource("SystemAccentColor");
|
var color = (Color)this.FindResource("SystemAccentColor");
|
||||||
var brush = new SolidColorBrush(color, 0.5);
|
var brush = new SolidColorBrush(color, 0.1);
|
||||||
var pen = new Pen(color.ToUInt32());
|
var pen = new Pen(color.ToUInt32());
|
||||||
|
|
||||||
var x = ((Point)view.TranslatePoint(new Point(0, 0), this)).X;
|
var x = ((Point)view.TranslatePoint(new Point(0, 0), this)).X;
|
||||||
var rect = new Rect(x - 4, highlightChunk.Y, view.Bounds.Width + 8, highlightChunk.Height);
|
var rect = new Rect(x - 4, highlightChunk.Y, view.Bounds.Width + 7, highlightChunk.Height);
|
||||||
|
|
||||||
context.DrawRectangle(brush, null, rect);
|
context.DrawRectangle(brush, null, rect);
|
||||||
context.DrawLine(pen, rect.TopLeft, rect.TopRight);
|
context.DrawLine(pen, rect.TopLeft, rect.TopRight);
|
||||||
|
@ -214,6 +225,21 @@ namespace SourceGit.Views
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected void TrySetHighlightChunk(TextViewHighlightChunk chunk)
|
||||||
|
{
|
||||||
|
var old = HighlightChunk;
|
||||||
|
if (chunk == null)
|
||||||
|
{
|
||||||
|
if (old != null)
|
||||||
|
SetCurrentValue(HighlightChunkProperty, null);
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (chunk.ShouldReplace(old))
|
||||||
|
SetCurrentValue(HighlightChunkProperty, chunk);
|
||||||
|
}
|
||||||
|
|
||||||
protected (int, int) FindRangeByIndex(List<Models.TextDiffLine> lines, int lineIdx)
|
protected (int, int) FindRangeByIndex(List<Models.TextDiffLine> lines, int lineIdx)
|
||||||
{
|
{
|
||||||
var startIdx = -1;
|
var startIdx = -1;
|
||||||
|
@ -598,7 +624,7 @@ namespace SourceGit.Views
|
||||||
|
|
||||||
if (!string.IsNullOrEmpty(SelectedText))
|
if (!string.IsNullOrEmpty(SelectedText))
|
||||||
{
|
{
|
||||||
SetCurrentValue(HighlightChunkProperty, null);
|
TrySetHighlightChunk(null);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -622,14 +648,14 @@ namespace SourceGit.Views
|
||||||
|
|
||||||
if (lineIdx == -1)
|
if (lineIdx == -1)
|
||||||
{
|
{
|
||||||
SetCurrentValue(HighlightChunkProperty, null);
|
TrySetHighlightChunk(null);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
var (startIdx, endIdx) = FindRangeByIndex(DiffData.Lines, lineIdx);
|
var (startIdx, endIdx) = FindRangeByIndex(DiffData.Lines, lineIdx);
|
||||||
if (startIdx == -1)
|
if (startIdx == -1)
|
||||||
{
|
{
|
||||||
SetCurrentValue(HighlightChunkProperty, null);
|
TrySetHighlightChunk(null);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -643,14 +669,13 @@ namespace SourceGit.Views
|
||||||
endLine.GetTextLineVisualYPosition(endLine.TextLines[^1], VisualYPosition.TextBottom) - view.VerticalOffset:
|
endLine.GetTextLineVisualYPosition(endLine.TextLines[^1], VisualYPosition.TextBottom) - view.VerticalOffset:
|
||||||
view.Bounds.Height;
|
view.Bounds.Height;
|
||||||
|
|
||||||
var hightlight = new TextViewHighlightChunk()
|
TrySetHighlightChunk(new TextViewHighlightChunk()
|
||||||
{
|
{
|
||||||
Y = rectStartY,
|
Y = rectStartY,
|
||||||
Height = rectEndY - rectStartY,
|
Height = rectEndY - rectStartY,
|
||||||
StartIdx = startIdx,
|
StartIdx = startIdx,
|
||||||
EndIdx = endIdx,
|
EndIdx = endIdx,
|
||||||
};
|
});
|
||||||
SetCurrentValue(HighlightChunkProperty, hightlight);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -982,14 +1007,14 @@ namespace SourceGit.Views
|
||||||
|
|
||||||
if (!string.IsNullOrEmpty(SelectedText))
|
if (!string.IsNullOrEmpty(SelectedText))
|
||||||
{
|
{
|
||||||
SetCurrentValue(HighlightChunkProperty, null);
|
TrySetHighlightChunk(null);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
var parentView = this.FindAncestorOfType<TextDiffView>();
|
var parentView = this.FindAncestorOfType<TextDiffView>();
|
||||||
if (parentView == null || parentView.DataContext == null)
|
if (parentView == null || parentView.DataContext == null)
|
||||||
{
|
{
|
||||||
SetCurrentValue(HighlightChunkProperty, null);
|
TrySetHighlightChunk(null);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1015,14 +1040,14 @@ namespace SourceGit.Views
|
||||||
|
|
||||||
if (lineIdx == -1)
|
if (lineIdx == -1)
|
||||||
{
|
{
|
||||||
SetCurrentValue(HighlightChunkProperty, null);
|
TrySetHighlightChunk(null);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
var (startIdx, endIdx) = FindRangeByIndex(lines, lineIdx);
|
var (startIdx, endIdx) = FindRangeByIndex(lines, lineIdx);
|
||||||
if (startIdx == -1)
|
if (startIdx == -1)
|
||||||
{
|
{
|
||||||
SetCurrentValue(HighlightChunkProperty, null);
|
TrySetHighlightChunk(null);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1036,14 +1061,13 @@ namespace SourceGit.Views
|
||||||
endLine.GetTextLineVisualYPosition(endLine.TextLines[^1], VisualYPosition.TextBottom) - view.VerticalOffset :
|
endLine.GetTextLineVisualYPosition(endLine.TextLines[^1], VisualYPosition.TextBottom) - view.VerticalOffset :
|
||||||
view.Bounds.Height;
|
view.Bounds.Height;
|
||||||
|
|
||||||
var hightlight = new TextViewHighlightChunk()
|
TrySetHighlightChunk(new TextViewHighlightChunk()
|
||||||
{
|
{
|
||||||
Y = rectStartY,
|
Y = rectStartY,
|
||||||
Height = rectEndY - rectStartY,
|
Height = rectEndY - rectStartY,
|
||||||
StartIdx = textDiff.Lines.IndexOf(lines[startIdx]),
|
StartIdx = textDiff.Lines.IndexOf(lines[startIdx]),
|
||||||
EndIdx = textDiff.Lines.IndexOf(lines[endIdx]),
|
EndIdx = endIdx == lines.Count - 1 ? textDiff.Lines.Count - 1 : textDiff.Lines.IndexOf(lines[endIdx]),
|
||||||
};
|
});
|
||||||
SetCurrentValue(HighlightChunkProperty, hightlight);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1135,10 +1159,10 @@ namespace SourceGit.Views
|
||||||
if (startLine > endLine)
|
if (startLine > endLine)
|
||||||
(startLine, endLine) = (endLine, startLine);
|
(startLine, endLine) = (endLine, startLine);
|
||||||
|
|
||||||
if (UseSideBySideDiff)
|
if (Editor.Content is ViewModels.TwoSideTextDiff twoSides)
|
||||||
(startLine, endLine) = GetUnifiedRange(diff, startLine, endLine, isOldSide);
|
twoSides.ConvertsToCombinedRange(diff, ref startLine, ref endLine, isOldSide);
|
||||||
|
|
||||||
var selection = MakeSelection(diff, startLine, endLine, isOldSide);
|
var selection = diff.MakeSelection(startLine, endLine, UseSideBySideDiff, isOldSide);
|
||||||
if (!selection.HasChanges)
|
if (!selection.HasChanges)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
@ -1405,7 +1429,7 @@ namespace SourceGit.Views
|
||||||
if (change == null)
|
if (change == null)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
var selection = MakeSelection(diff, chunk.StartIdx + 1, chunk.EndIdx + 1, false);
|
var selection = diff.MakeSelection(chunk.StartIdx + 1, chunk.EndIdx + 1, false, false);
|
||||||
if (!selection.HasChanges)
|
if (!selection.HasChanges)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
@ -1463,7 +1487,7 @@ namespace SourceGit.Views
|
||||||
if (change == null)
|
if (change == null)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
var selection = MakeSelection(diff, chunk.StartIdx + 1, chunk.EndIdx + 1, false);
|
var selection = diff.MakeSelection(chunk.StartIdx + 1, chunk.EndIdx + 1, false, false);
|
||||||
if (!selection.HasChanges)
|
if (!selection.HasChanges)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
@ -1519,7 +1543,7 @@ namespace SourceGit.Views
|
||||||
if (change == null)
|
if (change == null)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
var selection = MakeSelection(diff, chunk.StartIdx + 1, chunk.EndIdx + 1, false);
|
var selection = diff.MakeSelection(chunk.StartIdx + 1, chunk.EndIdx + 1, false, false);
|
||||||
if (!selection.HasChanges)
|
if (!selection.HasChanges)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
@ -1564,122 +1588,5 @@ namespace SourceGit.Views
|
||||||
repo.SetWatcherEnabled(true);
|
repo.SetWatcherEnabled(true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private (int, int) GetUnifiedRange(Models.TextDiff diff, int startLine, int endLine, bool isOldSide)
|
|
||||||
{
|
|
||||||
endLine = Math.Min(endLine, diff.Lines.Count);
|
|
||||||
if (Editor.Content is ViewModels.TwoSideTextDiff twoSides)
|
|
||||||
{
|
|
||||||
var target = isOldSide ? twoSides.Old : twoSides.New;
|
|
||||||
var firstContentLine = -1;
|
|
||||||
for (int i = startLine - 1; i < endLine; i++)
|
|
||||||
{
|
|
||||||
var line = target[i];
|
|
||||||
if (line.Type != Models.TextDiffLineType.None)
|
|
||||||
{
|
|
||||||
firstContentLine = i;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (firstContentLine < 0)
|
|
||||||
return (-1, -1);
|
|
||||||
|
|
||||||
var endContentLine = -1;
|
|
||||||
for (int i = Math.Min(endLine - 1, target.Count - 1); i >= startLine - 1; i--)
|
|
||||||
{
|
|
||||||
var line = target[i];
|
|
||||||
if (line.Type != Models.TextDiffLineType.None)
|
|
||||||
{
|
|
||||||
endContentLine = i;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (endContentLine < 0)
|
|
||||||
return (-1, -1);
|
|
||||||
|
|
||||||
var firstContent = target[firstContentLine];
|
|
||||||
var endContent = target[endContentLine];
|
|
||||||
startLine = diff.Lines.IndexOf(firstContent) + 1;
|
|
||||||
endLine = diff.Lines.IndexOf(endContent) + 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
return (startLine, endLine);
|
|
||||||
}
|
|
||||||
|
|
||||||
private Models.TextDiffSelection MakeSelection(Models.TextDiff diff, int startLine, int endLine, bool isOldSide)
|
|
||||||
{
|
|
||||||
var rs = new Models.TextDiffSelection();
|
|
||||||
rs.StartLine = startLine;
|
|
||||||
rs.EndLine = endLine;
|
|
||||||
|
|
||||||
for (int i = 0; i < startLine - 1; i++)
|
|
||||||
{
|
|
||||||
var line = diff.Lines[i];
|
|
||||||
if (line.Type == Models.TextDiffLineType.Added)
|
|
||||||
{
|
|
||||||
rs.HasLeftChanges = true;
|
|
||||||
rs.IgnoredAdds++;
|
|
||||||
}
|
|
||||||
else if (line.Type == Models.TextDiffLineType.Deleted)
|
|
||||||
{
|
|
||||||
rs.HasLeftChanges = true;
|
|
||||||
rs.IgnoredDeletes++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
for (int i = startLine - 1; i < endLine; i++)
|
|
||||||
{
|
|
||||||
var line = diff.Lines[i];
|
|
||||||
if (line.Type == Models.TextDiffLineType.Added)
|
|
||||||
{
|
|
||||||
if (!UseSideBySideDiff)
|
|
||||||
{
|
|
||||||
rs.HasChanges = true;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
else if (isOldSide)
|
|
||||||
{
|
|
||||||
rs.HasLeftChanges = true;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
rs.HasChanges = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (line.Type == Models.TextDiffLineType.Deleted)
|
|
||||||
{
|
|
||||||
if (!UseSideBySideDiff)
|
|
||||||
{
|
|
||||||
rs.HasChanges = true;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
else if (isOldSide)
|
|
||||||
{
|
|
||||||
rs.HasChanges = true;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
rs.HasLeftChanges = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!rs.HasLeftChanges)
|
|
||||||
{
|
|
||||||
for (int i = endLine; i < diff.Lines.Count; i++)
|
|
||||||
{
|
|
||||||
var line = diff.Lines[i];
|
|
||||||
if (line.Type == Models.TextDiffLineType.Added || line.Type == Models.TextDiffLineType.Deleted)
|
|
||||||
{
|
|
||||||
rs.HasLeftChanges = true;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return rs;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue