From 30b3a8fa53bf48da2b79492cddd98b4d219336a3 Mon Sep 17 00:00:00 2001 From: Petr Date: Tue, 4 Oct 2022 12:36:32 +0200 Subject: [PATCH] First steps towards reviving CodeLens --- .../CodeLens/CodeLensProvider.fs | 79 +++++++++---------- .../CodeLens/FSharpCodeLensService.fs | 4 +- 2 files changed, 41 insertions(+), 42 deletions(-) diff --git a/vsintegration/src/FSharp.Editor/CodeLens/CodeLensProvider.fs b/vsintegration/src/FSharp.Editor/CodeLens/CodeLensProvider.fs index 8d3be2fcf..7c015abad 100644 --- a/vsintegration/src/FSharp.Editor/CodeLens/CodeLensProvider.fs +++ b/vsintegration/src/FSharp.Editor/CodeLens/CodeLensProvider.fs @@ -28,51 +28,43 @@ type internal CodeLensProvider settings: EditorOptions ) = - let lineLensProvider = ResizeArray() + let tryGetTextDocument (buffer: ITextBuffer) (factory: ITextDocumentFactoryService) = + match factory.TryGetTextDocument buffer with + | true, document -> Some document + | _ -> None + let taggers = ResizeArray() + let lineLensProviders = ResizeArray() let componentModel = Package.GetGlobalService(typeof) :?> ComponentModelHost.IComponentModel let workspace = componentModel.GetService() - /// Returns an provider for the textView if already one has been created. Else create one. - let addCodeLensProviderOnce wpfView buffer = - let res = taggers |> Seq.tryFind(fun (view, _) -> view = wpfView) - match res with - | Some (_, (tagger, _)) -> tagger - | None -> - let documentId = - lazy ( - match textDocumentFactory.TryGetTextDocument(buffer) with - | true, textDocument -> - Seq.tryHead (workspace.CurrentSolution.GetDocumentIdsWithFilePath(textDocument.FilePath)) - | _ -> None - |> Option.get - ) - - let tagger = CodeLensGeneralTagger(wpfView, buffer) - let service = FSharpCodeLensService(serviceProvider, workspace, documentId, buffer, metadataAsSource, componentModel.GetService(), typeMap, tagger, settings) - let provider = (wpfView, (tagger, service)) - wpfView.Closed.Add (fun _ -> taggers.Remove provider |> ignore) - taggers.Add((wpfView, (tagger, service))) - tagger + let tryGetCodeLensTagger wpfView buffer = + taggers + |> Seq.tryFind (fun (view, _) -> view = wpfView) + |> Option.map (fun (_, (tagger, _)) -> tagger) + |> Option.orElse + (textDocumentFactory + |> tryGetTextDocument buffer + |> Option.map (fun document -> workspace.CurrentSolution.GetDocumentIdsWithFilePath document.FilePath) + |> Option.bind Seq.tryHead + |> Option.map (fun documentId -> + let tagger = CodeLensGeneralTagger(wpfView, buffer) + let service = FSharpCodeLensService(serviceProvider, workspace, documentId, buffer, metadataAsSource, componentModel.GetService(), typeMap, tagger, settings) + let provider = (wpfView, (tagger, service)) + wpfView.Closed.Add (fun _ -> taggers.Remove provider |> ignore) + taggers.Add provider + tagger)) - /// Returns an provider for the textView if already one has been created. Else create one. - let addLineLensProviderOnce wpfView buffer = - let res = lineLensProvider |> Seq.tryFind(fun (view, _) -> view = wpfView) - match res with - | None -> - let documentId = - lazy ( - match textDocumentFactory.TryGetTextDocument(buffer) with - | true, textDocument -> - Seq.tryHead (workspace.CurrentSolution.GetDocumentIdsWithFilePath(textDocument.FilePath)) - | _ -> None - |> Option.get - ) + let addLineLensProvider wpfView buffer = + textDocumentFactory + |> tryGetTextDocument buffer + |> Option.map (fun document -> workspace.CurrentSolution.GetDocumentIdsWithFilePath(document.FilePath)) + |> Option.bind Seq.tryHead + |> Option.map (fun documentId -> let service = FSharpCodeLensService(serviceProvider, workspace, documentId, buffer, metadataAsSource, componentModel.GetService(), typeMap, LineLensDisplayService(wpfView, buffer), settings) let provider = (wpfView, service) - wpfView.Closed.Add (fun _ -> lineLensProvider.Remove provider |> ignore) - lineLensProvider.Add(provider) - | _ -> () + wpfView.Closed.Add (fun _ -> lineLensProviders.Remove provider |> ignore) + lineLensProviders.Add(provider)) [); Name("CodeLens"); Order(Before = PredefinedAdornmentLayers.Text); @@ -92,11 +84,18 @@ type internal CodeLensProvider | :? IWpfTextView as view -> view | _ -> failwith "error" - box(addCodeLensProviderOnce wpfView buffer) :?> _ + match tryGetCodeLensTagger wpfView buffer with + | Some tagger -> box tagger :?> _ + | None -> null else null interface IWpfTextViewCreationListener with override _.TextViewCreated view = if settings.CodeLens.Enabled && settings.CodeLens.ReplaceWithLineLens then - addLineLensProviderOnce view (view.TextBuffer) |> ignore \ No newline at end of file + let provider = + lineLensProviders + |> Seq.tryFind (fun (v, _) -> v = view) + + if provider.IsNone then + addLineLensProvider view (view.TextBuffer) |> ignore \ No newline at end of file diff --git a/vsintegration/src/FSharp.Editor/CodeLens/FSharpCodeLensService.fs b/vsintegration/src/FSharp.Editor/CodeLens/FSharpCodeLensService.fs index 2e18270e9..01360f29e 100644 --- a/vsintegration/src/FSharp.Editor/CodeLens/FSharpCodeLensService.fs +++ b/vsintegration/src/FSharp.Editor/CodeLens/FSharpCodeLensService.fs @@ -42,7 +42,7 @@ type internal FSharpCodeLensService ( serviceProvider: IServiceProvider, workspace: Workspace, - documentId: Lazy, + documentId: DocumentId, buffer: ITextBuffer, metadataAsSource: FSharpMetadataAsSourceService, classificationFormatMapService: IClassificationFormatMapService, @@ -153,7 +153,7 @@ type internal FSharpCodeLensService #if DEBUG logInfof "Rechecking code due to buffer edit!" #endif - let! document = workspace.CurrentSolution.GetDocument(documentId.Value) |> Option.ofObj + let! document = workspace.CurrentSolution.GetDocument documentId |> Option.ofObj let! parseFileResults, checkFileResults = document.GetFSharpParseAndCheckResultsAsync(nameof(FSharpUseMutationWhenValueIsMutableFixProvider)) |> liftAsync let parsedInput = parseFileResults.ParseTree #if DEBUG -- GitLab