microsoft / microsoft/language-server-protocol

Proposal: NotebookCell - Static Analysis Ordering

Open
#2,224 0 comments 7 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Dominant language
TypeScript
Stars
13k
Forks
1k
Avg merge
6d 1h
Merged PRs (30d)
10

Description

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

Contributor guide

No contributing guide indexed for this repository

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start at the NotebookCell interface and review the existing executionSummary and executionOrder fields, then read the linked discussions and pull requests about notebook analysis ordering. Done means the protocol has an agreed field name, ordering semantics, compatibility behavior for unordered cells, and an accepted specification change.

Written by the indexing model from the issue text.

Assessment

Tech stack
typescript
Domain
api, devtools
Issue type
Feature
Difficulty
5/5
Estimated time
Over a week
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
30/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.