From f4e5f1ed5bfb2d94ddb510471972a46edeee5a38 Mon Sep 17 00:00:00 2001 From: Anh-Dung Phan Date: Sat, 17 Dec 2016 11:53:39 +0100 Subject: [PATCH 1/3] Colorize F# signature help --- .../src/FSharp.Editor/CommonConstants.fs | 2 + .../FSharp.Editor/Completion/SignatureHelp.fs | 62 ++++++++++++++++--- .../src/FSharp.Editor/ContentType.fs | 5 ++ 3 files changed, 60 insertions(+), 9 deletions(-) diff --git a/vsintegration/src/FSharp.Editor/CommonConstants.fs b/vsintegration/src/FSharp.Editor/CommonConstants.fs index a9233ebbda9..8640bdca211 100644 --- a/vsintegration/src/FSharp.Editor/CommonConstants.fs +++ b/vsintegration/src/FSharp.Editor/CommonConstants.fs @@ -20,4 +20,6 @@ module internal FSharpCommonConstants = [] let FSharpContentTypeName = "F#" [] + let FSharpSignatureHelpContentTypeName = "F# Signature Help" + [] let FSharpLanguageServiceCallbackName = "F# Language Service" diff --git a/vsintegration/src/FSharp.Editor/Completion/SignatureHelp.fs b/vsintegration/src/FSharp.Editor/Completion/SignatureHelp.fs index 80505437348..ee1f9ec82c2 100644 --- a/vsintegration/src/FSharp.Editor/Completion/SignatureHelp.fs +++ b/vsintegration/src/FSharp.Editor/Completion/SignatureHelp.fs @@ -3,6 +3,7 @@ namespace Microsoft.VisualStudio.FSharp.Editor open System +open System.Text.RegularExpressions open System.Composition open System.Collections.Concurrent open System.Collections.Generic @@ -181,20 +182,49 @@ type internal FSharpSignatureHelpProvider let paramDoc = XmlDocumentation.BuildMethodParamText(documentationBuilder, method.XmlDoc, p.ParameterName) let doc = if String.IsNullOrWhiteSpace(paramDoc) then [||] else [| TaggedText(TextTags.Text, paramDoc) |] - yield (p.ParameterName,p.IsOptional,doc,[| TaggedText(TextTags.Text,p.Display) |]) |] + let parameterParts = + if isStaticArgTip then + [| TaggedText(TextTags.Class, p.Display) |] + else + let str = p.Display + match str.IndexOf(':') with + | -1 -> [| TaggedText(TextTags.Parameter, str) |] + | 0 -> + [| TaggedText(TextTags.Punctuation, ":"); + TaggedText(TextTags.Class, str.[1..]) |] + | i -> + [| TaggedText(TextTags.Parameter, str.[..i-1]); + TaggedText(TextTags.Punctuation, ":"); + TaggedText(TextTags.Class, str.[i+1..]) |] + yield (p.ParameterName, p.IsOptional, doc, parameterParts) + |] let hasParamComments (pcs: (string*bool*TaggedText[]*TaggedText[])[]) = pcs |> Array.exists (fun (_, _, doc, _) -> doc.Length > 0) - let summaryText = if String.IsNullOrWhiteSpace(summaryDoc) then [| TaggedText() |] - elif (hasParamComments parameters) then [| TaggedText(TextTags.Text, summaryDoc + "\n") |] - else [| TaggedText(TextTags.Text, summaryDoc) |] - + let summaryText = + let doc = + if String.IsNullOrWhiteSpace summaryDoc then + String.Empty + elif hasParamComments parameters then + summaryDoc + "\n" + else + summaryDoc + [| TaggedText(TextTags.Text, doc) |] + // Prepare the text to display - let descriptionParts = [| TaggedText(TextTags.Text, method.TypeText) |] - let prefixParts = [| TaggedText(TextTags.Text, methodGroup.MethodName); TaggedText(TextTags.Punctuation, (if isStaticArgTip then "<" else "(")) |] + let descriptionParts = + let str = method.TypeText + if str.StartsWith(": ", StringComparison.OrdinalIgnoreCase) then + [| TaggedText(TextTags.Punctuation, ": "); + TaggedText(TextTags.Class, str.[2..]) |] + else + [| TaggedText(TextTags.Text, str) |] + let prefixParts = + [| TaggedText(TextTags.Method, methodGroup.MethodName); + TaggedText(TextTags.Punctuation, (if isStaticArgTip then "<" else "(")) |] let separatorParts = [| TaggedText(TextTags.Punctuation, ", ") |] - let suffixParts = [| TaggedText(TextTags.Text, (if isStaticArgTip then ">" else ")")) |] + let suffixParts = [| TaggedText(TextTags.Punctuation, (if isStaticArgTip then ">" else ")")) |] let completionItem = (method.HasParamArrayArg, summaryText, prefixParts, separatorParts, suffixParts, parameters, descriptionParts) // FSROSLYNTODO: Do we need a cache like for completion? @@ -234,7 +264,7 @@ type internal FSharpSignatureHelpProvider let parameters = parameters |> Array.map (fun (paramName, isOptional, paramDoc, displayParts) -> SignatureHelpParameter(paramName,isOptional,documentationFactory=(fun _ -> paramDoc :> seq<_>),displayParts=displayParts)) - SignatureHelpItem(isVariadic=hasParamArrayArg ,documentationFactory=(fun _ -> doc :> seq<_>),prefixParts=prefixParts,separatorParts=separatorParts,suffixParts=suffixParts,parameters=parameters,descriptionParts=descriptionParts)) + AbstractSignatureHelpProvider.SymbolKeySignatureHelpItem(null, isVariadic=hasParamArrayArg ,documentationFactory=(fun _ -> doc :> seq<_>),prefixParts=prefixParts,separatorParts=separatorParts,suffixParts=suffixParts,parameters=parameters,descriptionParts=descriptionParts) :> SignatureHelpItem) return SignatureHelpItems(items,applicableSpan,argumentIndex,argumentCount,Option.toObj argumentName) | None -> @@ -244,3 +274,17 @@ type internal FSharpSignatureHelpProvider return null } |> CommonRoslynHelpers.StartAsyncAsTask cancellationToken +open System.ComponentModel.Composition +open Microsoft.VisualStudio.Utilities +open Microsoft.VisualStudio.Text +open Microsoft.VisualStudio.Text.Classification +open Microsoft.CodeAnalysis.Editor.Implementation.IntelliSense.SignatureHelp.Presentation + +// Enable colorized signature help for F# buffers + +[)>] +[] +type FSharpSignatureHelpClassifierProvider [] (typeMap) = + interface IClassifierProvider with + override __.GetClassifier (buffer: ITextBuffer) = + buffer.Properties.GetOrCreateSingletonProperty(fun _ -> SignatureHelpClassifier(buffer, typeMap) :> _) diff --git a/vsintegration/src/FSharp.Editor/ContentType.fs b/vsintegration/src/FSharp.Editor/ContentType.fs index 24b0b863398..04ecfc714e2 100644 --- a/vsintegration/src/FSharp.Editor/ContentType.fs +++ b/vsintegration/src/FSharp.Editor/ContentType.fs @@ -15,6 +15,11 @@ module FSharpStaticTypeDefinitions = [] let FSharpContentTypeDefinition = ContentTypeDefinition() + [] + [] + [] + let FSharpSignatureHelpContentTypeDefinition = ContentTypeDefinition() + [] type FSharpContentType [](contentTypeRegistry : IContentTypeRegistryService) = member this.contentTypeRegistryService = contentTypeRegistry From 61faeffd9cdcef5c662dc90f9f0b883396b6205d Mon Sep 17 00:00:00 2001 From: Anh-Dung Phan Date: Sat, 17 Dec 2016 11:57:41 +0100 Subject: [PATCH 2/3] Remove unnecessary symbol API --- .../src/FSharp.Editor/Completion/SignatureHelp.fs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/vsintegration/src/FSharp.Editor/Completion/SignatureHelp.fs b/vsintegration/src/FSharp.Editor/Completion/SignatureHelp.fs index ee1f9ec82c2..ed277fa6d4f 100644 --- a/vsintegration/src/FSharp.Editor/Completion/SignatureHelp.fs +++ b/vsintegration/src/FSharp.Editor/Completion/SignatureHelp.fs @@ -215,9 +215,9 @@ type internal FSharpSignatureHelpProvider // Prepare the text to display let descriptionParts = let str = method.TypeText - if str.StartsWith(": ", StringComparison.OrdinalIgnoreCase) then - [| TaggedText(TextTags.Punctuation, ": "); - TaggedText(TextTags.Class, str.[2..]) |] + if str.StartsWith(":", StringComparison.OrdinalIgnoreCase) then + [| TaggedText(TextTags.Punctuation, ":"); + TaggedText(TextTags.Class, str.[1..]) |] else [| TaggedText(TextTags.Text, str) |] let prefixParts = @@ -264,7 +264,7 @@ type internal FSharpSignatureHelpProvider let parameters = parameters |> Array.map (fun (paramName, isOptional, paramDoc, displayParts) -> SignatureHelpParameter(paramName,isOptional,documentationFactory=(fun _ -> paramDoc :> seq<_>),displayParts=displayParts)) - AbstractSignatureHelpProvider.SymbolKeySignatureHelpItem(null, isVariadic=hasParamArrayArg ,documentationFactory=(fun _ -> doc :> seq<_>),prefixParts=prefixParts,separatorParts=separatorParts,suffixParts=suffixParts,parameters=parameters,descriptionParts=descriptionParts) :> SignatureHelpItem) + SignatureHelpItem(isVariadic=hasParamArrayArg ,documentationFactory=(fun _ -> doc :> seq<_>),prefixParts=prefixParts,separatorParts=separatorParts,suffixParts=suffixParts,parameters=parameters,descriptionParts=descriptionParts)) return SignatureHelpItems(items,applicableSpan,argumentIndex,argumentCount,Option.toObj argumentName) | None -> From 5c8041a43f920967a3c05f6ce1813aa5d2b25a08 Mon Sep 17 00:00:00 2001 From: Anh-Dung Phan Date: Sat, 17 Dec 2016 16:49:00 +0100 Subject: [PATCH 3/3] Fix assembly references --- vsintegration/tests/unittests/VisualFSharp.Unittests.fsproj | 3 +++ 1 file changed, 3 insertions(+) diff --git a/vsintegration/tests/unittests/VisualFSharp.Unittests.fsproj b/vsintegration/tests/unittests/VisualFSharp.Unittests.fsproj index 983f38c3319..6f59277cbb1 100644 --- a/vsintegration/tests/unittests/VisualFSharp.Unittests.fsproj +++ b/vsintegration/tests/unittests/VisualFSharp.Unittests.fsproj @@ -164,6 +164,9 @@ + + $(FSharpSourcesRoot)\..\packages\Microsoft.VisualStudio.Text.Logic.$(RoslynVSPackagesVersion)\lib\net45\Microsoft.VisualStudio.Text.Logic.dll + $(FSharpSourcesRoot)\..\packages\Microsoft.VisualStudio.Threading.14.1.131\lib\net45\Microsoft.VisualStudio.Threading.dll True