Browse Source

fix SD-1489 - Document reload due to external changes removes all bookmarks

pull/23/head
Siegfried Pammer 14 years ago
parent
commit
fd4a575bd9
  1. 2
      src/AddIns/DisplayBindings/AvalonEdit.AddIn/AvalonEdit.AddIn.csproj
  2. 6
      src/AddIns/DisplayBindings/AvalonEdit.AddIn/Src/AvalonEditViewContent.cs
  3. 13
      src/AddIns/DisplayBindings/AvalonEdit.AddIn/Src/CodeEditor.cs
  4. 2
      src/AddIns/DisplayBindings/AvalonEdit.AddIn/Src/DefaultChangeWatcher.cs
  5. 2
      src/AddIns/DisplayBindings/AvalonEdit.AddIn/Src/MyersDiff/Edit.cs
  6. 5
      src/AddIns/DisplayBindings/AvalonEdit.AddIn/Src/MyersDiff/MyersDiffAlgorithm.cs
  7. 19
      src/AddIns/DisplayBindings/AvalonEdit.AddIn/Src/MyersDiff/Utils.cs

2
src/AddIns/DisplayBindings/AvalonEdit.AddIn/AvalonEdit.AddIn.csproj

@ -111,7 +111,7 @@
<Compile Include="Src\MyersDiff\DocumentSequence.cs" /> <Compile Include="Src\MyersDiff\DocumentSequence.cs" />
<Compile Include="Src\MyersDiff\Edit.cs" /> <Compile Include="Src\MyersDiff\Edit.cs" />
<Compile Include="Src\MyersDiff\ISequence.cs" /> <Compile Include="Src\MyersDiff\ISequence.cs" />
<Compile Include="Src\MyersDiff\MyersDiff.cs" /> <Compile Include="Src\MyersDiff\MyersDiffAlgorithm.cs" />
<Compile Include="Src\MyersDiff\StringSequence.cs" /> <Compile Include="Src\MyersDiff\StringSequence.cs" />
<Compile Include="Src\MyersDiff\Utils.cs" /> <Compile Include="Src\MyersDiff\Utils.cs" />
<Compile Include="Src\NewLineConsistencyCheck.cs" /> <Compile Include="Src\NewLineConsistencyCheck.cs" />

6
src/AddIns/DisplayBindings/AvalonEdit.AddIn/Src/AvalonEditViewContent.cs

