Skip to content

Commit

Permalink
indicate when a cell is dirty wrt the server
Browse files Browse the repository at this point in the history
  • Loading branch information
Jake Donham committed May 1, 2024
1 parent a8b81ce commit b3a6e6c
Show file tree
Hide file tree
Showing 8 changed files with 71 additions and 19 deletions.
6 changes: 4 additions & 2 deletions packages/server/src/server.ts
Original file line number Diff line number Diff line change
Expand Up @@ -341,15 +341,17 @@ class VitaleDevServer {
path: string;
cellId: string;
language: string;
code: string;
code?: string;
}[]
) {
let dirtyCells: { path: string; cellId: string }[] = [];

for (const { path, cellId, language, code } of cells) {
const ext = extOfLanguage(language);
const id = `${path}-cellId=${cellId}.${ext}`;
this.cells.set(id, { cellId, code, language });
if (code) {
this.cells.set(id, { cellId, code, language });
}

const mod = this.viteServer.moduleGraph.getModuleById(id);
if (mod) {
Expand Down
2 changes: 1 addition & 1 deletion packages/server/src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ export type ServerFunctions = {
path: string;
cellId: string;
language: string;
code: string;
code?: string;
}[]
) => void;
};
Expand Down
7 changes: 2 additions & 5 deletions packages/vscode/src/cellStatusBarItemProvider.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,12 +17,9 @@ export class NotebookCellStatusBarItemProvider
};
items.push(idItem);

