Repository navigation
Check executed F# cells as FSI runs them, each in a fragment of its own - #129
Merged
TorreyBetts merged 1 commit intoOct 23, 2026
Conversation
The F# kernel checks a cell for diagnostics, hover and completions in one virtual script that holds every executed cell followed by the cell being edited. FSI compiles each execution as a fragment of its own and opens it for the ones after, so a later execution may define again a type or module an earlier one defined, as a cell does each time it is run again. In one file that is a duplicate definition: once a cell defining a type or module has run, checking it again reports FS0037 on each of its definitions, and the editor shows those as errors. Each executed source is now wrapped in a module of its own, which is then opened, the way FSI does it. Script directives (#r, #load, #I, #nowarn, ...) are lifted out of the module, since they apply to the whole script, and a fragment's top-level opens are repeated after it, since in FSI they stay open for later cells. The cell being edited stays at the top level, so its positions are unchanged. The wrapper modules are kept out of what a user sees: completions leave them out, and hover text and diagnostic messages drop their names, so a type reads as Notebook.Shape rather than Notebook.VersoExecutedCell1.Shape. Signed-off-by: Jonathan Schäfer <jonathan.schaefer.mail@gmail.com> Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
TorreyBetts
approved these changes
Oct 23, 2026
TorreyBetts
left a comment
Contributor
There was a problem hiding this comment.
Thanks for this, looks good. Will be included in the next release.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Fixes #128.
The F# kernel checks a cell for diagnostics, hover and completions in one virtual script that holds every executed cell followed by the cell being checked. Once a cell that defines a type or a module has run, its definitions appear twice in that file, and checking it again reports FS0037 on each of them.
FSI compiles each execution as a fragment of its own and opens it for the ones after. The virtual script imitates this.
Each executed cell is its own module. Each executed source is wrapped in a module of its own, followed by an open of that module. The cell being checked stays at the top level, so its positions are unchanged.
Directives still apply to the whole script. #r, #load, #I, #nowarn and the other script directives are lifted out of the module, since they apply to the whole script.
Opens stay open. A fragment’s top-level opens are repeated after it, since in FSI they stay open for later cells.
The wrappers stay invisible. Completions leave the wrapper modules out, and hover text and diagnostic messages drop their names, so a type reads as Notebook.Shape rather than Notebook.VersoExecutedCell1.Shape.
ExecutedCellsTests covers the cases:
a run cell checked again has no duplicate definitions;
a value redefined by a later cell takes the later definition;
opens persist, including the open of a module from the same cell, and a module from a run cell can be opened later;
an #r reference still resolves in later cells;
a cell with a triple-quoted string still checks;
the wrapper modules stay out of completions, hover and diagnostics.