You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Commit 0e32fd1
Browse filesBrowse the repository at this point in the historyBrowse files
Start the window's session where dotnet fsi would, and only on .NET
The window picked its own fsi: `dotnet.exe` from Program Files, or one of the desktop executables the extension ships, chosen through the options page the old window reads. The desktop ones cannot serve the protocol at all — the server exists in the .NET fsi alone — and the machine-wide `dotnet` ignored the SDK a solution pins.
The session now starts in the open solution's folder with the `dotnet` a shell there would run, so the host resolves the SDK from that folder's `global.json` exactly as `dotnet fsi` typed at a prompt does, and the window runs the same compiler bits as `dotnet build`. The platform choice, the desktop executables and the shadow-copy switch stay with the old window. When a session comes up the window prints which fsi answered, on what runtime and where, so a pinned SDK is seen rather than guessed at.
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Copy file name to clipboardExpand all lines: docs/ide/FSI-Modern-Interactive-Window-Plan.md
+15-22Lines changed: 15 additions & 22 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -28,9 +28,10 @@ and contains:
28
28
-`SubmissionAnalysis.fs` — the rule deciding when Enter submits, tested;
29
29
-`FSharpVsInteractiveWindowProvider.fs` — the MEF component that creates the tool window through
30
30
`IVsInteractiveWindowFactory.Create`, calls `SetLanguage` with the F# content type and language
31
-
service so the input buffer is an F# editor buffer, sets the caption from the platform, and reads
32
-
its options from the `SessionsProperties` the existing Tools, Options page already writes. No new
33
-
options page is needed.
31
+
service so the input buffer is an F# editor buffer, and reads its options from the
32
+
`SessionsProperties` the existing Tools, Options page already writes. No new options page is
33
+
needed. The session starts in the open solution's folder, so `dotnet fsi` runs the SDK that
34
+
folder's `global.json` resolves to.
34
35
35
36
Still to do before the window can be opened in Visual Studio:
36
37
@@ -40,7 +41,7 @@ Still to do before the window can be opened in Visual Studio:
40
41
calls the provider, rather than a new package with its own GUID and pkgdef;
41
42
- the `Microsoft.VisualStudio.InteractiveWindow` prerequisite entry in the VSIX manifest, and the
42
43
project's place in the VSIX itself. It is already in `VisualFSharp.slnx`, so it builds;
43
-
- commands: open the window, `#reset <platform>`, and retargeting Alt+Enter at the new window;
44
+
- commands: open the window, and retargeting Alt+Enter at the new window;
44
45
- the debugger attach/detach commands ported from the existing window. The session reports its own
45
46
process id in the handshake, so the attach no longer has to guess which process to target.
46
47
@@ -76,7 +77,7 @@ What the old window does have that C# Interactive does **not** (must be preserve
76
77
77
78
-**Debugging**: attach/detach the VS debugger to the FSI process, "Debug in Interactive" (`#dbgbreak`), debuggability check (`--debug+ --optimize-`) with a suppressible warning dialog. Roslyn's window has no debugging at all — this is an F# advantage to keep.
78
79
- Real script semantics: FSI executes actual `.fsx` interactions with `#load`/`#r`/`#i`, and `fsi` object, not a C#-script dialect.
79
-
-Platform choice already includes Arm64 (`fsiArm64.exe`).
80
+
-The .NET Framework hosts (`fsiAnyCpu.exe`, `fsi.exe`, `fsiArm64.exe`) stay with the old window; the new one is .NET-only, because the server mode exists only in the .NET fsi.
80
81
81
82
---
82
83
@@ -113,8 +114,7 @@ Five layers, copied from Roslyn's proven separation. Execution state lives **onl
- kills the `SERVER-PROMPT>` scraping, the PID-file hack, and the `# 1 "stdin"` directive juggling in one move;
127
127
- benefits every other fsi client (Ionide, VS Code, custom tooling) — the server mode is a compiler feature, not a VS-only one;
128
-
- keeps `dotnet fsi` as the .NET Core host (nothing new to deploy; the VSIX only carries the desktop `fsiAnyCpu`/`fsiArm64`it already ships).
128
+
- keeps `dotnet fsi` as the host, resolved from the solution folder's `global.json`, so the window runs the same compiler bits as `dotnet build` there and Visual Studio and SDK versions are decoupled (nothing new to deploy; the desktop `fsiAnyCpu`/`fsiArm64`the VSIX ships stay with the old window).
129
129
130
130
### 2.2 The RPC protocol (as implemented)
131
131
@@ -195,18 +195,11 @@ The single most valuable user-facing change. Mechanism (Roslyn's, adapted):
195
195
- Otherwise → submit iff the text is a syntactically complete interaction (FCS parse with `ScriptParseInfo`; incomplete constructs — open `let`, unclosed paren/string — return false). This matches `dotnet fsi`'s modern multiline behavior and C#'s `SyntaxFactory.IsCompleteSubmission`.
196
196
- The evaluator appends `;;` before sending to the host if absent; prompts: `> ` primary, `. ` (or `- `) continuation via `GetPrompt()`.
197
197
198
-
### 2.5 Platform selection
198
+
### 2.5 Host selection
199
199
200
-
Keep today's matrix, expressed the Roslyn way (`#reset` arguments + caption suffix + options page default):
200
+
The window is .NET-only. The server mode exists in the .NET fsi alone, and the desktop matrix (`fsiAnyCpu.exe`, `fsi.exe`, `fsiArm64.exe`, `#reset`platform arguments, the shadow-copy switch) stays with the old window until that is retired.
| .NET Framework x64 |`fsiAnyCpu.exe --fsi-server-jsonrpc:…`| shipped in VSIX |
206
-
| .NET Framework x86 |`fsi.exe`| shipped in VSIX |
207
-
| Arm64 |`fsiArm64.exe`| shipped in VSIX |
208
-
209
-
`#reset core` / `#reset net472` / etc. exported as a specialized-content-type command that displaces the package's generic `#reset` (Roslyn's `GetApplicableCommands` name-replacement mechanism).
202
+
The session is started in the open solution's folder, with the `dotnet` a shell there would run (`DOTNET_HOST_PATH`, then `PATH`, then the machine-wide install). The host resolves the SDK from that folder's `global.json` exactly as `dotnet fsi` typed in a shell would, so the window runs the same compiler bits as `dotnet build`, and Visual Studio and SDK versions are decoupled. Nothing in the window re-implements SDK resolution. `FSHARP_INTERACTIVE_PATH` names another fsi for development, until an SDK ships the protocol; the window prints which fsi answered, on what runtime and in which directory, when a session comes up.
210
203
211
204
### 2.6 Debugging (parity + improvement over C#)
212
205
@@ -243,7 +236,7 @@ Goal: de-risk the InteractiveWindow dependency before touching the compiler.
243
236
### Phase 2 — Evaluator + session on the new protocol — partly done
- Full `IInteractiveEvaluator`: `CanExecuteCode` (§2.4), `GetPrompt`, `ResetAsync` with platform args, `InitializeAsync`, `AbortExecution` → RPC `Interrupt` (note: this makes F# *better* than C# Interactive, whose `AbortExecution` is an unimplemented TODO).
239
+
- Full `IInteractiveEvaluator`: `CanExecuteCode` (§2.4), `GetPrompt`, `ResetAsync`, `InitializeAsync`, `AbortExecution` → RPC `Interrupt` (note: this makes F# *better* than C# Interactive, whose `AbortExecution` is an unimplemented TODO).
247
240
- Structured diagnostics from `ExecutionResult` rendered as error-classified output.
248
241
- Delete the stdin/stdout path from the new window (old window untouched).
249
242
@@ -260,9 +253,9 @@ Goal: de-risk the InteractiveWindow dependency before touching the compiler.
260
253
261
254
- Rewire `MenusAndCommands.vsct` targets: Alt+Enter Send Selection/Line, "Execute in Interactive", "Debug in Interactive" → new window (`window.SubmitAsync`, preserving the no-selection→current-line + caret-advance behavior; consider Roslyn's syntax-aware selection expansion from `SendToInteractiveSubmissionProvider`).
262
255
-`AddReferences` (Solution Explorer "Send project references to F# Interactive") → `#r` submissions.
263
-
- Optional: "Initialize Interactive with Project" parity — build project, reset with platform inferred from TFM, `SetPaths`, `#r` output assembly + references, `open` default namespaces (Roslyn's `ResetInteractive` flow).
264
-
- Port `FsiPropertyPage` (Tools → Options → F# Tools → F# Interactive): args, platform default, shadow copy (`--shadowcopyreferences` still honored via args), langversion preview, debug mode.
265
-
-Window caption platform suffix; `#reset` platform args; F1 help keyword.
- Port `FsiPropertyPage` (Tools → Options → F# Tools → F# Interactive): args, langversion preview, debug mode. The platform default and shadow copy belong to the desktop fsi and stay with the old window.
0 commit comments