mirror of
https://github.com/sourcegit-scm/sourcegit
synced 2025-05-30 08:34:59 +00:00
feature<*>: use DataGrid instead of RichTextBox to improve performance
This commit is contained in:
parent
544d819c96
commit
cbdebee4c2
9 changed files with 594 additions and 848 deletions
|
@ -1,4 +1,4 @@
|
|||
using System.Collections.Generic;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace SourceGit.Git {
|
||||
|
||||
|
@ -8,9 +8,9 @@ namespace SourceGit.Git {
|
|||
public class Blame {
|
||||
|
||||
/// <summary>
|
||||
/// Block content.
|
||||
/// Line content.
|
||||
/// </summary>
|
||||
public class Block {
|
||||
public class Line {
|
||||
public string CommitSHA { get; set; }
|
||||
public string Author { get; set; }
|
||||
public string Time { get; set; }
|
||||
|
@ -18,18 +18,13 @@ namespace SourceGit.Git {
|
|||
}
|
||||
|
||||
/// <summary>
|
||||
/// Blocks
|
||||
/// Lines
|
||||
/// </summary>
|
||||
public List<Block> Blocks { get; set; } = new List<Block>();
|
||||
public List<Line> Lines { get; set; } = new List<Line>();
|
||||
|
||||
/// <summary>
|
||||
/// Is binary file?
|
||||
/// </summary>
|
||||
public bool IsBinary { get; set; } = false;
|
||||
|
||||
/// <summary>
|
||||
/// Line count.
|
||||
/// </summary>
|
||||
public int LineCount { get; set; } = 0;
|
||||
}
|
||||
}
|
||||
|
|
186
src/Git/Diff.cs
186
src/Git/Diff.cs
|
@ -15,100 +15,36 @@ namespace SourceGit.Git {
|
|||
/// Line mode.
|
||||
/// </summary>
|
||||
public enum LineMode {
|
||||
None,
|
||||
Normal,
|
||||
Indicator,
|
||||
Empty,
|
||||
Added,
|
||||
Deleted,
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Side
|
||||
/// Line change.
|
||||
/// </summary>
|
||||
public enum Side {
|
||||
Left,
|
||||
Right,
|
||||
Both,
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Block
|
||||
/// </summary>
|
||||
public class Block {
|
||||
public Side Side = Side.Both;
|
||||
public class LineChange {
|
||||
public LineMode Mode = LineMode.Normal;
|
||||
public int LeftStart = 0;
|
||||
public int RightStart = 0;
|
||||
public int Count = 0;
|
||||
public StringBuilder Builder = new StringBuilder();
|
||||
public string Content = "";
|
||||
public string OldLine = "";
|
||||
public string NewLine = "";
|
||||
|
||||
public bool IsLeftDelete => Side == Side.Left && Mode == LineMode.Deleted;
|
||||
public bool IsRightAdded => Side == Side.Right && Mode == LineMode.Added;
|
||||
public bool IsBothSideNormal => Side == Side.Both && Mode == LineMode.Normal;
|
||||
public bool CanShowNumber => Mode != LineMode.Indicator && Mode != LineMode.Empty;
|
||||
|
||||
public void Append(string data) {
|
||||
if (Count > 0) Builder.AppendLine();
|
||||
Builder.Append(data);
|
||||
Count++;
|
||||
public LineChange(LineMode mode, string content, string oldLine = "", string newLine = "") {
|
||||
Mode = mode;
|
||||
Content = content;
|
||||
OldLine = oldLine;
|
||||
NewLine = newLine;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Text file change.
|
||||
/// Text change.
|
||||
/// </summary>
|
||||
public class TextChange {
|
||||
public bool IsValid = false;
|
||||
public List<LineChange> Lines = new List<LineChange>();
|
||||
public bool IsBinary = false;
|
||||
public List<Block> Blocks = new List<Block>();
|
||||
public int LeftLineCount = 0;
|
||||
public int RightLineCount = 0;
|
||||
|
||||
public void SetBinary() {
|
||||
IsValid = true;
|
||||
IsBinary = true;
|
||||
}
|
||||
|
||||
public void Add(Block b) {
|
||||
if (b.Count == 0) return;
|
||||
|
||||
switch (b.Side) {
|
||||
case Side.Left:
|
||||
LeftLineCount += b.Count;
|
||||
break;
|
||||
case Side.Right:
|
||||
RightLineCount += b.Count;
|
||||
break;
|
||||
default:
|
||||
LeftLineCount += b.Count;
|
||||
RightLineCount += b.Count;
|
||||
break;
|
||||
}
|
||||
|
||||
Blocks.Add(b);
|
||||
}
|
||||
|
||||
public void Fit() {
|
||||
if (LeftLineCount > RightLineCount) {
|
||||
var b = new Block();
|
||||
b.Side = Side.Right;
|
||||
b.Mode = LineMode.Empty;
|
||||
|
||||
var delta = LeftLineCount - RightLineCount;
|
||||
for (int i = 0; i < delta; i++) b.Append("");
|
||||
|
||||
Add(b);
|
||||
} else if (LeftLineCount < RightLineCount) {
|
||||
var b = new Block();
|
||||
b.Side = Side.Left;
|
||||
b.Mode = LineMode.Empty;
|
||||
|
||||
var delta = RightLineCount - LeftLineCount;
|
||||
for (int i = 0; i < delta; i++) b.Append("");
|
||||
|
||||
Add(b);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
@ -136,103 +72,49 @@ namespace SourceGit.Git {
|
|||
/// <returns></returns>
|
||||
public static TextChange GetTextChange(Repository repo, string args) {
|
||||
var rs = new TextChange();
|
||||
var current = new Block();
|
||||
var left = 0;
|
||||
var right = 0;
|
||||
var started = false;
|
||||
var oldLine = 0;
|
||||
var newLine = 0;
|
||||
|
||||
repo.RunCommand($"diff --ignore-cr-at-eol {args}", line => {
|
||||
if (rs.IsBinary) return;
|
||||
|
||||
if (!rs.IsValid) {
|
||||
if (!started) {
|
||||
var match = REG_INDICATOR.Match(line);
|
||||
if (!match.Success) {
|
||||
if (line.StartsWith("Binary ")) rs.SetBinary();
|
||||
if (line.StartsWith("Binary ")) rs.IsBinary = true;
|
||||
return;
|
||||
}
|
||||
|
||||
rs.IsValid = true;
|
||||
left = int.Parse(match.Groups[1].Value);
|
||||
right = int.Parse(match.Groups[2].Value);
|
||||
current.Mode = LineMode.Indicator;
|
||||
current.Append(line);
|
||||
started = true;
|
||||
oldLine = int.Parse(match.Groups[1].Value);
|
||||
newLine = int.Parse(match.Groups[2].Value);
|
||||
rs.Lines.Add(new LineChange(LineMode.Indicator, line));
|
||||
} else {
|
||||
if (line[0] == '-') {
|
||||
if (current.IsLeftDelete) {
|
||||
current.Append(line.Substring(1));
|
||||
} else {
|
||||
rs.Add(current);
|
||||
|
||||
current = new Block();
|
||||
current.Side = Side.Left;
|
||||
current.Mode = LineMode.Deleted;
|
||||
current.LeftStart = left;
|
||||
current.Append(line.Substring(1));
|
||||
}
|
||||
|
||||
left++;
|
||||
rs.Lines.Add(new LineChange(LineMode.Deleted, line.Substring(1), $"{oldLine}", ""));
|
||||
oldLine++;
|
||||
} else if (line[0] == '+') {
|
||||
if (current.IsRightAdded) {
|
||||
current.Append(line.Substring(1));
|
||||
} else {
|
||||
rs.Add(current);
|
||||
|
||||
current = new Block();
|
||||
current.Side = Side.Right;
|
||||
current.Mode = LineMode.Added;
|
||||
current.RightStart = right;
|
||||
current.Append(line.Substring(1));
|
||||
}
|
||||
|
||||
right++;
|
||||
rs.Lines.Add(new LineChange(LineMode.Added, line.Substring(1), "", $"{newLine}"));
|
||||
newLine++;
|
||||
} else if (line[0] == '\\') {
|
||||
var tmp = new Block();
|
||||
tmp.Side = current.Side;
|
||||
tmp.Mode = LineMode.Indicator;
|
||||
tmp.Append(line.Substring(1));
|
||||
|
||||
rs.Add(current);
|
||||
rs.Add(tmp);
|
||||
rs.Fit();
|
||||
|
||||
current = new Block();
|
||||
current.LeftStart = left;
|
||||
current.RightStart = right;
|
||||
rs.Lines.Add(new LineChange(LineMode.Indicator, line.Substring(1)));
|
||||
} else {
|
||||
var match = REG_INDICATOR.Match(line);
|
||||
if (match.Success) {
|
||||
rs.Add(current);
|
||||
rs.Fit();
|
||||
|
||||
left = int.Parse(match.Groups[1].Value);
|
||||
right = int.Parse(match.Groups[2].Value);
|
||||
|
||||
current = new Block();
|
||||
current.Mode = LineMode.Indicator;
|
||||
current.Append(line);
|
||||
oldLine = int.Parse(match.Groups[1].Value);
|
||||
newLine = int.Parse(match.Groups[2].Value);
|
||||
rs.Lines.Add(new LineChange(LineMode.Indicator, line));
|
||||
} else {
|
||||
if (current.IsBothSideNormal) {
|
||||
current.Append(line.Substring(1));
|
||||
} else {
|
||||
rs.Add(current);
|
||||
rs.Fit();
|
||||
|
||||
current = new Block();
|
||||
current.LeftStart = left;
|
||||
current.RightStart = right;
|
||||
current.Append(line.Substring(1));
|
||||
}
|
||||
|
||||
left++;
|
||||
right++;
|
||||
rs.Lines.Add(new LineChange(LineMode.Normal, line.Substring(1), $"{oldLine}", $"{newLine}"));
|
||||
oldLine++;
|
||||
newLine++;
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
rs.Add(current);
|
||||
rs.Fit();
|
||||
|
||||
if (rs.IsBinary) rs.Blocks.Clear();
|
||||
if (rs.IsBinary) rs.Lines.Clear();
|
||||
return rs;
|
||||
}
|
||||
|
||||
|
|
|
@ -945,7 +945,6 @@ namespace SourceGit.Git {
|
|||
public Blame BlameFile(string file, string revision) {
|
||||
var regex = new Regex(@"^\^?([0-9a-f]+)\s+.*\((.*)\s+(\d+)\s+[\-\+]?\d+\s+\d+\) (.*)");
|
||||
var blame = new Blame();
|
||||
var current = null as Blame.Block;
|
||||
|
||||
var errs = RunCommand($"blame -t {revision} -- \"{file}\"", line => {
|
||||
if (blame.IsBinary) return;
|
||||
|
@ -953,7 +952,7 @@ namespace SourceGit.Git {
|
|||
|
||||
if (line.IndexOf('\0') >= 0) {
|
||||
blame.IsBinary = true;
|
||||
blame.Blocks.Clear();
|
||||
blame.Lines.Clear();
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -961,25 +960,19 @@ namespace SourceGit.Git {
|
|||
if (!match.Success) return;
|
||||
|
||||
var commit = match.Groups[1].Value;
|
||||
var author = match.Groups[2].Value;
|
||||
var timestamp = int.Parse(match.Groups[3].Value);
|
||||
var data = match.Groups[4].Value;
|
||||
if (current != null && current.CommitSHA == commit) {
|
||||
current.Content = current.Content + "\n" + data;
|
||||
} else {
|
||||
var timestamp = int.Parse(match.Groups[3].Value);
|
||||
var when = new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc).AddSeconds(timestamp).ToLocalTime().ToString("yyyy-MM-dd HH:mm:ss");
|
||||
var when = new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc).AddSeconds(timestamp).ToLocalTime().ToString("yyyy-MM-dd HH:mm:ss");
|
||||
|
||||
current = new Blame.Block() {
|
||||
CommitSHA = commit,
|
||||
Author = match.Groups[2].Value,
|
||||
Time = when,
|
||||
Content = data,
|
||||
};
|
||||
var blameLine = new Blame.Line() {
|
||||
CommitSHA = commit,
|
||||
Author = author,
|
||||
Time = when,
|
||||
Content = data,
|
||||
};
|
||||
|
||||
if (current.Author == null) current.Author = "";
|
||||
blame.Blocks.Add(current);
|
||||
}
|
||||
|
||||
blame.LineCount++;
|
||||
blame.Lines.Add(blameLine);
|
||||
});
|
||||
|
||||
if (errs != null) App.RaiseError(errs);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue