Skip to content

Editable cell-based JupyterNotebookView + read-only output rendering#12303

Closed
evelyn-with-warp wants to merge 1 commit into
evelyn/render-jupyter-notebook-v1from
oz/ipynb-view
Closed

Editable cell-based JupyterNotebookView + read-only output rendering#12303
evelyn-with-warp wants to merge 1 commit into
evelyn/render-jupyter-notebook-v1from
oz/ipynb-view

Conversation

@evelyn-with-warp

Copy link
Copy Markdown
Contributor

Description

Implements the view slice of the editable, cell-based Jupyter .ipynb feature, building on the committed lossless NotebookDoc model. All behavior is gated (by the routing chokepoint, on the integration branch) behind FeatureFlag::JupyterNotebookEditing.

JupyterNotebookView parses content via NotebookDoc::parse and renders each cell as an editable surface:

  • Markdown cells → editable rendered markdown (RichTextEditorView/NotebooksEditorModel), serialized back to CellDoc.source on edit.
  • Code cells → editable, syntax-highlighted CodeEditorView using NotebookDoc::language(); source stored verbatim.
  • Outputs → read-only beneath code cells (stream / text/plain / ANSI-stripped tracebacks as preformatted text; image/png/image/jpeg decoded inline; invalid base64 → placeholder; display-only size guards that never alter saved bytes).

Editing only updates the edited cell's source (user-originated edits only); saved outputs and untouched cells are never mutated. Cell structural ops (insert/delete/move/convert). Robust fallback: unparseable .ipynb shows raw editable text and emits RawRequested so the host opens the real code editor — never blank, never panics.

This is edit-only: no kernel, no execution.

Main files to review

  • app/src/notebooks/file/jupyter/mod.rsJupyterNotebookView (View + Entity + TypedActionView + BackingView), edit→model sync, dirty tracking, structural ops, public API + events.
  • app/src/notebooks/file/jupyter/output.rsstrip_ansi, classify_outputs, image decode + display-only size guards.

Minor file changes

  • app/src/notebooks/file/mod.rs — adds pub(crate) mod jupyter; so the routing/pane can host the view.
  • app/src/notebooks/file/jupyter/{mod_tests.rs, output_tests.rs} — unit/view tests.

Public API (for the routing/integration branch)

new(content, path, ctx), set_content, to_json, is_dirty, mark_saved, request_save, path, title, pane_configuration. Events: Dirtied, SaveRequested { json }, RawRequested { json }, Focused, Pane(PaneEvent). BackingView::PaneHeaderOverflowMenuAction = JupyterNotebookAction.

Validation

  • cargo check -p warp --tests: passes (no errors).
  • cargo nextest run -p warp jupyter: 19/19 pass.
  • ./script/format: clean.
  • cargo clippy -p warp --tests: the only findings in this module are never used/constructed dead-code — expected because routing isn't wired on this branch (same class as the base branch's currently-unused ipynb_model); resolves once the integration branch wires JupyterNotebookView::new + NotebookDoc::parse.

Note: this is one half of a parallel split; the orchestrator integrates this with the routing/pane branch into a single combined PR (full presubmit/clippy clean after merge).

Conversation: https://staging.warp.dev/conversation/7eb55c0a-58d5-43e8-88d7-1deda8c567a8

Run: https://oz.staging.warp.dev/runs/019e9a20-4cd6-7283-8e9d-3b233cbd8a21

This PR was generated with Oz.

Implements the view slice of the editable .ipynb feature (gated behind
FeatureFlag::JupyterNotebookEditing). Builds on the committed lossless
NotebookDoc model.

- jupyter/mod.rs: JupyterNotebookView (View + Entity + TypedActionView +
  BackingView). Markdown cells -> editable RichTextEditorView; code cells ->
  editable, syntax-highlighted CodeEditorView using NotebookDoc::language();
  saved outputs render read-only beneath code cells. Parse via
  NotebookDoc::parse; on error falls back to an editable raw-text code editor
  (never blank, never panics). Dirty tracking only on user-originated edits;
  cell structural ops (insert/delete/move/convert). Public API: new,
  set_content, to_json, is_dirty, mark_saved, request_save, path, title,
  pane_configuration; events Dirtied/SaveRequested/RawRequested/Focused/Pane.
- jupyter/output.rs: strip_ansi, classify_outputs (stream / text/plain /
  error traceback as preformatted text; image/png + image/jpeg decoded inline;
  invalid base64 -> placeholder; display-only size guards that never alter
  saved bytes).
- notebooks/file/mod.rs: pub(crate) mod jupyter; (so the routing/pane can host).
- Tests: output classification + strip_ansi unit tests; view tests for
  fallback, round-trip, read-only outputs, markdown/code edit sync, reload,
  structural ops, path/title.

Co-Authored-By: Oz <oz-agent@warp.dev>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant