diff --git a/docs/release-notes/.VisualStudio/18.vNext.md b/docs/release-notes/.VisualStudio/18.vNext.md index 8e59087813c..a7a62a728f8 100644 --- a/docs/release-notes/.VisualStudio/18.vNext.md +++ b/docs/release-notes/.VisualStudio/18.vNext.md @@ -4,6 +4,7 @@ * Fixed Find All References crash when F# project contains non-F# files like `.cshtml`. ([Issue #16394](https://github.com/dotnet/fsharp/issues/16394), [PR #19252](https://github.com/dotnet/fsharp/pull/19252)) * Find All References for external DLL symbols now only searches projects that reference the specific assembly. ([Issue #10227](https://github.com/dotnet/fsharp/issues/10227), [PR #19252](https://github.com/dotnet/fsharp/pull/19252)) * Improve static compilation of state machines. ([PR #19297](https://github.com/dotnet/fsharp/pull/19297)) +* Make Alt+F1 (momentary toggle) work for inlay hints. ([PR #19421](https://github.com/dotnet/fsharp/pull/19421)) ### Changed diff --git a/vsintegration/src/FSharp.Editor/Hints/FSharpInlayHintsService.fs b/vsintegration/src/FSharp.Editor/Hints/FSharpInlayHintsService.fs index 678e903ff99..85ac8ef6edc 100644 --- a/vsintegration/src/FSharp.Editor/Hints/FSharpInlayHintsService.fs +++ b/vsintegration/src/FSharp.Editor/Hints/FSharpInlayHintsService.fs @@ -4,25 +4,28 @@ namespace Microsoft.VisualStudio.FSharp.Editor.Hints open System.Collections.Immutable open System.ComponentModel.Composition +open System.Threading.Tasks open Microsoft.CodeAnalysis.ExternalAccess.FSharp.InlineHints open Microsoft.VisualStudio.FSharp.Editor -open Microsoft.VisualStudio.FSharp.Editor.Telemetry open CancellableTasks -open System.Threading.Tasks // So the Roslyn interface is called IFSharpInlineHintsService // but our implementation is called just HintsService. // That's because we'll likely use this API for things other than inlay hints, // e.g. signature hints above the line, pipeline hints on the side and so on. -[)>] +[)>] type internal FSharpInlayHintsService [] (settings: EditorOptions) = static let userOpName = "Hints" - interface IFSharpInlineHintsService with - member _.GetInlineHintsAsync(document, _, cancellationToken) = - let hintKinds = OptionParser.getHintKinds settings.Advanced + interface IFSharpInlineHintsService2 with + member _.GetInlineHintsAsync(document, textSpan, displayAllOverride, cancellationToken) = + let hintKinds = + if displayAllOverride then + Hints.allHintKinds + else + OptionParser.getHintKinds settings.Advanced if hintKinds.IsEmpty then Task.FromResult ImmutableArray.Empty @@ -31,14 +34,13 @@ type internal FSharpInlayHintsService [] (settings: Editor let! cancellationToken = CancellableTask.getCancellationToken () let! sourceText = document.GetTextAsync cancellationToken - let! nativeHints = HintService.getHintsForDocument sourceText document hintKinds userOpName + let! nativeHints = HintService.getHintsForDocument sourceText document hintKinds textSpan userOpName - let tasks = + let roslynHints = nativeHints - |> Seq.map (fun hint -> NativeToRoslynHintConverter.convert sourceText hint cancellationToken) - - let! roslynHints = Task.WhenAll(tasks) + |> Seq.map (NativeToRoslynHintConverter.convert sourceText) + |> ImmutableArray.CreateRange - return roslynHints.ToImmutableArray() + return roslynHints } |> CancellableTask.start cancellationToken diff --git a/vsintegration/src/FSharp.Editor/Hints/HintService.fs b/vsintegration/src/FSharp.Editor/Hints/HintService.fs index 34871bcbb66..c09dc07aebd 100644 --- a/vsintegration/src/FSharp.Editor/Hints/HintService.fs +++ b/vsintegration/src/FSharp.Editor/Hints/HintService.fs @@ -39,7 +39,7 @@ module HintService = let hints = getHints sourceText parseResults hintKinds symbolUses symbol Seq.concat hints - let getHintsForDocument sourceText (document: Document) hintKinds userOpName = + let getHintsForDocument (sourceText: SourceText) (document: Document) hintKinds (textSpan: TextSpan) userOpName = cancellableTask { if isSignatureFile document.FilePath then return List.empty @@ -75,3 +75,8 @@ module HintService = return nativeHints } + |> CancellableTask.map ( + List.filter (fun hint -> + let hintSpan = RoslynHelpers.FSharpRangeToTextSpan(sourceText, hint.Range) + textSpan.IntersectsWith hintSpan) + ) diff --git a/vsintegration/src/FSharp.Editor/Hints/Hints.fs b/vsintegration/src/FSharp.Editor/Hints/Hints.fs index 0dd7fbff263..ca4fb7ee8c5 100644 --- a/vsintegration/src/FSharp.Editor/Hints/Hints.fs +++ b/vsintegration/src/FSharp.Editor/Hints/Hints.fs @@ -14,6 +14,9 @@ module Hints = | ParameterNameHint | ReturnTypeHint + let allHintKinds = + Set [ HintKind.TypeHint; HintKind.ParameterNameHint; HintKind.ReturnTypeHint ] + // Relatively convenient for testing type NativeHint = { diff --git a/vsintegration/src/FSharp.Editor/Hints/NativeToRoslynHintConverter.fs b/vsintegration/src/FSharp.Editor/Hints/NativeToRoslynHintConverter.fs index 61442b6b547..7e3e33b3e02 100644 --- a/vsintegration/src/FSharp.Editor/Hints/NativeToRoslynHintConverter.fs +++ b/vsintegration/src/FSharp.Editor/Hints/NativeToRoslynHintConverter.fs @@ -33,9 +33,7 @@ module NativeToRoslynHintConverter = } |> CancellableTask.start ct - cancellableTask { - let span = rangeToSpan hint.Range sourceText - let displayParts = hint.Parts |> Seq.map nativeToRoslynText + let span = rangeToSpan hint.Range sourceText + let displayParts = hint.Parts |> Seq.map nativeToRoslynText - return FSharpInlineHint(span, displayParts.ToImmutableArray(), getDescriptionAsync) - } + FSharpInlineHint(span, displayParts.ToImmutableArray(), getDescriptionAsync) diff --git a/vsintegration/tests/FSharp.Editor.Tests/Hints/HintTestFramework.fs b/vsintegration/tests/FSharp.Editor.Tests/Hints/HintTestFramework.fs index df6d3c73c0c..def34bfc516 100644 --- a/vsintegration/tests/FSharp.Editor.Tests/Hints/HintTestFramework.fs +++ b/vsintegration/tests/FSharp.Editor.Tests/Hints/HintTestFramework.fs @@ -3,6 +3,7 @@ namespace FSharp.Editor.Tests.Hints open Microsoft.CodeAnalysis +open Microsoft.CodeAnalysis.Text open Microsoft.VisualStudio.FSharp.Editor open Microsoft.VisualStudio.FSharp.Editor.Hints open Hints @@ -47,7 +48,8 @@ module HintTestFramework = } let! sourceText = document.GetTextAsync ct |> Async.AwaitTask - let! hints = HintService.getHintsForDocument sourceText document hintKinds "test" ct + let textSpan = TextSpan(0, sourceText.Length) + let! hints = HintService.getHintsForDocument sourceText document hintKinds textSpan "test" ct let! tooltips = hints |> Seq.map getTooltip |> Async.Parallel return tooltips |> Seq.zip hints |> Seq.map convert }