Browse Source

- XAML completion is now a bit less intrusive

- removed code duplication from XmlFormattingStrategy
- fixed bugs in XAML code completion
- added AssemblyName property to IProjectContent
- do not close insight and completion windows when they are still needed


git-svn-id: svn://svn.sharpdevelop.net/sharpdevelop/trunk@4280 1ccf3a8d-04fe-1044-b7c0-cef0b8235c61
shortcuts
Siegfried Pammer 17 years ago
parent
commit
485f751cc5
  1. 6
      src/AddIns/BackendBindings/Python/PythonBinding/Test/Utils/MockProjectContent.cs
  2. 32
      src/AddIns/BackendBindings/XamlBinding/XamlBinding.Tests/UtilsTests.cs
  3. 4
      src/AddIns/BackendBindings/XamlBinding/XamlBinding.Tests/XmlTests.cs
  4. 223
      src/AddIns/BackendBindings/XamlBinding/XamlBinding/CompletionDataHelper.cs
  5. 30
      src/AddIns/BackendBindings/XamlBinding/XamlBinding/Extensions.cs
  6. 3
      src/AddIns/BackendBindings/XamlBinding/XamlBinding/MarkupExtensionParser.cs
  7. 74
      src/AddIns/BackendBindings/XamlBinding/XamlBinding/Utils.cs
  8. 4
      src/AddIns/BackendBindings/XamlBinding/XamlBinding/XamlBinding.addin
  9. 42
      src/AddIns/BackendBindings/XamlBinding/XamlBinding/XamlCodeCompletionBinding.cs
  10. 91
      src/AddIns/BackendBindings/XamlBinding/XamlBinding/XamlCompletionItem.cs
  11. 25
      src/AddIns/BackendBindings/XamlBinding/XamlBinding/XamlCompletionItemList.cs
  12. 5
      src/AddIns/BackendBindings/XamlBinding/XamlBinding/XamlContext.cs
  13. 12
      src/AddIns/DisplayBindings/AvalonEdit.AddIn/Src/CodeEditor.cs
  14. 10
      src/AddIns/DisplayBindings/XmlEditor/Project/Src/FormatXmlCommand.cs
  15. 35
      src/AddIns/DisplayBindings/XmlEditor/Project/Src/XmlFormattingStrategy.cs
  16. 4
      src/AddIns/DisplayBindings/XmlEditor/Project/Src/XmlTreeView.cs
  17. 24
      src/AddIns/DisplayBindings/XmlEditor/Project/Src/XmlView.cs
  18. 5
      src/AddIns/DisplayBindings/XmlEditor/Project/XmlEditor.csproj
  19. 6
      src/AddIns/Misc/UnitTesting/Test/Utils/MockProjectContent.cs
  20. 2
      src/Main/Base/Project/Src/Gui/Dialogs/NewFileDialog.cs
  21. 7
      src/Main/Base/Project/Src/Services/ParserService/ParseProjectContent.cs
  22. 7
      src/Main/ICSharpCode.SharpDevelop.Dom/Project/Src/ProjectContent/DefaultProjectContent.cs
  23. 7
      src/Main/ICSharpCode.SharpDevelop.Dom/Project/Src/ProjectContent/IProjectContent.cs
  24. 6
      src/Main/ICSharpCode.SharpDevelop.Dom/Project/Src/ProjectContent/ReflectionProjectContent.cs

6
src/AddIns/BackendBindings/Python/PythonBinding/Test/Utils/MockProjectContent.cs

@ -354,5 +354,11 @@ namespace PythonBinding.Tests.Utils @@ -354,5 +354,11 @@ namespace PythonBinding.Tests.Utils
{
throw new NotImplementedException();
}
public string AssemblyName {
get {
throw new NotImplementedException();
}
}
}
}

32
src/AddIns/BackendBindings/XamlBinding/XamlBinding.Tests/UtilsTests.cs

@ -98,5 +98,37 @@ namespace ICSharpCode.XamlBinding.Tests @@ -98,5 +98,37 @@ namespace ICSharpCode.XamlBinding.Tests
Assert.AreEqual(expectedResult, actualResult);
}
[Test]
public void ExistingAttributesTest()
{
string xaml = "<UserControl\n" +
"\txmlns=\"http://schemas.microsoft.com/winfx/2006/xaml/presentation\"\n" +
"\txmlns:x=\"http://schemas.microsoft.com/winfx/2006/xaml\"\n" +
"\txmlns:toolkit=\"clr-namespace:System.Windows.Controls;assembly=PresentationFramework\"\n" +
"\txmlns:chartingToolkit=\"clr-namespace:XamlTest\" ";
var list = Utils.GetListOfExistingAttributeNames(xaml, xaml.Length);
var expected = new List<string> { "xmlns", "xmlns:x", "xmlns:toolkit", "xmlns:chartingToolkit" };
Assert.AreEqual(expected.Count, list.Length, "Wrong count!");
Assert.AreEqual(list, expected, "Wrong elements!");
}
[Test]
public void ExistingAttributesWithInvalidSyntaxTest()
{
string xaml = "<UserControl\n" +
"\txmlns=\"http://schemas.microsoft.com/winfx/2006/xaml/presentation\"\n" +
"\txmlns:x=\"http://schemas.microsoft.com/winfx/2006/xaml\"\n" +
"\txmlns:toolkit=\"clr-namespace:System.Windows.Controls;assembly=PresentationFramework\"\n" +
"\txmlns:chartingToolkit=\"clr-namespace:XamlTest\" asd ";
var list = Utils.GetListOfExistingAttributeNames(xaml, xaml.Length);
var expected = new List<string> { "xmlns", "xmlns:x", "xmlns:toolkit", "xmlns:chartingToolkit" };
Assert.AreEqual(expected.Count, list.Length, "Wrong count!");
Assert.AreEqual(list, expected, "Wrong elements!");
}
}
}

4
src/AddIns/BackendBindings/XamlBinding/XamlBinding.Tests/XmlTests.cs

@ -66,6 +66,8 @@ namespace ICSharpCode.XamlBinding.Tests @@ -66,6 +66,8 @@ namespace ICSharpCode.XamlBinding.Tests
int offset = "<Test val1=\"{Bin".Length;
Assert.AreEqual(true, XmlParser.IsInsideAttributeValue(xaml, offset));
Assert.AreEqual("{Binding Value}", XmlParser.GetAttributeValueAtIndex(xaml, offset));
Assert.AreEqual("val1", XmlParser.GetAttributeNameAtIndex(xaml, offset));
}
[Test]
@ -75,6 +77,8 @@ namespace ICSharpCode.XamlBinding.Tests @@ -75,6 +77,8 @@ namespace ICSharpCode.XamlBinding.Tests
int offset = "<Test val1=\"{Binding Value, Path=".Length;
Assert.AreEqual(true, XmlParser.IsInsideAttributeValue(xaml, offset));
Assert.AreEqual("{Binding Value, Path=Control}", XmlParser.GetAttributeValueAtIndex(xaml, offset));
Assert.AreEqual("val1", XmlParser.GetAttributeNameAtIndex(xaml, offset));
}
}
}

223
src/AddIns/BackendBindings/XamlBinding/XamlBinding/CompletionDataHelper.cs

