Browse Source

Add CodeCompletionItemProvider (editor-independent version of CodeCompletionDataProvider)

git-svn-id: svn://svn.sharpdevelop.net/sharpdevelop/trunk@3883 1ccf3a8d-04fe-1044-b7c0-cef0b8235c61
shortcuts
Daniel Grunwald 17 years ago
parent
commit
62582c6415
  1. 8
      src/AddIns/BackendBindings/CSharpBinding/Project/Src/CSharpAdvancedHighlighter.cs
  2. 35
      src/AddIns/BackendBindings/CSharpBinding/Project/Src/CSharpCompletionBinding.cs
  3. 7
      src/AddIns/BackendBindings/CSharpBinding/Project/Src/EventHandlerCompletitionDataProvider.cs
  4. 2
      src/AddIns/BackendBindings/CSharpBinding/Project/Src/FormattingStrategy/CSharpFormattingStrategy.cs
  5. 22
      src/AddIns/BackendBindings/CSharpBinding/Project/Src/FormattingStrategy/DocumentAccessor.cs
  6. 3
      src/AddIns/DisplayBindings/AvalonEdit.AddIn/AvalonEdit.AddIn.addin
  7. 4
      src/AddIns/DisplayBindings/AvalonEdit.AddIn/AvalonEdit.AddIn.csproj
  8. 53
      src/AddIns/DisplayBindings/AvalonEdit.AddIn/Src/AvalonEditTextEditorAdapter.cs
  9. 94
      src/AddIns/DisplayBindings/AvalonEdit.AddIn/Src/AvalonEditViewContent.cs
  10. 58
      src/AddIns/DisplayBindings/AvalonEdit.AddIn/Src/CodeEditor.cs
  11. 30
      src/AddIns/DisplayBindings/AvalonEdit.AddIn/Src/CodeEditorAdapter.cs
  12. 9
      src/Libraries/AvalonEdit/ICSharpCode.AvalonEdit/Gui/TextEditor.cs
  13. 37
      src/Libraries/AvalonEdit/ICSharpCode.AvalonEdit/Gui/TextEditorWeakEventManager.cs
  14. 1
      src/Libraries/AvalonEdit/ICSharpCode.AvalonEdit/ICSharpCode.AvalonEdit.csproj
  15. 5
      src/Libraries/ICSharpCode.TextEditor/Project/Src/Gui/CompletionWindow/CodeCompletionListView.cs
  16. 3
      src/Main/Base/Project/ICSharpCode.SharpDevelop.csproj
  17. 108
      src/Main/Base/Project/Src/TextEditor/CodeCompletionItemProvider.cs
  18. 2
      src/Main/Base/Project/Src/TextEditor/Gui/Editor/CodeCompletionBinding.cs
  19. 103
      src/Main/Base/Project/Src/TextEditor/Gui/TextEditorAdapter.cs
  20. 20
      src/Main/Base/Project/Src/TextEditor/ICompletionItem.cs
  21. 42
      src/Main/Base/Project/Src/TextEditor/ICompletionItemList.cs
  22. 11
      src/Main/Base/Project/Src/TextEditor/ITextEditor.cs

8
src/AddIns/BackendBindings/CSharpBinding/Project/Src/CSharpAdvancedHighlighter.cs

@ -7,6 +7,7 @@ @@ -7,6 +7,7 @@
* To change this template use Tools | Options | Coding | Edit Standard Headers.
*/
/*
using System;
using System.Collections.Generic;
using System.Drawing;
@ -147,9 +148,4 @@ namespace CSharpBinding @@ -147,9 +148,4 @@ namespace CSharpBinding
}
}
}
*/

35
src/AddIns/BackendBindings/CSharpBinding/Project/Src/CSharpCompletionBinding.cs

