From a55c3c8df778d0ccd6037665931efb7c040cc30e Mon Sep 17 00:00:00 2001 From: KevinRansom Date: Wed, 23 Nov 2022 10:45:33 -0800 Subject: [PATCH 1/3] prompt --- VisualFSharp.sln | 2 +- src/Compiler/Interactive/fsi.fs | 42 ++++++++++++++++--- src/Compiler/Service/ServiceLexing.fs | 1 + .../src/FSharp.VS.FSI/fsiSessionToolWindow.fs | 25 ++++++----- 4 files changed, 51 insertions(+), 19 deletions(-) diff --git a/VisualFSharp.sln b/VisualFSharp.sln index c9bb5ddc22..821fb3e510 100644 --- a/VisualFSharp.sln +++ b/VisualFSharp.sln @@ -193,7 +193,7 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "FCSBenchmarks", "FCSBenchma EndProject Project("{6EC3EE1D-3C4E-46DD-8F32-0CC8E7565705}") = "Fsharp.ProfilingStartpointProject", "tests\benchmarks\Fsharp.ProfilingStartpointProject\Fsharp.ProfilingStartpointProject.fsproj", "{FE23BB65-276A-4E41-8CC7-F7752241DEBA}" EndProject -Project("{F2A71F9B-5D33-465A-A702-920D77279786}") = "FSharp.Editor.Tests", "vsintegration\tests\FSharp.Editor.Tests\FSharp.Editor.Tests.fsproj", "{CBC96CC7-65AB-46EA-A82E-F6A788DABF80}" +Project("{6EC3EE1D-3C4E-46DD-8F32-0CC8E7565705}") = "FSharp.Editor.Tests", "vsintegration\tests\FSharp.Editor.Tests\FSharp.Editor.Tests.fsproj", "{CBC96CC7-65AB-46EA-A82E-F6A788DABF80}" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution diff --git a/src/Compiler/Interactive/fsi.fs b/src/Compiler/Interactive/fsi.fs index 5660f844d7..93880dd773 100644 --- a/src/Compiler/Interactive/fsi.fs +++ b/src/Compiler/Interactive/fsi.fs @@ -1127,15 +1127,38 @@ type internal FsiConsolePrompt(fsiOptions: FsiCommandLineOptions, fsiConsoleOutp // A prompt gets "printed ahead" at start up. Tells users to start type while initialisation completes. // A prompt can be skipped by "silent directives", e.g. ones sent to FSI by VS. let mutable dropPrompt = 0 + let mutable showPrompt = true + // NOTE: SERVER-PROMPT is not user displayed, rather it's a prefix that code elsewhere // uses to identify the prompt, see service\FsPkgs\FSharp.VS.FSI\fsiSessionToolWindow.fs - let prompt = if fsiOptions.UseServerPrompt then "SERVER-PROMPT>\n" else "> " - member _.Print() = if dropPrompt = 0 then fsiConsoleOutput.uprintf "%s" prompt else dropPrompt <- dropPrompt - 1 + let prompt = + if fsiOptions.UseServerPrompt then + "SERVER-PROMPT>" + Environment.NewLine + else + "> " + + member _.Print() = + if showPrompt then + if dropPrompt = 0 then + fsiConsoleOutput.uprintf "%s" prompt + else + dropPrompt <- dropPrompt - 1 + + member _.PrintAhead() = + if showPrompt then + dropPrompt <- dropPrompt + 1 + fsiConsoleOutput.uprintf "%s" prompt - member _.PrintAhead() = dropPrompt <- dropPrompt + 1; fsiConsoleOutput.uprintf "%s" prompt + // Can be turned off when executing blocks of code using: + // # silentPrompt + member _.ShowPrompt + with get () = showPrompt + and set (value) = showPrompt <- value - member _.SkipNext() = dropPrompt <- dropPrompt + 1 + member _.SkipNext() = + if showPrompt then + dropPrompt <- dropPrompt + 1 member _.FsiOptions = fsiOptions @@ -2772,6 +2795,15 @@ type FsiInteractionProcessor fsiConsolePrompt.SkipNext() (* "silent" directive *) istate, Completed None + | ParsedHashDirective("interactiveprompt", ParsedHashDirectiveArguments ["show" | "hide" | "skip" as showPrompt], m) -> + match showPrompt with + | "show" -> fsiConsolePrompt.ShowPrompt <- true + | "hide" -> fsiConsolePrompt.ShowPrompt <- false + | "skip" -> fsiConsolePrompt.SkipNext() + | _ -> error(Error((FSComp.SR.fsiInvalidDirective("prompt", String.concat " " [showPrompt])), m)) + + istate, Completed None + | ParsedHashDirective("dbgbreak", [], _) -> let istate = {istate with debugBreak = true} istate, Completed None @@ -3072,7 +3104,7 @@ type FsiInteractionProcessor // After we've unblocked and got something to run we switch // over to the run-thread (e.g. the GUI thread) - let res = istate |> runCodeOnMainThread (fun ctok istate -> ExecuteParsedInteractionOnMainThread (ctok, diagnosticsLogger, action, istate, cancellationToken)) + let res = istate |> runCodeOnMainThread (fun ctok istate ->ExecuteParsedInteractionOnMainThread (ctok, diagnosticsLogger, action, istate, cancellationToken)) if progress then fprintfn fsiConsoleOutput.Out "Just called runCodeOnMainThread, res = %O..." res res) diff --git a/src/Compiler/Service/ServiceLexing.fs b/src/Compiler/Service/ServiceLexing.fs index a772cd707a..c39546e975 100644 --- a/src/Compiler/Service/ServiceLexing.fs +++ b/src/Compiler/Service/ServiceLexing.fs @@ -1126,6 +1126,7 @@ type FSharpLineTokenizer(lexbuf: UnicodeLexing.Lexbuf, maxLength: int option, fi | true, "savedll" | true, "nosavedll" #endif + | true, "interactiveprompt" | true, "silentCd" | true, "q" | true, "quit" diff --git a/vsintegration/src/FSharp.VS.FSI/fsiSessionToolWindow.fs b/vsintegration/src/FSharp.VS.FSI/fsiSessionToolWindow.fs index b4a7397b86..9d807178d9 100644 --- a/vsintegration/src/FSharp.VS.FSI/fsiSessionToolWindow.fs +++ b/vsintegration/src/FSharp.VS.FSI/fsiSessionToolWindow.fs @@ -534,17 +534,16 @@ type internal FsiToolWindow() as this = executeTextNoHistory null text with _ -> () - let executeInteraction dbgBreak dir (filename: string) topLine text = - // Preserving previous functionality, including the #directives... - let interaction = - "\n" - + (sprintf "# silentCd @\"%s\" ;; " dir) + "\n" - + (if dbgBreak then "# dbgbreak\n" else "") - + (sprintf "# %d @\"%s\" " topLine filename) + "\n" - + text + "\n" - + "# 1 \"stdin\"" + "\n" (* stdin line number reset code *) - + ";;" + "\n" - + let executeInteraction dbgBreak dir filename topLine (text:string) = + let interaction = $""" +#interactiveprompt "hide" +#silentCd @"{dir}";; +{if dbgBreak then "#dbgbreak" else ""} +#{topLine} @"{filename}" +{text.ToString()};; +#1 "stdin" +#interactiveprompt "show";; +""" executeTextNoHistory filename interaction let sendSelectionToFSI action = @@ -555,8 +554,8 @@ type internal FsiToolWindow() as this = | DebugSelection -> true, false try - let dte = provider.GetService(typeof) :?> DTE - let activeD = dte.ActiveDocument + let dte = provider.GetService(typeof) :?> DTE + let activeD = dte.ActiveDocument match activeD.Selection with | :? TextSelection as selection when selectLine || selection.Text = "" -> selection.SelectLine() From 5acccd835f9cee69bc509ef0423ca2964844da9f Mon Sep 17 00:00:00 2001 From: KevinRansom Date: Sat, 26 Nov 2022 18:20:06 -0800 Subject: [PATCH 2/3] remove quotes --- vsintegration/src/FSharp.VS.FSI/fsiSessionToolWindow.fs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/vsintegration/src/FSharp.VS.FSI/fsiSessionToolWindow.fs b/vsintegration/src/FSharp.VS.FSI/fsiSessionToolWindow.fs index 9d807178d9..2b876ade12 100644 --- a/vsintegration/src/FSharp.VS.FSI/fsiSessionToolWindow.fs +++ b/vsintegration/src/FSharp.VS.FSI/fsiSessionToolWindow.fs @@ -540,7 +540,7 @@ type internal FsiToolWindow() as this = #silentCd @"{dir}";; {if dbgBreak then "#dbgbreak" else ""} #{topLine} @"{filename}" -{text.ToString()};; +{text.ToString()} #1 "stdin" #interactiveprompt "show";; """ From f293204f6518bcc39d23211331ebd01ff888d12f Mon Sep 17 00:00:00 2001 From: Vlad Zarytovskii Date: Wed, 30 Nov 2022 15:11:10 +0100 Subject: [PATCH 3/3] Apply suggestions from code review Co-authored-by: Petr Pokorny --- src/Compiler/Interactive/fsi.fs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/Compiler/Interactive/fsi.fs b/src/Compiler/Interactive/fsi.fs index b4bc3b79de..0485d4e06e 100644 --- a/src/Compiler/Interactive/fsi.fs +++ b/src/Compiler/Interactive/fsi.fs @@ -1138,7 +1138,7 @@ type internal FsiConsolePrompt(fsiOptions: FsiCommandLineOptions, fsiConsoleOutp else "> " - member _.Print() = + member _.Print() = if showPrompt then if dropPrompt = 0 then fsiConsoleOutput.uprintf "%s" prompt @@ -1156,7 +1156,7 @@ type internal FsiConsolePrompt(fsiOptions: FsiCommandLineOptions, fsiConsoleOutp with get () = showPrompt and set (value) = showPrompt <- value - member _.SkipNext() = + member _.SkipNext() = if showPrompt then dropPrompt <- dropPrompt + 1 @@ -3104,7 +3104,7 @@ type FsiInteractionProcessor // After we've unblocked and got something to run we switch // over to the run-thread (e.g. the GUI thread) - let res = istate |> runCodeOnMainThread (fun ctok istate ->ExecuteParsedInteractionOnMainThread (ctok, diagnosticsLogger, action, istate, cancellationToken)) + let res = istate |> runCodeOnMainThread (fun ctok istate -> ExecuteParsedInteractionOnMainThread (ctok, diagnosticsLogger, action, istate, cancellationToken)) if progress then fprintfn fsiConsoleOutput.Out "Just called runCodeOnMainThread, res = %O..." res res)