From 301d7ee33b9c6efce4aae5ff21b10a90823a3f41 Mon Sep 17 00:00:00 2001 From: Daniel Grunwald Date: Sat, 22 Jul 2006 11:09:38 +0000 Subject: [PATCH] Implemented enum completion after "return". git-svn-id: svn://svn.sharpdevelop.net/sharpdevelop/trunk@1615 1ccf3a8d-04fe-1044-b7c0-cef0b8235c61 --- .../Project/Src/CSharpCompletionBinding.cs | 40 ++++++++++++++++++- .../CompletionWindow/CodeCompletionWindow.cs | 25 +++++------- .../ICompletionDataProvider.cs | 31 ++++++++++---- .../NRefactoryResolver/NRefactoryResolver.cs | 4 +- .../AbstractCompletionDataProvider.cs | 25 ++++++++++-- .../CachedCompletionDataProvider.cs | 19 ++++++++- 6 files changed, 113 insertions(+), 31 deletions(-) diff --git a/src/AddIns/BackendBindings/CSharpBinding/Project/Src/CSharpCompletionBinding.cs b/src/AddIns/BackendBindings/CSharpBinding/Project/Src/CSharpCompletionBinding.cs index 6f86cc299a..eb8ef22ffe 100644 --- a/src/AddIns/BackendBindings/CSharpBinding/Project/Src/CSharpCompletionBinding.cs +++ b/src/AddIns/BackendBindings/CSharpBinding/Project/Src/CSharpCompletionBinding.cs @@ -222,7 +222,8 @@ namespace CSharpBinding if (c.ClassType == ClassType.Enum) { CtrlSpaceCompletionDataProvider cdp = new CtrlSpaceCompletionDataProvider(); cdp.ForceNewExpression = true; - CachedCompletionDataProvider cache = new CachedCompletionDataProvider(cdp); + ContextCompletionDataProvider cache = new ContextCompletionDataProvider(cdp); + cache.activationKey = charTyped; cache.GenerateCompletionData(editor.FileName, editor.ActiveTextAreaControl.TextArea, charTyped); ICompletionData[] completionData = cache.CompletionData; Array.Sort(completionData); @@ -236,13 +237,30 @@ namespace CSharpBinding } } if (cache.DefaultIndex >= 0) { - if (charTyped != ' ') cache.InsertSpace = true; + if (charTyped != ' ') cdp.InsertSpace = true; editor.ShowCompletionWindow(cache, charTyped); return true; } } return false; } + + private class ContextCompletionDataProvider : CachedCompletionDataProvider + { + internal char activationKey; + + internal ContextCompletionDataProvider(ICompletionDataProvider baseProvider) : base(baseProvider) + { + } + + public override CompletionDataProviderKeyResult ProcessKey(char key) + { + if (key == '=' && activationKey == '=') + return CompletionDataProviderKeyResult.BeforeStartKey; + activationKey = '\0'; + return base.ProcessKey(key); + } + } #endregion bool IsInComment(SharpDevelopTextAreaControl editor) @@ -276,6 +294,13 @@ namespace CSharpBinding return ShowNewCompletion(editor); case "case": return DoCaseCompletion(editor); + case "return": + IMember m = GetCurrentMember(editor); + if (m != null) { + return ProvideContextCompletion(editor, m.ReturnType, ' '); + } else { + goto default; + } default: return base.HandleKeyword(editor, word); } @@ -293,6 +318,17 @@ namespace CSharpBinding return false; } + IMember GetCurrentMember(SharpDevelopTextAreaControl editor) + { + ICSharpCode.TextEditor.Caret caret = editor.ActiveTextAreaControl.Caret; + NRefactoryResolver r = new NRefactoryResolver(SupportedLanguage.CSharp); + if (r.Initialize(editor.FileName, caret.Line + 1, caret.Column + 1)) { + return r.CallingMember; + } else { + return null; + } + } + #region "case"-keyword completion bool DoCaseCompletion(SharpDevelopTextAreaControl editor) { diff --git a/src/Libraries/ICSharpCode.TextEditor/Project/Src/Gui/CompletionWindow/CodeCompletionWindow.cs b/src/Libraries/ICSharpCode.TextEditor/Project/Src/Gui/CompletionWindow/CodeCompletionWindow.cs index b00527aff0..17d2fa3d88 100644 --- a/src/Libraries/ICSharpCode.TextEditor/Project/Src/Gui/CompletionWindow/CodeCompletionWindow.cs +++ b/src/Libraries/ICSharpCode.TextEditor/Project/Src/Gui/CompletionWindow/CodeCompletionWindow.cs @@ -151,17 +151,19 @@ namespace ICSharpCode.TextEditor.Gui.CompletionWindow public override bool ProcessKeyEvent(char ch) { - if (dataProvider.IsInsertionKey(ch)) { - if (ch == ' ' && dataProvider.InsertSpace) { - // increment start + end and process as normal space + switch (dataProvider.ProcessKey(ch)) { + case CompletionDataProviderKeyResult.BeforeStartKey: + // increment start + end and process as normal char ++startOffset; - } else { + goto case CompletionDataProviderKeyResult.NormalKey; + case CompletionDataProviderKeyResult.NormalKey: + ++endOffset; + return base.ProcessKeyEvent(ch); + case CompletionDataProviderKeyResult.InsertionKey: return InsertSelectedItem(ch); - } + default: + throw new InvalidOperationException("Invalid return value of dataProvider.ProcessKey"); } - dataProvider.InsertSpace = false; - ++endOffset; - return base.ProcessKeyEvent(ch); } protected override void CaretOffsetChanged(object sender, EventArgs e) @@ -262,12 +264,7 @@ namespace ICSharpCode.TextEditor.Gui.CompletionWindow if (endOffset - startOffset > 0) { control.Document.Remove(startOffset, endOffset - startOffset); } - if (dataProvider.InsertSpace) { - control.Document.Insert(startOffset++, " "); - } - control.ActiveTextAreaControl.Caret.Position = control.Document.OffsetToPosition(startOffset); - - result = data.InsertAction(control.ActiveTextAreaControl.TextArea, ch); + result = dataProvider.InsertAction(data, control.ActiveTextAreaControl.TextArea, startOffset, ch); } finally { control.EndUpdate(); } diff --git a/src/Libraries/ICSharpCode.TextEditor/Project/Src/Gui/CompletionWindow/ICompletionDataProvider.cs b/src/Libraries/ICSharpCode.TextEditor/Project/Src/Gui/CompletionWindow/ICompletionDataProvider.cs index 79b54b8f22..31d03cdb05 100644 --- a/src/Libraries/ICSharpCode.TextEditor/Project/Src/Gui/CompletionWindow/ICompletionDataProvider.cs +++ b/src/Libraries/ICSharpCode.TextEditor/Project/Src/Gui/CompletionWindow/ICompletionDataProvider.cs @@ -29,21 +29,38 @@ namespace ICSharpCode.TextEditor.Gui.CompletionWindow int DefaultIndex { get; } + /// - /// Gets/Sets if a space should be inserted in front of the completed expression. + /// Processes a keypress. Returns the action to be run with the key. /// - bool InsertSpace { - get; - set; - } + CompletionDataProviderKeyResult ProcessKey(char key); + /// - /// Gets if pressing 'key' should trigger the insertion of the currently selected element. + /// Executes the insertion. The provider should set the caret position and then + /// call data.InsertAction. /// - bool IsInsertionKey(char key); + bool InsertAction(ICompletionData data, TextArea textArea, int insertionOffset, char key); /// /// Generates the completion data. This method is called by the text editor control. /// ICompletionData[] GenerateCompletionData(string fileName, TextArea textArea, char charTyped); } + + public enum CompletionDataProviderKeyResult + { + /// + /// Normal key, used to choose + /// + NormalKey, + /// + /// This key triggers insertion of the completed expression + /// + InsertionKey, + /// + /// Increment both start and end offset of completion region when inserting this + /// key. Used to insert space. + /// + BeforeStartKey + } } diff --git a/src/Main/Base/Project/Src/Dom/NRefactoryResolver/NRefactoryResolver.cs b/src/Main/Base/Project/Src/Dom/NRefactoryResolver/NRefactoryResolver.cs index 225c715dd4..55d2a8cdd5 100644 --- a/src/Main/Base/Project/Src/Dom/NRefactoryResolver/NRefactoryResolver.cs +++ b/src/Main/Base/Project/Src/Dom/NRefactoryResolver/NRefactoryResolver.cs @@ -158,6 +158,7 @@ namespace ICSharpCode.SharpDevelop.Dom.NRefactoryResolver if (cu != null) { callingClass = cu.GetInnermostClass(caretLine, caretColumn); } + callingMember = GetCurrentMember(); return true; } @@ -282,7 +283,6 @@ namespace ICSharpCode.SharpDevelop.Dom.NRefactoryResolver { lookupTableVisitor = new LookupTableVisitor(languageProperties.NameComparer); - callingMember = GetCurrentMember(); if (callingMember != null) { CompilationUnit cu = ParseCurrentMemberAsCompilationUnit(fileContent); if (cu != null) { @@ -498,8 +498,6 @@ namespace ICSharpCode.SharpDevelop.Dom.NRefactoryResolver public TextReader ExtractCurrentMethod(string fileContent) { - if (callingMember == null) - callingMember = GetCurrentMember(); if (callingMember == null) return null; return ExtractMethod(fileContent, callingMember, language, caretLine); diff --git a/src/Main/Base/Project/Src/TextEditor/Gui/Editor/CompletionWindow/AbstractCompletionDataProvider.cs b/src/Main/Base/Project/Src/TextEditor/Gui/Editor/CompletionWindow/AbstractCompletionDataProvider.cs index 4163d8bf28..6c01410cd6 100644 --- a/src/Main/Base/Project/Src/TextEditor/Gui/Editor/CompletionWindow/AbstractCompletionDataProvider.cs +++ b/src/Main/Base/Project/Src/TextEditor/Gui/Editor/CompletionWindow/AbstractCompletionDataProvider.cs @@ -65,9 +65,28 @@ namespace ICSharpCode.SharpDevelop.DefaultEditor.Gui.Editor /// /// Gets if pressing 'key' should trigger the insertion of the currently selected element. /// - public virtual bool IsInsertionKey(char key) + public virtual CompletionDataProviderKeyResult ProcessKey(char key) { - return !char.IsLetterOrDigit(key) && key != '_'; + CompletionDataProviderKeyResult res; + if (key == ' ' && insertSpace) { + res = CompletionDataProviderKeyResult.BeforeStartKey; + } else if (char.IsLetterOrDigit(key) || key == '_') { + res = CompletionDataProviderKeyResult.NormalKey; + } else { + res = CompletionDataProviderKeyResult.InsertionKey; + } + insertSpace = false; + return res; + } + + public virtual bool InsertAction(ICompletionData data, TextArea textArea, int insertionOffset, char key) + { + if (InsertSpace) { + textArea.Document.Insert(insertionOffset++, " "); + } + textArea.Caret.Position = textArea.Document.OffsetToPosition(insertionOffset); + + return data.InsertAction(textArea, key); } /// @@ -75,7 +94,7 @@ namespace ICSharpCode.SharpDevelop.DefaultEditor.Gui.Editor /// public abstract ICompletionData[] GenerateCompletionData(string fileName, TextArea textArea, char charTyped); } - + public abstract class AbstractCodeCompletionDataProvider : AbstractCompletionDataProvider { Hashtable insertedElements = new Hashtable(); diff --git a/src/Main/Base/Project/Src/TextEditor/Gui/Editor/CompletionWindow/CachedCompletionDataProvider.cs b/src/Main/Base/Project/Src/TextEditor/Gui/Editor/CompletionWindow/CachedCompletionDataProvider.cs index df587cd179..35167762d9 100644 --- a/src/Main/Base/Project/Src/TextEditor/Gui/Editor/CompletionWindow/CachedCompletionDataProvider.cs +++ b/src/Main/Base/Project/Src/TextEditor/Gui/Editor/CompletionWindow/CachedCompletionDataProvider.cs @@ -44,9 +44,14 @@ namespace ICSharpCode.SharpDevelop.DefaultEditor.Gui.Editor } } - public override bool IsInsertionKey(char key) + public override CompletionDataProviderKeyResult ProcessKey(char key) { - return baseProvider.IsInsertionKey(key); + return baseProvider.ProcessKey(key); + } + + public override bool InsertAction(ICompletionData data, TextArea textArea, int insertionOffset, char key) + { + return baseProvider.InsertAction(data, textArea, insertionOffset, key); } public override ICompletionData[] GenerateCompletionData(string fileName, TextArea textArea, char charTyped) @@ -58,5 +63,15 @@ namespace ICSharpCode.SharpDevelop.DefaultEditor.Gui.Editor } return completionData; } + + [Obsolete("Cannot use InsertSpace on CachedCompletionDataProvider, please set it on the underlying provider!")] + public new bool InsertSpace { + get { + return false; + } + set { + throw new NotSupportedException(); + } + } } }