Browse Source

fix XML code completion weirdnesses and adjust unit tests

pull/18/head
Siegfried Pammer 14 years ago
parent
commit
cbb8cbbff6
  1. 75
      src/AddIns/DisplayBindings/XmlEditor/Project/Src/XmlCodeCompletionBinding.cs
  2. 4
      src/AddIns/DisplayBindings/XmlEditor/Project/Src/XmlCompletionItem.cs
  3. 2
      src/AddIns/DisplayBindings/XmlEditor/Project/Src/XmlCompletionItemCollection.cs
  4. 21
      src/AddIns/DisplayBindings/XmlEditor/Project/Src/XmlParser.cs
  5. 3
      src/AddIns/DisplayBindings/XmlEditor/Project/Src/XmlSchemaCompletionCollection.cs
  6. 8
      src/AddIns/DisplayBindings/XmlEditor/Test/Completion/AttributeCompletionWindowTestFixture.cs
  7. 7
      src/AddIns/DisplayBindings/XmlEditor/Test/Completion/CtrlSpaceAttributeValueCompletionTestFixture.cs
  8. 2
      src/AddIns/DisplayBindings/XmlEditor/Test/Completion/ElementCompletionWindowTests.cs
  9. 57
      src/AddIns/DisplayBindings/XmlEditor/Test/Completion/NamespaceCompletionWindowTestFixture.cs
  10. 8
      src/AddIns/DisplayBindings/XmlEditor/Test/Utils/MockDocument.cs
  11. 2
      src/AddIns/DisplayBindings/XmlEditor/Test/Utils/MockTextEditor.cs
  12. 1
      src/AddIns/DisplayBindings/XmlEditor/Test/XmlEditor.Tests.csproj

75
src/AddIns/DisplayBindings/XmlEditor/Project/Src/XmlCodeCompletionBinding.cs

