Browse Source

fix some bugs in ChangeMarkerMargin

4.1
Siegfried Pammer 14 years ago
parent
commit
429f0229b5
  1. 34
      src/AddIns/DisplayBindings/AvalonEdit.AddIn/Src/ChangeMarkerMargin.cs
  2. 40
      src/AddIns/DisplayBindings/AvalonEdit.AddIn/Src/DefaultChangeWatcher.cs
  3. 34
      src/AddIns/DisplayBindings/AvalonEdit.AddIn/Src/LineChangeInfo.cs
  4. 29
      src/Libraries/AvalonEdit/ICSharpCode.AvalonEdit/Utils/CompressingTreeList.cs

34
src/AddIns/DisplayBindings/AvalonEdit.AddIn/Src/ChangeMarkerMargin.cs

@ -158,6 +158,17 @@ namespace ICSharpCode.AvalonEdit.AddIn @@ -158,6 +158,17 @@ namespace ICSharpCode.AvalonEdit.AddIn
}
if (oldText != null) {
// TODO : deletions on line 0 cannot be displayed.
LineChangeInfo currLineInfo = changeWatcher.GetChange(startLine);
if (currLineInfo.Change == ChangeType.Deleted) {
var docLine = editor.Document.GetLineByNumber(startLine);
if (docLine.DelimiterLength == 0)
oldText = DocumentUtilitites.GetLineTerminator(changeWatcher.CurrentDocument, startLine);
oldText = editor.Document.GetText(docLine.Offset, docLine.TotalLength) + oldText;
}
DiffControl differ = new DiffControl();
differ.editor.SyntaxHighlighting = editor.SyntaxHighlighting;
differ.editor.HorizontalScrollBarVisibility = ScrollBarVisibility.Hidden;
@ -165,16 +176,6 @@ namespace ICSharpCode.AvalonEdit.AddIn @@ -165,16 +176,6 @@ namespace ICSharpCode.AvalonEdit.AddIn
differ.editor.Document.Text = oldText;
differ.Background = Brushes.White;
// TODO : deletions on line 0 cannot be displayed.
LineChangeInfo prevLineInfo = changeWatcher.GetChange(startLine - 1);
LineChangeInfo lineInfo = changeWatcher.GetChange(startLine);
if (prevLineInfo.Change == ChangeType.Deleted) {
var docLine = editor.Document.GetLineByNumber(startLine - 1);
differ.editor.Document.Insert(0, editor.Document.GetText(docLine.Offset, docLine.TotalLength));
}
if (oldText == string.Empty) {
differ.editor.Visibility = Visibility.Collapsed;
differ.copyButton.Visibility = Visibility.Collapsed;
@ -184,22 +185,13 @@ namespace ICSharpCode.AvalonEdit.AddIn @@ -184,22 +185,13 @@ namespace ICSharpCode.AvalonEdit.AddIn
var mainHighlighter = new DocumentHighlighter(baseDocument, differ.editor.SyntaxHighlighting.MainRuleSet);
var popupHighlighter = differ.editor.TextArea.GetService(typeof(IHighlighter)) as DocumentHighlighter;
if (prevLineInfo.Change == ChangeType.Deleted)
popupHighlighter.InitialSpanStack = mainHighlighter.GetSpanStack(prevLineInfo.OldStartLineNumber);
else
popupHighlighter.InitialSpanStack = mainHighlighter.GetSpanStack(lineInfo.OldStartLineNumber);
popupHighlighter.InitialSpanStack = mainHighlighter.GetSpanStack(currLineInfo.OldStartLineNumber);
}
}
differ.revertButton.Click += delegate {
if (hasNewVersion) {
int delimiter = 0;
DocumentLine l = Document.GetLineByOffset(offset + length);
if (added)
delimiter = l.DelimiterLength;
if (length == 0)
oldText += DocumentUtilitites.GetLineTerminator(new AvalonEditDocumentAdapter(Document, null), l.LineNumber);
Document.Replace(offset, length + delimiter, oldText);
Document.Replace(offset, length, oldText);
tooltip.IsOpen = false;
}
};

40
src/AddIns/DisplayBindings/AvalonEdit.AddIn/Src/DefaultChangeWatcher.cs

@ -81,7 +81,7 @@ namespace ICSharpCode.AvalonEdit.AddIn @@ -81,7 +81,7 @@ namespace ICSharpCode.AvalonEdit.AddIn
if (update)
changeList.Transform(TransformLineChangeInfo);
else
changeList.InsertRange(0, document.TotalNumberOfLines + 1, LineChangeInfo.Empty);
changeList.InsertRange(0, document.TotalNumberOfLines + 1, LineChangeInfo.EMPTY);
} else {
changeList.Clear();
@ -92,25 +92,23 @@ namespace ICSharpCode.AvalonEdit.AddIn @@ -92,25 +92,23 @@ namespace ICSharpCode.AvalonEdit.AddIn
new DocumentSequence(document, hashes)
);
changeList.Add(LineChangeInfo.Empty);
changeList.Add(LineChangeInfo.EMPTY);
int lastEndLine = 0;
foreach (Edit edit in diff.GetEdits()) {
int beginLine = edit.BeginB;
int endLine = edit.EndB;
changeList.InsertRange(changeList.Count, beginLine - lastEndLine, LineChangeInfo.Empty);
changeList.InsertRange(changeList.Count, beginLine - lastEndLine, LineChangeInfo.EMPTY);
LineChangeInfo change = new LineChangeInfo(edit.EditType, edit.BeginA, edit.BeginB, edit.EndA, edit.EndB);
if (endLine == beginLine)
changeList[changeList.Count - 1] = change;
changeList[changeList.Count - 1] = new LineChangeInfo(edit.EditType, edit.BeginA, edit.EndA);
else
changeList.InsertRange(changeList.Count, endLine - beginLine, change);
changeList.InsertRange(changeList.Count, endLine - beginLine, new LineChangeInfo(edit.EditType, edit.BeginA, edit.EndA));
lastEndLine = endLine;
}
changeList.InsertRange(changeList.Count, textDocument.LineCount - lastEndLine, LineChangeInfo.Empty);
changeList.InsertRange(changeList.Count, textDocument.LineCount - lastEndLine, LineChangeInfo.EMPTY);
}
OnChangeOccurred(EventArgs.Empty);
@ -158,7 +156,7 @@ namespace ICSharpCode.AvalonEdit.AddIn @@ -158,7 +156,7 @@ namespace ICSharpCode.AvalonEdit.AddIn
void ILineTracker.LineInserted(DocumentLine insertionPos, DocumentLine newLine)
{
int index = insertionPos.LineNumber;
var newLineInfo = new LineChangeInfo(ChangeType.Unsaved, index, index, newLine.LineNumber, newLine.LineNumber);
var newLineInfo = new LineChangeInfo(ChangeType.Unsaved, index, index);
changeList[index] = newLineInfo;
changeList.Insert(index + 1, newLineInfo);
@ -167,7 +165,7 @@ namespace ICSharpCode.AvalonEdit.AddIn @@ -167,7 +165,7 @@ namespace ICSharpCode.AvalonEdit.AddIn
void ILineTracker.RebuildDocument()
{
changeList.Clear();
changeList.InsertRange(0, document.TotalNumberOfLines + 1, new LineChangeInfo(ChangeType.Unsaved, 1, 1, baseDocument.TotalNumberOfLines, document.TotalNumberOfLines));
changeList.InsertRange(0, document.TotalNumberOfLines + 1, new LineChangeInfo(ChangeType.Unsaved, 1, baseDocument.TotalNumberOfLines));
}
bool disposed = false;
@ -188,7 +186,7 @@ namespace ICSharpCode.AvalonEdit.AddIn @@ -188,7 +186,7 @@ namespace ICSharpCode.AvalonEdit.AddIn
added = info.Change == ChangeType.Added;
if (info.Change != ChangeType.None && info.Change != ChangeType.Unsaved) {
newStartLine = info.NewStartLineNumber + 1;
newStartLine = CalculateNewStartLineNumber(lineNumber);
if (info.Change == ChangeType.Added)
return "";
@ -196,23 +194,37 @@ namespace ICSharpCode.AvalonEdit.AddIn @@ -196,23 +194,37 @@ namespace ICSharpCode.AvalonEdit.AddIn
var startDocumentLine = baseDocument.GetLine(info.OldStartLineNumber + 1);
var endLine = baseDocument.GetLine(info.OldEndLineNumber);
return baseDocument.GetText(startDocumentLine.Offset, endLine.EndOffset - startDocumentLine.Offset);
return TextUtilities.NormalizeNewLines(baseDocument.GetText(startDocumentLine.Offset, endLine.EndOffset - startDocumentLine.Offset), DocumentUtilitites.GetLineTerminator(document, newStartLine));
}
newStartLine = 0;
return null;
}
int CalculateNewStartLineNumber(int lineNumber)
{
return changeList.GetStartOfRun(lineNumber);
}
int CalculateNewEndLineNumber(int lineNumber)
{
return changeList.GetEndOfRun(lineNumber) - 1;
}
public bool GetNewVersionFromLine(int lineNumber, out int offset, out int length)
{
LineChangeInfo info = changeList[lineNumber];
if (info.Change != ChangeType.None && info.Change != ChangeType.Unsaved) {
var startLine = document.GetLine(info.NewStartLineNumber + 1);
var endLine = document.GetLine(info.NewEndLineNumber);
var startLine = document.GetLine(CalculateNewStartLineNumber(lineNumber));
var endLine = document.GetLine(CalculateNewEndLineNumber(lineNumber));
offset = startLine.Offset;
length = endLine.EndOffset - startLine.Offset;
if (info.Change == ChangeType.Added)
length += endLine.DelimiterLength;
return true;
}

34
src/AddIns/DisplayBindings/AvalonEdit.AddIn/Src/LineChangeInfo.cs

@ -3,6 +3,7 @@ @@ -3,6 +3,7 @@
using System;
using System.Collections.Generic;
using ICSharpCode.AvalonEdit.Utils;
using ICSharpCode.SharpDevelop.Editor;
namespace ICSharpCode.AvalonEdit.AddIn
@ -34,7 +35,7 @@ namespace ICSharpCode.AvalonEdit.AddIn @@ -34,7 +35,7 @@ namespace ICSharpCode.AvalonEdit.AddIn
public struct LineChangeInfo : IEquatable<LineChangeInfo>
{
public static readonly LineChangeInfo Empty = new LineChangeInfo(ChangeType.None, -1, -1, -1, -1);
public static readonly LineChangeInfo EMPTY = new LineChangeInfo(ChangeType.None, -1, -1);
ChangeType change;
@ -47,37 +48,19 @@ namespace ICSharpCode.AvalonEdit.AddIn @@ -47,37 +48,19 @@ namespace ICSharpCode.AvalonEdit.AddIn
public int OldStartLineNumber {
get { return oldStartLineNumber; }
set { oldStartLineNumber = value; }
}
int newStartLineNumber;
public int NewStartLineNumber {
get { return newStartLineNumber; }
set { newStartLineNumber = value; }
}
int oldEndLineNumber;
public int OldEndLineNumber {
get { return oldEndLineNumber; }
set { oldEndLineNumber = value; }
}
int newEndLineNumber;
public int NewEndLineNumber {
get { return newEndLineNumber; }
set { newEndLineNumber = value; }
}
public LineChangeInfo(ChangeType change, int oldStartLineNumber, int newStartLineNumber, int oldEndLineNumber, int newEndLineNumber)
public LineChangeInfo(ChangeType change, int oldStartLineNumber, int oldEndLineNumber)
{
this.change = change;
this.oldStartLineNumber = oldStartLineNumber;
this.newStartLineNumber = newStartLineNumber;
this.oldEndLineNumber = oldEndLineNumber;
this.newEndLineNumber = newEndLineNumber;
}
#region Equals and GetHashCode implementation
@ -88,11 +71,7 @@ namespace ICSharpCode.AvalonEdit.AddIn @@ -88,11 +71,7 @@ namespace ICSharpCode.AvalonEdit.AddIn
public bool Equals(LineChangeInfo other)
{
return this.change == other.change &&
this.oldEndLineNumber == other.oldEndLineNumber &&
this.newStartLineNumber == other.newStartLineNumber &&
this.oldStartLineNumber == other.oldStartLineNumber &&
this.newEndLineNumber == other.newEndLineNumber;
return this.change == other.change && this.oldStartLineNumber == other.oldStartLineNumber && this.oldEndLineNumber == other.oldEndLineNumber;
}
public override int GetHashCode()
@ -101,9 +80,7 @@ namespace ICSharpCode.AvalonEdit.AddIn @@ -101,9 +80,7 @@ namespace ICSharpCode.AvalonEdit.AddIn
unchecked {
hashCode += 1000000007 * change.GetHashCode();
hashCode += 1000000009 * oldStartLineNumber.GetHashCode();
hashCode += 1000000021 * newStartLineNumber.GetHashCode();
hashCode += 1000000033 * oldEndLineNumber.GetHashCode();
hashCode += 1000000087 * newEndLineNumber.GetHashCode();
hashCode += 1000000021 * oldEndLineNumber.GetHashCode();
}
return hashCode;
}
@ -118,5 +95,6 @@ namespace ICSharpCode.AvalonEdit.AddIn @@ -118,5 +95,6 @@ namespace ICSharpCode.AvalonEdit.AddIn
return !(lhs == rhs);
}
#endregion
}
}

