CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/npm-vscode-languageserver

Language Server Protocol implementation for Node.js providing comprehensive LSP server capabilities including text synchronization, diagnostics, code completion, and workspace symbol searching

Pending
Overview
Eval results
Files

notebooks.mddocs/

Notebook Support

Notebook document synchronization and management for Jupyter notebooks and other notebook formats. Supports both notebook-level and cell-level text document management with comprehensive lifecycle tracking.

Capabilities

Notebook Documents Manager

A manager for notebook documents that handles both notebook-level events and individual cell text documents.

/**
 * A manager for notebook documents that tracks both notebooks and their cell text documents
 */
class NotebookDocuments<T extends { uri: DocumentUri }> {
    /**
     * Create a new notebook documents manager
     * @param configurationOrTextDocuments Either a text documents configuration or an existing TextDocuments instance
     */
    constructor(configurationOrTextDocuments: TextDocumentsConfiguration<T> | TextDocuments<T>);
    
    /** Event fired when a notebook document has been opened */
    readonly onDidOpen: Event<NotebookDocument>;
    
    /** Event fired when a notebook document has changed */
    readonly onDidChange: Event<NotebookDocumentChangeEvent>;
    
    /** Event fired when a notebook document has been saved */
    readonly onDidSave: Event<NotebookDocument>;
    
    /** Event fired when a notebook document has been closed */
    readonly onDidClose: Event<NotebookDocument>;
    
    /**
     * Returns the text document for the given cell URI
     * @param cellUri The URI of the notebook cell
     */
    getCellTextDocument(cellUri: DocumentUri): T | undefined;
    
    /**
     * Returns the notebook document for the given notebook URI
     * @param notebookUri The URI of the notebook document
     */
    getNotebookDocument(notebookUri: DocumentUri): NotebookDocument | undefined;
    
    /**
     * Returns the notebook cell for the given cell URI
     * @param cellUri The URI of the notebook cell
     */
    getNotebookCell(cellUri: DocumentUri): NotebookCell | undefined;
    
    /**
     * Listens for notebook synchronization notifications and cell text document changes
     * @param connection The connection to listen on
     */
    listen(connection: Connection): void;
}

Usage Example:

import { NotebookDocuments, createConnection } from "vscode-languageserver";
import { TextDocument } from "vscode-languageserver-textdocument";

// Create connection and notebook documents manager
const connection = createConnection();
const notebooks = new NotebookDocuments(TextDocument);

// Listen for notebook events
notebooks.onDidOpen(notebook => {
    console.log(`Notebook opened: ${notebook.uri}`);
    console.log(`Cells: ${notebook.cells.length}`);
});

notebooks.onDidChange(event => {
    console.log(`Notebook changed: ${event.notebook.uri}`);
    event.contentChanges.forEach(change => {
        console.log(`Changed cells: ${change.cells?.length || 0}`);
    });
});

notebooks.onDidSave(notebook => {
    console.log(`Notebook saved: ${notebook.uri}`);
});

notebooks.onDidClose(notebook => {
    console.log(`Notebook closed: ${notebook.uri}`);
});

// Connect notebooks to the connection
notebooks.listen(connection);

// Access notebook and cell documents
const notebook = notebooks.getNotebookDocument("file:///path/to/notebook.ipynb");
const cell = notebooks.getNotebookCell("vscode-notebook-cell:/path/to/notebook.ipynb#cell1");
const cellDocument = notebooks.getCellTextDocument("vscode-notebook-cell:/path/to/notebook.ipynb#cell1");

Notebook Synchronization Feature

Feature interface for handling notebook synchronization events directly through the connection.

/**
 * Notebook synchronization feature for handling notebook lifecycle events
 */
interface NotebookSyncFeatureShape {
    synchronization: {
        /** Register handler for notebook open notifications */
        onDidOpenNotebookDocument(handler: NotificationHandler1<DidOpenNotebookDocumentParams>): Disposable;
        /** Register handler for notebook change notifications */
        onDidChangeNotebookDocument(handler: NotificationHandler1<DidChangeNotebookDocumentParams>): Disposable;
        /** Register handler for notebook save notifications */
        onDidSaveNotebookDocument(handler: NotificationHandler1<DidSaveNotebookDocumentParams>): Disposable;
        /** Register handler for notebook close notifications */
        onDidCloseNotebookDocument(handler: NotificationHandler1<DidCloseNotebookDocumentParams>): Disposable;
    };
}

Direct Usage Example:

// Access via connection.notebooks.synchronization
connection.notebooks.synchronization.onDidOpenNotebookDocument(params => {
    console.log(`Notebook opened: ${params.notebookDocument.uri}`);
    params.cellTextDocuments.forEach(cell => {
        console.log(`Cell: ${cell.uri} (${cell.languageId})`);
    });
});

connection.notebooks.synchronization.onDidChangeNotebookDocument(params => {
    console.log(`Notebook changed: ${params.notebookDocument.uri}`);
    params.change.cells?.structure?.array?.forEach(change => {
        console.log(`Cell operation: ${change.start} +${change.deleteCount} ${change.cells?.length || 0}`);
    });
});

Notebook Document Structure

Core interfaces for notebook documents and cells.

/**
 * A notebook document represents a collection of cells
 */
interface NotebookDocument {
    /** The notebook document's URI */
    uri: DocumentUri;
    /** The type of the notebook */
    notebookType: string;
    /** The version number of this document */
    version: number;
    /** Additional metadata stored with the notebook */
    metadata?: LSPObject;
    /** The cells of a notebook */
    cells: NotebookCell[];
}

