Skip to content

notebook: run notebook-scope code actions on all cells when saving - #340120

Open
Irish Joseph (Irish-Joseph) wants to merge 1 commit into
microsoft:mainfrom
Irish-Joseph:fix/notebook-codeactions-on-save-markdown-first-cell
Open

Irish Joseph (Irish-Joseph) wants to merge 1 commit into
microsoft:mainfrom
Irish-Joseph:fix/notebook-codeactions-on-save-markdown-first-cell

Conversation

@Irish-Joseph

@Irish-Joseph Irish Joseph (Irish-Joseph) commented Oct 6, 2026 •

Copy link
Copy Markdown

Summary

Fixes #338963 — notebook.codeActionsOnSave does nothing when the notebook's first cell is a markdown cell.

Notebook-scope code actions (kinds like notebook.source.organizeImports, i.e. everything under the notebook base kind that vscode.CodeActionKind.Notebook covers) are provided per cell but apply to the whole notebook. The save participant only asked the first cell for them, so with a leading markdown cell no provider matched the markdown language and the action silently never ran — even when a later Python/code cell's language server could (and would) provide it.

Change

src/vs/workbench/contrib/notebook/browser/contrib/saveParticipants/saveParticipants.ts

  • The notebook-scope branch of CodeActionOnSaveParticipant.participate now asks the cells in order and stops as soon as one of them has applied an action.
  • CodeActionParticipantUtils.applyOnSaveGenericCodeActions now returns whether at least one action was applied (Promise<void> → Promise<boolean>), used by the loop above.
  • CodeActionOnSaveParticipant is exported for testability (no behavior change).

Stopping after the first applied cell keeps notebook-scope semantics: an action such as Organize Imports touches the whole document, so applying it from every contributing cell would double-apply its multi-cell edits.

Tests

New suite: src/vs/workbench/contrib/notebook/test/browser/contrib/saveParticipants/saveParticipants.test.ts (3 tests, real NotebookTextModel + real LanguageFeaturesService with a Python CodeActionProvider returning a notebook.source.organizeImports action, and cell text models bound to the cells the same way the workbench's cell content provider does):

  1. markdown cell first, Python code cell second — the issue scenario. Asserts the provider is queried for the Python cell, the action's edit is applied, and the code cell's content is updated on save.
  2. code cell first — control: the previously-working layout still works (provider called once, edit applied).
  3. two Python cells — a notebook-scope action is applied only once (guard for the stop-after-first-applied behavior).

Evidence

  • Without the fix (loop temporarily pinned to cells[0]): test 1 fails — the provider is never called (providerCalls === []), tests 2–3 pass. Reproduced with scripts/test.bat --run vs/workbench/contrib/notebook/test/browser/contrib/saveParticipants/saveParticipants.test.js.
  • With the fix: all 3 tests pass (4 passing incl. the suite clean-state check).
  • Regression suites, all passing: editor codeAction (8), notebook cellOperations (27), notebookBrowser (5), notebookUndoRedo (7). No other code or test references the changed paths.
  • npm run precommit (hygiene) passes on both changed files.

Copilot AI balanced review requested due to automatic review settings October 6, 2026 18:46
Notebook-scope code actions (e.g. notebook.source.organizeImports) are
provided by per-cell language servers but apply to the whole notebook.
The save participant only requested them from the first cell's text
model, so when the first cell was markdown (a very common layout) no
provider matched and the action silently did nothing.

Ask the cells in order and stop once an action has been applied from
one of them, so a notebook-scope action still runs at most once per
save.

Fixes microsoft#338963
@Irish-Joseph
Irish Joseph (Irish-Joseph) force-pushed the fix/notebook-codeactions-on-save-markdown-first-cell branch from 68f2d96 to 4a989e2 Compare October 6, 2026 18:51

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot review overview

🟡 Changes recommended

The loop can skip configured actions from later language providers and continues scanning after cancellation.

Review effort: Balanced
Findings: 2 Medium severity

Open (2)
What changed in this PR

Fixes notebook-scope save actions when the first cell has no matching provider.

Changes:

  • Searches cells sequentially for notebook code actions.
  • Returns application status and adds regression tests.
File Description
saveParticipants.ts Updates notebook action discovery and application tracking.
saveParticipants.test.ts Tests markdown-first and duplicate-application scenarios.

💡 Configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment on lines +406 to +408
const applied = await this.instantiationService.invokeFunction(CodeActionParticipantUtils.applyOnSaveGenericCodeActions, textEditorModel, notebookCodeActionsOnSave, excludedActions, progress, token);
if (applied) {
break;
Comment on lines +407 to +409
if (applied) {
break;
}

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

notebook.codeActionsOnSave does nothing when the notebook's first cell is markdown

4 participants