diff options
author | Mike Krüger <mkrueger@xamarin.com> | 2017-01-24 01:26:15 +0300 |
---|---|---|
committer | Mike Krüger <mkrueger@xamarin.com> | 2017-01-24 01:26:15 +0300 |
commit | be7ee132375ab2159b84a1575e6251de226715f7 (patch) | |
tree | 31d480db7d0956af5192d286b51470e19e87ef46 /main | |
parent | 4a28174af1188ff9ae59fdaa55cdb21787642dd5 (diff) |
[Ide] Unified code completion handle paths.
We had 3 different cases of completion - the c# binding already
contained a solution for that : completion trigger info. That struct
contains all information the backend needs to take care of.
Diffstat (limited to 'main')
20 files changed, 151 insertions, 197 deletions
diff --git a/main/external/fsharpbinding/MonoDevelop.FSharpBinding/FSharpTextEditorCompletion.fs b/main/external/fsharpbinding/MonoDevelop.FSharpBinding/FSharpTextEditorCompletion.fs index 826156cc53..dd76126596 100644 --- a/main/external/fsharpbinding/MonoDevelop.FSharpBinding/FSharpTextEditorCompletion.fs +++ b/main/external/fsharpbinding/MonoDevelop.FSharpBinding/FSharpTextEditorCompletion.fs @@ -796,20 +796,18 @@ type FSharpTextEditorCompletion() = base.KeyPress (descriptor) // Run completion automatically when the user hits '.' - override x.HandleCodeCompletionAsync(context, completionChar, token) = - if IdeApp.Preferences.EnableAutoCodeCompletion.Value || completionChar = '.' then - let computation = - Completion.codeCompletionCommandImpl(x.Editor, x.DocumentContext, context, false) - - Async.StartAsTask (computation = computation, cancellationToken = token) + override x.HandleCodeCompletionAsync(context, triggerInfo, token) = + if IdeApp.Preferences.EnableAutoCodeCompletion.Value then + if triggerInfo.CompletionTriggerReason = CompletionTriggerReason.CharTyped && triggerInfo.TriggerCharacter.Value = '.' || triggerInfo.CompletionTriggerReason = CompletionTriggerReason.CompletionCommand then + let computation = + Completion.codeCompletionCommandImpl(x.Editor, x.DocumentContext, context, false) + + Async.StartAsTask (computation = computation, cancellationToken = token) + else + Task.FromResult null else Task.FromResult null - /// Completion was triggered explicitly using Ctrl+Space or by the function above - override x.CodeCompletionCommand(context) = - Completion.codeCompletionCommandImpl(x.Editor, x.DocumentContext, context, true) - |> Async.StartAsTask - override x.GetCurrentParameterIndex (startOffset: int, token) = let computation = diff --git a/main/src/addins/AspNet/Razor/RazorCSharpEditorExtension.cs b/main/src/addins/AspNet/Razor/RazorCSharpEditorExtension.cs index 6e245ce749..aca34d220e 100644 --- a/main/src/addins/AspNet/Razor/RazorCSharpEditorExtension.cs +++ b/main/src/addins/AspNet/Razor/RazorCSharpEditorExtension.cs @@ -442,16 +442,24 @@ namespace MonoDevelop.AspNet.Razor return hiddenOff; } - public override async System.Threading.Tasks.Task<ICompletionDataList> HandleCodeCompletionAsync (CodeCompletionContext completionContext, char completionChar, System.Threading.CancellationToken token) + public override async System.Threading.Tasks.Task<ICompletionDataList> HandleCodeCompletionAsync (CodeCompletionContext completionContext, CompletionTriggerInfo triggerInfo, System.Threading.CancellationToken token) { + if (triggerInfo.CompletionTriggerReason == CompletionTriggerReason.CompletionCommand) { + if (hiddenInfo != null && (isInCSharpContext || Tracker.Engine.CurrentState is RazorState) + && !(Tracker.Engine.Nodes.Peek () is XElement)) { + InitializeCodeCompletion (); + return await completionBuilder.HandlePopupCompletion (defaultEditor, defaultDocumentContext, hiddenInfo); + } + } char previousChar = defaultEditor.CaretOffset > 1 ? defaultEditor.GetCharAt ( defaultEditor.CaretOffset - 2) : ' '; - + if (triggerInfo.CompletionTriggerReason != CompletionTriggerReason.CharTyped) + return null; // Don't show completion window when directive's name is being typed var directive = Tracker.Engine.Nodes.Peek () as RazorDirective; if (directive != null && !directive.FirstBracket.HasValue) return null; - + var completionChar = triggerInfo.TriggerCharacter.Value; if (hiddenInfo != null && isInCSharpContext) { var list = (CompletionDataList) await completionBuilder.HandleCompletion (defaultEditor, defaultDocumentContext, completionContext, hiddenInfo, completionChar, token); @@ -472,7 +480,7 @@ namespace MonoDevelop.AspNet.Razor return list; } - return await base.HandleCodeCompletionAsync (completionContext, completionChar, token); + return await base.HandleCodeCompletionAsync (completionContext, triggerInfo, token); } //recreating the list is over 2x as fast as using remove operations, saves typically 10ms @@ -552,16 +560,6 @@ namespace MonoDevelop.AspNet.Razor return list; } - public override Task<ICompletionDataList> CodeCompletionCommand (CodeCompletionContext completionContext) - { - if (hiddenInfo != null && (isInCSharpContext || Tracker.Engine.CurrentState is RazorState) - && !(Tracker.Engine.Nodes.Peek () is XElement)) { - InitializeCodeCompletion (); - return completionBuilder.HandlePopupCompletion (defaultEditor, defaultDocumentContext, hiddenInfo); - } - - return base.CodeCompletionCommand (completionContext); - } /* public override bool GetParameterCompletionCommandOffset (out int cpos) { diff --git a/main/src/addins/AspNet/Tests/Razor/RazorCompletionTesting.cs b/main/src/addins/AspNet/Tests/Razor/RazorCompletionTesting.cs index a82c38ef35..a1b618bb15 100644 --- a/main/src/addins/AspNet/Tests/Razor/RazorCompletionTesting.cs +++ b/main/src/addins/AspNet/Tests/Razor/RazorCompletionTesting.cs @@ -59,19 +59,19 @@ namespace MonoDevelop.AspNet.Tests.Razor int cursorPosition = text.IndexOf ('$');
var ctx = GetCodeCompletionContext (isInCSharpContext, ed.View, ed.Extension.hiddenInfo.UnderlyingDocument);
-
+ + Task<ICompletionDataList> task;
if (isCtrlSpace) {
- var result = await ed.Extension.CodeCompletionCommand (ctx) as CompletionDataList;
- TypeSystemServiceTestExtensions.UnloadSolution (solution);
- return result;
+ task = ed.Extension.HandleCodeCompletionAsync (ctx, CompletionTriggerInfo.CodeCompletionCommand, default (CancellationToken));
} else {
- var task = ed.Extension.HandleCodeCompletionAsync (ctx, ed.EditorText [cursorPosition - 1], default(CancellationToken));
- TypeSystemServiceTestExtensions.UnloadSolution (solution); - if (task != null) { - return await task as CompletionDataList; - } - return null;
+ task = ed.Extension.HandleCodeCompletionAsync (ctx, new CompletionTriggerInfo (CompletionTriggerReason.CharTyped, ed.EditorText [cursorPosition - 1]), default (CancellationToken)); }
+ + TypeSystemServiceTestExtensions.UnloadSolution (solution); + if (task != null) { + return await task as CompletionDataList; + } + return null; }
static CodeCompletionContext GetCodeCompletionContext (bool cSharpContext, TestViewContent sev, UnderlyingDocument underlyingDocument)
diff --git a/main/src/addins/AspNet/Tests/WebForms/WebFormsTesting.cs b/main/src/addins/AspNet/Tests/WebForms/WebFormsTesting.cs index 1f8273e471..9143fa4793 100644 --- a/main/src/addins/AspNet/Tests/WebForms/WebFormsTesting.cs +++ b/main/src/addins/AspNet/Tests/WebForms/WebFormsTesting.cs @@ -53,9 +53,9 @@ namespace MonoDevelop.AspNet.Tests.WebForms var ctx = textEditorCompletion.GetCodeCompletionContext (sev); if (isCtrlSpace) - return await textEditorCompletion.CodeCompletionCommand (ctx) as CompletionDataList; + return await textEditorCompletion.HandleCodeCompletionAsync (ctx, CompletionTriggerInfo.CodeCompletionCommand) as CompletionDataList; else { - var task = textEditorCompletion.HandleCodeCompletionAsync (ctx, editorText [cursorPosition - 1]); + var task = textEditorCompletion.HandleCodeCompletionAsync (ctx, new CompletionTriggerInfo (CompletionTriggerReason.CharTyped, editorText [cursorPosition - 1])); if (task != null) { return await task as CompletionDataList; } diff --git a/main/src/addins/AspNet/WebForms/WebFormsEditorExtension.cs b/main/src/addins/AspNet/WebForms/WebFormsEditorExtension.cs index 317ab2acb8..6d1533318f 100644 --- a/main/src/addins/AspNet/WebForms/WebFormsEditorExtension.cs +++ b/main/src/addins/AspNet/WebForms/WebFormsEditorExtension.cs @@ -237,17 +237,17 @@ namespace MonoDevelop.AspNet.WebForms // }; } - + /* public override Task<ICompletionDataList> CodeCompletionCommand (CodeCompletionContext completionContext) { -/* //completion for ASP.NET expressions + //completion for ASP.NET expressions // TODO: Detect <script> state here !!! if (documentBuilder != null && Tracker.Engine.CurrentState is WebFormsExpressionState) { InitializeCodeCompletion ('\0'); return documentBuilder.HandlePopupCompletion (defaultEditor, defaultDocumentContext, documentInfo, localDocumentInfo); - }*/ + } return base.CodeCompletionCommand (completionContext); - } + }*/ protected override void Initialize () { diff --git a/main/src/addins/CSharpBinding/AspNet/RazorCSharpCompletionBuilder.cs b/main/src/addins/CSharpBinding/AspNet/RazorCSharpCompletionBuilder.cs index 6a39304a4f..8076890f66 100644 --- a/main/src/addins/CSharpBinding/AspNet/RazorCSharpCompletionBuilder.cs +++ b/main/src/addins/CSharpBinding/AspNet/RazorCSharpCompletionBuilder.cs @@ -79,7 +79,7 @@ namespace MonoDevelop.CSharp.Completion {
CodeCompletionContext ccc;
var completion = CreateCompletionAndUpdate (editor, context, docInfo, out ccc);
- return completion.CodeCompletionCommand (ccc);
+ return completion.HandleCodeCompletionAsync (ccc, CompletionTriggerInfo.CodeCompletionCommand);
}
public Task<ICompletionDataList> HandleCompletion (MonoDevelop.Ide.Editor.TextEditor editor, DocumentContext context, CodeCompletionContext completionContext,
@@ -87,7 +87,7 @@ namespace MonoDevelop.CSharp.Completion {
CodeCompletionContext ccc;
var completion = CreateCompletionAndUpdate (editor, context, docInfo, out ccc);
- return completion.HandleCodeCompletionAsync (completionContext, currentChar, token);
+ return completion.HandleCodeCompletionAsync (completionContext, new CompletionTriggerInfo (CompletionTriggerReason.CharTyped, currentChar), token);
}
public Task<ParameterHintingResult> HandleParameterCompletion (MonoDevelop.Ide.Editor.TextEditor editor, DocumentContext context, CodeCompletionContext completionContext,
diff --git a/main/src/addins/CSharpBinding/CSharpBinding.csproj b/main/src/addins/CSharpBinding/CSharpBinding.csproj index 03255be55b..43f283b7d5 100644 --- a/main/src/addins/CSharpBinding/CSharpBinding.csproj +++ b/main/src/addins/CSharpBinding/CSharpBinding.csproj @@ -643,8 +643,6 @@ <Compile Include="MonoDevelop.CSharp.Features\Completion\CompletionContext.cs" /> <Compile Include="MonoDevelop.CSharp.Features\Completion\CompletionEngine.cs" /> <Compile Include="MonoDevelop.CSharp.Features\Completion\CompletionResult.cs" /> - <Compile Include="MonoDevelop.CSharp.Features\Completion\CompletionTriggerInfo.cs" /> - <Compile Include="MonoDevelop.CSharp.Features\Completion\CompletionTriggerReason.cs" /> <Compile Include="MonoDevelop.CSharp.Features\Completion\EditorBrowsableBehavior.cs" /> <Compile Include="MonoDevelop.CSharp.Features\Completion\ICompletionDataFactory.cs" /> <Compile Include="MonoDevelop.CSharp.Features\Completion\ContextHandler\CastCompletionContextHandler.cs" /> diff --git a/main/src/addins/CSharpBinding/MonoDevelop.CSharp.Completion/CSharpCompletionTextEditorExtension.cs b/main/src/addins/CSharpBinding/MonoDevelop.CSharp.Completion/CSharpCompletionTextEditorExtension.cs index 82f593d0b4..ac2a8a1d90 100644 --- a/main/src/addins/CSharpBinding/MonoDevelop.CSharp.Completion/CSharpCompletionTextEditorExtension.cs +++ b/main/src/addins/CSharpBinding/MonoDevelop.CSharp.Completion/CSharpCompletionTextEditorExtension.cs @@ -277,33 +277,67 @@ namespace MonoDevelop.CSharp.Completion { HandleDocumentParsed (null, null); } - - public override Task<ICompletionDataList> HandleCodeCompletionAsync (CodeCompletionContext completionContext, char completionChar, CancellationToken token = default(CancellationToken)) + + public override Task<ICompletionDataList> HandleCodeCompletionAsync (CodeCompletionContext completionContext, CompletionTriggerInfo triggerInfo, CancellationToken token = default (CancellationToken)) { -// if (!EnableCodeCompletion) -// return null; - if (!IdeApp.Preferences.EnableAutoCodeCompletion && char.IsLetter (completionChar)) + // if (!EnableCodeCompletion) + // return null; + if (!IdeApp.Preferences.EnableAutoCodeCompletion) return null; - - // var timer = Counters.ResolveTime.BeginTiming (); - try { - int triggerWordLength = 0; - if (char.IsLetterOrDigit (completionChar) || completionChar == '_') { - if (completionContext.TriggerOffset > 1 && char.IsLetterOrDigit (Editor.GetCharAt (completionContext.TriggerOffset - 2))) - return null; - triggerWordLength = 1; + int triggerWordLength = 0; + switch (triggerInfo.CompletionTriggerReason) { + case CompletionTriggerReason.CharTyped: + // var timer = Counters.ResolveTime.BeginTiming (); + try { + var completionChar = triggerInfo.TriggerCharacter.Value; + if (char.IsLetterOrDigit (completionChar) || completionChar == '_') { + if (completionContext.TriggerOffset > 1 && char.IsLetterOrDigit (Editor.GetCharAt (completionContext.TriggerOffset - 2))) + return null; + triggerWordLength = 1; + } + return InternalHandleCodeCompletion (completionContext, completionChar, false, triggerWordLength, token); + } catch (Exception e) { + LoggingService.LogError ("Unexpected code completion exception." + Environment.NewLine + + "FileName: " + DocumentContext.Name + Environment.NewLine + + "Position: line=" + completionContext.TriggerLine + " col=" + completionContext.TriggerLineOffset + Environment.NewLine + + "Line text: " + Editor.GetLineText (completionContext.TriggerLine), + e); + return null; + } finally { + // if (timer != null) + // timer.Dispose (); } - return InternalHandleCodeCompletion (completionContext, completionChar, false, triggerWordLength, token); - } catch (Exception e) { - LoggingService.LogError ("Unexpected code completion exception." + Environment.NewLine + - "FileName: " + DocumentContext.Name + Environment.NewLine + - "Position: line=" + completionContext.TriggerLine + " col=" + completionContext.TriggerLineOffset + Environment.NewLine + - "Line text: " + Editor.GetLineText (completionContext.TriggerLine), - e); - return null; - } finally { - // if (timer != null) - // timer.Dispose (); + case CompletionTriggerReason.BackspaceOrDeleteCommand: + //char completionChar = Editor.GetCharAt (completionContext.TriggerOffset - 1); + //Console.WriteLine ("completion char: " + completionChar); + // var timer = Counters.ResolveTime.BeginTiming (); + char ch = completionContext.TriggerOffset > 0 ? Editor.GetCharAt (completionContext.TriggerOffset - 1) : '\0'; + char ch2 = completionContext.TriggerOffset < Editor.Length ? Editor.GetCharAt (completionContext.TriggerOffset) : '\0'; + if (!IsIdentifierPart (ch) && !IsIdentifierPart (ch2)) + return null; + try { + return InternalHandleCodeCompletion (completionContext, ch, true, triggerWordLength, token).ContinueWith (t => { + var result = (CompletionDataList)t.Result; + if (result == null) + return null; + result.AutoCompleteUniqueMatch = false; + result.AutoCompleteEmptyMatch = false; + return (ICompletionDataList)result; + }); + } catch (Exception e) { + LoggingService.LogError ("Unexpected code completion exception." + Environment.NewLine + + "FileName: " + DocumentContext.Name + Environment.NewLine + + "Position: line=" + completionContext.TriggerLine + " col=" + completionContext.TriggerLineOffset + Environment.NewLine + + "Line text: " + Editor.GetLineText (completionContext.TriggerLine), + e); + return null; + } finally { + // if (timer != null) + // timer.Dispose (); + } + default: + ch = completionContext.TriggerOffset > 0 ? Editor.GetCharAt (completionContext.TriggerOffset - 1) : '\0'; + return InternalHandleCodeCompletion (completionContext, ch, true, triggerWordLength, default (CancellationToken)); } } @@ -312,44 +346,6 @@ namespace MonoDevelop.CSharp.Completion return char.IsLetterOrDigit (ch) || ch == '_'; } - public override Task<ICompletionDataList> HandleBackspaceOrDeleteCodeCompletionAsync (CodeCompletionContext completionContext, SpecialKey key, char triggerCharacter, CancellationToken token = default(CancellationToken)) - { - if (!IdeApp.Preferences.EnableAutoCodeCompletion) - return null; - if (!char.IsLetterOrDigit (triggerCharacter) && triggerCharacter != '_') - return null; - //char completionChar = Editor.GetCharAt (completionContext.TriggerOffset - 1); - //Console.WriteLine ("completion char: " + completionChar); - // var timer = Counters.ResolveTime.BeginTiming (); - - if (key == SpecialKey.BackSpace || key == SpecialKey.Delete) { - char ch = completionContext.TriggerOffset > 0 ? Editor.GetCharAt (completionContext.TriggerOffset - 1) : '\0'; - char ch2 = completionContext.TriggerOffset < Editor.Length ? Editor.GetCharAt (completionContext.TriggerOffset) : '\0'; - if (!IsIdentifierPart (ch) && !IsIdentifierPart (ch2)) - return null; - } - try { - int triggerWordLength = 0; - return InternalHandleCodeCompletion (completionContext, triggerCharacter, true, triggerWordLength, token).ContinueWith ( t => { - var result = (CompletionDataList)t.Result; - if (result == null) - return null; - result.AutoCompleteUniqueMatch = false; - result.AutoCompleteEmptyMatch = false; - return (ICompletionDataList)result; - }); - } catch (Exception e) { - LoggingService.LogError ("Unexpected code completion exception." + Environment.NewLine + - "FileName: " + DocumentContext.Name + Environment.NewLine + - "Position: line=" + completionContext.TriggerLine + " col=" + completionContext.TriggerLineOffset + Environment.NewLine + - "Line text: " + Editor.GetLineText (completionContext.TriggerLine), - e); - return null; - } finally { - // if (timer != null) - // timer.Dispose (); - } } - internal class CSharpCompletionDataList : CompletionDataList { } @@ -524,13 +520,7 @@ namespace MonoDevelop.CSharp.Completion return (ICompletionDataList)list; }); } - - public override Task<ICompletionDataList> CodeCompletionCommand (CodeCompletionContext completionContext) - { - int triggerWordLength = 0; - char ch = completionContext.TriggerOffset > 0 ? Editor.GetCharAt (completionContext.TriggerOffset - 1) : '\0'; - return InternalHandleCodeCompletion (completionContext, ch, true, triggerWordLength, default(CancellationToken)); - } + static bool HasAllUsedParameters (MonoDevelop.Ide.CodeCompletion.ParameterHintingData provider, string[] list) { diff --git a/main/src/addins/TextTemplating/MonoDevelop.TextTemplating/Gui/T4EditorExtension.cs b/main/src/addins/TextTemplating/MonoDevelop.TextTemplating/Gui/T4EditorExtension.cs index dc4afb12c9..520954efab 100644 --- a/main/src/addins/TextTemplating/MonoDevelop.TextTemplating/Gui/T4EditorExtension.cs +++ b/main/src/addins/TextTemplating/MonoDevelop.TextTemplating/Gui/T4EditorExtension.cs @@ -99,19 +99,20 @@ namespace MonoDevelop.TextTemplating.Gui #region Code completion - public override Task<ICompletionDataList> CodeCompletionCommand (CodeCompletionContext completionContext) + public override Task<ICompletionDataList> HandleCodeCompletionAsync (CodeCompletionContext completionContext, CompletionTriggerInfo triggerInfo, CancellationToken token = default(CancellationToken)) { - int pos = completionContext.TriggerOffset; - if (pos <= 0) - return null; - return HandleCodeCompletion ((CodeCompletionContext) completionContext, true); - } + if (triggerInfo.CompletionTriggerReason == CompletionTriggerReason.CharTyped) { + char completionChar = triggerInfo.TriggerCharacter.Value; + int pos = completionContext.TriggerOffset; + if (pos > 0 && Editor.GetCharAt (pos - 1) == completionChar) { + return HandleCodeCompletion (completionContext, false); + } + } else if (triggerInfo.CompletionTriggerReason == CompletionTriggerReason.CompletionCommand) { + int pos = completionContext.TriggerOffset; + if (pos <= 0) + return null; + return HandleCodeCompletion ((CodeCompletionContext)completionContext, true); - public override Task<ICompletionDataList> HandleCodeCompletionAsync (CodeCompletionContext completionContext, char completionChar, CancellationToken token = default(CancellationToken)) - { - int pos = completionContext.TriggerOffset; - if (pos > 0 && Editor.GetCharAt (pos - 1) == completionChar) { - return HandleCodeCompletion (completionContext, false); } return null; } diff --git a/main/src/addins/Xml/Editor/BaseXmlEditorExtension.cs b/main/src/addins/Xml/Editor/BaseXmlEditorExtension.cs index 32d38c7449..ad325de517 100644 --- a/main/src/addins/Xml/Editor/BaseXmlEditorExtension.cs +++ b/main/src/addins/Xml/Editor/BaseXmlEditorExtension.cs @@ -260,22 +260,23 @@ namespace MonoDevelop.Xml.Editor #region Code completion - public override Task<ICompletionDataList> CodeCompletionCommand (CodeCompletionContext completionContext) - { - int pos = completionContext.TriggerOffset; - if (pos <= 0) - return null; - tracker.UpdateEngine (); - return HandleCodeCompletion (completionContext, true, default(CancellationToken)); - } - public override Task<ICompletionDataList> HandleCodeCompletionAsync (CodeCompletionContext completionContext, char completionChar, CancellationToken token = default(CancellationToken)) + public override Task<ICompletionDataList> HandleCodeCompletionAsync (CodeCompletionContext completionContext, CompletionTriggerInfo triggerInfo, CancellationToken token = default(CancellationToken)) { - int pos = completionContext.TriggerOffset; - char ch = CompletionWidget != null ? CompletionWidget.GetChar (pos - 1) : Editor.GetCharAt (pos - 1); - if (pos > 0 && ch == completionChar) { + if (triggerInfo.CompletionTriggerReason == CompletionTriggerReason.CharTyped) { + int pos = completionContext.TriggerOffset; + char ch = CompletionWidget != null ? CompletionWidget.GetChar (pos - 1) : Editor.GetCharAt (pos - 1); + if (pos > 0 && ch == triggerInfo.TriggerCharacter.Value) { + tracker.UpdateEngine (); + return HandleCodeCompletion (completionContext, false, token); + } + } else if (triggerInfo.CompletionTriggerReason == CompletionTriggerReason.CompletionCommand) { + int pos = completionContext.TriggerOffset; + if (pos <= 0) + return null; tracker.UpdateEngine (); - return HandleCodeCompletion (completionContext, false, token); + return HandleCodeCompletion (completionContext, true, default (CancellationToken)); + } return null; } diff --git a/main/src/addins/CSharpBinding/MonoDevelop.CSharp.Features/Completion/CompletionTriggerInfo.cs b/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.CodeCompletion/CompletionTriggerInfo.cs index a7b0a42ff1..d3838a005d 100644 --- a/main/src/addins/CSharpBinding/MonoDevelop.CSharp.Features/Completion/CompletionTriggerInfo.cs +++ b/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.CodeCompletion/CompletionTriggerInfo.cs @@ -26,13 +26,15 @@ using System; -namespace ICSharpCode.NRefactory6.CSharp.Completion +namespace MonoDevelop.Ide.CodeCompletion { /// <summary> /// Provides information about what triggered completion. /// </summary> public struct CompletionTriggerInfo { + public static readonly CompletionTriggerInfo CodeCompletionCommand = new CompletionTriggerInfo (CompletionTriggerReason.CompletionCommand); + /// <summary> /// Provides the reason that completion was triggered. /// </summary> diff --git a/main/src/addins/CSharpBinding/MonoDevelop.CSharp.Features/Completion/CompletionTriggerReason.cs b/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.CodeCompletion/CompletionTriggerReason.cs index df9a2edafb..7bb7392395 100644 --- a/main/src/addins/CSharpBinding/MonoDevelop.CSharp.Features/Completion/CompletionTriggerReason.cs +++ b/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.CodeCompletion/CompletionTriggerReason.cs @@ -26,7 +26,7 @@ using System; -namespace ICSharpCode.NRefactory6.CSharp.Completion +namespace MonoDevelop.Ide.CodeCompletion { public enum CompletionTriggerReason { diff --git a/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.CodeTemplates/ExpansionObject.cs b/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.CodeTemplates/ExpansionObject.cs index 2c514affc6..92e8c205dd 100644 --- a/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.CodeTemplates/ExpansionObject.cs +++ b/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.CodeTemplates/ExpansionObject.cs @@ -184,8 +184,9 @@ namespace MonoDevelop.Ide.CodeTemplates if (ext != null) { if (list == null) - list = ext.CodeCompletionCommand ( - CurrentContext.DocumentContext.GetContent <MonoDevelop.Ide.CodeCompletion.ICompletionWidget> ().CurrentCodeCompletionContext).Result; + list = ext.HandleCodeCompletionAsync ( + CurrentContext.DocumentContext.GetContent <MonoDevelop.Ide.CodeCompletion.ICompletionWidget> ().CurrentCodeCompletionContext, + CompletionTriggerInfo.CodeCompletionCommand).Result; foreach (var data in list.OfType<ISymbolCompletionData> ()) { if (data.Symbol == null) diff --git a/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Editor.Extension/CompletionTextEditorExtension.cs b/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Editor.Extension/CompletionTextEditorExtension.cs index e2440e5e65..24080dd410 100644 --- a/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Editor.Extension/CompletionTextEditorExtension.cs +++ b/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Editor.Extension/CompletionTextEditorExtension.cs @@ -157,7 +157,7 @@ namespace MonoDevelop.Ide.Editor.Extension var caretOffset = Editor.CaretOffset; var token = completionTokenSrc.Token; try { - var task = HandleCodeCompletionAsync (CurrentCompletionContext, descriptor.KeyChar, token); + var task = HandleCodeCompletionAsync (CurrentCompletionContext, new CompletionTriggerInfo (CompletionTriggerReason.CharTyped, descriptor.KeyChar), token); if (task != null) { // Show the completion window in two steps. The call to PrepareShowWindow creates the window but // it doesn't show it. It is used only to process the keys while the completion data is being retrieved. @@ -214,7 +214,7 @@ namespace MonoDevelop.Ide.Editor.Extension var caretOffset = Editor.CaretOffset; var token = completionTokenSrc.Token; try { - var task = HandleBackspaceOrDeleteCodeCompletionAsync (CurrentCompletionContext, descriptor.SpecialKey, deleteOrBackspaceTriggerChar, token); + var task = HandleCodeCompletionAsync (CurrentCompletionContext, new CompletionTriggerInfo (CompletionTriggerReason.BackspaceOrDeleteCommand, deleteOrBackspaceTriggerChar), token); if (task != null) { // Show the completion window in two steps. The call to PrepareShowWindow creates the window but // it doesn't show it. It is used only to process the keys while the completion data is being retrieved. @@ -362,9 +362,7 @@ namespace MonoDevelop.Ide.Editor.Extension } CurrentCompletionContext = CompletionWidget.CreateCodeCompletionContext (cpos); CurrentCompletionContext.TriggerWordLength = wlen; - completionList = await CodeCompletionCommand (CurrentCompletionContext); - if (completionList.TriggerWordStart >= 0) - CurrentCompletionContext.TriggerOffset = completionList.TriggerWordStart; + completionList = await HandleCodeCompletionAsync (CurrentCompletionContext, new CompletionTriggerInfo (CompletionTriggerReason.CompletionCommand)); if (completionList == null || !CompletionWindowManager.ShowWindow (this, (char)0, completionList, CompletionWidget, CurrentCompletionContext)) { CurrentCompletionContext = null; } @@ -467,15 +465,11 @@ namespace MonoDevelop.Ide.Editor.Extension static readonly ICompletionDataList emptyList = new CompletionDataList (); - public virtual Task<ICompletionDataList> HandleCodeCompletionAsync (CodeCompletionContext completionContext, char completionChar, CancellationToken token = default(CancellationToken)) + public virtual Task<ICompletionDataList> HandleCodeCompletionAsync (CodeCompletionContext completionContext, CompletionTriggerInfo triggerInfo, CancellationToken token = default(CancellationToken)) { return Task.FromResult (emptyList); } - public virtual Task<ICompletionDataList> HandleBackspaceOrDeleteCodeCompletionAsync (CodeCompletionContext completionContext, SpecialKey key, char triggerCharacter, CancellationToken token = default(CancellationToken)) - { - return Task.FromResult (emptyList); - } public virtual Task<ParameterHintingResult> HandleParameterCompletionAsync (CodeCompletionContext completionContext, char completionChar, CancellationToken token = default(CancellationToken)) { @@ -543,27 +537,6 @@ namespace MonoDevelop.Ide.Editor.Extension } return list; } - - public virtual async Task<ICompletionDataList> CodeCompletionCommand (CodeCompletionContext completionContext) - { - // This default implementation of CodeCompletionCommand calls HandleCodeCompletion providing - // the char at the cursor position. If it returns a provider, just return it. - - completionTokenSrc.Cancel (); - completionTokenSrc = new CancellationTokenSource (); - var ctoken = completionTokenSrc.Token; - - int pos = completionContext.TriggerOffset; - if (pos > 0) { - char ch = Editor.GetCharAt (pos - 1); - try { - return await HandleCodeCompletionAsync (completionContext, ch, ctoken); - } catch (TaskCanceledException) { - } catch (AggregateException) { - } - } - return null; - } public virtual async Task<ParameterHintingResult> ParameterCompletionCommand (CodeCompletionContext completionContext) { diff --git a/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Editor.TextMate/TextMateCompletionTextEditorExtension.cs b/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Editor.TextMate/TextMateCompletionTextEditorExtension.cs index 1c88f9a58e..e3f045d934 100644 --- a/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Editor.TextMate/TextMateCompletionTextEditorExtension.cs +++ b/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Editor.TextMate/TextMateCompletionTextEditorExtension.cs @@ -113,14 +113,16 @@ namespace MonoDevelop.Ide.Editor.TextMate }); } - public override async Task<ICompletionDataList> HandleCodeCompletionAsync (CodeCompletionContext completionContext, char completionChar, CancellationToken token) + public override async Task<ICompletionDataList> HandleCodeCompletionAsync (CodeCompletionContext completionContext, CompletionTriggerInfo triggerInfo, CancellationToken token) { if (inactive) - return await base.HandleCodeCompletionAsync (completionContext, completionChar, token); + return await base.HandleCodeCompletionAsync (completionContext, triggerInfo, token); - if (!IdeApp.Preferences.EnableAutoCodeCompletion && char.IsLetter (completionChar)) + if (!IdeApp.Preferences.EnableAutoCodeCompletion) return null; - + if (triggerInfo.CompletionTriggerReason != CompletionTriggerReason.CharTyped) + return null; + char completionChar = triggerInfo.TriggerCharacter.Value; int triggerWordLength = 0; if (char.IsLetterOrDigit (completionChar) || completionChar == '_') { if (completionContext.TriggerOffset > 1 && char.IsLetterOrDigit (Editor.GetCharAt (completionContext.TriggerOffset - 2))) diff --git a/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Editor/Projection/ProjectedCompletionExtension.cs b/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Editor/Projection/ProjectedCompletionExtension.cs index 741fabe3c2..66e8b84e4a 100644 --- a/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Editor/Projection/ProjectedCompletionExtension.cs +++ b/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Editor/Projection/ProjectedCompletionExtension.cs @@ -250,14 +250,6 @@ namespace MonoDevelop.Ide.Editor.Projection return projectedExtension.CanRunCompletionCommand (); } - public override Task<MonoDevelop.Ide.CodeCompletion.ICompletionDataList> CodeCompletionCommand (MonoDevelop.Ide.CodeCompletion.CodeCompletionContext completionContext) - { - var projectedExtension = GetExtensionAt (completionContext.TriggerOffset); - if (projectedExtension == null) - return null; - return projectedExtension.CodeCompletionCommand (ConvertContext (completionContext)); - } - public override bool CanRunParameterCompletionCommand () { var projectedExtension = GetCurrentExtension (); @@ -302,13 +294,13 @@ namespace MonoDevelop.Ide.Editor.Projection return projectedExtension.GuessBestMethodOverload (provider, currentOverload, token); } - public override System.Threading.Tasks.Task<MonoDevelop.Ide.CodeCompletion.ICompletionDataList> HandleCodeCompletionAsync (MonoDevelop.Ide.CodeCompletion.CodeCompletionContext completionContext, char completionChar, System.Threading.CancellationToken token) + public override System.Threading.Tasks.Task<MonoDevelop.Ide.CodeCompletion.ICompletionDataList> HandleCodeCompletionAsync (MonoDevelop.Ide.CodeCompletion.CodeCompletionContext completionContext, CompletionTriggerInfo triggerInfo, System.Threading.CancellationToken token) { var projectedExtension = GetExtensionAt (completionContext.TriggerOffset); if (projectedExtension == null) return null; - return projectedExtension.HandleCodeCompletionAsync (ConvertContext (completionContext), completionChar, token); + return projectedExtension.HandleCodeCompletionAsync (ConvertContext (completionContext), triggerInfo, token); } public override Task<ParameterHintingResult> HandleParameterCompletionAsync (MonoDevelop.Ide.CodeCompletion.CodeCompletionContext completionContext, char completionChar, System.Threading.CancellationToken token) diff --git a/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Editor/Projection/ProjectedFilterCompletionTextEditorExtension.cs b/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Editor/Projection/ProjectedFilterCompletionTextEditorExtension.cs index 934be1340e..9ee715512b 100644 --- a/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Editor/Projection/ProjectedFilterCompletionTextEditorExtension.cs +++ b/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Editor/Projection/ProjectedFilterCompletionTextEditorExtension.cs @@ -26,6 +26,7 @@ using System; using System.Collections.Generic; using System.Threading.Tasks; +using MonoDevelop.Ide.CodeCompletion; using MonoDevelop.Ide.Editor.Extension; namespace MonoDevelop.Ide.Editor.Projection @@ -140,9 +141,9 @@ namespace MonoDevelop.Ide.Editor.Projection return completionTextEditorExtension.CanRunParameterCompletionCommand (); } - public override System.Threading.Tasks.Task<CodeCompletion.ICompletionDataList> HandleCodeCompletionAsync (CodeCompletion.CodeCompletionContext completionContext, char completionChar, System.Threading.CancellationToken token) + public override System.Threading.Tasks.Task<CodeCompletion.ICompletionDataList> HandleCodeCompletionAsync (CodeCompletion.CodeCompletionContext completionContext, CompletionTriggerInfo triggerInfo, System.Threading.CancellationToken token) { - return completionTextEditorExtension.HandleCodeCompletionAsync (completionContext, completionChar, token); + return completionTextEditorExtension.HandleCodeCompletionAsync (completionContext, triggerInfo, token); } public override System.Threading.Tasks.Task<CodeCompletion.ParameterHintingResult> HandleParameterCompletionAsync (CodeCompletion.CodeCompletionContext completionContext, char completionChar, System.Threading.CancellationToken token) @@ -171,12 +172,6 @@ namespace MonoDevelop.Ide.Editor.Projection return completionTextEditorExtension.ShowCodeTemplatesCommand (completionContext); } - public override Task<CodeCompletion.ICompletionDataList> CodeCompletionCommand (CodeCompletion.CodeCompletionContext completionContext) - { - if (!IsActiveExtension()) return null; - return completionTextEditorExtension.CodeCompletionCommand (completionContext); - } - public override Task<CodeCompletion.ParameterHintingResult> ParameterCompletionCommand (CodeCompletion.CodeCompletionContext completionContext) { if (!IsActiveExtension()) return null; diff --git a/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.csproj b/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.csproj index 68104c6046..dc975d269a 100644 --- a/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.csproj +++ b/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.csproj @@ -9209,6 +9209,8 @@ <Compile Include="MonoDevelop.Components\RoundedFrameBox.cs" /> <Compile Include="MonoDevelop.Ide.Editor.Highlighting\ScopeStack.cs" /> <Compile Include="MonoDevelop.Ide.Editor.Extension\HighlightUrlExtension.cs" /> + <Compile Include="MonoDevelop.Ide.CodeCompletion\CompletionTriggerInfo.cs" /> + <Compile Include="MonoDevelop.Ide.CodeCompletion\CompletionTriggerReason.cs" /> </ItemGroup> <ItemGroup> <None Include="Makefile.am" /> diff --git a/main/tests/MonoDevelop.CSharpBinding.Tests/Features/CodeCompletion/PortedRoslynTests/CompletionTestBase.cs b/main/tests/MonoDevelop.CSharpBinding.Tests/Features/CodeCompletion/PortedRoslynTests/CompletionTestBase.cs index 5d8514d555..5629da0f0e 100644 --- a/main/tests/MonoDevelop.CSharpBinding.Tests/Features/CodeCompletion/PortedRoslynTests/CompletionTestBase.cs +++ b/main/tests/MonoDevelop.CSharpBinding.Tests/Features/CodeCompletion/PortedRoslynTests/CompletionTestBase.cs @@ -24,13 +24,14 @@ // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN // THE SOFTWARE. -// Copyright (c) Microsoft. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. +// Copyright (c) Microsoft. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. using System; using NUnit.Framework; using ICSharpCode.NRefactory6.CSharp.Completion; using Microsoft.CodeAnalysis; using MonoDevelop.CSharp.Completion; +using MonoDevelop.Ide.CodeCompletion; namespace ICSharpCode.NRefactory6.CSharp.CodeCompletion.Roslyn { diff --git a/main/tests/UnitTests/MonoDevelop.Ide.Editor/TextEditorProjectionTests.cs b/main/tests/UnitTests/MonoDevelop.Ide.Editor/TextEditorProjectionTests.cs index 13d94b72d8..541817e0c8 100644 --- a/main/tests/UnitTests/MonoDevelop.Ide.Editor/TextEditorProjectionTests.cs +++ b/main/tests/UnitTests/MonoDevelop.Ide.Editor/TextEditorProjectionTests.cs @@ -189,7 +189,7 @@ namespace MonoDevelop.Ide.Editor Editor = editor; } - public override Task<ICompletionDataList> HandleCodeCompletionAsync (CodeCompletionContext completionContext, char completionChar, System.Threading.CancellationToken token) + public override Task<ICompletionDataList> HandleCodeCompletionAsync (CodeCompletionContext completionContext, CompletionTriggerInfo triggerInfo, System.Threading.CancellationToken token) { CompletionRun = true; var list = new CompletionDataList (); |