/**
 * A notebook cell represents a single cell in a notebook
 */
interface NotebookCell {
    /** The cell's kind */
    kind: NotebookCellKind;
    /** The URI of the cell's text document content */
    document: DocumentUri;
    /** Additional metadata stored with the cell */
    metadata?: LSPObject;
    /** Additional execution summary information if supported by the client */
    executionSummary?: ExecutionSummary;
}

/**
 * The kind of a notebook cell
 */
enum NotebookCellKind {
    /** A markup cell is formatted source that is used for display */
    Markup = 1,
    /** A code cell is source code */
    Code = 2
}

/**
 * Execution summary for a notebook cell
 */
interface ExecutionSummary {
    /** A strict monotonically increasing value indicating the execution order of a cell inside a notebook */
    executionOrder?: number;
    /** Whether the execution was successful or not if known by the client */
    success?: boolean;
}

Notebook Change Events

Detailed change information for notebook updates.

/**
 * Parameters for notebook open notifications
 */
interface DidOpenNotebookDocumentParams {
    /** The notebook document that got opened */
    notebookDocument: NotebookDocument;
    /** The text documents that represent the content of a notebook cell */
    cellTextDocuments: TextDocumentItem[];
}

/**
 * Parameters for notebook change notifications
 */
interface DidChangeNotebookDocumentParams {
    /** The notebook document that did change */
    notebookDocument: VersionedNotebookDocumentIdentifier;
    /** The actual changes to the notebook document */
    change: NotebookDocumentChangeEvent;
}

/**
 * Parameters for notebook save notifications
 */
interface DidSaveNotebookDocumentParams {
    /** The notebook document that got saved */
    notebookDocument: NotebookDocumentIdentifier;
}

/**
 * Parameters for notebook close notifications
 */
interface DidCloseNotebookDocumentParams {
    /** The notebook document that got closed */
    notebookDocument: NotebookDocumentIdentifier;
    /** The text documents that represent the content of a notebook cell that got closed */
    cellTextDocuments: TextDocumentIdentifier[];
}

/**
 * A change event for a notebook document
 */
interface NotebookDocumentChangeEvent {
    /** The changed metadata if any */
    metadata?: LSPObject;
    /** Changes to cells */
    cells?: {
        /** Changes to the cell structure to add or remove cells */
        structure?: {
            /** The change to the number of cells in the document */
            array: NotebookCellArrayChange;
            /** Additional opened cell text documents */
            didOpen?: TextDocumentItem[];
            /** Additional closed cell text documents */
            didClose?: TextDocumentIdentifier[];
        };
        /** Changes to notebook cells */
        data?: NotebookCell[];
        /** Changes to the text content of notebook cells */
        textContent?: {
            document: VersionedTextDocumentIdentifier;
            changes: TextDocumentContentChangeEvent[];
        }[];
    };
}

/**
 * A change describing how to move a notebook cell array from state S to S'
 */
interface NotebookCellArrayChange {
    /** The start offset of the cell that changed */
    start: number;
    /** The deleted cells */
    deleteCount: number;
    /** The new cells, if any */
    cells?: NotebookCell[];
}

Notebook Document Identifiers

Identification interfaces for notebook documents.

/**
 * A literal to identify a notebook document in the client
 */
interface NotebookDocumentIdentifier {
    /** The notebook document's URI */
    uri: DocumentUri;
}

/**
 * A versioned notebook document identifier
 */
interface VersionedNotebookDocumentIdentifier extends NotebookDocumentIdentifier {
    /** The version number of this notebook document */
    version: number;
}

Integration with Text Documents

Notebook cells are backed by text documents, allowing for seamless integration with existing text document features.

// Notebook cells can be accessed as regular text documents
const cellDocument = notebooks.getCellTextDocument("vscode-notebook-cell:/path/to/notebook.ipynb#cell1");

// Use with existing text document features
connection.onHover((params) => {
    // Check if this is a notebook cell URI
    if (params.textDocument.uri.startsWith("vscode-notebook-cell:")) {
        const cellDocument = notebooks.getCellTextDocument(params.textDocument.uri);
        const cell = notebooks.getNotebookCell(params.textDocument.uri);
        
        if (cellDocument && cell) {
            // Provide hover information for notebook cell
            return {
                contents: `Notebook cell (${cell.kind === NotebookCellKind.Code ? 'Code' : 'Markdown'})`
            };
        }
    }
    return null;
});

Core Types

type DocumentUri = string;

type LSPObject = { [key: string]: any };

interface TextDocumentItem {
    /** The text document's URI */
    uri: DocumentUri;
    /** The text document's language identifier */
    languageId: string;
    /** The version number of this document */
    version: number;
    /** The content of the opened text document */
    text: string;
}

interface TextDocumentIdentifier {
    /** The text document's URI */
    uri: DocumentUri;
}

interface VersionedTextDocumentIdentifier extends TextDocumentIdentifier {
    /** The version number of this document */
    version: number;
}

interface TextDocumentContentChangeEvent {
    /** The range of the document that changed */
    range?: Range;
    /** The optional length of the range that got replaced */
    rangeLength?: number;
    /** The new text for the provided range or the whole document */
    text: string;
}

type NotificationHandler1<P> = (params: P) => void;

type Event<T> = (listener: (e: T) => any, thisArg?: any) => Disposable;

interface Disposable {
    dispose(): void;
}

Install with Tessl CLI

npx tessl i tessl/npm-vscode-languageserver

docs

connection.md

documents.md

extended-features.md

index.md

language-features.md

notebooks.md

utilities.md

tile.json