aboutsummaryrefslogtreecommitdiffstats
path: root/Software/Visual_Studio/Scripting
diff options
context:
space:
mode:
authorShlomo Hecht <shlomo@twine-s.com>2020-10-29 15:55:21 +0200
committerShlomo Hecht <shlomo@twine-s.com>2020-10-29 15:55:21 +0200
commit4b789f33eadfc5cc1d937a80ce03ea8425955ffe (patch)
tree7dbbd0529a24f9ca064cab688a0d6d2b8b762ea1 /Software/Visual_Studio/Scripting
parent8f3baa0d9097aa6ed800863a4680608e867c809a (diff)
parent11fb700fcbc4627162a9c3f84b03b5016248bd97 (diff)
downloadTango-4b789f33eadfc5cc1d937a80ce03ea8425955ffe.tar.gz
Tango-4b789f33eadfc5cc1d937a80ce03ea8425955ffe.zip
Merge branch 'master' of https://twinetfs.visualstudio.com/Tango/_git/Tango
Diffstat (limited to 'Software/Visual_Studio/Scripting')
-rw-r--r--Software/Visual_Studio/Scripting/Tango.Scripting.Basic/Project.cs183
-rw-r--r--Software/Visual_Studio/Scripting/Tango.Scripting.Core/BreakPoint.cs14
-rw-r--r--Software/Visual_Studio/Scripting/Tango.Scripting.Core/ScriptBreakPoint.cs23
-rw-r--r--Software/Visual_Studio/Scripting/Tango.Scripting.Core/ScriptBreakPointSymbol.cs16
-rw-r--r--Software/Visual_Studio/Scripting/Tango.Scripting.Core/Tango.Scripting.Core.csproj3
-rw-r--r--Software/Visual_Studio/Scripting/Tango.Scripting.Editors/BreakPointSymbolPressedEventArgs.cs16
-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.xshd2
-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.pngbin0 -> 453 bytes
-rw-r--r--Software/Visual_Studio/Scripting/Tango.Scripting.Editors/Images/snippet.pngbin0 -> 147 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/HideIntellisenseAttribute.cs12
-rw-r--r--Software/Visual_Studio/Scripting/Tango.Scripting.Editors/Intellisense/KnownType.cs43
-rw-r--r--Software/Visual_Studio/Scripting/Tango.Scripting.Editors/Intellisense/SnippetCompletionItem.cs26
-rw-r--r--Software/Visual_Studio/Scripting/Tango.Scripting.Editors/Rendering/TextView.cs2
-rw-r--r--Software/Visual_Studio/Scripting/Tango.Scripting.Editors/ScriptEditor.cs761
-rw-r--r--Software/Visual_Studio/Scripting/Tango.Scripting.Editors/Tango.Scripting.Editors.csproj13
-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.xaml104
-rw-r--r--Software/Visual_Studio/Scripting/Tango.Scripting.Editors/XamlEditor.cs47
-rw-r--r--Software/Visual_Studio/Scripting/Tango.Scripting/Parsing/ScriptParser.cs41
-rw-r--r--Software/Visual_Studio/Scripting/Tango.Scripting/Parsing/ScriptSymbol.cs4
29 files changed, 3784 insertions, 1348 deletions
diff --git a/Software/Visual_Studio/Scripting/Tango.Scripting.Basic/Project.cs b/Software/Visual_Studio/Scripting/Tango.Scripting.Basic/Project.cs
index fef43a35f..7500e404f 100644
--- a/Software/Visual_Studio/Scripting/Tango.Scripting.Basic/Project.cs
+++ b/Software/Visual_Studio/Scripting/Tango.Scripting.Basic/Project.cs
@@ -21,6 +21,10 @@ namespace Tango.Scripting.Basic
{
public class Project<T> : ExtendedObject where T : IContext
{
+ private object _compileLock = new object();
+
+ public String ID { get; set; }
+
private String _name;
public String Name
{
@@ -35,6 +39,22 @@ namespace Tango.Scripting.Basic
set { _description = value; RaisePropertyChangedAuto(); }
}
+ private bool _isRunning;
+ [JsonIgnore]
+ public bool IsRunning
+ {
+ get { return _isRunning; }
+ set { _isRunning = value; RaisePropertyChangedAuto(); }
+ }
+
+ private bool _isCompiling;
+ [JsonIgnore]
+ public bool IsCompiling
+ {
+ get { return _isCompiling; }
+ set { _isCompiling = value; RaisePropertyChangedAuto(); }
+ }
+
public ApartmentState ApartmentState { get; set; }
public ObservableCollection<ReferenceAssembly> ReferenceAssemblies { get; set; }
@@ -50,106 +70,134 @@ namespace Tango.Scripting.Basic
}
}
+ [JsonIgnore]
+ public List<ScriptBreakPoint> BreakPoints { get; set; }
+
public Project()
{
+ ID = Guid.NewGuid().ToString();
+
ApartmentState = ApartmentState.MTA;
ReferenceAssemblies = new ObservableCollection<ReferenceAssembly>();
Scripts = new ObservableCollection<Script>();
Scripts.CollectionChanged += (x, e) => { RaisePropertyChanged(nameof(AdditionalScripts)); };
+
+ BreakPoints = new List<ScriptBreakPoint>();
}
public Task<CompilationResult> Compile()
{
return Task.Factory.StartNew<CompilationResult>(() =>
{
- var result = new CompilationResult();
- var tempFolder = TemporaryManager.CreateFolder(Name);
- result.TemporaryProjectPath = tempFolder;
+ lock (_compileLock)
+ {
+ try
+ {
+ IsCompiling = true;
+ var result = new CompilationResult();
+ var tempFolder = TemporaryManager.CreateFolder(Name + "_" + ID);
+ result.TemporaryProjectPath = tempFolder;
- String mainScriptCode = String.Empty;
+ String mainScriptCode = String.Empty;
- foreach (var script in Scripts)
- {
- script.LoadCount = 0;
- script.LoadCharCount = 0;
- String code = script.Code;
- String codeFile = Path.Combine(tempFolder, script.Name);
+ foreach (var script in Scripts)
+ {
+ script.LoadCount = 0;
+ script.LoadCharCount = 0;
+ String code = script.Code;
+ String codeFile = Path.Combine(tempFolder, script.Name);
- String loadingString = String.Empty;
+ String loadingString = String.Empty;
- foreach (var file in Scripts.Where(x => !x.IsEntryPoint && script != x).Select(x => Path.Combine(tempFolder, x.Name)))
- {
- loadingString = $"#load \"{file}\"\n";
- script.LoadCount++;
- script.LoadCharCount += loadingString.Length;
- }
+ foreach (var file in Scripts.Where(x => !x.IsEntryPoint && script != x).Select(x => Path.Combine(tempFolder, x.Name)))
+ {
+ loadingString += $"#load \"{file}\"\n";
+ script.LoadCount++;
+ }
- code = loadingString + code;
+ script.LoadCharCount += loadingString.Length;
- if (!script.IsEntryPoint)
- {
- //In case we use #load
- //foreach (var match in Regex.Matches(code, "#load \".+\"").OfType<Match>())
- //{
- // String line = match.ToString();
- // var pathMatch = Regex.Match(line, "(?<=\")(.*?)(?=\")");
- // if (pathMatch.Success)
- // {
- // String path = pathMatch.ToString();
+ code = loadingString + code;
- // if (!System.IO.Path.IsPathRooted(path))
- // {
- // StringBuilder builder = new StringBuilder(code);
- // builder.Insert(match.Index + pathMatch.Index, System.IO.Path.GetFullPath(tempFolder + "\\"));
- // code = builder.ToString();
- // }
- // }
- //}
- File.WriteAllText(codeFile, code);
- }
- else
- {
- code += Environment.NewLine + Environment.NewLine + "new Program().OnExecute(GlobalContext);";
- mainScriptCode = code;
- }
- }
+ int debugLinesLength = 0;
- var scriptOptions = ScriptOptions.Default.WithReferences(LoadReferenceAssemblies());
+ foreach (var breakPoint in BreakPoints.Where(x => x.Script == script).OrderBy(x => x.LineNumber))
+ {
+ var debugLine = $"context.BreakPoint(\"{script.Name}\",{breakPoint.LineNumber}";
- var s = CSharpScript.Create<object>(mainScriptCode, scriptOptions, typeof(GlobalObject<T>));
- result.Script = s;
+ foreach (var symbol in breakPoint.ContextSymbols)
+ {
+ debugLine += $",\"{symbol.Name}\",{symbol.Offset},{symbol.Length},{symbol.Name}";
+ }
- var compileResults = s.Compile();
+ debugLine += ");";
- GC.Collect();
+ StringBuilder builder = new StringBuilder(code);
+ builder.Insert(breakPoint.LineStartOffset + loadingString.Length + debugLinesLength, debugLine);
+ code = builder.ToString();
- foreach (var error in compileResults.Where(x => x.Severity == Microsoft.CodeAnalysis.DiagnosticSeverity.Error))
- {
- CompilationError cError = new CompilationError();
- cError.File = System.IO.Path.GetFileName(error.Location.SourceTree.FilePath);
- if (cError.File == String.Empty)
+ debugLinesLength += debugLine.Length;
+ }
+
+ if (!script.IsEntryPoint)
+ {
+ File.WriteAllText(codeFile, code);
+ }
+ else
+ {
+ code += Environment.NewLine + Environment.NewLine + "new Program().OnExecute(GlobalContext);";
+ mainScriptCode = code;
+ }
+ }
+
+ var scriptOptions = ScriptOptions.Default.WithReferences(LoadReferenceAssemblies()).WithEmitDebugInformation(true);
+
+ var s = CSharpScript.Create<object>(mainScriptCode, scriptOptions, typeof(GlobalObject<T>));
+
+ result.Script = s;
+
+ var compileResults = s.Compile();
+
+ GC.Collect();
+
+ foreach (var error in compileResults.Where(x => x.Severity == Microsoft.CodeAnalysis.DiagnosticSeverity.Error))
+ {
+ CompilationError cError = new CompilationError();
+ cError.File = System.IO.Path.GetFileName(error.Location.SourceTree.FilePath);
+ if (cError.File == String.Empty)
+ {
+ cError.File = Scripts.Single(x => x.IsEntryPoint).Name;
+ }
+ Script errorScript = Scripts.Single(x => x.Name == cError.File);
+ cError.Message = error.GetMessage();
+ cError.Severity = error.Severity;
+ cError.Position = error.Location.SourceSpan.Start - (errorScript != null ? errorScript.LoadCharCount : 0);
+ var line = error.Location.GetMappedLineSpan();
+ cError.Line = line.StartLinePosition.Line + 1 - (errorScript != null ? errorScript.LoadCount : 0);
+ cError.Column = line.StartLinePosition.Character + 1;
+ cError.Length = line.EndLinePosition.Character - line.StartLinePosition.Character;
+ result.Errors.Add(cError);
+ }
+
+ return result;
+ }
+ catch (Exception)
+ {
+ throw;
+ }
+ finally
{
- cError.File = Scripts.Single(x => x.IsEntryPoint).Name;
+ IsCompiling = false;
}
- Script errorScript = Scripts.Single(x => x.Name == cError.File);
- cError.Message = error.GetMessage();
- cError.Severity = error.Severity;
- cError.Position = error.Location.SourceSpan.Start - (errorScript != null ? errorScript.LoadCharCount : 0);
- var line = error.Location.GetMappedLineSpan();
- cError.Line = line.StartLinePosition.Line + 1 - (errorScript != null ? errorScript.LoadCount : 0);
- cError.Column = line.StartLinePosition.Character + 1;
- cError.Length = line.EndLinePosition.Character - line.StartLinePosition.Character;
- result.Errors.Add(cError);
}
-
- return result;
});
}
public async Task<ProjectSession<T>> Run(T context)
{
+ IsRunning = true;
var result = await Compile();
if (result.Errors.Count > 0)
@@ -170,6 +218,7 @@ namespace Tango.Scripting.Basic
try
{
var runResult = result.Script.RunAsync(globals: new GlobalObject<T>() { GlobalContext = context }).Result;
+ IsRunning = false;
session.Completed(runResult.ReturnValue);
}
catch (ThreadAbortException)
@@ -182,7 +231,9 @@ namespace Tango.Scripting.Basic
}
finally
{
+ BreakPoints.Clear();
GC.Collect();
+ IsRunning = false;
}
});
diff --git a/Software/Visual_Studio/Scripting/Tango.Scripting.Core/BreakPoint.cs b/Software/Visual_Studio/Scripting/Tango.Scripting.Core/BreakPoint.cs
new file mode 100644
index 000000000..e847ea03e
--- /dev/null
+++ b/Software/Visual_Studio/Scripting/Tango.Scripting.Core/BreakPoint.cs
@@ -0,0 +1,14 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace Tango.Scripting.Core
+{
+ public class BreakPoint
+ {
+ public int LineNumber { get; set; }
+ public bool IsActive { get; set; }
+ }
+}
diff --git a/Software/Visual_Studio/Scripting/Tango.Scripting.Core/ScriptBreakPoint.cs b/Software/Visual_Studio/Scripting/Tango.Scripting.Core/ScriptBreakPoint.cs
new file mode 100644
index 000000000..626c1abc6
--- /dev/null
+++ b/Software/Visual_Studio/Scripting/Tango.Scripting.Core/ScriptBreakPoint.cs
@@ -0,0 +1,23 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using Tango.Scripting.Core;
+
+namespace Tango.Scripting.Core
+{
+ public class ScriptBreakPoint
+ {
+ public IScriptSource Script { get; set; }
+ public int LineNumber { get; set; }
+ public int LineStartOffset { get; set; }
+ public int LineEndOffset { get; set; }
+ public List<ScriptBreakPointSymbol> ContextSymbols { get; set; }
+
+ public ScriptBreakPoint()
+ {
+ ContextSymbols = new List<ScriptBreakPointSymbol>();
+ }
+ }
+}
diff --git a/Software/Visual_Studio/Scripting/Tango.Scripting.Core/ScriptBreakPointSymbol.cs b/Software/Visual_Studio/Scripting/Tango.Scripting.Core/ScriptBreakPointSymbol.cs
new file mode 100644
index 000000000..8da35fe55
--- /dev/null
+++ b/Software/Visual_Studio/Scripting/Tango.Scripting.Core/ScriptBreakPointSymbol.cs
@@ -0,0 +1,16 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace Tango.Scripting.Core
+{
+ public class ScriptBreakPointSymbol
+ {
+ public String Name { get; set; }
+ public int Offset { get; set; }
+ public int Length { get; set; }
+ public Object SymbolObject { get; set; }
+ }
+}
diff --git a/Software/Visual_Studio/Scripting/Tango.Scripting.Core/Tango.Scripting.Core.csproj b/Software/Visual_Studio/Scripting/Tango.Scripting.Core/Tango.Scripting.Core.csproj
index aa4bbb240..bb623a4fe 100644
--- a/Software/Visual_Studio/Scripting/Tango.Scripting.Core/Tango.Scripting.Core.csproj
+++ b/Software/Visual_Studio/Scripting/Tango.Scripting.Core/Tango.Scripting.Core.csproj
@@ -41,8 +41,11 @@
<Reference Include="System.Xml" />
</ItemGroup>
<ItemGroup>
+ <Compile Include="BreakPoint.cs" />
<Compile Include="IScriptSource.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
+ <Compile Include="ScriptBreakPoint.cs" />
+ <Compile Include="ScriptBreakPointSymbol.cs" />
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
</Project> \ No newline at end of file
diff --git a/Software/Visual_Studio/Scripting/Tango.Scripting.Editors/BreakPointSymbolPressedEventArgs.cs b/Software/Visual_Studio/Scripting/Tango.Scripting.Editors/BreakPointSymbolPressedEventArgs.cs
new file mode 100644
index 000000000..1728bb565
--- /dev/null
+++ b/Software/Visual_Studio/Scripting/Tango.Scripting.Editors/BreakPointSymbolPressedEventArgs.cs
@@ -0,0 +1,16 @@
+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/Editing/BreakPointMargin.cs b/Software/Visual_Studio/Scripting/Tango.Scripting.Editors/Editing/BreakPointMargin.cs
new file mode 100644
index 000000000..e566e6aa9
--- /dev/null
+++ b/Software/Visual_Studio/Scripting/Tango.Scripting.Editors/Editing/BreakPointMargin.cs
@@ -0,0 +1,285 @@
+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
new file mode 100644
index 000000000..dcbf8388a
--- /dev/null
+++ b/Software/Visual_Studio/Scripting/Tango.Scripting.Editors/Errors/ITextMarker.cs
@@ -0,0 +1,169 @@
+// 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
new file mode 100644
index 000000000..2bb3d8e03
--- /dev/null
+++ b/Software/Visual_Studio/Scripting/Tango.Scripting.Editors/Errors/TextMarkerService.cs
@@ -0,0 +1,365 @@
+// 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 1605ff281..d112c6141 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.GetGenericTypeDefinition().GetGenericArguments())
+ foreach (var lGenericArgument in type.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 a05d1fc75..72c27f9a9 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.SetForegroundBrush(Brush));
+ ChangeLinePart(StartOffset, EndOffset, element => element.TextRunProperties.SetBackgroundBrush(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 6f400c4f5..1f6139ff6 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" exampleText="this.Do(); base.Do();"/>
+ <Color name="ThisOrBaseReference" foreground="#3F8FD6" 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;"/>
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 ead5045ab..8e02db898 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,7 +5,6 @@
<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 " />
@@ -43,12 +42,6 @@
<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 8f0bdef76..50fdc0e2c 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="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="#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="Teal" name="Entity" exampleText="index.aspx?a=1&amp;amp;b=2" />
- <Color foreground="Olive" name="BrokenEntity" exampleText="index.aspx?a=1&amp;b=2" />
+ <Color foreground="Red" 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
new file mode 100644
index 000000000..e8d367028
--- /dev/null
+++ b/Software/Visual_Studio/Scripting/Tango.Scripting.Editors/Images/break_point_arrow.png
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
new file mode 100644
index 000000000..fe4d71eb4
--- /dev/null
+++ b/Software/Visual_Studio/Scripting/Tango.Scripting.Editors/Images/snippet.png
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 c8beebd28..191f99b6c 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,Text);
+ editor.Document.Replace(index, word.Length, GetCode());
}
public abstract BitmapSource Image { get; }
@@ -41,6 +41,11 @@ 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/HideIntellisenseAttribute.cs b/Software/Visual_Studio/Scripting/Tango.Scripting.Editors/Intellisense/HideIntellisenseAttribute.cs
new file mode 100644
index 000000000..548bd909e
--- /dev/null
+++ b/Software/Visual_Studio/Scripting/Tango.Scripting.Editors/Intellisense/HideIntellisenseAttribute.cs
@@ -0,0 +1,12 @@
+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 3dc465541..8010dc689 100644
--- a/Software/Visual_Studio/Scripting/Tango.Scripting.Editors/Intellisense/KnownType.cs
+++ b/Software/Visual_Studio/Scripting/Tango.Scripting.Editors/Intellisense/KnownType.cs
@@ -1,6 +1,8 @@
-using System;
+using Newtonsoft.Json;
+using System;
using System.Collections;
using System.Collections.Generic;
+using System.Drawing;
using System.IO;
using System.Linq;
using System.Reflection;
@@ -42,6 +44,13 @@ namespace Tango.Scripting.Editors.Intellisense
}
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...";
@@ -123,9 +132,31 @@ 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();
@@ -136,11 +167,13 @@ 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;
+ m.IsStatic = method.IsStatic && !method.IsDefined(typeof(System.Runtime.CompilerServices.ExtensionAttribute), false);
if (method.IsGenericMethod)
{
@@ -182,12 +215,14 @@ namespace Tango.Scripting.Editors.Intellisense
//Load Properties
{
- var properties = Type.GetProperties(BindingFlags.FlattenHierarchy | BindingFlags.Public | BindingFlags.Instance).ToList();
+ var properties = Type.GetProperties(BindingFlags.FlattenHierarchy | BindingFlags.Public | BindingFlags.Instance | BindingFlags.Static).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;
@@ -205,6 +240,8 @@ namespace Tango.Scripting.Editors.Intellisense
{
var ev = events[i];
+ if (ev.GetCustomAttribute<HideIntellisenseAttribute>() != null) continue;
+
KnownTypeEvent p = new KnownTypeEvent(this);
p.Name = ev.Name;
diff --git a/Software/Visual_Studio/Scripting/Tango.Scripting.Editors/Intellisense/SnippetCompletionItem.cs b/Software/Visual_Studio/Scripting/Tango.Scripting.Editors/Intellisense/SnippetCompletionItem.cs
new file mode 100644
index 000000000..97807ed19
--- /dev/null
+++ b/Software/Visual_Studio/Scripting/Tango.Scripting.Editors/Intellisense/SnippetCompletionItem.cs
@@ -0,0 +1,26 @@
+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/Rendering/TextView.cs b/Software/Visual_Studio/Scripting/Tango.Scripting.Editors/Rendering/TextView.cs
index 3dabb6b7a..1b1f12ff3 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.Blue));
+ new FrameworkPropertyMetadata(Brushes.Gray));
/// <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 f63cedcdc..e65ff671d 100644
--- a/Software/Visual_Studio/Scripting/Tango.Scripting.Editors/ScriptEditor.cs
+++ b/Software/Visual_Studio/Scripting/Tango.Scripting.Editors/ScriptEditor.cs
@@ -4,6 +4,7 @@ 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;
@@ -46,7 +47,10 @@ 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;
@@ -56,6 +60,12 @@ 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;
@@ -63,14 +73,35 @@ namespace Tango.Scripting.Editors
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; }
@@ -160,6 +191,55 @@ namespace Tango.Scripting.Editors
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
#region Constructors
@@ -171,6 +251,8 @@ namespace Tango.Scripting.Editors
{
DefaultStyleKeyProperty.OverrideMetadata(typeof(ScriptEditor), new FrameworkPropertyMetadata(typeof(ScriptEditor)));
+ snippets = new List<SnippetCompletionItem>();
+
BlockedUsingsCache = new List<string>();
if (KNOWN_TYPES_CACHE_FOLDER == null)
@@ -188,6 +270,67 @@ namespace Tango.Scripting.Editors
_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>
@@ -208,6 +351,8 @@ namespace Tango.Scripting.Editors
_knownTypes = new List<KnownType>();
_parser = new ScriptParser();
+ KnownTypesAvailable += ScriptEditor_KnownTypesAvailable;
+
TextArea.IndentationStrategy = new Indentation.CSharp.CSharpIndentationStrategy(Options);
foldingStrategy = new BraceFoldingStrategy();
@@ -227,6 +372,36 @@ namespace Tango.Scripting.Editors
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;
@@ -377,6 +552,8 @@ namespace Tango.Scripting.Editors
private void TextArea_TextEntered(object sender, TextCompositionEventArgs e)
{
+ if (IsReadOnly) return;
+
try
{
List<Object> items = new List<object>();
@@ -394,19 +571,19 @@ namespace Tango.Scripting.Editors
if (e.Text == " " && previousWords.Count > 2 && previousWords[previousWords.Count - 2] == "=")
{
var expression = previousWords.First();
- var knownType = GetKnownTypeFromExpression(expression + ".");
+ var knownTypeResult = GetKnownTypeFromExpression(expression + ".");
- if (knownType != null && knownType.Type.IsEnum)
+ if (knownTypeResult != null && knownTypeResult.KnownType.Type.IsEnum)
{
completionWindow.HideCompletion();
IList<ICompletionData> data = new List<ICompletionData>();
- foreach (var field in knownType.Fields)
+ foreach (var field in knownTypeResult.KnownType.Fields)
{
data.Add(new FieldCompletionItem()
{
- Class = knownType.FriendlyName,
- Name = knownType.FriendlyName + "." + field.Name,
+ Class = knownTypeResult.KnownType.FriendlyName,
+ Name = knownTypeResult.KnownType.FriendlyName + "." + field.Name,
Type = field.ReturnTypeFriendlyName,
Description = field.Summary,
});
@@ -441,25 +618,25 @@ namespace Tango.Scripting.Editors
}
else if (e.Text == ".")
{
- var knownType = GetCurrentKnownType();
+ var knownTypeResult = GetCurrentKnownType();
IList<ICompletionData> data = new List<ICompletionData>();
- if (knownType != null)
+ if (knownTypeResult != null)
{
completionWindow.HideCompletion();
- if (!knownType.Type.IsEnum)
+ if (!knownTypeResult.KnownType.Type.IsEnum)
{
- var typeMembers = knownType.Members.ToList();
+ var typeMembers = knownTypeResult.KnownType.Members.ToList();
- foreach (var methodGroup in typeMembers.OfType<KnownTypeMethod>().Where(x => !x.IsStatic).GroupBy(x => x.NameWithTypeArguments))
+ foreach (var methodGroup in typeMembers.OfType<KnownTypeMethod>().Where(x => (!knownTypeResult.IsStatic && !x.IsStatic) || (knownTypeResult.IsStatic && x.IsStatic)).GroupBy(x => x.NameWithTypeArguments))
{
var method = methodGroup.First();
data.Add(new MethodCompletionItem()
{
- Class = knownType.FriendlyName,
+ Class = knownTypeResult.KnownType.FriendlyName,
Name = method.NameWithTypeArguments,
ReturnType = method.ReturnTypeFriendlyName,
Description = method.Summary,
@@ -472,7 +649,7 @@ namespace Tango.Scripting.Editors
{
data.Add(new EventCompletionItem()
{
- Class = knownType.FriendlyName,
+ Class = knownTypeResult.KnownType.FriendlyName,
Name = ev.Name,
Description = ev.Summary,
});
@@ -484,7 +661,7 @@ namespace Tango.Scripting.Editors
data.Add(new PropertyCompletionItem()
{
- Class = knownType.FriendlyName,
+ Class = knownTypeResult.KnownType.FriendlyName,
Name = member.Name,
Type = member.ReturnTypeFriendlyName,
Description = member.Summary,
@@ -493,11 +670,11 @@ namespace Tango.Scripting.Editors
}
else
{
- foreach (var field in knownType.Fields)
+ foreach (var field in knownTypeResult.KnownType.Fields)
{
data.Add(new FieldCompletionItem()
{
- Class = knownType.FriendlyName,
+ Class = knownTypeResult.KnownType.FriendlyName,
Name = field.Name,
Type = field.ReturnTypeFriendlyName,
Description = field.Summary,
@@ -573,34 +750,6 @@ namespace Tango.Scripting.Editors
ShowCompletionWindow(data, GetCurrentWord());
}
- else
- {
- //Maybe static ...
- var typeText = GetPreviousWord();
- knownType = _knownTypes.FirstOrDefault(x => x.FriendlyName == typeText || x.Alias == typeText);
-
- if (knownType != null)
- {
- var typeMembers = knownType.Members.ToList();
-
- foreach (var methodGroup in typeMembers.OfType<KnownTypeMethod>().Where(x => x.IsStatic).GroupBy(x => x.NameWithTypeArguments))
- {
- var method = methodGroup.First();
-
- data.Add(new MethodCompletionItem()
- {
- Class = knownType.FriendlyName,
- Name = method.NameWithTypeArguments,
- ReturnType = method.ReturnTypeFriendlyName,
- Description = method.Summary,
- Parameters = method.Parameters,
- Overloads = methodGroup.Count() - 1,
- });
- }
-
- ShowCompletionWindow(data.OrderBy(x => x.Text).ToList(), GetCurrentWord());
- }
- }
}
}
else if (e.Text == "(" || e.Text == ",")
@@ -746,6 +895,11 @@ namespace Tango.Scripting.Editors
{
IList<ICompletionData> data = new List<ICompletionData>();
+ foreach (var snippet in snippets)
+ {
+ data.Add(snippet);
+ }
+
foreach (var type in _declaredTypes.Where(x => x.Name.StartsWith(word)))
{
if (type.Kind == TypeKind.Struct)
@@ -993,13 +1147,13 @@ namespace Tango.Scripting.Editors
return list;
}
- private KnownType GetCurrentKnownType()
+ private KnownTypeResult GetCurrentKnownType()
{
var expression = GetPreviousWords().LastOrDefault();
return GetKnownTypeFromExpression(expression);
}
- private KnownType GetKnownTypeFromExpression(String expression)
+ private KnownTypeResult GetKnownTypeFromExpression(String expression)
{
if (expression != null)
{
@@ -1020,7 +1174,7 @@ namespace Tango.Scripting.Editors
if (enumType != null)
{
- return enumType;
+ return new KnownTypeResult(enumType);
}
tree.RemoveAt(0);
@@ -1048,9 +1202,37 @@ namespace Tango.Scripting.Editors
knownType = _knownTypes.FirstOrDefault(x => x.Type.Namespace + "." + x.Type.Name == member.ReturnType.Namespace + "." + member.ReturnType.Name);
}
- return knownType;
+ 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);
+ }
+ }
+ }
+ }
}
}
+ else
+ {
+ //Maybe static...
+ var type = _knownTypes.FirstOrDefault(x => x.Name == variableName || x.Alias == variableName);
+ return type != null ? new KnownTypeResult(type) { IsStatic = true } : null;
+ }
}
}
@@ -1102,6 +1284,11 @@ namespace Tango.Scripting.Editors
return declaredType;
}
}
+ else
+ {
+ //Maybe static...
+ return _declaredTypes.FirstOrDefault(x => x.Name == variableName);
+ }
}
}
@@ -1191,7 +1378,7 @@ namespace Tango.Scripting.Editors
foreach (var m in session.Type.Methods.Where(x => x.Name == session.MethodName))
{
MethodDescription method = new MethodDescription();
- method.ReturnType = session.Type.Name;
+ method.ReturnType = m.ReturnTypeFriendlyName;
method.Description = m.Summary;
method.Name = m.NameWithTypeArguments;
method.Class = session.Type.FriendlyName;
@@ -1284,7 +1471,7 @@ namespace Tango.Scripting.Editors
return popup;
}
- public static void LoadUsingsSymbols(List<Assembly> assemblies, List<String> usings)
+ public void LoadUsingsSymbols(List<Assembly> assemblies, List<String> usings)
{
lock (_loadUsingsLock)
{
@@ -1296,6 +1483,12 @@ namespace Tango.Scripting.Editors
{
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))
@@ -1317,6 +1510,9 @@ namespace Tango.Scripting.Editors
_knownTypesCache.Add(knownType.Type, knownType);
}
+ KnownTypesAvailable?.Invoke(this, new EventArgs());
+ InvalidateHighlightingPartial();
+
continue;
}
@@ -1370,13 +1566,17 @@ namespace Tango.Scripting.Editors
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 => x == use))
+ if (!BlockedUsingsCache.Exists(x => use.StartsWith(x)))
{
Task.Factory.StartNew(() =>
{
@@ -1387,6 +1587,11 @@ namespace Tango.Scripting.Editors
}
}
+ if (_isUsingsLoadingStarted)
+ {
+ UsingsLoadingCompleted?.Invoke(this, new EventArgs());
+ }
+
LoadingSymbolsCompleted?.Invoke(null, new EventArgs());
}
}
@@ -1502,6 +1707,100 @@ namespace Tango.Scripting.Editors
// _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)
{
if (!_isLoadingTypes)
@@ -1509,6 +1808,7 @@ namespace Tango.Scripting.Editors
_isLoadingTypes = true;
var assemblies = ReferenceAssemblies.ToList();
+ KnownType.ExtensionMethodsAssemblies = assemblies.ToList();
var usings = _current_usings.ToList();
Thread t = new Thread(() =>
@@ -1876,6 +2176,8 @@ namespace Tango.Scripting.Editors
currentLine = currentLine.Split('(')[currentLine.Split('(').Length - 2];
}
+ currentLine = Regex.Replace(currentLine, "(?<=\")(.*?)(?=\")", string.Empty);
+
var words = currentLine.Split(' ');
if (words.Count() > 0 && (words.First() == "private" || words.First() == "public" || words.First() == "void"))
@@ -1888,6 +2190,8 @@ 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();
@@ -2132,6 +2436,363 @@ namespace Tango.Scripting.Editors
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 5f9548262..11e023f86 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
@@ -180,6 +180,7 @@
<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" />
@@ -196,6 +197,9 @@
<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" />
@@ -205,6 +209,7 @@
<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" />
@@ -355,6 +360,7 @@
<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" />
@@ -507,6 +513,7 @@
<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" />
@@ -644,6 +651,12 @@
<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" />
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
new file mode 100644
index 000000000..70a4840c4
--- /dev/null
+++ b/Software/Visual_Studio/Scripting/Tango.Scripting.Editors/Tango.Scripting.Editors_di35u2uj_wpftmp.csproj
@@ -0,0 +1,628 @@
+<?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 d2fc9e02b..cd9977520 100644
--- a/Software/Visual_Studio/Scripting/Tango.Scripting.Editors/TextEditor.cs
+++ b/Software/Visual_Studio/Scripting/Tango.Scripting.Editors/TextEditor.cs
@@ -3,6 +3,7 @@
using System;
using System.ComponentModel;
+using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Text;
@@ -24,1121 +25,1229 @@ 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)
- 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);
- }
- }
- }
- }
- }
+ /// <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);
+ }
+ }
+ }
+ }
+ }
} \ 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 6455b8fcb..5de763df3 100644
--- a/Software/Visual_Studio/Scripting/Tango.Scripting.Editors/Themes/Generic.xaml
+++ b/Software/Visual_Studio/Scripting/Tango.Scripting.Editors/Themes/Generic.xaml
@@ -48,12 +48,18 @@
<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>
@@ -84,95 +90,6 @@
<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>
@@ -224,6 +141,15 @@
<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>
diff --git a/Software/Visual_Studio/Scripting/Tango.Scripting.Editors/XamlEditor.cs b/Software/Visual_Studio/Scripting/Tango.Scripting.Editors/XamlEditor.cs
new file mode 100644
index 000000000..22b425ba2
--- /dev/null
+++ b/Software/Visual_Studio/Scripting/Tango.Scripting.Editors/XamlEditor.cs
@@ -0,0 +1,47 @@
+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/Parsing/ScriptParser.cs b/Software/Visual_Studio/Scripting/Tango.Scripting/Parsing/ScriptParser.cs
index e9cb8fc4c..63d2cca5d 100644
--- a/Software/Visual_Studio/Scripting/Tango.Scripting/Parsing/ScriptParser.cs
+++ b/Software/Visual_Studio/Scripting/Tango.Scripting/Parsing/ScriptParser.cs
@@ -138,9 +138,32 @@ namespace Tango.Scripting.Parsing
varSymbol.Type = type;
varSymbol.Class = ReplaceFakeScript(symbol.ContainingType?.Name);
varSymbol.Kind = symbol.Kind;
+ varSymbol.RealSymbol = symbol;
varSymbol.Accessibility = symbol.DeclaredAccessibility;
varSymbol.ContainingNamespace = ReplaceFakeScript(symbol.ContainingNamespace?.Name);
varSymbol.Summary = GetSymbolDocumentation(symbol);
+
+ try
+ {
+ if (symbol.Kind == SymbolKind.Local && symbol.DeclaringSyntaxReferences.Count() > 0)
+ {
+ var node = symbol.DeclaringSyntaxReferences.First().GetSyntax() as VariableDeclaratorSyntax;
+
+ if (node != null)
+ {
+ varSymbol.IsUnassigned = node.Initializer == null;
+ }
+ }
+ }
+ catch { }
+
+ try
+ {
+ varSymbol.Offset = symbol.Locations[0].SourceSpan.Start;
+ varSymbol.Length = symbol.Locations[0].SourceSpan.Length;
+ }
+ catch { }
+
vars.Add(varSymbol);
if (type == "?")
@@ -417,7 +440,7 @@ namespace Tango.Scripting.Parsing
var root = (CompilationUnitSyntax)tree.GetRoot();
List<VariableDeclaratorSyntax> variables = new List<VariableDeclaratorSyntax>();
- FillVariables(variables, root.Members[0]);
+ FillVariables(variables, new List<SyntaxNode>(), root.Members[0]);
variables = variables.Distinct().ToList();
foreach (var item in variables)
@@ -440,17 +463,27 @@ namespace Tango.Scripting.Parsing
return vars;
}
- private void FillVariables(List<VariableDeclaratorSyntax> variables, SyntaxNode node)
+ private void FillVariables(List<VariableDeclaratorSyntax> variables, List<SyntaxNode> existingNodes, SyntaxNode node)
{
- foreach (var item in node.DescendantNodes(x => true))
+ var nodes = node.ChildNodes().ToList();
+
+ nodes.RemoveAll(x => existingNodes.Contains(x));
+
+ foreach (var item in nodes)
{
+ existingNodes.Add(item);
+
if (item.GetType() == typeof(VariableDeclaratorSyntax))
{
variables.Add(item as VariableDeclaratorSyntax);
}
+ else if (item == node)
+ {
+ continue;
+ }
else
{
- FillVariables(variables, item);
+ FillVariables(variables, existingNodes, item);
}
}
}
diff --git a/Software/Visual_Studio/Scripting/Tango.Scripting/Parsing/ScriptSymbol.cs b/Software/Visual_Studio/Scripting/Tango.Scripting/Parsing/ScriptSymbol.cs
index d6fdaeebf..4b34837af 100644
--- a/Software/Visual_Studio/Scripting/Tango.Scripting/Parsing/ScriptSymbol.cs
+++ b/Software/Visual_Studio/Scripting/Tango.Scripting/Parsing/ScriptSymbol.cs
@@ -17,6 +17,10 @@ namespace Tango.Scripting.Parsing
public String ContainingNamespace { get; set; }
public List<KeyValuePair<String,String>> Parameters { get; set; }
public String Summary { get; set; }
+ public int Offset { get; set; }
+ public int Length { get; set; }
+ public bool IsUnassigned { get; set; }
+ public ISymbol RealSymbol { get; set; }
public ScriptSymbol()
{