@ -5,7 +5,7 @@ @@ -5,7 +5,7 @@
// <version>$Revision$</version>
// </file>
using ICSharpCode.SharpDevelop.Editor.CodeCompletion;
using ICSharpCode.SharpDevelop.Project;
using System;
using System.Collections.Generic;
using System.Diagnostics;
@ -15,6 +15,7 @@ using System.Xml; @@ -15,6 +15,7 @@ using System.Xml;
using ICSharpCode.SharpDevelop;
using ICSharpCode.SharpDevelop.Dom;
using ICSharpCode.SharpDevelop.Editor;
using ICSharpCode.SharpDevelop.Editor.CodeCompletion;
using ICSharpCode.XmlEditor;
using LoggingService = ICSharpCode.Core.LoggingService;
@ -32,6 +33,10 @@ namespace ICSharpCode.XamlBinding @@ -32,6 +33,10 @@ namespace ICSharpCode.XamlBinding
static readonly List<ICompletionItem> standardAttributes = new List<ICompletionItem> {
new DefaultCompletionItem("xmlns:")
};
static readonly List<string> xamlNamespaceAttributes = new List<string> {
"Class", "ClassModifier", "FieldModifier", "Name", "Subclass", "TypeArguments", "Uid"
};
#endregion
public const string XamlNamespace = "http://schemas.microsoft.com/winfx/2006/xaml";
@ -62,7 +67,7 @@ namespace ICSharpCode.XamlBinding @@ -62,7 +67,7 @@ namespace ICSharpCode.XamlBinding
XamlContextDescription description = XamlContextDescription.InTag;
if (path == null || path.Elements.Count == 0) {
description = XamlContextDescription.AtTag;
description = XamlContextDescription.None;
path = XmlParser.GetParentElementPath(text.Substring(0, offset));
} else {
int ltOffset = XmlParser.GetActiveElementStartIndex(text, offset);
@ -71,7 +76,7 @@ namespace ICSharpCode.XamlBinding @@ -71,7 +76,7 @@ namespace ICSharpCode.XamlBinding
else {
string space = text.Substring(ltOffset + 1, offset - ltOffset - 1);
var last = path.Elements.LastOrDefault();
if (last != null && last.ToString().Equals(space, StringComparison.Ordinal))
if (last != null && last.ToString().StartsWith(space, StringComparison.Ordinal))
description = XamlContextDescription.AtTag;
}
}
@ -101,31 +106,96 @@ namespace ICSharpCode.XamlBinding @@ -101,31 +106,96 @@ namespace ICSharpCode.XamlBinding
return context;
}
static List<ICompletionItem> CreateListForAttributeName(ParseInformation parseInfo, XamlExpressionContext context, string[] existingItems)
static List<ICompletionItem> CreateListForAttributeName(ITextEditor editor, ParseInformation parseInfo, XamlExpressionContext context, string[] existingItems)
{
if (context.ElementPath.Elements.Count == 0)
return null;
QualifiedName lastElement = context.ElementPath.Elements[context.ElementPath.Elements.Count - 1];
QualifiedName lastElement = context.ElementPath.Elements.LastOrDefault();
XamlCompilationUnit cu = parseInfo.BestCompilationUnit as XamlCompilationUnit;
if (cu == null)
return null;
IReturnType rt = cu.CreateType(lastElement.Namespace, lastElement.Name);
IReturnType rt = cu.CreateType(lastElement.Namespace, lastElement.Name.Trim('.'));
if (rt == null)
return null;
var list = new List<ICompletionItem>();
string xamlPrefix = Utils.GetXamlNamespacePrefix(editor.Document.Text, editor.Caret.Offset);
foreach (string item in xamlNamespaceAttributes) {
if (!existingItems.Contains(xamlPrefix + ":" + item))
list.Add(new XamlCompletionItem(xamlPrefix, XamlNamespace, item));
}
foreach (IProperty p in rt.GetProperties()) {
if (p.IsPublic && p.CanSet && !existingItems.Contains(p.Name)) {
list.Add(new XamlCompletionItem(p));
list.Add(new XamlCodeCompletionItem(p));
}
}
foreach (IEvent e in rt.GetEvents()) {
if (e.IsPublic && !existingItems.Contains(e.Name)) {
list.Add(new XamlCompletionItem(e));
list.Add(new XamlCodeCompletionItem(e));
}
}
return list;
}
public static IEnumerable<ICompletionItem> CreateListForXmlnsCompletion(IProjectContent projectContent)
{
List<XmlnsCompletionItem> list = new List<XmlnsCompletionItem>();
foreach (IProjectContent content in projectContent.ReferencedContents) {
foreach (IAttribute att in content.GetAssemblyAttributes()) {
if (att.PositionalArguments.Count == 2
&& att.AttributeType.FullyQualifiedName == "System.Windows.Markup.XmlnsDefinitionAttribute") {
list.Add(new XmlnsCompletionItem(att.PositionalArguments[0] as string, true));
}
}
foreach (string @namespace in content.NamespaceNames) {
if (!string.IsNullOrEmpty(@namespace))
list.Add(new XmlnsCompletionItem(@namespace, content.AssemblyName));
}
}
foreach (string @namespace in projectContent.NamespaceNames) {
if (!string.IsNullOrEmpty(@namespace))
list.Add(new XmlnsCompletionItem(@namespace, false));
}
return list
.Distinct(new XmlnsEqualityComparer())
.OrderBy(item => item, new XmlnsComparer())
.Cast<ICompletionItem>();
}
sealed class XmlnsEqualityComparer : IEqualityComparer<XmlnsCompletionItem> {
public bool Equals(XmlnsCompletionItem x, XmlnsCompletionItem y)
{
return x.Namespace == y.Namespace && x.Assembly == y.Assembly;
}
public int GetHashCode(XmlnsCompletionItem obj)
{
return string.IsNullOrEmpty(obj.Assembly) ? obj.Namespace.GetHashCode() : obj.Namespace.GetHashCode() ^ obj.Assembly.GetHashCode();
}
}
sealed class XmlnsComparer : IComparer<XmlnsCompletionItem> {
public int Compare(XmlnsCompletionItem x, XmlnsCompletionItem y)
{
if (x.IsUrl && y.IsUrl)
return x.Namespace.CompareTo(y.Namespace);
if (x.IsUrl)
return -1;
if (y.IsUrl)
return 1;
if (x.Assembly == y.Assembly)
return x.Namespace.CompareTo(y.Namespace);
else
return x.Assembly.CompareTo(y.Assembly);
}
}
static bool IsReaderAtTarget(XmlTextReader r, int caretLine, int caretColumn)
{
if (r.LineNumber > caretLine)
@ -136,18 +206,18 @@ namespace ICSharpCode.XamlBinding @@ -136,18 +206,18 @@ namespace ICSharpCode.XamlBinding
return false;
}
public static IList<ICompletionItem> CreateListForElement(ParseInformation parseInfo, string fileContent, int caretLine, int caretColumn)
public static IList<ICompletionItem> CreateListForElement(ParseInformation parseInfo, string fileContent, int caretLine, int caretColumn, bool addOpeningBrace)
{
var items = GetClassesFromContext(parseInfo, fileContent, caretLine, caretColumn);
var result = new List<ICompletionItem>();
foreach (var ns in items) {
result.AddRange(from c in ns.Value
result.AddRange((from c in ns.Value
where (c.ClassType == ClassType.Class &&
!c.IsAbstract && !c.IsStatic &&
!c.ClassInheritanceTree.Any(b => b.FullyQualifiedName == "System.Attribute") &&
c.Methods.Any(m => m.IsConstructor && m.IsPublic))
select (new XamlCompletionItem(c, ns.Key) as ICompletionItem)
select (new XamlCodeCompletionItem(c, ns.Key, addOpeningBrace))).Cast<ICompletionItem>()
);
}
@ -156,20 +226,21 @@ namespace ICSharpCode.XamlBinding @@ -156,20 +226,21 @@ namespace ICSharpCode.XamlBinding
public static IList<ICompletionItem> CreateListOfMarkupExtensions(ParseInformation parseInfo, string fileContent, int caretLine, int caretColumn)
{
var list = CreateListForElement(parseInfo, fileContent, caretLine, caretColumn);
var list = CreateListForElement(parseInfo, fileContent, caretLine, caretColumn, false);
var neededItems = list
.Where(i => ((i as XamlCompletionItem).Entity as IClass).ClassInheritanceTree
.Where(i => ((i as XamlCodeCompletionItem).Entity as IClass).ClassInheritanceTree
.Any(item => item.FullyQualifiedName == "System.Windows.Markup.MarkupExtension"))
.Select(
selItem => {
var it = selItem as XamlCompletionItem;
var it = selItem as XamlCodeCompletionItem;
string text = it.Text;
if (it.Text.EndsWith("Extension", StringComparison.Ordinal))
text = text.Remove(it.Text.Length - "Extension".Length);
return new XamlCompletionItem(text, it.Entity) as ICompletionItem;
return new XamlCodeCompletionItem(it.Entity, text);
}
);
)
.Cast<ICompletionItem>();
return neededItems.ToList();
}
@ -180,13 +251,23 @@ namespace ICSharpCode.XamlBinding @@ -180,13 +251,23 @@ namespace ICSharpCode.XamlBinding
ParseInformation info = ParserService.GetParseInformation(editor.FileName);
switch (context.Description) {
case XamlContextDescription.None:
if (context.Forced) {
list.Items.AddRange(standardElements.Select(item => new DefaultCompletionItem("<" + item.Text)).Cast<ICompletionItem>());
list.Items.AddRange(CreateListForElement(info, editor.Document.Text, editor.Caret.Line, editor.Caret.Column, true));
}
break;
case XamlContextDescription.AtTag:
list.Items.AddRange(standardElements);
list.Items.AddRange(CreateListForElement(info, editor.Document.Text, editor.Caret.Line, editor.Caret.Column));
if (editor.Document.GetCharAt(editor.Caret.Offset - 1) == '.' || context.PressedKey == '.') {
var existing = Utils.GetListOfExistingAttributeNames(editor.Document.Text, Utils.GetParentElementStart(editor));
list.Items.AddRange(CreateListForAttributeName(editor, info, new XamlExpressionContext(context.Path, null, false), existing).RemoveEvents());
} else
list.Items.AddRange(CreateListForElement(info, editor.Document.Text, editor.Caret.Line, editor.Caret.Column, false));
break;
case XamlContextDescription.InTag:
var existing = Utils.GetListOfExistingAttributeNames(editor.Document.Text, editor.Caret.Offset);
list.Items.AddRange(CreateListForAttributeName(info, new XamlExpressionContext(context.Path, null, false), existing));
var existingAttribs = Utils.GetListOfExistingAttributeNames(editor.Document.Text, editor.Caret.Offset);
list.Items.AddRange(CreateListForAttributeName(editor, info, new XamlExpressionContext(context.Path, null, false), existingAttribs));
QualifiedName last = context.Path.Elements[context.Path.Elements.Count - 1];
@ -194,10 +275,11 @@ namespace ICSharpCode.XamlBinding @@ -194,10 +275,11 @@ namespace ICSharpCode.XamlBinding
if (trr != null && trr.ResolvedType != null && trr.ResolvedType.GetUnderlyingClass() != null) {
if (trr.ResolvedType.GetUnderlyingClass().ClassInheritanceTree.Any(i => i.FullyQualifiedName == "System.Windows.DependencyObject")) {
list.Items.AddRange(GetListOfAttachedProperties(info, editor.Document.Text, editor.Caret.Line, editor.Caret.Column, existing));
list.Items.AddRange(GetListOfAttachedEvents(info, editor.Document.Text, editor.Caret.Line, editor.Caret.Column, existing));
list.Items.AddRange(GetListOfAttachedProperties(info, editor.Document.Text, editor.Caret.Line, editor.Caret.Column, existingAttribs));
list.Items.AddRange(GetListOfAttachedEvents(info, editor.Document.Text, editor.Caret.Line, editor.Caret.Column, existingAttribs));
}
}
list.Items.AddRange(standardAttributes);
break;
case XamlContextDescription.InAttributeValue:
@ -210,6 +292,20 @@ namespace ICSharpCode.XamlBinding @@ -210,6 +292,20 @@ namespace ICSharpCode.XamlBinding
return list;
}
static bool FilterCollectionAttributes(ICompletionItem item)
{
if (item is XamlCodeCompletionItem) {
var comItem = item as XamlCodeCompletionItem;
if (comItem.Entity is IProperty) {
var prop = comItem.Entity as IProperty;
var c = prop.ReturnType.GetUnderlyingClass();
return c != null && c.ClassInheritanceTree.Any(b => b.FullyQualifiedName == "System.Collections.IEnumerable");
}
}
return false;
}
public static IEnumerable<IInsightItem> CreateMarkupExtensionInsight(XamlContext context, ParseInformation info, ITextEditor editor)
{
var markup = GetInnermostMarkup(context.AttributeValue.ExtensionValue);
@ -259,7 +355,7 @@ namespace ICSharpCode.XamlBinding @@ -259,7 +355,7 @@ namespace ICSharpCode.XamlBinding
{
var ctors = trr.ResolvedType.GetMethods().Where(m => m.IsConstructor && m.Parameters.Count >= markup.PositionalArguments.Count);
if (ctors.Any(ctor => ctor.Parameters.Count >= markup.PositionalArguments.Count)) {
list.Items.AddRange(trr.ResolvedType.GetProperties().Select(p => new XamlCompletionItem(p.Name + "=", p) as ICompletionItem));
list.Items.AddRange(trr.ResolvedType.GetProperties().Select(p => new XamlCodeCompletionItem(p, p.Name + "=")).Cast<ICompletionItem>());
}
}
@ -277,7 +373,7 @@ namespace ICSharpCode.XamlBinding @@ -277,7 +373,7 @@ namespace ICSharpCode.XamlBinding
case "System.Windows.Markup.TypeExtension":
if (context.AttributeValue.ExtensionValue.PositionalArguments.Count == 1 && context.PressedKey == ' ') break;
if (context.AttributeValue.ExtensionValue.PositionalArguments.Count <= 1) {
list.Items.AddRange(CreateListForElement(info, editor.Document.Text, editor.Caret.Line, editor.Caret.Column));
list.Items.AddRange(CreateListForElement(info, editor.Document.Text, editor.Caret.Line, editor.Caret.Column, false));
AttributeValue selItem = context.AttributeValue.ExtensionValue.PositionalArguments.LastOrDefault();
if (selItem != null && selItem.IsString) {
string s = selItem.StringValue;
@ -328,7 +424,7 @@ namespace ICSharpCode.XamlBinding @@ -328,7 +424,7 @@ namespace ICSharpCode.XamlBinding
switch (c.ClassType) {
case ClassType.Enum:
foreach (IField f in c.Fields)
yield return new XamlCompletionItem(f);
yield return new XamlCodeCompletionItem(f);
break;
case ClassType.Struct:
if (c.FullyQualifiedName == "System.Boolean") {
@ -343,11 +439,18 @@ namespace ICSharpCode.XamlBinding @@ -343,11 +439,18 @@ namespace ICSharpCode.XamlBinding
if (path != null && path.Elements.Count > 0) {
var item = path.Elements[path.Elements.Count - 1];
string attribute = XmlParser.GetAttributeNameAtIndex(editor.Document.Text, editor.Caret.Offset);
var e = ResolveAttribute(attribute, editor) as IEvent;
if (e == null)
var evt = ResolveAttribute(attribute, editor) as IEvent;
if (evt == null)
break;
string prefix = Utils.GetXamlNamespacePrefix(editor.Document.Text, editor.Caret.Offset);
string name = Utils.GetAttributeValue(editor.Document.Text, editor.Caret.Offset, "name");
yield return new NewEventCompletionItem(e, (string.IsNullOrEmpty(name)) ? item.Name : name);
if (string.IsNullOrEmpty(name))
name = Utils.GetAttributeValue(editor.Document.Text, editor.Caret.Offset, (string.IsNullOrEmpty(prefix) ? "" : prefix + ":") + "name");
Debug.Print("prefix: " + prefix + " name: " + name);
yield return new NewEventCompletionItem(evt, (string.IsNullOrEmpty(name)) ? item.Name : name);
foreach (var eventItem in CompletionDataHelper.AddMatchingEventHandlers(editor, invoker))
yield return eventItem;
@ -355,6 +458,19 @@ namespace ICSharpCode.XamlBinding @@ -355,6 +458,19 @@ namespace ICSharpCode.XamlBinding
}
break;
}
switch (c.FullyQualifiedName) {
case "System.Windows.Media.Brush":
foreach (var item in typeof(System.Windows.Media.Brushes).GetProperties()) {
yield return new DefaultCompletionItem(item.Name);
}
break;
case "System.Windows.Media.Color":
foreach (var item in typeof(System.Windows.Media.Colors).GetProperties()) {
yield return new DefaultCompletionItem(item.Name);
}
break;
}
}
static IEntity ResolveAttribute(string attribute, ITextEditor editor)
@ -401,7 +517,9 @@ namespace ICSharpCode.XamlBinding @@ -401,7 +517,9 @@ namespace ICSharpCode.XamlBinding
{
var items = GetClassesFromContext(info, editor.Document.Text, editor.Caret.Line, editor.Caret.Column);
foreach (var ns in items) {
list.Items.AddRange(ns.Value.Where(c => c.Fields.Any(f => f.IsStatic) || c.Properties.Any(p => p.IsStatic)).Select(c => new XamlCompletionItem(c, ns.Key) as ICompletionItem));
list.Items.AddRange(ns.Value.Where(c => c.Fields.Any(f => f.IsStatic) || c.Properties.Any(p => p.IsStatic))
.Select(c => new XamlCodeCompletionItem(c, ns.Key, false))
.Cast<ICompletionItem>());
}
if (selItem != null && selItem.IsString) {
string s = selItem.StringValue;
@ -473,7 +591,7 @@ namespace ICSharpCode.XamlBinding @@ -473,7 +591,7 @@ namespace ICSharpCode.XamlBinding
break;
}
if (equal) {
yield return new XamlCompletionItem(m);
yield return new XamlCodeCompletionItem(m);
}
}
}
@ -491,15 +609,35 @@ namespace ICSharpCode.XamlBinding @@ -491,15 +609,35 @@ namespace ICSharpCode.XamlBinding
return result;
}
static IDictionary<string, IEnumerable<IClass>> GetClassesFromContext(ParseInformation parseInfo, string fileContent, int caretLine, int caretColumn)
static XmlTextReader CreateReaderAtTarget(string fileContent, int caretLine, int caretColumn)
{
using (XmlTextReader r = new XmlTextReader(new StringReader(fileContent))) {
XmlTextReader r = new XmlTextReader(new StringReader(fileContent));
try {
r.WhitespaceHandling = WhitespaceHandling.Significant;
// move reader to correct position
while (r.Read() && !IsReaderAtTarget(r, caretLine, caretColumn)) { }
} catch (XmlException) {}
return r;
}
static string GetPrefixForNamespace(string @namespace, string fileContent, int caretLine, int caretColumn)
{
using (XmlTextReader r = CreateReaderAtTarget(fileContent, caretLine, caretColumn)) {
foreach (var item in r.GetNamespacesInScope(XmlNamespaceScope.ExcludeXml)) {
if (item.Value == @namespace) {
return item.Key;
}
}
return string.Empty;
}
}
static IDictionary<string, IEnumerable<IClass>> GetClassesFromContext(ParseInformation parseInfo, string fileContent, int caretLine, int caretColumn)
{
using (XmlTextReader r = CreateReaderAtTarget(fileContent, caretLine, caretColumn)) {
IProjectContent pc = parseInfo.BestCompilationUnit.ProjectContent;
var result = new Dictionary<string, IEnumerable<IClass>>();
@ -514,15 +652,8 @@ namespace ICSharpCode.XamlBinding @@ -514,15 +652,8 @@ namespace ICSharpCode.XamlBinding
static List<ICompletionItem> GetListOfAttachedProperties(ParseInformation parseInfo, string fileContent, int caretLine, int caretColumn, string[] existingItems)
{
using (XmlTextReader r = new XmlTextReader(new StringReader(fileContent))) {
try {
r.WhitespaceHandling = WhitespaceHandling.Significant;
// move reader to correct position
while (r.Read() && !IsReaderAtTarget(r, caretLine, caretColumn)) { }
}
catch (XmlException) {
}
var result = new List<ICompletionItem>();
using (XmlTextReader r = CreateReaderAtTarget(fileContent, caretLine, caretColumn)) {
List<ICompletionItem> result = new List<ICompletionItem>();
IProjectContent pc = parseInfo.BestCompilationUnit.ProjectContent;
foreach (var ns in r.GetNamespacesInScope(XmlNamespaceScope.ExcludeXml)) {
@ -561,10 +692,11 @@ namespace ICSharpCode.XamlBinding @@ -561,10 +692,11 @@ namespace ICSharpCode.XamlBinding
string name = (!string.IsNullOrEmpty(ns.Key)) ? ns.Key + ":" : "";
string property = item.Name.Remove(item.Name.Length - "Property".Length);
name += c.Name + "." + item.Name.Remove(item.Name.Length - "Property".Length);
return new XamlCompletionItem(name, new DefaultProperty(c, property) { ReturnType = GetAttachedPropertyType(item, c) } ) as ICompletionItem;
return new XamlCodeCompletionItem(new DefaultProperty(c, property) { ReturnType = GetAttachedPropertyType(item, c) }, name);
}
)
.Where(item => !existingItems.Any(str => str == item.Text))
.Cast<ICompletionItem>()
);
}
}
@ -611,14 +743,15 @@ namespace ICSharpCode.XamlBinding @@ -611,14 +743,15 @@ namespace ICSharpCode.XamlBinding
result.AddRange(attachedEvents
.Select(
item => new XamlCompletionItem(
(string.IsNullOrEmpty(ns.Key) ? "" : ns.Key + ":") + c.Name + "." + item.Name.Remove(item.Name.Length - "Event".Length),
item => new XamlCodeCompletionItem(
new DefaultEvent(c, GetEventNameFromField(item)) {
ReturnType = GetAttachedEventDelegateType(item, c)
}
) as ICompletionItem
},
(string.IsNullOrEmpty(ns.Key) ? "" : ns.Key + ":") + c.Name + "." + item.Name.Remove(item.Name.Length - "Event".Length)
)
)
.Where(item => !existingItems.Any(str => str == item.Text))
.Cast<ICompletionItem>()
);
}
}

30
src/AddIns/BackendBindings/XamlBinding/XamlBinding/Extensions.cs

@ -5,10 +5,13 @@ @@ -5,10 +5,13 @@
// <version>$Revision$</version>
// </file>
using ICSharpCode.SharpDevelop;
using System;
using System.Collections.Generic;
using System.Linq;
using ICSharpCode.SharpDevelop;
using ICSharpCode.SharpDevelop.Dom;
using ICSharpCode.SharpDevelop.Editor.CodeCompletion;
using ICSharpCode.XmlEditor;
namespace ICSharpCode.XamlBinding
@ -36,15 +39,26 @@ namespace ICSharpCode.XamlBinding @@ -36,15 +39,26 @@ namespace ICSharpCode.XamlBinding
return false;
}
public static QualifiedName LastOrDefault(this QualifiedNameCollection collection)
public static IEnumerable<ICompletionItem> RemoveEvents(this IEnumerable<ICompletionItem> list)
{
if (collection == null)
throw new ArgumentNullException("collection");
if (collection.Count > 0)
return collection[collection.Count - 1];
foreach (var item in list) {
if (item is XamlCodeCompletionItem) {
var comItem = item as XamlCodeCompletionItem;
if (!(comItem.Entity is IEvent))
yield return item;
} else yield return item;
}
}
return null;
public static IEnumerable<ICompletionItem> RemoveProperties(this IEnumerable<ICompletionItem> list)
{
foreach (var item in list) {
if (item is XamlCodeCompletionItem) {
var comItem = item as XamlCodeCompletionItem;
if (!(comItem.Entity is IProperty))
yield return item;
} else yield return item;
}
}
}
}