@ -4,7 +4,7 @@ @@ -4,7 +4,7 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using ICSharpCode.Core;
using ICSharpCode.SharpDevelop.Editor;
using ICSharpCode.SharpDevelop.Editor.CodeCompletion;
@ -12,7 +12,7 @@ using ICSharpCode.SharpDevelop.Editor.CodeCompletion; @@ -12,7 +12,7 @@ using ICSharpCode.SharpDevelop.Editor.CodeCompletion;
namespace ICSharpCode.XmlEditor
{
public class XmlCodeCompletionBinding : ICodeCompletionBinding
{
{
XmlSchemaFileAssociations schemaFileAssociations;
XmlSchemaCompletionCollection schemas;
@ -27,42 +27,37 @@ namespace ICSharpCode.XmlEditor @@ -27,42 +27,37 @@ namespace ICSharpCode.XmlEditor
this.schemas = schemaFileAssociations.Schemas;
}
char[] ignoredChars = new[] { '\\', '/', '"', '\'', '=', '>' };
public CodeCompletionKeyPressResult HandleKeyPress(ITextEditor editor, char ch)
{
XmlSchemaCompletion defaultSchema = schemaFileAssociations.GetSchemaCompletion(editor.FileName);
XmlCompletionItemCollection completionItems = GetCompletionItems(editor, ch, defaultSchema);
if (completionItems.HasItems) {
completionItems.Sort();
ICompletionListWindow completionWindow = editor.ShowCompletionWindow(completionItems);
if (completionWindow != null) {
SetCompletionWindowWidth(completionWindow, completionItems);
}
}
if ((ch == '<') || (ch == ' ') || (ch == '=')) {
return CodeCompletionKeyPressResult.Completed;
}
return CodeCompletionKeyPressResult.None;
if (char.IsWhiteSpace(ch) || editor.SelectionLength > 0)
return CodeCompletionKeyPressResult.None;
if (ignoredChars.Contains(ch))
return CodeCompletionKeyPressResult.None;
if (XmlParser.GetXmlIdentifierBeforeIndex(editor.Document, editor.Caret.Offset).Length > 0)
return CodeCompletionKeyPressResult.None;
editor.Document.Insert(editor.Caret.Offset, ch.ToString());
CtrlSpace(editor);
return CodeCompletionKeyPressResult.EatKey;
}
XmlCompletionItemCollection GetCompletionItems(ITextEditor editor, char characterTyped, XmlSchemaCompletion defaultSchema)
XmlCompletionItemCollection GetCompletionItems(ITextEditor editor, XmlSchemaCompletion defaultSchema)
{
string textUpToCursor = GetTextUpToCursor(editor, characterTyped);
int offset = editor.Caret.Offset;
string textUpToCursor = editor.Document.GetText(0, offset);
switch (characterTyped) {
case '=':
return schemas.GetNamespaceCompletion(textUpToCursor);
case '<':
return schemas.GetElementCompletion(textUpToCursor, defaultSchema);
case ' ':
return schemas.GetAttributeCompletion(textUpToCursor, defaultSchema);
}
return schemas.GetAttributeValueCompletion(characterTyped, textUpToCursor, defaultSchema);
}
string GetTextUpToCursor(ITextEditor editor, char characterTyped)
{
return editor.Document.GetText(0, editor.Caret.Offset) + characterTyped;
XmlCompletionItemCollection items = new XmlCompletionItemCollection();
if (XmlParser.IsInsideAttributeValue(textUpToCursor, offset)) {
items = schemas.GetNamespaceCompletion(textUpToCursor);
if (items.Count == 0)
items = schemas.GetAttributeValueCompletion(textUpToCursor, editor.Caret.Offset, defaultSchema);
} else {
items = schemas.GetAttributeCompletion(textUpToCursor, defaultSchema);
if (items.Count == 0)
items = schemas.GetElementCompletion(textUpToCursor, defaultSchema);
}
return items;
}
void SetCompletionWindowWidth(ICompletionListWindow completionWindow, XmlCompletionItemCollection completionItems)
@ -74,14 +69,18 @@ namespace ICSharpCode.XmlEditor @@ -74,14 +69,18 @@ namespace ICSharpCode.XmlEditor
}
public bool CtrlSpace(ITextEditor editor)
{
string text = editor.Document.Text;
int offset = editor.Caret.Offset;
{
XmlSchemaCompletion defaultSchema = schemaFileAssociations.GetSchemaCompletion(editor.FileName);
XmlCompletionItemCollection completionItems = schemas.GetAttributeValueCompletion(text, offset, defaultSchema);
XmlCompletionItemCollection completionItems = GetCompletionItems(editor, defaultSchema);
if (completionItems.HasItems) {
editor.ShowCompletionWindow(completionItems);
completionItems.Sort();
string identifier = XmlParser.GetXmlIdentifierBeforeIndex(editor.Document, editor.Caret.Offset);
completionItems.PreselectionLength = identifier.Length;
ICompletionListWindow completionWindow = editor.ShowCompletionWindow(completionItems);
if (completionWindow != null) {
SetCompletionWindowWidth(completionWindow, completionItems);
}
return true;
}
return false;

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

@ -65,10 +65,6 @@ namespace ICSharpCode.XmlEditor @@ -65,10 +65,6 @@ namespace ICSharpCode.XmlEditor
base.Complete(context);
switch (dataType) {
case XmlCompletionItemType.NamespaceUri:
context.Editor.Document.Insert(context.StartOffset, "\"");
context.Editor.Document.Insert(context.EndOffset + 1, "\"");
break;
case XmlCompletionItemType.XmlAttribute:
context.Editor.Document.Insert(context.EndOffset, "=\"\"");
context.Editor.Caret.Offset--;

2
src/AddIns/DisplayBindings/XmlEditor/Project/Src/XmlCompletionItemCollection.cs

@ -134,7 +134,7 @@ namespace ICSharpCode.XmlEditor @@ -134,7 +134,7 @@ namespace ICSharpCode.XmlEditor
public ICompletionItem SuggestedItem {
get {
if (HasItems) {
if (HasItems && PreselectionLength == 0) {
return this[0];
}
return null;

21
src/AddIns/DisplayBindings/XmlEditor/Project/Src/XmlParser.cs

@ -7,6 +7,7 @@ using System.IO; @@ -7,6 +7,7 @@ using System.IO;
using System.Text;
using System.Text.RegularExpressions;
using System.Xml;
using ICSharpCode.SharpDevelop;
namespace ICSharpCode.XmlEditor
{
@ -19,14 +20,10 @@ namespace ICSharpCode.XmlEditor @@ -19,14 +20,10 @@ namespace ICSharpCode.XmlEditor
/// since we are interested in the complete path or tree to the
/// currently active element.
/// </remarks>
public sealed class XmlParser
public static class XmlParser
{
static readonly char[] whitespaceCharacters = new char[] {' ', '\n', '\t', '\r'};
XmlParser()
{
}
/// <summary>
/// Gets path of the xml element start tag that the specified
/// <paramref name="index"/> is currently inside.
@ -687,9 +684,21 @@ namespace ICSharpCode.XmlEditor @@ -687,9 +684,21 @@ namespace ICSharpCode.XmlEditor
return path;
}
static bool IsQuoteChar(char ch)
public static bool IsQuoteChar(char ch)
{
return (ch == '\"') || (ch == '\'');
}
public static string GetXmlIdentifierBeforeIndex(ITextBuffer document, int index)
{
if (document == null)
throw new ArgumentNullException("document");
if (index < 0 || index > document.TextLength)
throw new ArgumentOutOfRangeException("index", index, "Value must be between 0 and " + document.TextLength);
int i = index - 1;
while (i >= 0 && IsXmlNameChar(document.GetCharAt(i)) && document.GetCharAt(i) != '/')
i--;
return document.GetText(i + 1, index - i - 1);
}
}
}

3
src/AddIns/DisplayBindings/XmlEditor/Project/Src/XmlSchemaCompletionCollection.cs

@ -26,7 +26,8 @@ namespace ICSharpCode.XmlEditor @@ -26,7 +26,8 @@ namespace ICSharpCode.XmlEditor
public XmlCompletionItemCollection GetNamespaceCompletion(string textUpToCursor)
{
if (XmlParser.IsNamespaceDeclaration(textUpToCursor, textUpToCursor.Length)) {
string attrName = XmlParser.GetAttributeNameAtIndex(textUpToCursor, textUpToCursor.Length);
if (attrName == "xmlns" || attrName.StartsWith("xmlns:")) {
return GetNamespaceCompletion();
}
return new XmlCompletionItemCollection();

8
src/AddIns/DisplayBindings/XmlEditor/Test/Completion/AttributeCompletionWindowTestFixture.cs

@ -40,15 +40,15 @@ namespace XmlEditor.Tests.Completion @@ -40,15 +40,15 @@ namespace XmlEditor.Tests.Completion
}
[Test]
public void KeyPressResultIsCompletedAfterPressingSpaceBar()
public void KeyPressResultIsNotCompletedAfterPressingSpaceBar()
{
Assert.AreEqual(CodeCompletionKeyPressResult.Completed, keyPressResult);
Assert.AreEqual(CodeCompletionKeyPressResult.None, keyPressResult);
}
[Test]
public void CompletionListUsedInShowCompletionWindowHasItems()
public void CompletionListUsedInShowCompletionWindowHasNoItems()
{
Assert.IsTrue(textEditor.CompletionItemsDisplayedToArray().Length > 0);
Assert.IsTrue(textEditor.CompletionItemsDisplayedToArray().Length == 0);
}
}
}

7
src/AddIns/DisplayBindings/XmlEditor/Test/Completion/CtrlSpaceAttributeValueCompletionTestFixture.cs

@ -46,13 +46,6 @@ namespace XmlEditor.Tests.Completion @@ -46,13 +46,6 @@ namespace XmlEditor.Tests.Completion
Assert.IsTrue(result);
}
[Test]
public void CtrlSpaceMethodResultIsFalseWhenCursorIsOutsideAttributeValue()
{
textEditor.Caret.Offset = 0;
Assert.IsFalse(completionBinding.CtrlSpace(textEditor));
}
[Test]
public void ShowCompletionWindowCalledWithCompletionItems()
{

2
src/AddIns/DisplayBindings/XmlEditor/Test/Completion/ElementCompletionWindowTests.cs

@ -42,7 +42,7 @@ namespace XmlEditor.Tests.Completion @@ -42,7 +42,7 @@ namespace XmlEditor.Tests.Completion
public void HandleKeyPress_LessThanKeyPressed_KeyPressResultIsCompletedAfterPressingLessThanSign()
{
keyPressResult = completionBinding.HandleKeyPress(textEditor, '<');
Assert.AreEqual(CodeCompletionKeyPressResult.Completed, keyPressResult);
Assert.AreEqual(CodeCompletionKeyPressResult.EatKey, keyPressResult);
}
[Test]

57
src/AddIns/DisplayBindings/XmlEditor/Test/Completion/NamespaceCompletionWindowTestFixture.cs

@ -1,57 +0,0 @@ @@ -1,57 +0,0 @@
// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt)
// This code is distributed under the GNU LGPL (for details please see \doc\license.txt)
using System;
using System.Collections.Generic;
using System.IO;
using ICSharpCode.Core;
using ICSharpCode.SharpDevelop.Editor.CodeCompletion;
using ICSharpCode.XmlEditor;
using NUnit.Framework;
using XmlEditor.Tests.Utils;
namespace XmlEditor.Tests.Completion
{
[TestFixture]
public class NamespaceCompletionWindowTestFixture : NamespaceCompletionWindowTestFixtureBase
{
[SetUp]
public void Init()
{
base.InitBase();
XmlCodeCompletionBinding completionBinding = new XmlCodeCompletionBinding(associations);
keyPressResult = completionBinding.HandleKeyPress(textEditor, '=');
}
[Test]
public void KeyPressResultIsCompletedAfterPressingEqualsSign()
{
Assert.AreEqual(CodeCompletionKeyPressResult.Completed, keyPressResult);
}
[Test]
public void CompletionWindowWidthSetToMatchLongestNamespaceTextWidth()
{
Assert.AreEqual(double.NaN, textEditor.CompletionWindowDisplayed.Width);
}
[Test]
public void ExpectedCompletionDataItems()
{
XmlCompletionItemCollection expectedItems = new XmlCompletionItemCollection();
expectedItems.Add(new XmlCompletionItem("a", XmlCompletionItemType.NamespaceUri));
expectedItems.Add(new XmlCompletionItem("b", XmlCompletionItemType.NamespaceUri));
expectedItems.Add(new XmlCompletionItem("c", XmlCompletionItemType.NamespaceUri));
Assert.AreEqual(expectedItems.ToArray(), textEditor.CompletionItemsDisplayedToArray());
}
[Test]
public void TextEditorDocumentGetTextCalledWithOffsetAndLength()
{
TextSection expectedTextSection = new TextSection(0, 8);
Assert.AreEqual(expectedTextSection, textEditor.MockDocument.GetTextSectionUsedWithGetTextMethod());
}
}
}

8
src/AddIns/DisplayBindings/XmlEditor/Test/Utils/MockDocument.cs

@ -49,9 +49,7 @@ namespace XmlEditor.Tests.Utils @@ -49,9 +49,7 @@ namespace XmlEditor.Tests.Utils
}
public int TextLength {
get {
throw new NotImplementedException();
}
get { return text.Length; }
}
public IDocumentLine GetLine(int lineNumber)
@ -78,7 +76,7 @@ namespace XmlEditor.Tests.Utils @@ -78,7 +76,7 @@ namespace XmlEditor.Tests.Utils
public void Insert(int offset, string text)
{
throw new NotImplementedException();
this.text = this.text.Insert(offset, text);
}
public void Insert(int offset, string text, AnchorMovementType defaultAnchorMovementType)
@ -138,7 +136,7 @@ namespace XmlEditor.Tests.Utils @@ -138,7 +136,7 @@ namespace XmlEditor.Tests.Utils
public char GetCharAt(int offset)
{
throw new NotImplementedException();
return text[offset];
}
public string GetText(int offset, int length)

2
src/AddIns/DisplayBindings/XmlEditor/Test/Utils/MockTextEditor.cs

@ -156,6 +156,8 @@ namespace XmlEditor.Tests.Utils @@ -156,6 +156,8 @@ namespace XmlEditor.Tests.Utils
public ICompletionItem[] CompletionItemsDisplayedToArray()
{
List<ICompletionItem> items = new List<ICompletionItem>();
if (completionItemsDisplayed == null)
return items.ToArray();
foreach (ICompletionItem item in completionItemsDisplayed.Items) {
items.Add(item);
}

1
src/AddIns/DisplayBindings/XmlEditor/Test/XmlEditor.Tests.csproj

@ -82,7 +82,6 @@ @@ -82,7 +82,6 @@
<Compile Include="Completion\CtrlSpaceNoAttributeValuesForCompletionTestFixture.cs" />
<Compile Include="Completion\ElementCompletionWindowTests.cs" />
<Compile Include="Completion\FirstCompletionListItemSelectedTestFixture.cs" />
<Compile Include="Completion\NamespaceCompletionWindowTestFixture.cs" />
<Compile Include="Completion\NamespaceCompletionWindowTestFixtureBase.cs" />
<Compile Include="Completion\NoCompletionItemsTestFixture.cs" />
<Compile Include="Completion\NullCompletionItemsReturnedTestFixture.cs" />

Loading…
Cancel
Save