@ -17,8 +17,6 @@ using ICSharpCode.SharpDevelop.Dom; @@ -17,8 +17,6 @@ using ICSharpCode.SharpDevelop.Dom;
using ICSharpCode.SharpDevelop.Dom.CSharp;
using ICSharpCode.SharpDevelop.Dom.NRefactoryResolver;
using ICSharpCode.SharpDevelop.Dom.Refactoring;
using ICSharpCode.TextEditor.Document;
using ICSharpCode.TextEditor.Gui.CompletionWindow;
using AST = ICSharpCode.NRefactory.Ast;
using CSTokens = ICSharpCode.NRefactory.Parser.CSharp.Tokens;
@ -94,13 +92,13 @@ namespace CSharpBinding @@ -94,13 +92,13 @@ namespace CSharpBinding
}
}
} else if (ch == '.') {
editor.ShowCompletionWindow(new CSharpCodeCompletionDataProvider(), ch);
editor.ShowCompletionWindow(new CSharpCodeCompletionDataProvider().GenerateCompletionList(editor));
return true;
} else if (ch == '>') {
if (IsInComment(editor)) return false;
char prevChar = cursor > 1 ? editor.Document.GetCharAt(cursor - 1) : ' ';
if (prevChar == '-') {
editor.ShowCompletionWindow(new PointerArrowCompletionDataProvider(), ch);
editor.ShowCompletionWindow(new PointerArrowCompletionDataProvider().GenerateCompletionList(editor));
return true;
}
@ -138,23 +136,23 @@ namespace CSharpBinding @@ -138,23 +136,23 @@ namespace CSharpBinding
return base.HandleKeyPress(editor, ch);
}
class CSharpCodeCompletionDataProvider : CodeCompletionDataProvider
class CSharpCodeCompletionDataProvider : CodeCompletionItemProvider
{
protected override ResolveResult Resolve(ExpressionResult expressionResult, int caretLineNumber, int caretColumn, string fileName, string fileContent)
public override ResolveResult Resolve(ITextEditor editor, ExpressionResult expressionResult)
{
// bypass ParserService.Resolve and set resolver.LimitMethodExtractionUntilCaretLine
ParseInformation parseInfo = ParserService.GetParseInformation(fileName);
ParseInformation parseInfo = ParserService.GetParseInformation(editor.FileName);
NRefactoryResolver resolver = new NRefactoryResolver(LanguageProperties.CSharp);
resolver.LimitMethodExtractionUntilLine = caretLineNumber;
return resolver.Resolve(expressionResult, parseInfo, fileContent);
resolver.LimitMethodExtractionUntilLine = editor.Caret.Line;
return resolver.Resolve(expressionResult, parseInfo, editor.Document.Text);
}
}
class PointerArrowCompletionDataProvider : CodeCompletionDataProvider
class PointerArrowCompletionDataProvider : CodeCompletionItemProvider
{
protected override ResolveResult Resolve(ExpressionResult expressionResult, int caretLineNumber, int caretColumn, string fileName, string fileContent)
public override ResolveResult Resolve(ITextEditor editor, ExpressionResult expressionResult)
{
ResolveResult rr = base.Resolve(expressionResult, caretLineNumber, caretColumn, fileName, fileContent);
ResolveResult rr = base.Resolve(editor, expressionResult);
if (rr != null && rr.ResolvedType != null) {
PointerReturnType prt = rr.ResolvedType.CastToDecoratingReturnType<PointerReturnType>();
if (prt != null)
@ -163,17 +161,14 @@ namespace CSharpBinding @@ -163,17 +161,14 @@ namespace CSharpBinding
return null;
}
protected override ExpressionResult GetExpression(ICSharpCode.TextEditor.TextArea textArea)
public override ExpressionResult GetExpression(ITextEditor editor)
{
ICSharpCode.TextEditor.Document.IDocument document = textArea.Document;
IExpressionFinder expressionFinder = ParserService.GetExpressionFinder(fileName);
var document = editor.Document;
IExpressionFinder expressionFinder = ParserService.GetExpressionFinder(editor.FileName);
if (expressionFinder == null) {
return new ExpressionResult(TextUtilities.GetExpressionBeforeOffset(textArea, textArea.Caret.Offset - 1));
return ExpressionResult.Empty;
} else {
ExpressionResult res = expressionFinder.FindExpression(document.GetText(0, textArea.Caret.Offset - 1), textArea.Caret.Offset - 1);
if (overrideContext != null)
res.Context = overrideContext;
return res;
return expressionFinder.FindExpression(document.GetText(0, editor.Caret.Offset - 1), editor.Caret.Offset - 1);
}
}
}

7
src/AddIns/BackendBindings/CSharpBinding/Project/Src/EventHandlerCompletitionDataProvider.cs

@ -276,10 +276,3 @@ namespace CSharpBinding @@ -276,10 +276,3 @@ namespace CSharpBinding
}
}
}

2
src/AddIns/BackendBindings/CSharpBinding/Project/Src/FormattingStrategy/CSharpFormattingStrategy.cs

@ -5,6 +5,7 @@ @@ -5,6 +5,7 @@
// <version>$Revision$</version>
// </file>
/*
using System;
using System.Collections;
using System.Diagnostics;
@ -787,3 +788,4 @@ namespace CSharpBinding.FormattingStrategy @@ -787,3 +788,4 @@ namespace CSharpBinding.FormattingStrategy
#endregion
}
}
*/

22
src/AddIns/BackendBindings/CSharpBinding/Project/Src/FormattingStrategy/DocumentAccessor.cs