3
src/AddIns/BackendBindings/XamlBinding/XamlBinding/MarkupExtensionParser.cs

@ -27,6 +27,9 @@ namespace ICSharpCode.XamlBinding @@ -27,6 +27,9 @@ namespace ICSharpCode.XamlBinding
info.ExtensionType = token.Value;
break;
case MarkupExtensionTokenKind.MemberName:
// if there is an open member without a value add the member name
if (argumentName != null)
info.NamedArguments.Add(argumentName, new AttributeValue(string.Empty));
argumentName = token.Value;
break;
case MarkupExtensionTokenKind.String:

74
src/AddIns/BackendBindings/XamlBinding/XamlBinding/Utils.cs

@ -5,13 +5,13 @@ @@ -5,13 +5,13 @@
// <version>$Revision$</version>
// </file>
using ICSharpCode.SharpDevelop.Editor;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Xml;
using ICSharpCode.Core;
using ICSharpCode.XmlEditor;
@ -64,7 +64,8 @@ namespace ICSharpCode.XamlBinding @@ -64,7 +64,8 @@ namespace ICSharpCode.XamlBinding
if (text == null)
return null;
XmlReader reader = XmlTextReader.Create(new StringReader(text));
XmlTextReader reader = new XmlTextReader(new StringReader(text));
reader.XmlResolver = null;
try {
reader.ReadToFollowing("Test");
@ -74,13 +75,14 @@ namespace ICSharpCode.XamlBinding @@ -74,13 +75,14 @@ namespace ICSharpCode.XamlBinding
do {
LoggingService.Debug("name: " + reader.Name + " value: " + reader.Value);
int start = reader.Name.IndexOf(':') + 1;
string plainName = reader.Name.Substring(start, reader.Name.Length - start).ToUpperInvariant();
string plainName = reader.Name.ToUpperInvariant();
if (plainName == name.ToUpperInvariant())
return reader.Value;
} while (reader.MoveToNextAttribute());
} catch (XmlException) { }
} catch (XmlException e) {
Debug.Print(e.ToString());
}
return null;
}
@ -183,7 +185,12 @@ namespace ICSharpCode.XamlBinding @@ -183,7 +185,12 @@ namespace ICSharpCode.XamlBinding
LoggingService.Debug("name: " + reader.Name + " value: " + reader.Value);
list.Add(reader.Name);
} while (reader.MoveToNextAttribute());
} catch (XmlException) { }
} catch (XmlException e) {
Debug.Print(e.ToString());
}
foreach (var item in list)
Debug.Print(item);
return list.ToArray();
}
@ -204,18 +211,33 @@ namespace ICSharpCode.XamlBinding @@ -204,18 +211,33 @@ namespace ICSharpCode.XamlBinding
return startIndex;
}
static char[] whitespace = new char[] {' ', '\t', '\n', '\r'};
static string SimplifyToSingleElement(string text, int offset, string name)
{
int index = XmlParser.GetActiveElementStartIndex(text, offset);
if (index == -1) return null;
index = text.IndexOf(' ', index);
index = text.IndexOfAny(whitespace, index);
if (index == -1) return null;
text = text.Substring(index);
int endIndex = text.IndexOfAny(new char[] { '<', '>' });
if (endIndex == -1) return null;
text = text.Substring(0, endIndex).Trim(' ', '\t', '\n', '\r', '/');
LoggingService.Debug("text: '" + text + "'");
text = "<" + name + " " + text + " />";
string newText = text.Substring(index);
int endIndex = newText.IndexOfAny(new char[] { '<', '>' });
if (endIndex == -1)
endIndex = newText.Length;
newText = newText.Substring(0, endIndex).Trim(' ', '\t', '\n', '\r', '/');
LoggingService.Debug("text: '" + newText + "'");
if (!newText.EndsWith("\"") && newText.LastIndexOfAny(whitespace) > -1) {
newText = newText.Substring(0, newText.LastIndexOfAny(whitespace));
}
string namespaceDecls = "";
var list = Utils.GetXmlNamespacesForOffset(text, offset);
foreach (var item in list) {
namespaceDecls += item.Key + "=\"" + item.Value + "\" ";
}
text = "<" + name + " " + newText + " " + namespaceDecls + " />";
return text;
}
@ -237,7 +259,7 @@ namespace ICSharpCode.XamlBinding @@ -237,7 +259,7 @@ namespace ICSharpCode.XamlBinding
if (offset < 0)
throw new ArgumentOutOfRangeException("offset", offset, "Value must be between 0 and " + (xaml.Length - 1));
if (offset >= xaml.Length)
if (offset >= xaml.Length && offset > 0)
offset = xaml.Length - 1;
string interestingPart = xaml.Substring(0, offset);
@ -247,5 +269,29 @@ namespace ICSharpCode.XamlBinding @@ -247,5 +269,29 @@ namespace ICSharpCode.XamlBinding
return interestingPart.LastIndexOf("<!--", StringComparison.OrdinalIgnoreCase) != -1;
}
public static int GetParentElementStart(ITextEditor editor)
{
Stack<int> offsetStack = new Stack<int>();
using (XmlTextReader xmlReader = new XmlTextReader(new StringReader(editor.Document.GetText(0, editor.Caret.Offset)))) {
try {
xmlReader.XmlResolver = null; // prevent XmlTextReader from loading external DTDs
while (xmlReader.Read()) {
switch (xmlReader.NodeType) {
case XmlNodeType.Element:
if (!xmlReader.IsEmptyElement) {
offsetStack.Push(editor.Document.PositionToOffset(xmlReader.LineNumber, xmlReader.LinePosition));
}
break;
case XmlNodeType.EndElement:
offsetStack.Pop();
break;
}
}
} catch (XmlException) { }
}
return (offsetStack.Count > 0) ? offsetStack.Pop() : -1;
}
}
}