29
src/Libraries/AvalonEdit/ICSharpCode.AvalonEdit/Utils/CompressingTreeList.cs

@ -343,9 +343,38 @@ namespace ICSharpCode.AvalonEdit.Utils @@ -343,9 +343,38 @@ namespace ICSharpCode.AvalonEdit.Utils
return -1;
}
/// <summary>
/// Gets the the first index so that all values from the result index to <paramref name="index"/>
/// are equal.
/// </summary>
public int GetStartOfRun(int index)
{
if (index < 0 || index >= this.Count)
throw new ArgumentOutOfRangeException("index", index, "Value must be between 0 and " + (this.Count - 1));
int indexInRun = index;
GetNode(ref indexInRun);
return index - indexInRun;
}
/// <summary>
/// Gets the first index after <paramref name="index"/> so that the value at the result index is not
/// equal to the value at <paramref name="index"/>.
/// That is, this method returns the exclusive end index of the run of equal values.
/// </summary>
public int GetEndOfRun(int index)
{
if (index < 0 || index >= this.Count)
throw new ArgumentOutOfRangeException("index", index, "Value must be between 0 and " + (this.Count - 1));
int indexInRun = index;
int runLength = GetNode(ref indexInRun).count;
return index - indexInRun + runLength;
}
/// <summary>
/// Gets the number of elements after <paramref name="index"/> that have the same value as each other.
/// </summary>
[Obsolete("This method may be confusing as it returns only the remaining run length after index. " +
"Use GetStartOfRun/GetEndOfRun instead.")]
public int GetRunLength(int index)
{
if (index < 0 || index >= this.Count)

Loading…
Cancel
Save