@ -8,9 +8,8 @@ @@ -8,9 +8,8 @@
using System;
using System.Collections.Generic;
using System.IO;
using ICSharpCode.SharpDevelop;
using ICSharpCode.TextEditor.Document;
using ICSharpCode.SharpDevelop.Dom.Refactoring;
namespace CSharpBinding.FormattingStrategy
{
@ -33,6 +32,9 @@ namespace CSharpBinding.FormattingStrategy @@ -33,6 +32,9 @@ namespace CSharpBinding.FormattingStrategy
}
#region DocumentAccessor
/// <summary>
/// Adapter IDocumentAccessor -> IDocument
/// </summary>
public sealed class DocumentAccessor : IDocumentAccessor
{
IDocument doc;
@ -44,8 +46,8 @@ namespace CSharpBinding.FormattingStrategy @@ -44,8 +46,8 @@ namespace CSharpBinding.FormattingStrategy
public DocumentAccessor(IDocument document)
{
doc = document;
this.minLine = 0;
this.maxLine = doc.TotalNumberOfLines - 1;
this.minLine = 1;
this.maxLine = doc.TotalNumberOfLines;
}
public DocumentAccessor(IDocument document, int minLine, int maxLine)
@ -55,10 +57,10 @@ namespace CSharpBinding.FormattingStrategy @@ -55,10 +57,10 @@ namespace CSharpBinding.FormattingStrategy
this.maxLine = maxLine;
}
int num = -1;
int num = 0;
bool dirty;
string text;
LineSegment line;
IDocumentLine line;
public bool ReadOnly {
get {
@ -99,14 +101,16 @@ namespace CSharpBinding.FormattingStrategy @@ -99,14 +101,16 @@ namespace CSharpBinding.FormattingStrategy
public bool Next()
{
if (lineDirty) {
DefaultFormattingStrategy.SmartReplaceLine(doc, line, text);
// TODO: AVALONEDIT reimplement this
//DefaultFormattingStrategy.SmartReplaceLine(doc, line, text);
lineDirty = false;
++changedLines;
throw new NotImplementedException();
}
++num;
if (num > maxLine) return false;
line = doc.GetLineSegment(num);
text = doc.GetText(line);
line = doc.GetLine(num);
text = line.Text;
return true;
}
}

3
src/AddIns/DisplayBindings/AvalonEdit.AddIn/AvalonEdit.AddIn.addin

@ -1,6 +1,7 @@ @@ -1,6 +1,7 @@
<AddIn name = "AvalonEdit.AddIn"
author = "Daniel Grunwald"
description = "The main text editor for SharpDevelop">
description = "The main text editor for SharpDevelop"
addInManagerHidden="preinstalled">
<Manifest>
<Identity name="ICSharpCode.AvalonEdit" />

4
src/AddIns/DisplayBindings/AvalonEdit.AddIn/AvalonEdit.AddIn.csproj

@ -13,6 +13,8 @@ @@ -13,6 +13,8 @@
<NoStdLib>False</NoStdLib>
<WarningLevel>4</WarningLevel>
<TreatWarningsAsErrors>false</TreatWarningsAsErrors>
<RunCodeAnalysis>False</RunCodeAnalysis>
<CodeAnalysisRules>-Microsoft.Design#CA1014;-Microsoft.Design#CA2210</CodeAnalysisRules>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)' == 'Debug' ">
<DebugSymbols>true</DebugSymbols>
@ -61,6 +63,8 @@ @@ -61,6 +63,8 @@
<Compile Include="Src\AvalonEditDocumentAdapter.cs" />
<Compile Include="Src\AvalonEditTextEditorAdapter.cs" />
<Compile Include="Src\AvalonEditViewContent.cs" />
<Compile Include="Src\CodeEditor.cs" />
<Compile Include="Src\CodeEditorAdapter.cs" />
</ItemGroup>
<ItemGroup>
<Folder Include="Src" />

53
src/AddIns/DisplayBindings/AvalonEdit.AddIn/Src/AvalonEditTextEditorAdapter.cs

@ -10,32 +10,53 @@ using System.Diagnostics; @@ -10,32 +10,53 @@ using System.Diagnostics;
using ICSharpCode.AvalonEdit.Gui;
using ICSharpCode.SharpDevelop;
using ICSharpCode.SharpDevelop.Dom.Refactoring;
using System.Windows;
namespace ICSharpCode.AvalonEdit.AddIn
{
/// <summary>
/// Wraps AvalonEdit to provide the ITextEditor interface.
/// </summary>
public class AvalonEditTextEditorAdapter : ITextEditor
public class AvalonEditTextEditorAdapter : ITextEditor, IWeakEventListener
{
readonly TextEditor textEditor;
readonly AvalonEditDocumentAdapter document;
AvalonEditDocumentAdapter document;
public AvalonEditTextEditorAdapter(TextEditor textEditor)
{
this.textEditor = textEditor;
this.document = new AvalonEditDocumentAdapter(textEditor.Document);
this.Caret = new CaretAdapter(textEditor.TextArea.Caret);
TextEditorWeakEventManager.DocumentChanged.AddListener(textEditor, this);
OnDocumentChanged();
}
protected virtual bool ReceiveWeakEvent(Type managerType, object sender, EventArgs e)
{
if (managerType == typeof(TextEditorWeakEventManager.DocumentChanged)) {
OnDocumentChanged();
return true;
}
return false;
}
bool IWeakEventListener.ReceiveWeakEvent(Type managerType, object sender, EventArgs e)
{
return ReceiveWeakEvent(managerType, sender, e);
}
void OnDocumentChanged()
{
if (textEditor.Document != null)
document = new AvalonEditDocumentAdapter(textEditor.Document);
else
document = null;
}
public IDocument Document {
get { return document; }
}
public ITextEditorCaret Caret {
get {
throw new NotImplementedException();
}
}
public ITextEditorCaret Caret { get; private set; }
sealed class CaretAdapter : ITextEditorCaret
{
@ -68,20 +89,20 @@ namespace ICSharpCode.AvalonEdit.AddIn @@ -68,20 +89,20 @@ namespace ICSharpCode.AvalonEdit.AddIn
}
}
public string FileName {
get {
throw new NotImplementedException();
}
public virtual string FileName {
get { return null; }
}
public void ShowInsightWindow(ICSharpCode.TextEditor.Gui.InsightWindow.IInsightDataProvider provider)
public virtual void ShowInsightWindow(ICSharpCode.TextEditor.Gui.InsightWindow.IInsightDataProvider provider)
{
throw new NotImplementedException();
}
public void ShowCompletionWindow(ICSharpCode.TextEditor.Gui.CompletionWindow.ICompletionDataProvider provider, char ch)
public virtual void ShowCompletionWindow(ICSharpCode.TextEditor.Gui.CompletionWindow.ICompletionDataProvider provider, char ch)
{
}
public void ShowCompletionWindow(ICompletionItemList data)
{
throw new NotImplementedException();
}
public string GetWordBeforeCaret()

94
src/AddIns/DisplayBindings/AvalonEdit.AddIn/Src/AvalonEditViewContent.cs

@ -5,53 +5,117 @@ @@ -5,53 +5,117 @@
// <version>$Revision$</version>
// </file>
using ICSharpCode.AvalonEdit.Document;
using System;
using System.IO;
using System.Windows.Media;
using ICSharpCode.AvalonEdit.Document;
using ICSharpCode.AvalonEdit.Highlighting;
using ICSharpCode.Core;
using ICSharpCode.SharpDevelop;
using ICSharpCode.SharpDevelop.Gui;
namespace ICSharpCode.AvalonEdit.AddIn
{
public class AvalonEditViewContent : AbstractViewContent
public class AvalonEditViewContent : AbstractViewContent, IEditable, IMementoCapable
{
TextEditor textEditor = new TextEditor {
Background = Brushes.White,
FontFamily = new FontFamily("Consolas")
};
readonly CodeEditor codeEditor = new CodeEditor();
public AvalonEditViewContent(OpenedFile file)
{
this.Files.Add(file);
file.ForceInitializeView(this);
textEditor.Document.Changed += textEditor_Document_Changed;
codeEditor.Document.Changed += textEditor_Document_Changed;
}
void textEditor_Document_Changed(object sender, DocumentChangeEventArgs e)
{
PrimaryFile.IsDirty = true;
if (!isLoading) {
PrimaryFile.IsDirty = true;
}
}
public CodeEditor CodeEditor {
get { return codeEditor; }
}
public override object Content {
get { return textEditor; }
get { return codeEditor; }
}
public override void Save(OpenedFile file, Stream stream)
{
if (file != PrimaryFile)
return;
textEditor.Save(stream);
codeEditor.Save(stream);
}
bool isLoading;
public override void Load(OpenedFile file, Stream stream)
{
if (file != PrimaryFile)
return;
textEditor.SyntaxHighlighting =
HighlightingManager.Instance.GetDefinitionByExtension(Path.GetExtension(file.FileName));
textEditor.Load(stream);
isLoading = true;
try {
codeEditor.FileName = file.FileName;
codeEditor.SyntaxHighlighting =
HighlightingManager.Instance.GetDefinitionByExtension(Path.GetExtension(file.FileName));
codeEditor.Load(stream);
} finally {
isLoading = false;
}
}
protected override void OnFileNameChanged(OpenedFile file)
{
base.OnFileNameChanged(file);
if (file == PrimaryFile)
codeEditor.FileName = file.FileName;
}
public override void Dispose()
{
base.Dispose();
// Unload document on dispose.
codeEditor.Document = null;
}
public override string ToString()
{
return "[" + GetType().Name + " " + this.PrimaryFileName + "]";
}
#region IEditable
public string Text {
get {
if (WorkbenchSingleton.InvokeRequired)
return WorkbenchSingleton.SafeThreadFunction(() => codeEditor.Text);
else
return codeEditor.Text;
}
set {
WorkbenchSingleton.SafeThreadCall(text => codeEditor.Text = text, value);
}
}
#endregion
#region IMementoCapable
public Properties CreateMemento()
{
Properties memento = new Properties();
memento.Set("CaretOffset", codeEditor.CaretOffset);
memento.Set("ScrollPositionY", codeEditor.VerticalOffset);
return memento;
}
public void SetMemento(Properties memento)
{
codeEditor.ScrollToVerticalOffset(memento.Get("ScrollPositionY", 0.0));
try {
codeEditor.CaretOffset = memento.Get("CaretOffset", 0);
} catch (ArgumentOutOfRangeException) {
// ignore caret out of range - maybe file was changed externally?
}
}
#endregion
}
}

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

@ -0,0 +1,58 @@ @@ -0,0 +1,58 @@
// <file>
// <copyright see="prj:///doc/copyright.txt"/>
// <license see="prj:///doc/license.txt"/>
// <author name="Daniel Grunwald"/>
// <version>$Revision$</version>
// </file>
using System;
using System.Collections.ObjectModel;
using System.Windows.Input;
using System.Windows.Media;
using ICSharpCode.Core;
using ICSharpCode.SharpDevelop.DefaultEditor.Gui.Editor;
namespace ICSharpCode.AvalonEdit.AddIn
{
/// <summary>
/// Integrates AvalonEdit with SharpDevelop.
/// </summary>
public class CodeEditor : TextEditor
{
readonly CodeEditorAdapter textEditorAdapter;
internal string FileName;
public CodeEditor()
{
textEditorAdapter = new CodeEditorAdapter(this);
this.Background = Brushes.White;
this.FontFamily = new FontFamily("Consolas");
this.FontSize = 13;
}
volatile static ReadOnlyCollection<ICodeCompletionBinding> codeCompletionBindings;
public static ReadOnlyCollection<ICodeCompletionBinding> CodeCompletionBindings {
get {
if (codeCompletionBindings == null) {
codeCompletionBindings = AddInTree.BuildItems<ICodeCompletionBinding>("/AddIns/DefaultTextEditor/CodeCompletion", null, false).AsReadOnly();
}
return codeCompletionBindings;
}
}
protected override void OnPreviewTextInput(TextCompositionEventArgs e)
{
base.OnPreviewTextInput(e);
if (!e.Handled && e.Text.Length == 1) {
foreach (ICodeCompletionBinding cc in CodeCompletionBindings) {
if (cc.HandleKeyPress(textEditorAdapter, e.Text[0])) {
e.Handled = true;
return;
}
}
}
}
}
}

30
src/AddIns/DisplayBindings/AvalonEdit.AddIn/Src/CodeEditorAdapter.cs

@ -0,0 +1,30 @@ @@ -0,0 +1,30 @@
// <file>
// <copyright see="prj:///doc/copyright.txt"/>
// <license see="prj:///doc/license.txt"/>
// <author name="Daniel Grunwald"/>
// <version>$Revision$</version>
// </file>
using System;
namespace ICSharpCode.AvalonEdit.AddIn
{
/// <summary>
/// Wraps the CodeEditor class to provide the ITextEditor interface.
/// </summary>
public class CodeEditorAdapter : AvalonEditTextEditorAdapter
{
readonly CodeEditor codeEditor;
public CodeEditorAdapter(CodeEditor codeEditor) : base(codeEditor)
{
if (codeEditor == null)
throw new ArgumentNullException("codeEditor");
this.codeEditor = codeEditor;
}
public override string FileName {
get { return codeEditor.FileName; }
}
}
}

9
src/Libraries/AvalonEdit/ICSharpCode.AvalonEdit/Gui/TextEditor.cs

@ -69,6 +69,11 @@ namespace ICSharpCode.AvalonEdit @@ -69,6 +69,11 @@ namespace ICSharpCode.AvalonEdit
set { SetValue(DocumentProperty, value); }
}
/// <summary>
/// Occurs when the document property has changed.
/// </summary>
public event EventHandler DocumentChanged;
static void OnDocumentChanged(DependencyObject dp, DependencyPropertyChangedEventArgs e)
{
((TextEditor)dp).OnDocumentChanged((TextDocument)e.OldValue, (TextDocument)e.NewValue);
@ -82,8 +87,10 @@ namespace ICSharpCode.AvalonEdit @@ -82,8 +87,10 @@ namespace ICSharpCode.AvalonEdit
if (newValue != null) {
newValue.TextChanged += DocumentTextChanged;
}
if (DocumentChanged != null)
DocumentChanged(this, EventArgs.Empty);
}
/// <summary>
/// Gets/Sets the text of the current document.
/// </summary>

37
src/Libraries/AvalonEdit/ICSharpCode.AvalonEdit/Gui/TextEditorWeakEventManager.cs

@ -0,0 +1,37 @@ @@ -0,0 +1,37 @@
// <file>
// <copyright see="prj:///doc/copyright.txt"/>
// <license see="prj:///doc/license.txt"/>
// <author name="Daniel Grunwald"/>
// <version>$Revision$</version>
// </file>
using ICSharpCode.AvalonEdit.Utils;
using System;
namespace ICSharpCode.AvalonEdit
{
/// <summary>
/// Contains weak event managers for the TexEditor events.
/// </summary>
public static class TextEditorWeakEventManager
{
/// <summary>
/// Weak event manager for the <see cref="TextEditor.DocumentChanged"/> event.
/// </summary>
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", "CA1034:NestedTypesShouldNotBeVisible")]
public sealed class DocumentChanged : WeakEventManagerBase<DocumentChanged, TextEditor>
{
/// <inheritdoc/>
protected override void StartListening(TextEditor source)
{
source.DocumentChanged += DeliverEvent;
}
/// <inheritdoc/>
protected override void StopListening(TextEditor source)
{
source.DocumentChanged -= DeliverEvent;
}
}
}
}

1
src/Libraries/AvalonEdit/ICSharpCode.AvalonEdit/ICSharpCode.AvalonEdit.csproj

@ -155,6 +155,7 @@ @@ -155,6 +155,7 @@
<Compile Include="Gui\SelectionMouseHandler.cs">
<DependentUpon>Selection.cs</DependentUpon>
</Compile>
<Compile Include="Gui\TextEditorWeakEventManager.cs" />
<Compile Include="Gui\TextLayer.cs">
<DependentUpon>TextView.cs</DependentUpon>
</Compile>

5
src/Libraries/ICSharpCode.TextEditor/Project/Src/Gui/CompletionWindow/CodeCompletionListView.cs

@ -233,8 +233,9 @@ namespace ICSharpCode.TextEditor.Gui.CompletionWindow @@ -233,8 +233,9 @@ namespace ICSharpCode.TextEditor.Gui.CompletionWindow
// draw Icon
int xPos = 0;
if (imageList != null && completionData[curItem].ImageIndex < imageList.Images.Count) {
g.DrawImage(imageList.Images[completionData[curItem].ImageIndex], new RectangleF(1, yPos, imageWidth, itemHeight));
int imageIndex = completionData[curItem].ImageIndex;
if (imageList != null && imageIndex < imageList.Images.Count && imageIndex >= 0) {
g.DrawImage(imageList.Images[imageIndex], new RectangleF(1, yPos, imageWidth, itemHeight));
xPos = imageWidth;
}

3
src/Main/Base/Project/ICSharpCode.SharpDevelop.csproj

@ -483,6 +483,7 @@ @@ -483,6 +483,7 @@
<Compile Include="Src\TextEditor\Bookmarks\BookmarkEventHandler.cs" />
<Compile Include="Src\TextEditor\Bookmarks\BookmarkManager.cs" />
<Compile Include="Src\TextEditor\ClipboardHandling.cs" />
<Compile Include="Src\TextEditor\CodeCompletionItemProvider.cs" />
<Compile Include="Src\TextEditor\Codons\AddInTreeSyntaxModeProvider.cs" />
<Compile Include="Src\TextEditor\Codons\EditActionDoozer.cs" />
<Compile Include="Src\TextEditor\Codons\SyntaxModeDoozer.cs" />
@ -553,6 +554,8 @@ @@ -553,6 +554,8 @@
<Compile Include="Src\TextEditor\Actions.cs" />
<Compile Include="Src\TextEditor\CharacterEncodings.cs" />
<Compile Include="Src\TextEditor\Gui\TextEditorAdapter.cs" />
<Compile Include="Src\TextEditor\ICompletionItem.cs" />
<Compile Include="Src\TextEditor\ICompletionItemList.cs" />
<Compile Include="Src\TextEditor\ITextEditor.cs" />
<Compile Include="Src\TextEditor\XmlFormattingStrategy.cs" />
<Compile Include="Src\Services\Tasks\TaskEventHandler.cs" />

108
src/Main/Base/Project/Src/TextEditor/CodeCompletionItemProvider.cs

@ -0,0 +1,108 @@ @@ -0,0 +1,108 @@
// <file>
// <copyright see="prj:///doc/copyright.txt"/>
// <license see="prj:///doc/license.txt"/>
// <author name="Daniel Grunwald"/>
// <version>$Revision$</version>
// </file>
using System;
using ICSharpCode.Core;
using ICSharpCode.SharpDevelop.Dom;
using ICSharpCode.SharpDevelop.Dom.Refactoring;
using System.Collections;
namespace ICSharpCode.SharpDevelop
{
/// <summary>
/// Allows creating an <see cref="ICompletionDataList"/> from code-completion information.
/// </summary>
public class CodeCompletionItemProvider
{
public virtual ICompletionItemList GenerateCompletionList(ITextEditor editor)
{
if (editor == null)
throw new ArgumentNullException("textEditor");
ExpressionResult expression = GetExpression(editor);
return GenerateCompletionListForExpression(editor, expression);
}
public virtual ExpressionResult GetExpression(ITextEditor editor)
{
if (editor == null)
throw new ArgumentNullException("editor");
IDocument document = editor.Document;
IExpressionFinder expressionFinder = ParserService.GetExpressionFinder(editor.FileName);
if (expressionFinder == null) {
return ExpressionResult.Empty;
} else {
return expressionFinder.FindExpression(document.GetText(0, editor.Caret.Offset), editor.Caret.Offset);
}
}
public virtual ICompletionItemList GenerateCompletionListForExpression(ITextEditor editor, ExpressionResult expressionResult)
{
if (expressionResult.Expression == null) {
return null;
}
if (LoggingService.IsDebugEnabled) {
if (expressionResult.Context == ExpressionContext.Default)
LoggingService.DebugFormatted("GenerateCompletionData for >>{0}<<", expressionResult.Expression);
else
LoggingService.DebugFormatted("GenerateCompletionData for >>{0}<<, context={1}", expressionResult.Expression, expressionResult.Context);
}
ResolveResult rr = Resolve(editor, expressionResult);
return GenerateCompletionListForResolveResult(rr, expressionResult.Context);
}
public virtual ResolveResult Resolve(ITextEditor editor, ExpressionResult expressionResult)
{
if (editor == null)
throw new ArgumentNullException("editor");
return ParserService.Resolve(expressionResult, editor.Caret.Line, editor.Caret.Column, editor.FileName, editor.Document.Text);
}
public virtual ICompletionItemList GenerateCompletionListForResolveResult(ResolveResult rr, ExpressionContext context)
{
if (rr == null)
return null;
IProjectContent callingContent = rr.CallingClass != null ? rr.CallingClass.ProjectContent : null;
ArrayList arr = rr.GetCompletionData(callingContent ?? ParserService.CurrentProjectContent);
DefaultCompletionItemList result = new DefaultCompletionItemList();
foreach (object o in arr) {
IEntity entity = o as IEntity;
if (entity != null)
result.Items.Add(new CodeCompletionItem(entity));
}
return result;
}
public virtual ICompletionItem CreateCompletionItem(IEntity entity)
{
return new CodeCompletionItem(entity);
}
}
public class CodeCompletionItem : ICompletionItem
{
readonly IEntity entity;
public CodeCompletionItem(IEntity entity)
{
if (entity == null)
throw new ArgumentNullException("entity");
this.entity = entity;
}
public string Text {
get {
return entity.Name;
}
}
public string Description {
get {
return entity.Documentation;
}
}
}
}

2
src/Main/Base/Project/Src/TextEditor/Gui/Editor/CodeCompletionBinding.cs

@ -166,7 +166,7 @@ namespace ICSharpCode.SharpDevelop.DefaultEditor.Gui.Editor @@ -166,7 +166,7 @@ namespace ICSharpCode.SharpDevelop.DefaultEditor.Gui.Editor
}
case '.':
if (enableDotCompletion) {
editor.ShowCompletionWindow(new CodeCompletionDataProvider(), ch);
editor.ShowCompletionWindow(new CodeCompletionItemProvider().GenerateCompletionList(editor));
return true;
} else {
return false;

103
src/Main/Base/Project/Src/TextEditor/Gui/TextEditorAdapter.cs

@ -5,12 +5,14 @@ @@ -5,12 +5,14 @@
// <version>$Revision$</version>
// </file>
using ICSharpCode.TextEditor.Document;
using ICSharpCode.TextEditor.Gui.CompletionWindow;
using System;
using System.Linq;
using System.Diagnostics;
using ICSharpCode.SharpDevelop.DefaultEditor.Gui.Editor;
using ICSharpCode.SharpDevelop.Refactoring;
using ICSharpCode.TextEditor;
using ICSharpCode.TextEditor.Document;
namespace ICSharpCode.SharpDevelop
{
@ -96,10 +98,18 @@ namespace ICSharpCode.SharpDevelop @@ -96,10 +98,18 @@ namespace ICSharpCode.SharpDevelop
sdtac.ShowInsightWindow(provider);
}
public void ShowCompletionWindow(ICSharpCode.TextEditor.Gui.CompletionWindow.ICompletionDataProvider provider, char ch)
public void ShowCompletionWindow(ICompletionDataProvider provider, char ch)
{
if (sdtac != null)
if (sdtac != null) {
sdtac.ShowCompletionWindow(provider, ch);
}
}
public void ShowCompletionWindow(ICompletionItemList items)
{
if (sdtac != null) {
sdtac.ShowCompletionWindow(new CompletionItemListAdapter(items), '.');
}
}
public string GetWordBeforeCaret()
@ -145,4 +155,91 @@ namespace ICSharpCode.SharpDevelop @@ -145,4 +155,91 @@ namespace ICSharpCode.SharpDevelop
doc.OffsetToPosition(selectionStart), doc.OffsetToPosition(selectionStart + selectionLength));
}
}
sealed class CompletionItemListAdapter : ICompletionDataProvider
{
readonly ICompletionItemList list;
public CompletionItemListAdapter(ICompletionItemList list)
{
if (list == null)
throw new ArgumentNullException("list");
this.list = list;
}
public System.Windows.Forms.ImageList ImageList {
get {
return ClassBrowserIconService.ImageList;
}
}
public string PreSelection {
get {
return null;
}
}
public int DefaultIndex {
get {
return 0;
}
}
public CompletionDataProviderKeyResult ProcessKey(char key)
{
return CompletionDataProviderKeyResult.NormalKey;
}
public bool InsertAction(ICompletionData data, TextArea textArea, int insertionOffset, char key)
{
return false;
}
public ICompletionData[] GenerateCompletionData(string fileName, TextArea textArea, char charTyped)
{
return list.Items.Select(item => new CompletionItemAdapter(item)).ToArray();
}
}
sealed class CompletionItemAdapter : ICompletionData
{
readonly ICompletionItem item;
public CompletionItemAdapter(ICompletionItem item)
{
if (item == null)
throw new ArgumentNullException("item");
this.item = item;
}
public int ImageIndex {
get {
return -1;
}
}
public string Text {
get { return item.Text; }
set {
throw new NotSupportedException();
}
}
public string Description {
get {
return item.Description;
}
}
public double Priority {
get {
return 0;
}
}
public bool InsertAction(TextArea textArea, char ch)
{
return false;
}
}
}

20
src/Main/Base/Project/Src/TextEditor/ICompletionItem.cs

@ -0,0 +1,20 @@ @@ -0,0 +1,20 @@
// <file>
// <copyright see="prj:///doc/copyright.txt"/>
// <license see="prj:///doc/license.txt"/>
// <author name="Daniel Grunwald"/>
// <version>$Revision$</version>
// </file>
using System;
using ICSharpCode.NRefactory;
using ICSharpCode.SharpDevelop.Dom.Refactoring;
using System.Collections.Generic;
namespace ICSharpCode.SharpDevelop
{
public interface ICompletionItem
{
string Text { get; }
string Description { get; }
}
}

42
src/Main/Base/Project/Src/TextEditor/ICompletionItemList.cs

@ -0,0 +1,42 @@ @@ -0,0 +1,42 @@
// <file>
// <copyright see="prj:///doc/copyright.txt"/>
// <license see="prj:///doc/license.txt"/>
// <author name="Daniel Grunwald"/>
// <version>$Revision$</version>
// </file>
using System;
using ICSharpCode.NRefactory;
using ICSharpCode.SharpDevelop.Dom.Refactoring;
using System.Collections.Generic;
namespace ICSharpCode.SharpDevelop
{
public interface ICompletionItemList
{
IEnumerable<ICompletionItem> Items { get; }
}
public class DefaultCompletionItemList : ICompletionItemList
{
IList<ICompletionItem> items;
public DefaultCompletionItemList()
: this(new List<ICompletionItem>())
{
}
public DefaultCompletionItemList(IList<ICompletionItem> items)
{
this.items = items;
}
public IList<ICompletionItem> Items {
get { return items; }
}
IEnumerable<ICompletionItem> ICompletionItemList.Items {
get { return items; }
}
}
}

