diff --git a/src/OmniSharp.Abstractions/Models/v1/AutoComplete/AutoCompleteResponse.cs b/src/OmniSharp.Abstractions/Models/v1/AutoComplete/AutoCompleteResponse.cs index 7195e7c747..1054978e10 100644 --- a/src/OmniSharp.Abstractions/Models/v1/AutoComplete/AutoCompleteResponse.cs +++ b/src/OmniSharp.Abstractions/Models/v1/AutoComplete/AutoCompleteResponse.cs @@ -17,6 +17,7 @@ public class AutoCompleteResponse public string ReturnType { get; set; } public string Snippet { get; set; } public string Kind { get; set; } + public bool IsSuggestionMode { get; set; } public override bool Equals(object other) { @@ -37,4 +38,4 @@ public override int GetHashCode() return hashCode; } } -} \ No newline at end of file +} diff --git a/src/OmniSharp.Roslyn.CSharp/Services/Intellisense/IntellisenseService.cs b/src/OmniSharp.Roslyn.CSharp/Services/Intellisense/IntellisenseService.cs index 71d534e5d8..aeb6ef5475 100644 --- a/src/OmniSharp.Roslyn.CSharp/Services/Intellisense/IntellisenseService.cs +++ b/src/OmniSharp.Roslyn.CSharp/Services/Intellisense/IntellisenseService.cs @@ -47,6 +47,8 @@ public async Task> Handle(AutoCompleteRequest var semanticModel = await document.GetSemanticModelAsync(); var recommendedSymbols = await Recommender.GetRecommendedSymbolsAtPositionAsync(semanticModel, position, _workspace); + var isSuggestionMode = completionList.SuggestionModeItem != null; + foreach (var item in completionList.Items) { var completionText = item.DisplayText; @@ -74,14 +76,14 @@ public async Task> Handle(AutoCompleteRequest { if (request.WantSnippet) { - foreach (var completion in MakeSnippetedResponses(request, symbol, completionText)) + foreach (var completion in MakeSnippetedResponses(request, symbol, completionText, isSuggestionMode)) { completions.Add(completion); } } else { - completions.Add(MakeAutoCompleteResponse(request, symbol, completionText)); + completions.Add(MakeAutoCompleteResponse(request, symbol, completionText, isSuggestionMode)); } } } @@ -99,7 +101,8 @@ public async Task> Handle(AutoCompleteRequest CompletionText = item.DisplayText, DisplayText = item.DisplayText, Snippet = item.DisplayText, - Kind = request.WantKind ? item.Tags.First() : null + Kind = request.WantKind ? item.Tags.First() : null, + IsSuggestionMode = isSuggestionMode }; completions.Add(response); @@ -117,53 +120,53 @@ public async Task> Handle(AutoCompleteRequest .ThenBy(c => c.CompletionText, StringComparer.OrdinalIgnoreCase); } - private IEnumerable MakeSnippetedResponses(AutoCompleteRequest request, ISymbol symbol, string completionText) + private IEnumerable MakeSnippetedResponses(AutoCompleteRequest request, ISymbol symbol, string completionText, bool isSuggestionMode) { switch (symbol) { case IMethodSymbol methodSymbol: - return MakeSnippetedResponses(request, methodSymbol, completionText); + return MakeSnippetedResponses(request, methodSymbol, completionText, isSuggestionMode); case INamedTypeSymbol typeSymbol: - return MakeSnippetedResponses(request, typeSymbol, completionText); + return MakeSnippetedResponses(request, typeSymbol, completionText, isSuggestionMode); default: - return new[] { MakeAutoCompleteResponse(request, symbol, completionText) }; + return new[] { MakeAutoCompleteResponse(request, symbol, completionText, isSuggestionMode) }; } } - private IEnumerable MakeSnippetedResponses(AutoCompleteRequest request, IMethodSymbol methodSymbol, string completionText) + private IEnumerable MakeSnippetedResponses(AutoCompleteRequest request, IMethodSymbol methodSymbol, string completionText, bool isSuggestionMode) { var completions = new List(); if (methodSymbol.Parameters.Any(p => p.IsOptional)) { - completions.Add(MakeAutoCompleteResponse(request, methodSymbol, completionText, includeOptionalParams: false)); + completions.Add(MakeAutoCompleteResponse(request, methodSymbol, completionText, isSuggestionMode, includeOptionalParams: false)); } - completions.Add(MakeAutoCompleteResponse(request, methodSymbol, completionText)); + completions.Add(MakeAutoCompleteResponse(request, methodSymbol, completionText, isSuggestionMode)); return completions; } - private IEnumerable MakeSnippetedResponses(AutoCompleteRequest request, INamedTypeSymbol typeSymbol, string completionText) + private IEnumerable MakeSnippetedResponses(AutoCompleteRequest request, INamedTypeSymbol typeSymbol, string completionText, bool isSuggestionMode) { var completions = new List { - MakeAutoCompleteResponse(request, typeSymbol, completionText) + MakeAutoCompleteResponse(request, typeSymbol, completionText, isSuggestionMode) }; if (typeSymbol.TypeKind != TypeKind.Enum) { foreach (var ctor in typeSymbol.InstanceConstructors) { - completions.Add(MakeAutoCompleteResponse(request, ctor, completionText)); + completions.Add(MakeAutoCompleteResponse(request, ctor, completionText, isSuggestionMode)); } } return completions; } - private AutoCompleteResponse MakeAutoCompleteResponse(AutoCompleteRequest request, ISymbol symbol, string completionText, bool includeOptionalParams = true) + private AutoCompleteResponse MakeAutoCompleteResponse(AutoCompleteRequest request, ISymbol symbol, string completionText, bool isSuggestionMode, bool includeOptionalParams = true) { var displayNameGenerator = new SnippetGenerator(); displayNameGenerator.IncludeMarkers = false; @@ -175,6 +178,8 @@ private AutoCompleteResponse MakeAutoCompleteResponse(AutoCompleteRequest reques // TODO: Do something more intelligent here response.DisplayText = displayNameGenerator.Generate(symbol); + response.IsSuggestionMode = isSuggestionMode; + if (request.WantDocumentationForEveryCompletionResult) { response.Description = DocumentationConverter.ConvertDocumentation(symbol.GetDocumentationCommentXml(), _formattingOptions.NewLine); diff --git a/tests/OmniSharp.Roslyn.CSharp.Tests/IntellisenseFacts.cs b/tests/OmniSharp.Roslyn.CSharp.Tests/IntellisenseFacts.cs index 216c54c040..e8e392fdf6 100644 --- a/tests/OmniSharp.Roslyn.CSharp.Tests/IntellisenseFacts.cs +++ b/tests/OmniSharp.Roslyn.CSharp.Tests/IntellisenseFacts.cs @@ -316,6 +316,102 @@ public async Task Returns_host_object_members_in_csx() ContainsCompletions(completions.Select(c => c.CompletionText), new[] { "Print", "PrintOptions" }); } + [Theory] + [InlineData("dummy.cs")] + [InlineData("dummy.csx")] + public async Task Is_suggestion_mode_true_for_lambda_expression_position1(string filename) + { + const string source = @" +using System; +class C +{ + int CallMe(int i) => 42; + + void M(Func a) { } + + void M() + { + M(c$$ + } +} +"; + + var completions = await FindCompletionsAsync(filename, source); + + Assert.True(completions.All(c => c.IsSuggestionMode)); + } + + [Theory] + [InlineData("dummy.cs")] + [InlineData("dummy.csx")] + public async Task Is_suggestion_mode_true_for_lambda_expression_position2(string filename) + { + const string source = @" +using System; +class C +{ + int CallMe(int i) => 42; + + void M() + { + Func a = c$$ + } +} +"; + + var completions = await FindCompletionsAsync(filename, source); + + Assert.True(completions.All(c => c.IsSuggestionMode)); + } + + [Theory] + [InlineData("dummy.cs")] + [InlineData("dummy.csx")] + public async Task Is_suggestion_mode_false_for_normal_position1(string filename) + { + const string source = @" +using System; +class C +{ + int CallMe(int i) => 42; + + void M(int a) { } + + void M() + { + M(c$$ + } +} +"; + + var completions = await FindCompletionsAsync(filename, source); + + Assert.True(completions.All(c => !c.IsSuggestionMode)); + } + + [Theory] + [InlineData("dummy.cs")] + [InlineData("dummy.csx")] + public async Task Is_suggestion_mode_false_for_normal_position2(string filename) + { + const string source = @" +using System; +class C +{ + int CallMe(int i) => 42; + + void M() + { + int a = c$$ + } +} +"; + + var completions = await FindCompletionsAsync(filename, source); + + Assert.True(completions.All(c => !c.IsSuggestionMode)); + } + private void ContainsCompletions(IEnumerable completions, params string[] expected) { if (!completions.SequenceEqual(expected))