дзеркало
https://github.com/l0ng-ai/openidea.git
синхронізовано 2026-11-08 19:02:17 +02:00
Opens .ipynb files in a native notebook editor, in a project or LightEdit. - crates/ide-notebook: lossless nbformat documents (unchanged notebooks save byte-for-byte, unknown fields kept, external changes detected) and owned local kernels over ZMQ via kernelspec — the selected Python environment only needs ipykernel, no Jupyter server. - ide-host owns notebook documents per project incarnation and admits one execution batch at a time; outputs stream over IPC channels and kernel status is an IdeEvent. - src/features/notebook: virtualized Python/Markdown cells, insert/delete/move/change type, Run Cell / Run All (Shift+Enter), interrupt, restart, interpreter selection from ide-sdk discovery, shared split views. Raw/unknown cells stay read-only. - Custom editor kinds take part in dirty state, save/save all, undo/redo and Save/Don't Save/Cancel; closing editors from other features awaits that decision. - Outputs: text, tracebacks, PNG/JPEG and sanitized SVG inline; HTML sanitized in a sandboxed iframe without allow-same-origin; JavaScript output is shown as inert source. - Explicit launches (opening a notebook from the OS) win over session restoration. Closes #131 Co-authored-by: dvictor357 <[email protected]>
54 рядки
2.1 KiB
TypeScript
54 рядки
2.1 KiB
TypeScript
import { afterEach, describe, expect, it, vi } from "vitest";
|
|
import { history } from "@codemirror/commands";
|
|
import { EditorState } from "@codemirror/state";
|
|
import { EditorView } from "@codemirror/view";
|
|
import { editCommand } from "../appActions";
|
|
import * as contributions from "@/workbench/contributions";
|
|
|
|
describe("Edit menu Undo / Redo", () => {
|
|
let view: EditorView | null = null;
|
|
afterEach(() => {
|
|
view?.destroy();
|
|
view = null;
|
|
vi.restoreAllMocks();
|
|
});
|
|
|
|
it("use the focused editor's history, including programmatic edits", () => {
|
|
view = new EditorView({ state: EditorState.create({ doc: "a", extensions: history() }), parent: document.body });
|
|
view.dispatch({ changes: { from: 1, insert: "b" }, userEvent: "input.complete" });
|
|
view.contentDOM.focus();
|
|
editCommand("undo")();
|
|
expect(view.state.doc.toString()).toBe("a");
|
|
editCommand("redo")();
|
|
expect(view.state.doc.toString()).toBe("ab");
|
|
});
|
|
|
|
it("routes custom document history before CodeMirror's independent local history", () => {
|
|
const parent = document.createElement("div");
|
|
parent.dataset.paneId = "custom-pane";
|
|
document.body.appendChild(parent);
|
|
view = new EditorView({ state: EditorState.create({ doc: "local", extensions: history() }), parent });
|
|
view.dispatch({ changes: { from: 5, insert: " edit" }, userEvent: "input" });
|
|
let source = "backend edited";
|
|
vi.spyOn(contributions, "maybeEditorService").mockReturnValue({
|
|
openFile: async () => {},
|
|
openInput: async () => {},
|
|
activePath: () => "/p/notebook.ipynb",
|
|
activeCursor: () => null,
|
|
saveAll: async () => {},
|
|
documentHistory: (command) => {
|
|
source = command === "undo" ? "backend original" : "backend edited";
|
|
return true;
|
|
},
|
|
});
|
|
view.contentDOM.focus();
|
|
editCommand("undo")();
|
|
expect(source).toBe("backend original");
|
|
expect(view.state.doc.toString()).toBe("local edit");
|
|
editCommand("redo")();
|
|
expect(source).toBe("backend edited");
|
|
expect(view.state.doc.toString()).toBe("local edit");
|
|
parent.remove();
|
|
});
|
|
});
|