11
src/Main/Base/Project/Src/TextEditor/ITextEditor.cs

@ -5,11 +5,10 @@ @@ -5,11 +5,10 @@
// <version>$Revision$</version>
// </file>
using ICSharpCode.NRefactory;
using System;
using ICSharpCode.NRefactory;
using ICSharpCode.SharpDevelop.Dom.Refactoring;
using ICSharpCode.TextEditor.Gui.CompletionWindow;
using ICSharpCode.TextEditor.Gui.InsightWindow;
using System.Collections.Generic;
namespace ICSharpCode.SharpDevelop
{
@ -39,8 +38,10 @@ namespace ICSharpCode.SharpDevelop @@ -39,8 +38,10 @@ namespace ICSharpCode.SharpDevelop
void Select(int selectionStart, int selectionLength);
string FileName { get; }
void ShowInsightWindow(IInsightDataProvider provider);
void ShowCompletionWindow(ICompletionDataProvider provider, char ch);
void ShowInsightWindow(ICSharpCode.TextEditor.Gui.InsightWindow.IInsightDataProvider provider);
[Obsolete]
void ShowCompletionWindow(ICSharpCode.TextEditor.Gui.CompletionWindow.ICompletionDataProvider provider, char ch);
void ShowCompletionWindow(ICompletionItemList data);
string GetWordBeforeCaret();
}

Loading…
Cancel
Save