From fe36d6f8828b810137f3a18926d735d7dd362883 Mon Sep 17 00:00:00 2001 From: Arnesh Banerjee Date: Mon, 20 Jul 2026 15:34:24 +0530 Subject: [PATCH 1/2] repl: Show add-cell controls in empty notebooks When a notebook has no cells, the editor rendered a blank pane with no visible way to add one. Render an empty-state with add code cell and add markdown cell buttons in the editor body, each with an icon and its keybinding, matching the affordance VSCode provides. This is the follow-up direction suggested in #61296. Co-Authored-By: Claude Fable 5 --- crates/repl/src/notebook/notebook_ui.rs | 51 ++++++++++++++++++++++++- 1 file changed, 49 insertions(+), 2 deletions(-) diff --git a/crates/repl/src/notebook/notebook_ui.rs b/crates/repl/src/notebook/notebook_ui.rs index 235a711428bbf3..4632a337c0387f 100644 --- a/crates/repl/src/notebook/notebook_ui.rs +++ b/crates/repl/src/notebook/notebook_ui.rs @@ -18,7 +18,7 @@ use language::{Language, LanguageRegistry}; use log; use project::{Project, ProjectEntryId, ProjectPath}; use settings::Settings as _; -use ui::{CommonAnimationExt, Tooltip, prelude::*}; +use ui::{CommonAnimationExt, KeyBinding, Tooltip, prelude::*}; use workspace::item::{ItemEvent, SaveOptions, TabContentParams}; use workspace::searchable::SearchableItemHandle; use workspace::{Item, ItemHandle, Pane, ProjectItem, ToolbarItemLocation}; @@ -1276,6 +1276,44 @@ impl NotebookEditor { .size_full() } + fn render_empty_state(&self, cx: &mut Context) -> impl IntoElement { + v_flex() + .size_full() + .items_center() + .justify_center() + .gap_3() + .child(Label::new("This notebook is empty").color(Color::Muted)) + .child( + h_flex() + .gap_2() + .child( + Button::new("empty-state-add-code", "Add code cell") + .start_icon(Icon::new(IconName::Code)) + .key_binding(KeyBinding::for_action_in( + &AddCodeBlock, + &self.focus_handle, + cx, + )) + .on_click( + cx.listener(|this, _, window, cx| this.add_code_block(window, cx)), + ), + ) + .child( + Button::new("empty-state-add-markdown", "Add markdown cell") + .style(ButtonStyle::Subtle) + .start_icon(Icon::new(IconName::FileMarkdown)) + .key_binding(KeyBinding::for_action_in( + &AddMarkdownBlock, + &self.focus_handle, + cx, + )) + .on_click(cx.listener(|this, _, window, cx| { + this.add_markdown_block(window, cx) + })), + ), + ) + } + fn cell_position(&self, index: usize) -> CellPosition { match index { 0 => CellPosition::First, @@ -1475,7 +1513,16 @@ impl Render for NotebookEditor { .w_full() .h_full() .gap_2() - .child(div().flex_1().h_full().child(self.cell_list(window, cx))) + .child( + div() + .flex_1() + .h_full() + .child(if self.cell_order.is_empty() { + self.render_empty_state(cx).into_any_element() + } else { + self.cell_list(window, cx).into_any_element() + }), + ) .child(self.render_notebook_controls(window, cx)), ) .child(self.render_kernel_status_bar(window, cx)) From ab068873af9585b43aebc30fcb84bfbb9d5a72bc Mon Sep 17 00:00:00 2001 From: Finn Evers Date: Fri, 24 Jul 2026 12:57:59 +0200 Subject: [PATCH 2/2] Apply suggestion from @MrSubidubi --- crates/repl/src/notebook/notebook_ui.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/crates/repl/src/notebook/notebook_ui.rs b/crates/repl/src/notebook/notebook_ui.rs index 4632a337c0387f..867acc7c583fcc 100644 --- a/crates/repl/src/notebook/notebook_ui.rs +++ b/crates/repl/src/notebook/notebook_ui.rs @@ -1282,7 +1282,7 @@ impl NotebookEditor { .items_center() .justify_center() .gap_3() - .child(Label::new("This notebook is empty").color(Color::Muted)) + .child(Label::new("This notebook is empty.").color(Color::Muted)) .child( h_flex() .gap_2()