Skip to content

Commit 8b8328d

Browse files
committed
fix output pane
1 parent 05822f0 commit 8b8328d

File tree

3 files changed

+58
-76
lines changed

3 files changed

+58
-76
lines changed

vsintegration/src/FSharp.Editor/Common/Logging.fs renamed to vsintegration/src/FSharp.Editor/Common/DebugHelpers.fs

Lines changed: 40 additions & 68 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,9 @@
1-
namespace Microsoft.VisualStudio.FSharp.Editor.Logging
1+
namespace Microsoft.VisualStudio.FSharp.Editor.DebugHelpers
22

33
open System
44
open System.Diagnostics
5-
open System.ComponentModel.Composition
65
open Microsoft.VisualStudio.Shell
76
open Microsoft.VisualStudio.Shell.Interop
8-
open Microsoft.VisualStudio.FSharp.Editor
97

108
open FSharp.Compiler.Diagnostics
119

@@ -32,75 +30,49 @@ module Config =
3230
open Config
3331
open System.Diagnostics.Metrics
3432
open System.Text
33+
open Microsoft.VisualStudio.Threading
3534

36-
[<Export>]
37-
type Logger [<ImportingConstructor>] ([<Import(typeof<SVsServiceProvider>)>] serviceProvider: IServiceProvider) =
38-
let outputWindow =
39-
serviceProvider.GetService<SVsOutputWindow, IVsOutputWindow>() |> Option.ofObj
40-
41-
let createPane () =
42-
outputWindow
43-
|> Option.iter (fun x ->
44-
x.CreatePane(ref fsharpOutputGuid, "F# Language Service", Convert.ToInt32 true, Convert.ToInt32 false)
45-
|> ignore)
46-
47-
do createPane ()
48-
49-
let getPane () =
50-
match outputWindow |> Option.map (fun x -> x.GetPane(ref fsharpOutputGuid)) with
51-
| Some(0, pane) ->
52-
pane.Activate() |> ignore
53-
Some pane
54-
| _ -> None
55-
56-
static let mutable globalServiceProvider: IServiceProvider option = None
57-
58-
static member GlobalServiceProvider
59-
with get () =
60-
globalServiceProvider
61-
|> Option.defaultValue (ServiceProvider.GlobalProvider :> IServiceProvider)
62-
and set v = globalServiceProvider <- Some v
63-
64-
member _.FSharpLoggingPane =
65-
getPane ()
66-
|> function
67-
| Some pane -> Some pane
68-
| None ->
69-
createPane ()
70-
getPane ()
71-
72-
member self.Log(msgType: LogType, msg: string) =
73-
let time = DateTime.Now.ToString("hh:mm:ss tt")
74-
75-
match self.FSharpLoggingPane, msgType with
76-
| None, _ -> ()
77-
| Some pane, LogType.Message ->
78-
String.Format("[{0}{1}] {2}{3}", "", time, msg, Environment.NewLine)
79-
|> pane.OutputString
80-
|> ignore
81-
| Some pane, LogType.Info ->
82-
String.Format("[{0}{1}] {2}{3}", "INFO ", time, msg, Environment.NewLine)
83-
|> pane.OutputString
84-
|> ignore
85-
| Some pane, LogType.Warn ->
86-
String.Format("[{0}{1}] {2}{3}", "WARN ", time, msg, Environment.NewLine)
87-
|> pane.OutputString
88-
|> ignore
89-
| Some pane, LogType.Error ->
90-
String.Format("[{0}{1}] {2}{3}", "ERROR ", time, msg, Environment.NewLine)
91-
|> pane.OutputString
92-
|> ignore
93-
94-
[<AutoOpen>]
95-
module Logging =
35+
module FSharpOutputPane =
9636

97-
let inline debug msg = Printf.kprintf Debug.WriteLine msg
37+
let private pane = AsyncLazy(fun () -> task {
38+
do! ThreadHelper.JoinableTaskFactory.SwitchToMainThreadAsync()
39+
let! window = AsyncServiceProvider.GlobalProvider.GetServiceAsync<SVsOutputWindow, IVsOutputWindow>()
40+
window.CreatePane(ref fsharpOutputGuid, "F# Language Service", Convert.ToInt32 true, Convert.ToInt32 false) |> ignore
41+
match window.GetPane(ref fsharpOutputGuid) with
42+
| 0, pane -> return pane
43+
| _ -> return failwith "Could not get F# output pane"
44+
}, ThreadHelper.JoinableTaskFactory)
9845

99-
let private logger = lazy Logger(Logger.GlobalServiceProvider)
46+
let inline debug msg = Printf.kprintf Debug.WriteLine msg
10047