@ -135,7 +135,7 @@ namespace ICSharpCode.AvalonEdit.AddIn
return; return;
isLoading = true; isLoading = true;
try { try {
BookmarksDetach(); // BookmarksDetach();
codeEditor.SyntaxHighlighting = codeEditor.SyntaxHighlighting =
HighlightingManager.Instance.GetDefinitionByExtension(Path.GetExtension(file.FileName)); HighlightingManager.Instance.GetDefinitionByExtension(Path.GetExtension(file.FileName));
@ -207,8 +207,12 @@ namespace ICSharpCode.AvalonEdit.AddIn
} }
#region Bookmark Handling #region Bookmark Handling
bool bookmarksAttached;
void BookmarksAttach() void BookmarksAttach()
{ {
if (bookmarksAttached) return;
bookmarksAttached = true;
foreach (SDBookmark bookmark in BookmarkManager.GetBookmarks(codeEditor.FileName)) { foreach (SDBookmark bookmark in BookmarkManager.GetBookmarks(codeEditor.FileName)) {
bookmark.Document = codeEditor.DocumentAdapter; bookmark.Document = codeEditor.DocumentAdapter;
codeEditor.IconBarManager.Bookmarks.Add(bookmark); codeEditor.IconBarManager.Bookmarks.Add(bookmark);

13
src/AddIns/DisplayBindings/AvalonEdit.AddIn/Src/CodeEditor.cs

@ -13,6 +13,8 @@ using System.Windows.Controls;
using System.Windows.Data; using System.Windows.Data;
using System.Windows.Input; using System.Windows.Input;
using System.Windows.Threading; using System.Windows.Threading;
using ICSharpCode.AvalonEdit.AddIn.MyersDiff;
using ICSharpCode.AvalonEdit.AddIn.Options; using ICSharpCode.AvalonEdit.AddIn.Options;
using ICSharpCode.AvalonEdit.Document; using ICSharpCode.AvalonEdit.Document;
using ICSharpCode.AvalonEdit.Editing; using ICSharpCode.AvalonEdit.Editing;
@ -296,12 +298,12 @@ namespace ICSharpCode.AvalonEdit.AddIn
{ {
if (UseFixedEncoding) { if (UseFixedEncoding) {
using (StreamReader reader = new StreamReader(stream, primaryTextEditor.Encoding, detectEncodingFromByteOrderMarks: false)) { using (StreamReader reader = new StreamReader(stream, primaryTextEditor.Encoding, detectEncodingFromByteOrderMarks: false)) {
primaryTextEditor.Text = reader.ReadToEnd(); ReloadDocument(primaryTextEditor.Document, reader.ReadToEnd());
} }
} else { } else {
// do encoding auto-detection // do encoding auto-detection
using (StreamReader reader = FileReader.OpenStream(stream, this.Encoding ?? FileService.DefaultFileEncoding.GetEncoding())) { using (StreamReader reader = FileReader.OpenStream(stream, this.Encoding ?? FileService.DefaultFileEncoding.GetEncoding())) {
primaryTextEditor.Text = reader.ReadToEnd(); ReloadDocument(primaryTextEditor.Document, reader.ReadToEnd());
this.Encoding = reader.CurrentEncoding; this.Encoding = reader.CurrentEncoding;
} }
} }
@ -311,6 +313,13 @@ namespace ICSharpCode.AvalonEdit.AddIn
NewLineConsistencyCheck.StartConsistencyCheck(this); NewLineConsistencyCheck.StartConsistencyCheck(this);
} }
void ReloadDocument(TextDocument document, string newContent)
{
var diff = new MyersDiffAlgorithm(new StringSequence(document.Text), new StringSequence(newContent));
document.Replace(0, document.TextLength, newContent, diff.GetEdits().ToOffsetChangeMap());
document.UndoStack.ClearAll();
}
public event EventHandler LoadedFileContent; public event EventHandler LoadedFileContent;
public void Save(Stream stream) public void Save(Stream stream)

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

@ -104,7 +104,7 @@ namespace ICSharpCode.AvalonEdit.AddIn
Dictionary<string, int> hashes = new Dictionary<string, int>(); Dictionary<string, int> hashes = new Dictionary<string, int>();
MyersDiff.MyersDiff diff = new MyersDiff.MyersDiff( MyersDiffAlgorithm diff = new MyersDiffAlgorithm(
new DocumentSequence(baseDocument, hashes), new DocumentSequence(baseDocument, hashes),
new DocumentSequence(document, hashes) new DocumentSequence(document, hashes)
); );

2
src/AddIns/DisplayBindings/AvalonEdit.AddIn/Src/MyersDiff/Edit.cs

@ -104,7 +104,7 @@ namespace ICSharpCode.AvalonEdit.AddIn.MyersDiff
/// <summary> /// <summary>
/// Start point in sequence A. /// Start point in sequence A.
/// </summary> /// </summary>
public int BeginA { get; set; } public int BeginA { get; private set; }
/// <summary> /// <summary>
/// End point in sequence A. /// End point in sequence A.

5
src/AddIns/DisplayBindings/AvalonEdit.AddIn/Src/MyersDiff/MyersDiff.cs → src/AddIns/DisplayBindings/AvalonEdit.AddIn/Src/MyersDiff/MyersDiffAlgorithm.cs

@ -94,7 +94,7 @@ namespace ICSharpCode.AvalonEdit.AddIn.MyersDiff
/// So the overall runtime complexity stays the same with linear space, /// So the overall runtime complexity stays the same with linear space,
/// albeit with a larger constant factor. /// albeit with a larger constant factor.
/// </summary> /// </summary>
public class MyersDiff public class MyersDiffAlgorithm
{ {
/// <summary> /// <summary>
/// The list of edits found during the last call to <see cref="calculateEdits()"/> /// The list of edits found during the last call to <see cref="calculateEdits()"/>
@ -116,7 +116,7 @@ namespace ICSharpCode.AvalonEdit.AddIn.MyersDiff
/// </summary> /// </summary>
/// <param name="a">the text A which should be compared</param> /// <param name="a">the text A which should be compared</param>
/// <param name="b">the text B which should be compared</param> /// <param name="b">the text B which should be compared</param>
public MyersDiff(ISequence a, ISequence b) public MyersDiffAlgorithm(ISequence a, ISequence b)
{ {
this.a = a; this.a = a;
this.b = b; this.b = b;
@ -229,7 +229,6 @@ namespace ICSharpCode.AvalonEdit.AddIn.MyersDiff
/// ///
/// It is assumed that there is at least one edit in the range. /// It is assumed that there is at least one edit in the range.
/// </summary> /// </summary>
// TODO: measure speed impact when this is synchronized
public Edit Calculate(int beginA, int endA, int beginB, int endB) public Edit Calculate(int beginA, int endA, int beginB, int endB)
{ {
if (beginA == endA || beginB == endB) if (beginA == endA || beginB == endB)

19
src/AddIns/DisplayBindings/AvalonEdit.AddIn/Src/MyersDiff/Utils.cs

@ -3,6 +3,9 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using ICSharpCode.AvalonEdit.Document;
namespace ICSharpCode.AvalonEdit.AddIn.MyersDiff namespace ICSharpCode.AvalonEdit.AddIn.MyersDiff
{ {
@ -18,5 +21,21 @@ namespace ICSharpCode.AvalonEdit.AddIn.MyersDiff
else else
instance[index] = value; instance[index] = value;
} }
public static OffsetChangeMap ToOffsetChangeMap(this IEnumerable<Edit> edits)
{
var map = new OffsetChangeMap();
int diff = 0;
foreach (var edit in edits) {
Debug.Assert(edit.EditType != ChangeType.None && edit.EditType != ChangeType.Unsaved);
int offset = edit.BeginA + diff;
int removalLength = edit.EndA - edit.BeginA;
int insertionLength = edit.EndB - edit.BeginB;
diff += (insertionLength - removalLength);
map.Add(new OffsetChangeMapEntry(offset, removalLength, insertionLength));
}
return map;
}
} }
} }

Loading…
Cancel
Save