diff --git a/ICSharpCode.Editor/IDocument.cs b/ICSharpCode.Editor/IDocument.cs
new file mode 100644
index 0000000000..edffab12ab
--- /dev/null
+++ b/ICSharpCode.Editor/IDocument.cs
@@ -0,0 +1,134 @@
+// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt)
+// This code is distributed under MIT license (for details please see \doc\license.txt)
+
+using System;
+
+namespace ICSharpCode.Editor
+{
+ ///
+ /// A document representing a source code file for refactoring.
+ /// Line and column counting starts at 1.
+ /// Offset counting starts at 0.
+ ///
+ public interface IDocument : ITextBuffer, IServiceProvider
+ {
+ ///
+ /// Gets/Sets the text of the whole document..
+ ///
+ new string Text { get; set; } // hides TextBuffer.Text to add the setter
+
+ ///
+ /// Gets the total number of lines in the document.
+ ///
+ int TotalNumberOfLines { get; }
+
+ ///
+ /// Gets the document line with the specified number.
+ ///
+ /// The number of the line to retrieve. The first line has number 1.
+ IDocumentLine GetLine(int lineNumber);
+
+ ///
+ /// Gets the document line that contains the specified offset.
+ ///
+ IDocumentLine GetLineByOffset(int offset);
+
+ ///
+ /// Gets the offset from a text location.
+ ///
+ ///
+ int GetOffset(int line, int column);
+
+ ///
+ /// Gets the offset from a text location.
+ ///
+ ///
+ int GetOffset(TextLocation location);
+
+ ///
+ /// Gets the location from an offset.
+ ///
+ ///
+ TextLocation GetLocation(int offset);
+
+ ///
+ /// Inserts text.
+ ///
+ /// The offset at which the text is inserted.
+ /// The new text.
+ ///
+ /// Anchors positioned exactly at the insertion offset will move according to their movement type.
+ /// For AnchorMovementType.Default, they will move behind the inserted text.
+ ///
+ void Insert(int offset, string text);
+
+ ///
+ /// Inserts text.
+ ///
+ /// The offset at which the text is inserted.
+ /// The new text.
+ ///
+ /// Anchors positioned exactly at the insertion offset will move according to the anchor's movement type.
+ /// For AnchorMovementType.Default, they will move according to the movement type specified by this parameter.
+ ///
+ void Insert(int offset, string text, AnchorMovementType defaultAnchorMovementType);
+
+ ///
+ /// Removes text.
+ ///
+ /// Starting offset of the text to be removed.
+ /// Length of the text to be removed.
+ void Remove(int offset, int length);
+
+ ///
+ /// Replaces text.
+ ///
+ /// The starting offset of the text to be replaced.
+ /// The length of the text to be replaced.
+ /// The new text.
+ void Replace(int offset, int length, string newText);
+
+ ///
+ /// Make the document combine the following actions into a single
+ /// action for undo purposes.
+ ///
+ void StartUndoableAction();
+
+ ///
+ /// Ends the undoable action started with .
+ ///
+ void EndUndoableAction();
+
+ ///
+ /// Creates an undo group. Dispose the returned value to close the undo group.
+ ///
+ /// An object that closes the undo group when Dispose() is called.
+ IDisposable OpenUndoGroup();
+
+ ///
+ /// Creates a new at the specified offset.
+ ///
+ ///
+ ITextAnchor CreateAnchor(int offset);
+
+ ///
+ /// This event is called directly before a change is applied to the document.
+ ///
+ ///
+ /// It is invalid to modify the document within this event handler.
+ /// Aborting the change (by throwing an exception) is likely to cause corruption of data structures
+ /// that listen to the Changing and Changed events.
+ ///
+ event EventHandler Changing;
+
+ ///
+ /// This event is called directly after a change is applied to the document.
+ ///
+ ///
+ /// It is invalid to modify the document within this event handler.
+ /// Aborting the event handler (by throwing an exception) is likely to cause corruption of data structures
+ /// that listen to the Changing and Changed events.
+ ///
+ event EventHandler Changed;
+ }
+}
diff --git a/ICSharpCode.Editor/IDocumentLine.cs b/ICSharpCode.Editor/IDocumentLine.cs
new file mode 100644
index 0000000000..5709f7e374
--- /dev/null
+++ b/ICSharpCode.Editor/IDocumentLine.cs
@@ -0,0 +1,50 @@
+// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt)
+// This code is distributed under MIT license (for details please see \doc\license.txt)
+
+using System;
+
+namespace ICSharpCode.Editor
+{
+ ///
+ /// A line inside a .
+ ///
+ public interface IDocumentLine
+ {
+ ///
+ /// Gets the starting offset of the line in the document's text.
+ ///
+ int Offset { get; }
+
+ ///
+ /// Gets the length of this line (=the number of characters on the line).
+ ///
+ int Length { get; }
+
+ ///
+ /// Gets the ending offset of the line in the document's text (= Offset + Length).
+ ///
+ int EndOffset { get; }
+
+ ///
+ /// Gets the length of this line, including the line delimiter.
+ ///
+ int TotalLength { get; }
+
+ ///
+ /// Gets the length of the line terminator.
+ /// Returns 1 or 2; or 0 at the end of the document.
+ ///
+ int DelimiterLength { get; }
+
+ ///
+ /// Gets the number of this line.
+ /// The first line has the number 1.
+ ///
+ int LineNumber { get; }
+
+ ///
+ /// Gets the text on this line.
+ ///
+ string Text { get; }
+ }
+}
diff --git a/ICSharpCode.Editor/ITextAnchor.cs b/ICSharpCode.Editor/ITextAnchor.cs
new file mode 100644
index 0000000000..dfc95c9e74
--- /dev/null
+++ b/ICSharpCode.Editor/ITextAnchor.cs
@@ -0,0 +1,102 @@
+// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt)
+// This code is distributed under MIT license (for details please see \doc\license.txt)
+
+using System;
+
+namespace ICSharpCode.Editor
+{
+ ///
+ /// The TextAnchor class references an offset (a position between two characters).
+ /// It automatically updates the offset when text is inserted/removed in front of the anchor.
+ ///
+ ///
+ /// Use the property to get the offset from a text anchor.
+ /// Use the method to create an anchor from an offset.
+ ///
+ ///
+ /// The document will automatically update all text anchors; and because it uses weak references to do so,
+ /// the garbage collector can simply collect the anchor object when you don't need it anymore.
+ ///
+ /// Moreover, the document is able to efficiently update a large number of anchors without having to look
+ /// at each anchor object individually. Updating the offsets of all anchors usually only takes time logarithmic
+ /// to the number of anchors. Retrieving the property also runs in O(lg N).
+ ///
+ ///
+ /// Usage:
+ /// TextAnchor anchor = document.CreateAnchor(offset);
+ /// ChangeMyDocument();
+ /// int newOffset = anchor.Offset;
+ ///
+ ///
+ public interface ITextAnchor
+ {
+ ///
+ /// Gets the text location of this anchor.
+ ///
+ /// Thrown when trying to get the Offset from a deleted anchor.
+ TextLocation Location { get; }
+
+ ///
+ /// Gets the offset of the text anchor.
+ ///
+ /// Thrown when trying to get the Offset from a deleted anchor.
+ int Offset { get; }
+
+ ///
+ /// Controls how the anchor moves.
+ ///
+ AnchorMovementType MovementType { get; set; }
+
+ ///
+ /// Specifies whether the anchor survives deletion of the text containing it.
+ /// false: The anchor is deleted when the a selection that includes the anchor is deleted.
+ /// true: The anchor is not deleted.
+ ///
+ bool SurviveDeletion { get; set; }
+
+ ///
+ /// Gets whether the anchor was deleted.
+ ///
+ bool IsDeleted { get; }
+
+ ///
+ /// Occurs after the anchor was deleted.
+ ///
+ event EventHandler Deleted;
+
+ ///
+ /// Gets the line number of the anchor.
+ ///
+ /// Thrown when trying to get the Offset from a deleted anchor.
+ int Line { get; }
+
+ ///
+ /// Gets the column number of this anchor.
+ ///
+ /// Thrown when trying to get the Offset from a deleted anchor.
+ int Column { get; }
+ }
+
+ ///
+ /// Defines how a text anchor moves.
+ ///
+ public enum AnchorMovementType
+ {
+ ///
+ /// When text is inserted at the anchor position, the type of the insertion
+ /// determines where the caret moves to. For normal insertions, the anchor will stay
+ /// behind the inserted text.
+ ///
+ Default,
+ ///
+ /// Behaves like a start marker - when text is inserted at the anchor position, the anchor will stay
+ /// before the inserted text.
+ ///
+ BeforeInsertion,
+ ///
+ /// Behave like an end marker - when text is insered at the anchor position, the anchor will move
+ /// after the inserted text.
+ ///
+ AfterInsertion
+ }
+}
diff --git a/ICSharpCode.Editor/ITextBuffer.cs b/ICSharpCode.Editor/ITextBuffer.cs
new file mode 100644
index 0000000000..8b950ebb7b
--- /dev/null
+++ b/ICSharpCode.Editor/ITextBuffer.cs
@@ -0,0 +1,130 @@
+// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt)
+// This code is distributed under MIT license (for details please see \doc\license.txt)
+
+using System;
+using System.Collections.Generic;
+using System.IO;
+
+namespace ICSharpCode.Editor
+{
+ ///
+ /// A read-only view on a (potentially mutable) text buffer.
+ /// The IDocument interfaces derives from this interface.
+ ///
+ public interface ITextBuffer
+ {
+ ///
+ /// Gets a version identifier for this text buffer.
+ /// Returns null for unversioned text buffers.
+ ///
+ ITextBufferVersion Version { get; }
+
+ ///
+ /// Creates an immutable snapshot of this text buffer.
+ /// Unlike all other methods in this interface, this method is thread-safe.
+ ///
+ ITextBuffer CreateSnapshot();
+
+ ///
+ /// Creates an immutable snapshot of a part of this text buffer.
+ /// Unlike all other methods in this interface, this method is thread-safe.
+ ///
+ ITextBuffer CreateSnapshot(int offset, int length);
+
+ ///
+ /// Creates a new TextReader to read from this text buffer.
+ ///
+ TextReader CreateReader();
+
+ ///
+ /// Creates a new TextReader to read from this text buffer.
+ ///
+ TextReader CreateReader(int offset, int length);
+
+ ///
+ /// Gets the total text length.
+ ///
+ /// The length of the text, in characters.
+ /// This is the same as Text.Length, but is more efficient because
+ /// it doesn't require creating a String object.
+ int TextLength { get; }
+
+ ///
+ /// Gets the whole text as string.
+ ///
+ string Text { get; }
+
+ ///
+ /// Is raised when the Text property changes.
+ ///
+ event EventHandler TextChanged;
+
+ ///
+ /// Gets a character at the specified position in the document.
+ ///
+ /// The index of the character to get.
+ /// Offset is outside the valid range (0 to TextLength-1).
+ /// The character at the specified position.
+ /// This is the same as Text[offset], but is more efficient because
+ /// it doesn't require creating a String object.
+ char GetCharAt(int offset);
+
+ ///
+ /// Retrieves the text for a portion of the document.
+ ///
+ /// offset or length is outside the valid range.
+ /// This is the same as Text.Substring, but is more efficient because
+ /// it doesn't require creating a String object for the whole document.
+ string GetText(int offset, int length);
+
+ ///
+ /// Gets the index of the first occurrence of any character in the specified array.
+ ///
+ /// Characters to search for
+ /// Start index of the search.
+ /// Length of the area to search.
+ /// The first index where any character was found; or -1 if no occurrence was found.
+ int IndexOfAny(char[] anyOf, int startIndex, int count);
+ }
+
+ ///
+ /// Represents a version identifier for a text buffer.
+ ///
+ ///
+ /// This is SharpDevelop's equivalent to AvalonEdit ChangeTrackingCheckpoint.
+ /// It is used by the ParserService to efficiently detect whether a document has changed and needs reparsing.
+ /// It is a separate class from ITextBuffer to allow the GC to collect the text buffer while the version checkpoint
+ /// is still in use.
+ ///
+ public interface ITextBufferVersion
+ {
+ ///
+ /// Gets whether this checkpoint belongs to the same document as the other checkpoint.
+ ///
+ bool BelongsToSameDocumentAs(ITextBufferVersion other);
+
+ ///
+ /// Compares the age of this checkpoint to the other checkpoint.
+ ///
+ /// This method is thread-safe.
+ /// Raised if 'other' belongs to a different document than this version.
+ /// -1 if this version is older than .
+ /// 0 if this version instance represents the same version as .
+ /// 1 if this version is newer than .
+ int CompareAge(ITextBufferVersion other);
+
+ ///
+ /// Gets the changes from this checkpoint to the other checkpoint.
+ /// If 'other' is older than this checkpoint, reverse changes are calculated.
+ ///
+ /// This method is thread-safe.
+ /// Raised if 'other' belongs to a different document than this checkpoint.
+ IEnumerable GetChangesTo(ITextBufferVersion other);
+
+ ///
+ /// Calculates where the offset has moved in the other buffer version.
+ ///
+ /// Raised if 'other' belongs to a different document than this checkpoint.
+ int MoveOffsetTo(ITextBufferVersion other, int oldOffset, AnchorMovementType movement);
+ }
+}
\ No newline at end of file
diff --git a/ICSharpCode.Editor/ReadOnlyDocument.cs b/ICSharpCode.Editor/ReadOnlyDocument.cs
new file mode 100644
index 0000000000..714ad66b7f
--- /dev/null
+++ b/ICSharpCode.Editor/ReadOnlyDocument.cs
@@ -0,0 +1,321 @@
+// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt)
+// This code is distributed under MIT license (for details please see \doc\license.txt)
+
+using System;
+using System.Collections.Generic;
+
+namespace ICSharpCode.Editor
+{
+ ///
+ /// Read-only implementation of .
+ ///
+ public sealed class ReadOnlyDocument : IDocument
+ {
+ readonly ITextBuffer textBuffer;
+ int[] lines;
+
+ static readonly char[] newline = { '\r', '\n' };
+
+ ///
+ /// Creates a new ReadOnlyDocument from the given text buffer.
+ ///
+ public ReadOnlyDocument(ITextBuffer textBuffer)
+ {
+ if (textBuffer == null)
+ throw new ArgumentNullException("textBuffer");
+ // ensure that underlying buffer is immutable
+ this.textBuffer = textBuffer.CreateSnapshot();
+ List lines = new List();
+ lines.Add(0);
+ int offset = 0;
+ int textLength = textBuffer.TextLength;
+ while ((offset = textBuffer.IndexOfAny(newline, offset, textLength - offset)) >= 0) {
+ offset++;
+ if (textBuffer.GetCharAt(offset - 1) == '\r' && offset < textLength && textBuffer.GetCharAt(offset) == '\n') {
+ offset++;
+ }
+ lines.Add(offset);
+ }
+ this.lines = lines.ToArray();
+ }
+
+ ///
+ /// Creates a new ReadOnlyDocument from the given string.
+ ///
+ public ReadOnlyDocument(string text)
+ : this(new StringTextBuffer(text))
+ {
+ }
+
+ ///
+ public IDocumentLine GetLine(int lineNumber)
+ {
+ if (lineNumber < 1 || lineNumber > lines.Length)
+ throw new ArgumentOutOfRangeException("lineNumber", lineNumber, "Value must be between 1 and " + lines.Length);
+ return new ReadOnlyDocumentLine(this, lineNumber);
+ }
+
+ sealed class ReadOnlyDocumentLine : IDocumentLine
+ {
+ readonly ReadOnlyDocument doc;
+ readonly int lineNumber;
+ readonly int offset, endOffset;
+
+ public ReadOnlyDocumentLine(ReadOnlyDocument doc, int lineNumber)
+ {
+ this.doc = doc;
+ this.lineNumber = lineNumber;
+ this.offset = doc.GetStartOffset(lineNumber);
+ this.endOffset = doc.GetEndOffset(lineNumber);
+ }
+
+ public int Offset {
+ get { return offset; }
+ }
+
+ public int Length {
+ get { return endOffset - offset; }
+ }
+
+ public int EndOffset {
+ get { return endOffset; }
+ }
+
+ public int TotalLength {
+ get {
+ return doc.GetTotalEndOffset(lineNumber) - offset;
+ }
+ }
+
+ public int DelimiterLength {
+ get {
+ return doc.GetTotalEndOffset(lineNumber) - endOffset;
+ }
+ }
+
+ public int LineNumber {
+ get { return lineNumber; }
+ }
+
+ public string Text {
+ get {
+ return doc.GetText(this.Offset, this.Length);
+ }
+ }
+ }
+
+ int GetStartOffset(int lineNumber)
+ {
+ return lines[lineNumber-1];
+ }
+
+ int GetTotalEndOffset(int lineNumber)
+ {
+ return lineNumber < lines.Length ? lines[lineNumber] : textBuffer.TextLength;
+ }
+
+ int GetEndOffset(int lineNumber)
+ {
+ if (lineNumber == lines.Length)
+ return textBuffer.TextLength;
+ int off = lines[lineNumber] - 1;
+ if (off > 0 && textBuffer.GetCharAt(off - 1) == '\r' && textBuffer.GetCharAt(off) == '\n')
+ off--;
+ return off;
+ }
+
+ ///
+ public IDocumentLine GetLineByOffset(int offset)
+ {
+ return GetLine(GetLineNumberForOffset(offset));
+ }
+
+ int GetLineNumberForOffset(int offset)
+ {
+ int r = Array.BinarySearch(lines, offset);
+ return r < 0 ? ~r : r + 1;
+ }
+
+ ///
+ public int GetOffset(int line, int column)
+ {
+ if (line < 1 || line > lines.Length)
+ throw new ArgumentOutOfRangeException("line", line, "Value must be between 1 and " + lines.Length);
+ int lineStart = GetStartOffset(line);
+ if (column <= 0)
+ return lineStart;
+ int lineEnd = GetEndOffset(line);
+ if (column >= lineEnd - lineStart)
+ return lineEnd;
+ return lineStart + column - 1;
+ }
+
+ ///
+ public int GetOffset(TextLocation location)
+ {
+ return GetOffset(location.Line, location.Column);
+ }
+
+ ///
+ public TextLocation GetLocation(int offset)
+ {
+ if (offset < 0 || offset > textBuffer.TextLength)
+ throw new ArgumentOutOfRangeException("offset", offset, "Value must be between 0 and " + textBuffer.TextLength);
+ int line = GetLineNumberForOffset(offset);
+ return new TextLocation(offset-GetStartOffset(line)+1, line);
+ }
+
+ ///
+ public string Text {
+ get { return textBuffer.Text; }
+ set {
+ throw new NotSupportedException();
+ }
+ }
+
+ ///
+ public int TotalNumberOfLines {
+ get { return lines.Length; }
+ }
+
+ ITextBufferVersion ITextBuffer.Version {
+ get { return null; }
+ }
+
+ ///
+ public int TextLength {
+ get { return textBuffer.TextLength; }
+ }
+
+ event EventHandler IDocument.Changing { add {} remove {} }
+
+ event EventHandler IDocument.Changed { add {} remove {} }
+
+ event EventHandler ITextBuffer.TextChanged { add {} remove {} }
+
+ void IDocument.Insert(int offset, string text)
+ {
+ throw new NotSupportedException();
+ }
+
+ void IDocument.Insert(int offset, string text, AnchorMovementType defaultAnchorMovementType)
+ {
+ throw new NotSupportedException();
+ }
+
+ void IDocument.Remove(int offset, int length)
+ {
+ throw new NotSupportedException();
+ }
+
+ void IDocument.Replace(int offset, int length, string newText)
+ {
+ throw new NotSupportedException();
+ }
+
+ void IDocument.StartUndoableAction()
+ {
+ }
+
+ void IDocument.EndUndoableAction()
+ {
+ }
+
+ IDisposable IDocument.OpenUndoGroup()
+ {
+ return null;
+ }
+
+ ///
+ public ITextAnchor CreateAnchor(int offset)
+ {
+ return new ReadOnlyDocumentTextAnchor(GetLocation(offset), offset);
+ }
+
+ sealed class ReadOnlyDocumentTextAnchor : ITextAnchor
+ {
+ readonly TextLocation location;
+ readonly int offset;
+
+ public ReadOnlyDocumentTextAnchor(TextLocation location, int offset)
+ {
+ this.location = location;
+ this.offset = offset;
+ }
+
+ public event EventHandler Deleted { add {} remove {} }
+
+ public TextLocation Location {
+ get { return location; }
+ }
+
+ public int Offset {
+ get { return offset; }
+ }
+
+ public AnchorMovementType MovementType { get; set; }
+
+ public bool SurviveDeletion { get; set; }
+
+ public bool IsDeleted {
+ get { return false; }
+ }
+
+ public int Line {
+ get { return location.Line; }
+ }
+
+ public int Column {
+ get { return location.Column; }
+ }
+ }
+
+ ///
+ public ITextBuffer CreateSnapshot()
+ {
+ return textBuffer; // textBuffer is immutable
+ }
+
+ ///
+ public ITextBuffer CreateSnapshot(int offset, int length)
+ {
+ return textBuffer.CreateSnapshot(offset, length);
+ }
+
+ ///
+ public System.IO.TextReader CreateReader()
+ {
+ return textBuffer.CreateReader();
+ }
+
+ ///
+ public System.IO.TextReader CreateReader(int offset, int length)
+ {
+ return textBuffer.CreateReader(offset, length);
+ }
+
+ ///
+ public char GetCharAt(int offset)
+ {
+ return textBuffer.GetCharAt(offset);
+ }
+
+ ///
+ public string GetText(int offset, int length)
+ {
+ return textBuffer.GetText(offset, length);
+ }
+
+ ///
+ public int IndexOfAny(char[] anyOf, int startIndex, int count)
+ {
+ return textBuffer.IndexOfAny(anyOf, startIndex, count);
+ }
+
+ ///
+ public object GetService(Type serviceType)
+ {
+ return null;
+ }
+ }
+}
diff --git a/ICSharpCode.Editor/StringTextBuffer.cs b/ICSharpCode.Editor/StringTextBuffer.cs
new file mode 100644
index 0000000000..cb9857dac5
--- /dev/null
+++ b/ICSharpCode.Editor/StringTextBuffer.cs
@@ -0,0 +1,85 @@
+// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt)
+// This code is distributed under MIT license (for details please see \doc\license.txt)
+
+using System;
+using System.IO;
+
+namespace ICSharpCode.Editor
+{
+ ///
+ /// Implements the ITextBuffer interface using a string.
+ ///
+ [Serializable]
+ public class StringTextBuffer : ITextBuffer
+ {
+ readonly string text;
+
+ ///
+ /// Creates a new StringTextBuffer with the given text.
+ ///
+ public StringTextBuffer(string text)
+ {
+ if (text == null)
+ throw new ArgumentNullException("text");
+ this.text = text;
+ }
+
+ event EventHandler ITextBuffer.TextChanged { add {} remove {} }
+
+ ITextBufferVersion ITextBuffer.Version {
+ get { return null; }
+ }
+
+ ///
+ public int TextLength {
+ get { return text.Length; }
+ }
+
+ ///
+ public string Text {
+ get { return text; }
+ }
+
+ ///
+ public ITextBuffer CreateSnapshot()
+ {
+ return this; // StringTextBuffer is immutable
+ }
+
+ ///
+ public ITextBuffer CreateSnapshot(int offset, int length)
+ {
+ return new StringTextBuffer(text.Substring(offset, length));
+ }
+
+ ///
+ public TextReader CreateReader()
+ {
+ return new StringReader(text);
+ }
+
+ ///
+ public TextReader CreateReader(int offset, int length)
+ {
+ return new StringReader(text.Substring(offset, length));
+ }
+
+ ///
+ public char GetCharAt(int offset)
+ {
+ return text[offset];
+ }
+
+ ///
+ public string GetText(int offset, int length)
+ {
+ return text.Substring(offset, length);
+ }
+
+ ///
+ public int IndexOfAny(char[] anyOf, int startIndex, int count)
+ {
+ return text.IndexOfAny(anyOf, startIndex, count);
+ }
+ }
+}
diff --git a/ICSharpCode.Editor/TextChangeEventArgs.cs b/ICSharpCode.Editor/TextChangeEventArgs.cs
new file mode 100644
index 0000000000..385f5104a2
--- /dev/null
+++ b/ICSharpCode.Editor/TextChangeEventArgs.cs
@@ -0,0 +1,64 @@
+// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt)
+// This code is distributed under MIT license (for details please see \doc\license.txt)
+
+using System;
+
+namespace ICSharpCode.Editor
+{
+ ///
+ /// Describes a change of the document text.
+ /// This class is thread-safe.
+ ///
+ [Serializable]
+ public class TextChangeEventArgs : EventArgs
+ {
+ readonly int offset;
+ readonly string removedText;
+ readonly string insertedText;
+
+ ///
+ /// The offset at which the change occurs.
+ ///
+ public int Offset {
+ get { return offset; }
+ }
+
+ ///
+ /// The text that was inserted.
+ ///
+ public string RemovedText {
+ get { return removedText; }
+ }
+
+ ///
+ /// The number of characters removed.
+ ///
+ public int RemovalLength {
+ get { return removedText.Length; }
+ }
+
+ ///
+ /// The text that was inserted.
+ ///
+ public string InsertedText {
+ get { return insertedText; }
+ }
+
+ ///
+ /// The number of characters inserted.
+ ///
+ public int InsertionLength {
+ get { return insertedText.Length; }
+ }
+
+ ///
+ /// Creates a new TextChangeEventArgs object.
+ ///
+ public TextChangeEventArgs(int offset, string removedText, string insertedText)
+ {
+ this.offset = offset;
+ this.removedText = removedText ?? string.Empty;
+ this.insertedText = insertedText ?? string.Empty;
+ }
+ }
+}
diff --git a/ICSharpCode.Editor/TextLocation.cs b/ICSharpCode.Editor/TextLocation.cs
new file mode 100644
index 0000000000..eef1fcf145
--- /dev/null
+++ b/ICSharpCode.Editor/TextLocation.cs
@@ -0,0 +1,163 @@
+// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt)
+// This code is distributed under MIT license (for details please see \doc\license.txt)
+
+using System;
+using System.Globalization;
+
+namespace ICSharpCode.Editor
+{
+ ///
+ /// A line/column position.
+ /// Text editor lines/columns are counted started from one.
+ ///
+ ///
+ /// The document provides the methods and
+ /// to convert between offsets and TextLocations.
+ ///
+ [Serializable]
+ public struct TextLocation : IComparable, IEquatable
+ {
+ ///
+ /// Represents no text location (0, 0).
+ ///
+ public static readonly TextLocation Empty = new TextLocation(0, 0);
+
+ ///
+ /// Creates a TextLocation instance.
+ ///
+ public TextLocation(int line, int column)
+ {
+ this.line = line;
+ this.column = column;
+ }
+
+ int column, line;
+
+ ///
+ /// Gets the line number.
+ ///
+ public int Line {
+ get { return line; }
+ }
+
+ ///
+ /// Gets the column number.
+ ///
+ public int Column {
+ get { return column; }
+ }
+
+ ///
+ /// Gets whether the TextLocation instance is empty.
+ ///
+ public bool IsEmpty {
+ get {
+ return column <= 0 && line <= 0;
+ }
+ }
+
+ ///
+ /// Gets a string representation for debugging purposes.
+ ///
+ public override string ToString()
+ {
+ return string.Format(CultureInfo.InvariantCulture, "(Line {1}, Col {0})", this.column, this.line);
+ }
+
+ ///
+ /// Gets a hash code.
+ ///
+ public override int GetHashCode()
+ {
+ return unchecked (191 * column.GetHashCode() ^ line.GetHashCode());
+ }
+
+ ///
+ /// Equality test.
+ ///
+ public override bool Equals(object obj)
+ {
+ if (!(obj is TextLocation)) return false;
+ return (TextLocation)obj == this;
+ }
+
+ ///
+ /// Equality test.
+ ///
+ public bool Equals(TextLocation other)
+ {
+ return this == other;
+ }
+
+ ///
+ /// Equality test.
+ ///
+ public static bool operator ==(TextLocation left, TextLocation right)
+ {
+ return left.column == right.column && left.line == right.line;
+ }
+
+ ///
+ /// Inequality test.
+ ///
+ public static bool operator !=(TextLocation left, TextLocation right)
+ {
+ return left.column != right.column || left.line != right.line;
+ }
+
+ ///
+ /// Compares two text locations.
+ ///
+ public static bool operator <(TextLocation left, TextLocation right)
+ {
+ if (left.line < right.line)
+ return true;
+ else if (left.line == right.line)
+ return left.column < right.column;
+ else
+ return false;
+ }
+
+ ///
+ /// Compares two text locations.
+ ///
+ public static bool operator >(TextLocation left, TextLocation right)
+ {
+ if (left.line > right.line)
+ return true;
+ else if (left.line == right.line)
+ return left.column > right.column;
+ else
+ return false;
+ }
+
+ ///
+ /// Compares two text locations.
+ ///
+ public static bool operator <=(TextLocation left, TextLocation right)
+ {
+ return !(left > right);
+ }
+
+ ///
+ /// Compares two text locations.
+ ///
+ public static bool operator >=(TextLocation left, TextLocation right)
+ {
+ return !(left < right);
+ }
+
+ ///
+ /// Compares two text locations.
+ ///
+ public int CompareTo(TextLocation other)
+ {
+ if (this == other)
+ return 0;
+ if (this < other)
+ return -1;
+ else
+ return 1;
+ }
+ }
+}
diff --git a/ICSharpCode.NRefactory/ICSharpCode.NRefactory.csproj b/ICSharpCode.NRefactory/ICSharpCode.NRefactory.csproj
index 79ce68c693..4d7aeb786a 100644
--- a/ICSharpCode.NRefactory/ICSharpCode.NRefactory.csproj
+++ b/ICSharpCode.NRefactory/ICSharpCode.NRefactory.csproj
@@ -1,4 +1,4 @@
-
+
{3B2A5653-EC97-4001-BB9B-D90F1AF2C371}
@@ -367,6 +367,10 @@
{D68133BD-1E63-496E-9EDE-4FBDBF77B486}
Mono.Cecil
+
+ {F054A788-B591-4561-A8BA-AE745BBEB817}
+ ICSharpCode.Editor
+
\ No newline at end of file
diff --git a/NRefactory.sln b/NRefactory.sln
index c96b7b6f70..baf2f03d50 100644
--- a/NRefactory.sln
+++ b/NRefactory.sln
@@ -1,7 +1,7 @@
Microsoft Visual Studio Solution File, Format Version 11.00
# Visual Studio 2010
-# SharpDevelop 4.1.0.7372-alpha
+# SharpDevelop 4.1.0.7590-alpha
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{DC98210E-1646-483B-819A-2BB8272461E4}"
ProjectSection(SolutionItems) = postProject
README = README
@@ -20,6 +20,8 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Mono.Cecil", "..\Mono.Cecil
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ICSharpCode.NRefactory.Demo", "ICSharpCode.NRefactory.Demo\ICSharpCode.NRefactory.Demo.csproj", "{9C19E629-C93E-4ACB-9A4B-13072B5AEF9D}"
EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ICSharpCode.Editor", "ICSharpCode.Editor\ICSharpCode.Editor.csproj", "{F054A788-B591-4561-A8BA-AE745BBEB817}"
+EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
@@ -68,6 +70,14 @@ Global
{9C19E629-C93E-4ACB-9A4B-13072B5AEF9D}.Release|Any CPU.ActiveCfg = Release|x86
{9C19E629-C93E-4ACB-9A4B-13072B5AEF9D}.Release|x86.Build.0 = Release|x86
{9C19E629-C93E-4ACB-9A4B-13072B5AEF9D}.Release|x86.ActiveCfg = Release|x86
+ {F054A788-B591-4561-A8BA-AE745BBEB817}.Debug|Any CPU.Build.0 = Debug|x86
+ {F054A788-B591-4561-A8BA-AE745BBEB817}.Debug|Any CPU.ActiveCfg = Debug|x86
+ {F054A788-B591-4561-A8BA-AE745BBEB817}.Debug|x86.Build.0 = Debug|x86
+ {F054A788-B591-4561-A8BA-AE745BBEB817}.Debug|x86.ActiveCfg = Debug|x86
+ {F054A788-B591-4561-A8BA-AE745BBEB817}.Release|Any CPU.Build.0 = Release|x86
+ {F054A788-B591-4561-A8BA-AE745BBEB817}.Release|Any CPU.ActiveCfg = Release|x86
+ {F054A788-B591-4561-A8BA-AE745BBEB817}.Release|x86.Build.0 = Release|x86
+ {F054A788-B591-4561-A8BA-AE745BBEB817}.Release|x86.ActiveCfg = Release|x86
EndGlobalSection
GlobalSection(MonoDevelopProperties) = preSolution
StartupItem = ICSharpCode.NRefactory\ICSharpCode.NRefactory.csproj
diff --git a/README b/README
index 551448567d..4c6a493aa3 100644
--- a/README
+++ b/README
@@ -1,5 +1,9 @@
Overview of the NRefactory library:
+ICSharpCode.Editor:
+ Interfaces that abstract from the text editor control used.
+ Maybe future AvalonEdit versions will directly implement these interfaces, but you could also write adapters for other editors.
+
ICSharpCode.NRefactory.TypeSystem:
Contains a language-independent representation of the .NET type system.
@@ -10,8 +14,17 @@ ICSharpCode.NRefactory.CSharp.Ast:
Abstract Syntax Tree for C#
ICSharpCode.NRefactory.CSharp.Resolver:
- Semantic analysis for C#
-
+ Semantic analysis for C# (resolving the meaning of expressions)
+
+ICSharpCode.NRefactory.CSharp.Analysis:
+ Semantic analysis for C# (additional analysis functionality)
+
+ICSharpCode.NRefactory.Documentation:
+ Classes for working with .xml documentation files.
+
+ICSharpCode.NRefactory.PatternMatching:
+ Provides classes for pattern matching over the C# and VB ASTs.
+
ICSharpCode.NRefactory.Util:
Various helper classes.