// TODO(jaked)
// provideCellStatusBarItems is called on cell edits
// but the cell.document.dirty flag is always false
if (cell.metadata.dirty || cell.document.isDirty) {
if (cell.metadata.dirty || cell.metadata.docDirty) {
const dirtyItem = new vscode.NotebookCellStatusBarItem(
"$(circle-filled)",
cell.metadata.docDirty ? "$(circle-filled)" : "$(circle-outline)",
vscode.NotebookCellStatusBarAlignment.Right
);
// TODO(jaked)
Expand Down
40 changes: 31 additions & 9 deletions packages/vscode/src/controller.ts
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,7 @@ export class NotebookController {

this._controller.supportedLanguages = this.supportedLanguages;
this._controller.supportsExecutionOrder = true;
this._controller.executeHandler = this.executeCells.bind(this);
this._controller.executeHandler = this.executeHandler.bind(this);

getPort({ port: 51205 }).then((port) => {
this._port = port;
Expand Down Expand Up @@ -288,12 +288,21 @@ export class NotebookController {
}

private setCellDirty(cell: vscode.NotebookCell, dirty: boolean) {
const metadata = { ...(cell.metadata ?? {}), dirty };
const metadata = { ...cell.metadata, dirty };
const edit = new vscode.WorkspaceEdit();
edit.set(cell.notebook.uri, [
vscode.NotebookEdit.updateCellMetadata(cell.index, metadata),
]);
vscode.workspace.applyEdit(edit);
return vscode.workspace.applyEdit(edit);
}

private setCellDocDirty(cell: vscode.NotebookCell, docDirty: boolean) {
const metadata = { ...cell.metadata, docDirty };
const edit = new vscode.WorkspaceEdit();
edit.set(cell.notebook.uri, [
vscode.NotebookEdit.updateCellMetadata(cell.index, metadata),
]);
return vscode.workspace.applyEdit(edit);
}

private async markCellsDirty(cells: { path: string; cellId: string }[]) {
Expand All @@ -310,11 +319,11 @@ export class NotebookController {
}
}

for (const cell of notebookCells) {
this.setCellDirty(cell, true);
}
await Promise.all(
notebookCells.map((cell) => this.setCellDirty(cell, true))
);
if (getRerunCellsWhenDirty()) {
this.executeCells(notebookCells);
this.executeCells(notebookCells, false);
}
}

Expand Down Expand Up @@ -365,17 +374,30 @@ export class NotebookController {
}
}

private async executeCells(notebookCells: vscode.NotebookCell[]) {
private executeHandler(notebookCells: vscode.NotebookCell[]) {
this.executeCells(notebookCells);
}

private async executeCells(
notebookCells: vscode.NotebookCell[],
sendDirtyDocs = true
) {
if (notebookCells.length === 0) {
return;
}
const cells = notebookCells.map((cell) => ({
path: cell.notebook.uri.fsPath,
cellId: cell.metadata.id,
language: cell.document.languageId,
code: cell.document.getText(),
code: sendDirtyDocs ? cell.document.getText() : undefined,
}));

if (sendDirtyDocs) {
await Promise.all(
notebookCells.map((cell) => this.setCellDocDirty(cell, false))
);
}

const client = await this.getClient();
client.executeCells(cells);
}
Expand Down
2 changes: 2 additions & 0 deletions packages/vscode/src/extension.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import { NotebookSerializer } from "./serializer";
import { NotebookController } from "./controller";
import { NotebookCellStatusBarItemProvider } from "./cellStatusBarItemProvider";
import { makeHandleDidChangeNotebookDocument } from "./handleDidChangeNotebookDocument";
import { handleDidChangeTextDocument } from "./handleDidChangeTextDocument";

export function activate(context: vscode.ExtensionContext) {
const controller = new NotebookController(
Expand Down Expand Up @@ -30,6 +31,7 @@ export function activate(context: vscode.ExtensionContext) {
vscode.workspace.onDidChangeNotebookDocument(
makeHandleDidChangeNotebookDocument(controller)
),
vscode.workspace.onDidChangeTextDocument(handleDidChangeTextDocument),
controller,
vscode.notebooks.registerNotebookCellStatusBarItemProvider(
"vitale-notebook",
Expand Down
2 changes: 1 addition & 1 deletion packages/vscode/src/handleDidChangeNotebookDocument.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ export function makeHandleDidChangeNotebookDocument(
for (const contentChange of e.contentChanges) {
for (const cell of contentChange.addedCells) {
const id = uniqueId(e.notebook);
const metadata = { ...(cell.metadata ?? {}), id };
const metadata = { ...cell.metadata, id };
edits.push(NotebookEdit.updateCellMetadata(cell.index, metadata));
}
removedCells.push(...contentChange.removedCells);
Expand Down
27 changes: 27 additions & 0 deletions packages/vscode/src/handleDidChangeTextDocument.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
import type { TextDocumentChangeEvent } from "vscode";
import { NotebookEdit, WorkspaceEdit, workspace } from "vscode";

export function handleDidChangeTextDocument(e: TextDocumentChangeEvent) {
if (e.document.uri.scheme !== "vscode-notebook-cell") {
return;
}
const notebook = workspace.notebookDocuments.find(
(notebook) => notebook.uri.path === e.document.uri.path
);
if (!notebook) {
return;
}
const cell = notebook
.getCells()
.find((cell) => cell.document.uri.fragment === e.document.uri.fragment);
if (!cell) {
return;
}

const metadata = { ...cell.metadata, docDirty: true };
const edit = new WorkspaceEdit();
edit.set(notebook.uri, [
NotebookEdit.updateCellMetadata(cell.index, metadata),
]);
workspace.applyEdit(edit);
}
4 changes: 3 additions & 1 deletion packages/vscode/src/serializer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,8 @@ import JSON5 from "json5";

interface NotebookCellMetadata {
id: string;
dirty: boolean;
dirty: boolean; // a dependency of cell has changed
docDirty: boolean; // cell document has changed
}

interface NotebookCell {
Expand Down Expand Up @@ -59,6 +60,7 @@ export class NotebookSerializer implements vscode.NotebookSerializer {
for (const cell of data.cells) {
if (cell.metadata) {
delete cell.metadata.dirty;
delete cell.metadata.docDirty;
}
contents.cells.push({
kind: cell.kind,
Expand Down

0 comments on commit b3a6e6c

Please sign in to comment.