10148
let private log logType msg =
102-
logger.Value.Log(logType, msg)
103-
System.Diagnostics.Trace.TraceInformation(msg)
49+
task {
50+
System.Diagnostics.Trace.TraceInformation(msg)
51+
let time = DateTime.Now.ToString("hh:mm:ss tt")
52+
53+
let! pane = pane.GetValueAsync()
54+
55+
do! ThreadHelper.JoinableTaskFactory.SwitchToMainThreadAsync()
56+
57+
match logType with
58+
| LogType.Message ->
59+
String.Format("[{0}{1}] {2}{3}", "", time, msg, Environment.NewLine)
60+
|> pane.OutputStringThreadSafe
61+
|> ignore
62+
| LogType.Info ->
63+
String.Format("[{0}{1}] {2}{3}", "INFO ", time, msg, Environment.NewLine)
64+
|> pane.OutputStringThreadSafe
65+
|> ignore
66+
| LogType.Warn ->
67+
String.Format("[{0}{1}] {2}{3}", "WARN ", time, msg, Environment.NewLine)
68+
|> pane.OutputStringThreadSafe
69+
|> ignore
70+
| LogType.Error ->
71+
String.Format("[{0}{1}] {2}{3}", "ERROR ", time, msg, Environment.NewLine)
72+
|> pane.OutputStringThreadSafe
73+
|> ignore
74+
}
75+
|> ignore
10476

10577
let logMsg msg = log LogType.Message msg
10678
let logInfo msg = log LogType.Info msg
@@ -145,7 +117,7 @@ module FSharpServiceTelemetry =
145117
ActivitySamplingResult.AllData
146118
else
147119
ActivitySamplingResult.None),
148-
ActivityStarted = (fun a -> logMsg $"{indent a}{a.OperationName} {collectTags a}")
120+
ActivityStarted = (fun a -> FSharpOutputPane.logMsg $"{indent a}{a.OperationName} {collectTags a}")
149121
)
150122

151123
ActivitySource.AddActivityListener(listener)

vsintegration/src/FSharp.Editor/FSharp.Editor.fsproj

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@
3838
<Compile Include="Common\Constants.fs" />
3939
<Compile Include="Common\Extensions.fs" />
4040
<Compile Include="Common\Error.fs" />
41-
<Compile Include="Common\Logging.fs" />
41+
<Compile Include="Common\DebugHelpers.fs" />
4242
<Compile Include="Common\RoslynHelpers.fs" />
4343
<Compile Include="Common\FSharpCodeAnalysisExtensions.fs" />
4444
<Compile Include="Common\CodeAnalysisExtensions.fs" />

vsintegration/src/FSharp.Editor/LanguageService/LanguageService.fs

Lines changed: 17 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -322,7 +322,8 @@ type internal FSharpPackage() as this =
322322
do FSharp.Interactive.Hooks.fsiConsoleWindowPackageCtorUnsited (this :> Package)
323323

324324
#if DEBUG
325-
let flushTelemetry = Logging.FSharpServiceTelemetry.otelExport ()
325+
let flushTelemetry = DebugHelpers.FSharpServiceTelemetry.otelExport ()
326+
do DebugHelpers.FSharpServiceTelemetry.listenToAll()
326327

327328
override this.Dispose(disposing: bool) =
328329
base.Dispose(disposing: bool)
@@ -335,19 +336,25 @@ type internal FSharpPackage() as this =
335336
base.RegisterInitializeAsyncWork(packageRegistrationTasks)
336337

337338
packageRegistrationTasks.AddTask(
338-
false,
339+
true,
339340
(fun _tasks cancellationToken ->
340-
cancellableTask {
341+
foregroundCancellableTask {
342+
// FSI-LINKAGE-POINT: private method GetDialogPage forces fsi options to be loaded
343+
this.GetDialogPage(typeof<FSharp.Interactive.FsiPropertyPage>) |> ignore
344+
341345
let! commandService = this.GetServiceAsync(typeof<IMenuCommandService>)
342346
let commandService = commandService :?> OleMenuCommandService
343347

344348
// FSI-LINKAGE-POINT: sited init
345349
FSharp.Interactive.Hooks.fsiConsoleWindowPackageInitializeSited (this :> Package) commandService
350+
}
351+
|> CancellableTask.startAsTask cancellationToken)
352+
)
346353

347-
// FSI-LINKAGE-POINT: private method GetDialogPage forces fsi options to be loaded
348-
let _fsiPropertyPage =
349-
this.GetDialogPage(typeof<FSharp.Interactive.FsiPropertyPage>)
350-
354+
packageRegistrationTasks.AddTask(
355+
false,
356+
(fun _tasks cancellationToken ->
357+
cancellableTask {
351358
let workspace =
352359
this.ComponentModel.DefaultExportProvider.GetExportedValue<VisualStudioWorkspace>()
353360

@@ -372,6 +379,9 @@ type internal FSharpPackage() as this =
372379
let projectContextFactory =
373380
this.ComponentModel.GetService<FSharpWorkspaceProjectContextFactory>()
374381

382+
let _ =
383+
this.ComponentModel.DefaultExportProvider.GetExport<HackCpsCommandLineChanges>()
384+
375385
let miscFilesWorkspace =
376386
this.ComponentModel.GetService<MiscellaneousFilesWorkspace>()
377387

0 commit comments

Comments
 (0)