aboutsummaryrefslogtreecommitdiffstats
path: root/Software/Visual_Studio/Scripting/Tango.Scripting.Editors
diff options
context:
space:
mode:
Diffstat (limited to 'Software/Visual_Studio/Scripting/Tango.Scripting.Editors')
-rw-r--r--Software/Visual_Studio/Scripting/Tango.Scripting.Editors/BreakPointSymbolPressedEventArgs.cs16
-rw-r--r--Software/Visual_Studio/Scripting/Tango.Scripting.Editors/CachedAssembly.cs21
-rw-r--r--Software/Visual_Studio/Scripting/Tango.Scripting.Editors/CachedUsing.cs20
-rw-r--r--Software/Visual_Studio/Scripting/Tango.Scripting.Editors/Document/TextDocument.cs1695
-rw-r--r--Software/Visual_Studio/Scripting/Tango.Scripting.Editors/Document/UndoStack.cs2
-rw-r--r--Software/Visual_Studio/Scripting/Tango.Scripting.Editors/Editing/BreakPointMargin.cs285
-rw-r--r--Software/Visual_Studio/Scripting/Tango.Scripting.Editors/Errors/ITextMarker.cs169
-rw-r--r--Software/Visual_Studio/Scripting/Tango.Scripting.Editors/Errors/TextMarkerService.cs365
-rw-r--r--Software/Visual_Studio/Scripting/Tango.Scripting.Editors/ExtensionMethods.cs2
-rw-r--r--Software/Visual_Studio/Scripting/Tango.Scripting.Editors/Highlighting/OffsetColorizer.cs2
-rw-r--r--Software/Visual_Studio/Scripting/Tango.Scripting.Editors/Highlighting/Resources/CSharp-Mode.xshd29
-rw-r--r--Software/Visual_Studio/Scripting/Tango.Scripting.Editors/Highlighting/Resources/MarkDown-Mode.xshd7
-rw-r--r--Software/Visual_Studio/Scripting/Tango.Scripting.Editors/Highlighting/Resources/XML-Mode.xshd14
-rw-r--r--Software/Visual_Studio/Scripting/Tango.Scripting.Editors/Images/break_point_arrow.pngbin453 -> 0 bytes
-rw-r--r--Software/Visual_Studio/Scripting/Tango.Scripting.Editors/Images/event.pngbin210 -> 0 bytes
-rw-r--r--Software/Visual_Studio/Scripting/Tango.Scripting.Editors/Images/snippet.pngbin147 -> 0 bytes
-rw-r--r--Software/Visual_Studio/Scripting/Tango.Scripting.Editors/Intellisense/CompletionItem.cs7
-rw-r--r--Software/Visual_Studio/Scripting/Tango.Scripting.Editors/Intellisense/EventCompletionItem.cs22
-rw-r--r--Software/Visual_Studio/Scripting/Tango.Scripting.Editors/Intellisense/HideIntellisenseAttribute.cs12
-rw-r--r--Software/Visual_Studio/Scripting/Tango.Scripting.Editors/Intellisense/KnownType.cs75
-rw-r--r--Software/Visual_Studio/Scripting/Tango.Scripting.Editors/Intellisense/KnownTypeEvent.cs21
-rw-r--r--Software/Visual_Studio/Scripting/Tango.Scripting.Editors/Intellisense/KnownTypeMethod.cs2
-rw-r--r--Software/Visual_Studio/Scripting/Tango.Scripting.Editors/Intellisense/SnippetCompletionItem.cs26
-rw-r--r--Software/Visual_Studio/Scripting/Tango.Scripting.Editors/Intellisense/Utils.cs14
-rw-r--r--Software/Visual_Studio/Scripting/Tango.Scripting.Editors/Rendering/TextView.cs2
-rw-r--r--Software/Visual_Studio/Scripting/Tango.Scripting.Editors/ScriptEditor.cs1991
-rw-r--r--Software/Visual_Studio/Scripting/Tango.Scripting.Editors/Tango.Scripting.Editors.csproj33
-rw-r--r--Software/Visual_Studio/Scripting/Tango.Scripting.Editors/Tango.Scripting.Editors_di35u2uj_wpftmp.csproj628
-rw-r--r--Software/Visual_Studio/Scripting/Tango.Scripting.Editors/TextEditor.cs2343
-rw-r--r--Software/Visual_Studio/Scripting/Tango.Scripting.Editors/Themes/Generic.xaml107
-rw-r--r--Software/Visual_Studio/Scripting/Tango.Scripting.Editors/XamlEditor.cs47
-rw-r--r--Software/Visual_Studio/Scripting/Tango.Scripting.Editors/app.config8
-rw-r--r--Software/Visual_Studio/Scripting/Tango.Scripting.Editors/packages.config1
33 files changed, 2469 insertions, 5497 deletions
diff --git a/Software/Visual_Studio/Scripting/Tango.Scripting.Editors/BreakPointSymbolPressedEventArgs.cs b/Software/Visual_Studio/Scripting/Tango.Scripting.Editors/BreakPointSymbolPressedEventArgs.cs
deleted file mode 100644
index 1728bb565..000000000
--- a/Software/Visual_Studio/Scripting/Tango.Scripting.Editors/BreakPointSymbolPressedEventArgs.cs
+++ /dev/null
@@ -1,16 +0,0 @@
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-using System.Threading.Tasks;
-using System.Windows;
-using Tango.Scripting.Core;
-
-namespace Tango.Scripting.Editors
-{
- public class BreakPointSymbolPressedEventArgs : EventArgs
- {
- public ScriptBreakPointSymbol BreakPointSymbol { get; set; }
- public Point Position { get; set; }
- }
-}
diff --git a/Software/Visual_Studio/Scripting/Tango.Scripting.Editors/CachedAssembly.cs b/Software/Visual_Studio/Scripting/Tango.Scripting.Editors/CachedAssembly.cs
deleted file mode 100644
index b0178e63e..000000000
--- a/Software/Visual_Studio/Scripting/Tango.Scripting.Editors/CachedAssembly.cs
+++ /dev/null
@@ -1,21 +0,0 @@
-using Newtonsoft.Json;
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-using System.Threading.Tasks;
-using Tango.Scripting.Editors.Intellisense;
-
-namespace Tango.Scripting.Editors
-{
- public class CachedAssembly
- {
- public String Name { get; set; }
- public List<KnownType> KnownTypes { get; set; }
-
- public CachedAssembly()
- {
- KnownTypes = new List<KnownType>();
- }
- }
-}
diff --git a/Software/Visual_Studio/Scripting/Tango.Scripting.Editors/CachedUsing.cs b/Software/Visual_Studio/Scripting/Tango.Scripting.Editors/CachedUsing.cs
deleted file mode 100644
index 4a663bee9..000000000
--- a/Software/Visual_Studio/Scripting/Tango.Scripting.Editors/CachedUsing.cs
+++ /dev/null
@@ -1,20 +0,0 @@
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-using System.Threading.Tasks;
-using Tango.Scripting.Editors.Intellisense;
-
-namespace Tango.Scripting.Editors
-{
- public class CachedUsing
- {
- public String Namespace { get; set; }
- public List<KnownType> KnownTypes { get; set; }
-
- public CachedUsing()
- {
- KnownTypes = new List<KnownType>();
- }
- }
-}
diff --git a/Software/Visual_Studio/Scripting/Tango.Scripting.Editors/Document/TextDocument.cs b/Software/Visual_Studio/Scripting/Tango.Scripting.Editors/Document/TextDocument.cs
index a95d07fcf..84fc86f44 100644
--- a/Software/Visual_Studio/Scripting/Tango.Scripting.Editors/Document/TextDocument.cs
+++ b/Software/Visual_Studio/Scripting/Tango.Scripting.Editors/Document/TextDocument.cs
@@ -14,884 +14,823 @@ using Tango.Scripting.Editors.Utils;
namespace Tango.Scripting.Editors.Document
{
- /// <summary>
- /// This class is the main class of the text model. Basically, it is a <see cref="System.Text.StringBuilder"/> with events.
- /// </summary>
- /// <remarks>
- /// <b>Thread safety:</b>
- /// <inheritdoc cref="VerifyAccess"/>
- /// <para>However, there is a single method that is thread-safe: <see cref="CreateSnapshot()"/> (and its overloads).</para>
- /// </remarks>
- public sealed class TextDocument : ITextSource, INotifyPropertyChanged
- {
- #region Thread ownership
- readonly object lockObject = new object();
- Thread owner = Thread.CurrentThread;
-
- /// <summary>
- /// Verifies that the current thread is the documents owner thread.
- /// Throws an <see cref="InvalidOperationException"/> if the wrong thread accesses the TextDocument.
- /// </summary>
- /// <remarks>
- /// <para>The TextDocument class is not thread-safe. A document instance expects to have a single owner thread
- /// and will throw an <see cref="InvalidOperationException"/> when accessed from another thread.
- /// It is possible to change the owner thread using the <see cref="SetOwnerThread"/> method.</para>
- /// </remarks>
- public void VerifyAccess()
- {
- if (Thread.CurrentThread != owner)
- throw new InvalidOperationException("TextDocument can be accessed only from the thread that owns it.");
- }
-
- /// <summary>
- /// Transfers ownership of the document to another thread. This method can be used to load
- /// a file into a TextDocument on a background thread and then transfer ownership to the UI thread
- /// for displaying the document.
- /// </summary>
- /// <remarks>
- /// <inheritdoc cref="VerifyAccess"/>
- /// <para>
- /// The owner can be set to null, which means that no thread can access the document. But, if the document
- /// has no owner thread, any thread may take ownership by calling <see cref="SetOwnerThread"/>.
- /// </para>
- /// </remarks>
- public void SetOwnerThread(Thread newOwner)
- {
- // We need to lock here to ensure that in the null owner case,
- // only one thread succeeds in taking ownership.
- lock (lockObject)
- {
- if (owner != null)
- {
- VerifyAccess();
- }
- owner = newOwner;
- }
- }
- #endregion
-
- #region Fields + Constructor
- readonly Rope<char> rope;
- readonly DocumentLineTree lineTree;
- readonly LineManager lineManager;
- readonly TextAnchorTree anchorTree;
- ChangeTrackingCheckpoint currentCheckpoint;
-
- /// <summary>
- /// Create an empty text document.
- /// </summary>
- public TextDocument()
- : this(string.Empty)
- {
- }
-
- /// <summary>
- /// Create a new text document with the specified initial text.
- /// </summary>
- public TextDocument(IEnumerable<char> initialText)
- {
- if (initialText == null)
- throw new ArgumentNullException("initialText");
- rope = new Rope<char>(initialText);
- lineTree = new DocumentLineTree(this);
- lineManager = new LineManager(lineTree, this);
- lineTrackers.CollectionChanged += delegate
- {
- lineManager.UpdateListOfLineTrackers();
- };
-
- anchorTree = new TextAnchorTree(this);
- undoStack = new UndoStack();
- FireChangeEvents();
- }
-
- /// <summary>
- /// Create a new text document with the specified initial text.
- /// </summary>
- public TextDocument(ITextSource initialText)
- : this(GetTextFromTextSource(initialText))
- {
- }
-
- // gets the text from a text source, directly retrieving the underlying rope where possible
- static IEnumerable<char> GetTextFromTextSource(ITextSource textSource)
- {
- if (textSource == null)
- throw new ArgumentNullException("textSource");
-
- RopeTextSource rts = textSource as RopeTextSource;
- if (rts != null)
- return rts.GetRope();
-
- TextDocument doc = textSource as TextDocument;
- if (doc != null)
- return doc.rope;
-
- return textSource.Text;
- }
- #endregion
-
- #region Text
- void ThrowIfRangeInvalid(int offset, int length)
- {
- if (offset < 0 || offset > rope.Length)
- {
- throw new ArgumentOutOfRangeException("offset", offset, "0 <= offset <= " + rope.Length.ToString(CultureInfo.InvariantCulture));
- }
- if (length < 0 || offset + length > rope.Length)
- {
- throw new ArgumentOutOfRangeException("length", length, "0 <= length, offset(" + offset + ")+length <= " + rope.Length.ToString(CultureInfo.InvariantCulture));
- }
- }
-
- /// <inheritdoc/>
- public string GetText(int offset, int length)
- {
- VerifyAccess();
- return rope.ToString(Math.Max(offset, 0), length);
- }
-
- /// <summary>
- /// Retrieves the text for a portion of the document.
- /// </summary>
- public string GetText(ISegment segment)
- {
- if (segment == null)
- throw new ArgumentNullException("segment");
- return GetText(segment.Offset, segment.Length);
- }
-
- int ITextSource.IndexOfAny(char[] anyOf, int startIndex, int count)
- {
- DebugVerifyAccess(); // frequently called (NewLineFinder), so must be fast in release builds
- return rope.IndexOfAny(anyOf, startIndex, count);
- }
-
- /// <inheritdoc/>
- public char GetCharAt(int offset)
- {
- DebugVerifyAccess(); // frequently called, so must be fast in release builds
- return rope[offset];
- }
-
- WeakReference cachedText;
-
- /// <summary>
- /// Gets/Sets the text of the whole document.
- /// </summary>
- public string Text
- {
- get
- {
- VerifyAccess();
- string completeText = cachedText != null ? (cachedText.Target as string) : null;
- if (completeText == null)
- {
- completeText = rope.ToString();
- cachedText = new WeakReference(completeText);
- }
- return completeText;
- }
- set
- {
- VerifyAccess();
- if (value == null)
- throw new ArgumentNullException("value");
- Replace(0, rope.Length, value);
- }
- }
-
- /// <inheritdoc/>
- /// <remarks><inheritdoc cref="Changing"/></remarks>
- public event EventHandler TextChanged;
-
- /// <inheritdoc/>
- public int TextLength
- {
- get
- {
- VerifyAccess();
- return rope.Length;
- }
- }
-
- /// <summary>
- /// Is raised when the TextLength property changes.
- /// </summary>
- /// <remarks><inheritdoc cref="Changing"/></remarks>
- [Obsolete("This event will be removed in a future version; use the PropertyChanged event instead")]
- public event EventHandler TextLengthChanged;
-
- /// <summary>
- /// Is raised when one of the properties <see cref="Text"/>, <see cref="TextLength"/>, <see cref="LineCount"/>,
- /// <see cref="UndoStack"/> changes.
- /// </summary>
- /// <remarks><inheritdoc cref="Changing"/></remarks>
- public event PropertyChangedEventHandler PropertyChanged;
-
- /// <summary>
- /// Is raised before the document changes.
- /// </summary>
- /// <remarks>
- /// <para>Here is the order in which events are raised during a document update:</para>
- /// <list type="bullet">
- /// <item><description><b><see cref="BeginUpdate">BeginUpdate()</see></b></description>
- /// <list type="bullet">
- /// <item><description>Start of change group (on undo stack)</description></item>
- /// <item><description><see cref="UpdateStarted"/> event is raised</description></item>
- /// </list></item>
- /// <item><description><b><see cref="Insert(int,string)">Insert()</see> / <see cref="Remove(int,int)">Remove()</see> / <see cref="Replace(int,int,string)">Replace()</see></b></description>
- /// <list type="bullet">
- /// <item><description><see cref="Changing"/> event is raised</description></item>
- /// <item><description>The document is changed</description></item>
- /// <item><description><see cref="TextAnchor.Deleted">TextAnchor.Deleted</see> event is raised if anchors were
- /// in the deleted text portion</description></item>
- /// <item><description><see cref="Changed"/> event is raised</description></item>
- /// </list></item>
- /// <item><description><b><see cref="EndUpdate">EndUpdate()</see></b></description>
- /// <list type="bullet">
- /// <item><description><see cref="TextChanged"/> event is raised</description></item>
- /// <item><description><see cref="PropertyChanged"/> event is raised (for the Text, TextLength, LineCount properties, in that order)</description></item>
- /// <item><description>End of change group (on undo stack)</description></item>
- /// <item><description><see cref="UpdateFinished"/> event is raised</description></item>
- /// </list></item>
- /// </list>
- /// <para>
- /// If the insert/remove/replace methods are called without a call to <c>BeginUpdate()</c>,
- /// they will call <c>BeginUpdate()</c> and <c>EndUpdate()</c> to ensure no change happens outside of <c>UpdateStarted</c>/<c>UpdateFinished</c>.
- /// </para><para>
- /// There can be multiple document changes between the <c>BeginUpdate()</c> and <c>EndUpdate()</c> calls.
- /// In this case, the events associated with EndUpdate will be raised only once after the whole document update is done.
- /// </para><para>
- /// The <see cref="UndoStack"/> listens to the <c>UpdateStarted</c> and <c>UpdateFinished</c> events to group all changes into a single undo step.
- /// </para>
- /// </remarks>
- public event EventHandler<DocumentChangeEventArgs> Changing;
-
- /// <summary>
- /// Is raised after the document has changed.
- /// </summary>
- /// <remarks><inheritdoc cref="Changing"/></remarks>
- public event EventHandler<DocumentChangeEventArgs> Changed;
-
- /// <summary>
- /// Creates a snapshot of the current text.
- /// </summary>
- /// <remarks>
- /// <para>This method returns an immutable snapshot of the document, and may be safely called even when
- /// the document's owner thread is concurrently modifying the document.
- /// </para><para>
- /// This special thread-safety guarantee is valid only for TextDocument.CreateSnapshot(), not necessarily for other
- /// classes implementing ITextSource.CreateSnapshot().
- /// </para><para>
- /// </para>
- /// </remarks>
- public ITextSource CreateSnapshot()
- {
- lock (lockObject)
- {
- return new RopeTextSource(rope.Clone());
- }
- }
-
- /// <summary>
- /// Creates a snapshot of the current text.
- /// Additionally, creates a checkpoint that allows tracking document changes.
- /// </summary>
- /// <remarks><inheritdoc cref="CreateSnapshot()"/><inheritdoc cref="ChangeTrackingCheckpoint"/></remarks>
- [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", "CA1021:AvoidOutParameters", Justification = "Need to return snapshot and checkpoint together to ensure thread-safety")]
- public ITextSource CreateSnapshot(out ChangeTrackingCheckpoint checkpoint)
- {
- lock (lockObject)
- {
- if (currentCheckpoint == null)
- currentCheckpoint = new ChangeTrackingCheckpoint(lockObject);
- checkpoint = currentCheckpoint;
- return new RopeTextSource(rope.Clone());
- }
- }
-
- internal ChangeTrackingCheckpoint CreateChangeTrackingCheckpoint()
- {
- lock (lockObject)
- {
- if (currentCheckpoint == null)
- currentCheckpoint = new ChangeTrackingCheckpoint(lockObject);
- return currentCheckpoint;
- }
- }
-
- /// <summary>
- /// Creates a snapshot of a part of the current text.
- /// </summary>
- /// <remarks><inheritdoc cref="CreateSnapshot()"/></remarks>
- public ITextSource CreateSnapshot(int offset, int length)
- {
- lock (lockObject)
- {
- return new RopeTextSource(rope.GetRange(offset, length));
- }
- }
-
- /// <inheritdoc/>
- public System.IO.TextReader CreateReader()
- {
- lock (lockObject)
- {
- return new RopeTextReader(rope);
- }
- }
- #endregion
-
- #region BeginUpdate / EndUpdate
- int beginUpdateCount;
-
- /// <summary>
- /// Gets if an update is running.
- /// </summary>
- /// <remarks><inheritdoc cref="BeginUpdate"/></remarks>
- public bool IsInUpdate
- {
- get
- {
- VerifyAccess();
- return beginUpdateCount > 0;
- }
- }
-
- /// <summary>
- /// Immediately calls <see cref="BeginUpdate()"/>,
- /// and returns an IDisposable that calls <see cref="EndUpdate()"/>.
- /// </summary>
- /// <remarks><inheritdoc cref="BeginUpdate"/></remarks>
- public IDisposable RunUpdate()
- {
- BeginUpdate();
- return new CallbackOnDispose(EndUpdate);
- }
-
- /// <summary>
- /// <para>Begins a group of document changes.</para>
- /// <para>Some events are suspended until EndUpdate is called, and the <see cref="UndoStack"/> will
- /// group all changes into a single action.</para>
- /// <para>Calling BeginUpdate several times increments a counter, only after the appropriate number
- /// of EndUpdate calls the events resume their work.</para>
- /// </summary>
- /// <remarks><inheritdoc cref="Changing"/></remarks>
- public void BeginUpdate()
- {
- VerifyAccess();
- if (inDocumentChanging)
- throw new InvalidOperationException("Cannot change document within another document change.");
- beginUpdateCount++;
- if (beginUpdateCount == 1)
- {
- undoStack.StartUndoGroup();
- if (UpdateStarted != null)
- UpdateStarted(this, EventArgs.Empty);
- }
- }
-
- /// <summary>
- /// Ends a group of document changes.
- /// </summary>
- /// <remarks><inheritdoc cref="Changing"/></remarks>
- public void EndUpdate()
- {
- VerifyAccess();
- if (inDocumentChanging)
- throw new InvalidOperationException("Cannot end update within document change.");
- if (beginUpdateCount == 0)
- throw new InvalidOperationException("No update is active.");
- if (beginUpdateCount == 1)
- {
- // fire change events inside the change group - event handlers might add additional
- // document changes to the change group
- FireChangeEvents();
- undoStack.EndUndoGroup();
- beginUpdateCount = 0;
- if (UpdateFinished != null)
- UpdateFinished(this, EventArgs.Empty);
- }
- else
- {
- beginUpdateCount -= 1;
- }
- }
-
- /// <summary>
- /// Occurs when a document change starts.
- /// </summary>
- /// <remarks><inheritdoc cref="Changing"/></remarks>
- public event EventHandler UpdateStarted;
-
- /// <summary>
- /// Occurs when a document change is finished.
- /// </summary>
- /// <remarks><inheritdoc cref="Changing"/></remarks>
- public event EventHandler UpdateFinished;
- #endregion
-
- #region Fire events after update
- int oldTextLength;
- int oldLineCount;
- bool fireTextChanged;
-
- /// <summary>
- /// Fires TextChanged, TextLengthChanged, LineCountChanged if required.
- /// </summary>
- internal void FireChangeEvents()
- {
- // it may be necessary to fire the event multiple times if the document is changed
- // from inside the event handlers
- while (fireTextChanged)
- {
- fireTextChanged = false;
- if (TextChanged != null)
- TextChanged(this, EventArgs.Empty);
- OnPropertyChanged("Text");
-
- int textLength = rope.Length;
- if (textLength != oldTextLength)
- {
- oldTextLength = textLength;
- if (TextLengthChanged != null)
- TextLengthChanged(this, EventArgs.Empty);
- OnPropertyChanged("TextLength");
- }
- int lineCount = lineTree.LineCount;
- if (lineCount != oldLineCount)
- {
- oldLineCount = lineCount;
- if (LineCountChanged != null)
- LineCountChanged(this, EventArgs.Empty);
- OnPropertyChanged("LineCount");
- }
- }
- }
-
- void OnPropertyChanged(string propertyName)
- {
- if (PropertyChanged != null)
- PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
- }
- #endregion
-
- #region Insert / Remove / Replace
- /// <summary>
- /// Inserts text.
- /// </summary>
- public void Insert(int offset, string text)
- {
- Replace(offset, 0, text);
- }
-
- /// <summary>
- /// Removes text.
- /// </summary>
- public void Remove(ISegment segment)
- {
- Replace(segment, string.Empty);
- }
-
- /// <summary>
- /// Removes text.
- /// </summary>
- public void Remove(int offset, int length)
- {
- Replace(offset, length, string.Empty);
- }
-
- internal bool inDocumentChanging;
-
- /// <summary>
- /// Replaces text.
- /// </summary>
- public void Replace(ISegment segment, string text)
- {
- if (segment == null)
- throw new ArgumentNullException("segment");
- Replace(segment.Offset, segment.Length, text, null);
- }
-
- /// <summary>
- /// Replaces text.
- /// </summary>
- public void Replace(int offset, int length, string text)
- {
- Replace(offset, length, text, null);
- }
-
- /// <summary>
- /// Replaces text.
- /// </summary>
- /// <param name="offset">The starting offset of the text to be replaced.</param>
- /// <param name="length">The length of the text to be replaced.</param>
- /// <param name="text">The new text.</param>
- /// <param name="offsetChangeMappingType">The offsetChangeMappingType determines how offsets inside the old text are mapped to the new text.
- /// This affects how the anchors and segments inside the replaced region behave.</param>
- public void Replace(int offset, int length, string text, OffsetChangeMappingType offsetChangeMappingType)
- {
- if (text == null)
- throw new ArgumentNullException("text");
- // Please see OffsetChangeMappingType XML comments for details on how these modes work.
- switch (offsetChangeMappingType)
- {
- case OffsetChangeMappingType.Normal:
- Replace(offset, length, text, null);
- break;
- case OffsetChangeMappingType.KeepAnchorBeforeInsertion:
- Replace(offset, length, text, OffsetChangeMap.FromSingleElement(
- new OffsetChangeMapEntry(offset, length, text.Length, false, true)));
- break;
- case OffsetChangeMappingType.RemoveAndInsert:
- if (length == 0 || text.Length == 0)
- {
- // only insertion or only removal?
- // OffsetChangeMappingType doesn't matter, just use Normal.
- Replace(offset, length, text, null);
- }
- else
- {
- OffsetChangeMap map = new OffsetChangeMap(2);
- map.Add(new OffsetChangeMapEntry(offset, length, 0));
- map.Add(new OffsetChangeMapEntry(offset, 0, text.Length));
- map.Freeze();
- Replace(offset, length, text, map);
- }
- break;
- case OffsetChangeMappingType.CharacterReplace:
- if (length == 0 || text.Length == 0)
- {
- // only insertion or only removal?
- // OffsetChangeMappingType doesn't matter, just use Normal.
- Replace(offset, length, text, null);
- }
- else if (text.Length > length)
- {
- // look at OffsetChangeMappingType.CharacterReplace XML comments on why we need to replace
- // the last character
- OffsetChangeMapEntry entry = new OffsetChangeMapEntry(offset + length - 1, 1, 1 + text.Length - length);
- Replace(offset, length, text, OffsetChangeMap.FromSingleElement(entry));
- }
- else if (text.Length < length)
- {
- OffsetChangeMapEntry entry = new OffsetChangeMapEntry(offset + text.Length, length - text.Length, 0, true, false);
- Replace(offset, length, text, OffsetChangeMap.FromSingleElement(entry));
- }
- else
- {
- Replace(offset, length, text, OffsetChangeMap.Empty);
- }
- break;
- default:
- throw new ArgumentOutOfRangeException("offsetChangeMappingType", offsetChangeMappingType, "Invalid enum value");
- }
- }
-
- /// <summary>
- /// Replaces text.
- /// </summary>
- /// <param name="offset">The starting offset of the text to be replaced.</param>
- /// <param name="length">The length of the text to be replaced.</param>
- /// <param name="text">The new text.</param>
- /// <param name="offsetChangeMap">The offsetChangeMap determines how offsets inside the old text are mapped to the new text.
- /// This affects how the anchors and segments inside the replaced region behave.
- /// If you pass null (the default when using one of the other overloads), the offsets are changed as
- /// in OffsetChangeMappingType.Normal mode.
- /// If you pass OffsetChangeMap.Empty, then everything will stay in its old place (OffsetChangeMappingType.CharacterReplace mode).
- /// The offsetChangeMap must be a valid 'explanation' for the document change. See <see cref="OffsetChangeMap.IsValidForDocumentChange"/>.
- /// Passing an OffsetChangeMap to the Replace method will automatically freeze it to ensure the thread safety of the resulting
- /// DocumentChangeEventArgs instance.
- /// </param>
- public void Replace(int offset, int length, string text, OffsetChangeMap offsetChangeMap)
- {
- if (text == null)
- throw new ArgumentNullException("text");
-
- if (offsetChangeMap != null)
- offsetChangeMap.Freeze();
-
- // Ensure that all changes take place inside an update group.
- // Will also take care of throwing an exception if inDocumentChanging is set.
- BeginUpdate();
- try
- {
- // protect document change against corruption by other changes inside the event handlers
- inDocumentChanging = true;
- try
- {
- // The range verification must wait until after the BeginUpdate() call because the document
- // might be modified inside the UpdateStarted event.
- ThrowIfRangeInvalid(offset, length);
-
- DoReplace(offset, length, text, offsetChangeMap);
- }
- finally
- {
- inDocumentChanging = false;
- }
- }
- finally
- {
- EndUpdate();
- }
- }
-
- void DoReplace(int offset, int length, string newText, OffsetChangeMap offsetChangeMap)
- {
- if (length == 0 && newText.Length == 0)
- return;
-
- // trying to replace a single character in 'Normal' mode?
- // for single characters, 'CharacterReplace' mode is equivalent, but more performant
- // (we don't have to touch the anchorTree at all in 'CharacterReplace' mode)
- if (length == 1 && newText.Length == 1 && offsetChangeMap == null)
- offsetChangeMap = OffsetChangeMap.Empty;
-
- string removedText = rope.ToString(offset, length);
- DocumentChangeEventArgs args = new DocumentChangeEventArgs(offset, removedText, newText, offsetChangeMap);
-
- // fire DocumentChanging event
- if (Changing != null)
- Changing(this, args);
-
- undoStack.Push(this, args);
-
- cachedText = null; // reset cache of complete document text
- fireTextChanged = true;
- DelayedEvents delayedEvents = new DelayedEvents();
-
- lock (lockObject)
- {
- // create linked list of checkpoints, if required
- if (currentCheckpoint != null)
- {
- currentCheckpoint = currentCheckpoint.Append(args);
- }
-
- // now update the textBuffer and lineTree
- if (offset == 0 && length == rope.Length)
- {
- // optimize replacing the whole document
- rope.Clear();
- rope.InsertText(0, newText);
- lineManager.Rebuild();
- }
- else
- {
- rope.RemoveRange(offset, length);
- lineManager.Remove(offset, length);
-#if DEBUG
- lineTree.CheckProperties();
-#endif
- rope.InsertText(offset, newText);
- lineManager.Insert(offset, newText);
-#if DEBUG
- lineTree.CheckProperties();
-#endif
- }
- }
-
- // update text anchors
- if (offsetChangeMap == null)
- {
- anchorTree.HandleTextChange(args.CreateSingleChangeMapEntry(), delayedEvents);
- }
- else
- {
- foreach (OffsetChangeMapEntry entry in offsetChangeMap)
- {
- anchorTree.HandleTextChange(entry, delayedEvents);
- }
- }
-
- // raise delayed events after our data structures are consistent again
- delayedEvents.RaiseEvents();
-
- // fire DocumentChanged event
- if (Changed != null)
- Changed(this, args);
- }
- #endregion
-
- #region GetLineBy...
- /// <summary>
- /// Gets a read-only list of lines.
- /// </summary>
- /// <remarks><inheritdoc cref="DocumentLine"/></remarks>
- public IList<DocumentLine> Lines
- {
- get { return lineTree; }
- }
-
- /// <summary>
- /// Gets a line by the line number: O(log n)
- /// </summary>
- public DocumentLine GetLineByNumber(int number)
- {
- VerifyAccess();
- if (number < 1 || number > lineTree.LineCount)
- throw new ArgumentOutOfRangeException("number", number, "Value must be between 1 and " + lineTree.LineCount);
- return lineTree.GetByNumber(number);
- }
-
- /// <summary>
- /// Gets a document lines by offset.
- /// Runtime: O(log n)
- /// </summary>
- [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Globalization", "CA1305:SpecifyIFormatProvider", MessageId = "System.Int32.ToString")]
- public DocumentLine GetLineByOffset(int offset)
- {
- VerifyAccess();
- if (offset < 0 || offset > rope.Length)
- {
- throw new ArgumentOutOfRangeException("offset", offset, "0 <= offset <= " + rope.Length.ToString());
- }
- return lineTree.GetByOffset(offset);
- }
- #endregion
-
- /// <summary>
- /// Gets the offset from a text location.
- /// </summary>
- /// <seealso cref="GetLocation"/>
- public int GetOffset(TextLocation location)
- {
- return GetOffset(location.Line, location.Column);
- }
-
- /// <summary>
- /// Gets the offset from a text location.
- /// </summary>
- /// <seealso cref="GetLocation"/>
- public int GetOffset(int line, int column)
- {
- DocumentLine docLine = GetLineByNumber(line);
- if (column <= 0)
- return docLine.Offset;
- if (column > docLine.Length)
- return docLine.EndOffset;
- return docLine.Offset + column - 1;
- }
-
- /// <summary>
- /// Gets the location from an offset.
- /// </summary>
- /// <seealso cref="GetOffset(TextLocation)"/>
- public TextLocation GetLocation(int offset)
- {
- DocumentLine line = GetLineByOffset(offset);
- return new TextLocation(line.LineNumber, offset - line.Offset + 1);
- }
-
- readonly ObservableCollection<ILineTracker> lineTrackers = new ObservableCollection<ILineTracker>();
-
- /// <summary>
- /// Gets the list of <see cref="ILineTracker"/>s attached to this document.
- /// You can add custom line trackers to this list.
- /// </summary>
- public IList<ILineTracker> LineTrackers
- {
- get
- {
- VerifyAccess();
- return lineTrackers;
- }
- }
-
- UndoStack undoStack;
-
- /// <summary>
- /// Gets the <see cref="UndoStack"/> of the document.
- /// </summary>
- /// <remarks>This property can also be used to set the undo stack, e.g. for sharing a common undo stack between multiple documents.</remarks>
- public UndoStack UndoStack
- {
- get { return undoStack; }
- set
- {
- if (value == null)
- throw new ArgumentNullException();
- if (value != undoStack)
- {
- undoStack.ClearAll(); // first clear old undo stack, so that it can't be used to perform unexpected changes on this document
- // ClearAll() will also throw an exception when it's not safe to replace the undo stack (e.g. update is currently in progress)
- undoStack = value;
- OnPropertyChanged("UndoStack");
- }
- }
- }
-
- /// <summary>
- /// Creates a new <see cref="TextAnchor"/> at the specified offset.
- /// </summary>
- /// <inheritdoc cref="TextAnchor" select="remarks|example"/>
- public TextAnchor CreateAnchor(int offset)
- {
- VerifyAccess();
- if (offset < 0 || offset > rope.Length)
- {
- throw new ArgumentOutOfRangeException("offset", offset, "0 <= offset <= " + rope.Length.ToString(CultureInfo.InvariantCulture));
- }
- return anchorTree.CreateAnchor(offset);
- }
-
- #region LineCount
- /// <summary>
- /// Gets the total number of lines in the document.
- /// Runtime: O(1).
- /// </summary>
- public int LineCount
- {
- get
- {
- VerifyAccess();
- return lineTree.LineCount;
- }
- }
-
- /// <summary>
- /// Is raised when the LineCount property changes.
- /// </summary>
- [Obsolete("This event will be removed in a future version; use the PropertyChanged event instead")]
- public event EventHandler LineCountChanged;
- #endregion
-
- #region Debugging
- [Conditional("DEBUG")]
- internal void DebugVerifyAccess()
- {
- VerifyAccess();
- }
-
- /// <summary>
- /// Gets the document lines tree in string form.
- /// </summary>
- [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
- [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", "CA1024:UsePropertiesWhereAppropriate")]
- internal string GetLineTreeAsString()
- {
-#if DEBUG
- return lineTree.GetTreeAsString();
-#else
+ /// <summary>
+ /// This class is the main class of the text model. Basically, it is a <see cref="System.Text.StringBuilder"/> with events.
+ /// </summary>
+ /// <remarks>
+ /// <b>Thread safety:</b>
+ /// <inheritdoc cref="VerifyAccess"/>
+ /// <para>However, there is a single method that is thread-safe: <see cref="CreateSnapshot()"/> (and its overloads).</para>
+ /// </remarks>
+ public sealed class TextDocument : ITextSource, INotifyPropertyChanged
+ {
+ #region Thread ownership
+ readonly object lockObject = new object();
+ Thread owner = Thread.CurrentThread;
+
+ /// <summary>
+ /// Verifies that the current thread is the documents owner thread.
+ /// Throws an <see cref="InvalidOperationException"/> if the wrong thread accesses the TextDocument.
+ /// </summary>
+ /// <remarks>
+ /// <para>The TextDocument class is not thread-safe. A document instance expects to have a single owner thread
+ /// and will throw an <see cref="InvalidOperationException"/> when accessed from another thread.
+ /// It is possible to change the owner thread using the <see cref="SetOwnerThread"/> method.</para>
+ /// </remarks>
+ public void VerifyAccess()
+ {
+ if (Thread.CurrentThread != owner)
+ throw new InvalidOperationException("TextDocument can be accessed only from the thread that owns it.");
+ }
+
+ /// <summary>
+ /// Transfers ownership of the document to another thread. This method can be used to load
+ /// a file into a TextDocument on a background thread and then transfer ownership to the UI thread
+ /// for displaying the document.
+ /// </summary>
+ /// <remarks>
+ /// <inheritdoc cref="VerifyAccess"/>
+ /// <para>
+ /// The owner can be set to null, which means that no thread can access the document. But, if the document
+ /// has no owner thread, any thread may take ownership by calling <see cref="SetOwnerThread"/>.
+ /// </para>
+ /// </remarks>
+ public void SetOwnerThread(Thread newOwner)
+ {
+ // We need to lock here to ensure that in the null owner case,
+ // only one thread succeeds in taking ownership.
+ lock (lockObject) {
+ if (owner != null) {
+ VerifyAccess();
+ }
+ owner = newOwner;
+ }
+ }
+ #endregion
+
+ #region Fields + Constructor
+ readonly Rope<char> rope;
+ readonly DocumentLineTree lineTree;
+ readonly LineManager lineManager;
+ readonly TextAnchorTree anchorTree;
+ ChangeTrackingCheckpoint currentCheckpoint;
+
+ /// <summary>
+ /// Create an empty text document.
+ /// </summary>
+ public TextDocument()
+ : this(string.Empty)
+ {
+ }
+
+ /// <summary>
+ /// Create a new text document with the specified initial text.
+ /// </summary>
+ public TextDocument(IEnumerable<char> initialText)
+ {
+ if (initialText == null)
+ throw new ArgumentNullException("initialText");
+ rope = new Rope<char>(initialText);
+ lineTree = new DocumentLineTree(this);
+ lineManager = new LineManager(lineTree, this);
+ lineTrackers.CollectionChanged += delegate {
+ lineManager.UpdateListOfLineTrackers();
+ };
+
+ anchorTree = new TextAnchorTree(this);
+ undoStack = new UndoStack();
+ FireChangeEvents();
+ }
+
+ /// <summary>
+ /// Create a new text document with the specified initial text.
+ /// </summary>
+ public TextDocument(ITextSource initialText)
+ : this(GetTextFromTextSource(initialText))
+ {
+ }
+
+ // gets the text from a text source, directly retrieving the underlying rope where possible
+ static IEnumerable<char> GetTextFromTextSource(ITextSource textSource)
+ {
+ if (textSource == null)
+ throw new ArgumentNullException("textSource");
+
+ RopeTextSource rts = textSource as RopeTextSource;
+ if (rts != null)
+ return rts.GetRope();
+
+ TextDocument doc = textSource as TextDocument;
+ if (doc != null)
+ return doc.rope;
+
+ return textSource.Text;
+ }
+ #endregion
+
+ #region Text
+ void ThrowIfRangeInvalid(int offset, int length)
+ {
+ if (offset < 0 || offset > rope.Length) {
+ throw new ArgumentOutOfRangeException("offset", offset, "0 <= offset <= " + rope.Length.ToString(CultureInfo.InvariantCulture));
+ }
+ if (length < 0 || offset + length > rope.Length) {
+ throw new ArgumentOutOfRangeException("length", length, "0 <= length, offset(" + offset + ")+length <= " + rope.Length.ToString(CultureInfo.InvariantCulture));
+ }
+ }
+
+ /// <inheritdoc/>
+ public string GetText(int offset, int length)
+ {
+ VerifyAccess();
+ return rope.ToString(offset, length);
+ }
+
+ /// <summary>
+ /// Retrieves the text for a portion of the document.
+ /// </summary>
+ public string GetText(ISegment segment)
+ {
+ if (segment == null)
+ throw new ArgumentNullException("segment");
+ return GetText(segment.Offset, segment.Length);
+ }
+
+ int ITextSource.IndexOfAny(char[] anyOf, int startIndex, int count)
+ {
+ DebugVerifyAccess(); // frequently called (NewLineFinder), so must be fast in release builds
+ return rope.IndexOfAny(anyOf, startIndex, count);
+ }
+
+ /// <inheritdoc/>
+ public char GetCharAt(int offset)
+ {
+ DebugVerifyAccess(); // frequently called, so must be fast in release builds
+ return rope[offset];
+ }
+
+ WeakReference cachedText;
+
+ /// <summary>
+ /// Gets/Sets the text of the whole document.
+ /// </summary>
+ public string Text {
+ get {
+ VerifyAccess();
+ string completeText = cachedText != null ? (cachedText.Target as string) : null;
+ if (completeText == null) {
+ completeText = rope.ToString();
+ cachedText = new WeakReference(completeText);
+ }
+ return completeText;
+ }
+ set {
+ VerifyAccess();
+ if (value == null)
+ throw new ArgumentNullException("value");
+ Replace(0, rope.Length, value);
+ }
+ }
+
+ /// <inheritdoc/>
+ /// <remarks><inheritdoc cref="Changing"/></remarks>
+ public event EventHandler TextChanged;
+
+ /// <inheritdoc/>
+ public int TextLength {
+ get {
+ VerifyAccess();
+ return rope.Length;
+ }
+ }
+
+ /// <summary>
+ /// Is raised when the TextLength property changes.
+ /// </summary>
+ /// <remarks><inheritdoc cref="Changing"/></remarks>
+ [Obsolete("This event will be removed in a future version; use the PropertyChanged event instead")]
+ public event EventHandler TextLengthChanged;
+
+ /// <summary>
+ /// Is raised when one of the properties <see cref="Text"/>, <see cref="TextLength"/>, <see cref="LineCount"/>,
+ /// <see cref="UndoStack"/> changes.
+ /// </summary>
+ /// <remarks><inheritdoc cref="Changing"/></remarks>
+ public event PropertyChangedEventHandler PropertyChanged;
+
+ /// <summary>
+ /// Is raised before the document changes.
+ /// </summary>
+ /// <remarks>
+ /// <para>Here is the order in which events are raised during a document update:</para>
+ /// <list type="bullet">
+ /// <item><description><b><see cref="BeginUpdate">BeginUpdate()</see></b></description>
+ /// <list type="bullet">
+ /// <item><description>Start of change group (on undo stack)</description></item>
+ /// <item><description><see cref="UpdateStarted"/> event is raised</description></item>
+ /// </list></item>
+ /// <item><description><b><see cref="Insert(int,string)">Insert()</see> / <see cref="Remove(int,int)">Remove()</see> / <see cref="Replace(int,int,string)">Replace()</see></b></description>
+ /// <list type="bullet">
+ /// <item><description><see cref="Changing"/> event is raised</description></item>
+ /// <item><description>The document is changed</description></item>
+ /// <item><description><see cref="TextAnchor.Deleted">TextAnchor.Deleted</see> event is raised if anchors were
+ /// in the deleted text portion</description></item>
+ /// <item><description><see cref="Changed"/> event is raised</description></item>
+ /// </list></item>
+ /// <item><description><b><see cref="EndUpdate">EndUpdate()</see></b></description>
+ /// <list type="bullet">
+ /// <item><description><see cref="TextChanged"/> event is raised</description></item>
+ /// <item><description><see cref="PropertyChanged"/> event is raised (for the Text, TextLength, LineCount properties, in that order)</description></item>
+ /// <item><description>End of change group (on undo stack)</description></item>
+ /// <item><description><see cref="UpdateFinished"/> event is raised</description></item>
+ /// </list></item>
+ /// </list>
+ /// <para>
+ /// If the insert/remove/replace methods are called without a call to <c>BeginUpdate()</c>,
+ /// they will call <c>BeginUpdate()</c> and <c>EndUpdate()</c> to ensure no change happens outside of <c>UpdateStarted</c>/<c>UpdateFinished</c>.
+ /// </para><para>
+ /// There can be multiple document changes between the <c>BeginUpdate()</c> and <c>EndUpdate()</c> calls.
+ /// In this case, the events associated with EndUpdate will be raised only once after the whole document update is done.
+ /// </para><para>
+ /// The <see cref="UndoStack"/> listens to the <c>UpdateStarted</c> and <c>UpdateFinished</c> events to group all changes into a single undo step.
+ /// </para>
+ /// </remarks>
+ public event EventHandler<DocumentChangeEventArgs> Changing;
+
+ /// <summary>
+ /// Is raised after the document has changed.
+ /// </summary>
+ /// <remarks><inheritdoc cref="Changing"/></remarks>
+ public event EventHandler<DocumentChangeEventArgs> Changed;
+
+ /// <summary>
+ /// Creates a snapshot of the current text.
+ /// </summary>
+ /// <remarks>
+ /// <para>This method returns an immutable snapshot of the document, and may be safely called even when
+ /// the document's owner thread is concurrently modifying the document.
+ /// </para><para>
+ /// This special thread-safety guarantee is valid only for TextDocument.CreateSnapshot(), not necessarily for other
+ /// classes implementing ITextSource.CreateSnapshot().
+ /// </para><para>
+ /// </para>
+ /// </remarks>
+ public ITextSource CreateSnapshot()
+ {
+ lock (lockObject) {
+ return new RopeTextSource(rope.Clone());
+ }
+ }
+
+ /// <summary>
+ /// Creates a snapshot of the current text.
+ /// Additionally, creates a checkpoint that allows tracking document changes.
+ /// </summary>
+ /// <remarks><inheritdoc cref="CreateSnapshot()"/><inheritdoc cref="ChangeTrackingCheckpoint"/></remarks>
+ [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", "CA1021:AvoidOutParameters", Justification = "Need to return snapshot and checkpoint together to ensure thread-safety")]
+ public ITextSource CreateSnapshot(out ChangeTrackingCheckpoint checkpoint)
+ {
+ lock (lockObject) {
+ if (currentCheckpoint == null)
+ currentCheckpoint = new ChangeTrackingCheckpoint(lockObject);
+ checkpoint = currentCheckpoint;
+ return new RopeTextSource(rope.Clone());
+ }
+ }
+
+ internal ChangeTrackingCheckpoint CreateChangeTrackingCheckpoint()
+ {
+ lock (lockObject) {
+ if (currentCheckpoint == null)
+ currentCheckpoint = new ChangeTrackingCheckpoint(lockObject);
+ return currentCheckpoint;
+ }
+ }
+
+ /// <summary>
+ /// Creates a snapshot of a part of the current text.
+ /// </summary>
+ /// <remarks><inheritdoc cref="CreateSnapshot()"/></remarks>
+ public ITextSource CreateSnapshot(int offset, int length)
+ {
+ lock (lockObject) {
+ return new RopeTextSource(rope.GetRange(offset, length));
+ }
+ }
+
+ /// <inheritdoc/>
+ public System.IO.TextReader CreateReader()
+ {
+ lock (lockObject) {
+ return new RopeTextReader(rope);
+ }
+ }
+ #endregion
+
+ #region BeginUpdate / EndUpdate
+ int beginUpdateCount;
+
+ /// <summary>
+ /// Gets if an update is running.
+ /// </summary>
+ /// <remarks><inheritdoc cref="BeginUpdate"/></remarks>
+ public bool IsInUpdate {
+ get {
+ VerifyAccess();
+ return beginUpdateCount > 0;
+ }
+ }
+
+ /// <summary>
+ /// Immediately calls <see cref="BeginUpdate()"/>,
+ /// and returns an IDisposable that calls <see cref="EndUpdate()"/>.
+ /// </summary>
+ /// <remarks><inheritdoc cref="BeginUpdate"/></remarks>
+ public IDisposable RunUpdate()
+ {
+ BeginUpdate();
+ return new CallbackOnDispose(EndUpdate);
+ }
+
+ /// <summary>
+ /// <para>Begins a group of document changes.</para>
+ /// <para>Some events are suspended until EndUpdate is called, and the <see cref="UndoStack"/> will
+ /// group all changes into a single action.</para>
+ /// <para>Calling BeginUpdate several times increments a counter, only after the appropriate number
+ /// of EndUpdate calls the events resume their work.</para>
+ /// </summary>
+ /// <remarks><inheritdoc cref="Changing"/></remarks>
+ public void BeginUpdate()
+ {
+ VerifyAccess();
+ if (inDocumentChanging)
+ throw new InvalidOperationException("Cannot change document within another document change.");
+ beginUpdateCount++;
+ if (beginUpdateCount == 1) {
+ undoStack.StartUndoGroup();
+ if (UpdateStarted != null)
+ UpdateStarted(this, EventArgs.Empty);
+ }
+ }
+
+ /// <summary>
+ /// Ends a group of document changes.
+ /// </summary>
+ /// <remarks><inheritdoc cref="Changing"/></remarks>
+ public void EndUpdate()
+ {
+ VerifyAccess();
+ if (inDocumentChanging)
+ throw new InvalidOperationException("Cannot end update within document change.");
+ if (beginUpdateCount == 0)
+ throw new InvalidOperationException("No update is active.");
+ if (beginUpdateCount == 1) {
+ // fire change events inside the change group - event handlers might add additional
+ // document changes to the change group
+ FireChangeEvents();
+ undoStack.EndUndoGroup();
+ beginUpdateCount = 0;
+ if (UpdateFinished != null)
+ UpdateFinished(this, EventArgs.Empty);
+ } else {
+ beginUpdateCount -= 1;
+ }
+ }
+
+ /// <summary>
+ /// Occurs when a document change starts.
+ /// </summary>
+ /// <remarks><inheritdoc cref="Changing"/></remarks>
+ public event EventHandler UpdateStarted;
+
+ /// <summary>
+ /// Occurs when a document change is finished.
+ /// </summary>
+ /// <remarks><inheritdoc cref="Changing"/></remarks>
+ public event EventHandler UpdateFinished;
+ #endregion
+
+ #region Fire events after update
+ int oldTextLength;
+ int oldLineCount;
+ bool fireTextChanged;
+
+ /// <summary>
+ /// Fires TextChanged, TextLengthChanged, LineCountChanged if required.
+ /// </summary>
+ internal void FireChangeEvents()
+ {
+ // it may be necessary to fire the event multiple times if the document is changed
+ // from inside the event handlers
+ while (fireTextChanged) {
+ fireTextChanged = false;
+ if (TextChanged != null)
+ TextChanged(this, EventArgs.Empty);
+ OnPropertyChanged("Text");
+
+ int textLength = rope.Length;
+ if (textLength != oldTextLength) {
+ oldTextLength = textLength;
+ if (TextLengthChanged != null)
+ TextLengthChanged(this, EventArgs.Empty);
+ OnPropertyChanged("TextLength");
+ }
+ int lineCount = lineTree.LineCount;
+ if (lineCount != oldLineCount) {
+ oldLineCount = lineCount;
+ if (LineCountChanged != null)
+ LineCountChanged(this, EventArgs.Empty);
+ OnPropertyChanged("LineCount");
+ }
+ }
+ }
+
+ void OnPropertyChanged(string propertyName)
+ {
+ if (PropertyChanged != null)
+ PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
+ }
+ #endregion
+
+ #region Insert / Remove / Replace
+ /// <summary>
+ /// Inserts text.
+ /// </summary>
+ public void Insert(int offset, string text)
+ {
+ Replace(offset, 0, text);
+ }
+
+ /// <summary>
+ /// Removes text.
+ /// </summary>
+ public void Remove(ISegment segment)
+ {
+ Replace(segment, string.Empty);
+ }
+
+ /// <summary>
+ /// Removes text.
+ /// </summary>
+ public void Remove(int offset, int length)
+ {
+ Replace(offset, length, string.Empty);
+ }
+
+ internal bool inDocumentChanging;
+
+ /// <summary>
+ /// Replaces text.
+ /// </summary>
+ public void Replace(ISegment segment, string text)
+ {
+ if (segment == null)
+ throw new ArgumentNullException("segment");
+ Replace(segment.Offset, segment.Length, text, null);
+ }
+
+ /// <summary>
+ /// Replaces text.
+ /// </summary>
+ public void Replace(int offset, int length, string text)
+ {
+ Replace(offset, length, text, null);
+ }
+
+ /// <summary>
+ /// Replaces text.
+ /// </summary>
+ /// <param name="offset">The starting offset of the text to be replaced.</param>
+ /// <param name="length">The length of the text to be replaced.</param>
+ /// <param name="text">The new text.</param>
+ /// <param name="offsetChangeMappingType">The offsetChangeMappingType determines how offsets inside the old text are mapped to the new text.
+ /// This affects how the anchors and segments inside the replaced region behave.</param>
+ public void Replace(int offset, int length, string text, OffsetChangeMappingType offsetChangeMappingType)
+ {
+ if (text == null)
+ throw new ArgumentNullException("text");
+ // Please see OffsetChangeMappingType XML comments for details on how these modes work.
+ switch (offsetChangeMappingType) {
+ case OffsetChangeMappingType.Normal:
+ Replace(offset, length, text, null);
+ break;
+ case OffsetChangeMappingType.KeepAnchorBeforeInsertion:
+ Replace(offset, length, text, OffsetChangeMap.FromSingleElement(
+ new OffsetChangeMapEntry(offset, length, text.Length, false, true)));
+ break;
+ case OffsetChangeMappingType.RemoveAndInsert:
+ if (length == 0 || text.Length == 0) {
+ // only insertion or only removal?
+ // OffsetChangeMappingType doesn't matter, just use Normal.
+ Replace(offset, length, text, null);
+ } else {
+ OffsetChangeMap map = new OffsetChangeMap(2);
+ map.Add(new OffsetChangeMapEntry(offset, length, 0));
+ map.Add(new OffsetChangeMapEntry(offset, 0, text.Length));
+ map.Freeze();
+ Replace(offset, length, text, map);
+ }
+ break;
+ case OffsetChangeMappingType.CharacterReplace:
+ if (length == 0 || text.Length == 0) {
+ // only insertion or only removal?
+ // OffsetChangeMappingType doesn't matter, just use Normal.
+ Replace(offset, length, text, null);
+ } else if (text.Length > length) {
+ // look at OffsetChangeMappingType.CharacterReplace XML comments on why we need to replace
+ // the last character
+ OffsetChangeMapEntry entry = new OffsetChangeMapEntry(offset + length - 1, 1, 1 + text.Length - length);
+ Replace(offset, length, text, OffsetChangeMap.FromSingleElement(entry));
+ } else if (text.Length < length) {
+ OffsetChangeMapEntry entry = new OffsetChangeMapEntry(offset + text.Length, length - text.Length, 0, true, false);
+ Replace(offset, length, text, OffsetChangeMap.FromSingleElement(entry));
+ } else {
+ Replace(offset, length, text, OffsetChangeMap.Empty);
+ }
+ break;
+ default:
+ throw new ArgumentOutOfRangeException("offsetChangeMappingType", offsetChangeMappingType, "Invalid enum value");
+ }
+ }
+
+ /// <summary>
+ /// Replaces text.
+ /// </summary>
+ /// <param name="offset">The starting offset of the text to be replaced.</param>
+ /// <param name="length">The length of the text to be replaced.</param>
+ /// <param name="text">The new text.</param>
+ /// <param name="offsetChangeMap">The offsetChangeMap determines how offsets inside the old text are mapped to the new text.
+ /// This affects how the anchors and segments inside the replaced region behave.
+ /// If you pass null (the default when using one of the other overloads), the offsets are changed as
+ /// in OffsetChangeMappingType.Normal mode.
+ /// If you pass OffsetChangeMap.Empty, then everything will stay in its old place (OffsetChangeMappingType.CharacterReplace mode).
+ /// The offsetChangeMap must be a valid 'explanation' for the document change. See <see cref="OffsetChangeMap.IsValidForDocumentChange"/>.
+ /// Passing an OffsetChangeMap to the Replace method will automatically freeze it to ensure the thread safety of the resulting
+ /// DocumentChangeEventArgs instance.
+ /// </param>
+ public void Replace(int offset, int length, string text, OffsetChangeMap offsetChangeMap)
+ {
+ if (text == null)
+ throw new ArgumentNullException("text");
+
+ if (offsetChangeMap != null)
+ offsetChangeMap.Freeze();
+
+ // Ensure that all changes take place inside an update group.
+ // Will also take care of throwing an exception if inDocumentChanging is set.
+ BeginUpdate();
+ try {
+ // protect document change against corruption by other changes inside the event handlers
+ inDocumentChanging = true;
+ try {
+ // The range verification must wait until after the BeginUpdate() call because the document
+ // might be modified inside the UpdateStarted event.
+ ThrowIfRangeInvalid(offset, length);
+
+ DoReplace(offset, length, text, offsetChangeMap);
+ } finally {
+ inDocumentChanging = false;
+ }
+ } finally {
+ EndUpdate();
+ }
+ }
+
+ void DoReplace(int offset, int length, string newText, OffsetChangeMap offsetChangeMap)
+ {
+ if (length == 0 && newText.Length == 0)
+ return;
+
+ // trying to replace a single character in 'Normal' mode?
+ // for single characters, 'CharacterReplace' mode is equivalent, but more performant
+ // (we don't have to touch the anchorTree at all in 'CharacterReplace' mode)
+ if (length == 1 && newText.Length == 1 && offsetChangeMap == null)
+ offsetChangeMap = OffsetChangeMap.Empty;
+
+ string removedText = rope.ToString(offset, length);
+ DocumentChangeEventArgs args = new DocumentChangeEventArgs(offset, removedText, newText, offsetChangeMap);
+
+ // fire DocumentChanging event
+ if (Changing != null)
+ Changing(this, args);
+
+ undoStack.Push(this, args);
+
+ cachedText = null; // reset cache of complete document text
+ fireTextChanged = true;
+ DelayedEvents delayedEvents = new DelayedEvents();
+
+ lock (lockObject) {
+ // create linked list of checkpoints, if required
+ if (currentCheckpoint != null) {
+ currentCheckpoint = currentCheckpoint.Append(args);
+ }
+
+ // now update the textBuffer and lineTree
+ if (offset == 0 && length == rope.Length) {
+ // optimize replacing the whole document
+ rope.Clear();
+ rope.InsertText(0, newText);
+ lineManager.Rebuild();
+ } else {
+ rope.RemoveRange(offset, length);
+ lineManager.Remove(offset, length);
+ #if DEBUG
+ lineTree.CheckProperties();
+ #endif
+ rope.InsertText(offset, newText);
+ lineManager.Insert(offset, newText);
+ #if DEBUG
+ lineTree.CheckProperties();
+ #endif
+ }
+ }
+
+ // update text anchors
+ if (offsetChangeMap == null) {
+ anchorTree.HandleTextChange(args.CreateSingleChangeMapEntry(), delayedEvents);
+ } else {
+ foreach (OffsetChangeMapEntry entry in offsetChangeMap) {
+ anchorTree.HandleTextChange(entry, delayedEvents);
+ }
+ }
+
+ // raise delayed events after our data structures are consistent again
+ delayedEvents.RaiseEvents();
+
+ // fire DocumentChanged event
+ if (Changed != null)
+ Changed(this, args);
+ }
+ #endregion
+
+ #region GetLineBy...
+ /// <summary>
+ /// Gets a read-only list of lines.
+ /// </summary>
+ /// <remarks><inheritdoc cref="DocumentLine"/></remarks>
+ public IList<DocumentLine> Lines {
+ get { return lineTree; }
+ }
+
+ /// <summary>
+ /// Gets a line by the line number: O(log n)
+ /// </summary>
+ public DocumentLine GetLineByNumber(int number)
+ {
+ VerifyAccess();
+ if (number < 1 || number > lineTree.LineCount)
+ throw new ArgumentOutOfRangeException("number", number, "Value must be between 1 and " + lineTree.LineCount);
+ return lineTree.GetByNumber(number);
+ }
+
+ /// <summary>
+ /// Gets a document lines by offset.
+ /// Runtime: O(log n)
+ /// </summary>
+ [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Globalization", "CA1305:SpecifyIFormatProvider", MessageId = "System.Int32.ToString")]
+ public DocumentLine GetLineByOffset(int offset)
+ {
+ VerifyAccess();
+ if (offset < 0 || offset > rope.Length) {
+ throw new ArgumentOutOfRangeException("offset", offset, "0 <= offset <= " + rope.Length.ToString());
+ }
+ return lineTree.GetByOffset(offset);
+ }
+ #endregion
+
+ /// <summary>
+ /// Gets the offset from a text location.
+ /// </summary>
+ /// <seealso cref="GetLocation"/>
+ public int GetOffset(TextLocation location)
+ {
+ return GetOffset(location.Line, location.Column);
+ }
+
+ /// <summary>
+ /// Gets the offset from a text location.
+ /// </summary>
+ /// <seealso cref="GetLocation"/>
+ public int GetOffset(int line, int column)
+ {
+ DocumentLine docLine = GetLineByNumber(line);
+ if (column <= 0)
+ return docLine.Offset;
+ if (column > docLine.Length)
+ return docLine.EndOffset;
+ return docLine.Offset + column - 1;
+ }
+
+ /// <summary>
+ /// Gets the location from an offset.
+ /// </summary>
+ /// <seealso cref="GetOffset(TextLocation)"/>
+ public TextLocation GetLocation(int offset)
+ {
+ DocumentLine line = GetLineByOffset(offset);
+ return new TextLocation(line.LineNumber, offset - line.Offset + 1);
+ }
+
+ readonly ObservableCollection<ILineTracker> lineTrackers = new ObservableCollection<ILineTracker>();
+
+ /// <summary>
+ /// Gets the list of <see cref="ILineTracker"/>s attached to this document.
+ /// You can add custom line trackers to this list.
+ /// </summary>
+ public IList<ILineTracker> LineTrackers {
+ get {
+ VerifyAccess();
+ return lineTrackers;
+ }
+ }
+
+ UndoStack undoStack;
+
+ /// <summary>
+ /// Gets the <see cref="UndoStack"/> of the document.
+ /// </summary>
+ /// <remarks>This property can also be used to set the undo stack, e.g. for sharing a common undo stack between multiple documents.</remarks>
+ public UndoStack UndoStack {
+ get { return undoStack; }
+ set {
+ if (value == null)
+ throw new ArgumentNullException();
+ if (value != undoStack) {
+ undoStack.ClearAll(); // first clear old undo stack, so that it can't be used to perform unexpected changes on this document
+ // ClearAll() will also throw an exception when it's not safe to replace the undo stack (e.g. update is currently in progress)
+ undoStack = value;
+ OnPropertyChanged("UndoStack");
+ }
+ }
+ }
+
+ /// <summary>
+ /// Creates a new <see cref="TextAnchor"/> at the specified offset.
+ /// </summary>
+ /// <inheritdoc cref="TextAnchor" select="remarks|example"/>
+ public TextAnchor CreateAnchor(int offset)
+ {
+ VerifyAccess();
+ if (offset < 0 || offset > rope.Length) {
+ throw new ArgumentOutOfRangeException("offset", offset, "0 <= offset <= " + rope.Length.ToString(CultureInfo.InvariantCulture));
+ }
+ return anchorTree.CreateAnchor(offset);
+ }
+
+ #region LineCount
+ /// <summary>
+ /// Gets the total number of lines in the document.
+ /// Runtime: O(1).
+ /// </summary>
+ public int LineCount {
+ get {
+ VerifyAccess();
+ return lineTree.LineCount;
+ }
+ }
+
+ /// <summary>
+ /// Is raised when the LineCount property changes.
+ /// </summary>
+ [Obsolete("This event will be removed in a future version; use the PropertyChanged event instead")]
+ public event EventHandler LineCountChanged;
+ #endregion
+
+ #region Debugging
+ [Conditional("DEBUG")]
+ internal void DebugVerifyAccess()
+ {
+ VerifyAccess();
+ }
+
+ /// <summary>
+ /// Gets the document lines tree in string form.
+ /// </summary>
+ [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
+ [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", "CA1024:UsePropertiesWhereAppropriate")]
+ internal string GetLineTreeAsString()
+ {
+ #if DEBUG
+ return lineTree.GetTreeAsString();
+ #else
return "Not available in release build.";
-#endif
- }
-
- /// <summary>
- /// Gets the text anchor tree in string form.
- /// </summary>
- [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
- [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", "CA1024:UsePropertiesWhereAppropriate")]
- internal string GetTextAnchorTreeAsString()
- {
-#if DEBUG
- return anchorTree.GetTreeAsString();
-#else
+ #endif
+ }
+
+ /// <summary>
+ /// Gets the text anchor tree in string form.
+ /// </summary>
+ [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
+ [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", "CA1024:UsePropertiesWhereAppropriate")]
+ internal string GetTextAnchorTreeAsString()
+ {
+ #if DEBUG
+ return anchorTree.GetTreeAsString();
+ #else
return "Not available in release build.";
-#endif
- }
- #endregion
- }
+ #endif
+ }
+ #endregion
+ }
}
diff --git a/Software/Visual_Studio/Scripting/Tango.Scripting.Editors/Document/UndoStack.cs b/Software/Visual_Studio/Scripting/Tango.Scripting.Editors/Document/UndoStack.cs
index 86e1fa33e..f0a759b23 100644
--- a/Software/Visual_Studio/Scripting/Tango.Scripting.Editors/Document/UndoStack.cs
+++ b/Software/Visual_Studio/Scripting/Tango.Scripting.Editors/Document/UndoStack.cs
@@ -414,7 +414,7 @@ namespace Tango.Scripting.Editors.Document
/// </summary>
public void ClearAll()
{
- //ThrowIfUndoGroupOpen();
+ ThrowIfUndoGroupOpen();
actionCountInUndoGroup = 0;
optionalActionCount = 0;
if (undostack.Count != 0) {
diff --git a/Software/Visual_Studio/Scripting/Tango.Scripting.Editors/Editing/BreakPointMargin.cs b/Software/Visual_Studio/Scripting/Tango.Scripting.Editors/Editing/BreakPointMargin.cs
deleted file mode 100644
index e566e6aa9..000000000
--- a/Software/Visual_Studio/Scripting/Tango.Scripting.Editors/Editing/BreakPointMargin.cs
+++ /dev/null
@@ -1,285 +0,0 @@
-using System;
-using System.Collections.Generic;
-using System.Collections.ObjectModel;
-using System.ComponentModel;
-using System.Diagnostics;
-using System.Globalization;
-using System.Linq;
-using System.Text;
-using System.Threading.Tasks;
-using System.Windows;
-using System.Windows.Controls;
-using System.Windows.Input;
-using System.Windows.Media;
-using System.Windows.Media.Imaging;
-using System.Windows.Media.TextFormatting;
-using Tango.Scripting.Core;
-using Tango.Scripting.Editors.Document;
-using Tango.Scripting.Editors.Rendering;
-using Tango.Scripting.Editors.Utils;
-
-namespace Tango.Scripting.Editors.Editing
-{
- public class BreakPointMargin : AbstractMargin, IWeakEventListener
- {
- private TextArea textArea;
- private int maxLineNumberLength = 1;
- private BitmapSource _arrowBitmap;
- private ScriptEditor _editor;
-
- public ObservableCollection<BreakPoint> BreakPoints { get; set; }
-
- public Brush Background
- {
- get { return (Brush)GetValue(BackgroundProperty); }
- set { SetValue(BackgroundProperty, value); }
- }
- public static readonly DependencyProperty BackgroundProperty =
- DependencyProperty.Register("Background", typeof(Brush), typeof(BreakPointMargin), new PropertyMetadata(new SolidColorBrush(Color.FromRgb(50, 50, 50))));
-
- public Brush Foreground
- {
- get { return (Brush)GetValue(ForegroundProperty); }
- set { SetValue(ForegroundProperty, value); }
- }
- public static readonly DependencyProperty ForegroundProperty =
- DependencyProperty.Register("Foreground", typeof(Brush), typeof(BreakPointMargin), new PropertyMetadata(Brushes.Red));
-
- static BreakPointMargin()
- {
- DefaultStyleKeyProperty.OverrideMetadata(typeof(BreakPointMargin),
- new FrameworkPropertyMetadata(typeof(BreakPointMargin)));
- }
-
- public BreakPointMargin(ScriptEditor editor)
- {
- _editor = editor;
- BreakPoints = new ObservableCollection<BreakPoint>();
- BreakPoints.CollectionChanged += BreakPoints_CollectionChanged;
- RenderOptions.SetEdgeMode(this, EdgeMode.Unspecified);
-
- _arrowBitmap = new BitmapImage(new Uri($"pack://application:,,,/Tango.Scripting.Editors;component/Images/break_point_arrow.png", UriKind.Absolute));
- }
-
- private void BreakPoints_CollectionChanged(object sender, System.Collections.Specialized.NotifyCollectionChangedEventArgs e)
- {
- InvalidateVisual();
- }
-
- protected override Size MeasureOverride(Size availableSize)
- {
- return new Size(20, 0);
- }
-
- protected override void OnRender(DrawingContext drawingContext)
- {
- TextView textView = this.TextView;
- Size renderSize = this.RenderSize;
- if (textView != null && textView.VisualLinesValid)
- {
- drawingContext.DrawRectangle(Background, new Pen(Background, 1), new Rect(0, 0, ActualWidth, ActualHeight));
-
- var foreground = Foreground;
- foreach (VisualLine line in textView.VisualLines)
- {
- int lineNumber = line.FirstDocumentLine.LineNumber;
-
- BreakPoint b = BreakPoints.FirstOrDefault(x => x.LineNumber == lineNumber);
-
- if (b != null)
- {
- double y = line.GetTextLineVisualYPosition(line.TextLines[0], VisualYPosition.TextTop);
- drawingContext.DrawEllipse(Foreground, new Pen(Brushes.Gainsboro, 1), new Point(10, y - textView.VerticalOffset + 8), 6, 6);
-
- if (b.IsActive)
- {
- drawingContext.DrawImage(_arrowBitmap, new Rect(6, y - textView.VerticalOffset + 2.5, 8.5, 10));
- }
- }
- }
- }
- }
-
- protected override void OnTextViewChanged(TextView oldTextView, TextView newTextView)
- {
- if (oldTextView != null)
- {
- oldTextView.VisualLinesChanged -= TextViewVisualLinesChanged;
- }
- base.OnTextViewChanged(oldTextView, newTextView);
- if (newTextView != null)
- {
- newTextView.VisualLinesChanged += TextViewVisualLinesChanged;
-
- // find the text area belonging to the new text view
- textArea = newTextView.Services.GetService(typeof(TextArea)) as TextArea;
- }
- else
- {
- textArea = null;
- }
- InvalidateVisual();
- }
-
- protected override void OnDocumentChanged(TextDocument oldDocument, TextDocument newDocument)
- {
- if (oldDocument != null)
- {
- PropertyChangedEventManager.RemoveListener(oldDocument, this, "LineCount");
- }
- base.OnDocumentChanged(oldDocument, newDocument);
- if (newDocument != null)
- {
- PropertyChangedEventManager.AddListener(newDocument, this, "LineCount");
- }
- OnDocumentLineCountChanged();
- }
-
- protected virtual bool ReceiveWeakEvent(Type managerType, object sender, EventArgs e)
- {
- if (managerType == typeof(PropertyChangedEventManager))
- {
- OnDocumentLineCountChanged();
- return true;
- }
- return false;
- }
-
- bool IWeakEventListener.ReceiveWeakEvent(Type managerType, object sender, EventArgs e)
- {
- return ReceiveWeakEvent(managerType, sender, e);
- }
-
- private void OnDocumentLineCountChanged()
- {
- int documentLineCount = Document != null ? Document.LineCount : 1;
- int newLength = documentLineCount.ToString(CultureInfo.CurrentCulture).Length;
-
- foreach (var breakPoint in BreakPoints.ToList())
- {
- if (breakPoint.LineNumber > documentLineCount)
- {
- BreakPoints.Remove(breakPoint);
- }
- else
- {
- try
- {
- var line = Document.GetLineByNumber(breakPoint.LineNumber);
- if (line != null)
- {
- String lineText = Document.GetText(line.Offset, line.Length);
- if (!IsBreakPointValid(lineText))
- {
- BreakPoints.Remove(breakPoint);
- }
- }
- }
- catch { }
- }
- }
-
- // The margin looks too small when there is only one digit, so always reserve space for
- // at least two digits
- if (newLength < 2)
- newLength = 2;
-
- if (newLength != maxLineNumberLength)
- {
- maxLineNumberLength = newLength;
- InvalidateMeasure();
- }
- }
-
- private void TextViewVisualLinesChanged(object sender, EventArgs e)
- {
- InvalidateVisual();
- }
-
- protected override HitTestResult HitTestCore(PointHitTestParameters hitTestParameters)
- {
- // accept clicks even when clicking on the background
- return new PointHitTestResult(this, hitTestParameters.HitPoint);
- }
-
- private VisualLine GetLineNumberByMousePosition(MouseEventArgs e)
- {
- Point pos = e.GetPosition(TextView);
- pos.X = 0;
- pos.Y += TextView.VerticalOffset;
- VisualLine vl = TextView.GetVisualLineFromVisualTop(pos.Y);
- return vl;
- }
-
- private bool IsBreakPointValid(String lineText)
- {
- if (lineText.EndsWith(";") && !lineText.StartsWith("using"))
- {
- return true;
- }
-
- return false;
- }
-
- protected override void OnPreviewMouseMove(MouseEventArgs e)
- {
- base.OnPreviewMouseMove(e);
-
- if (_editor.DisableBreakPoints)
- {
- Cursor = Cursors.No;
- }
- else
- {
- Cursor = Cursors.Arrow;
- }
- }
-
- protected override void OnMouseLeftButtonDown(MouseButtonEventArgs e)
- {
- base.OnMouseLeftButtonDown(e);
-
- if (_editor.DisableBreakPoints)
- {
- return;
- }
-
- try
- {
- if (!e.Handled && TextView != null && textArea != null)
- {
- e.Handled = true;
- textArea.Focus();
-
- var visualLine = GetLineNumberByMousePosition(e);
-
- int? lineNumber = visualLine != null ? (int?)visualLine.FirstDocumentLine.LineNumber : null;
-
- if (lineNumber != null)
- {
- var breakPoint = BreakPoints.FirstOrDefault(x => x.LineNumber == lineNumber.Value);
- if (breakPoint != null)
- {
- BreakPoints.Remove(breakPoint);
- }
- else
- {
- var lineText = Document.GetText(visualLine.FirstDocumentLine.Offset, visualLine.FirstDocumentLine.Length).Trim();
-
- if (IsBreakPointValid(lineText))
- {
- BreakPoint newBreakPoint = new BreakPoint();
- newBreakPoint.LineNumber = lineNumber.Value;
- BreakPoints.Add(newBreakPoint);
- }
- }
- }
- }
- }
- catch (Exception ex)
- {
- Debug.WriteLine(ex);
- }
- }
- }
-}
diff --git a/Software/Visual_Studio/Scripting/Tango.Scripting.Editors/Errors/ITextMarker.cs b/Software/Visual_Studio/Scripting/Tango.Scripting.Editors/Errors/ITextMarker.cs
deleted file mode 100644
index dcbf8388a..000000000
--- a/Software/Visual_Studio/Scripting/Tango.Scripting.Editors/Errors/ITextMarker.cs
+++ /dev/null
@@ -1,169 +0,0 @@
-// Copyright (c) 2014 AlphaSierraPapa for the SharpDevelop Team
-//
-// Permission is hereby granted, free of charge, to any person obtaining a copy of this
-// software and associated documentation files (the "Software"), to deal in the Software
-// without restriction, including without limitation the rights to use, copy, modify, merge,
-// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons
-// to whom the Software is furnished to do so, subject to the following conditions:
-//
-// The above copyright notice and this permission notice shall be included in all copies or
-// substantial portions of the Software.
-//
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
-// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
-// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE
-// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
-// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
-// DEALINGS IN THE SOFTWARE.
-
-using System;
-using System.Collections.Generic;
-using System.Windows;
-using System.Windows.Media;
-
-namespace Tango.Scripting.Editors
-{
- /// <summary>
- /// Represents a text marker.
- /// </summary>
- public interface ITextMarker
- {
- /// <summary>
- /// Gets the start offset of the marked text region.
- /// </summary>
- int StartOffset { get; }
-
- /// <summary>
- /// Gets the end offset of the marked text region.
- /// </summary>
- int EndOffset { get; }
-
- /// <summary>
- /// Gets the length of the marked region.
- /// </summary>
- int Length { get; }
-
- /// <summary>
- /// Deletes the text marker.
- /// </summary>
- void Delete();
-
- /// <summary>
- /// Gets whether the text marker was deleted.
- /// </summary>
- bool IsDeleted { get; }
-
- /// <summary>
- /// Event that occurs when the text marker is deleted.
- /// </summary>
- event EventHandler Deleted;
-
- /// <summary>
- /// Gets/Sets the background color.
- /// </summary>
- Color? BackgroundColor { get; set; }
-
- /// <summary>
- /// Gets/Sets the foreground color.
- /// </summary>
- Color? ForegroundColor { get; set; }
-
- /// <summary>
- /// Gets/Sets the font weight.
- /// </summary>
- FontWeight? FontWeight { get; set; }
-
- /// <summary>
- /// Gets/Sets the font style.
- /// </summary>
- FontStyle? FontStyle { get; set; }
-
- /// <summary>
- /// Gets/Sets the type of the marker. Use TextMarkerType.None for normal markers.
- /// </summary>
- TextMarkerTypes MarkerTypes { get; set; }
-
- /// <summary>
- /// Gets/Sets the color of the marker.
- /// </summary>
- Color MarkerColor { get; set; }
-
- /// <summary>
- /// Gets/Sets an object with additional data for this text marker.
- /// </summary>
- object Tag { get; set; }
-
- /// <summary>
- /// Gets/Sets an object that will be displayed as tooltip in the text editor.
- /// </summary>
- /// <remarks>Not supported in this sample!</remarks>
- object ToolTip { get; set; }
- }
-
- [Flags]
- public enum TextMarkerTypes
- {
- /// <summary>
- /// Use no marker
- /// </summary>
- None = 0x0000,
- /// <summary>
- /// Use squiggly underline marker
- /// </summary>
- SquigglyUnderline = 0x001,
- /// <summary>
- /// Normal underline.
- /// </summary>
- NormalUnderline = 0x002,
- /// <summary>
- /// Dotted underline.
- /// </summary>
- DottedUnderline = 0x004,
-
- /// <summary>
- /// Horizontal line in the scroll bar.
- /// </summary>
- LineInScrollBar = 0x0100,
- /// <summary>
- /// Small triangle in the scroll bar, pointing to the right.
- /// </summary>
- ScrollBarRightTriangle = 0x0400,
- /// <summary>
- /// Small triangle in the scroll bar, pointing to the left.
- /// </summary>
- ScrollBarLeftTriangle = 0x0800,
- /// <summary>
- /// Small circle in the scroll bar.
- /// </summary>
- CircleInScrollBar = 0x1000
- }
-
- public interface ITextMarkerService
- {
- /// <summary>
- /// Creates a new text marker. The text marker will be invisible at first,
- /// you need to set one of the Color properties to make it visible.
- /// </summary>
- ITextMarker Create(int startOffset, int length);
-
- /// <summary>
- /// Gets the list of text markers.
- /// </summary>
- IEnumerable<ITextMarker> TextMarkers { get; }
-
- /// <summary>
- /// Removes the specified text marker.
- /// </summary>
- void Remove(ITextMarker marker);
-
- /// <summary>
- /// Removes all text markers that match the condition.
- /// </summary>
- void RemoveAll(Predicate<ITextMarker> predicate);
-
- /// <summary>
- /// Finds all text markers at the specified offset.
- /// </summary>
- IEnumerable<ITextMarker> GetMarkersAtOffset(int offset);
- }
-}
diff --git a/Software/Visual_Studio/Scripting/Tango.Scripting.Editors/Errors/TextMarkerService.cs b/Software/Visual_Studio/Scripting/Tango.Scripting.Editors/Errors/TextMarkerService.cs
deleted file mode 100644
index 2bb3d8e03..000000000
--- a/Software/Visual_Studio/Scripting/Tango.Scripting.Editors/Errors/TextMarkerService.cs
+++ /dev/null
@@ -1,365 +0,0 @@
-// Copyright (c) 2014 AlphaSierraPapa for the SharpDevelop Team
-//
-// Permission is hereby granted, free of charge, to any person obtaining a copy of this
-// software and associated documentation files (the "Software"), to deal in the Software
-// without restriction, including without limitation the rights to use, copy, modify, merge,
-// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons
-// to whom the Software is furnished to do so, subject to the following conditions:
-//
-// The above copyright notice and this permission notice shall be included in all copies or
-// substantial portions of the Software.
-//
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
-// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
-// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE
-// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
-// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
-// DEALINGS IN THE SOFTWARE.
-
-using System;
-using System.Collections.Generic;
-using System.Diagnostics;
-using System.Linq;
-using System.Windows;
-using System.Windows.Media;
-using System.Windows.Threading;
-using Tango.Scripting.Editors.Document;
-using Tango.Scripting.Editors.Rendering;
-
-namespace Tango.Scripting.Editors
-{
- /// <summary>
- /// Handles the text markers for a code editor.
- /// </summary>
- public sealed class TextMarkerService : DocumentColorizingTransformer, IBackgroundRenderer, ITextMarkerService, ITextViewConnect
- {
- TextSegmentCollection<TextMarker> markers;
- TextDocument document;
-
- public TextMarkerService(TextDocument document)
- {
- if (document == null)
- throw new ArgumentNullException("document");
- this.document = document;
- this.markers = new TextSegmentCollection<TextMarker>(document);
- }
-
- #region ITextMarkerService
- public ITextMarker Create(int startOffset, int length)
- {
- if (markers == null)
- throw new InvalidOperationException("Cannot create a marker when not attached to a document");
-
- int textLength = document.TextLength;
- if (startOffset < 0 || startOffset > textLength)
- throw new ArgumentOutOfRangeException("startOffset", startOffset, "Value must be between 0 and " + textLength);
- if (length < 0 || startOffset + length > textLength)
- throw new ArgumentOutOfRangeException("length", length, "length must not be negative and startOffset+length must not be after the end of the document");
-
- TextMarker m = new TextMarker(this, startOffset, length);
- markers.Add(m);
- // no need to mark segment for redraw: the text marker is invisible until a property is set
- return m;
- }
-
- public IEnumerable<ITextMarker> GetMarkersAtOffset(int offset)
- {
- if (markers == null)
- return Enumerable.Empty<ITextMarker>();
- else
- return markers.FindSegmentsContaining(offset);
- }
-
- public IEnumerable<ITextMarker> TextMarkers {
- get { return markers ?? Enumerable.Empty<ITextMarker>(); }
- }
-
- public void RemoveAll(Predicate<ITextMarker> predicate)
- {
- if (predicate == null)
- throw new ArgumentNullException("predicate");
- if (markers != null) {
- foreach (TextMarker m in markers.ToArray()) {
- if (predicate(m))
- Remove(m);
- }
- }
- }
-
- public void Remove(ITextMarker marker)
- {
- if (marker == null)
- throw new ArgumentNullException("marker");
- TextMarker m = marker as TextMarker;
- if (markers != null && markers.Remove(m)) {
- Redraw(m);
- m.OnDeleted();
- }
- }
-
- /// <summary>
- /// Redraws the specified text segment.
- /// </summary>
- internal void Redraw(ISegment segment)
- {
- foreach (var view in textViews) {
- view.Redraw(segment, DispatcherPriority.Normal);
- }
- if (RedrawRequested != null)
- RedrawRequested(this, EventArgs.Empty);
- }
-
- public event EventHandler RedrawRequested;
- #endregion
-
- #region DocumentColorizingTransformer
- protected override void ColorizeLine(DocumentLine line)
- {
- if (markers == null)
- return;
- int lineStart = line.Offset;
- int lineEnd = lineStart + line.Length;
- foreach (TextMarker marker in markers.FindOverlappingSegments(lineStart, line.Length)) {
- Brush foregroundBrush = null;
- if (marker.ForegroundColor != null) {
- foregroundBrush = new SolidColorBrush(marker.ForegroundColor.Value);
- foregroundBrush.Freeze();
- }
- ChangeLinePart(
- Math.Max(marker.StartOffset, lineStart),
- Math.Min(marker.EndOffset, lineEnd),
- element => {
- if (foregroundBrush != null) {
- element.TextRunProperties.SetForegroundBrush(foregroundBrush);
- }
- Typeface tf = element.TextRunProperties.Typeface;
- element.TextRunProperties.SetTypeface(new Typeface(
- tf.FontFamily,
- marker.FontStyle ?? tf.Style,
- marker.FontWeight ?? tf.Weight,
- tf.Stretch
- ));
- }
- );
- }
- }
- #endregion
-
- #region IBackgroundRenderer
- public KnownLayer Layer {
- get {
- // draw behind selection
- return KnownLayer.Selection;
- }
- }
-
- public void Draw(TextView textView, DrawingContext drawingContext)
- {
- if (textView == null)
- throw new ArgumentNullException("textView");
- if (drawingContext == null)
- throw new ArgumentNullException("drawingContext");
- if (markers == null || !textView.VisualLinesValid)
- return;
- var visualLines = textView.VisualLines;
- if (visualLines.Count == 0)
- return;
- int viewStart = visualLines.First().FirstDocumentLine.Offset;
- int viewEnd = visualLines.Last().LastDocumentLine.EndOffset;
- foreach (TextMarker marker in markers.FindOverlappingSegments(viewStart, viewEnd - viewStart)) {
- if (marker.BackgroundColor != null) {
- BackgroundGeometryBuilder geoBuilder = new BackgroundGeometryBuilder();
- geoBuilder.AlignToWholePixels = true;
- geoBuilder.CornerRadius = 3;
- geoBuilder.AddSegment(textView, marker);
- Geometry geometry = geoBuilder.CreateGeometry();
- if (geometry != null) {
- Color color = marker.BackgroundColor.Value;
- SolidColorBrush brush = new SolidColorBrush(color);
- brush.Freeze();
- drawingContext.DrawGeometry(brush, null, geometry);
- }
- }
- var underlineMarkerTypes = TextMarkerTypes.SquigglyUnderline | TextMarkerTypes.NormalUnderline | TextMarkerTypes.DottedUnderline;
- if ((marker.MarkerTypes & underlineMarkerTypes) != 0) {
- foreach (Rect r in BackgroundGeometryBuilder.GetRectsForSegment(textView, marker)) {
- Point startPoint = r.BottomLeft;
- Point endPoint = r.BottomRight;
-
- Brush usedBrush = new SolidColorBrush(marker.MarkerColor);
- usedBrush.Freeze();
- if ((marker.MarkerTypes & TextMarkerTypes.SquigglyUnderline) != 0) {
- double offset = 2.5;
-
- int count = Math.Max((int)((endPoint.X - startPoint.X) / offset) + 1, 4);
-
- StreamGeometry geometry = new StreamGeometry();
-
- using (StreamGeometryContext ctx = geometry.Open()) {
- ctx.BeginFigure(startPoint, false, false);
- ctx.PolyLineTo(CreatePoints(startPoint, endPoint, offset, count).ToArray(), true, false);
- }
-
- geometry.Freeze();
-
- Pen usedPen = new Pen(usedBrush, 1);
- usedPen.Freeze();
- drawingContext.DrawGeometry(Brushes.Transparent, usedPen, geometry);
- }
- if ((marker.MarkerTypes & TextMarkerTypes.NormalUnderline) != 0) {
- Pen usedPen = new Pen(usedBrush, 1);
- usedPen.Freeze();
- drawingContext.DrawLine(usedPen, startPoint, endPoint);
- }
- if ((marker.MarkerTypes & TextMarkerTypes.DottedUnderline) != 0) {
- Pen usedPen = new Pen(usedBrush, 1);
- usedPen.DashStyle = DashStyles.Dot;
- usedPen.Freeze();
- drawingContext.DrawLine(usedPen, startPoint, endPoint);
- }
- }
- }
- }
- }
-
- IEnumerable<Point> CreatePoints(Point start, Point end, double offset, int count)
- {
- for (int i = 0; i < count; i++)
- yield return new Point(start.X + i * offset, start.Y - ((i + 1) % 2 == 0 ? offset : 0));
- }
- #endregion
-
- #region ITextViewConnect
- readonly List<TextView> textViews = new List<TextView>();
-
- void ITextViewConnect.AddToTextView(TextView textView)
- {
- if (textView != null && !textViews.Contains(textView)) {
- Debug.Assert(textView.Document == document);
- textViews.Add(textView);
- }
- }
-
- void ITextViewConnect.RemoveFromTextView(TextView textView)
- {
- if (textView != null) {
- Debug.Assert(textView.Document == document);
- textViews.Remove(textView);
- }
- }
- #endregion
- }
-
- public sealed class TextMarker : TextSegment, ITextMarker
- {
- readonly TextMarkerService service;
-
- public TextMarker(TextMarkerService service, int startOffset, int length)
- {
- if (service == null)
- throw new ArgumentNullException("service");
- this.service = service;
- this.StartOffset = startOffset;
- this.Length = length;
- this.markerTypes = TextMarkerTypes.None;
- }
-
- public event EventHandler Deleted;
-
- public bool IsDeleted {
- get { return !this.IsConnectedToCollection; }
- }
-
- public void Delete()
- {
- service.Remove(this);
- }
-
- internal void OnDeleted()
- {
- if (Deleted != null)
- Deleted(this, EventArgs.Empty);
- }
-
- void Redraw()
- {
- service.Redraw(this);
- }
-
- Color? backgroundColor;
-
- public Color? BackgroundColor {
- get { return backgroundColor; }
- set {
- if (backgroundColor != value) {
- backgroundColor = value;
- Redraw();
- }
- }
- }
-
- Color? foregroundColor;
-
- public Color? ForegroundColor {
- get { return foregroundColor; }
- set {
- if (foregroundColor != value) {
- foregroundColor = value;
- Redraw();
- }
- }
- }
-
- FontWeight? fontWeight;
-
- public FontWeight? FontWeight {
- get { return fontWeight; }
- set {
- if (fontWeight != value) {
- fontWeight = value;
- Redraw();
- }
- }
- }
-
- FontStyle? fontStyle;
-
- public FontStyle? FontStyle {
- get { return fontStyle; }
- set {
- if (fontStyle != value) {
- fontStyle = value;
- Redraw();
- }
- }
- }
-
- public object Tag { get; set; }
-
- TextMarkerTypes markerTypes;
-
- public TextMarkerTypes MarkerTypes {
- get { return markerTypes; }
- set {
- if (markerTypes != value) {
- markerTypes = value;
- Redraw();
- }
- }
- }
-
- Color markerColor;
-
- public Color MarkerColor {
- get { return markerColor; }
- set {
- if (markerColor != value) {
- markerColor = value;
- Redraw();
- }
- }
- }
-
- public object ToolTip { get; set; }
- }
-}
diff --git a/Software/Visual_Studio/Scripting/Tango.Scripting.Editors/ExtensionMethods.cs b/Software/Visual_Studio/Scripting/Tango.Scripting.Editors/ExtensionMethods.cs
index d112c6141..1605ff281 100644
--- a/Software/Visual_Studio/Scripting/Tango.Scripting.Editors/ExtensionMethods.cs
+++ b/Software/Visual_Studio/Scripting/Tango.Scripting.Editors/ExtensionMethods.cs
@@ -22,7 +22,7 @@ namespace Tango.Scripting.Editors
{
List<String> args = new List<string>();
- foreach (var lGenericArgument in type.GetGenericArguments())
+ foreach (var lGenericArgument in type.GetGenericTypeDefinition().GetGenericArguments())
{
args.Add(lGenericArgument.Name);
}
diff --git a/Software/Visual_Studio/Scripting/Tango.Scripting.Editors/Highlighting/OffsetColorizer.cs b/Software/Visual_Studio/Scripting/Tango.Scripting.Editors/Highlighting/OffsetColorizer.cs
index 72c27f9a9..a05d1fc75 100644
--- a/Software/Visual_Studio/Scripting/Tango.Scripting.Editors/Highlighting/OffsetColorizer.cs
+++ b/Software/Visual_Studio/Scripting/Tango.Scripting.Editors/Highlighting/OffsetColorizer.cs
@@ -30,7 +30,7 @@ namespace Tango.Scripting.Editors.Highlighting
{
try
{
- ChangeLinePart(StartOffset, EndOffset, element => element.TextRunProperties.SetBackgroundBrush(Brush));
+ ChangeLinePart(StartOffset, EndOffset, element => element.TextRunProperties.SetForegroundBrush(Brush));
}
catch { }
}
diff --git a/Software/Visual_Studio/Scripting/Tango.Scripting.Editors/Highlighting/Resources/CSharp-Mode.xshd b/Software/Visual_Studio/Scripting/Tango.Scripting.Editors/Highlighting/Resources/CSharp-Mode.xshd
index 1f6139ff6..40f362e08 100644
--- a/Software/Visual_Studio/Scripting/Tango.Scripting.Editors/Highlighting/Resources/CSharp-Mode.xshd
+++ b/Software/Visual_Studio/Scripting/Tango.Scripting.Editors/Highlighting/Resources/CSharp-Mode.xshd
@@ -11,7 +11,7 @@
<Color name="InterfaceTypes" foreground="#B5CE8A" exampleText="object o;" />
<Color name="MethodCall" foreground="Gainsboro" exampleText="o.ToString();"/>
<Color name="NumberLiteral" foreground="#B5CE8A" exampleText="3.1415f"/>
- <Color name="ThisOrBaseReference" foreground="#3F8FD6" exampleText="this.Do(); base.Do();"/>
+ <Color name="ThisOrBaseReference" exampleText="this.Do(); base.Do();"/>
<Color name="NullOrValueKeywords" exampleText="if (value == null)"/>
<Color name="Keywords" foreground="#3F8FD6" exampleText="if (a) {} else {}"/>
<Color name="GotoKeywords" foreground="#3F8FD6" exampleText="continue; return null;"/>
@@ -22,7 +22,7 @@
<Color name="OperatorKeywords" foreground="Pink" exampleText="public static implicit operator..."/>
<Color name="ParameterModifiers" foreground="DeepPink" exampleText="(ref int a, params int[] b)"/>
<Color name="Modifiers" foreground="#3F8FD6" exampleText="static readonly int a;"/>
- <Color name="CustomKeywords" foreground="DarkGray" />
+ <Color name="CustomKeywords" foreground="#FAFF00" />
<Color name="Visibility" foreground="#3F8FD6" exampleText="public override void ToString();"/>
<Color name="NamespaceKeywords" foreground="#569CD6" exampleText="namespace A.B { using System; }"/>
<Color name="GetSetAddRemove" foreground="#3F8FD6" exampleText="int Prop { get; set; }"/>
@@ -47,7 +47,26 @@
<!-- This is the main ruleset. -->
<RuleSet>
-
+ <Span color="Preprocessor">
+ <Begin>\#</Begin>
+ <RuleSet name="PreprocessorSet">
+ <Span> <!-- preprocessor directives that allows comments -->
+ <Begin >
+ (define|undef|if|elif|else|endif|line)\b
+ </Begin>
+ <RuleSet>
+ <Span color="Comment" ruleSet="CommentMarkerSet">
+ <Begin>//</Begin>
+ </Span>
+ </RuleSet>
+ </Span>
+ <Span> <!-- preprocessor directives that don't allow comments -->
+ <Begin >
+ (region|endregion|error|warning|pragma)\b
+ </Begin>
+ </Span>
+ </RuleSet>
+ </Span>
<!--<Span color="Comment">
<Begin color="XmlDoc/DocComment">///</Begin>
@@ -99,7 +118,8 @@
</Rule>
<Keywords color="CustomKeywords">
- <Word>#load</Word>
+ <Word>include</Word>
+ <Word>import</Word>
</Keywords>
<Keywords color="ThisOrBaseReference">
@@ -194,7 +214,6 @@
<Word>enum</Word>
<Word>float</Word>
<Word>int</Word>
- <Word>object</Word>
<Word>string</Word>
<Word>long</Word>
<Word>sbyte</Word>
diff --git a/Software/Visual_Studio/Scripting/Tango.Scripting.Editors/Highlighting/Resources/MarkDown-Mode.xshd b/Software/Visual_Studio/Scripting/Tango.Scripting.Editors/Highlighting/Resources/MarkDown-Mode.xshd
index 8e02db898..ead5045ab 100644
--- a/Software/Visual_Studio/Scripting/Tango.Scripting.Editors/Highlighting/Resources/MarkDown-Mode.xshd
+++ b/Software/Visual_Studio/Scripting/Tango.Scripting.Editors/Highlighting/Resources/MarkDown-Mode.xshd
@@ -5,6 +5,7 @@
<Color name="StrongEmphasis" fontWeight="bold" exampleText="**this** is more important!" />
<Color name="Code" exampleText="this is `int.GetHashCode()`" />
<Color name="BlockQuote" foreground="DarkBlue" exampleText="&gt; This is a\r\n&gt; quote." />
+ <Color name="Link" foreground="Blue" exampleText="[text](http://example.com)" />
<Color name="Image" foreground="Green" exampleText="[text][http://example.com/test.png]" />
<Color name="LineBreak" background="LightGray" exampleText="end of line \r\n2nd line " />
@@ -42,6 +43,12 @@
<Rule color="Image">
\!\[.*\]\[.*\]
</Rule>
+ <Rule color="Link">
+ \[.*\]\(.*\)
+ </Rule>
+ <Rule color="Link">
+ \[.*\]\[.*\]
+ </Rule>
<Rule color="LineBreak">
[ ]{2}$
</Rule>
diff --git a/Software/Visual_Studio/Scripting/Tango.Scripting.Editors/Highlighting/Resources/XML-Mode.xshd b/Software/Visual_Studio/Scripting/Tango.Scripting.Editors/Highlighting/Resources/XML-Mode.xshd
index 50fdc0e2c..8f0bdef76 100644
--- a/Software/Visual_Studio/Scripting/Tango.Scripting.Editors/Highlighting/Resources/XML-Mode.xshd
+++ b/Software/Visual_Studio/Scripting/Tango.Scripting.Editors/Highlighting/Resources/XML-Mode.xshd
@@ -1,13 +1,13 @@
<SyntaxDefinition name="XML" extensions=".xml;.xsl;.xslt;.xsd;.manifest;.config;.addin;.xshd;.wxs;.wxi;.wxl;.proj;.csproj;.vbproj;.ilproj;.booproj;.build;.xfrm;.targets;.xaml;.xpt;.xft;.map;.wsdl;.disco;.ps1xml;.nuspec" xmlns="http://icsharpcode.net/sharpdevelop/syntaxdefinition/2008">
<Color foreground="Green" name="Comment" exampleText="&lt;!-- comment --&gt;" />
- <Color foreground="#3F92D6" name="CData" exampleText="&lt;![CDATA[data]]&gt;" />
- <Color foreground="#C8C8C7" name="DocType" exampleText="&lt;!DOCTYPE rootElement&gt;" />
- <Color foreground="#3F92D6" name="XmlDeclaration" exampleText='&lt;?xml version="1.0"?&gt;' />
- <Color foreground="#3F92D6" name="XmlTag" exampleText='&lt;tag attribute="value" /&gt;' />
- <Color foreground="#92CAF4" name="AttributeName" exampleText='&lt;tag attribute="value" /&gt;' />
- <Color foreground="#C8C8C7" name="AttributeValue" exampleText='&lt;tag attribute="value" /&gt;' />
+ <Color foreground="Blue" name="CData" exampleText="&lt;![CDATA[data]]&gt;" />
+ <Color foreground="Blue" name="DocType" exampleText="&lt;!DOCTYPE rootElement&gt;" />
+ <Color foreground="Blue" name="XmlDeclaration" exampleText='&lt;?xml version="1.0"?&gt;' />
+ <Color foreground="DarkMagenta" name="XmlTag" exampleText='&lt;tag attribute="value" /&gt;' />
+ <Color foreground="Red" name="AttributeName" exampleText='&lt;tag attribute="value" /&gt;' />
+ <Color foreground="Blue" name="AttributeValue" exampleText='&lt;tag attribute="value" /&gt;' />
<Color foreground="Teal" name="Entity" exampleText="index.aspx?a=1&amp;amp;b=2" />
- <Color foreground="Red" name="BrokenEntity" exampleText="index.aspx?a=1&amp;b=2" />
+ <Color foreground="Olive" name="BrokenEntity" exampleText="index.aspx?a=1&amp;b=2" />
<RuleSet>
<Span color="Comment" multiline="true">
diff --git a/Software/Visual_Studio/Scripting/Tango.Scripting.Editors/Images/break_point_arrow.png b/Software/Visual_Studio/Scripting/Tango.Scripting.Editors/Images/break_point_arrow.png
deleted file mode 100644
index e8d367028..000000000
--- a/Software/Visual_Studio/Scripting/Tango.Scripting.Editors/Images/break_point_arrow.png
+++ /dev/null
Binary files differ
diff --git a/Software/Visual_Studio/Scripting/Tango.Scripting.Editors/Images/event.png b/Software/Visual_Studio/Scripting/Tango.Scripting.Editors/Images/event.png
deleted file mode 100644
index 4566835c0..000000000
--- a/Software/Visual_Studio/Scripting/Tango.Scripting.Editors/Images/event.png
+++ /dev/null
Binary files differ
diff --git a/Software/Visual_Studio/Scripting/Tango.Scripting.Editors/Images/snippet.png b/Software/Visual_Studio/Scripting/Tango.Scripting.Editors/Images/snippet.png
deleted file mode 100644
index fe4d71eb4..000000000
--- a/Software/Visual_Studio/Scripting/Tango.Scripting.Editors/Images/snippet.png
+++ /dev/null
Binary files differ
diff --git a/Software/Visual_Studio/Scripting/Tango.Scripting.Editors/Intellisense/CompletionItem.cs b/Software/Visual_Studio/Scripting/Tango.Scripting.Editors/Intellisense/CompletionItem.cs
index 191f99b6c..c8beebd28 100644
--- a/Software/Visual_Studio/Scripting/Tango.Scripting.Editors/Intellisense/CompletionItem.cs
+++ b/Software/Visual_Studio/Scripting/Tango.Scripting.Editors/Intellisense/CompletionItem.cs
@@ -31,7 +31,7 @@ namespace Tango.Scripting.Editors.Intellisense
int index = editor.GetCurrentWordStartIndex();
int max = editor.GetCurrentLine().EndOffset;
- editor.Document.Replace(index, word.Length, GetCode());
+ editor.Document.Replace(index, word.Length,Text);
}
public abstract BitmapSource Image { get; }
@@ -41,11 +41,6 @@ namespace Tango.Scripting.Editors.Intellisense
return new BitmapImage(new Uri($"pack://application:,,,/Tango.Scripting.Editors;component/Images/{name}", UriKind.Absolute));
}
- protected virtual String GetCode()
- {
- return Text;
- }
-
public override string ToString()
{
return Text;
diff --git a/Software/Visual_Studio/Scripting/Tango.Scripting.Editors/Intellisense/EventCompletionItem.cs b/Software/Visual_Studio/Scripting/Tango.Scripting.Editors/Intellisense/EventCompletionItem.cs
deleted file mode 100644
index 5c510c39f..000000000
--- a/Software/Visual_Studio/Scripting/Tango.Scripting.Editors/Intellisense/EventCompletionItem.cs
+++ /dev/null
@@ -1,22 +0,0 @@
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-using System.Threading.Tasks;
-using System.Windows.Media.Imaging;
-
-namespace Tango.Scripting.Editors.Intellisense
-{
- public class EventCompletionItem : CompletionItem
- {
- private static BitmapSource image = GetImage("event.png");
-
- public override string Text => Name;
- public override CompletionItemPopupControl PopupControl => new FieldCompletionItemPopup();
- public override BitmapSource Image => image;
-
- public String Name { get; set; }
- public String Class { get; set; }
- public String Type { get; set; }
- }
-}
diff --git a/Software/Visual_Studio/Scripting/Tango.Scripting.Editors/Intellisense/HideIntellisenseAttribute.cs b/Software/Visual_Studio/Scripting/Tango.Scripting.Editors/Intellisense/HideIntellisenseAttribute.cs
deleted file mode 100644
index 548bd909e..000000000
--- a/Software/Visual_Studio/Scripting/Tango.Scripting.Editors/Intellisense/HideIntellisenseAttribute.cs
+++ /dev/null
@@ -1,12 +0,0 @@
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-using System.Threading.Tasks;
-
-namespace Tango.Scripting.Editors.Intellisense
-{
- public class HideIntellisenseAttribute : Attribute
- {
- }
-}
diff --git a/Software/Visual_Studio/Scripting/Tango.Scripting.Editors/Intellisense/KnownType.cs b/Software/Visual_Studio/Scripting/Tango.Scripting.Editors/Intellisense/KnownType.cs
index 8010dc689..28f9ccb9a 100644
--- a/Software/Visual_Studio/Scripting/Tango.Scripting.Editors/Intellisense/KnownType.cs
+++ b/Software/Visual_Studio/Scripting/Tango.Scripting.Editors/Intellisense/KnownType.cs
@@ -1,14 +1,11 @@
-using Newtonsoft.Json;
-using System;
+using System;
using System.Collections;
using System.Collections.Generic;
-using System.Drawing;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Threading.Tasks;
-using System.Windows.Forms;
using System.Xml;
using Tango.Core;
@@ -17,18 +14,16 @@ namespace Tango.Scripting.Editors.Intellisense
public class KnownType
{
private bool _initialized;
+ private bool _documentationLoaded;
- public String Alias { get; set; }
- public bool DocumentationLoaded { get; set; }
public Type Type { get; private set; }
- public String Name { get; set; }
+ public String Name { get; private set; }
public String TypeDefinition { get; private set; }
public String FriendlyName { get; private set; }
public String Summary { get; set; }
public List<KnownTypeConstructor> Constructors { get; set; }
public List<KnownTypeMethod> Methods { get; set; }
public List<KnownTypeProperty> Properties { get; set; }
- public List<KnownTypeEvent> Events { get; set; }
public List<KnownTypeMember> Members
{
get
@@ -37,20 +32,12 @@ namespace Tango.Scripting.Editors.Intellisense
members.AddRange(Properties);
members.AddRange(Methods);
- members.AddRange(Events);
return members.OrderBy(x => x.Name).ToList();
}
}
public List<KnownTypeField> Fields { get; set; }
- public static List<Assembly> ExtensionMethodsAssemblies { get; set; }
-
- static KnownType()
- {
- ExtensionMethodsAssemblies = new List<Assembly>();
- }
-
public KnownType(Type type)
{
Summary = "Loading documentation...";
@@ -58,7 +45,6 @@ namespace Tango.Scripting.Editors.Intellisense
Methods = new List<KnownTypeMethod>();
Properties = new List<KnownTypeProperty>();
Fields = new List<KnownTypeField>();
- Events = new List<KnownTypeEvent>();
Type = type;
Name = type.Name;
@@ -132,31 +118,9 @@ namespace Tango.Scripting.Editors.Intellisense
{
var methods = Type.GetRuntimeMethods().Where(x => x.IsPublic && !x.IsSpecialName).ToList();
- if (Type.IsInterface)
- {
- foreach (var inter in Type.GetInterfaces())
- {
- methods.AddRange(inter.GetRuntimeMethods().Where(x => x.IsPublic && !x.IsSpecialName).ToList());
- }
- methods = methods.Distinct().ToList();
-
- if (!methods.Exists(x => x.Name == "ToString"))
- {
- methods.Add(typeof(Object).GetMethod("ToString"));
- }
- }
-
//TODO: Separate extension methods!
methods.AddRange(Type.GetExtensionMethods(Type.Assembly).ToList());
- if (Type.Namespace.StartsWith("Tango"))
- {
- foreach (var asm in ExtensionMethodsAssemblies.Where(x => x != Type.Assembly))
- {
- methods.AddRange(Type.GetExtensionMethods(asm).ToList());
- }
- }
-
if (typeof(IEnumerable).IsAssignableFrom(Type))
{
var linqMethods = typeof(System.Linq.Enumerable).GetMethods(BindingFlags.Static | BindingFlags.Public).ToList();
@@ -167,13 +131,10 @@ namespace Tango.Scripting.Editors.Intellisense
{
var method = methods[i];
- if (method.GetCustomAttribute<HideIntellisenseAttribute>() != null) continue;
-
KnownTypeMethod m = new KnownTypeMethod(this);
m.Name = method.Name;
m.ReturnType = method.ReturnType;
m.ReturnTypeFriendlyName = method.ReturnType.GetFriendlyName();
- m.IsStatic = method.IsStatic && !method.IsDefined(typeof(System.Runtime.CompilerServices.ExtensionAttribute), false);
if (method.IsGenericMethod)
{
@@ -187,11 +148,6 @@ namespace Tango.Scripting.Editors.Intellisense
bool isLinq = method.DeclaringType == typeof(Enumerable);
- if (isLinq)
- {
- m.IsStatic = false;
- }
-
for (int j = 0; j < parameters.Count; j++)
{
var parameter = parameters[j];
@@ -215,14 +171,12 @@ namespace Tango.Scripting.Editors.Intellisense
//Load Properties
{
- var properties = Type.GetProperties(BindingFlags.FlattenHierarchy | BindingFlags.Public | BindingFlags.Instance | BindingFlags.Static).ToList();
+ var properties = Type.GetProperties(BindingFlags.Public | BindingFlags.Instance).Where(x => x.PropertyType.IsPublic).ToList();
for (int i = 0; i < properties.Count; i++)
{
var property = properties[i];
- if (property.GetCustomAttribute<HideIntellisenseAttribute>() != null) continue;
-
KnownTypeProperty p = new KnownTypeProperty(this);
p.Name = property.Name;
p.ReturnType = property.PropertyType;
@@ -232,23 +186,6 @@ namespace Tango.Scripting.Editors.Intellisense
}
}
- //Load Events
- {
- var events = Type.GetRuntimeEvents().ToList();
-
- for (int i = 0; i < events.Count; i++)
- {
- var ev = events[i];
-
- if (ev.GetCustomAttribute<HideIntellisenseAttribute>() != null) continue;
-
- KnownTypeEvent p = new KnownTypeEvent(this);
- p.Name = ev.Name;
-
- Events.Add(p);
- }
- }
-
//Load Enum Values
{
if (Type.IsEnum)
@@ -274,9 +211,9 @@ namespace Tango.Scripting.Editors.Intellisense
public void LoadDocumentation()
{
- if (!DocumentationLoaded)
+ if (!_documentationLoaded)
{
- DocumentationLoaded = true;
+ _documentationLoaded = true;
Utils.LoadKnownTypeDocs(this);
}
diff --git a/Software/Visual_Studio/Scripting/Tango.Scripting.Editors/Intellisense/KnownTypeEvent.cs b/Software/Visual_Studio/Scripting/Tango.Scripting.Editors/Intellisense/KnownTypeEvent.cs
deleted file mode 100644
index 7403d2cbd..000000000
--- a/Software/Visual_Studio/Scripting/Tango.Scripting.Editors/Intellisense/KnownTypeEvent.cs
+++ /dev/null
@@ -1,21 +0,0 @@
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-using System.Threading.Tasks;
-
-namespace Tango.Scripting.Editors.Intellisense
-{
- public class KnownTypeEvent : KnownTypeMember
- {
- public KnownTypeEvent()
- {
- Summary = "Loading documentation...";
- }
-
- public KnownTypeEvent(KnownType knownType) : this()
- {
- Type = knownType;
- }
- }
-}
diff --git a/Software/Visual_Studio/Scripting/Tango.Scripting.Editors/Intellisense/KnownTypeMethod.cs b/Software/Visual_Studio/Scripting/Tango.Scripting.Editors/Intellisense/KnownTypeMethod.cs
index 4cedad377..f84e26fe5 100644
--- a/Software/Visual_Studio/Scripting/Tango.Scripting.Editors/Intellisense/KnownTypeMethod.cs
+++ b/Software/Visual_Studio/Scripting/Tango.Scripting.Editors/Intellisense/KnownTypeMethod.cs
@@ -8,8 +8,6 @@ namespace Tango.Scripting.Editors.Intellisense
{
public class KnownTypeMethod : KnownTypeMember
{
- public bool IsStatic { get; set; }
-
public List<KnownTypeMethodParameter> Parameters { get; set; }
public List<String> TypeArguments { get; set; }
diff --git a/Software/Visual_Studio/Scripting/Tango.Scripting.Editors/Intellisense/SnippetCompletionItem.cs b/Software/Visual_Studio/Scripting/Tango.Scripting.Editors/Intellisense/SnippetCompletionItem.cs
deleted file mode 100644
index 97807ed19..000000000
--- a/Software/Visual_Studio/Scripting/Tango.Scripting.Editors/Intellisense/SnippetCompletionItem.cs
+++ /dev/null
@@ -1,26 +0,0 @@
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-using System.Threading.Tasks;
-using System.Windows.Media.Imaging;
-
-namespace Tango.Scripting.Editors.Intellisense
-{
- public class SnippetCompletionItem : CompletionItem
- {
- private static BitmapSource image = GetImage("snippet.png");
-
- public override string Text => Name;
- public override CompletionItemPopupControl PopupControl => new FieldCompletionItemPopup();
- public override BitmapSource Image => image;
-
- public String Name { get; set; }
- public String Code { get; set; }
-
- protected override string GetCode()
- {
- return Code;
- }
- }
-}
diff --git a/Software/Visual_Studio/Scripting/Tango.Scripting.Editors/Intellisense/Utils.cs b/Software/Visual_Studio/Scripting/Tango.Scripting.Editors/Intellisense/Utils.cs
index 2ead15d0d..f8cc7072d 100644
--- a/Software/Visual_Studio/Scripting/Tango.Scripting.Editors/Intellisense/Utils.cs
+++ b/Software/Visual_Studio/Scripting/Tango.Scripting.Editors/Intellisense/Utils.cs
@@ -150,12 +150,7 @@ namespace Tango.Scripting.Editors.Intellisense
var property = knownType.Properties[i];
var pDoc = docNodes.FirstOrDefault(x => x.Attributes["name"].InnerText.Contains(knownType.Type.Name + "." + property.Name));
-
- if (pDoc != null)
- {
- var summaryNode = pDoc.SelectSingleNode("summary");
- property.Summary = summaryNode != null ? summaryNode.InnerXml : "No documentation";
- }
+ property.Summary = pDoc != null ? pDoc.SelectSingleNode("summary").InnerXml : "No documentation";
}
}
@@ -167,12 +162,7 @@ namespace Tango.Scripting.Editors.Intellisense
{
var field = knownType.Fields[i];
var pDoc = xmlDoc.SelectSingleNode("//member[starts-with(@name, '" + $"F:{knownType.Type.FullName}.{field.Name}" + "')]");
-
- if (pDoc != null)
- {
- var summaryNode = pDoc.SelectSingleNode("summary");
- field.Summary = summaryNode != null ? summaryNode.InnerXml : "No documentation";
- }
+ field.Summary = pDoc != null ? pDoc.SelectSingleNode("summary").InnerXml : "No documentation";
}
}
}
diff --git a/Software/Visual_Studio/Scripting/Tango.Scripting.Editors/Rendering/TextView.cs b/Software/Visual_Studio/Scripting/Tango.Scripting.Editors/Rendering/TextView.cs
index 1b1f12ff3..3dabb6b7a 100644
--- a/Software/Visual_Studio/Scripting/Tango.Scripting.Editors/Rendering/TextView.cs
+++ b/Software/Visual_Studio/Scripting/Tango.Scripting.Editors/Rendering/TextView.cs
@@ -554,7 +554,7 @@ namespace Tango.Scripting.Editors.Rendering
/// </summary>
public static readonly DependencyProperty LinkTextForegroundBrushProperty =
DependencyProperty.Register("LinkTextForegroundBrush", typeof(Brush), typeof(TextView),
- new FrameworkPropertyMetadata(Brushes.Gray));
+ new FrameworkPropertyMetadata(Brushes.Blue));
/// <summary>
/// Gets/sets the Brush used for displaying link texts.
diff --git a/Software/Visual_Studio/Scripting/Tango.Scripting.Editors/ScriptEditor.cs b/Software/Visual_Studio/Scripting/Tango.Scripting.Editors/ScriptEditor.cs
index e65ff671d..efa1b087a 100644
--- a/Software/Visual_Studio/Scripting/Tango.Scripting.Editors/ScriptEditor.cs
+++ b/Software/Visual_Studio/Scripting/Tango.Scripting.Editors/ScriptEditor.cs
@@ -1,10 +1,8 @@
using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.CSharp.Syntax;
-using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
-using System.ComponentModel.Design;
using System.Diagnostics;
using System.IO;
using System.Linq;
@@ -25,9 +23,7 @@ using System.Windows.Navigation;
using System.Windows.Shapes;
using System.Windows.Threading;
using System.Xml;
-using Tango.Core;
using Tango.Core.Commands;
-using Tango.Scripting.Core;
using Tango.Scripting.Editors.CodeCompletion;
using Tango.Scripting.Editors.Document;
using Tango.Scripting.Editors.Editing;
@@ -37,7 +33,6 @@ using Tango.Scripting.Editors.Highlighting.Xshd;
using Tango.Scripting.Editors.Intellisense;
using Tango.Scripting.Editors.Popups;
using Tango.Scripting.Editors.Rendering;
-using Tango.Scripting.Formatting;
using Tango.Scripting.Parsing;
namespace Tango.Scripting.Editors
@@ -47,10 +42,7 @@ namespace Tango.Scripting.Editors
private char[] word_separators = { ' ', '\t', '\n', '.', '(', ',', '-', '*', '/', '+', '$', '=', '<', '>' };
private string[] _blocking_type_words = { "class", "void" };
- public event EventHandler<BreakPointSymbolPressedEventArgs> BreakPointSymbolPressed;
-
private DispatcherTimer _update_timer;
- private BreakPointMargin breakPointMargin;
private Popup _popup;
private FoldingManager foldingManager;
private BraceFoldingStrategy foldingStrategy;
@@ -60,48 +52,9 @@ namespace Tango.Scripting.Editors
private List<KnownType> _knownTypes;
private List<ScriptType> _declaredTypes;
private bool _isLoadingTypes;
- private TextMarkerService errorMarkerService;
- private List<ScriptBreakPointSymbol> _breakPointSymbols;
- private int _breakPointLineNumber;
- private ScriptBreakPointSymbol _currentBreakPointSymbol;
- private Point _currentBreakPointSymbolPosition;
-
- private static JsonSerializerSettings _jsonSettings;
- private static Dictionary<Type, KnownType> _knownTypesCache;
- private static String KNOWN_TYPES_CACHE_FOLDER;
- private static List<CachedAssembly> _cachedAssemblies;
- private static List<CachedUsing> _cachedUsings;
- private static bool _isLoadingCachedAssemblies;
- private static bool _isCacheAssembliesLoaded;
- private static bool _isUsingsLoadingStarted;
- private static object _loadUsingsLock = new object();
- private static List<SnippetCompletionItem> snippets;
-
- public static event EventHandler<TangoProgressChangedEventArgs<int>> LoadingSymbolsProgress;
- public static event EventHandler LoadingSymbolsStarted;
- public static event EventHandler LoadingSymbolsCompleted;
- private static event EventHandler KnownTypesAvailable;
- public static event EventHandler UsingsLoadingStarted;
- public static event EventHandler UsingsLoadingCompleted;
#region Mini Classes
- private class KnownTypeResult
- {
- public KnownType KnownType { get; set; }
- public bool IsStatic { get; set; }
-
- public KnownTypeResult()
- {
-
- }
-
- public KnownTypeResult(KnownType knownType)
- {
- KnownType = knownType;
- }
- }
-
private class ScriptClass
{
public String Name { get; set; }
@@ -132,8 +85,6 @@ namespace Tango.Scripting.Editors
#region Properties
- public static List<String> BlockedUsingsCache { get; set; }
-
/// <summary>
/// Gets or sets a value indicating whether to enable folding.
/// </summary>
@@ -159,13 +110,13 @@ namespace Tango.Scripting.Editors
/// <summary>
/// Gets or sets the reference assemblies.
/// </summary>
- public ObservableCollection<Assembly> ReferenceAssemblies
+ public ObservableCollection<ReferenceAssembly> ReferenceAssemblies
{
- get { return (ObservableCollection<Assembly>)GetValue(ReferenceAssembliesProperty); }
+ get { return (ObservableCollection<ReferenceAssembly>)GetValue(ReferenceAssembliesProperty); }
set { SetValue(ReferenceAssembliesProperty, value); }
}
public static readonly DependencyProperty ReferenceAssembliesProperty =
- DependencyProperty.Register("ReferenceAssemblies", typeof(ObservableCollection<Assembly>), typeof(ScriptEditor), new PropertyMetadata(null, (d, e) => (d as ScriptEditor).OnReferenceAssembliesChanged()));
+ DependencyProperty.Register("ReferenceAssemblies", typeof(ObservableCollection<ReferenceAssembly>), typeof(ScriptEditor), new PropertyMetadata(null));
public Object CurrentPopupContent
{
@@ -175,70 +126,6 @@ namespace Tango.Scripting.Editors
public static readonly DependencyProperty CurrentPopupContentProperty =
DependencyProperty.Register("CurrentPopupContent", typeof(Object), typeof(ScriptEditor), new PropertyMetadata(null));
- public String Code
- {
- get { return (String)GetValue(CodeProperty); }
- set { SetValue(CodeProperty, value); }
- }
- public static readonly DependencyProperty CodeProperty =
- DependencyProperty.Register("Code", typeof(String), typeof(ScriptEditor), new PropertyMetadata(null, (d, e) => (d as ScriptEditor).OnCodeChanged()));
-
- public ObservableCollection<IScriptSource> AdditionalScripts
- {
- get { return (ObservableCollection<IScriptSource>)GetValue(AdditionalScriptsProperty); }
- set { SetValue(AdditionalScriptsProperty, value); }
- }
- public static readonly DependencyProperty AdditionalScriptsProperty =
- DependencyProperty.Register("AdditionalScripts", typeof(ObservableCollection<IScriptSource>), typeof(ScriptEditor), new PropertyMetadata(null));
-
- public Brush ColorizeBrush
- {
- get { return (Brush)GetValue(ColorizeBrushProperty); }
- set { SetValue(ColorizeBrushProperty, value); }
- }
- public static readonly DependencyProperty ColorizeBrushProperty =
- DependencyProperty.Register("ColorizeBrush", typeof(Brush), typeof(ScriptEditor), new PropertyMetadata(new SolidColorBrush(Colors.YellowGreen) { Opacity = 0.5 }));
-
- public Brush ErrorLineBrush
- {
- get { return (Brush)GetValue(ErrorLineBrushProperty); }
- set { SetValue(ErrorLineBrushProperty, value); }
- }
- public static readonly DependencyProperty ErrorLineBrushProperty =
- DependencyProperty.Register("ErrorLineBrush", typeof(Brush), typeof(ScriptEditor), new PropertyMetadata(new SolidColorBrush(Colors.Red) { Opacity = 0.5 }));
-
- public Brush DebugLineBrush
- {
- get { return (Brush)GetValue(DebugLineBrushProperty); }
- set { SetValue(DebugLineBrushProperty, value); }
- }
- public static readonly DependencyProperty DebugLineBrushProperty =
- DependencyProperty.Register("DebugLineBrush", typeof(Brush), typeof(ScriptEditor), new PropertyMetadata(new SolidColorBrush(Colors.Gray) { Opacity = 0.5 }));
-
- public Brush BreakPointLineBrush
- {
- get { return (Brush)GetValue(BreakPointLineBrushProperty); }
- set { SetValue(BreakPointLineBrushProperty, value); }
- }
- public static readonly DependencyProperty BreakPointLineBrushProperty =
- DependencyProperty.Register("BreakPointLineBrush", typeof(Brush), typeof(ScriptEditor), new PropertyMetadata(new SolidColorBrush(Colors.Yellow) { Opacity = 0.5 }));
-
- public IScriptSource ScriptSource
- {
- get { return (IScriptSource)GetValue(ScriptSourceProperty); }
- set { SetValue(ScriptSourceProperty, value); }
- }
- public static readonly DependencyProperty ScriptSourceProperty =
- DependencyProperty.Register("ScriptSource", typeof(IScriptSource), typeof(ScriptEditor), new PropertyMetadata(null));
-
- public bool DisableBreakPoints
- {
- get { return (bool)GetValue(DisableBreakPointsProperty); }
- set { SetValue(DisableBreakPointsProperty, value); }
- }
- public static readonly DependencyProperty DisableBreakPointsProperty =
- DependencyProperty.Register("DisableBreakPoints", typeof(bool), typeof(ScriptEditor), new PropertyMetadata(false));
-
#endregion
@@ -250,87 +137,6 @@ namespace Tango.Scripting.Editors
static ScriptEditor()
{
DefaultStyleKeyProperty.OverrideMetadata(typeof(ScriptEditor), new FrameworkPropertyMetadata(typeof(ScriptEditor)));
-
- snippets = new List<SnippetCompletionItem>();
-
- BlockedUsingsCache = new List<string>();
-
- if (KNOWN_TYPES_CACHE_FOLDER == null)
- {
- KNOWN_TYPES_CACHE_FOLDER = System.IO.Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData), "Twine", "Tango", "Scripting", "Cache");
- Directory.CreateDirectory(KNOWN_TYPES_CACHE_FOLDER);
- }
-
- _jsonSettings = new JsonSerializerSettings()
- {
- TypeNameHandling = TypeNameHandling.Auto,
- PreserveReferencesHandling = PreserveReferencesHandling.All
- };
-
- _knownTypesCache = new Dictionary<Type, KnownType>();
- _cachedAssemblies = new List<CachedAssembly>();
- _cachedUsings = new List<CachedUsing>();
-
- snippets.Add(new SnippetCompletionItem()
- {
- Name = "for",
- Code = @"for (int i = 0; i < 10; i++)
- {
-
- }"
- });
-
- snippets.Add(new SnippetCompletionItem()
- {
- Name = "while",
- Code = @"while (true)
- {
-
- }"
- });
-
- snippets.Add(new SnippetCompletionItem()
- {
- Name = "foreach",
- Code = @"foreach (var item in items)
- {
-
- }"
- });
-
- snippets.Add(new SnippetCompletionItem()
- {
- Name = "prop",
- Code = @"public int MyProperty { get; set; }"
- });
-
- snippets.Add(new SnippetCompletionItem()
- {
- Name = "do",
- Code = @"do
- {
-
- } while (true)"
- });
-
- snippets.Add(new SnippetCompletionItem()
- {
- Name = "try",
- Code = @"try
- {
-
- }
- catch (Exception ex)
- {
-
- }"
- });
-
- snippets.Add(new SnippetCompletionItem()
- {
- Name = "cw",
- Code = "context.WriteLine(\"\");"
- });
}
/// <summary>
@@ -342,17 +148,16 @@ namespace Tango.Scripting.Editors
_current_usings = new List<string>();
- //ReferenceAssemblies = new ObservableCollection<ReferenceAssembly>();
+ ReferenceAssemblies = new ObservableCollection<ReferenceAssembly>();
- ////Add basic assemblies...
- //ReferenceAssemblies.Add(new ReferenceAssembly(typeof(String))); //mscorelib
- //ReferenceAssemblies.Add(new ReferenceAssembly(typeof(Enumerable))); //System.Core
+ //Add basic assemblies...
+ ReferenceAssemblies.Add(new ReferenceAssembly(typeof(String))); //mscorelib
+ ReferenceAssemblies.Add(new ReferenceAssembly(typeof(Enumerable))); //System.Core
+ ReferenceAssemblies.Add(new ReferenceAssembly(typeof(Tango.Core.CoreSettings))); //System.Core
_knownTypes = new List<KnownType>();
_parser = new ScriptParser();
- KnownTypesAvailable += ScriptEditor_KnownTypesAvailable;
-
TextArea.IndentationStrategy = new Indentation.CSharp.CSharpIndentationStrategy(Options);
foldingStrategy = new BraceFoldingStrategy();
@@ -370,59 +175,6 @@ namespace Tango.Scripting.Editors
completionWindow.AllowsTransparency = true;
completionWindow.ResizeMode = ResizeMode.NoResize;
completionWindow.InsertionRequest += CompletionWindow_InsertionRequest;
-
- TextChanged += ScriptEditor_TextChanged;
-
- errorMarkerService = new TextMarkerService(Document);
- TextArea.TextView.BackgroundRenderers.Add(errorMarkerService);
- TextArea.TextView.LineTransformers.Add(errorMarkerService);
-
- Unloaded += ScriptEditor_Unloaded;
-
- breakPointMargin = new BreakPointMargin(this);
- _breakPointSymbols = new List<ScriptBreakPointSymbol>();
- Loaded += ScriptEditor_Loaded;
-
- MouseMove += ScriptEditor_MouseMove;
- }
-
- private void ScriptEditor_Loaded(object sender, RoutedEventArgs e)
- {
- TextArea.LeftMargins.Insert(0, breakPointMargin);
- }
-
- private void ScriptEditor_Unloaded(object sender, RoutedEventArgs e)
- {
- _update_timer.Stop();
- }
-
- private void ScriptEditor_KnownTypesAvailable(object sender, EventArgs e)
- {
- if (sender != this)
- {
- InvalidateHighlightingPartial();
- }
- }
-
- private bool preventCodeUpdate;
- private void ScriptEditor_TextChanged(object sender, EventArgs e)
- {
- if (!preventCodeUpdate)
- {
- preventCodeUpdate = true;
- Code = Text;
- preventCodeUpdate = false;
- }
- }
-
- private void OnCodeChanged()
- {
- if (!preventCodeUpdate)
- {
- preventCodeUpdate = true;
- Text = Code;
- preventCodeUpdate = false;
- }
}
#endregion
@@ -527,18 +279,18 @@ namespace Tango.Scripting.Editors
}
else if (e.Key == Key.Oem2)
{
- //int offset = CaretOffset;
- //var line = Document.GetLineByOffset(offset);
+ int offset = CaretOffset;
+ var line = Document.GetLineByOffset(offset);
- //String text = GetCurrentLineText();
- //if (text.TrimStart('\t', ' ').StartsWith("//"))
- //{
- // Document.BeginUpdate();
- // Document.Replace(line, "/// <summary>\n/// \n/// </summary>");
- // Document.EndUpdate();
- // e.Handled = true;
- // CaretOffset = Document.GetLineByNumber(line.LineNumber + 1).EndOffset;
- //}
+ String text = GetCurrentLineText();
+ if (text.TrimStart('\t', ' ').StartsWith("//"))
+ {
+ Document.BeginUpdate();
+ Document.Replace(line, "/// <summary>\n/// \n/// </summary>");
+ Document.EndUpdate();
+ e.Handled = true;
+ CaretOffset = Document.GetLineByNumber(line.LineNumber + 1).EndOffset;
+ }
}
else if (e.Key == Key.End || e.Key == Key.Home)
{
@@ -552,509 +304,474 @@ namespace Tango.Scripting.Editors
private void TextArea_TextEntered(object sender, TextCompositionEventArgs e)
{
- if (IsReadOnly) return;
+ List<Object> items = new List<object>();
- try
- {
- List<Object> items = new List<object>();
+ HidePopup();
- HidePopup();
+ var lineText = GetCurrentLineText();
+ var previousWords = GetPreviousWords();
+ var previousWordsLast = previousWords.LastOrDefault();
+ String currentWord = previousWordsLast != null ? previousWordsLast.Replace("\t", "") : String.Empty;
+ String currentWordIncludingParenthesis = currentWord.Split('(').LastOrDefault();
- var lineText = GetCurrentLineText();
- var previousWords = GetPreviousWords();
- var previousWordsLast = previousWords.LastOrDefault();
- String currentWord = previousWordsLast != null ? previousWordsLast.Replace("\t", "") : String.Empty;
- String currentWordIncludingParenthesis = currentWord.Split('(').LastOrDefault();
+ if (previousWords.Count > 0 && previousWords.First().Trim().StartsWith("//")) return;
- if (previousWords.Count > 0 && previousWords.First().Trim().StartsWith("//")) return;
+ if (e.Text == " " && previousWords.Count > 2 && previousWords[previousWords.Count - 2] == "=")
+ {
+ var expression = previousWords.First();
+ var knownType = GetKnownTypeFromExpression(expression + ".");
- if (e.Text == " " && previousWords.Count > 2 && previousWords[previousWords.Count - 2] == "=")
+ if (knownType != null && knownType.Type.IsEnum)
{
- var expression = previousWords.First();
- var knownTypeResult = GetKnownTypeFromExpression(expression + ".");
+ completionWindow.HideCompletion();
+ IList<ICompletionData> data = new List<ICompletionData>();
- if (knownTypeResult != null && knownTypeResult.KnownType.Type.IsEnum)
+ foreach (var field in knownType.Fields)
{
- completionWindow.HideCompletion();
- IList<ICompletionData> data = new List<ICompletionData>();
-
- foreach (var field in knownTypeResult.KnownType.Fields)
+ data.Add(new FieldCompletionItem()
{
- data.Add(new FieldCompletionItem()
- {
- Class = knownTypeResult.KnownType.FriendlyName,
- Name = knownTypeResult.KnownType.FriendlyName + "." + field.Name,
- Type = field.ReturnTypeFriendlyName,
- Description = field.Summary,
- });
- }
-
- ShowCompletionWindow(data.OrderBy(x => x.Text).ToList(), GetCurrentWord());
+ Class = knownType.FriendlyName,
+ Name = knownType.FriendlyName + "." + field.Name,
+ Type = field.ReturnTypeFriendlyName,
+ Description = field.Summary,
+ });
}
+ ShowCompletionWindow(data.OrderBy(x => x.Text).ToList(), GetCurrentWord());
}
- else if (e.Text == " " && GetPreviousWord() == "new")
- {
- var s = _parser.GetExpressionFirst<FieldDeclarationSyntax>(GetCurrentLineText());
- if (s != null)
- {
- String type = s.Declaration.Type.ToString();
+ }
+ else if (e.Text == " " && GetPreviousWord() == "new")
+ {
+ var s = _parser.GetExpressionFirst<FieldDeclarationSyntax>(GetCurrentLineText());
- IList<ICompletionData> data = new List<ICompletionData>();
+ if (s != null)
+ {
+ String type = s.Declaration.Type.ToString();
- data.Add(new ClassCompletionItem()
- {
- Name = type,
- Description = "Auto generate assignment...",
- });
+ IList<ICompletionData> data = new List<ICompletionData>();
- ShowCompletionWindow(data, type);
- }
- }
- else if (e.Text == ";" || e.Text == " ")
- {
- HideCompletionWindow();
+ data.Add(new ClassCompletionItem()
+ {
+ Name = type,
+ Description = "Auto generate assignment...",
+ });
+
+ ShowCompletionWindow(data, type);
}
- else if (e.Text == ".")
- {
- var knownTypeResult = GetCurrentKnownType();
+ }
+ else if (e.Text == ";" || e.Text == " ")
+ {
+ HideCompletionWindow();
+ }
+ else if (e.Text == ".")
+ {
+ var knownType = GetCurrentKnownType();
+ if (knownType != null)
+ {
+ completionWindow.HideCompletion();
IList<ICompletionData> data = new List<ICompletionData>();
- if (knownTypeResult != null)
+ if (!knownType.Type.IsEnum)
{
- completionWindow.HideCompletion();
+ var typeMembers = knownType.Members.ToList();
- if (!knownTypeResult.KnownType.Type.IsEnum)
+ foreach (var methodGroup in typeMembers.OfType<KnownTypeMethod>().GroupBy(x => x.NameWithTypeArguments))
{
- var typeMembers = knownTypeResult.KnownType.Members.ToList();
+ var method = methodGroup.First();
- foreach (var methodGroup in typeMembers.OfType<KnownTypeMethod>().Where(x => (!knownTypeResult.IsStatic && !x.IsStatic) || (knownTypeResult.IsStatic && x.IsStatic)).GroupBy(x => x.NameWithTypeArguments))
+ data.Add(new MethodCompletionItem()
{
- var method = methodGroup.First();
-
- data.Add(new MethodCompletionItem()
- {
- Class = knownTypeResult.KnownType.FriendlyName,
- Name = method.NameWithTypeArguments,
- ReturnType = method.ReturnTypeFriendlyName,
- Description = method.Summary,
- Parameters = method.Parameters,
- Overloads = methodGroup.Count() - 1,
- });
- }
+ Class = knownType.FriendlyName,
+ Name = method.NameWithTypeArguments,
+ ReturnType = method.ReturnTypeFriendlyName,
+ Description = method.Summary,
+ Parameters = method.Parameters,
+ Overloads = methodGroup.Count() - 1,
+ });
+ }
- foreach (var ev in typeMembers.OfType<KnownTypeEvent>())
- {
- data.Add(new EventCompletionItem()
- {
- Class = knownTypeResult.KnownType.FriendlyName,
- Name = ev.Name,
- Description = ev.Summary,
- });
- }
+ foreach (var methodGroup in typeMembers.Where(x => x.GetType() != typeof(KnownTypeMethod)).GroupBy(x => x.Name))
+ {
+ var member = methodGroup.First();
- foreach (var methodGroup in typeMembers.Where(x => x.GetType() != typeof(KnownTypeMethod) && x.GetType() != typeof(KnownTypeEvent)).GroupBy(x => x.Name))
+ data.Add(new PropertyCompletionItem()
{
- var member = methodGroup.First();
+ Class = knownType.FriendlyName,
+ Name = member.Name,
+ Type = member.ReturnTypeFriendlyName,
+ Description = member.Summary,
+ });
- data.Add(new PropertyCompletionItem()
- {
- Class = knownTypeResult.KnownType.FriendlyName,
- Name = member.Name,
- Type = member.ReturnTypeFriendlyName,
- Description = member.Summary,
- });
- }
}
- else
+ }
+ else
+ {
+ foreach (var field in knownType.Fields)
{
- foreach (var field in knownTypeResult.KnownType.Fields)
+ data.Add(new FieldCompletionItem()
{
- data.Add(new FieldCompletionItem()
- {
- Class = knownTypeResult.KnownType.FriendlyName,
- Name = field.Name,
- Type = field.ReturnTypeFriendlyName,
- Description = field.Summary,
- });
+ Class = knownType.FriendlyName,
+ Name = field.Name,
+ Type = field.ReturnTypeFriendlyName,
+ Description = field.Summary,
+ });
- }
}
-
- ShowCompletionWindow(data.OrderBy(x => x.Text).ToList(), GetCurrentWord());
}
- else
+
+ ShowCompletionWindow(data.OrderBy(x => x.Text).ToList(), GetCurrentWord());
+ }
+ else
+ {
+ var declaredType = GetCurrentDeclaredType();
+
+ if (declaredType != null)
{
- var declaredType = GetCurrentDeclaredType();
+ completionWindow.HideCompletion();
+ IList<ICompletionData> data = new List<ICompletionData>();
- if (declaredType != null)
- {
- completionWindow.HideCompletion();
+ var typeMembers = declaredType.Symbols.ToList();
- var typeMembers = declaredType.Symbols.ToList();
+ foreach (var methodGroup in typeMembers.GroupBy(x => x.Name))
+ {
+ var member = methodGroup.First();
- foreach (var methodGroup in typeMembers.GroupBy(x => x.Name))
+ if (member.Kind == SymbolKind.Method)
{
- var member = methodGroup.First();
-
- if (member.Kind == SymbolKind.Method)
+ var methodCompletion = new MethodCompletionItem()
{
- var methodCompletion = new MethodCompletionItem()
- {
- Class = declaredType.Name,
- Name = member.Name,
- ReturnType = member.Type,
- Description = member.Summary,
- Overloads = methodGroup.Count() - 1,
- };
-
-
- for (int i = 0; i < member.Parameters.Count; i++)
- {
- var pair = member.Parameters[i];
-
- methodCompletion.Parameters.Add(new KnownTypeMethodParameter()
- {
- Type = pair.Key,
- Name = pair.Value,
- IsLast = (i == member.Parameters.Count - 1)
- });
- }
+ Class = declaredType.Name,
+ Name = member.Name,
+ ReturnType = member.Type,
+ Description = member.Summary,
+ Overloads = methodGroup.Count() - 1,
+ };
- data.Add(methodCompletion);
- }
- else if (member.Kind == SymbolKind.Property)
+ for (int i = 0; i < member.Parameters.Count; i++)
{
- data.Add(new PropertyCompletionItem()
+ var pair = member.Parameters[i];
+
+ methodCompletion.Parameters.Add(new KnownTypeMethodParameter()
{
- Class = declaredType.Name,
- Name = member.Name,
- Type = member.Type,
- Description = member.Summary,
+ Type = pair.Key,
+ Name = pair.Value,
+ IsLast = (i == member.Parameters.Count - 1)
});
}
- else if (member.Kind == SymbolKind.Field)
+
+ data.Add(methodCompletion);
+
+ }
+ else if (member.Kind == SymbolKind.Property)
+ {
+ data.Add(new PropertyCompletionItem()
{
- data.Add(new FieldCompletionItem()
- {
- Class = declaredType.Name,
- Name = member.Name,
- Type = member.Type,
- Description = member.Summary,
- });
- }
+ Class = declaredType.Name,
+ Name = member.Name,
+ Type = member.Type,
+ Description = member.Summary,
+ });
+ }
+ else if (member.Kind == SymbolKind.Field)
+ {
+ data.Add(new FieldCompletionItem()
+ {
+ Class = declaredType.Name,
+ Name = member.Name,
+ Type = member.Type,
+ Description = member.Summary,
+ });
}
-
- ShowCompletionWindow(data, GetCurrentWord());
}
+
+ ShowCompletionWindow(data, GetCurrentWord());
}
}
- else if (e.Text == "(" || e.Text == ",")
+ }
+ else if (e.Text == "(" || e.Text == ",")
+ {
+ completionWindow.HideCompletion();
+
+ try
{
- completionWindow.HideCompletion();
+ var session = GetConstructionSession();
- try
+ if (session != null)
{
- var session = GetConstructionSession();
-
- if (session != null)
- {
- var content = CreateConstructionSessionPopupContent(session);
- if (content.Methods.Count > 0)
- {
- ShowPopup(content);
- return;
- }
- }
-
- var methodSession = GetMethodSession();
-
- if (methodSession != null)
+ var content = CreateConstructionSessionPopupContent(session);
+ if (content.Methods.Count > 0)
{
- var content = CreateMethodSessionPopupContent(methodSession);
- if (content.Methods.Count > 0)
- {
- ShowPopup(content);
- return;
- }
+ ShowPopup(content);
+ return;
}
+ }
- var declaredMethodSession = GetDeclaredMethodSession();
+ var methodSession = GetMethodSession();
- if (declaredMethodSession != null)
+ if (methodSession != null)
+ {
+ var content = CreateMethodSessionPopupContent(methodSession);
+ if (content.Methods.Count > 0)
{
- var content = CreateDeclaredMethodSessionPopupContent(declaredMethodSession);
- if (content.Methods.Count > 0)
- {
- ShowPopup(content);
- return;
- }
+ ShowPopup(content);
+ return;
}
+ }
- var staticMethodSession = GetStaticMethodSession();
+ var declaredMethodSession = GetDeclaredMethodSession();
- if (staticMethodSession != null)
+ if (declaredMethodSession != null)
+ {
+ var content = CreateDeclaredMethodSessionPopupContent(declaredMethodSession);
+ if (content.Methods.Count > 0)
{
- var content = CreateMethodSessionPopupContent(staticMethodSession);
- if (content.Methods.Count > 0)
- {
- ShowPopup(content);
- return;
- }
+ ShowPopup(content);
+ return;
}
}
- catch (Exception ex)
- {
- Debug.WriteLine(ex);
- }
}
- else if (lineText.StartsWith("using") && e.Text != "\n")
+ catch (Exception ex)
{
- if (completionWindow.IsVisible)
- {
- completionWindow.UpdatePositionFix();
- return;
- }
+ Debug.WriteLine(ex);
+ }
+ }
+ else if (lineText.StartsWith("using"))
+ {
+ if (completionWindow.IsVisible)
+ {
+ completionWindow.UpdatePositionFix();
+ return;
+ }
- IList<ICompletionData> data = new List<ICompletionData>();
+ IList<ICompletionData> data = new List<ICompletionData>();
- foreach (var asm in ReferenceAssemblies)
+ foreach (var asm in ReferenceAssemblies)
+ {
+ foreach (var ns in asm.Assembly.GetTypes().Select(x => x.Namespace).Distinct().Where(x => x != null))
{
- foreach (var ns in asm.GetTypes().Select(x => x.Namespace).Distinct().Where(x => x != null))
+ data.Add(new NamespaceCompletionItem()
{
- data.Add(new NamespaceCompletionItem()
- {
- Name = ns,
- Assembly = asm.GetName().Name,
- });
- }
+ Name = ns,
+ Assembly = asm.Assembly.GetName().Name,
+ });
}
+ }
- data = data.DistinctBy(x => x.Text).ToList();
+ data = data.DistinctBy(x => x.Text).ToList();
- ShowCompletionWindow(data, GetCurrentWord());
+ ShowCompletionWindow(data, GetCurrentWord());
+ }
+ else if (e.Text == "{")
+ {
+ int parentesisCount = lineText.TakeWhile(x => x != '{').Count(x => x == '\"');
+
+ if (parentesisCount % 2 == 0)
+ {
+ Document.Insert(CaretOffset, "}");
+ CaretOffset--;
}
- else if (e.Text == "{")
+ }
+ else if (e.Text == "}")
+ {
+ if (Document.GetText(CaretOffset - 2, 1) == "{" && Document.GetText(CaretOffset, 1) == "}")
{
- int parentesisCount = lineText.TakeWhile(x => x != '{').Count(x => x == '\"');
-
- if (parentesisCount % 2 == 0)
- {
- Document.Insert(CaretOffset, "}");
- CaretOffset--;
- }
+ Document.Replace(CaretOffset, 1, "");
}
- else if (e.Text == "}")
+ }
+ else if (e.Text == "\n")
+ {
+ if (Document.GetText(CaretOffset - 3, 1) == "{" && Document.GetText(CaretOffset, 1) == "}")
{
- if (Document.GetText(CaretOffset - 2, 1) == "{" && Document.GetText(CaretOffset, 1) == "}")
- {
- Document.Replace(CaretOffset, 1, "");
- }
+ CaretOffset--;
+ Document.Insert(CaretOffset, "\n\t");
+ }
+ }
+ else if (!currentWordIncludingParenthesis.Contains(".") || currentWord[currentWord.Length - 2] == '<')
+ {
+ if (completionWindow.IsVisible)
+ {
+ completionWindow.UpdatePositionFix();
+ return;
}
- else if (e.Text == "\n")
+
+ var previous_word = GetPreviousWord();
+ var word = GetCurrentWord();
+
+ if (word.Contains("<"))
{
- if (Document.GetText(CaretOffset - 3, 1) == "{" && Document.GetText(CaretOffset, 1) == "}")
- {
- CaretOffset--;
- Document.Insert(CaretOffset, "\n\t");
- }
+ word = word.Last(x => x != '<').ToString();
}
- else if (!currentWordIncludingParenthesis.Contains(".") || currentWord[currentWord.Length - 2] == '<')
+
+ if (previous_word != word)
{
- if (completionWindow.IsVisible)
+ if (_knownTypes.Exists(x => x.Name == previous_word))
{
- completionWindow.UpdatePositionFix();
return;
}
- var previous_word = GetPreviousWord();
- var word = GetCurrentWord();
-
- if (word.Contains("<"))
+ if (_blocking_type_words.Contains(previous_word))
{
- word = word.Last(x => x != '<').ToString();
+ return;
}
+ }
- if (previous_word != word)
+ if (!String.IsNullOrWhiteSpace(word))
+ {
+ IList<ICompletionData> data = new List<ICompletionData>();
+
+ foreach (var type in _declaredTypes.Where(x => x.Name.StartsWith(word)))
{
- if (_knownTypes.Exists(x => x.Name == previous_word))
+ if (type.Kind == TypeKind.Struct)
{
- return;
+ data.Add(new StructCompletionItem()
+ {
+ Name = type.Name,
+ Description = type.Summary,
+ Namespace = type.ContainingNamespace,
+ Priority = 1,
+ });
}
-
- if (_blocking_type_words.Contains(previous_word))
+ else if (type.Kind == TypeKind.Enum)
{
- return;
+ data.Add(new EnumCompletionItem()
+ {
+ Name = type.Name,
+ Description = type.Summary,
+ Namespace = type.ContainingNamespace,
+ Priority = 1,
+ });
+ }
+ else if (type.Kind == TypeKind.Interface)
+ {
+ data.Add(new InterfaceCompletionItem()
+ {
+ Name = type.Name,
+ Description = type.Summary,
+ Namespace = type.ContainingNamespace,
+ Priority = 1,
+ });
+ }
+ else if (type.Kind == TypeKind.Class)
+ {
+ data.Add(new ClassCompletionItem()
+ {
+ Name = type.Name,
+ Description = type.Summary,
+ Namespace = type.ContainingNamespace,
+ Priority = 1,
+ });
+ }
+ else
+ {
+ throw new NotImplementedException("Implement generic item here!");
}
}
- if (!String.IsNullOrWhiteSpace(word))
+ foreach (var type in _knownTypes.ToList().Where(x => x.Name.StartsWith(word)))
{
- IList<ICompletionData> data = new List<ICompletionData>();
-
- foreach (var snippet in snippets)
+ if (type.Type.IsEnum)
{
- data.Add(snippet);
+ data.Add(new EnumCompletionItem()
+ {
+ Namespace = type.Type.Namespace,
+ Description = type.Summary,
+ Name = type.FriendlyName,
+ Priority = 0,
+ });
}
-
- foreach (var type in _declaredTypes.Where(x => x.Name.StartsWith(word)))
+ else if (type.Type.IsInterface)
{
- if (type.Kind == TypeKind.Struct)
+ data.Add(new InterfaceCompletionItem()
{
- data.Add(new StructCompletionItem()
- {
- Name = type.Name,
- Description = type.Summary,
- Namespace = type.ContainingNamespace,
- Priority = 1,
- });
- }
- else if (type.Kind == TypeKind.Enum)
- {
- data.Add(new EnumCompletionItem()
- {
- Name = type.Name,
- Description = type.Summary,
- Namespace = type.ContainingNamespace,
- Priority = 1,
- });
- }
- else if (type.Kind == TypeKind.Interface)
- {
- data.Add(new InterfaceCompletionItem()
- {
- Name = type.Name,
- Description = type.Summary,
- Namespace = type.ContainingNamespace,
- Priority = 1,
- });
- }
- else if (type.Kind == TypeKind.Class)
+ Name = type.FriendlyName,
+ Description = type.Summary,
+ Namespace = type.Type.Namespace,
+ Priority = 0,
+ });
+ }
+ else if (type.Type.IsValueType)
+ {
+ data.Add(new StructCompletionItem()
{
- data.Add(new ClassCompletionItem()
- {
- Name = type.Name,
- Description = type.Summary,
- Namespace = type.ContainingNamespace,
- Priority = 1,
- });
- }
- else
+ Name = type.FriendlyName,
+ Description = type.Summary,
+ Namespace = type.Type.Namespace,
+ Priority = 0,
+ });
+ }
+ else if (type.Type.IsClass)
+ {
+ data.Add(new ClassCompletionItem()
{
- throw new NotImplementedException("Implement generic item here!");
- }
+ Name = type.FriendlyName,
+ Description = type.Summary,
+ Namespace = type.Type.Namespace,
+ Priority = 0,
+ });
+ }
+ else
+ {
+ throw new NotImplementedException("Implement generic item here.");
}
+ }
- foreach (var type in _knownTypes.ToList().Where(x => x.Name.StartsWith(word)))
+ foreach (var symbol in _parser.GetContextSymbols(Document.Text, CaretOffset).Where(x => x.Name.StartsWith(GetCurrentWord())))
+ {
+ if (symbol.Kind == SymbolKind.Property)
{
- if (type.Type.IsEnum)
- {
- data.Add(new EnumCompletionItem()
- {
- Namespace = type.Type.Namespace,
- Description = type.Summary,
- Name = type.FriendlyName,
- Priority = 0,
- });
- }
- else if (type.Type.IsInterface)
+ data.Add(new PropertyCompletionItem()
{
- data.Add(new InterfaceCompletionItem()
- {
- Name = type.FriendlyName,
- Description = type.Summary,
- Namespace = type.Type.Namespace,
- Priority = 0,
- });
- }
- else if (type.Type.IsValueType)
- {
- data.Add(new StructCompletionItem()
- {
- Name = type.FriendlyName,
- Description = type.Summary,
- Namespace = type.Type.Namespace,
- Priority = 0,
- });
- }
- else if (type.Type.IsClass)
- {
- data.Add(new ClassCompletionItem()
- {
- Name = type.FriendlyName,
- Description = type.Summary,
- Namespace = type.Type.Namespace,
- Priority = 0,
- });
- }
- else
+ Class = symbol.Class,
+ Description = symbol.Summary,
+ Name = symbol.Name,
+ Type = symbol.Type,
+ Priority = 2,
+ });
+ }
+ else if (symbol.Kind == SymbolKind.Field || symbol.Kind == SymbolKind.Local || symbol.Kind == SymbolKind.Parameter)
+ {
+ data.Add(new FieldCompletionItem()
{
- throw new NotImplementedException("Implement generic item here.");
- }
+ Class = symbol.Class,
+ Description = symbol.Summary,
+ Name = symbol.Name,
+ Type = symbol.Type,
+ Priority = 2,
+ });
}
-
- foreach (var symbol in _parser.GetContextSymbols(Document.Text, CaretOffset).Where(x => x.Name.StartsWith(GetCurrentWord())))
+ else if (symbol.Kind == SymbolKind.Method)
{
- if (symbol.Kind == SymbolKind.Property)
+ var methodCompletion = new MethodCompletionItem()
{
- data.Add(new PropertyCompletionItem()
- {
- Class = symbol.Class,
- Description = symbol.Summary,
- Name = symbol.Name,
- Type = symbol.Type,
- Priority = 2,
- });
- }
- else if (symbol.Kind == SymbolKind.Field || symbol.Kind == SymbolKind.Local || symbol.Kind == SymbolKind.Parameter)
+ Class = symbol.Class,
+ Description = symbol.Summary,
+ Name = symbol.Name,
+ ReturnType = symbol.Type,
+ Priority = 2,
+ };
+
+ for (int i = 0; i < symbol.Parameters.Count; i++)
{
- data.Add(new FieldCompletionItem()
+ var pair = symbol.Parameters[i];
+
+ methodCompletion.Parameters.Add(new KnownTypeMethodParameter()
{
- Class = symbol.Class,
- Description = symbol.Summary,
- Name = symbol.Name,
- Type = symbol.Type,
- Priority = 2,
+ Type = pair.Key,
+ Name = pair.Value,
+ IsLast = (i == symbol.Parameters.Count - 1)
});
}
- else if (symbol.Kind == SymbolKind.Method)
- {
- var methodCompletion = new MethodCompletionItem()
- {
- Class = symbol.Class,
- Description = symbol.Summary,
- Name = symbol.Name,
- ReturnType = symbol.Type,
- Priority = 2,
- };
-
- for (int i = 0; i < symbol.Parameters.Count; i++)
- {
- var pair = symbol.Parameters[i];
- methodCompletion.Parameters.Add(new KnownTypeMethodParameter()
- {
- Type = pair.Key,
- Name = pair.Value,
- IsLast = (i == symbol.Parameters.Count - 1)
- });
- }
-
- data.Add(methodCompletion);
- }
+ data.Add(methodCompletion);
}
-
- ShowCompletionWindow(data, word);
}
+
+ ShowCompletionWindow(data, word);
}
}
- catch (Exception ex)
- {
- Debug.WriteLine(ex.ToString());
- }
}
#endregion
@@ -1075,7 +792,7 @@ namespace Tango.Scripting.Editors
IList<ICompletionData> data = completionWindow.CompletionList.CompletionData;
data.Clear();
- foreach (var item in suggestions.DistinctBy(x => x.Text))
+ foreach (var item in suggestions)
{
data.Add(item);
}
@@ -1147,23 +864,16 @@ namespace Tango.Scripting.Editors
return list;
}
- private KnownTypeResult GetCurrentKnownType()
+ private KnownType GetCurrentKnownType()
{
var expression = GetPreviousWords().LastOrDefault();
return GetKnownTypeFromExpression(expression);
}
- private KnownTypeResult GetKnownTypeFromExpression(String expression)
+ private KnownType GetKnownTypeFromExpression(String expression)
{
if (expression != null)
{
- var insideMethodExp = expression.Split('(').LastOrDefault();
-
- if (insideMethodExp != null)
- {
- expression = insideMethodExp;
- }
-
var tree = expression.Split('.').Select(x => x.Remove(@"\n|\t|\r|\(.*\)|\[.*\]|\s")).ToList();
var variableName = tree.FirstOrDefault();
@@ -1174,7 +884,7 @@ namespace Tango.Scripting.Editors
if (enumType != null)
{
- return new KnownTypeResult(enumType);
+ return enumType;
}
tree.RemoveAt(0);
@@ -1183,8 +893,7 @@ namespace Tango.Scripting.Editors
if (variable != null)
{
- var name = Regex.Replace(variable.Type, "<.+>", "<T>");
- var knownType = _knownTypes.FirstOrDefault(x => name == x.FriendlyName || name == x.Alias);
+ var knownType = _knownTypes.FirstOrDefault(x => x.FriendlyName == Regex.Replace(variable.Type, "<.+>", "<T>"));
if (knownType != null)
{
@@ -1202,37 +911,9 @@ namespace Tango.Scripting.Editors
knownType = _knownTypes.FirstOrDefault(x => x.Type.Namespace + "." + x.Type.Name == member.ReturnType.Namespace + "." + member.ReturnType.Name);
}
- return new KnownTypeResult(knownType);
- }
- else //Maybe a variable of a declared type...
- {
- if (tree.Count > 0)
- {
- var memberName = tree[0];
- var declaredType = _declaredTypes.SingleOrDefault(x => x.Name == name);
-
- if (declaredType != null)
- {
- var member = declaredType.Symbols.FirstOrDefault(x => x.Name == memberName);
- if (member != null)
- {
- knownType = _knownTypes.SingleOrDefault(x => x.Name.ToLower() == member.Type.ToLower());
-
- if (knownType != null)
- {
- return new KnownTypeResult(knownType);
- }
- }
- }
- }
+ return knownType;
}
}
- else
- {
- //Maybe static...
- var type = _knownTypes.FirstOrDefault(x => x.Name == variableName || x.Alias == variableName);
- return type != null ? new KnownTypeResult(type) { IsStatic = true } : null;
- }
}
}
@@ -1245,13 +926,6 @@ namespace Tango.Scripting.Editors
if (expression != null)
{
- var insideMethodExp = expression.Split('(').LastOrDefault();
-
- if (insideMethodExp != null)
- {
- expression = insideMethodExp;
- }
-
var tree = expression.Split('.').Select(x => x.Remove(@"\n|\t|\r|\(.*\)|\[.*\]|\s")).ToList();
var variableName = tree.FirstOrDefault();
@@ -1284,11 +958,6 @@ namespace Tango.Scripting.Editors
return declaredType;
}
}
- else
- {
- //Maybe static...
- return _declaredTypes.FirstOrDefault(x => x.Name == variableName);
- }
}
}
@@ -1378,7 +1047,7 @@ namespace Tango.Scripting.Editors
foreach (var m in session.Type.Methods.Where(x => x.Name == session.MethodName))
{
MethodDescription method = new MethodDescription();
- method.ReturnType = m.ReturnTypeFriendlyName;
+ method.ReturnType = session.Type.Name;
method.Description = m.Summary;
method.Name = m.NameWithTypeArguments;
method.Class = session.Type.FriendlyName;
@@ -1471,364 +1140,33 @@ namespace Tango.Scripting.Editors
return popup;
}
- public void LoadUsingsSymbols(List<Assembly> assemblies, List<String> usings)
- {
- lock (_loadUsingsLock)
- {
- LoadingSymbolsStarted?.Invoke(null, new EventArgs());
-
- var allTypes = assemblies.SelectMany(x => x.GetTypes());
-
- foreach (var use in usings)
- {
- if (!_cachedUsings.Exists(x => x.Namespace == use))
- {
- if (!_isUsingsLoadingStarted)
- {
- _isUsingsLoadingStarted = true;
- UsingsLoadingStarted?.Invoke(this, new EventArgs());
- }
-
- var useFileName = System.IO.Path.Combine(KNOWN_TYPES_CACHE_FOLDER, use + ".json");
-
- if (File.Exists(useFileName))
- {
- LoadingSymbolsProgress?.Invoke(null, new TangoProgressChangedEventArgs<int>()
- {
- Progress = new TangoProgress<int>()
- {
- IsIndeterminate = true,
- Maximum = 100,
- Message = $"Loading symbols for '{use}'..."
- }
- });
-
- CachedUsing cached = JsonConvert.DeserializeObject<CachedUsing>(File.ReadAllText(useFileName), _jsonSettings);
- _cachedUsings.Add(cached);
- foreach (var knownType in cached.KnownTypes)
- {
- _knownTypesCache.Add(knownType.Type, knownType);
- }
-
- KnownTypesAvailable?.Invoke(this, new EventArgs());
- InvalidateHighlightingPartial();
-
- continue;
- }
-
- var useTypes = allTypes.Where(x => x.IsVisible && x.IsPublic && x.Namespace == use).ToList();
-
- CachedUsing cachedUsing = new CachedUsing();
- cachedUsing.Namespace = use;
- _cachedUsings.Add(cachedUsing);
-
- int i = 1;
-
- foreach (var type in useTypes)
- {
- LoadingSymbolsProgress?.Invoke(null, new TangoProgressChangedEventArgs<int>()
- {
- Progress = new TangoProgress<int>()
- {
- IsIndeterminate = false,
- Maximum = useTypes.Count,
- Value = i++,
- Message = $"Loading symbols for '{use}'..."
- }
- });
-
- KnownType knownType = new KnownType(type);
-
- if (type.IsPrimitive)
- {
- if (type == typeof(Int32))
- {
- knownType.Alias = "int";
- }
- else if (type == typeof(float))
- {
- knownType.Alias = "float";
- }
- else if (type == typeof(Double))
- {
- knownType.Alias = "double";
- }
- else if (type == typeof(long))
- {
- knownType.Alias = "long";
- }
- else if (type == typeof(bool))
- {
- knownType.Alias = "bool";
- }
- else if (type == typeof(uint))
- {
- knownType.Alias = "uint";
- }
- }
- else if (type == typeof(String))
- {
- knownType.Alias = "string";
- }
-
- _knownTypesCache.Add(type, knownType);
- cachedUsing.KnownTypes.Add(knownType);
- knownType.LoadDocumentation();
- }
-
- if (!BlockedUsingsCache.Exists(x => use.StartsWith(x)))
- {
- Task.Factory.StartNew(() =>
- {
- var json = JsonConvert.SerializeObject(cachedUsing, _jsonSettings);
- File.WriteAllText(useFileName, json);
- });
- }
- }
- }
-
- if (_isUsingsLoadingStarted)
- {
- UsingsLoadingCompleted?.Invoke(this, new EventArgs());
- }
-
- LoadingSymbolsCompleted?.Invoke(null, new EventArgs());
- }
- }
-
- //public static void LoadCachedAssemblies(List<Assembly> assemblies, List<String> usings = null)
- //{
- // if (_isLoadingCachedAssemblies) return;
-
- // _isLoadingCachedAssemblies = true;
-
- // LoadingSymbolsStarted?.Invoke(null, new EventArgs());
-
- // if (!_isCacheAssembliesLoaded)
- // {
- // foreach (var file in System.IO.Directory.GetFiles(KNOWN_TYPES_CACHE_FOLDER))
- // {
- // try
- // {
- // LoadingSymbolsProgress?.Invoke(null, new TangoProgressChangedEventArgs<int>()
- // {
- // Progress = new TangoProgress<int>()
- // {
- // IsIndeterminate = true,
- // Maximum = 100,
- // Message = $"Loading metadata cache for '{System.IO.Path.GetFileName(file)}'..."
- // }
- // });
-
- // var cachedAssembly = JsonConvert.DeserializeObject<CachedAssembly>(System.IO.File.ReadAllText(file), _jsonSettings);
-
- // foreach (var knownType in cachedAssembly.KnownTypes)
- // {
- // _knownTypesCache.Add(knownType.Type, knownType);
- // }
-
- // _cachedAssemblies.Add(cachedAssembly);
- // }
- // catch { }
- // }
-
- // _isCacheAssembliesLoaded = true;
- // }
-
- // foreach (var asm in assemblies)
- // {
- // if (!_cachedAssemblies.Exists(x => x.Name == asm.FullName))
- // {
- // String asmFileName = System.IO.Path.GetFileName(asm.Location);
-
- // CachedAssembly cachedAssembly = new CachedAssembly();
- // cachedAssembly.Name = asm.FullName;
- // _cachedAssemblies.Add(cachedAssembly);
-
- // var types = asm.GetTypes().Where(x => x.IsVisible && x.IsPublic).ToList();
-
- // int i = 0;
-
- // foreach (var type in types)
- // {
- // LoadingSymbolsProgress?.Invoke(null, new TangoProgressChangedEventArgs<int>()
- // {
- // Progress = new TangoProgress<int>()
- // {
- // IsIndeterminate = false,
- // Maximum = types.Count,
- // Value = i++,
- // Message = $"Caching metadata for '{asmFileName}'..."
- // }
- // });
-
- // KnownType knownType = new KnownType(type);
-
- // if (type.IsPrimitive)
- // {
- // if (type == typeof(Int32))
- // {
- // knownType.Alias = "int";
- // }
- // else if (type == typeof(float))
- // {
- // knownType.Alias = "float";
- // }
- // else if (type == typeof(Double))
- // {
- // knownType.Alias = "double";
- // }
- // else if (type == typeof(long))
- // {
- // knownType.Alias = "long";
- // }
- // else if (type == typeof(bool))
- // {
- // knownType.Alias = "bool";
- // }
- // else if (type == typeof(uint))
- // {
- // knownType.Alias = "uint";
- // }
- // }
-
- // _knownTypesCache.Add(type, knownType);
- // cachedAssembly.KnownTypes.Add(knownType);
- // //knownType.LoadDocumentation();
- // }
-
- // String cachedAssemblyFile = System.IO.Path.Combine(KNOWN_TYPES_CACHE_FOLDER, asmFileName);
- // File.WriteAllText(cachedAssemblyFile, JsonConvert.SerializeObject(cachedAssembly, _jsonSettings));
- // }
- // }
-
- // LoadingSymbolsCompleted?.Invoke(null, new EventArgs());
-
- // _isLoadingCachedAssemblies = false;
- //}
-
- private void InvalidateHighlightingPartial()
- {
- List<Assembly> assemblies = new List<Assembly>();
- Dispatcher.Invoke(() =>
- {
- assemblies = ReferenceAssemblies.ToList();
- });
-
- var usings = _current_usings.ToList();
-
- _knownTypes.Clear();
-
- foreach (var knownType in _knownTypesCache.ToList().Select(x => x.Value).ToList())
- {
- if (usings.Exists(x => knownType.Type.Namespace == x) && assemblies.Exists(x => x == knownType.Type.Assembly))
- {
- lock (_knownTypes)
- {
- _knownTypes.Add(knownType);
- }
- }
- }
-
- if (_knownTypes.Count > 0 || _declaredTypes.Count > 0)
- {
- String text = String.Empty;
-
- Stream xshd_stream = typeof(ScriptEditor).Assembly.GetManifestResourceStream("Tango.Scripting.Editors.Highlighting.Resources.CSharp-Mode.xshd");
-
- using (StreamReader reader = new StreamReader(xshd_stream))
- {
- text = reader.ReadToEnd();
- }
-
- List<String> referenceTypes = new List<string>();
- List<String> interfaceTypes = new List<string>();
-
- lock (_knownTypes)
- {
- foreach (var type in _knownTypes.ToList().Where(x => x != null))
- {
- String name = type.Name;
-
- if (type.Type.ContainsGenericParameters)
- {
- name = new String(name.TakeWhile(x => x != '`').ToArray());
- }
-
- if (type.Type.IsInterface || type.Type.IsEnum)
- {
- interfaceTypes.Add(String.Format("<Word>{0}</Word>", name));
- }
- else if (type.Type.IsClass || (type.Type.IsValueType))
- {
- referenceTypes.Add(String.Format("<Word>{0}</Word>", name));
- }
- }
- }
-
- foreach (var type in _declaredTypes)
- {
- if (type.Kind == TypeKind.Interface || type.Kind == TypeKind.Enum)
- {
- interfaceTypes.Add(String.Format("<Word>{0}</Word>", type.Name));
- }
- else if (type.Kind == TypeKind.Class)
- {
- referenceTypes.Add(String.Format("<Word>{0}</Word>", type.Name));
- }
- }
-
- if (referenceTypes.Count > 0)
- {
- text = text.Replace("<Word>@ReferenceTypes@</Word>", String.Join(Environment.NewLine, referenceTypes.Distinct()));
- }
-
- if (interfaceTypes.Count > 0)
- {
- text = text.Replace("<Word>@InterfaceTypes@</Word>", String.Join(Environment.NewLine, interfaceTypes.Distinct()));
- }
-
- MemoryStream ms = new MemoryStream(Encoding.UTF8.GetBytes(text));
-
- XmlTextReader xshd_reader = new XmlTextReader(ms);
-
- Dispatcher.Invoke(new Action(() =>
- {
- SyntaxHighlighting = HighlightingLoader.Load(xshd_reader, HighlightingManager.Instance);
- xshd_reader.Close();
- ms.Dispose();
- }));
- }
- }
-
- public void InvalidateHighlighting(bool loadKnownTypes = true)
+ private void InvalidateHighlighting()
{
if (!_isLoadingTypes)
{
_isLoadingTypes = true;
+ _knownTypes.Clear();
var assemblies = ReferenceAssemblies.ToList();
- KnownType.ExtensionMethodsAssemblies = assemblies.ToList();
var usings = _current_usings.ToList();
Thread t = new Thread(() =>
{
- LoadUsingsSymbols(assemblies, usings);
-
- if (loadKnownTypes)
+ foreach (var asm in assemblies.Select(x => x.Assembly))
{
- _knownTypes.Clear();
-
- foreach (var knownType in _knownTypesCache.ToList().Select(x => x.Value).ToList())
+ Parallel.ForEach(asm.GetTypes().Where(x => x.IsVisible && x.IsPublic && !x.IsPrimitive), (type) =>
{
- if (usings.Exists(x => knownType.Type.Namespace == x) && assemblies.Exists(x => x == knownType.Type.Assembly))
+ if (usings.Exists(x => type.Namespace == x))
{
lock (_knownTypes)
{
- _knownTypes.Add(knownType);
+ if (!_knownTypes.Exists(x => x.Type.FullName == type.FullName))
+ {
+ _knownTypes.Add(new KnownType(type));
+ }
}
}
- }
+ });
}
if (_knownTypes.Count > 0 || _declaredTypes.Count > 0)
@@ -1901,10 +1239,10 @@ namespace Tango.Scripting.Editors
}));
- //foreach (var knownType in _knownTypes)
- //{
- // knownType.LoadDocumentation();
- //}
+ foreach (var knownType in _knownTypes)
+ {
+ knownType.LoadDocumentation();
+ }
}
_isLoadingTypes = false;
@@ -1918,19 +1256,10 @@ namespace Tango.Scripting.Editors
{
var declaredTypes = _parser.GetDeclaredTypes(Text);
- if (AdditionalScripts != null)
- {
- foreach (var script in AdditionalScripts)
- {
- declaredTypes.AddRange(_parser.GetDeclaredTypes(script.Code));
- }
- }
-
-
if (declaredTypes.Exists(x => !_declaredTypes.Exists(y => y.Name == x.Name)) || _declaredTypes.Exists(x => !declaredTypes.Exists(y => y.Name == x.Name)))
{
_declaredTypes = declaredTypes;
- InvalidateHighlighting(false);
+ InvalidateHighlighting();
}
_declaredTypes = declaredTypes;
@@ -1982,8 +1311,7 @@ namespace Tango.Scripting.Editors
private void IndentCode()
{
- Text = CodeFormatter.Format(Text);
- //Text = Indentation.CSharp.CSharpIndentationHelper.IndentCSharpCode(Text);
+ Text = Indentation.CSharp.CSharpIndentationHelper.IndentCSharpCode(Text);
//Text = _parser.IndentCSharpCode(Text);
}
@@ -2061,11 +1389,7 @@ namespace Tango.Scripting.Editors
private ConstructionSession GetConstructionSession()
{
- var currentLine = GetCurrentLineText();
-
- //if (currentLine.Count(x => x == '(') > 1) return null;
-
- var expression = _parser.GetCurrentConstructionExpression(currentLine);
+ var expression = _parser.GetCurrentConstructionExpression(GetCurrentLineText());
if (expression != null)
{
@@ -2121,64 +1445,13 @@ namespace Tango.Scripting.Editors
}
}
- else
- {
- var expression2 = _parser.GetCurrentConstructionExpressionAlt(GetCurrentLineText());
-
- if (expression2 != null && expression2.Identifier != null)
- {
- ConstructionSession session = new ConstructionSession();
-
- var line = GetCurrentLine();
- int parameterIndex = 0;
- for (int i = CaretOffset; i > line.Offset; i--)
- {
- String c = Document.GetText(i, 1);
-
- if (c == "(")
- {
- KnownType type = null;
-
- if (expression2.Identifier != null)
- {
- var typeName = expression2.Identifier.ToString();
- type = _knownTypes.FirstOrDefault(x => x.Type.Name == typeName);
-
- if (type != null)
- {
- session.Type = type;
- session.ParameterIndex = parameterIndex;
- return session;
- }
- else
- {
- return null;
- }
- }
- }
- else if (c == ",")
- {
- parameterIndex++;
- }
- }
- }
- }
return null;
}
private MethodSession GetMethodSession()
{
- var currentLine = GetCurrentLineText();
-
- if (currentLine.Count(x => x == '(') > 1)
- {
- currentLine = currentLine.Split('(')[currentLine.Split('(').Length - 2];
- }
-
- currentLine = Regex.Replace(currentLine, "(?<=\")(.*?)(?=\")", string.Empty);
-
- var words = currentLine.Split(' ');
+ var words = GetCurrentLineText().Split(' ');
if (words.Count() > 0 && (words.First() == "private" || words.First() == "public" || words.First() == "void"))
{
@@ -2190,8 +1463,6 @@ namespace Tango.Scripting.Editors
if (expression != null)
{
int parameterIndex = expression.Count(x => x == ',');
-
-
expression = new string(expression.TakeWhile(x => x != '(').ToArray());
var tree = expression.Split('.').Select(x => x.Remove(@"\n|\r|\s|\t|\(|\)|\[|\]|<.*>")).ToList();
@@ -2237,82 +1508,16 @@ namespace Tango.Scripting.Editors
return null;
}
- private MethodSession GetStaticMethodSession()
- {
- var words = GetCurrentLineText().Split(' ');
-
- if (words.Count() > 0 && (words.First() == "private" || words.First() == "public" || words.First() == "void"))
- {
- return null;
- }
-
- var expression = words.LastOrDefault();
-
- if (expression != null)
- {
- int parameterIndex = expression.Count(x => x == ',');
- expression = new string(expression.TakeWhile(x => x != '(').ToArray());
-
- var tree = expression.Split('.').Select(x => x.Remove(@"\n|\r|\s|\t|\(|\)|\[|\]|<.*>")).ToList();
- var variableName = tree.FirstOrDefault();
-
- if (variableName != null && tree.Count > 1)
- {
- tree.RemoveAt(0);
- var variables = _parser.GetContextSymbols(Document.Text, CaretOffset);
- var variable = variableName;
-
- if (variable != null)
- {
- var knownType = _knownTypes.FirstOrDefault(x => x.FriendlyName == Regex.Replace(variable, "<.+>", "<T>"));
-
- if (knownType != null)
- {
- while (tree.Count > 1)
- {
- var memberName = tree.First();
- tree.RemoveAt(0);
- var member = knownType.Members.FirstOrDefault(x => x.Name == memberName);
-
- if (member == null)
- {
- return null;
- }
-
- knownType = _knownTypes.FirstOrDefault(x => x.Type.Namespace + "." + x.Type.Name == member.ReturnType.Namespace + "." + member.ReturnType.Name);
- }
-
- return new MethodSession()
- {
- Type = knownType,
- MethodName = tree.Last(),
- ParameterIndex = parameterIndex,
- };
- }
- }
- }
- }
-
- return null;
- }
-
private DeclaredMethodSession GetDeclaredMethodSession()
{
- var currentLine = GetCurrentLineText();
-
- if (currentLine.Count(x => x == '(') > 1)
- {
- currentLine = currentLine.Split('(')[currentLine.Split('(').Length - 2];
- }
-
- var words = currentLine.Split(' ');
+ var words = GetCurrentLineText().Split(' ');
if (words.Count() > 0 && (words.First() == "private" || words.First() == "public" || words.First() == "void"))
{
return null;
}
- var expression = currentLine;
+ var expression = GetPreviousWords().LastOrDefault();
if (expression != null)
{
@@ -2327,7 +1532,7 @@ namespace Tango.Scripting.Editors
if (variable != null)
{
- var declaredType = _declaredTypes.FirstOrDefault(x => x.Name == Regex.Replace(variable.Type, "<.+>", "<T>"));
+ var declaredType = _declaredTypes.FirstOrDefault(x => x.Name == Regex.Replace(variable.Class, "<.+>", "<T>"));
if (declaredType != null)
{
@@ -2386,413 +1591,5 @@ namespace Tango.Scripting.Editors
}
#endregion
-
- #region Reference Assemblies Changed
-
- private void OnReferenceAssembliesChanged()
- {
- if (ReferenceAssemblies != null)
- {
- ReferenceAssemblies.CollectionChanged -= ReferenceAssemblies_CollectionChanged;
- ReferenceAssemblies.CollectionChanged += ReferenceAssemblies_CollectionChanged;
-
- InvalidateHighlighting();
- }
- }
-
- private void ReferenceAssemblies_CollectionChanged(object sender, System.Collections.Specialized.NotifyCollectionChangedEventArgs e)
- {
- InvalidateHighlighting();
- }
-
- #endregion
-
- #region Public Methods
-
- public void FormatCode()
- {
- try
- {
- int index = CaretOffset;
- Document.BeginUpdate();
- IndentCode();
- Document.EndUpdate();
- CaretOffset = index;
- }
- catch
- {
- Debug.WriteLine("Error formatting code.");
- }
- }
-
- public void Highlight(int position, int length, int line)
- {
- Select(position, Math.Max(length, 1));
- ScrollToLine(line);
- }
-
- public void InsertCode(String code)
- {
- Document.Insert(TextArea.Caret.Offset, code);
- }
-
- public int Find(String text)
- {
- if (String.IsNullOrEmpty(text)) return -1;
-
- string txt = Document.Text;
- int index = txt.IndexOf(text, TextArea.Caret.Offset);
-
- if (index > -1)
- {
- Select(index, text.Length);
- ScrollToLine(TextArea.Selection.StartPosition.Line);
- }
- else
- {
- index = txt.IndexOf(text, 0);
-
- if (index > -1)
- {
- Select(index, text.Length);
- ScrollToLine(TextArea.Selection.StartPosition.Line);
- }
- else
- {
- Select(0, 0);
- System.Media.SystemSounds.Beep.Play();
- }
- }
-
- return index;
- }
-
- public int ReplaceNext(String text, String replace)
- {
- if (String.IsNullOrEmpty(text)) return -1;
-
- String selectedText = TextArea.Selection.GetText();
-
- if (selectedText == text)
- {
- TextArea.Selection.ReplaceSelectionWithText(replace);
- }
-
- return Find(text);
- }
-
- public int ReplaceAll(String text, String replace)
- {
- int counter = 0;
-
- Select(0, 0);
-
- while (ReplaceNext(text, replace) > -1)
- {
- counter++;
- };
-
- return counter;
- }
-
- public void ColorizeByKeyword(String text)
- {
- ResetColorizationByKeyword();
-
- if (String.IsNullOrEmpty(text)) return;
-
- var txt = Document.Text;
-
- var indexes = txt.AllIndexesOf(text).ToList();
-
- foreach (var index in indexes)
- {
- Document.BeginUpdate();
-
- var line = Document.GetLineByOffset(index);
-
- OffsetColorizer colorizer = new OffsetColorizer(line, index, index + text.Length, ColorizeBrush);
- TextArea.TextView.LineTransformers.Add(colorizer);
-
- Document.EndUpdate();
- }
- }
-
- public void ResetColorizationByKeyword()
- {
- Document.BeginUpdate();
-
- for (int i = 0; i < TextArea.TextView.LineTransformers.Count; i++)
- {
- if (TextArea.TextView.LineTransformers[i] is OffsetColorizer)
- {
- TextArea.TextView.LineTransformers.RemoveAt(i);
- i--;
- }
- }
-
- Document.EndUpdate();
- }
-
- public void HighlighError(int position, int length)
- {
- try
- {
- ITextMarker marker = errorMarkerService.Create(position, length);
- marker.MarkerTypes = TextMarkerTypes.SquigglyUnderline;
- marker.MarkerColor = Colors.Red;
- }
- catch (Exception ex)
- {
- Debug.WriteLine($"Error highlighting script error.\n{ex.ToString()}");
- }
- }
-
- public void ClearErrors()
- {
- errorMarkerService.RemoveAll(m => true);
- }
-
- public void HighlightErrorLine(int lineNumber)
- {
- Document.BeginUpdate();
-
- var line = Document.GetLineByNumber(lineNumber);
- OffsetColorizer errorLineColrizer = new OffsetColorizer(line, line.Offset, line.EndOffset, ErrorLineBrush);
- TextArea.TextView.LineTransformers.Add(errorLineColrizer);
-
- Document.EndUpdate();
- }
-
- public void HighlightDebugLine(int lineNumber)
- {
- Document.BeginUpdate();
-
- var line = Document.GetLineByNumber(lineNumber);
- OffsetColorizer errorLineColrizer = new OffsetColorizer(line, line.Offset, line.EndOffset, DebugLineBrush);
- TextArea.TextView.LineTransformers.Add(errorLineColrizer);
-
- Document.EndUpdate();
- }
-
- public void HighlightBreakPoint(int lineNumber, List<ScriptBreakPointSymbol> symbols)
- {
- _breakPointLineNumber = lineNumber;
- _breakPointSymbols = symbols.ToList();
- _currentBreakPointSymbol = null;
-
- Document.BeginUpdate();
-
- var line = Document.GetLineByNumber(lineNumber);
- OffsetColorizer errorLineColrizer = new OffsetColorizer(line, line.Offset, line.EndOffset, BreakPointLineBrush);
- TextArea.TextView.LineTransformers.Add(errorLineColrizer);
-
- var breakPoint = breakPointMargin.BreakPoints.FirstOrDefault(x => x.LineNumber == lineNumber);
- breakPoint.IsActive = true;
- breakPointMargin.InvalidateVisual();
-
- Document.EndUpdate();
- }
-
- public void ResetBreakPointLine()
- {
- _breakPointSymbols = new List<ScriptBreakPointSymbol>();
- _currentBreakPointSymbol = null;
- ResetColorizationByKeyword();
- breakPointMargin.BreakPoints.ToList().ForEach(x => x.IsActive = false);
- Mouse.OverrideCursor = null;
- ClearErrors();
- breakPointMargin.InvalidateVisual();
- }
-
- public Point? GetLineVisualPosition(int lineNumber)
- {
- double top = TextArea.TextView.GetVisualTopByDocumentLine(lineNumber);
- var visualLine = TextArea.TextView.GetVisualLine(lineNumber);
-
- if (visualLine != null)
- {
- var textLine = visualLine.GetTextLine(0);
- var x = visualLine.GetTextLineVisualXPosition(textLine, visualLine.VisualLengthWithEndOfLineMarker);
- var left = visualLine.VisualLengthWithEndOfLineMarker;
- return new Point(x, top);
- }
-
- return null;
- }
-
- public List<ScriptBreakPoint> GetBreakPoints()
- {
- List<ScriptBreakPoint> breakPoints = new List<ScriptBreakPoint>();
-
- foreach (var b in breakPointMargin.BreakPoints)
- {
- ScriptBreakPoint breakPoint = new ScriptBreakPoint();
- breakPoint.Script = ScriptSource;
- breakPoint.LineNumber = b.LineNumber;
-
- var line = Document.GetLineByNumber(b.LineNumber);
- breakPoint.LineStartOffset = line.Offset;
- breakPoint.LineEndOffset = line.EndOffset;
-
- var symbols = _parser.GetContextSymbols(Document.Text, line.Offset);
-
- foreach (var symbol in symbols.Where(x => (x.Kind == SymbolKind.Property || x.Kind == SymbolKind.Field || x.Kind == SymbolKind.Local || x.Kind == SymbolKind.Parameter) && !x.IsUnassigned))
- {
- if (symbol.Offset < line.Offset)
- {
- breakPoint.ContextSymbols.Add(new ScriptBreakPointSymbol()
- {
- Name = symbol.Name,
- Offset = symbol.Offset,
- Length = symbol.Length,
- });
- }
- }
-
- breakPoints.Add(breakPoint);
- }
-
- return breakPoints;
- }
-
- #endregion
-
- #region BreakPoint Symbols Search
-
- private void ScriptEditor_MouseMove(object sender, MouseEventArgs e)
- {
- if (IsReadOnly && _breakPointSymbols.Count > 0)
- {
- try
- {
- var word_separators_plus = word_separators.ToList();
- word_separators_plus.Add(')');
- word_separators_plus.Add(';');
-
- var textView = TextArea.TextView;
- Point position = e.GetPosition(textView);
- position.Y += textView.VerticalOffset;
- VisualLine visualLine = textView.GetVisualLineFromVisualTop(position.Y);
- int columnIndex = visualLine.GetVisualColumnFloor(position, false);
- String line = Document.GetText(visualLine.FirstDocumentLine.Offset, visualLine.FirstDocumentLine.Length);
- if (columnIndex < line.Length)
- {
- int wordStartIndex = columnIndex;
- int wordEndIndex = columnIndex;
-
- while (wordStartIndex > 0)
- {
- if (word_separators_plus.Contains(line[wordStartIndex])) break;
- wordStartIndex--;
- }
-
- while (wordEndIndex < line.Length)
- {
- if (word_separators_plus.Contains(line[wordEndIndex])) break;
- wordEndIndex++;
- }
-
- if (wordStartIndex > 0)
- {
- wordStartIndex++;
- }
-
- String word = line.Substring(wordStartIndex, wordEndIndex - wordStartIndex);
-
- var breakPointSymbol = _breakPointSymbols.FirstOrDefault(x => x.Name == word);
-
- if (breakPointSymbol != null)
- {
- int wordStartOffset = visualLine.FirstDocumentLine.Offset + wordStartIndex;
-
- ClearErrors();
- ITextMarker marker = errorMarkerService.Create(wordStartOffset, word.Length);
- marker.MarkerTypes = TextMarkerTypes.NormalUnderline;
- marker.MarkerColor = Colors.Yellow;
- Mouse.OverrideCursor = Cursors.Hand;
-
- _currentBreakPointSymbol = breakPointSymbol;
- _currentBreakPointSymbolPosition = visualLine.GetVisualPosition(wordEndIndex, VisualYPosition.LineTop);
- }
- else
- {
- _currentBreakPointSymbol = null;
- Mouse.OverrideCursor = null;
- ClearErrors();
- }
- }
- else
- {
- _currentBreakPointSymbol = null;
- Mouse.OverrideCursor = null;
- ClearErrors();
- }
- }
- catch (Exception ex)
- {
- _currentBreakPointSymbol = null;
- Mouse.OverrideCursor = null;
- ClearErrors();
- Debug.WriteLine(ex.Message);
- }
- }
- }
-
- protected override void OnPreviewMouseLeftButtonUp(MouseButtonEventArgs e)
- {
- base.OnPreviewMouseLeftButtonUp(e);
-
- if (_currentBreakPointSymbol != null)
- {
- Mouse.OverrideCursor = null;
- Debug.WriteLine($"Pressed on break point symbol: {_currentBreakPointSymbol.Name}");
- BreakPointSymbolPressed?.Invoke(this, new BreakPointSymbolPressedEventArgs()
- {
- BreakPointSymbol = _currentBreakPointSymbol,
- Position = _currentBreakPointSymbolPosition
- });
- }
- }
-
- public String GetCaretWord()
- {
- try
- {
- var word_separators_plus = word_separators.ToList();
- word_separators_plus.Add(')');
- word_separators_plus.Add(';');
-
- int wordStartOffset = CaretOffset;
- int wordEndOffset = CaretOffset;
-
- while (wordStartOffset > 0)
- {
- if (word_separators_plus.Contains(Document.Text[wordStartOffset])) break;
- wordStartOffset--;
- }
-
- while (wordEndOffset < Document.Text.Length)
- {
- if (word_separators_plus.Contains(Document.Text[wordEndOffset])) break;
- wordEndOffset++;
- }
-
- if (wordStartOffset > 0)
- {
- wordStartOffset++;
- }
-
- String word = Document.Text.Substring(wordStartOffset, wordEndOffset - wordStartOffset);
-
- return word;
- }
- catch
- {
- return null;
- }
- }
-
- #endregion
}
}
diff --git a/Software/Visual_Studio/Scripting/Tango.Scripting.Editors/Tango.Scripting.Editors.csproj b/Software/Visual_Studio/Scripting/Tango.Scripting.Editors/Tango.Scripting.Editors.csproj
index 11e023f86..ce7c361e3 100644
--- a/Software/Visual_Studio/Scripting/Tango.Scripting.Editors/Tango.Scripting.Editors.csproj
+++ b/Software/Visual_Studio/Scripting/Tango.Scripting.Editors/Tango.Scripting.Editors.csproj
@@ -77,9 +77,6 @@
<Reference Include="Microsoft.CodeAnalysis.CSharp, Version=2.4.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<HintPath>..\..\packages\Microsoft.CodeAnalysis.CSharp.2.4.0\lib\netstandard1.3\Microsoft.CodeAnalysis.CSharp.dll</HintPath>
</Reference>
- <Reference Include="Newtonsoft.Json, Version=9.0.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed, processorArchitecture=MSIL">
- <HintPath>..\..\packages\Newtonsoft.Json.9.0.1\lib\net45\Newtonsoft.Json.dll</HintPath>
- </Reference>
<Reference Include="PresentationCore">
<RequiredTargetFramework>3.0</RequiredTargetFramework>
</Reference>
@@ -180,9 +177,6 @@
<Link>GlobalVersionInfo.cs</Link>
</Compile>
<Compile Include="AvalonEditCommands.cs" />
- <Compile Include="BreakPointSymbolPressedEventArgs.cs" />
- <Compile Include="CachedAssembly.cs" />
- <Compile Include="CachedUsing.cs" />
<Compile Include="CodeCompletion\CompletionListBox.cs" />
<Compile Include="CodeCompletion\CompletionListBoxItem.cs" />
<Compile Include="CodeCompletion\CompletionWindowBase.cs" />
@@ -197,19 +191,14 @@
<Compile Include="CodeCompletion\OverloadViewer.cs" />
<Compile Include="Converters\BooleanToVisibilityConverter.cs" />
<Compile Include="Converters\BooleanToVisibilityInversedConverter.cs" />
- <Compile Include="Editing\BreakPointMargin.cs" />
- <Compile Include="Errors\ITextMarker.cs" />
- <Compile Include="Errors\TextMarkerService.cs" />
<Compile Include="ExtensionMethods.cs" />
<Compile Include="Intellisense\ClassCompletionItemPopup.cs" />
<Compile Include="Intellisense\CompletionItem.cs" />
<Compile Include="Intellisense\CompletionItemPopupControl.cs" />
<Compile Include="Intellisense\EnumCompletionItem.cs" />
<Compile Include="Intellisense\EnumCompletionItemPopup.cs" />
- <Compile Include="Intellisense\EventCompletionItem.cs" />
<Compile Include="Intellisense\FieldCompletionItem.cs" />
<Compile Include="Intellisense\FieldCompletionItemPopup.cs" />
- <Compile Include="Intellisense\HideIntellisenseAttribute.cs" />
<Compile Include="Intellisense\ICompletionItem.cs" />
<Compile Include="Intellisense\ICompletionProvider.cs" />
<Compile Include="Intellisense\InterfaceCompletionItem.cs" />
@@ -347,7 +336,6 @@
<Compile Include="Indentation\DefaultIndentationStrategy.cs" />
<Compile Include="Indentation\IIndentationStrategy.cs" />
<Compile Include="Intellisense\KnownTypeConstructor.cs" />
- <Compile Include="Intellisense\KnownTypeEvent.cs" />
<Compile Include="Intellisense\KnownTypeField.cs" />
<Compile Include="Intellisense\KnownTypeMember.cs" />
<Compile Include="Intellisense\KnownTypeMethodParameter.cs" />
@@ -360,7 +348,6 @@
<Compile Include="Intellisense\NamespaceCompletionItemPopup.cs" />
<Compile Include="Intellisense\PropertyCompletionItem.cs" />
<Compile Include="Intellisense\PropertyCompletionItemPopup.cs" />
- <Compile Include="Intellisense\SnippetCompletionItem.cs" />
<Compile Include="Intellisense\StructCompletionItem.cs" />
<Compile Include="Intellisense\StructCompletionItemPopup.cs" />
<Compile Include="Intellisense\Utils.cs" />
@@ -513,7 +500,6 @@
<Compile Include="Utils\ThrowUtil.cs" />
<Compile Include="Utils\Win32.cs" />
<CodeAnalysisDictionary Include="Properties\CodeAnalysisDictionary.xml" />
- <Compile Include="XamlEditor.cs" />
<Compile Include="Xml\AbstractAXmlVisitor.cs" />
<Compile Include="Xml\AXmlAttribute.cs" />
<Compile Include="Xml\AXmlAttributeCollection.cs" />
@@ -593,14 +579,6 @@
<Project>{a34ee0f0-649d-41c8-8489-b6f1cc6924ee}</Project>
<Name>Tango.Core</Name>
</ProjectReference>
- <ProjectReference Include="..\Tango.Scripting.Core\Tango.Scripting.Core.csproj">
- <Project>{5812E1C6-ABAA-4066-94AC-971C27B4F46A}</Project>
- <Name>Tango.Scripting.Core</Name>
- </ProjectReference>
- <ProjectReference Include="..\Tango.Scripting.Formatting\Tango.Scripting.Formatting.csproj">
- <Project>{8d8f06ed-7f75-4933-b0c5-829b0ff654d0}</Project>
- <Name>Tango.Scripting.Formatting</Name>
- </ProjectReference>
<ProjectReference Include="..\Tango.Scripting\Tango.Scripting.csproj">
<Project>{1e938fd2-c669-4738-98c9-77f96ce4d451}</Project>
<Name>Tango.Scripting</Name>
@@ -648,18 +626,9 @@
<Analyzer Include="..\..\packages\Microsoft.CodeAnalysis.Analyzers.1.1.0\analyzers\dotnet\cs\Microsoft.CodeAnalysis.Analyzers.dll" />
<Analyzer Include="..\..\packages\Microsoft.CodeAnalysis.Analyzers.1.1.0\analyzers\dotnet\cs\Microsoft.CodeAnalysis.CSharp.Analyzers.dll" />
</ItemGroup>
- <ItemGroup>
- <Resource Include="Images\event.png" />
- </ItemGroup>
- <ItemGroup>
- <Resource Include="Images\snippet.png" />
- </ItemGroup>
- <ItemGroup>
- <Resource Include="Images\break_point_arrow.png" />
- </ItemGroup>
<ProjectExtensions>
<VisualStudio>
- <UserProperties BuildVersion_StartDate="2000/1/1" BuildVersion_BuildVersioningStyle="None.None.Increment.TimeStamp" BuildVersion_UpdateAssemblyVersion="True" BuildVersion_AssemblyInfoFilename="Properties\AssemblyInfo.cs" BuildVersion_UseGlobalSettings="True" />
+ <UserProperties BuildVersion_UseGlobalSettings="True" BuildVersion_AssemblyInfoFilename="Properties\AssemblyInfo.cs" BuildVersion_UpdateAssemblyVersion="True" BuildVersion_BuildVersioningStyle="None.None.Increment.TimeStamp" BuildVersion_StartDate="2000/1/1" />
</VisualStudio>
</ProjectExtensions>
</Project> \ No newline at end of file
diff --git a/Software/Visual_Studio/Scripting/Tango.Scripting.Editors/Tango.Scripting.Editors_di35u2uj_wpftmp.csproj b/Software/Visual_Studio/Scripting/Tango.Scripting.Editors/Tango.Scripting.Editors_di35u2uj_wpftmp.csproj
deleted file mode 100644
index 70a4840c4..000000000
--- a/Software/Visual_Studio/Scripting/Tango.Scripting.Editors/Tango.Scripting.Editors_di35u2uj_wpftmp.csproj
+++ /dev/null
@@ -1,628 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
- <PropertyGroup>
- <ProjectGuid>{DA62FA39-668B-47A6-B0F2-D2C1DAF777B0}</ProjectGuid>
- <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
- <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
- <OutputType>Library</OutputType>
- <RootNamespace>Tango.Scripting.Editors</RootNamespace>
- <AssemblyName>Tango.Scripting.Editors</AssemblyName>
- <TargetFrameworkVersion>v4.6.1</TargetFrameworkVersion>
- <AppDesignerFolder>Properties</AppDesignerFolder>
- <SourceAnalysisOverrideSettingsFile>"C:\Program Files\SharpDevelop\3.0\bin\..\AddIns\AddIns\Misc\SourceAnalysis\Settings.SourceAnalysis"</SourceAnalysisOverrideSettingsFile>
- <AllowUnsafeBlocks>False</AllowUnsafeBlocks>
- <NoStdLib>False</NoStdLib>
- <WarningLevel>4</WarningLevel>
- <TreatWarningsAsErrors>false</TreatWarningsAsErrors>
- <SignAssembly>false</SignAssembly>
- <AssemblyOriginatorKeyFile>ICSharpCode.AvalonEdit.snk</AssemblyOriginatorKeyFile>
- <DelaySign>False</DelaySign>
- <AssemblyOriginatorKeyMode>File</AssemblyOriginatorKeyMode>
- <RunCodeAnalysis>False</RunCodeAnalysis>
- <CodeAnalysisRules>-Microsoft.Design#CA1020;-Microsoft.Design#CA1033;-Microsoft.Performance#CA1805;-Microsoft.Performance#CA1810</CodeAnalysisRules>
- <OutputPath>..\bin\$(Configuration)</OutputPath>
- <DocumentationFile>..\bin\$(Configuration)\ICSharpCode.AvalonEdit.xml</DocumentationFile>
- <NoWarn>1607</NoWarn>
- <TargetFrameworkProfile>
- </TargetFrameworkProfile>
- <SccProjectName>SAK</SccProjectName>
- <SccLocalPath>SAK</SccLocalPath>
- <SccAuxPath>SAK</SccAuxPath>
- <SccProvider>SAK</SccProvider>
- </PropertyGroup>
- <PropertyGroup Condition=" '$(Configuration)' == 'Debug' ">
- <DebugSymbols>true</DebugSymbols>
- <DebugType>Full</DebugType>
- <Optimize>False</Optimize>
- <CheckForOverflowUnderflow>True</CheckForOverflowUnderflow>
- <DefineConstants>DEBUG;TRACE;DOTNET4</DefineConstants>
- </PropertyGroup>
- <PropertyGroup Condition=" '$(Configuration)' == 'Release' ">
- <DebugSymbols>false</DebugSymbols>
- <DebugType>PdbOnly</DebugType>
- <Optimize>True</Optimize>
- <CheckForOverflowUnderflow>False</CheckForOverflowUnderflow>
- <DefineConstants>TRACE;DOTNET4</DefineConstants>
- </PropertyGroup>
- <PropertyGroup Condition=" '$(Platform)' == 'AnyCPU' ">
- <RegisterForComInterop>False</RegisterForComInterop>
- <GenerateSerializationAssemblies>Auto</GenerateSerializationAssemblies>
- <BaseAddress>4194304</BaseAddress>
- <PlatformTarget>AnyCPU</PlatformTarget>
- <FileAlignment>4096</FileAlignment>
- </PropertyGroup>
- <PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug|AnyCPU'">
- <OutputPath>..\..\Build\Scripting\Debug\</OutputPath>
- <DocumentationFile>
- </DocumentationFile>
- <Prefer32Bit>false</Prefer32Bit>
- <DefineConstants>TRACE;DEBUG</DefineConstants>
- </PropertyGroup>
- <PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Release|AnyCPU'">
- <Prefer32Bit>false</Prefer32Bit>
- <OutputPath>..\..\Build\Scripting\Release\</OutputPath>
- <DocumentationFile />
- </PropertyGroup>
- <PropertyGroup>
- <ProjectTypeGuids>{60dc8134-eba5-43b8-bcc9-bb4bc16c2548};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
- </PropertyGroup>
- <Import Project="$(MSBuildBinPath)\Microsoft.CSharp.Targets" />
- <ItemGroup>
- </ItemGroup>
- <ItemGroup>
- <Compile Include="..\..\Versioning\GlobalVersionInfo.cs">
- <Link>GlobalVersionInfo.cs</Link>
- </Compile>
- <Compile Include="AvalonEditCommands.cs" />
- <Compile Include="CachedAssembly.cs" />
- <Compile Include="CachedUsing.cs" />
- <Compile Include="CodeCompletion\CompletionListBox.cs" />
- <Compile Include="CodeCompletion\CompletionListBoxItem.cs" />
- <Compile Include="CodeCompletion\CompletionWindowBase.cs" />
- <Compile Include="CodeCompletion\CompletionList.cs" />
- <Compile Include="CodeCompletion\CompletionWindow.cs">
- <SubType>Code</SubType>
- </Compile>
- <Compile Include="CodeCompletion\ICompletionData.cs" />
- <Compile Include="CodeCompletion\InsightWindow.cs" />
- <Compile Include="CodeCompletion\IOverloadProvider.cs" />
- <Compile Include="CodeCompletion\OverloadInsightWindow.cs" />
- <Compile Include="CodeCompletion\OverloadViewer.cs" />
- <Compile Include="Converters\BooleanToVisibilityConverter.cs" />
- <Compile Include="Converters\BooleanToVisibilityInversedConverter.cs" />
- <Compile Include="Editing\BreakPoint.cs" />
- <Compile Include="Editing\BreakPointMargin.cs" />
- <Compile Include="Errors\ITextMarker.cs" />
- <Compile Include="Errors\TextMarkerService.cs" />
- <Compile Include="ExtensionMethods.cs" />
- <Compile Include="Intellisense\ClassCompletionItemPopup.cs" />
- <Compile Include="Intellisense\CompletionItem.cs" />
- <Compile Include="Intellisense\CompletionItemPopupControl.cs" />
- <Compile Include="Intellisense\EnumCompletionItem.cs" />
- <Compile Include="Intellisense\EnumCompletionItemPopup.cs" />
- <Compile Include="Intellisense\EventCompletionItem.cs" />
- <Compile Include="Intellisense\FieldCompletionItem.cs" />
- <Compile Include="Intellisense\FieldCompletionItemPopup.cs" />
- <Compile Include="Intellisense\ICompletionItem.cs" />
- <Compile Include="Intellisense\ICompletionProvider.cs" />
- <Compile Include="Intellisense\InterfaceCompletionItem.cs" />
- <Compile Include="Intellisense\InterfaceCompletionItemPopup.cs" />
- <Compile Include="Intellisense\KnownType.cs" />
- <Compile Include="Document\ChangeTrackingCheckpoint.cs" />
- <Compile Include="Document\DocumentChangeOperation.cs">
- <DependentUpon>UndoStack.cs</DependentUpon>
- </Compile>
- <Compile Include="Document\ILineTracker.cs" />
- <Compile Include="Document\ISegment.cs" />
- <Compile Include="Document\ITextSource.cs" />
- <Compile Include="Document\IUndoableOperation.cs">
- <DependentUpon>UndoStack.cs</DependentUpon>
- </Compile>
- <Compile Include="Document\LineNode.cs">
- <DependentUpon>DocumentLine.cs</DependentUpon>
- </Compile>
- <Compile Include="Document\NewLineFinder.cs" />
- <Compile Include="Document\OffsetChangeMap.cs" />
- <Compile Include="Document\TextDocumentWeakEventManager.cs">
- <DependentUpon>TextDocument.cs</DependentUpon>
- </Compile>
- <Compile Include="Document\TextSegmentCollection.cs" />
- <Compile Include="Document\TextAnchor.cs" />
- <Compile Include="Document\TextAnchorNode.cs">
- <DependentUpon>TextAnchor.cs</DependentUpon>
- </Compile>
- <Compile Include="Document\TextAnchorTree.cs">
- <DependentUpon>TextAnchor.cs</DependentUpon>
- </Compile>
- <Compile Include="Document\TextLocation.cs" />
- <Compile Include="Document\TextSegment.cs" />
- <Compile Include="Document\TextUtilities.cs" />
- <Compile Include="Document\UndoOperationGroup.cs">
- <DependentUpon>UndoStack.cs</DependentUpon>
- </Compile>
- <Compile Include="Document\UndoStack.cs">
- </Compile>
- <Compile Include="Document\WeakLineTracker.cs">
- <DependentUpon>ILineTracker.cs</DependentUpon>
- </Compile>
- <Compile Include="Editing\AbstractMargin.cs" />
- <Compile Include="Editing\Caret.cs" />
- <Compile Include="Editing\CaretLayer.cs">
- </Compile>
- <Compile Include="Editing\CaretNavigationCommandHandler.cs">
- </Compile>
- <Compile Include="Editing\CaretWeakEventHandler.cs" />
- <Compile Include="Editing\DottedLineMargin.cs" />
- <Compile Include="Editing\DragDropException.cs" />
- <Compile Include="Editing\EditingCommandHandler.cs" />
- <Compile Include="Editing\EmptySelection.cs">
- <DependentUpon>Selection.cs</DependentUpon>
- </Compile>
- <Compile Include="Editing\ImeNativeWrapper.cs" />
- <Compile Include="Editing\SelectionSegment.cs" />
- <Compile Include="Editing\ImeSupport.cs" />
- <Compile Include="Folding\AbstractFoldingStrategy.cs" />
- <Compile Include="Folding\BraceFoldingStrategy.cs" />
- <Compile Include="Folding\FoldingElementGenerator.cs" />
- <Compile Include="Folding\FoldingManager.cs" />
- <Compile Include="Folding\FoldingMargin.cs" />
- <Compile Include="Folding\FoldingMarginMarker.cs" />
- <Compile Include="Folding\FoldingSection.cs" />
- <Compile Include="Editing\IReadOnlySectionProvider.cs" />
- <Compile Include="Editing\LineNumberMargin.cs" />
- <Compile Include="Editing\NoReadOnlySections.cs">
- <DependentUpon>IReadOnlySectionProvider.cs</DependentUpon>
- </Compile>
- <Compile Include="Editing\RectangleSelection.cs">
- <DependentUpon>Selection.cs</DependentUpon>
- </Compile>
- <Compile Include="Editing\Selection.cs" />
- <Compile Include="Editing\SelectionColorizer.cs">
- <DependentUpon>Selection.cs</DependentUpon>
- </Compile>
- <Compile Include="Editing\SelectionLayer.cs">
- <DependentUpon>Selection.cs</DependentUpon>
- </Compile>
- <Compile Include="Editing\SelectionMouseHandler.cs">
- <DependentUpon>Selection.cs</DependentUpon>
- </Compile>
- <Compile Include="Editing\SimpleSelection.cs">
- <DependentUpon>Selection.cs</DependentUpon>
- </Compile>
- <Compile Include="Editing\TextArea.cs" />
- <Compile Include="Editing\TextAreaDefaultInputHandlers.cs" />
- <Compile Include="Editing\TextAreaInputHandler.cs" />
- <Compile Include="Editing\TextSegmentReadOnlySectionProvider.cs">
- <DependentUpon>IReadOnlySectionProvider.cs</DependentUpon>
- </Compile>
- <Compile Include="Folding\NewFolding.cs" />
- <Compile Include="Folding\XmlFoldingStrategy.cs" />
- <Compile Include="Highlighting\DocumentHighlighter.cs" />
- <Compile Include="Highlighting\HighlightedInlineBuilder.cs" />
- <Compile Include="Highlighting\HighlightedLine.cs" />
- <Compile Include="Highlighting\HighlightedSection.cs" />
- <Compile Include="Highlighting\HighlightingBrush.cs" />
- <Compile Include="Highlighting\HighlightingColor.cs" />
- <Compile Include="Highlighting\HighlightingColorizer.cs" />
- <Compile Include="Highlighting\HighlightingDefinitionInvalidException.cs" />
- <Compile Include="Highlighting\HighlightingDefinitionTypeConverter.cs" />
- <Compile Include="Highlighting\HighlightingManager.cs" />
- <Compile Include="Highlighting\HtmlClipboard.cs" />
- <Compile Include="Highlighting\IHighlighter.cs" />
- <Compile Include="Highlighting\IHighlightingDefinition.cs" />
- <Compile Include="Highlighting\HighlightingRule.cs" />
- <Compile Include="Highlighting\OffsetColorizer.cs" />
- <Compile Include="Highlighting\Resources\Resources.cs" />
- <Compile Include="Highlighting\HighlightingRuleSet.cs" />
- <Compile Include="Highlighting\HighlightingSpan.cs" />
- <Compile Include="Highlighting\IHighlightingDefinitionReferenceResolver.cs">
- </Compile>
- <Compile Include="Highlighting\Xshd\HighlightingLoader.cs" />
- <Compile Include="Highlighting\Xshd\IXshdVisitor.cs" />
- <Compile Include="Highlighting\Xshd\SaveXshdVisitor.cs" />
- <Compile Include="Highlighting\Xshd\V1Loader.cs" />
- <Compile Include="Highlighting\Xshd\V2Loader.cs" />
- <Compile Include="Highlighting\Xshd\XmlHighlightingDefinition.cs" />
- <Compile Include="Highlighting\Xshd\XshdColor.cs" />
- <Compile Include="Highlighting\Xshd\XshdImport.cs" />
- <Compile Include="Highlighting\Xshd\XshdProperty.cs" />
- <Compile Include="Highlighting\Xshd\XshdReference.cs" />
- <Compile Include="Highlighting\Xshd\XshdElement.cs" />
- <Compile Include="Highlighting\Xshd\XshdKeywords.cs" />
- <Compile Include="Highlighting\Xshd\XshdRule.cs" />
- <Compile Include="Highlighting\Xshd\XshdRuleSet.cs" />
- <Compile Include="Highlighting\Xshd\XshdSpan.cs" />
- <Compile Include="Highlighting\Xshd\XshdSyntaxDefinition.cs" />
- <Compile Include="Indentation\CSharp\CSharpIndentationHelper.cs" />
- <Compile Include="Indentation\CSharp\IndentationReformatter.cs" />
- <Compile Include="Indentation\CSharp\CSharpIndentationStrategy.cs" />
- <Compile Include="Indentation\CSharp\DocumentAccessor.cs" />
- <Compile Include="Indentation\DefaultIndentationStrategy.cs" />
- <Compile Include="Indentation\IIndentationStrategy.cs" />
- <Compile Include="Intellisense\KnownTypeConstructor.cs" />
- <Compile Include="Intellisense\KnownTypeEvent.cs" />
- <Compile Include="Intellisense\KnownTypeField.cs" />
- <Compile Include="Intellisense\KnownTypeMember.cs" />
- <Compile Include="Intellisense\KnownTypeMethodParameter.cs" />
- <Compile Include="Intellisense\KnownTypeMethod.cs" />
- <Compile Include="Intellisense\KnownTypeProperty.cs" />
- <Compile Include="Intellisense\ClassCompletionItem.cs" />
- <Compile Include="Intellisense\MethodCompletionItem.cs" />
- <Compile Include="Intellisense\MethodCompletionItemPopup.cs" />
- <Compile Include="Intellisense\NamespaceCompletionItem.cs" />
- <Compile Include="Intellisense\NamespaceCompletionItemPopup.cs" />
- <Compile Include="Intellisense\PropertyCompletionItem.cs" />
- <Compile Include="Intellisense\PropertyCompletionItemPopup.cs" />
- <Compile Include="Intellisense\SnippetCompletionItem.cs" />
- <Compile Include="Intellisense\StructCompletionItem.cs" />
- <Compile Include="Intellisense\StructCompletionItemPopup.cs" />
- <Compile Include="Intellisense\Utils.cs" />
- <Compile Include="Popups\MethodDescription.cs" />
- <Compile Include="Popups\MethodPopup.cs" />
- <Compile Include="Popups\ParameterDescription.cs" />
- <Compile Include="Rendering\BackgroundGeometryBuilder.cs">
- <DependentUpon>IBackgroundRenderer.cs</DependentUpon>
- </Compile>
- <Compile Include="Rendering\CollapsedLineSection.cs">
- <DependentUpon>HeightTree.cs</DependentUpon>
- </Compile>
- <Compile Include="Rendering\ColorizingTransformer.cs">
- <DependentUpon>IVisualLineTransformer.cs</DependentUpon>
- </Compile>
- <Compile Include="Rendering\ColumnRulerRenderer.cs" />
- <Compile Include="Rendering\DefaultTextRunTypographyProperties.cs" />
- <Compile Include="Rendering\DocumentColorizingTransformer.cs">
- <DependentUpon>IVisualLineTransformer.cs</DependentUpon>
- </Compile>
- <Compile Include="Rendering\FormattedTextElement.cs" />
- <Compile Include="Rendering\GlobalTextRunProperties.cs">
- <DependentUpon>TextView.cs</DependentUpon>
- </Compile>
- <Compile Include="Rendering\HeightTree.cs" />
- <Compile Include="Rendering\HeightTreeLineNode.cs">
- <DependentUpon>HeightTree.cs</DependentUpon>
- </Compile>
- <Compile Include="Rendering\HeightTreeNode.cs">
- <DependentUpon>HeightTree.cs</DependentUpon>
- </Compile>
- <Compile Include="Rendering\IBackgroundRenderer.cs" />
- <Compile Include="Rendering\InlineObjectRun.cs" />
- <Compile Include="Rendering\ITextRunConstructionContext.cs">
- <DependentUpon>VisualLineElementGenerator.cs</DependentUpon>
- </Compile>
- <Compile Include="Rendering\ITextViewConnect.cs">
- <DependentUpon>TextView.cs</DependentUpon>
- </Compile>
- <Compile Include="Rendering\IVisualLineTransformer.cs" />
- <Compile Include="Rendering\Layer.cs">
- <DependentUpon>TextView.cs</DependentUpon>
- </Compile>
- <Compile Include="Rendering\LayerPosition.cs">
- <DependentUpon>TextView.cs</DependentUpon>
- </Compile>
- <Compile Include="Rendering\LinkElementGenerator.cs" />
- <Compile Include="Rendering\MouseHoverLogic.cs" />
- <Compile Include="Rendering\SimpleTextSource.cs">
- <DependentUpon>FormattedTextElement.cs</DependentUpon>
- </Compile>
- <Compile Include="Rendering\SingleCharacterElementGenerator.cs" />
- <Compile Include="Rendering\TextLayer.cs">
- <DependentUpon>TextView.cs</DependentUpon>
- </Compile>
- <Compile Include="Rendering\TextView.cs" />
- <Compile Include="Rendering\TextViewCachedElements.cs" />
- <Compile Include="Rendering\TextViewWeakEventManager.cs">
- <DependentUpon>TextView.cs</DependentUpon>
- </Compile>
- <Compile Include="Rendering\VisualLine.cs" />
- <Compile Include="Rendering\VisualLineConstructionStartEventArgs.cs" />
- <Compile Include="Rendering\VisualLineElement.cs" />
- <Compile Include="Rendering\VisualLineElementGenerator.cs" />
- <Compile Include="Rendering\VisualLineElementTextRunProperties.cs">
- <DependentUpon>VisualLine.cs</DependentUpon>
- </Compile>
- <Compile Include="Rendering\VisualLineLinkText.cs" />
- <Compile Include="Rendering\VisualLinesInvalidException.cs" />
- <Compile Include="Rendering\VisualLineText.cs" />
- <Compile Include="Rendering\VisualLineTextParagraphProperties.cs">
- <DependentUpon>VisualLine.cs</DependentUpon>
- </Compile>
- <Compile Include="Rendering\VisualLineTextSource.cs">
- <DependentUpon>VisualLineElementGenerator.cs</DependentUpon>
- </Compile>
- <Compile Include="Rendering\VisualYPosition.cs">
- <DependentUpon>VisualLine.cs</DependentUpon>
- </Compile>
- <Compile Include="ScriptEditor.cs" />
- <Compile Include="Search\Localization.cs" />
- <Compile Include="Search\RegexSearchStrategy.cs" />
- <Compile Include="Search\DropDownButton.cs" />
- <Compile Include="Search\ISearchStrategy.cs" />
- <Compile Include="Search\SearchCommands.cs" />
- <Compile Include="Search\SearchResultBackgroundRenderer.cs" />
- <Compile Include="Search\SearchPanel.cs">
- <SubType>Code</SubType>
- </Compile>
- <Compile Include="Search\SearchStrategyFactory.cs" />
- <Compile Include="Snippets\IActiveElement.cs" />
- <Compile Include="Snippets\SnippetAnchorElement.cs" />
- <Compile Include="Snippets\SnippetEventArgs.cs" />
- <Compile Include="Snippets\SnippetInputHandler.cs" />
- <Compile Include="Snippets\Snippet.cs" />
- <Compile Include="Snippets\SnippetBoundElement.cs" />
- <Compile Include="Snippets\SnippetCaretElement.cs" />
- <Compile Include="Snippets\SnippetContainerElement.cs" />
- <Compile Include="Snippets\SnippetElement.cs" />
- <Compile Include="Snippets\InsertionContext.cs" />
- <Compile Include="Snippets\SnippetReplaceableTextElement.cs" />
- <Compile Include="Snippets\SnippetSelectionElement.cs" />
- <Compile Include="Snippets\SnippetTextElement.cs" />
- <Compile Include="TextEditor.cs" />
- <Compile Include="TextEditorAutomationPeer.cs" />
- <Compile Include="TextEditorComponent.cs">
- </Compile>
- <Compile Include="Properties\AssemblyInfo.cs" />
- <Compile Include="Document\DocumentChangeEventArgs.cs" />
- <Compile Include="Document\GapTextBuffer.cs">
- <DependentUpon>TextDocument.cs</DependentUpon>
- </Compile>
- <Compile Include="Document\LineManager.cs">
- <DependentUpon>TextDocument.cs</DependentUpon>
- </Compile>
- <Compile Include="Document\DocumentLine.cs" />
- <Compile Include="Document\DocumentLineTree.cs">
- <DependentUpon>DocumentLine.cs</DependentUpon>
- </Compile>
- <Compile Include="Document\TextDocument.cs" />
- <Compile Include="TextEditorOptions.cs" />
- <Compile Include="TextEditorWeakEventManager.cs">
- <DependentUpon>TextEditor.cs</DependentUpon>
- </Compile>
- <Compile Include="TextViewPosition.cs" />
- <Compile Include="Utils\Boxes.cs" />
- <Compile Include="Utils\BusyManager.cs">
- <DependentUpon>ObserveAddRemoveCollection.cs</DependentUpon>
- </Compile>
- <Compile Include="Utils\CharRope.cs" />
- <Compile Include="Utils\CompressingTreeList.cs" />
- <Compile Include="Utils\Constants.cs" />
- <Compile Include="Utils\DelayedEvents.cs" />
- <Compile Include="Utils\CallbackOnDispose.cs" />
- <Compile Include="Utils\Deque.cs" />
- <Compile Include="Utils\Empty.cs" />
- <Compile Include="Utils\ExtensionMethods.cs" />
- <Compile Include="Utils\FileReader.cs" />
- <Compile Include="Utils\ImmutableStack.cs" />
- <Compile Include="Utils\NullSafeCollection.cs" />
- <Compile Include="Utils\ObserveAddRemoveCollection.cs" />
- <Compile Include="Utils\PropertyChangedWeakEventManager.cs" />
- <Compile Include="Utils\Rope.cs" />
- <Compile Include="Utils\RopeNode.cs" />
- <Compile Include="Utils\RopeTextReader.cs" />
- <Compile Include="Utils\StringSegment.cs" />
- <Compile Include="Utils\TextFormatterFactory.cs" />
- <Compile Include="Utils\WeakEventManagerBase.cs" />
- <Compile Include="Utils\PixelSnapHelpers.cs" />
- <Compile Include="Utils\ThrowUtil.cs" />
- <Compile Include="Utils\Win32.cs" />
- <CodeAnalysisDictionary Include="Properties\CodeAnalysisDictionary.xml" />
- <Compile Include="XamlEditor.cs" />
- <Compile Include="Xml\AbstractAXmlVisitor.cs" />
- <Compile Include="Xml\AXmlAttribute.cs" />
- <Compile Include="Xml\AXmlAttributeCollection.cs" />
- <Compile Include="Xml\AXmlContainer.cs" />
- <Compile Include="Xml\AXmlDocument.cs" />
- <Compile Include="Xml\AXmlElement.cs" />
- <Compile Include="Xml\AXmlObject.cs" />
- <Compile Include="Xml\AXmlObjectCollection.cs" />
- <Compile Include="Xml\AXmlObjectEventArgs.cs" />
- <Compile Include="Xml\AXmlParser.cs" />
- <Compile Include="Xml\AXmlTag.cs" />
- <Compile Include="Xml\AXmlText.cs" />
- <Compile Include="Xml\CanonicalPrintAXmlVisitor.cs" />
- <Compile Include="Xml\InternalException.cs" />
- <Compile Include="Xml\TrackedSegmentCollection.cs">
- <DependentUpon>AXmlParser.cs</DependentUpon>
- </Compile>
- <Compile Include="Xml\ExtensionMethods.cs" />
- <Compile Include="Xml\FilteredCollection.cs" />
- <Compile Include="Xml\IAXmlVisitor.cs" />
- <Compile Include="Xml\MergedCollection.cs" />
- <Compile Include="Xml\PrettyPrintAXmlVisitor.cs" />
- <Compile Include="Xml\SyntaxError.cs" />
- <Compile Include="Xml\TagMatchingHeuristics.cs">
- <DependentUpon>AXmlParser.cs</DependentUpon>
- </Compile>
- <Compile Include="Xml\TagReader.cs">
- <DependentUpon>AXmlParser.cs</DependentUpon>
- </Compile>
- <Compile Include="Xml\TextType.cs">
- <DependentUpon>AXmlText.cs</DependentUpon>
- </Compile>
- <Compile Include="Xml\TokenReader.cs">
- <DependentUpon>AXmlParser.cs</DependentUpon>
- </Compile>
- <EmbeddedResource Include="Highlighting\Resources\ASPX.xshd" />
- <EmbeddedResource Include="Highlighting\Resources\Boo.xshd" />
- <EmbeddedResource Include="Highlighting\Resources\Coco-Mode.xshd" />
- <EmbeddedResource Include="Highlighting\Resources\CPP-Mode.xshd" />
- <EmbeddedResource Include="Highlighting\Resources\HTML-Mode.xshd" />
- <EmbeddedResource Include="Highlighting\Resources\Java-Mode.xshd" />
- <EmbeddedResource Include="Highlighting\Resources\JavaScript-Mode.xshd" />
- <EmbeddedResource Include="Highlighting\Resources\Patch-Mode.xshd" />
- <EmbeddedResource Include="Highlighting\Resources\PHP-Mode.xshd" />
- <EmbeddedResource Include="Highlighting\Resources\Tex-Mode.xshd" />
- <EmbeddedResource Include="Highlighting\Resources\VBNET-Mode.xshd" />
- <EmbeddedResource Include="Highlighting\Resources\XML-Mode.xshd" />
- <EmbeddedResource Include="Highlighting\Resources\ModeV1.xsd" />
- <EmbeddedResource Include="Highlighting\Resources\ModeV2.xsd" />
- <EmbeddedResource Include="Highlighting\Resources\CSharp-Mode.xshd" />
- <EmbeddedResource Include="Highlighting\Resources\XmlDoc.xshd" />
- </ItemGroup>
- <ItemGroup>
- </ItemGroup>
- <ItemGroup>
- <EmbeddedResource Include="Highlighting\Resources\CSS-Mode.xshd" />
- </ItemGroup>
- <ItemGroup>
- <ProjectReference Include="..\..\Tango.Core\Tango.Core.csproj">
- <Project>{a34ee0f0-649d-41c8-8489-b6f1cc6924ee}</Project>
- <Name>Tango.Core</Name>
- </ProjectReference>
- <ProjectReference Include="..\Tango.Scripting.Core\Tango.Scripting.Core.csproj">
- <Project>{5812E1C6-ABAA-4066-94AC-971C27B4F46A}</Project>
- <Name>Tango.Scripting.Core</Name>
- </ProjectReference>
- <ProjectReference Include="..\Tango.Scripting.Formatting\Tango.Scripting.Formatting.csproj">
- <Project>{8d8f06ed-7f75-4933-b0c5-829b0ff654d0}</Project>
- <Name>Tango.Scripting.Formatting</Name>
- </ProjectReference>
- <ProjectReference Include="..\Tango.Scripting\Tango.Scripting.csproj">
- <Project>{1e938fd2-c669-4738-98c9-77f96ce4d451}</Project>
- <Name>Tango.Scripting</Name>
- </ProjectReference>
- </ItemGroup>
- <ItemGroup>
- </ItemGroup>
- <ItemGroup>
- <EmbeddedResource Include="Highlighting\Resources\PowerShell.xshd" />
- </ItemGroup>
- <ItemGroup>
- <EmbeddedResource Include="Highlighting\Resources\MarkDown-Mode.xshd" />
- </ItemGroup>
- <ItemGroup>
- <None Include="app.config" />
- <None Include="packages.config" />
- </ItemGroup>
- <ItemGroup>
- </ItemGroup>
- <ItemGroup>
- </ItemGroup>
- <ItemGroup>
- </ItemGroup>
- <ItemGroup>
- </ItemGroup>
- <ItemGroup>
- </ItemGroup>
- <ItemGroup>
- </ItemGroup>
- <ItemGroup>
- </ItemGroup>
- <ItemGroup>
- </ItemGroup>
- <ItemGroup>
- <Analyzer Include="..\..\packages\Microsoft.CodeAnalysis.Analyzers.1.1.0\analyzers\dotnet\cs\Microsoft.CodeAnalysis.Analyzers.dll" />
- <Analyzer Include="..\..\packages\Microsoft.CodeAnalysis.Analyzers.1.1.0\analyzers\dotnet\cs\Microsoft.CodeAnalysis.CSharp.Analyzers.dll" />
- </ItemGroup>
- <ItemGroup>
- </ItemGroup>
- <ItemGroup>
- </ItemGroup>
- <ProjectExtensions>
- <VisualStudio>
- <UserProperties BuildVersion_UseGlobalSettings="True" BuildVersion_AssemblyInfoFilename="Properties\AssemblyInfo.cs" BuildVersion_UpdateAssemblyVersion="True" BuildVersion_BuildVersioningStyle="None.None.Increment.TimeStamp" BuildVersion_StartDate="2000/1/1" />
- </VisualStudio>
- </ProjectExtensions>
- <ItemGroup>
- <ReferencePath Include="C:\DATA\Development\Tango\Software\Visual_Studio\packages\FontAwesome.WPF.4.7.0.9\lib\net40\FontAwesome.WPF.dll" />
- <ReferencePath Include="C:\DATA\Development\Tango\Software\Visual_Studio\packages\Microsoft.CodeAnalysis.CSharp.2.4.0\lib\netstandard1.3\Microsoft.CodeAnalysis.CSharp.dll" />
- <ReferencePath Include="C:\DATA\Development\Tango\Software\Visual_Studio\packages\Microsoft.CodeAnalysis.Common.2.4.0\lib\netstandard1.3\Microsoft.CodeAnalysis.dll" />
- <ReferencePath Include="C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.6.1\mscorlib.dll" />
- <ReferencePath Include="C:\DATA\Development\Tango\Software\Visual_Studio\packages\Newtonsoft.Json.9.0.1\lib\net45\Newtonsoft.Json.dll" />
- <ReferencePath Include="C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.6.1\PresentationCore.dll" />
- <ReferencePath Include="C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.6.1\PresentationFramework.dll" />
- <ReferencePath Include="C:\DATA\Development\Tango\Software\Visual_Studio\packages\System.AppContext.4.3.0\lib\net46\System.AppContext.dll" />
- <ReferencePath Include="C:\DATA\Development\Tango\Software\Visual_Studio\packages\System.Collections.Immutable.1.3.1\lib\portable-net45+win8+wp8+wpa81\System.Collections.Immutable.dll" />
- <ReferencePath Include="C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.6.1\System.ComponentModel.Composition.dll" />
- <ReferencePath Include="C:\DATA\Development\Tango\Software\Visual_Studio\packages\System.Console.4.3.0\lib\net46\System.Console.dll" />
- <ReferencePath Include="C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.6.1\System.Core.dll" />
- <ReferencePath Include="C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.6.1\System.Data.DataSetExtensions.dll" />
- <ReferencePath Include="C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.6.1\System.Data.dll" />
- <ReferencePath Include="C:\DATA\Development\Tango\Software\Visual_Studio\packages\System.Diagnostics.FileVersionInfo.4.3.0\lib\net46\System.Diagnostics.FileVersionInfo.dll" />
- <ReferencePath Include="C:\DATA\Development\Tango\Software\Visual_Studio\packages\System.Diagnostics.StackTrace.4.3.0\lib\net46\System.Diagnostics.StackTrace.dll" />
- <ReferencePath Include="C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.6.1\System.dll" />
- <ReferencePath Include="C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.6.1\System.Drawing.dll" />
- <ReferencePath Include="C:\DATA\Development\Tango\Software\Visual_Studio\packages\System.IO.Compression.4.3.0\lib\net46\System.IO.Compression.dll" />
- <ReferencePath Include="C:\DATA\Development\Tango\Software\Visual_Studio\packages\System.IO.FileSystem.4.3.0\lib\net46\System.IO.FileSystem.dll" />
- <ReferencePath Include="C:\DATA\Development\Tango\Software\Visual_Studio\packages\System.IO.FileSystem.Primitives.4.3.0\lib\net46\System.IO.FileSystem.Primitives.dll" />
- <ReferencePath Include="C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.6.1\System.Numerics.dll" />
- <ReferencePath Include="C:\DATA\Development\Tango\Software\Visual_Studio\packages\System.Reflection.Metadata.1.4.2\lib\portable-net45+win8\System.Reflection.Metadata.dll" />
- <ReferencePath Include="C:\DATA\Development\Tango\Software\Visual_Studio\packages\System.Security.Cryptography.Algorithms.4.3.0\lib\net461\System.Security.Cryptography.Algorithms.dll" />
- <ReferencePath Include="C:\DATA\Development\Tango\Software\Visual_Studio\packages\System.Security.Cryptography.Encoding.4.3.0\lib\net46\System.Security.Cryptography.Encoding.dll" />
- <ReferencePath Include="C:\DATA\Development\Tango\Software\Visual_Studio\packages\System.Security.Cryptography.Primitives.4.3.0\lib\net46\System.Security.Cryptography.Primitives.dll" />
- <ReferencePath Include="C:\DATA\Development\Tango\Software\Visual_Studio\packages\System.Security.Cryptography.X509Certificates.4.3.0\lib\net461\System.Security.Cryptography.X509Certificates.dll" />
- <ReferencePath Include="C:\DATA\Development\Tango\Software\Visual_Studio\packages\System.Text.Encoding.CodePages.4.3.0\lib\net46\System.Text.Encoding.CodePages.dll" />
- <ReferencePath Include="C:\DATA\Development\Tango\Software\Visual_Studio\packages\System.Threading.Thread.4.3.0\lib\net46\System.Threading.Thread.dll" />
- <ReferencePath Include="C:\DATA\Development\Tango\Software\Visual_Studio\packages\System.ValueTuple.4.3.0\lib\netstandard1.0\System.ValueTuple.dll" />
- <ReferencePath Include="C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.6.1\System.Windows.Forms.dll" />
- <ReferencePath Include="C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.6.1\System.Xaml.dll" />
- <ReferencePath Include="C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.6.1\System.Xml.dll" />
- <ReferencePath Include="C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.6.1\System.Xml.Linq.dll" />
- <ReferencePath Include="C:\DATA\Development\Tango\Software\Visual_Studio\packages\System.Xml.ReaderWriter.4.3.0\lib\net46\System.Xml.ReaderWriter.dll" />
- <ReferencePath Include="C:\DATA\Development\Tango\Software\Visual_Studio\packages\System.Xml.XmlDocument.4.3.0\lib\net46\System.Xml.XmlDocument.dll" />
- <ReferencePath Include="C:\DATA\Development\Tango\Software\Visual_Studio\packages\System.Xml.XPath.4.3.0\lib\net46\System.Xml.XPath.dll" />
- <ReferencePath Include="C:\DATA\Development\Tango\Software\Visual_Studio\packages\System.Xml.XPath.XDocument.4.3.0\lib\net46\System.Xml.XPath.XDocument.dll" />
- <ReferencePath Include="C:\DATA\Development\Tango\Software\Visual_Studio\Build\Core\Debug\Tango.Core.dll" />
- <ReferencePath Include="C:\DATA\Development\Tango\Software\Visual_Studio\Scripting\Tango.Scripting.Core\bin\Debug\Tango.Scripting.Core.dll" />
- <ReferencePath Include="C:\DATA\Development\Tango\Software\Visual_Studio\Build\Scripting\Debug\Tango.Scripting.dll" />
- <ReferencePath Include="C:\DATA\Development\Tango\Software\Visual_Studio\Scripting\Tango.Scripting.Formatting\bin\Debug\Tango.Scripting.Formatting.dll" />
- <ReferencePath Include="C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.6.1\UIAutomationProvider.dll" />
- <ReferencePath Include="C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.6.1\UIAutomationTypes.dll" />
- <ReferencePath Include="C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.6.1\WindowsBase.dll" />
- <ReferencePath Include="C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.6.1\Facades\System.Collections.Concurrent.dll" />
- <ReferencePath Include="C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.6.1\Facades\System.Collections.dll" />
- <ReferencePath Include="C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.6.1\Facades\System.ComponentModel.Annotations.dll" />
- <ReferencePath Include="C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.6.1\Facades\System.ComponentModel.dll" />
- <ReferencePath Include="C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.6.1\Facades\System.ComponentModel.EventBasedAsync.dll" />
- <ReferencePath Include="C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.6.1\Facades\System.Diagnostics.Contracts.dll" />
- <ReferencePath Include="C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.6.1\Facades\System.Diagnostics.Debug.dll" />
- <ReferencePath Include="C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.6.1\Facades\System.Diagnostics.Tools.dll" />
- <ReferencePath Include="C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.6.1\Facades\System.Diagnostics.Tracing.dll" />
- <ReferencePath Include="C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.6.1\Facades\System.Dynamic.Runtime.dll" />
- <ReferencePath Include="C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.6.1\Facades\System.Globalization.dll" />
- <ReferencePath Include="C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.6.1\Facades\System.IO.dll" />
- <ReferencePath Include="C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.6.1\Facades\System.Linq.dll" />
- <ReferencePath Include="C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.6.1\Facades\System.Linq.Expressions.dll" />
- <ReferencePath Include="C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.6.1\Facades\System.Linq.Parallel.dll" />
- <ReferencePath Include="C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.6.1\Facades\System.Linq.Queryable.dll" />
- <ReferencePath Include="C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.6.1\Facades\System.Net.NetworkInformation.dll" />
- <ReferencePath Include="C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.6.1\Facades\System.Net.Primitives.dll" />
- <ReferencePath Include="C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.6.1\Facades\System.Net.Requests.dll" />
- <ReferencePath Include="C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.6.1\Facades\System.Net.WebHeaderCollection.dll" />
- <ReferencePath Include="C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.6.1\Facades\System.ObjectModel.dll" />
- <ReferencePath Include="C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.6.1\Facades\System.Reflection.dll" />
- <ReferencePath Include="C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.6.1\Facades\System.Reflection.Emit.dll" />
- <ReferencePath Include="C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.6.1\Facades\System.Reflection.Emit.ILGeneration.dll" />
- <ReferencePath Include="C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.6.1\Facades\System.Reflection.Emit.Lightweight.dll" />
- <ReferencePath Include="C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.6.1\Facades\System.Reflection.Extensions.dll" />
- <ReferencePath Include="C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.6.1\Facades\System.Reflection.Primitives.dll" />
- <ReferencePath Include="C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.6.1\Facades\System.Resources.ResourceManager.dll" />
- <ReferencePath Include="C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.6.1\Facades\System.Runtime.dll" />
- <ReferencePath Include="C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.6.1\Facades\System.Runtime.Extensions.dll" />
- <ReferencePath Include="C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.6.1\Facades\System.Runtime.Handles.dll" />
- <ReferencePath Include="C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.6.1\Facades\System.Runtime.InteropServices.dll" />
- <ReferencePath Include="C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.6.1\Facades\System.Runtime.InteropServices.WindowsRuntime.dll" />
- <ReferencePath Include="C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.6.1\Facades\System.Runtime.Numerics.dll" />
- <ReferencePath Include="C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.6.1\Facades\System.Runtime.Serialization.Json.dll" />
- <ReferencePath Include="C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.6.1\Facades\System.Runtime.Serialization.Primitives.dll" />
- <ReferencePath Include="C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.6.1\Facades\System.Runtime.Serialization.Xml.dll" />
- <ReferencePath Include="C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.6.1\Facades\System.Security.Principal.dll" />
- <ReferencePath Include="C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.6.1\Facades\System.ServiceModel.Duplex.dll" />
- <ReferencePath Include="C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.6.1\Facades\System.ServiceModel.Http.dll" />
- <ReferencePath Include="C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.6.1\Facades\System.ServiceModel.NetTcp.dll" />
- <ReferencePath Include="C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.6.1\Facades\System.ServiceModel.Primitives.dll" />
- <ReferencePath Include="C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.6.1\Facades\System.ServiceModel.Security.dll" />
- <ReferencePath Include="C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.6.1\Facades\System.Text.Encoding.dll" />
- <ReferencePath Include="C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.6.1\Facades\System.Text.Encoding.Extensions.dll" />
- <ReferencePath Include="C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.6.1\Facades\System.Text.RegularExpressions.dll" />
- <ReferencePath Include="C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.6.1\Facades\System.Threading.dll" />
- <ReferencePath Include="C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.6.1\Facades\System.Threading.Tasks.dll" />
- <ReferencePath Include="C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.6.1\Facades\System.Threading.Tasks.Parallel.dll" />
- <ReferencePath Include="C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.6.1\Facades\System.Threading.Timer.dll" />
- <ReferencePath Include="C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.6.1\Facades\System.Xml.XDocument.dll" />
- <ReferencePath Include="C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.6.1\Facades\System.Xml.XmlSerializer.dll" />
- </ItemGroup>
- <ItemGroup>
- <Compile Include="C:\DATA\Development\Tango\Software\Visual_Studio\Scripting\Tango.Scripting.Editors\obj\Debug\GeneratedInternalTypeHelper.g.cs" />
- </ItemGroup>
-</Project> \ No newline at end of file
diff --git a/Software/Visual_Studio/Scripting/Tango.Scripting.Editors/TextEditor.cs b/Software/Visual_Studio/Scripting/Tango.Scripting.Editors/TextEditor.cs
index cd9977520..d2fc9e02b 100644
--- a/Software/Visual_Studio/Scripting/Tango.Scripting.Editors/TextEditor.cs
+++ b/Software/Visual_Studio/Scripting/Tango.Scripting.Editors/TextEditor.cs
@@ -3,7 +3,6 @@
using System;
using System.ComponentModel;
-using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Text;
@@ -25,1229 +24,1121 @@ using Tango.Scripting.Editors.Utils;
namespace Tango.Scripting.Editors
{
- /// <summary>
- /// The text editor control.
- /// Contains a scrollable TextArea.
- /// </summary>
- [Localizability(LocalizationCategory.Text), ContentProperty("Text")]
- public class TextEditor : Control, ITextEditorComponent, IServiceProvider, IWeakEventListener
- {
- #region Constructors
- static TextEditor()
- {
- DefaultStyleKeyProperty.OverrideMetadata(typeof(TextEditor),
- new FrameworkPropertyMetadata(typeof(TextEditor)));
- FocusableProperty.OverrideMetadata(typeof(TextEditor),
- new FrameworkPropertyMetadata(Boxes.True));
- }
-
- /// <summary>
- /// Creates a new TextEditor instance.
- /// </summary>
- public TextEditor() : this(new TextArea())
- {
- }
-
- /// <summary>
- /// Creates a new TextEditor instance.
- /// </summary>
- protected TextEditor(TextArea textArea)
- {
- if (textArea == null)
- throw new ArgumentNullException("textArea");
- this.textArea = textArea;
-
- textArea.TextView.Services.AddService(typeof(TextEditor), this);
-
- SetCurrentValue(OptionsProperty, textArea.Options);
- SetCurrentValue(DocumentProperty, new TextDocument());
- }
-
- #endregion
-
- /// <inheritdoc/>
- protected override System.Windows.Automation.Peers.AutomationPeer OnCreateAutomationPeer()
- {
- return new TextEditorAutomationPeer(this);
- }
-
- /// Forward focus to TextArea.
- /// <inheritdoc/>
- protected override void OnGotKeyboardFocus(KeyboardFocusChangedEventArgs e)
- {
- base.OnGotKeyboardFocus(e);
- if (e.NewFocus == this)
- {
- Keyboard.Focus(this.TextArea);
- e.Handled = true;
- }
- }
-
- #region Document property
- /// <summary>
- /// Document property.
- /// </summary>
- public static readonly DependencyProperty DocumentProperty
- = TextView.DocumentProperty.AddOwner(
- typeof(TextEditor), new FrameworkPropertyMetadata(OnDocumentChanged));
-
- /// <summary>
- /// Gets/Sets the document displayed by the text editor.
- /// This is a dependency property.
- /// </summary>
- public TextDocument Document
- {
- get { return (TextDocument)GetValue(DocumentProperty); }
- set { SetValue(DocumentProperty, value); }
- }
-
- /// <summary>
- /// Occurs when the document property has changed.
- /// </summary>
- public event EventHandler DocumentChanged;
-
- /// <summary>
- /// Raises the <see cref="DocumentChanged"/> event.
- /// </summary>
- protected virtual void OnDocumentChanged(EventArgs e)
- {
- if (DocumentChanged != null)
- {
- DocumentChanged(this, e);
- }
- }
-
- static void OnDocumentChanged(DependencyObject dp, DependencyPropertyChangedEventArgs e)
- {
- ((TextEditor)dp).OnDocumentChanged((TextDocument)e.OldValue, (TextDocument)e.NewValue);
- }
-
- void OnDocumentChanged(TextDocument oldValue, TextDocument newValue)
- {
- if (oldValue != null)
- {
- TextDocumentWeakEventManager.TextChanged.RemoveListener(oldValue, this);
- PropertyChangedEventManager.RemoveListener(oldValue.UndoStack, this, "IsOriginalFile");
- }
- textArea.Document = newValue;
- if (newValue != null)
- {
- TextDocumentWeakEventManager.TextChanged.AddListener(newValue, this);
- PropertyChangedEventManager.AddListener(newValue.UndoStack, this, "IsOriginalFile");
- }
- OnDocumentChanged(EventArgs.Empty);
- OnTextChanged(EventArgs.Empty);
- }
- #endregion
-
- #region Options property
- /// <summary>
- /// Options property.
- /// </summary>
- public static readonly DependencyProperty OptionsProperty
- = TextView.OptionsProperty.AddOwner(typeof(TextEditor), new FrameworkPropertyMetadata(OnOptionsChanged));
-
- /// <summary>
- /// Gets/Sets the options currently used by the text editor.
- /// </summary>
- public TextEditorOptions Options
- {
- get { return (TextEditorOptions)GetValue(OptionsProperty); }
- set { SetValue(OptionsProperty, value); }
- }
-
- /// <summary>
- /// Occurs when a text editor option has changed.
- /// </summary>
- public event PropertyChangedEventHandler OptionChanged;
-
- /// <summary>
- /// Raises the <see cref="OptionChanged"/> event.
- /// </summary>
- protected virtual void OnOptionChanged(PropertyChangedEventArgs e)
- {
- if (OptionChanged != null)
- {
- OptionChanged(this, e);
- }
- }
-
- static void OnOptionsChanged(DependencyObject dp, DependencyPropertyChangedEventArgs e)
- {
- ((TextEditor)dp).OnOptionsChanged((TextEditorOptions)e.OldValue, (TextEditorOptions)e.NewValue);
- }
-
- void OnOptionsChanged(TextEditorOptions oldValue, TextEditorOptions newValue)
- {
- if (oldValue != null)
- {
- PropertyChangedWeakEventManager.RemoveListener(oldValue, this);
- }
- textArea.Options = newValue;
- if (newValue != null)
- {
- PropertyChangedWeakEventManager.AddListener(newValue, this);
- }
- OnOptionChanged(new PropertyChangedEventArgs(null));
- }
-
- /// <inheritdoc cref="IWeakEventListener.ReceiveWeakEvent"/>
- protected virtual bool ReceiveWeakEvent(Type managerType, object sender, EventArgs e)
- {
- if (managerType == typeof(PropertyChangedWeakEventManager))
- {
- OnOptionChanged((PropertyChangedEventArgs)e);
- return true;
- }
- else if (managerType == typeof(TextDocumentWeakEventManager.TextChanged))
- {
- OnTextChanged(e);
- return true;
- }
- else if (managerType == typeof(PropertyChangedEventManager))
- {
- return HandleIsOriginalChanged((PropertyChangedEventArgs)e);
- }
- return false;
- }
-
- bool IWeakEventListener.ReceiveWeakEvent(Type managerType, object sender, EventArgs e)
- {
- return ReceiveWeakEvent(managerType, sender, e);
- }
- #endregion
-
- #region Text property
- /// <summary>
- /// Gets/Sets the text of the current document.
- /// </summary>
- [Localizability(LocalizationCategory.Text), DefaultValue("")]
- public string Text
- {
- get
- {
- TextDocument document = this.Document;
- return document != null ? document.Text : string.Empty;
- }
- set
- {
- TextDocument document = GetDocument();
- document.Text = value ?? string.Empty;
- // after replacing the full text, the caret is positioned at the end of the document
- // - reset it to the beginning.
- this.CaretOffset = 0;
- document.UndoStack.ClearAll();
- }
- }
-
- TextDocument GetDocument()
- {
- TextDocument document = this.Document;
- if (document == null)
- throw ThrowUtil.NoDocumentAssigned();
- return document;
- }
-
- /// <summary>
- /// Occurs when the Text property changes.
- /// </summary>
- public event EventHandler TextChanged;
-
- /// <summary>
- /// Raises the <see cref="TextChanged"/> event.
- /// </summary>
- protected virtual void OnTextChanged(EventArgs e)
- {
- if (TextChanged != null)
- {
- TextChanged(this, e);
- }
- }
- #endregion
-
- #region TextArea / ScrollViewer properties
- readonly TextArea textArea;
- ScrollViewer scrollViewer;
-
- /// <summary>
- /// Is called after the template was applied.
- /// </summary>
- public override void OnApplyTemplate()
- {
- base.OnApplyTemplate();
- scrollViewer = (ScrollViewer)Template.FindName("PART_ScrollViewer", this);
- }
-
- /// <summary>
- /// Gets the text area.
- /// </summary>
- public TextArea TextArea
- {
- get
- {
- return textArea;
- }
- }
-
- /// <summary>
- /// Gets the scroll viewer used by the text editor.
- /// This property can return null if the template has not been applied / does not contain a scroll viewer.
- /// </summary>
- internal ScrollViewer ScrollViewer
- {
- get { return scrollViewer; }
- }
-
- bool CanExecute(RoutedUICommand command)
- {
- TextArea textArea = this.TextArea;
- if (textArea == null)
- return false;
- else
- return command.CanExecute(null, textArea);
- }
-
- void Execute(RoutedUICommand command)
- {
- TextArea textArea = this.TextArea;
- if (textArea != null)
- command.Execute(null, textArea);
- }
- #endregion
-
- #region Syntax highlighting
- /// <summary>
- /// The <see cref="SyntaxHighlighting"/> property.
- /// </summary>
- public static readonly DependencyProperty SyntaxHighlightingProperty =
- DependencyProperty.Register("SyntaxHighlighting", typeof(IHighlightingDefinition), typeof(TextEditor),
- new FrameworkPropertyMetadata(OnSyntaxHighlightingChanged));
-
-
- /// <summary>
- /// Gets/sets the syntax highlighting definition used to colorize the text.
- /// </summary>
- public IHighlightingDefinition SyntaxHighlighting
- {
- get { return (IHighlightingDefinition)GetValue(SyntaxHighlightingProperty); }
- set { SetValue(SyntaxHighlightingProperty, value); }
- }
-
- IVisualLineTransformer colorizer;
-
- static void OnSyntaxHighlightingChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
- {
- ((TextEditor)d).OnSyntaxHighlightingChanged(e.NewValue as IHighlightingDefinition);
- }
-
- void OnSyntaxHighlightingChanged(IHighlightingDefinition newValue)
- {
- if (colorizer != null)
- {
- this.TextArea.TextView.LineTransformers.Remove(colorizer);
- colorizer = null;
- }
- if (newValue != null)
- {
- colorizer = CreateColorizer(newValue);
- this.TextArea.TextView.LineTransformers.Insert(0, colorizer);
- }
- }
-
- /// <summary>
- /// Creates the highlighting colorizer for the specified highlighting definition.
- /// Allows derived classes to provide custom colorizer implementations for special highlighting definitions.
- /// </summary>
- /// <returns></returns>
- protected virtual IVisualLineTransformer CreateColorizer(IHighlightingDefinition highlightingDefinition)
- {
- if (highlightingDefinition == null)
- throw new ArgumentNullException("highlightingDefinition");
- return new HighlightingColorizer(highlightingDefinition.MainRuleSet);
- }
- #endregion
-
- #region WordWrap
- /// <summary>
- /// Word wrap dependency property.
- /// </summary>
- public static readonly DependencyProperty WordWrapProperty =
- DependencyProperty.Register("WordWrap", typeof(bool), typeof(TextEditor),
- new FrameworkPropertyMetadata(Boxes.False));
-
- /// <summary>
- /// Specifies whether the text editor uses word wrapping.
- /// </summary>
- /// <remarks>
- /// Setting WordWrap=true has the same effect as setting HorizontalScrollBarVisibility=Disabled and will override the
- /// HorizontalScrollBarVisibility setting.
- /// </remarks>
- public bool WordWrap
- {
- get { return (bool)GetValue(WordWrapProperty); }
- set { SetValue(WordWrapProperty, Boxes.Box(value)); }
- }
- #endregion
-
- #region IsReadOnly
- /// <summary>
- /// IsReadOnly dependency property.
- /// </summary>
- public static readonly DependencyProperty IsReadOnlyProperty =
- DependencyProperty.Register("IsReadOnly", typeof(bool), typeof(TextEditor),
- new FrameworkPropertyMetadata(Boxes.False, OnIsReadOnlyChanged));
-
- /// <summary>
- /// Specifies whether the user can change the text editor content.
- /// Setting this property will replace the
- /// <see cref="Editing.TextArea.ReadOnlySectionProvider">TextArea.ReadOnlySectionProvider</see>.
- /// </summary>
- public bool IsReadOnly
- {
- get { return (bool)GetValue(IsReadOnlyProperty); }
- set { SetValue(IsReadOnlyProperty, Boxes.Box(value)); }
- }
-
- static void OnIsReadOnlyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
- {
- TextEditor editor = d as TextEditor;
- if (editor != null)
- {
- if ((bool)e.NewValue)
- editor.TextArea.ReadOnlySectionProvider = ReadOnlyDocument.Instance;
- else
- editor.TextArea.ReadOnlySectionProvider = NoReadOnlySections.Instance;
-
- TextEditorAutomationPeer peer = TextEditorAutomationPeer.FromElement(editor) as TextEditorAutomationPeer;
- if (peer != null)
- {
- peer.RaiseIsReadOnlyChanged((bool)e.OldValue, (bool)e.NewValue);
- }
- }
- }
- #endregion
-
- #region IsModified
- /// <summary>
- /// Dependency property for <see cref="IsModified"/>
- /// </summary>
- public static readonly DependencyProperty IsModifiedProperty =
- DependencyProperty.Register("IsModified", typeof(bool), typeof(TextEditor),
- new FrameworkPropertyMetadata(Boxes.False, OnIsModifiedChanged));
-
- /// <summary>
- /// Gets/Sets the 'modified' flag.
- /// </summary>
- public bool IsModified
- {
- get { return (bool)GetValue(IsModifiedProperty); }
- set { SetValue(IsModifiedProperty, Boxes.Box(value)); }
- }
-
- static void OnIsModifiedChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
- {
- TextEditor editor = d as TextEditor;
- if (editor != null)
- {
- TextDocument document = editor.Document;
- if (document != null)
- {
- UndoStack undoStack = document.UndoStack;
- if ((bool)e.NewValue)
- {
- if (undoStack.IsOriginalFile)
- undoStack.DiscardOriginalFileMarker();
- }
- else
- {
- undoStack.MarkAsOriginalFile();
- }
- }
- }
- }
-
- bool HandleIsOriginalChanged(PropertyChangedEventArgs e)
- {
- if (e.PropertyName == "IsOriginalFile")
- {
- TextDocument document = this.Document;
- if (document != null)
- {
- SetCurrentValue(IsModifiedProperty, Boxes.Box(!document.UndoStack.IsOriginalFile));
- }
- return true;
- }
- else
- {
- return false;
- }
- }
- #endregion
-
- #region ShowLineNumbers
- /// <summary>
- /// ShowLineNumbers dependency property.
- /// </summary>
- public static readonly DependencyProperty ShowLineNumbersProperty =
- DependencyProperty.Register("ShowLineNumbers", typeof(bool), typeof(TextEditor),
- new FrameworkPropertyMetadata(Boxes.False, OnShowLineNumbersChanged));
-
- /// <summary>
- /// Specifies whether line numbers are shown on the left to the text view.
- /// </summary>
- public bool ShowLineNumbers
- {
- get { return (bool)GetValue(ShowLineNumbersProperty); }
- set { SetValue(ShowLineNumbersProperty, Boxes.Box(value)); }
- }
-
- static void OnShowLineNumbersChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
- {
- TextEditor editor = (TextEditor)d;
- var leftMargins = editor.TextArea.LeftMargins;
- if ((bool)e.NewValue)
- {
- LineNumberMargin lineNumbers = new LineNumberMargin();
- Line line = (Line)DottedLineMargin.Create();
- leftMargins.Insert(0, lineNumbers);
- leftMargins.Insert(1, line);
- var lineNumbersForeground = new Binding("LineNumbersForeground") { Source = editor };
- line.SetBinding(Line.StrokeProperty, lineNumbersForeground);
- lineNumbers.SetBinding(Control.ForegroundProperty, lineNumbersForeground);
- }
- else
- {
- for (int i = 0; i < leftMargins.Count; i++)
- {
- if (leftMargins[i] is LineNumberMargin)
- {
- leftMargins.RemoveAt(i);
- if (i < leftMargins.Count && DottedLineMargin.IsDottedLineMargin(leftMargins[i]))
- {
- leftMargins.RemoveAt(i);
- }
- break;
- }
- }
- }
- }
- #endregion
-
- #region LineNumbersForeground
- /// <summary>
- /// LineNumbersForeground dependency property.
- /// </summary>
- public static readonly DependencyProperty LineNumbersForegroundProperty =
- DependencyProperty.Register("LineNumbersForeground", typeof(Brush), typeof(TextEditor),
- new FrameworkPropertyMetadata(Brushes.Gray, OnLineNumbersForegroundChanged));
-
- /// <summary>
- /// Gets/sets the Brush used for displaying the foreground color of line numbers.
- /// </summary>
- public Brush LineNumbersForeground
- {
- get { return (Brush)GetValue(LineNumbersForegroundProperty); }
- set { SetValue(LineNumbersForegroundProperty, value); }
- }
-
- static void OnLineNumbersForegroundChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
- {
- TextEditor editor = (TextEditor)d;
- var lineNumberMargin = editor.TextArea.LeftMargins.FirstOrDefault(margin => margin is LineNumberMargin) as LineNumberMargin; ;
-
- if (lineNumberMargin != null)
- {
- lineNumberMargin.SetValue(Control.ForegroundProperty, e.NewValue);
- }
- }
- #endregion
-
- #region TextBoxBase-like methods
- /// <summary>
- /// Appends text to the end of the document.
- /// </summary>
- public void AppendText(string textData)
- {
- var document = GetDocument();
- document.Insert(document.TextLength, textData);
- }
-
- /// <summary>
- /// Begins a group of document changes.
- /// </summary>
- public void BeginChange()
- {
- GetDocument().BeginUpdate();
- }
-
- /// <summary>
- /// Copies the current selection to the clipboard.
- /// </summary>
- public void Copy()
- {
- Execute(ApplicationCommands.Copy);
- }
-
- /// <summary>
- /// Removes the current selection and copies it to the clipboard.
- /// </summary>
- public void Cut()
- {
- Execute(ApplicationCommands.Cut);
- }
-
- /// <summary>
- /// Begins a group of document changes and returns an object that ends the group of document
- /// changes when it is disposed.
- /// </summary>
- public IDisposable DeclareChangeBlock()
- {
- return GetDocument().RunUpdate();
- }
-
- /// <summary>
- /// Ends the current group of document changes.
- /// </summary>
- public void EndChange()
- {
- GetDocument().EndUpdate();
- }
-
- /// <summary>
- /// Scrolls one line down.
- /// </summary>
- public void LineDown()
- {
- if (scrollViewer != null)
- scrollViewer.LineDown();
- }
-
- /// <summary>
- /// Scrolls to the left.
- /// </summary>
- public void LineLeft()
- {
- if (scrollViewer != null)
- scrollViewer.LineLeft();
- }
-
- /// <summary>
- /// Scrolls to the right.
- /// </summary>
- public void LineRight()
- {
- if (scrollViewer != null)
- scrollViewer.LineRight();
- }
-
- /// <summary>
- /// Scrolls one line up.
- /// </summary>
- public void LineUp()
- {
- if (scrollViewer != null)
- scrollViewer.LineUp();
- }
-
- /// <summary>
- /// Scrolls one page down.
- /// </summary>
- public void PageDown()
- {
- if (scrollViewer != null)
- scrollViewer.PageDown();
- }
-
- /// <summary>
- /// Scrolls one page up.
- /// </summary>
- public void PageUp()
- {
- if (scrollViewer != null)
- scrollViewer.PageUp();
- }
-
- /// <summary>
- /// Scrolls one page left.
- /// </summary>
- public void PageLeft()
- {
- if (scrollViewer != null)
- scrollViewer.PageLeft();
- }
-
- /// <summary>
- /// Scrolls one page right.
- /// </summary>
- public void PageRight()
- {
- if (scrollViewer != null)
- scrollViewer.PageRight();
- }
-
- /// <summary>
- /// Pastes the clipboard content.
- /// </summary>
- public void Paste()
- {
- Execute(ApplicationCommands.Paste);
- }
-
- /// <summary>
- /// Redoes the most recent undone command.
- /// </summary>
- /// <returns>True is the redo operation was successful, false is the redo stack is empty.</returns>
- public bool Redo()
- {
- if (CanExecute(ApplicationCommands.Redo))
- {
- Execute(ApplicationCommands.Redo);
- return true;
- }
- return false;
- }
-
- /// <summary>
- /// Scrolls to the end of the document.
- /// </summary>
- public void ScrollToEnd()
- {
- ApplyTemplate(); // ensure scrollViewer is created
- if (scrollViewer != null)
- scrollViewer.ScrollToEnd();
- }
-
- /// <summary>
- /// Scrolls to the start of the document.
- /// </summary>
- public void ScrollToHome()
- {
- ApplyTemplate(); // ensure scrollViewer is created
- if (scrollViewer != null)
- scrollViewer.ScrollToHome();
- }
-
- /// <summary>
- /// Scrolls to the specified position in the document.
- /// </summary>
- public void ScrollToHorizontalOffset(double offset)
- {
- ApplyTemplate(); // ensure scrollViewer is created
- if (scrollViewer != null)
- scrollViewer.ScrollToHorizontalOffset(offset);
- }
-
- /// <summary>
- /// Scrolls to the specified position in the document.
- /// </summary>
- public void ScrollToVerticalOffset(double offset)
- {
- ApplyTemplate(); // ensure scrollViewer is created
- if (scrollViewer != null)
- scrollViewer.ScrollToVerticalOffset(offset);
- }
-
- /// <summary>
- /// Selects the entire text.
- /// </summary>
- public void SelectAll()
- {
- Execute(ApplicationCommands.SelectAll);
- }
-
- /// <summary>
- /// Undoes the most recent command.
- /// </summary>
- /// <returns>True is the undo operation was successful, false is the undo stack is empty.</returns>
- public bool Undo()
- {
- if (CanExecute(ApplicationCommands.Undo))
- {
- Execute(ApplicationCommands.Undo);
- return true;
- }
- return false;
- }
-
- /// <summary>
- /// Gets if the most recent undone command can be redone.
- /// </summary>
- public bool CanRedo
- {
- get { return CanExecute(ApplicationCommands.Redo); }
- }
-
- /// <summary>
- /// Gets if the most recent command can be undone.
- /// </summary>
- public bool CanUndo
- {
- get { return CanExecute(ApplicationCommands.Undo); }
- }
-
- /// <summary>
- /// Gets the vertical size of the document.
- /// </summary>
- public double ExtentHeight
- {
- get
- {
- return scrollViewer != null ? scrollViewer.ExtentHeight : 0;
- }
- }
-
- /// <summary>
- /// Gets the horizontal size of the current document region.
- /// </summary>
- public double ExtentWidth
- {
- get
- {
- return scrollViewer != null ? scrollViewer.ExtentWidth : 0;
- }
- }
-
- /// <summary>
- /// Gets the horizontal size of the viewport.
- /// </summary>
- public double ViewportHeight
- {
- get
- {
- return scrollViewer != null ? scrollViewer.ViewportHeight : 0;
- }
- }
-
- /// <summary>
- /// Gets the horizontal size of the viewport.
- /// </summary>
- public double ViewportWidth
- {
- get
- {
- return scrollViewer != null ? scrollViewer.ViewportWidth : 0;
- }
- }
-
- /// <summary>
- /// Gets the vertical scroll position.
- /// </summary>
- public double VerticalOffset
- {
- get
- {
- return scrollViewer != null ? scrollViewer.VerticalOffset : 0;
- }
- }
-
- /// <summary>
- /// Gets the horizontal scroll position.
- /// </summary>
- public double HorizontalOffset
- {
- get
- {
- return scrollViewer != null ? scrollViewer.HorizontalOffset : 0;
- }
- }
- #endregion
-
- #region TextBox methods
- /// <summary>
- /// Gets/Sets the selected text.
- /// </summary>
- [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
- public string SelectedText
- {
- get
- {
- TextArea textArea = this.TextArea;
- // We'll get the text from the whole surrounding segment.
- // This is done to ensure that SelectedText.Length == SelectionLength.
- if (textArea != null && textArea.Document != null && !textArea.Selection.IsEmpty)
- return textArea.Document.GetText(textArea.Selection.SurroundingSegment);
- else
- return string.Empty;
- }
- set
- {
- if (value == null)
- throw new ArgumentNullException("value");
- TextArea textArea = this.TextArea;
- if (textArea != null && textArea.Document != null)
- {
- int offset = this.SelectionStart;
- int length = this.SelectionLength;
- textArea.Document.Replace(offset, length, value);
- // keep inserted text selected
- textArea.Selection = SimpleSelection.Create(textArea, offset, offset + value.Length);
- }
- }
- }
-
- /// <summary>
- /// Gets/sets the caret position.
- /// </summary>
- [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
- public int CaretOffset
- {
- get
- {
- TextArea textArea = this.TextArea;
- if (textArea != null)
- return textArea.Caret.Offset;
- else
- return 0;
- }
- set
- {
- TextArea textArea = this.TextArea;
- if (textArea != null)
- textArea.Caret.Offset = value;
- }
- }
-
- /// <summary>
- /// Gets/sets the start position of the selection.
- /// </summary>
- [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
- public int SelectionStart
- {
- get
- {
- TextArea textArea = this.TextArea;
- if (textArea != null)
- {
- if (textArea.Selection.IsEmpty)
- return textArea.Caret.Offset;
- else
- return textArea.Selection.SurroundingSegment.Offset;
- }
- else
- {
- return 0;
- }
- }
- set
- {
- Select(value, SelectionLength);
- }
- }
-
- /// <summary>
- /// Gets/sets the length of the selection.
- /// </summary>
- [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
- public int SelectionLength
- {
- get
- {
- TextArea textArea = this.TextArea;
- if (textArea != null && !textArea.Selection.IsEmpty)
- return textArea.Selection.SurroundingSegment.Length;
- else
- return 0;
- }
- set
- {
- Select(SelectionStart, value);
- }
- }
-
- /// <summary>
- /// Selects the specified text section.
- /// </summary>
- public void Select(int start, int length)
- {
- int documentLength = Document != null ? Document.TextLength : 0;
-
- if (start < 0 || start > documentLength)
- {
- Debug.WriteLine(new ArgumentOutOfRangeException("start", start, "Value must be between 0 and " + documentLength));
- return;
- }
-
- if (length < 0 || start + length > documentLength)
- {
- Debug.WriteLine(new ArgumentOutOfRangeException("length", length, "Value must be between 0 and " + (documentLength - length)));
- return;
- }
-
- textArea.Selection = SimpleSelection.Create(textArea, start, start + length);
- textArea.Caret.Offset = start + length;
- }
-
- /// <summary>
- /// Gets the number of lines in the document.
- /// </summary>
- [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
- public int LineCount
- {
- get
- {
- TextDocument document = this.Document;
- if (document != null)
- return document.LineCount;
- else
- return 1;
- }
- }
-
- /// <summary>
- /// Clears the text.
- /// </summary>
- public void Clear()
- {
- this.Text = string.Empty;
- }
- #endregion
-
- #region Loading from stream
- /// <summary>
- /// Loads the text from the stream, auto-detecting the encoding.
- /// </summary>
- /// <remarks>
- /// This method sets <see cref="IsModified"/> to false.
- /// </remarks>
- public void Load(Stream stream)
- {
- using (StreamReader reader = FileReader.OpenStream(stream, this.Encoding ?? Encoding.UTF8))
- {
- this.Text = reader.ReadToEnd();
- this.Encoding = reader.CurrentEncoding; // assign encoding after ReadToEnd() so that the StreamReader can autodetect the encoding
- }
- this.IsModified = false;
- }
-
- /// <summary>
- /// Loads the text from the stream, auto-detecting the encoding.
- /// </summary>
- public void Load(string fileName)
- {
- if (fileName == null)
- throw new ArgumentNullException("fileName");
- using (FileStream fs = new FileStream(fileName, FileMode.Open, FileAccess.Read, FileShare.Read))
- {
- Load(fs);
- }
- }
-
- /// <summary>
- /// Gets/sets the encoding used when the file is saved.
- /// </summary>
- [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
- public Encoding Encoding { get; set; }
-
- /// <summary>
- /// Saves the text to the stream.
- /// </summary>
- /// <remarks>
- /// This method sets <see cref="IsModified"/> to false.
- /// </remarks>
- public void Save(Stream stream)
- {
- if (stream == null)
- throw new ArgumentNullException("stream");
- StreamWriter writer = new StreamWriter(stream, this.Encoding ?? Encoding.UTF8);
- writer.Write(this.Text);
- writer.Flush();
- // do not close the stream
- this.IsModified = false;
- }
-
- /// <summary>
- /// Saves the text to the file.
- /// </summary>
- public void Save(string fileName)
- {
- if (fileName == null)
- throw new ArgumentNullException("fileName");
- using (FileStream fs = new FileStream(fileName, FileMode.Create, FileAccess.Write, FileShare.None))
- {
- Save(fs);
- }
- }
- #endregion
-
- #region MouseHover events
- /// <summary>
- /// The PreviewMouseHover event.
- /// </summary>
- public static readonly RoutedEvent PreviewMouseHoverEvent =
- TextView.PreviewMouseHoverEvent.AddOwner(typeof(TextEditor));
-
- /// <summary>
- /// The MouseHover event.
- /// </summary>
- public static readonly RoutedEvent MouseHoverEvent =
- TextView.MouseHoverEvent.AddOwner(typeof(TextEditor));
-
-
- /// <summary>
- /// The PreviewMouseHoverStopped event.
- /// </summary>
- public static readonly RoutedEvent PreviewMouseHoverStoppedEvent =
- TextView.PreviewMouseHoverStoppedEvent.AddOwner(typeof(TextEditor));
-
- /// <summary>
- /// The MouseHoverStopped event.
- /// </summary>
- public static readonly RoutedEvent MouseHoverStoppedEvent =
- TextView.MouseHoverStoppedEvent.AddOwner(typeof(TextEditor));
-
-
- /// <summary>
- /// Occurs when the mouse has hovered over a fixed location for some time.
- /// </summary>
- public event MouseEventHandler PreviewMouseHover
- {
- add { AddHandler(PreviewMouseHoverEvent, value); }
- remove { RemoveHandler(PreviewMouseHoverEvent, value); }
- }
-
- /// <summary>
- /// Occurs when the mouse has hovered over a fixed location for some time.
- /// </summary>
- public event MouseEventHandler MouseHover
- {
- add { AddHandler(MouseHoverEvent, value); }
- remove { RemoveHandler(MouseHoverEvent, value); }
- }
-
- /// <summary>
- /// Occurs when the mouse had previously hovered but now started moving again.
- /// </summary>
- public event MouseEventHandler PreviewMouseHoverStopped
- {
- add { AddHandler(PreviewMouseHoverStoppedEvent, value); }
- remove { RemoveHandler(PreviewMouseHoverStoppedEvent, value); }
- }
-
- /// <summary>
- /// Occurs when the mouse had previously hovered but now started moving again.
- /// </summary>
- public event MouseEventHandler MouseHoverStopped
- {
- add { AddHandler(MouseHoverStoppedEvent, value); }
- remove { RemoveHandler(MouseHoverStoppedEvent, value); }
- }
- #endregion
-
- #region ScrollBarVisibility
- /// <summary>
- /// Dependency property for <see cref="HorizontalScrollBarVisibility"/>
- /// </summary>
- public static readonly DependencyProperty HorizontalScrollBarVisibilityProperty = ScrollViewer.HorizontalScrollBarVisibilityProperty.AddOwner(typeof(TextEditor), new FrameworkPropertyMetadata(ScrollBarVisibility.Visible));
-
- /// <summary>
- /// Gets/Sets the horizontal scroll bar visibility.
- /// </summary>
- public ScrollBarVisibility HorizontalScrollBarVisibility
- {
- get { return (ScrollBarVisibility)GetValue(HorizontalScrollBarVisibilityProperty); }
- set { SetValue(HorizontalScrollBarVisibilityProperty, value); }
- }
-
- /// <summary>
- /// Dependency property for <see cref="VerticalScrollBarVisibility"/>
- /// </summary>
- public static readonly DependencyProperty VerticalScrollBarVisibilityProperty = ScrollViewer.VerticalScrollBarVisibilityProperty.AddOwner(typeof(TextEditor), new FrameworkPropertyMetadata(ScrollBarVisibility.Visible));
-
- /// <summary>
- /// Gets/Sets the vertical scroll bar visibility.
- /// </summary>
- public ScrollBarVisibility VerticalScrollBarVisibility
- {
- get { return (ScrollBarVisibility)GetValue(VerticalScrollBarVisibilityProperty); }
- set { SetValue(VerticalScrollBarVisibilityProperty, value); }
- }
- #endregion
-
- object IServiceProvider.GetService(Type serviceType)
- {
- return textArea.GetService(serviceType);
- }
-
- /// <summary>
- /// Gets the text view position from a point inside the editor.
- /// </summary>
- /// <param name="point">The position, relative to top left
- /// corner of TextEditor control</param>
- /// <returns>The text view position, or null if the point is outside the document.</returns>
- public TextViewPosition? GetPositionFromPoint(Point point)
- {
- if (this.Document == null)
- return null;
- TextView textView = this.TextArea.TextView;
- return textView.GetPosition(TranslatePoint(point, textView) + textView.ScrollOffset);
- }
-
- /// <summary>
- /// Scrolls to the specified line.
- /// This method requires that the TextEditor was already assigned a size (WPF layout must have run prior).
- /// </summary>
- public void ScrollToLine(int line)
- {
- ScrollTo(line, -1);
- }
-
- /// <summary>
- /// Scrolls to the specified line/column.
- /// This method requires that the TextEditor was already assigned a size (WPF layout must have run prior).
- /// </summary>
- public void ScrollTo(int line, int column)
- {
- const double MinimumScrollPercentage = 0.3;
-
- TextView textView = textArea.TextView;
- TextDocument document = textView.Document;
- if (scrollViewer != null && document != null)
- {
- if (line < 1)
- line = 1;
- if (line > document.LineCount)
- line = document.LineCount;
-
- IScrollInfo scrollInfo = textView;
- if (!scrollInfo.CanHorizontallyScroll)
- {
- // Word wrap is enabled. Ensure that we have up-to-date info about line height so that we scroll
- // to the correct position.
- // This avoids that the user has to repeat the ScrollTo() call several times when there are very long lines.
- VisualLine vl = textView.GetOrConstructVisualLine(document.GetLineByNumber(line));
- double remainingHeight = scrollViewer.ViewportHeight / 2;
- while (remainingHeight > 0)
- {
- DocumentLine prevLine = vl.FirstDocumentLine.PreviousLine;
- if (prevLine == null)
- break;
- vl = textView.GetOrConstructVisualLine(prevLine);
- remainingHeight -= vl.Height;
- }
- }
-
- Point p = textArea.TextView.GetVisualPosition(new TextViewPosition(line, Math.Max(1, column)), VisualYPosition.LineMiddle);
- double verticalPos = p.Y - scrollViewer.ViewportHeight / 2;
- if (Math.Abs(verticalPos - scrollViewer.VerticalOffset) > MinimumScrollPercentage * scrollViewer.ViewportHeight)
- {
- scrollViewer.ScrollToVerticalOffset(Math.Max(0, verticalPos));
- }
- if (column > 0)
- {
- if (p.X > scrollViewer.ViewportWidth - Caret.MinimumDistanceToViewBorder * 2)
- {
- double horizontalPos = Math.Max(0, p.X - scrollViewer.ViewportWidth / 2);
- if (Math.Abs(horizontalPos - scrollViewer.HorizontalOffset) > MinimumScrollPercentage * scrollViewer.ViewportWidth)
- {
- scrollViewer.ScrollToHorizontalOffset(horizontalPos);
- }
- }
- else
- {
- scrollViewer.ScrollToHorizontalOffset(0);
- }
- }
- }
- }
- }
+ /// <summary>
+ /// The text editor control.
+ /// Contains a scrollable TextArea.
+ /// </summary>
+ [Localizability(LocalizationCategory.Text), ContentProperty("Text")]
+ public class TextEditor : Control, ITextEditorComponent, IServiceProvider, IWeakEventListener
+ {
+ #region Constructors
+ static TextEditor()
+ {
+ DefaultStyleKeyProperty.OverrideMetadata(typeof(TextEditor),
+ new FrameworkPropertyMetadata(typeof(TextEditor)));
+ FocusableProperty.OverrideMetadata(typeof(TextEditor),
+ new FrameworkPropertyMetadata(Boxes.True));
+ }
+
+ /// <summary>
+ /// Creates a new TextEditor instance.
+ /// </summary>
+ public TextEditor() : this(new TextArea())
+ {
+ }
+
+ /// <summary>
+ /// Creates a new TextEditor instance.
+ /// </summary>
+ protected TextEditor(TextArea textArea)
+ {
+ if (textArea == null)
+ throw new ArgumentNullException("textArea");
+ this.textArea = textArea;
+
+ textArea.TextView.Services.AddService(typeof(TextEditor), this);
+
+ SetCurrentValue(OptionsProperty, textArea.Options);
+ SetCurrentValue(DocumentProperty, new TextDocument());
+ }
+
+ #endregion
+
+ /// <inheritdoc/>
+ protected override System.Windows.Automation.Peers.AutomationPeer OnCreateAutomationPeer()
+ {
+ return new TextEditorAutomationPeer(this);
+ }
+
+ /// Forward focus to TextArea.
+ /// <inheritdoc/>
+ protected override void OnGotKeyboardFocus(KeyboardFocusChangedEventArgs e)
+ {
+ base.OnGotKeyboardFocus(e);
+ if (e.NewFocus == this) {
+ Keyboard.Focus(this.TextArea);
+ e.Handled = true;
+ }
+ }
+
+ #region Document property
+ /// <summary>
+ /// Document property.
+ /// </summary>
+ public static readonly DependencyProperty DocumentProperty
+ = TextView.DocumentProperty.AddOwner(
+ typeof(TextEditor), new FrameworkPropertyMetadata(OnDocumentChanged));
+
+ /// <summary>
+ /// Gets/Sets the document displayed by the text editor.
+ /// This is a dependency property.
+ /// </summary>
+ public TextDocument Document {
+ get { return (TextDocument)GetValue(DocumentProperty); }
+ set { SetValue(DocumentProperty, value); }
+ }
+
+ /// <summary>
+ /// Occurs when the document property has changed.
+ /// </summary>
+ public event EventHandler DocumentChanged;
+
+ /// <summary>
+ /// Raises the <see cref="DocumentChanged"/> event.
+ /// </summary>
+ protected virtual void OnDocumentChanged(EventArgs e)
+ {
+ if (DocumentChanged != null) {
+ DocumentChanged(this, e);
+ }
+ }
+
+ static void OnDocumentChanged(DependencyObject dp, DependencyPropertyChangedEventArgs e)
+ {
+ ((TextEditor)dp).OnDocumentChanged((TextDocument)e.OldValue, (TextDocument)e.NewValue);
+ }
+
+ void OnDocumentChanged(TextDocument oldValue, TextDocument newValue)
+ {
+ if (oldValue != null) {
+ TextDocumentWeakEventManager.TextChanged.RemoveListener(oldValue, this);
+ PropertyChangedEventManager.RemoveListener(oldValue.UndoStack, this, "IsOriginalFile");
+ }
+ textArea.Document = newValue;
+ if (newValue != null) {
+ TextDocumentWeakEventManager.TextChanged.AddListener(newValue, this);
+ PropertyChangedEventManager.AddListener(newValue.UndoStack, this, "IsOriginalFile");
+ }
+ OnDocumentChanged(EventArgs.Empty);
+ OnTextChanged(EventArgs.Empty);
+ }
+ #endregion
+
+ #region Options property
+ /// <summary>
+ /// Options property.
+ /// </summary>
+ public static readonly DependencyProperty OptionsProperty
+ = TextView.OptionsProperty.AddOwner(typeof(TextEditor), new FrameworkPropertyMetadata(OnOptionsChanged));
+
+ /// <summary>
+ /// Gets/Sets the options currently used by the text editor.
+ /// </summary>
+ public TextEditorOptions Options {
+ get { return (TextEditorOptions)GetValue(OptionsProperty); }
+ set { SetValue(OptionsProperty, value); }
+ }
+
+ /// <summary>
+ /// Occurs when a text editor option has changed.
+ /// </summary>
+ public event PropertyChangedEventHandler OptionChanged;
+
+ /// <summary>
+ /// Raises the <see cref="OptionChanged"/> event.
+ /// </summary>
+ protected virtual void OnOptionChanged(PropertyChangedEventArgs e)
+ {
+ if (OptionChanged != null) {
+ OptionChanged(this, e);
+ }
+ }
+
+ static void OnOptionsChanged(DependencyObject dp, DependencyPropertyChangedEventArgs e)
+ {
+ ((TextEditor)dp).OnOptionsChanged((TextEditorOptions)e.OldValue, (TextEditorOptions)e.NewValue);
+ }
+
+ void OnOptionsChanged(TextEditorOptions oldValue, TextEditorOptions newValue)
+ {
+ if (oldValue != null) {
+ PropertyChangedWeakEventManager.RemoveListener(oldValue, this);
+ }
+ textArea.Options = newValue;
+ if (newValue != null) {
+ PropertyChangedWeakEventManager.AddListener(newValue, this);
+ }
+ OnOptionChanged(new PropertyChangedEventArgs(null));
+ }
+
+ /// <inheritdoc cref="IWeakEventListener.ReceiveWeakEvent"/>
+ protected virtual bool ReceiveWeakEvent(Type managerType, object sender, EventArgs e)
+ {
+ if (managerType == typeof(PropertyChangedWeakEventManager)) {
+ OnOptionChanged((PropertyChangedEventArgs)e);
+ return true;
+ } else if (managerType == typeof(TextDocumentWeakEventManager.TextChanged)) {
+ OnTextChanged(e);
+ return true;
+ } else if (managerType == typeof(PropertyChangedEventManager)) {
+ return HandleIsOriginalChanged((PropertyChangedEventArgs)e);
+ }
+ return false;
+ }
+
+ bool IWeakEventListener.ReceiveWeakEvent(Type managerType, object sender, EventArgs e)
+ {
+ return ReceiveWeakEvent(managerType, sender, e);
+ }
+ #endregion
+
+ #region Text property
+ /// <summary>
+ /// Gets/Sets the text of the current document.
+ /// </summary>
+ [Localizability(LocalizationCategory.Text), DefaultValue("")]
+ public string Text {
+ get {
+ TextDocument document = this.Document;
+ return document != null ? document.Text : string.Empty;
+ }
+ set {
+ TextDocument document = GetDocument();
+ document.Text = value ?? string.Empty;
+ // after replacing the full text, the caret is positioned at the end of the document
+ // - reset it to the beginning.
+ this.CaretOffset = 0;
+ document.UndoStack.ClearAll();
+ }
+ }
+
+ TextDocument GetDocument()
+ {
+ TextDocument document = this.Document;
+ if (document == null)
+ throw ThrowUtil.NoDocumentAssigned();
+ return document;
+ }
+
+ /// <summary>
+ /// Occurs when the Text property changes.
+ /// </summary>
+ public event EventHandler TextChanged;
+
+ /// <summary>
+ /// Raises the <see cref="TextChanged"/> event.
+ /// </summary>
+ protected virtual void OnTextChanged(EventArgs e)
+ {
+ if (TextChanged != null) {
+ TextChanged(this, e);
+ }
+ }
+ #endregion
+
+ #region TextArea / ScrollViewer properties
+ readonly TextArea textArea;
+ ScrollViewer scrollViewer;
+
+ /// <summary>
+ /// Is called after the template was applied.
+ /// </summary>
+ public override void OnApplyTemplate()
+ {
+ base.OnApplyTemplate();
+ scrollViewer = (ScrollViewer)Template.FindName("PART_ScrollViewer", this);
+ }
+
+ /// <summary>
+ /// Gets the text area.
+ /// </summary>
+ public TextArea TextArea {
+ get {
+ return textArea;
+ }
+ }
+
+ /// <summary>
+ /// Gets the scroll viewer used by the text editor.
+ /// This property can return null if the template has not been applied / does not contain a scroll viewer.
+ /// </summary>
+ internal ScrollViewer ScrollViewer {
+ get { return scrollViewer; }
+ }
+
+ bool CanExecute(RoutedUICommand command)
+ {
+ TextArea textArea = this.TextArea;
+ if (textArea == null)
+ return false;
+ else
+ return command.CanExecute(null, textArea);
+ }
+
+ void Execute(RoutedUICommand command)
+ {
+ TextArea textArea = this.TextArea;
+ if (textArea != null)
+ command.Execute(null, textArea);
+ }
+ #endregion
+
+ #region Syntax highlighting
+ /// <summary>
+ /// The <see cref="SyntaxHighlighting"/> property.
+ /// </summary>
+ public static readonly DependencyProperty SyntaxHighlightingProperty =
+ DependencyProperty.Register("SyntaxHighlighting", typeof(IHighlightingDefinition), typeof(TextEditor),
+ new FrameworkPropertyMetadata(OnSyntaxHighlightingChanged));
+
+
+ /// <summary>
+ /// Gets/sets the syntax highlighting definition used to colorize the text.
+ /// </summary>
+ public IHighlightingDefinition SyntaxHighlighting {
+ get { return (IHighlightingDefinition)GetValue(SyntaxHighlightingProperty); }
+ set { SetValue(SyntaxHighlightingProperty, value); }
+ }
+
+ IVisualLineTransformer colorizer;
+
+ static void OnSyntaxHighlightingChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
+ {
+ ((TextEditor)d).OnSyntaxHighlightingChanged(e.NewValue as IHighlightingDefinition);
+ }
+
+ void OnSyntaxHighlightingChanged(IHighlightingDefinition newValue)
+ {
+ if (colorizer != null) {
+ this.TextArea.TextView.LineTransformers.Remove(colorizer);
+ colorizer = null;
+ }
+ if (newValue != null) {
+ colorizer = CreateColorizer(newValue);
+ this.TextArea.TextView.LineTransformers.Insert(0, colorizer);
+ }
+ }
+
+ /// <summary>
+ /// Creates the highlighting colorizer for the specified highlighting definition.
+ /// Allows derived classes to provide custom colorizer implementations for special highlighting definitions.
+ /// </summary>
+ /// <returns></returns>
+ protected virtual IVisualLineTransformer CreateColorizer(IHighlightingDefinition highlightingDefinition)
+ {
+ if (highlightingDefinition == null)
+ throw new ArgumentNullException("highlightingDefinition");
+ return new HighlightingColorizer(highlightingDefinition.MainRuleSet);
+ }
+ #endregion
+
+ #region WordWrap
+ /// <summary>
+ /// Word wrap dependency property.
+ /// </summary>
+ public static readonly DependencyProperty WordWrapProperty =
+ DependencyProperty.Register("WordWrap", typeof(bool), typeof(TextEditor),
+ new FrameworkPropertyMetadata(Boxes.False));
+
+ /// <summary>
+ /// Specifies whether the text editor uses word wrapping.
+ /// </summary>
+ /// <remarks>
+ /// Setting WordWrap=true has the same effect as setting HorizontalScrollBarVisibility=Disabled and will override the
+ /// HorizontalScrollBarVisibility setting.
+ /// </remarks>
+ public bool WordWrap {
+ get { return (bool)GetValue(WordWrapProperty); }
+ set { SetValue(WordWrapProperty, Boxes.Box(value)); }
+ }
+ #endregion
+
+ #region IsReadOnly
+ /// <summary>
+ /// IsReadOnly dependency property.
+ /// </summary>
+ public static readonly DependencyProperty IsReadOnlyProperty =
+ DependencyProperty.Register("IsReadOnly", typeof(bool), typeof(TextEditor),
+ new FrameworkPropertyMetadata(Boxes.False, OnIsReadOnlyChanged));
+
+ /// <summary>
+ /// Specifies whether the user can change the text editor content.
+ /// Setting this property will replace the
+ /// <see cref="Editing.TextArea.ReadOnlySectionProvider">TextArea.ReadOnlySectionProvider</see>.
+ /// </summary>
+ public bool IsReadOnly {
+ get { return (bool)GetValue(IsReadOnlyProperty); }
+ set { SetValue(IsReadOnlyProperty, Boxes.Box(value)); }
+ }
+
+ static void OnIsReadOnlyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
+ {
+ TextEditor editor = d as TextEditor;
+ if (editor != null) {
+ if ((bool)e.NewValue)
+ editor.TextArea.ReadOnlySectionProvider = ReadOnlyDocument.Instance;
+ else
+ editor.TextArea.ReadOnlySectionProvider = NoReadOnlySections.Instance;
+
+ TextEditorAutomationPeer peer = TextEditorAutomationPeer.FromElement(editor) as TextEditorAutomationPeer;
+ if (peer != null) {
+ peer.RaiseIsReadOnlyChanged((bool)e.OldValue, (bool)e.NewValue);
+ }
+ }
+ }
+ #endregion
+
+ #region IsModified
+ /// <summary>
+ /// Dependency property for <see cref="IsModified"/>
+ /// </summary>
+ public static readonly DependencyProperty IsModifiedProperty =
+ DependencyProperty.Register("IsModified", typeof(bool), typeof(TextEditor),
+ new FrameworkPropertyMetadata(Boxes.False, OnIsModifiedChanged));
+
+ /// <summary>
+ /// Gets/Sets the 'modified' flag.
+ /// </summary>
+ public bool IsModified {
+ get { return (bool)GetValue(IsModifiedProperty); }
+ set { SetValue(IsModifiedProperty, Boxes.Box(value)); }
+ }
+
+ static void OnIsModifiedChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
+ {
+ TextEditor editor = d as TextEditor;
+ if (editor != null) {
+ TextDocument document = editor.Document;
+ if (document != null) {
+ UndoStack undoStack = document.UndoStack;
+ if ((bool)e.NewValue) {
+ if (undoStack.IsOriginalFile)
+ undoStack.DiscardOriginalFileMarker();
+ } else {
+ undoStack.MarkAsOriginalFile();
+ }
+ }
+ }
+ }
+
+ bool HandleIsOriginalChanged(PropertyChangedEventArgs e)
+ {
+ if (e.PropertyName == "IsOriginalFile") {
+ TextDocument document = this.Document;
+ if (document != null) {
+ SetCurrentValue(IsModifiedProperty, Boxes.Box(!document.UndoStack.IsOriginalFile));
+ }
+ return true;
+ } else {
+ return false;
+ }
+ }
+ #endregion
+
+ #region ShowLineNumbers
+ /// <summary>
+ /// ShowLineNumbers dependency property.
+ /// </summary>
+ public static readonly DependencyProperty ShowLineNumbersProperty =
+ DependencyProperty.Register("ShowLineNumbers", typeof(bool), typeof(TextEditor),
+ new FrameworkPropertyMetadata(Boxes.False, OnShowLineNumbersChanged));
+
+ /// <summary>
+ /// Specifies whether line numbers are shown on the left to the text view.
+ /// </summary>
+ public bool ShowLineNumbers {
+ get { return (bool)GetValue(ShowLineNumbersProperty); }
+ set { SetValue(ShowLineNumbersProperty, Boxes.Box(value)); }
+ }
+
+ static void OnShowLineNumbersChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
+ {
+ TextEditor editor = (TextEditor)d;
+ var leftMargins = editor.TextArea.LeftMargins;
+ if ((bool)e.NewValue) {
+ LineNumberMargin lineNumbers = new LineNumberMargin();
+ Line line = (Line)DottedLineMargin.Create();
+ leftMargins.Insert(0, lineNumbers);
+ leftMargins.Insert(1, line);
+ var lineNumbersForeground = new Binding("LineNumbersForeground") { Source = editor };
+ line.SetBinding(Line.StrokeProperty, lineNumbersForeground);
+ lineNumbers.SetBinding(Control.ForegroundProperty, lineNumbersForeground);
+ } else {
+ for (int i = 0; i < leftMargins.Count; i++) {
+ if (leftMargins[i] is LineNumberMargin) {
+ leftMargins.RemoveAt(i);
+ if (i < leftMargins.Count && DottedLineMargin.IsDottedLineMargin(leftMargins[i])) {
+ leftMargins.RemoveAt(i);
+ }
+ break;
+ }
+ }
+ }
+ }
+ #endregion
+
+ #region LineNumbersForeground
+ /// <summary>
+ /// LineNumbersForeground dependency property.
+ /// </summary>
+ public static readonly DependencyProperty LineNumbersForegroundProperty =
+ DependencyProperty.Register("LineNumbersForeground", typeof(Brush), typeof(TextEditor),
+ new FrameworkPropertyMetadata(Brushes.Gray, OnLineNumbersForegroundChanged));
+
+ /// <summary>
+ /// Gets/sets the Brush used for displaying the foreground color of line numbers.
+ /// </summary>
+ public Brush LineNumbersForeground {
+ get { return (Brush)GetValue(LineNumbersForegroundProperty); }
+ set { SetValue(LineNumbersForegroundProperty, value); }
+ }
+
+ static void OnLineNumbersForegroundChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
+ {
+ TextEditor editor = (TextEditor)d;
+ var lineNumberMargin = editor.TextArea.LeftMargins.FirstOrDefault(margin => margin is LineNumberMargin) as LineNumberMargin;;
+
+ if (lineNumberMargin != null) {
+ lineNumberMargin.SetValue(Control.ForegroundProperty, e.NewValue);
+ }
+ }
+ #endregion
+
+ #region TextBoxBase-like methods
+ /// <summary>
+ /// Appends text to the end of the document.
+ /// </summary>
+ public void AppendText(string textData)
+ {
+ var document = GetDocument();
+ document.Insert(document.TextLength, textData);
+ }
+
+ /// <summary>
+ /// Begins a group of document changes.
+ /// </summary>
+ public void BeginChange()
+ {
+ GetDocument().BeginUpdate();
+ }
+
+ /// <summary>
+ /// Copies the current selection to the clipboard.
+ /// </summary>
+ public void Copy()
+ {
+ Execute(ApplicationCommands.Copy);
+ }
+
+ /// <summary>
+ /// Removes the current selection and copies it to the clipboard.
+ /// </summary>
+ public void Cut()
+ {
+ Execute(ApplicationCommands.Cut);
+ }
+
+ /// <summary>
+ /// Begins a group of document changes and returns an object that ends the group of document
+ /// changes when it is disposed.
+ /// </summary>
+ public IDisposable DeclareChangeBlock()
+ {
+ return GetDocument().RunUpdate();
+ }
+
+ /// <summary>
+ /// Ends the current group of document changes.
+ /// </summary>
+ public void EndChange()
+ {
+ GetDocument().EndUpdate();
+ }
+
+ /// <summary>
+ /// Scrolls one line down.
+ /// </summary>
+ public void LineDown()
+ {
+ if (scrollViewer != null)
+ scrollViewer.LineDown();
+ }
+
+ /// <summary>
+ /// Scrolls to the left.
+ /// </summary>
+ public void LineLeft()
+ {
+ if (scrollViewer != null)
+ scrollViewer.LineLeft();
+ }
+
+ /// <summary>
+ /// Scrolls to the right.
+ /// </summary>
+ public void LineRight()
+ {
+ if (scrollViewer != null)
+ scrollViewer.LineRight();
+ }
+
+ /// <summary>
+ /// Scrolls one line up.
+ /// </summary>
+ public void LineUp()
+ {
+ if (scrollViewer != null)
+ scrollViewer.LineUp();
+ }
+
+ /// <summary>
+ /// Scrolls one page down.
+ /// </summary>
+ public void PageDown()
+ {
+ if (scrollViewer != null)
+ scrollViewer.PageDown();
+ }
+
+ /// <summary>
+ /// Scrolls one page up.
+ /// </summary>
+ public void PageUp()
+ {
+ if (scrollViewer != null)
+ scrollViewer.PageUp();
+ }
+
+ /// <summary>
+ /// Scrolls one page left.
+ /// </summary>
+ public void PageLeft()
+ {
+ if (scrollViewer != null)
+ scrollViewer.PageLeft();
+ }
+
+ /// <summary>
+ /// Scrolls one page right.
+ /// </summary>
+ public void PageRight()
+ {
+ if (scrollViewer != null)
+ scrollViewer.PageRight();
+ }
+
+ /// <summary>
+ /// Pastes the clipboard content.
+ /// </summary>
+ public void Paste()
+ {
+ Execute(ApplicationCommands.Paste);
+ }
+
+ /// <summary>
+ /// Redoes the most recent undone command.
+ /// </summary>
+ /// <returns>True is the redo operation was successful, false is the redo stack is empty.</returns>
+ public bool Redo()
+ {
+ if (CanExecute(ApplicationCommands.Redo)) {
+ Execute(ApplicationCommands.Redo);
+ return true;
+ }
+ return false;
+ }
+
+ /// <summary>
+ /// Scrolls to the end of the document.
+ /// </summary>
+ public void ScrollToEnd()
+ {
+ ApplyTemplate(); // ensure scrollViewer is created
+ if (scrollViewer != null)
+ scrollViewer.ScrollToEnd();
+ }
+
+ /// <summary>
+ /// Scrolls to the start of the document.
+ /// </summary>
+ public void ScrollToHome()
+ {
+ ApplyTemplate(); // ensure scrollViewer is created
+ if (scrollViewer != null)
+ scrollViewer.ScrollToHome();
+ }
+
+ /// <summary>
+ /// Scrolls to the specified position in the document.
+ /// </summary>
+ public void ScrollToHorizontalOffset(double offset)
+ {
+ ApplyTemplate(); // ensure scrollViewer is created
+ if (scrollViewer != null)
+ scrollViewer.ScrollToHorizontalOffset(offset);
+ }
+
+ /// <summary>
+ /// Scrolls to the specified position in the document.
+ /// </summary>
+ public void ScrollToVerticalOffset(double offset)
+ {
+ ApplyTemplate(); // ensure scrollViewer is created
+ if (scrollViewer != null)
+ scrollViewer.ScrollToVerticalOffset(offset);
+ }
+
+ /// <summary>
+ /// Selects the entire text.
+ /// </summary>
+ public void SelectAll()
+ {
+ Execute(ApplicationCommands.SelectAll);
+ }
+
+ /// <summary>
+ /// Undoes the most recent command.
+ /// </summary>
+ /// <returns>True is the undo operation was successful, false is the undo stack is empty.</returns>
+ public bool Undo()
+ {
+ if (CanExecute(ApplicationCommands.Undo)) {
+ Execute(ApplicationCommands.Undo);
+ return true;
+ }
+ return false;
+ }
+
+ /// <summary>
+ /// Gets if the most recent undone command can be redone.
+ /// </summary>
+ public bool CanRedo {
+ get { return CanExecute(ApplicationCommands.Redo); }
+ }
+
+ /// <summary>
+ /// Gets if the most recent command can be undone.
+ /// </summary>
+ public bool CanUndo {
+ get { return CanExecute(ApplicationCommands.Undo); }
+ }
+
+ /// <summary>
+ /// Gets the vertical size of the document.
+ /// </summary>
+ public double ExtentHeight {
+ get {
+ return scrollViewer != null ? scrollViewer.ExtentHeight : 0;
+ }
+ }
+
+ /// <summary>
+ /// Gets the horizontal size of the current document region.
+ /// </summary>
+ public double ExtentWidth {
+ get {
+ return scrollViewer != null ? scrollViewer.ExtentWidth : 0;
+ }
+ }
+
+ /// <summary>
+ /// Gets the horizontal size of the viewport.
+ /// </summary>
+ public double ViewportHeight {
+ get {
+ return scrollViewer != null ? scrollViewer.ViewportHeight : 0;
+ }
+ }
+
+ /// <summary>
+ /// Gets the horizontal size of the viewport.
+ /// </summary>
+ public double ViewportWidth {
+ get {
+ return scrollViewer != null ? scrollViewer.ViewportWidth : 0;
+ }
+ }
+
+ /// <summary>
+ /// Gets the vertical scroll position.
+ /// </summary>
+ public double VerticalOffset {
+ get {
+ return scrollViewer != null ? scrollViewer.VerticalOffset : 0;
+ }
+ }
+
+ /// <summary>
+ /// Gets the horizontal scroll position.
+ /// </summary>
+ public double HorizontalOffset {
+ get {
+ return scrollViewer != null ? scrollViewer.HorizontalOffset : 0;
+ }
+ }
+ #endregion
+
+ #region TextBox methods
+ /// <summary>
+ /// Gets/Sets the selected text.
+ /// </summary>
+ [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
+ public string SelectedText {
+ get {
+ TextArea textArea = this.TextArea;
+ // We'll get the text from the whole surrounding segment.
+ // This is done to ensure that SelectedText.Length == SelectionLength.
+ if (textArea != null && textArea.Document != null && !textArea.Selection.IsEmpty)
+ return textArea.Document.GetText(textArea.Selection.SurroundingSegment);
+ else
+ return string.Empty;
+ }
+ set {
+ if (value == null)
+ throw new ArgumentNullException("value");
+ TextArea textArea = this.TextArea;
+ if (textArea != null && textArea.Document != null) {
+ int offset = this.SelectionStart;
+ int length = this.SelectionLength;
+ textArea.Document.Replace(offset, length, value);
+ // keep inserted text selected
+ textArea.Selection = SimpleSelection.Create(textArea, offset, offset + value.Length);
+ }
+ }
+ }
+
+ /// <summary>
+ /// Gets/sets the caret position.
+ /// </summary>
+ [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
+ public int CaretOffset {
+ get {
+ TextArea textArea = this.TextArea;
+ if (textArea != null)
+ return textArea.Caret.Offset;
+ else
+ return 0;
+ }
+ set {
+ TextArea textArea = this.TextArea;
+ if (textArea != null)
+ textArea.Caret.Offset = value;
+ }
+ }
+
+ /// <summary>
+ /// Gets/sets the start position of the selection.
+ /// </summary>
+ [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
+ public int SelectionStart {
+ get {
+ TextArea textArea = this.TextArea;
+ if (textArea != null) {
+ if (textArea.Selection.IsEmpty)
+ return textArea.Caret.Offset;
+ else
+ return textArea.Selection.SurroundingSegment.Offset;
+ } else {
+ return 0;
+ }
+ }
+ set {
+ Select(value, SelectionLength);
+ }
+ }
+
+ /// <summary>
+ /// Gets/sets the length of the selection.
+ /// </summary>
+ [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
+ public int SelectionLength {
+ get {
+ TextArea textArea = this.TextArea;
+ if (textArea != null && !textArea.Selection.IsEmpty)
+ return textArea.Selection.SurroundingSegment.Length;
+ else
+ return 0;
+ }
+ set {
+ Select(SelectionStart, value);
+ }
+ }
+
+ /// <summary>
+ /// Selects the specified text section.
+ /// </summary>
+ public void Select(int start, int length)
+ {
+ int documentLength = Document != null ? Document.TextLength : 0;
+ if (start < 0 || start > documentLength)
+ throw new ArgumentOutOfRangeException("start", start, "Value must be between 0 and " + documentLength);
+ if (length < 0 || start + length > documentLength)
+ throw new ArgumentOutOfRangeException("length", length, "Value must be between 0 and " + (documentLength - length));
+ textArea.Selection = SimpleSelection.Create(textArea, start, start + length);
+ textArea.Caret.Offset = start + length;
+ }
+
+ /// <summary>
+ /// Gets the number of lines in the document.
+ /// </summary>
+ [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
+ public int LineCount {
+ get {
+ TextDocument document = this.Document;
+ if (document != null)
+ return document.LineCount;
+ else
+ return 1;
+ }
+ }
+
+ /// <summary>
+ /// Clears the text.
+ /// </summary>
+ public void Clear()
+ {
+ this.Text = string.Empty;
+ }
+ #endregion
+
+ #region Loading from stream
+ /// <summary>
+ /// Loads the text from the stream, auto-detecting the encoding.
+ /// </summary>
+ /// <remarks>
+ /// This method sets <see cref="IsModified"/> to false.
+ /// </remarks>
+ public void Load(Stream stream)
+ {
+ using (StreamReader reader = FileReader.OpenStream(stream, this.Encoding ?? Encoding.UTF8)) {
+ this.Text = reader.ReadToEnd();
+ this.Encoding = reader.CurrentEncoding; // assign encoding after ReadToEnd() so that the StreamReader can autodetect the encoding
+ }
+ this.IsModified = false;
+ }
+
+ /// <summary>
+ /// Loads the text from the stream, auto-detecting the encoding.
+ /// </summary>
+ public void Load(string fileName)
+ {
+ if (fileName == null)
+ throw new ArgumentNullException("fileName");
+ using (FileStream fs = new FileStream(fileName, FileMode.Open, FileAccess.Read, FileShare.Read)) {
+ Load(fs);
+ }
+ }
+
+ /// <summary>
+ /// Gets/sets the encoding used when the file is saved.
+ /// </summary>
+ [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
+ public Encoding Encoding { get; set; }
+
+ /// <summary>
+ /// Saves the text to the stream.
+ /// </summary>
+ /// <remarks>
+ /// This method sets <see cref="IsModified"/> to false.
+ /// </remarks>
+ public void Save(Stream stream)
+ {
+ if (stream == null)
+ throw new ArgumentNullException("stream");
+ StreamWriter writer = new StreamWriter(stream, this.Encoding ?? Encoding.UTF8);
+ writer.Write(this.Text);
+ writer.Flush();
+ // do not close the stream
+ this.IsModified = false;
+ }
+
+ /// <summary>
+ /// Saves the text to the file.
+ /// </summary>
+ public void Save(string fileName)
+ {
+ if (fileName == null)
+ throw new ArgumentNullException("fileName");
+ using (FileStream fs = new FileStream(fileName, FileMode.Create, FileAccess.Write, FileShare.None)) {
+ Save(fs);
+ }
+ }
+ #endregion
+
+ #region MouseHover events
+ /// <summary>
+ /// The PreviewMouseHover event.
+ /// </summary>
+ public static readonly RoutedEvent PreviewMouseHoverEvent =
+ TextView.PreviewMouseHoverEvent.AddOwner(typeof(TextEditor));
+
+ /// <summary>
+ /// The MouseHover event.
+ /// </summary>
+ public static readonly RoutedEvent MouseHoverEvent =
+ TextView.MouseHoverEvent.AddOwner(typeof(TextEditor));
+
+
+ /// <summary>
+ /// The PreviewMouseHoverStopped event.
+ /// </summary>
+ public static readonly RoutedEvent PreviewMouseHoverStoppedEvent =
+ TextView.PreviewMouseHoverStoppedEvent.AddOwner(typeof(TextEditor));
+
+ /// <summary>
+ /// The MouseHoverStopped event.
+ /// </summary>
+ public static readonly RoutedEvent MouseHoverStoppedEvent =
+ TextView.MouseHoverStoppedEvent.AddOwner(typeof(TextEditor));
+
+
+ /// <summary>
+ /// Occurs when the mouse has hovered over a fixed location for some time.
+ /// </summary>
+ public event MouseEventHandler PreviewMouseHover {
+ add { AddHandler(PreviewMouseHoverEvent, value); }
+ remove { RemoveHandler(PreviewMouseHoverEvent, value); }
+ }
+
+ /// <summary>
+ /// Occurs when the mouse has hovered over a fixed location for some time.
+ /// </summary>
+ public event MouseEventHandler MouseHover {
+ add { AddHandler(MouseHoverEvent, value); }
+ remove { RemoveHandler(MouseHoverEvent, value); }
+ }
+
+ /// <summary>
+ /// Occurs when the mouse had previously hovered but now started moving again.
+ /// </summary>
+ public event MouseEventHandler PreviewMouseHoverStopped {
+ add { AddHandler(PreviewMouseHoverStoppedEvent, value); }
+ remove { RemoveHandler(PreviewMouseHoverStoppedEvent, value); }
+ }
+
+ /// <summary>
+ /// Occurs when the mouse had previously hovered but now started moving again.
+ /// </summary>
+ public event MouseEventHandler MouseHoverStopped {
+ add { AddHandler(MouseHoverStoppedEvent, value); }
+ remove { RemoveHandler(MouseHoverStoppedEvent, value); }
+ }
+ #endregion
+
+ #region ScrollBarVisibility
+ /// <summary>
+ /// Dependency property for <see cref="HorizontalScrollBarVisibility"/>
+ /// </summary>
+ public static readonly DependencyProperty HorizontalScrollBarVisibilityProperty = ScrollViewer.HorizontalScrollBarVisibilityProperty.AddOwner(typeof(TextEditor), new FrameworkPropertyMetadata(ScrollBarVisibility.Visible));
+
+ /// <summary>
+ /// Gets/Sets the horizontal scroll bar visibility.
+ /// </summary>
+ public ScrollBarVisibility HorizontalScrollBarVisibility {
+ get { return (ScrollBarVisibility)GetValue(HorizontalScrollBarVisibilityProperty); }
+ set { SetValue(HorizontalScrollBarVisibilityProperty, value); }
+ }
+
+ /// <summary>
+ /// Dependency property for <see cref="VerticalScrollBarVisibility"/>
+ /// </summary>
+ public static readonly DependencyProperty VerticalScrollBarVisibilityProperty = ScrollViewer.VerticalScrollBarVisibilityProperty.AddOwner(typeof(TextEditor), new FrameworkPropertyMetadata(ScrollBarVisibility.Visible));
+
+ /// <summary>
+ /// Gets/Sets the vertical scroll bar visibility.
+ /// </summary>
+ public ScrollBarVisibility VerticalScrollBarVisibility {
+ get { return (ScrollBarVisibility)GetValue(VerticalScrollBarVisibilityProperty); }
+ set { SetValue(VerticalScrollBarVisibilityProperty, value); }
+ }
+ #endregion
+
+ object IServiceProvider.GetService(Type serviceType)
+ {
+ return textArea.GetService(serviceType);
+ }
+
+ /// <summary>
+ /// Gets the text view position from a point inside the editor.
+ /// </summary>
+ /// <param name="point">The position, relative to top left
+ /// corner of TextEditor control</param>
+ /// <returns>The text view position, or null if the point is outside the document.</returns>
+ public TextViewPosition? GetPositionFromPoint(Point point)
+ {
+ if (this.Document == null)
+ return null;
+ TextView textView = this.TextArea.TextView;
+ return textView.GetPosition(TranslatePoint(point, textView) + textView.ScrollOffset);
+ }
+
+ /// <summary>
+ /// Scrolls to the specified line.
+ /// This method requires that the TextEditor was already assigned a size (WPF layout must have run prior).
+ /// </summary>
+ public void ScrollToLine(int line)
+ {
+ ScrollTo(line, -1);
+ }
+
+ /// <summary>
+ /// Scrolls to the specified line/column.
+ /// This method requires that the TextEditor was already assigned a size (WPF layout must have run prior).
+ /// </summary>
+ public void ScrollTo(int line, int column)
+ {
+ const double MinimumScrollPercentage = 0.3;
+
+ TextView textView = textArea.TextView;
+ TextDocument document = textView.Document;
+ if (scrollViewer != null && document != null) {
+ if (line < 1)
+ line = 1;
+ if (line > document.LineCount)
+ line = document.LineCount;
+
+ IScrollInfo scrollInfo = textView;
+ if (!scrollInfo.CanHorizontallyScroll) {
+ // Word wrap is enabled. Ensure that we have up-to-date info about line height so that we scroll
+ // to the correct position.
+ // This avoids that the user has to repeat the ScrollTo() call several times when there are very long lines.
+ VisualLine vl = textView.GetOrConstructVisualLine(document.GetLineByNumber(line));
+ double remainingHeight = scrollViewer.ViewportHeight / 2;
+ while (remainingHeight > 0) {
+ DocumentLine prevLine = vl.FirstDocumentLine.PreviousLine;
+ if (prevLine == null)
+ break;
+ vl = textView.GetOrConstructVisualLine(prevLine);
+ remainingHeight -= vl.Height;
+ }
+ }
+
+ Point p = textArea.TextView.GetVisualPosition(new TextViewPosition(line, Math.Max(1, column)), VisualYPosition.LineMiddle);
+ double verticalPos = p.Y - scrollViewer.ViewportHeight / 2;
+ if (Math.Abs(verticalPos - scrollViewer.VerticalOffset) > MinimumScrollPercentage * scrollViewer.ViewportHeight) {
+ scrollViewer.ScrollToVerticalOffset(Math.Max(0, verticalPos));
+ }
+ if (column > 0) {
+ if (p.X > scrollViewer.ViewportWidth - Caret.MinimumDistanceToViewBorder * 2) {
+ double horizontalPos = Math.Max(0, p.X - scrollViewer.ViewportWidth / 2);
+ if (Math.Abs(horizontalPos - scrollViewer.HorizontalOffset) > MinimumScrollPercentage * scrollViewer.ViewportWidth) {
+ scrollViewer.ScrollToHorizontalOffset(horizontalPos);
+ }
+ } else {
+ scrollViewer.ScrollToHorizontalOffset(0);
+ }
+ }
+ }
+ }
+ }
} \ No newline at end of file
diff --git a/Software/Visual_Studio/Scripting/Tango.Scripting.Editors/Themes/Generic.xaml b/Software/Visual_Studio/Scripting/Tango.Scripting.Editors/Themes/Generic.xaml
index 5de763df3..ce5cb39e1 100644
--- a/Software/Visual_Studio/Scripting/Tango.Scripting.Editors/Themes/Generic.xaml
+++ b/Software/Visual_Studio/Scripting/Tango.Scripting.Editors/Themes/Generic.xaml
@@ -47,19 +47,12 @@
<BitmapImage x:Key="namespace" UriSource="pack://application:,,,/Tango.Scripting.Editors;component/Images/namespace.png" />
<BitmapImage x:Key="method" UriSource="pack://application:,,,/Tango.Scripting.Editors;component/Images/method.png" />
<BitmapImage x:Key="property" UriSource="pack://application:,,,/Tango.Scripting.Editors;component/Images/property.png" />
- <BitmapImage x:Key="event" UriSource="pack://application:,,,/Tango.Scripting.Editors;component/Images/event.png" />
- <BitmapImage x:Key="snippet" UriSource="pack://application:,,,/Tango.Scripting.Editors;component/Images/snippet.png" />
<!--Converters-->
<converters:BooleanToVisibilityConverter x:Key="BooleanToVisibilityConverter" />
<converters:BooleanToVisibilityInversedConverter x:Key="BooleanToVisibilityInversedConverter" />
<Style TargetType="{x:Type completion:CompletionList}">
- <Style.Resources>
- <Style TargetType="ToolTip">
-
- </Style>
- </Style.Resources>
<Setter Property="Background" Value="{StaticResource CompletionBackgroundBrush}"></Setter>
<Setter Property="BorderThickness" Value="0"></Setter>
@@ -90,6 +83,95 @@
<Setter.Value>
<DataTemplate>
<Border Background="{StaticResource CompletionToolTipBackgroundBrush}" CornerRadius="3" BorderThickness="0.5" BorderBrush="#434343" Padding="10 5" TextElement.Foreground="{StaticResource ScriptForegroundBrush}" TextElement.FontSize="12">
+ <!--<ContentControl Content="{Binding}">
+ <ContentControl.Style>
+ <Style TargetType="ContentControl">
+ <Setter Property="ContentTemplate">
+ <Setter.Value>
+ <DataTemplate>
+ <ContentPresenter Content="{Binding PopupControl}" />
+ </DataTemplate>
+ </Setter.Value>
+ </Setter>
+ <Style.Triggers>
+ <DataTrigger Binding="{Binding Type}" Value="method">
+ <Setter Property="ContentTemplate">
+ <Setter.Value>
+ <DataTemplate>
+ <StackPanel>
+ <StackPanel Orientation="Horizontal">
+ <TextBlock Text="{Binding ReturnType}" Foreground="{StaticResource ScriptReferenceTypesBrush}"></TextBlock>
+ <TextBlock Margin="5 0 0 0" Text="{Binding Class}" Foreground="{StaticResource ScriptReferenceTypesBrush}"></TextBlock>
+ <TextBlock>.</TextBlock>
+ <TextBlock Text="{Binding Text}"></TextBlock>
+ <TextBlock>(</TextBlock>
+ <ItemsControl ItemsSource="{Binding Parameters}">
+ <ItemsControl.ItemsPanel>
+ <ItemsPanelTemplate>
+ <StackPanel Orientation="Horizontal"></StackPanel>
+ </ItemsPanelTemplate>
+ </ItemsControl.ItemsPanel>
+ <ItemsControl.ItemTemplate>
+ <DataTemplate>
+ <StackPanel Orientation="Horizontal">
+ <TextBlock Text="{Binding Type.Name}" Foreground="{StaticResource ScriptReferenceTypesBrush}"></TextBlock>
+ <TextBlock Margin="5 0 0 0" Text="{Binding Name}"></TextBlock>
+ <TextBlock Margin="0 0 5 0" Text="," Visibility="{Binding IsLast,Converter={StaticResource BooleanToVisibilityInversedConverter}}"></TextBlock>
+ </StackPanel>
+ </DataTemplate>
+ </ItemsControl.ItemTemplate>
+ </ItemsControl>
+ <TextBlock>)</TextBlock>
+
+ <StackPanel Margin="5 0 0 0" Orientation="Horizontal" Visibility="{Binding HasOverloads,Converter={StaticResource BooleanToVisibilityConverter}}">
+ <TextBlock>(+</TextBlock>
+ <TextBlock Margin="2 0" Text="{Binding Overloads}"></TextBlock>
+ <TextBlock>overloads)</TextBlock>
+ </StackPanel>
+ </StackPanel>
+
+ <TextBlock Text="{Binding Description}"></TextBlock>
+ </StackPanel>
+ </DataTemplate>
+ </Setter.Value>
+ </Setter>
+ </DataTrigger>
+
+ <DataTrigger Binding="{Binding Type}" Value="property">
+ <Setter Property="ContentTemplate">
+ <Setter.Value>
+ <DataTemplate>
+ <StackPanel>
+ <StackPanel Orientation="Horizontal">
+ <TextBlock Text="{Binding ReturnType}" Foreground="{StaticResource ScriptReferenceTypesBrush}"></TextBlock>
+ <TextBlock Margin="5 0 0 0" Text="{Binding Class}" Foreground="{StaticResource ScriptReferenceTypesBrush}"></TextBlock>
+ <TextBlock>.</TextBlock>
+ <TextBlock Text="{Binding Text}"></TextBlock>
+ <TextBlock Margin="5 0 0 0">
+ <Run>{</Run>
+ <Run Foreground="{StaticResource ScriptKeywordBrush}">get</Run><Run>;</Run>
+ <Run Foreground="{StaticResource ScriptKeywordBrush}">set</Run><Run>;</Run>
+ <Run>}</Run>
+ </TextBlock>
+ </StackPanel>
+
+ <TextBlock Text="{Binding Description}"></TextBlock>
+ </StackPanel>
+ </DataTemplate>
+ </Setter.Value>
+ </Setter>
+ </DataTrigger>
+ </Style.Triggers>
+ </Style>
+ </ContentControl.Style>
+
+ <ContentControl.ContentTemplate>
+ <DataTemplate>
+ <ContentPresenter Content="{Binding PopupControl}" />
+ </DataTemplate>
+ </ContentControl.ContentTemplate>
+ </ContentControl>-->
+
<ContentPresenter DataContext="{Binding}" Content="{Binding PopupControl}" />
</Border>
</DataTemplate>
@@ -141,15 +223,6 @@
<Setter Property="Control.Cursor" Value="/Tango.Scripting.Editors;component/themes/RightArrow.cur"/>
</Style>
- <Style TargetType="{x:Type local:XamlEditor}">
- <Setter Property="ScrollViewer.HorizontalScrollBarVisibility" Value="Auto"></Setter>
- <Setter Property="ScrollViewer.VerticalScrollBarVisibility" Value="Auto"></Setter>
- <Setter Property="FontFamily" Value="Consolas"></Setter>
- <Setter Property="FontSize" Value="13"></Setter>
- <Setter Property="SyntaxHighlighting" Value="XML"></Setter>
- <Setter Property="ShowLineNumbers" Value="True"></Setter>
- </Style>
-
<Style TargetType="{x:Type local:ScriptEditor}">
<Setter Property="Background" Value="{StaticResource ScriptBackgroundBrush}"></Setter>
<Setter Property="Foreground" Value="{StaticResource ScriptForegroundBrush}"></Setter>
@@ -494,6 +567,4 @@
</Setter.Value>
</Setter>
</Style>
-
-
</ResourceDictionary>
diff --git a/Software/Visual_Studio/Scripting/Tango.Scripting.Editors/XamlEditor.cs b/Software/Visual_Studio/Scripting/Tango.Scripting.Editors/XamlEditor.cs
deleted file mode 100644
index 22b425ba2..000000000
--- a/Software/Visual_Studio/Scripting/Tango.Scripting.Editors/XamlEditor.cs
+++ /dev/null
@@ -1,47 +0,0 @@
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-using System.Threading.Tasks;
-using System.Windows;
-
-namespace Tango.Scripting.Editors
-{
- public class XamlEditor : TextEditor
- {
- private bool preventCodeUpdate;
-
- public String Xaml
- {
- get { return (String)GetValue(XamlProperty); }
- set { SetValue(XamlProperty, value); }
- }
- public static readonly DependencyProperty XamlProperty =
- DependencyProperty.Register("Xaml", typeof(String), typeof(XamlEditor), new PropertyMetadata(null, (d, e) => (d as XamlEditor).OnXamlChanged()));
-
- public XamlEditor()
- {
- TextChanged += XamlEditor_TextChanged;
- }
-
- private void XamlEditor_TextChanged(object sender, EventArgs e)
- {
- if (!preventCodeUpdate)
- {
- preventCodeUpdate = true;
- Xaml = Text;
- preventCodeUpdate = false;
- }
- }
-
- private void OnXamlChanged()
- {
- if (!preventCodeUpdate)
- {
- preventCodeUpdate = true;
- Text = Xaml;
- preventCodeUpdate = false;
- }
- }
- }
-}
diff --git a/Software/Visual_Studio/Scripting/Tango.Scripting.Editors/app.config b/Software/Visual_Studio/Scripting/Tango.Scripting.Editors/app.config
index 16d75cf59..d3a17b4de 100644
--- a/Software/Visual_Studio/Scripting/Tango.Scripting.Editors/app.config
+++ b/Software/Visual_Studio/Scripting/Tango.Scripting.Editors/app.config
@@ -77,14 +77,6 @@
</dependentAssembly>
- <dependentAssembly>
-
- <assemblyIdentity name="Microsoft.IdentityModel.Clients.ActiveDirectory" publicKeyToken="31bf3856ad364e35" culture="neutral" />
-
- <bindingRedirect oldVersion="0.0.0.0-5.0.5.0" newVersion="5.0.5.0" />
-
- </dependentAssembly>
-
</assemblyBinding>
</runtime>
diff --git a/Software/Visual_Studio/Scripting/Tango.Scripting.Editors/packages.config b/Software/Visual_Studio/Scripting/Tango.Scripting.Editors/packages.config
index a0f62a1d4..00eef19db 100644
--- a/Software/Visual_Studio/Scripting/Tango.Scripting.Editors/packages.config
+++ b/Software/Visual_Studio/Scripting/Tango.Scripting.Editors/packages.config
@@ -4,7 +4,6 @@
<package id="Microsoft.CodeAnalysis.Analyzers" version="1.1.0" targetFramework="net461" />
<package id="Microsoft.CodeAnalysis.Common" version="2.4.0" targetFramework="net461" />
<package id="Microsoft.CodeAnalysis.CSharp" version="2.4.0" targetFramework="net461" />
- <package id="Newtonsoft.Json" version="9.0.1" targetFramework="net461" />
<package id="System.AppContext" version="4.3.0" targetFramework="net461" />
<package id="System.Collections" version="4.3.0" targetFramework="net461" />
<package id="System.Collections.Concurrent" version="4.3.0" targetFramework="net461" />