Skip to content

Proposal: NotebookCell - Static Analysis Ordering #2224

@manzt

Description

@manzt

Problem

Some notebook environments execute cells based on a dependency graph rather than document order. For example, in marimo notebooks:

Cell 1:  x = y + 1    # LSP reports F821: 'y' undefined
Cell 2:  y = 10       # Actually executes first due to dependency graph

LSP servers analyzing notebooks assume top-to-bottom execution, causing false positives when the actual execution order differs from document order.

Proposal

Add an analysisOrder field to NotebookCell:

export interface NotebookCell {
  kind: NotebookCellKind;
  document: DocumentUri;
  metadata?: LSPObject;
  executionSummary?: ExecutionSummary;

  /**
   * Optional ordering hint for static analysis.
   * When present, language servers SHOULD sort cells by this value
   * (ascending) before analyzing. Cells without this field are
   * analyzed after ordered cells, in document order.
   *
   * This allows notebook clients to communicate non-linear execution
   * semantics to language servers for more accurate diagnostics.
   */
  analysisOrder?: uinteger;
}

Example:

{
  "cells": [
    { "document": "cell:1", "analysisOrder": 2 },
    { "document": "cell:2", "analysisOrder": 1 }
  ]
}

Cell 2 is analyzed first, so y is defined before cell 1 references it.

Alternatives

executionSummary.executionOrder

The existing executionOrder field could be used for this, but we want diagnostics before running any cells. Relying on executionOrder means:

  • No ordering until the notebook is executed
  • Resetting the notebook loses the order
  • Clients need workarounds like creating fake executions just to maintain state

In VS Code, executionSummary is readonly on NotebookCell - the only way to set it is through NotebookCellExecution:

const execution = controller.createNotebookCellExecution(cell);
execution.executionOrder = order;
execution.start();
execution.end(true); // immediately end

This is awkward because it requires a NotebookController, shows execution UI feedback, and signals "this cell ran" when it hasn't.

analysisOrder should be something any LSP can set and manage independently.

metadata field

For today, we'll likely start implementing this in marimo-lsp using the metadata field and try to get buy-in from language servers:

{
  "cells": [
    { "document": "cell:1", "metadata": { "analysisOrder": 2 } },
    { "document": "cell:2", "metadata": { "analysisOrder": 1 } }
  ]
}

A first-class field would signal that this is a supported protocol feature and give servers a clear contract to implement.

Use cases

  • Reactive notebooks (marimo, Observable)
  • Dependency-ordered execution environments
  • Any notebook where static analysis order should differ from document order

Related

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions