10 changed files with 336 additions and 11 deletions
@ -0,0 +1,77 @@
@@ -0,0 +1,77 @@
|
||||
// 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 ICSharpCode.SharpDevelop.Editor; |
||||
using ICSharpCode.SharpDevelop.Editor.CodeCompletion; |
||||
|
||||
namespace ICSharpCode.PythonBinding |
||||
{ |
||||
public class PythonInsightWindowHandler : IInsightWindowHandler |
||||
{ |
||||
ITextEditor editor; |
||||
IInsightWindow insightWindow; |
||||
|
||||
public void InitializeOpenedInsightWindow(ITextEditor editor, IInsightWindow insightWindow) |
||||
{ |
||||
this.editor = editor; |
||||
this.insightWindow = insightWindow; |
||||
int offset = insightWindow.StartOffset; |
||||
insightWindow.DocumentChanged += DocumentChanged; |
||||
} |
||||
|
||||
void DocumentChanged(object sender, TextChangeEventArgs e) |
||||
{ |
||||
if (IsOutsideMethodCall()) { |
||||
insightWindow.Close(); |
||||
} |
||||
} |
||||
|
||||
bool IsOutsideMethodCall() |
||||
{ |
||||
string text = GetTextInsideMethodCallUpToCursor(); |
||||
return TextContainsClosingBracketForMethod(text); |
||||
} |
||||
|
||||
string GetTextInsideMethodCallUpToCursor() |
||||
{ |
||||
int insightStartOffset = insightWindow.StartOffset; |
||||
int currentOffset = editor.Caret.Offset; |
||||
int length = currentOffset - insightStartOffset; |
||||
if (length < 0) { |
||||
// Force completion window to close by returning the close bracket.
|
||||
return ")"; |
||||
} |
||||
return editor.Document.GetText(insightStartOffset, length); |
||||
} |
||||
|
||||
bool TextContainsClosingBracketForMethod(string text) |
||||
{ |
||||
int bracketCount = 1; |
||||
foreach (char ch in text) { |
||||
switch (ch) { |
||||
case '(': |
||||
bracketCount++; |
||||
break; |
||||
case ')': |
||||
bracketCount--; |
||||
if (bracketCount == 0) { |
||||
return true; |
||||
} |
||||
break; |
||||
} |
||||
} |
||||
return false; |
||||
} |
||||
|
||||
public bool InsightRefreshOnComma(ITextEditor editor, char ch, out IInsightWindow insightWindow) |
||||
{ |
||||
insightWindow = null; |
||||
return false; |
||||
} |
||||
|
||||
public void HighlightParameter(IInsightWindow window, int index) |
||||
{ |
||||
} |
||||
} |
||||
} |
@ -0,0 +1,29 @@
@@ -0,0 +1,29 @@
|
||||
// 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 ICSharpCode.PythonBinding; |
||||
using NUnit.Framework; |
||||
using PythonBinding.Tests.Utils; |
||||
|
||||
namespace PythonBinding.Tests.Completion |
||||
{ |
||||
[TestFixture] |
||||
public class PythonCodeCompletionBindingTests |
||||
{ |
||||
TestablePythonCodeCompletionBinding completionBinding; |
||||
|
||||
void CreatePythonCodeCompletionBinding() |
||||
{ |
||||
completionBinding = new TestablePythonCodeCompletionBinding(); |
||||
} |
||||
|
||||
[Test] |
||||
public void InsightHandler_CreateNewCodecompletionBindingInstance_IsSetToPythonInsightWindowHandlerInstance() |
||||
{ |
||||
CreatePythonCodeCompletionBinding(); |
||||
PythonInsightWindowHandler handler = completionBinding.PythonInsightWindowHandler; |
||||
Assert.IsNotNull(handler); |
||||
} |
||||
} |
||||
} |
@ -0,0 +1,126 @@
@@ -0,0 +1,126 @@
|
||||
// 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 ICSharpCode.PythonBinding; |
||||
using ICSharpCode.Scripting.Tests.Utils; |
||||
using ICSharpCode.SharpDevelop.Editor; |
||||
using NUnit.Framework; |
||||
using PythonBinding.Tests.Utils; |
||||
|
||||
namespace PythonBinding.Tests.Completion |
||||
{ |
||||
[TestFixture] |
||||
public class PythonInsightWindowHandlerTests |
||||
{ |
||||
PythonInsightWindowHandler handler; |
||||
MockTextEditor fakeTextEditor; |
||||
FakeInsightWindow fakeInsightWindow; |
||||
|
||||
void CreatePythonInsightWindowHandler() |
||||
{ |
||||
fakeTextEditor = new MockTextEditor(); |
||||
fakeInsightWindow = new FakeInsightWindow(); |
||||
handler = new PythonInsightWindowHandler(); |
||||
} |
||||
|
||||
void InitializePythonInsightWindowHandler() |
||||
{ |
||||
handler.InitializeOpenedInsightWindow(fakeTextEditor, fakeInsightWindow); |
||||
} |
||||
|
||||
TextChangeEventArgs CreateInsertedTextChangeEventArgs(int offset, string insertedText) |
||||
{ |
||||
return new TextChangeEventArgs(offset, String.Empty, insertedText); |
||||
} |
||||
|
||||
[Test] |
||||
public void InitializeOpenedInsightWindow_CloseParenthesisCharacterAddedToDocument_InsightWindowClosed() |
||||
{ |
||||
CreatePythonInsightWindowHandler(); |
||||
fakeTextEditor.FakeDocument.Text = "method("; |
||||
fakeTextEditor.FakeCaret.Offset = 7; |
||||
fakeInsightWindow.StartOffset = 7; |
||||
InitializePythonInsightWindowHandler(); |
||||
|
||||
int newCaretOffset = 8; |
||||
fakeTextEditor.FakeCaret.Offset = newCaretOffset; |
||||
fakeTextEditor.FakeDocument.Text = "method()"; |
||||
TextChangeEventArgs e = CreateInsertedTextChangeEventArgs(newCaretOffset, ")"); |
||||
fakeInsightWindow.FireDocumentChangedEvent(e); |
||||
|
||||
bool closed = fakeInsightWindow.IsClosed; |
||||
Assert.IsTrue(closed); |
||||
} |
||||
|
||||
[Test] |
||||
public void InitializeOpenedInsightWindow_MethodCallWithCursorAtOpenBracket_InsightWindowIsClosedBeforeDocumentIsChanged() |
||||
{ |
||||
CreatePythonInsightWindowHandler(); |
||||
fakeTextEditor.FakeDocument.Text = "method("; |
||||
fakeTextEditor.FakeCaret.Offset = 7; |
||||
fakeInsightWindow.StartOffset = 7; |
||||
InitializePythonInsightWindowHandler(); |
||||
|
||||
bool closed = fakeInsightWindow.IsClosed; |
||||
Assert.IsFalse(closed); |
||||
} |
||||
|
||||
[Test] |
||||
public void InitializeOpenedInsightWindow_SingleCharacterAddedToDocumentAfterOpenParenthesis_InsightWindowIsNotClosed() |
||||
{ |
||||
CreatePythonInsightWindowHandler(); |
||||
fakeTextEditor.FakeDocument.Text = "method("; |
||||
fakeTextEditor.FakeCaret.Offset = 7; |
||||
fakeInsightWindow.StartOffset = 7; |
||||
InitializePythonInsightWindowHandler(); |
||||
|
||||
int newCaretOffset = 8; |
||||
fakeTextEditor.FakeCaret.Offset = newCaretOffset; |
||||
fakeTextEditor.FakeDocument.Text = "method(a"; |
||||
TextChangeEventArgs e = CreateInsertedTextChangeEventArgs(newCaretOffset, "a"); |
||||
fakeInsightWindow.FireDocumentChangedEvent(e); |
||||
|
||||
bool closed = fakeInsightWindow.IsClosed; |
||||
Assert.IsFalse(closed); |
||||
} |
||||
|
||||
[Test] |
||||
public void InitializeOpenedInsightWindow_MethodCallInsideMethodCallAndCloseParenthesisCharacterAddedToDocument_InsightWindowIsNotClosed() |
||||
{ |
||||
CreatePythonInsightWindowHandler(); |
||||
fakeTextEditor.FakeDocument.Text = "method(a("; |
||||
fakeTextEditor.FakeCaret.Offset = 9; |
||||
fakeInsightWindow.StartOffset = 7; |
||||
InitializePythonInsightWindowHandler(); |
||||
|
||||
int newCaretOffset = 10; |
||||
fakeTextEditor.FakeCaret.Offset = newCaretOffset; |
||||
fakeTextEditor.FakeDocument.Text = "method(a()"; |
||||
TextChangeEventArgs e = CreateInsertedTextChangeEventArgs(newCaretOffset, ")"); |
||||
fakeInsightWindow.FireDocumentChangedEvent(e); |
||||
|
||||
bool closed = fakeInsightWindow.IsClosed; |
||||
Assert.IsFalse(closed); |
||||
} |
||||
|
||||
[Test] |
||||
public void InitializeOpenedInsightWindow_CharacterAddedToDocumentBeforeStartOfInsightWindow_InsightWindowClosed() |
||||
{ |
||||
CreatePythonInsightWindowHandler(); |
||||
fakeTextEditor.FakeDocument.Text = "method("; |
||||
fakeTextEditor.FakeCaret.Offset = 7; |
||||
fakeInsightWindow.StartOffset = 7; |
||||
InitializePythonInsightWindowHandler(); |
||||
|
||||
int newCaretOffset = 1; |
||||
fakeTextEditor.FakeCaret.Offset = newCaretOffset; |
||||
fakeTextEditor.FakeDocument.Text = "aethod("; |
||||
TextChangeEventArgs e = CreateInsertedTextChangeEventArgs(newCaretOffset, "a"); |
||||
fakeInsightWindow.FireDocumentChangedEvent(e); |
||||
|
||||
bool closed = fakeInsightWindow.IsClosed; |
||||
Assert.IsTrue(closed); |
||||
} |
||||
} |
||||
} |
@ -0,0 +1,87 @@
@@ -0,0 +1,87 @@
|
||||
// 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 ICSharpCode.SharpDevelop.Editor; |
||||
using ICSharpCode.SharpDevelop.Editor.CodeCompletion; |
||||
|
||||
namespace PythonBinding.Tests.Utils |
||||
{ |
||||
public class FakeInsightWindow : IInsightWindow |
||||
{ |
||||
#pragma warning disable 67
|
||||
public event EventHandler<TextChangeEventArgs> DocumentChanged; |
||||
public event EventHandler SelectedItemChanged; |
||||
public event EventHandler CaretPositionChanged; |
||||
public event EventHandler Closed; |
||||
#pragma warning restore 67
|
||||
|
||||
public bool IsClosed; |
||||
|
||||
public IList<IInsightItem> Items { |
||||
get { |
||||
throw new NotImplementedException(); |
||||
} |
||||
} |
||||
|
||||
public IInsightItem SelectedItem { |
||||
get { |
||||
throw new NotImplementedException(); |
||||
} |
||||
set { |
||||
throw new NotImplementedException(); |
||||
} |
||||
} |
||||
|
||||
public double Width { |
||||
get { |
||||
throw new NotImplementedException(); |
||||
} |
||||
set { |
||||
throw new NotImplementedException(); |
||||
} |
||||
} |
||||
|
||||
public double Height { |
||||
get { |
||||
throw new NotImplementedException(); |
||||
} |
||||
set { |
||||
throw new NotImplementedException(); |
||||
} |
||||
} |
||||
|
||||
public bool CloseAutomatically { |
||||
get { |
||||
throw new NotImplementedException(); |
||||
} |
||||
set { |
||||
throw new NotImplementedException(); |
||||
} |
||||
} |
||||
|
||||
public int StartOffset { get; set; } |
||||
|
||||
public int EndOffset { |
||||
get { |
||||
throw new NotImplementedException(); |
||||
} |
||||
set { |
||||
throw new NotImplementedException(); |
||||
} |
||||
} |
||||
|
||||
public void Close() |
||||
{ |
||||
IsClosed = true; |
||||
} |
||||
|
||||
public void FireDocumentChangedEvent(TextChangeEventArgs e) |
||||
{ |
||||
if (DocumentChanged != null) { |
||||
DocumentChanged(this, e); |
||||
} |
||||
} |
||||
} |
||||
} |
Loading…
Reference in new issue