4
src/AddIns/BackendBindings/XamlBinding/XamlBinding/XamlBinding.addin

@ -41,4 +41,8 @@ @@ -41,4 +41,8 @@
<Path name = "/AddIns/DefaultTextEditor/CodeCompletion">
<CodeCompletionBinding id = "Xaml" extensions = ".xaml" class = "ICSharpCode.XamlBinding.XamlCodeCompletionBinding"/>
</Path>
<Path name = "/AddIns/DefaultTextEditor/Formatter/XML">
<Class id ="XmlFormatter" class = "ICSharpCode.XmlEditor.XmlFormattingStrategy"/>
</Path>
</AddIn>

42
src/AddIns/BackendBindings/XamlBinding/XamlBinding/XamlCodeCompletionBinding.cs

@ -41,13 +41,12 @@ namespace ICSharpCode.XamlBinding @@ -41,13 +41,12 @@ namespace ICSharpCode.XamlBinding
switch (ch) {
case '<':
context.Description = (context.Description == XamlContextDescription.None) ? XamlContextDescription.AtTag : context.Description;
list = CompletionDataHelper.CreateListForContext(editor, context);
editor.ShowCompletionWindow(list);
return CodeCompletionKeyPressResult.Completed;
case '>': // XML tag completion
if (DoXmlTagCompletion(editor))
return CodeCompletionKeyPressResult.EatKey;
break;
case '>':
return CodeCompletionKeyPressResult.None;
case '"':
if (!XmlParser.IsInsideAttributeValue(editor.Document.Text, editor.Caret.Offset)) {
int search = editor.Caret.Offset + 1;
@ -77,6 +76,7 @@ namespace ICSharpCode.XamlBinding @@ -77,6 +76,7 @@ namespace ICSharpCode.XamlBinding
break;
case '.':
if (context.Path != null && !XmlParser.IsInsideAttributeValue(editor.Document.Text, editor.Caret.Offset)) {
context.Description = XamlContextDescription.AtTag;
list = CompletionDataHelper.CreateListForContext(editor, context);
editor.ShowCompletionWindow(list);
return CodeCompletionKeyPressResult.Completed;
@ -84,20 +84,26 @@ namespace ICSharpCode.XamlBinding @@ -84,20 +84,26 @@ namespace ICSharpCode.XamlBinding
break;
case ':':
if (context.Path != null && XmlParser.GetQualifiedAttributeNameAtIndex(editor.Document.Text, editor.Caret.Offset) == null) {
if (!context.AttributeName.StartsWith("xmlns")) {
list = CompletionDataHelper.CreateListForContext(editor, context);
editor.ShowCompletionWindow(list);
return CodeCompletionKeyPressResult.CompletedIncludeKeyInCompletion;
}
}
break;
case '/': // ignore '/' when trying to type '/>'
return CodeCompletionKeyPressResult.None;
case '=':
if (!XmlParser.IsInsideAttributeValue(editor.Document.Text, editor.Caret.Offset)) {
int searchOffset = editor.Caret.Offset + 1;
while (char.IsWhiteSpace(editor.Document.GetCharAt(searchOffset)))
int searchOffset = editor.Caret.Offset;
while (searchOffset < editor.Document.TextLength - 1) {
searchOffset++;
if (!char.IsWhiteSpace(editor.Document.GetCharAt(searchOffset)))
break;
}
if (editor.Document.GetCharAt(searchOffset) != '"') {
if (searchOffset >= editor.Document.TextLength || editor.Document.GetCharAt(searchOffset) != '"') {
editor.Document.Insert(editor.Caret.Offset, "=\"\"");
editor.Caret.Offset--;
} else {
@ -110,10 +116,14 @@ namespace ICSharpCode.XamlBinding @@ -110,10 +116,14 @@ namespace ICSharpCode.XamlBinding
}
break;
default:
if (context.Description != XamlContextDescription.None && !char.IsWhiteSpace(context.PressedKey)) {
editor.Document.Insert(editor.Caret.Offset, ch.ToString());
if (!context.AttributeName.StartsWith("xmlns"))
this.CtrlSpace(editor);
return CodeCompletionKeyPressResult.EatKey;
}
break;
}
return CodeCompletionKeyPressResult.None;
}
@ -148,12 +158,13 @@ namespace ICSharpCode.XamlBinding @@ -148,12 +158,13 @@ namespace ICSharpCode.XamlBinding
public bool CtrlSpace(ITextEditor editor)
{
XamlContext context = CompletionDataHelper.ResolveContext(editor, ' ');
context.Forced = true;
var info = ParserService.GetParseInformation(editor.FileName);
if (context.Path != null) {
if (!XmlParser.IsInsideAttributeValue(editor.Document.Text, editor.Caret.Offset)) {
var list = CompletionDataHelper.CreateListForContext(editor, context) as XamlCompletionItemList;
string starter = editor.GetWordBeforeCaret().Trim('<');
string starter = editor.GetWordBeforeCaret().Trim('<', '>');
if (!string.IsNullOrEmpty(starter) && !starter.EndsWith(StringComparison.Ordinal, ' ', '\t', '\n', '\r'))
list.PreselectionLength = starter.Length;
editor.ShowCompletionWindow(list);
@ -167,15 +178,26 @@ namespace ICSharpCode.XamlBinding @@ -167,15 +178,26 @@ namespace ICSharpCode.XamlBinding
if (!DoMarkupExtensionCompletion(editor, info, context)) {
XamlResolver resolver = new XamlResolver();
var completionList = new XamlCompletionItemList();
var mrr = resolver.Resolve(new ExpressionResult(context.AttributeName, new XamlExpressionContext(context.Path, context.AttributeName, false)),
info, editor.Document.Text) as MemberResolveResult;
if (mrr != null && mrr.ResolvedType != null) {
var c = mrr.ResolvedType.GetUnderlyingClass();
var completionList = new XamlCompletionItemList();
completionList.Items.AddRange(CompletionDataHelper.MemberCompletion(editor, mrr.ResolvedType));
editor.ShowCompletionWindow(completionList);
editor.ShowInsightWindow(CompletionDataHelper.MemberInsight(mrr));
}
if (context.AttributeName.StartsWith("xmlns"))
completionList.Items.AddRange(CompletionDataHelper.CreateListForXmlnsCompletion(info.BestCompilationUnit.ProjectContent));
ICompletionListWindow window = editor.ShowCompletionWindow(completionList);
if (context.AttributeName.StartsWith("xmlns"))
window.Width = double.NaN;
return true;
}
}
}

91
src/AddIns/BackendBindings/XamlBinding/XamlBinding/XamlCompletionItem.cs

@ -14,24 +14,27 @@ using ICSharpCode.SharpDevelop.Editor; @@ -14,24 +14,27 @@ using ICSharpCode.SharpDevelop.Editor;
namespace ICSharpCode.XamlBinding
{
class XamlCompletionItem : CodeCompletionItem
class XamlCodeCompletionItem : CodeCompletionItem
{
public XamlCompletionItem(IEntity entity, string prefix)
public XamlCodeCompletionItem(IEntity entity, string prefix, bool addOpeningBrace)
: base(entity)
{
if (string.IsNullOrEmpty(prefix))
this.Text = entity.Name;
else
this.Text = prefix + ":" + entity.Name;
if (addOpeningBrace)
this.Text = "<" + this.Text;
}
public XamlCompletionItem(IEntity entity)
public XamlCodeCompletionItem(IEntity entity)
: base(entity)
{
this.Text = entity.Name;
}
public XamlCompletionItem(string text, IEntity entity)
public XamlCodeCompletionItem(IEntity entity, string text)
: base(entity)
{
this.Text = text;
@ -43,6 +46,86 @@ namespace ICSharpCode.XamlBinding @@ -43,6 +46,86 @@ namespace ICSharpCode.XamlBinding
}
}
class XamlCompletionItem : DefaultCompletionItem
{
string prefix, @namespace, name;
public XamlCompletionItem(string prefix, string @namespace, string name)
: base(prefix + ":" + name)
{
this.prefix = prefix;
this.@namespace = @namespace;
this.name = name;
}
public XamlCompletionItem(string @namespace, string name)
: base(name)
{
this.prefix = "";
this.@namespace = @namespace;
this.name = name;
}
public string Prefix {
get { return prefix; }
}
public string Namespace {
get { return @namespace; }
}
public string Name {
get { return name; }
}
}
class XmlnsCompletionItem : DefaultCompletionItem
{
string @namespace, assembly;
bool isUrl;
public bool IsUrl {
get { return isUrl; }
}
public XmlnsCompletionItem(string @namespace, string assembly)
: base(@namespace + " (" + assembly + ")")
{
this.@namespace = @namespace;
this.assembly = assembly;
}
public XmlnsCompletionItem(string @namespace, bool isUrl)
: base(@namespace)
{
this.@namespace = @namespace;
this.isUrl = isUrl;
this.assembly = string.Empty;
}
public string Namespace {
get { return @namespace; }
}
public string Assembly {
get { return assembly; }
}
public override void Complete(CompletionContext context)
{
if (isUrl)
base.Complete(context);
else {
ITextEditor editor = context.Editor;
string newText = "clr-namespace:" + @namespace;
if (!string.IsNullOrEmpty(assembly))
newText += ";assembly=" + assembly;
editor.Document.Replace(context.StartOffset, context.Length, newText);
context.EndOffset = context.StartOffset + newText.Length;
}
}
}
class NewEventCompletionItem : DefaultCompletionItem
{
IEvent eventType;

25
src/AddIns/BackendBindings/XamlBinding/XamlBinding/XamlCompletionItemList.cs

@ -26,7 +26,7 @@ namespace ICSharpCode.XamlBinding @@ -26,7 +26,7 @@ namespace ICSharpCode.XamlBinding
public override CompletionItemListKeyResult ProcessInput(char key)
{
if (key == ':')
if (key == ':' || key == '/')
return CompletionItemListKeyResult.NormalKey;
return base.ProcessInput(key);
@ -36,8 +36,8 @@ namespace ICSharpCode.XamlBinding @@ -36,8 +36,8 @@ namespace ICSharpCode.XamlBinding
{
base.Complete(context, item);
if (item is XamlCompletionItem) {
XamlCompletionItem cItem = item as XamlCompletionItem;
if (item is XamlCodeCompletionItem) {
XamlCodeCompletionItem cItem = item as XamlCodeCompletionItem;
if (cItem.Entity is IProperty || cItem.Entity is IEvent) {
if (context.Editor.Document.GetCharAt(context.StartOffset - 1) != '.') {
@ -55,7 +55,12 @@ namespace ICSharpCode.XamlBinding @@ -55,7 +55,12 @@ namespace ICSharpCode.XamlBinding
if (markup.NamedArguments.Count > 0 || markup.PositionalArguments.Count > 0) {
int oldOffset = context.Editor.Caret.Offset;
context.Editor.Caret.Offset = context.StartOffset;
string word = context.Editor.GetWordBeforeCaret();
string word = context.Editor.GetWordBeforeCaret().Trim();
if (!word.EndsWith(",") && markup.ExtensionType != word) {
context.Editor.Document.Insert(context.Editor.Caret.Offset, ", ");
oldOffset += 2;
}
context.Editor.Caret.Offset = oldOffset;
}
@ -96,11 +101,21 @@ namespace ICSharpCode.XamlBinding @@ -96,11 +101,21 @@ namespace ICSharpCode.XamlBinding
XamlCodeCompletionBinding.Instance.CtrlSpace(context.Editor);
}
}
} else {
}
if (item is NewEventCompletionItem) {
NewEventCompletionItem eventItem = item as NewEventCompletionItem;
CreateEventHandlerCode(context, eventItem);
}
if (item is XmlnsCompletionItem) {
context.Editor.Caret.Offset++;
}
if (item is XamlCompletionItem) {
XamlCompletionItem xamlItem = item as XamlCompletionItem;
context.Editor.Document.Insert(context.EndOffset, "=\"\"");
context.Editor.Caret.Offset--;
}
}

5
src/AddIns/BackendBindings/XamlBinding/XamlBinding/XamlContext.cs

@ -27,6 +27,7 @@ namespace ICSharpCode.XamlBinding @@ -27,6 +27,7 @@ namespace ICSharpCode.XamlBinding
public string RawAttributeValue { get; set; }
public int ValueStartOffset { get; set; }
public XamlContextDescription Description { get; set; }
public bool Forced { get; set; }
public XamlContext() {}
@ -43,6 +44,10 @@ namespace ICSharpCode.XamlBinding @@ -43,6 +44,10 @@ namespace ICSharpCode.XamlBinding
}
public enum XamlContextDescription {
/// <summary>
/// Outside any tag
/// </summary>
None,
/// <summary>
/// After '&lt;'
/// </summary>

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

@ -391,7 +391,7 @@ namespace ICSharpCode.AvalonEdit.AddIn @@ -391,7 +391,7 @@ namespace ICSharpCode.AvalonEdit.AddIn
void OnCodeCompletion(object sender, ExecutedRoutedEventArgs e)
{
CloseExistingCompletionWindows();
CloseExistingCompletionWindow();
TextEditor textEditor = GetTextEditorFromSender(sender);
foreach (ICodeCompletionBinding cc in CodeCompletionBindings) {
if (cc.CtrlSpace(GetAdapter(textEditor))) {
@ -404,11 +404,15 @@ namespace ICSharpCode.AvalonEdit.AddIn @@ -404,11 +404,15 @@ namespace ICSharpCode.AvalonEdit.AddIn
SharpDevelopCompletionWindow completionWindow;
SharpDevelopInsightWindow insightWindow;
void CloseExistingCompletionWindows()
void CloseExistingCompletionWindow()
{
if (completionWindow != null) {
completionWindow.Close();
}
}
void CloseExistingInsightWindow()
{
if (insightWindow != null) {
insightWindow.Close();
}
@ -424,7 +428,7 @@ namespace ICSharpCode.AvalonEdit.AddIn @@ -424,7 +428,7 @@ namespace ICSharpCode.AvalonEdit.AddIn
internal void ShowCompletionWindow(SharpDevelopCompletionWindow window)
{
CloseExistingCompletionWindows();
CloseExistingCompletionWindow();
completionWindow = window;
window.Closed += delegate {
completionWindow = null;
@ -440,7 +444,7 @@ namespace ICSharpCode.AvalonEdit.AddIn @@ -440,7 +444,7 @@ namespace ICSharpCode.AvalonEdit.AddIn
internal void ShowInsightWindow(SharpDevelopInsightWindow window)
{
CloseExistingCompletionWindows();
CloseExistingInsightWindow();
insightWindow = window;
window.Closed += delegate {
insightWindow = null;

10
src/AddIns/DisplayBindings/XmlEditor/Project/Src/FormatXmlCommand.cs

@ -5,9 +5,10 @@ @@ -5,9 +5,10 @@
// <version>$Revision$</version>
// </file>
using ICSharpCode.SharpDevelop.Gui;
using ICSharpCode.SharpDevelop.Editor;
using System;
using ICSharpCode.Core;
using ICSharpCode.SharpDevelop.Gui;
namespace ICSharpCode.XmlEditor
{
@ -18,11 +19,10 @@ namespace ICSharpCode.XmlEditor @@ -18,11 +19,10 @@ namespace ICSharpCode.XmlEditor
{
public override void Run()
{
// Find active XmlView.
XmlView xmlView = XmlView.ActiveXmlView;
ITextEditorProvider provider = WorkbenchSingleton.Workbench.ActiveViewContent as ITextEditorProvider;
if (xmlView != null) {
xmlView.FormatXml();
if (provider != null) {
XmlView.FormatXml(provider.TextEditor);
}
}
}

35
src/AddIns/DisplayBindings/XmlEditor/Project/Src/XmlFormattingStrategy.cs

@ -5,14 +5,16 @@ @@ -5,14 +5,16 @@
// <version>$Revision$</version>
// </file>
using ICSharpCode.SharpDevelop.Editor;
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Text;
using System.Xml;
using ICSharpCode.Core;
using ICSharpCode.SharpDevelop.Editor;
namespace ICSharpCode.XmlEditor
{
@ -68,7 +70,7 @@ namespace ICSharpCode.XmlEditor @@ -68,7 +70,7 @@ namespace ICSharpCode.XmlEditor
Debug.Assert(false, e.ToString());
}
if (charTyped == '\n') {
IndentLine(editor, editor.Document.GetLineForOffset(editor.Caret.Offset));
IndentLine(editor, editor.Document.GetLine(editor.Caret.Line));
}
editor.Document.EndUndoableAction();
}
@ -99,11 +101,11 @@ namespace ICSharpCode.XmlEditor @@ -99,11 +101,11 @@ namespace ICSharpCode.XmlEditor
editor.Document.EndUndoableAction();
}
}
#region Smart Indentation
static void TryIndent(ITextEditor editor, int begin, int end)
{
string currentIndentation = "";
Stack tagStack = new Stack();
Stack<string> tagStack = new Stack<string>();
IDocument document = editor.Document;
string tab = editor.Options.IndentationString;
int nextLine = begin; // in #dev coordinates
@ -118,16 +120,16 @@ namespace ICSharpCode.XmlEditor @@ -118,16 +120,16 @@ namespace ICSharpCode.XmlEditor
if (tagStack.Count == 0)
currentIndentation = "";
else
currentIndentation = (string)tagStack.Pop();
currentIndentation = tagStack.Pop();
}
if (r.NodeType == XmlNodeType.EndElement) {
if (tagStack.Count == 0)
currentIndentation = "";
else
currentIndentation = (string)tagStack.Pop();
currentIndentation = tagStack.Pop();
}
while (r.LineNumber >= nextLine) { // caution: here we compare 1-based and 0-based line numbers
while (r.LineNumber > nextLine) { // caution: here we compare 1-based and 0-based line numbers
if (nextLine > end) break;
if (lastType == XmlNodeType.CDATA || lastType == XmlNodeType.Comment) {
nextLine++;
@ -140,7 +142,7 @@ namespace ICSharpCode.XmlEditor @@ -140,7 +142,7 @@ namespace ICSharpCode.XmlEditor
string newText;
// special case: opening tag has closing bracket on extra line: remove one indentation level
if (lineText.Trim() == ">")
newText = (string)tagStack.Peek() + lineText.Trim();
newText = tagStack.Peek() + lineText.Trim();
else
newText = currentIndentation + lineText.Trim();
@ -156,9 +158,9 @@ namespace ICSharpCode.XmlEditor @@ -156,9 +158,9 @@ namespace ICSharpCode.XmlEditor
if (r.NodeType == XmlNodeType.Element) {
tagStack.Push(currentIndentation);
if (r.LineNumber < begin)
currentIndentation = DocumentUtilitites.GetIndentation(editor.Document, r.LineNumber - 1);
currentIndentation = DocumentUtilitites.GetIndentation(editor.Document, editor.Document.PositionToOffset(r.LineNumber, 1));
if (r.Name.Length < 16)
attribIndent = currentIndentation + new String(' ', 2 + r.Name.Length);
attribIndent = currentIndentation + new string(' ', 2 + r.Name.Length);
else
attribIndent = currentIndentation + tab;
currentIndentation += tab;
@ -170,15 +172,12 @@ namespace ICSharpCode.XmlEditor @@ -170,15 +172,12 @@ namespace ICSharpCode.XmlEditor
if (r.LineNumber != startLine)
attribIndent = currentIndentation; // change to tab-indentation
r.MoveToAttribute(r.AttributeCount - 1);
while (r.LineNumber >= nextLine) {
while (r.LineNumber > nextLine) {
if (nextLine > end) break;
// set indentation of 'nextLine'
IDocumentLine line = document.GetLine(nextLine);
string lineText = line.Text;
string newText = attribIndent + lineText.Trim();
if (newText != lineText) {
document.Replace(line.Offset, line.Length, newText);
}
string newText = attribIndent + line.Text.Trim();
document.SmartReplaceLine(line, newText);
nextLine++;
}
}
@ -186,6 +185,6 @@ namespace ICSharpCode.XmlEditor @@ -186,6 +185,6 @@ namespace ICSharpCode.XmlEditor
r.Close();
}
}
#endregion
}
}

4
src/AddIns/DisplayBindings/XmlEditor/Project/Src/XmlTreeView.cs

@ -137,7 +137,7 @@ namespace ICSharpCode.XmlEditor @@ -137,7 +137,7 @@ namespace ICSharpCode.XmlEditor
treeViewContainer.LoadXml(provider.GetDocumentForFile(this.PrimaryFile).Text, XmlCodeCompletionBinding.GetProvider(Path.GetExtension(this.PrimaryFileName)));
XmlView view = XmlView.ForFile(this.PrimaryFile);
if (view != null) {
view.CheckIsWellFormed();
XmlView.CheckIsWellFormed(view.TextEditor);
}
}
@ -147,7 +147,7 @@ namespace ICSharpCode.XmlEditor @@ -147,7 +147,7 @@ namespace ICSharpCode.XmlEditor
if (!treeViewContainer.IsErrorMessageTextBoxVisible && treeViewContainer.IsDirty) {
XmlView view = XmlView.ForFile(this.PrimaryFile);
if (view != null) {
view.ReplaceAll(treeViewContainer.Document.OuterXml);
XmlView.ReplaceAll(treeViewContainer.Document.OuterXml, view.TextEditor);
ignoreDirtyChange = true;
treeViewContainer.IsDirty = false;
ignoreDirtyChange = false;

24
src/AddIns/DisplayBindings/XmlEditor/Project/Src/XmlView.cs

@ -189,7 +189,11 @@ namespace ICSharpCode.XmlEditor @@ -189,7 +189,11 @@ namespace ICSharpCode.XmlEditor
public bool CheckIsWellFormed()
{
ITextEditor editor = TextEditor;
return CheckIsWellFormed(TextEditor);
}
public static bool CheckIsWellFormed(ITextEditor editor)
{
if (editor == null) return false;
try {
XmlDocument Document = new XmlDocument();
@ -429,14 +433,13 @@ namespace ICSharpCode.XmlEditor @@ -429,14 +433,13 @@ namespace ICSharpCode.XmlEditor
/// <summary>
/// Pretty prints the xml.
/// </summary>
public void FormatXml()
public static void FormatXml(ITextEditor editor)
{
ITextEditor editor = TextEditor;
if (editor == null) return;
TaskService.ClearExceptCommentTasks();
if (IsWellFormed) {
ReplaceAll(editor.Document.Text);
if (CheckIsWellFormed(editor)) {
ReplaceAll(editor.Document.Text, editor);
} else {
ShowErrorList();
}
@ -446,12 +449,11 @@ namespace ICSharpCode.XmlEditor @@ -446,12 +449,11 @@ namespace ICSharpCode.XmlEditor
/// Replaces the entire text of the xml view with the xml in the
/// specified. The xml will be formatted.
/// </summary>
public void ReplaceAll(string xml)
public static void ReplaceAll(string xml, ITextEditor editor)
{
ITextEditor editor = TextEditor;
if (editor == null) return;
string formattedXml = SimpleFormat(IndentedFormat(xml));
string formattedXml = SimpleFormat(IndentedFormat(xml, editor));
editor.Document.Text = formattedXml;
//UpdateFolding(); // TODO : add again when folding is implemented in AvalonEdit
}
@ -471,11 +473,9 @@ namespace ICSharpCode.XmlEditor @@ -471,11 +473,9 @@ namespace ICSharpCode.XmlEditor
/// <returns>A pretty print version of the specified xml. If the
/// string is not well formed xml the original string is returned.
/// </returns>
string IndentedFormat(string xml)
static string IndentedFormat(string xml, ITextEditor editor)
{
string indentedText = string.Empty;
ITextEditor editor = TextEditor;
if (editor == null) return indentedText;
try {
@ -676,7 +676,7 @@ namespace ICSharpCode.XmlEditor @@ -676,7 +676,7 @@ namespace ICSharpCode.XmlEditor
void ShowTransformOutput(string xml)
{
// Pretty print the xml.
xml = SimpleFormat(IndentedFormat(xml));
xml = SimpleFormat(IndentedFormat(xml, TextEditor));
// Display the output xml.
XslOutputView.EditorInstance.Document.Text = xml;

5
src/AddIns/DisplayBindings/XmlEditor/Project/XmlEditor.csproj

@ -166,6 +166,11 @@ @@ -166,6 +166,11 @@
<Name>ICSharpCode.AvalonEdit</Name>
<Private>False</Private>
</ProjectReference>
<ProjectReference Include="..\..\..\..\Libraries\NRefactory\Project\NRefactory.csproj">
<Project>{3A9AE6AA-BC07-4A2F-972C-581E3AE2F195}</Project>
<Name>NRefactory</Name>
<Private>False</Private>
</ProjectReference>
<ProjectReference Include="..\..\..\..\Main\Base\Project\ICSharpCode.SharpDevelop.csproj">
<Project>{2748AD25-9C63-4E12-877B-4DCE96FBED54}</Project>
<Name>ICSharpCode.SharpDevelop</Name>

6
src/AddIns/Misc/UnitTesting/Test/Utils/MockProjectContent.cs

@ -180,5 +180,11 @@ namespace UnitTesting.Tests.Utils @@ -180,5 +180,11 @@ namespace UnitTesting.Tests.Utils
{
throw new NotImplementedException();
}
public string AssemblyName {
get {
throw new NotImplementedException();
}
}
}
}

2
src/Main/Base/Project/Src/Gui/Dialogs/NewFileDialog.cs

@ -505,7 +505,7 @@ namespace ICSharpCode.SharpDevelop.Gui @@ -505,7 +505,7 @@ namespace ICSharpCode.SharpDevelop.Gui
foreach (FileDescriptionTemplate newfile in item.Template.FileDescriptionTemplates) {
if (!IsFilenameAvailable(StringParser.Parse(newfile.Name))) {
MessageService.ShowError("Filename " + StringParser.Parse(newfile.Name) + " is in use.\nChoose another one");
MessageService.ShowError(string.Format("Filename {0} is in use.\nChoose another one", StringParser.Parse(newfile.Name))); // TODO : translate
return;
}
}

7
src/Main/Base/Project/Src/Services/ParserService/ParseProjectContent.cs

@ -9,8 +9,9 @@ using System; @@ -9,8 +9,9 @@ using System;
using System.Collections.Generic;
using ICSharpCode.Core;
using ICSharpCode.SharpDevelop.Dom;
using ICSharpCode.SharpDevelop.Project;
using ICSharpCode.SharpDevelop.Gui;
using ICSharpCode.SharpDevelop.Project;
using System.IO;
namespace ICSharpCode.SharpDevelop
{
@ -35,6 +36,10 @@ namespace ICSharpCode.SharpDevelop @@ -35,6 +36,10 @@ namespace ICSharpCode.SharpDevelop
}
}
public string AssemblyName {
get { return project.AssemblyName; }
}
bool initializing;
public override string ToString()

7
src/Main/ICSharpCode.SharpDevelop.Dom/Project/Src/ProjectContent/DefaultProjectContent.cs

@ -1020,5 +1020,12 @@ namespace ICSharpCode.SharpDevelop.Dom @@ -1020,5 +1020,12 @@ namespace ICSharpCode.SharpDevelop.Dom
}
}
}
/// <inheritdoc/>
public virtual string AssemblyName {
get {
return null;
}
}
}
}

7
src/Main/ICSharpCode.SharpDevelop.Dom/Project/Src/ProjectContent/IProjectContent.cs

@ -115,6 +115,13 @@ namespace ICSharpCode.SharpDevelop.Dom @@ -115,6 +115,13 @@ namespace ICSharpCode.SharpDevelop.Dom
/// Gets whether internals in the project content are visible to the other project content.
/// </summary>
bool InternalsVisibleTo(IProjectContent otherProjectContent);
/// <summary>
/// Gets the name of the assembly.
/// </summary>
string AssemblyName {
get;
}
}
[Flags]

6
src/Main/ICSharpCode.SharpDevelop.Dom/Project/Src/ProjectContent/ReflectionProjectContent.cs

@ -17,6 +17,7 @@ namespace ICSharpCode.SharpDevelop.Dom @@ -17,6 +17,7 @@ namespace ICSharpCode.SharpDevelop.Dom
public class ReflectionProjectContent : DefaultProjectContent
{
string assemblyFullName;
string assemblyName;
DomAssemblyName[] referencedAssemblyNames;
ICompilationUnit assemblyCompilationUnit;
string assemblyLocation;
@ -34,6 +35,10 @@ namespace ICSharpCode.SharpDevelop.Dom @@ -34,6 +35,10 @@ namespace ICSharpCode.SharpDevelop.Dom
}
}
public override string AssemblyName {
get { return assemblyName; }
}
/// <summary>
/// Gets the list of assembly names referenced by this project content.
/// </summary>
@ -110,6 +115,7 @@ namespace ICSharpCode.SharpDevelop.Dom @@ -110,6 +115,7 @@ namespace ICSharpCode.SharpDevelop.Dom
this.registry = registry;
this.assemblyFullName = assemblyFullName;
this.assemblyName = (assemblyFullName.IndexOf(',') > -1) ? assemblyFullName.Substring(0, assemblyFullName.IndexOf(',')) : assemblyFullName;
this.referencedAssemblyNames = referencedAssemblies;
this.assemblyLocation = assemblyLocation;
this.assemblyCompilationUnit = new DefaultCompilationUnit(this);

Loading…
Cancel
Save