Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions assets/keymaps/vim.json
Original file line number Diff line number Diff line change
Expand Up @@ -1110,4 +1110,12 @@
"shift-g": "menu::SelectLast",
},
},
{
"context": "NotebookEditor > Editor && VimControl && vim_mode == normal",

"bindings": {
"j": "notebook::NotebookMoveDown",
"k": "notebook::NotebookMoveUp",
},
},
]
96 changes: 19 additions & 77 deletions crates/repl/src/notebook/cell.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,12 @@
use std::sync::Arc;
use std::time::{Duration, Instant};

use editor::{Editor, EditorMode, MultiBuffer};
use editor::{Editor, EditorMode, MultiBuffer, SizingBehavior};
use futures::future::Shared;
use gpui::{
App, Entity, EventEmitter, Focusable, Hsla, InteractiveElement, RetainAllImageCache,
StatefulInteractiveElement, Task, TextStyleRefinement, image_cache, prelude::*,
App, Entity, EventEmitter, Focusable, Hsla, InteractiveElement, KeyContext,
RetainAllImageCache, StatefulInteractiveElement, Task, TextStyleRefinement, image_cache,
prelude::*,
};
use language::{Buffer, Language, LanguageRegistry};
use markdown::{Markdown, MarkdownElement, MarkdownStyle};
Expand Down Expand Up @@ -357,9 +358,10 @@ impl MarkdownCell {

let editor = cx.new(|cx| {
let mut editor = Editor::new(
EditorMode::AutoHeight {
min_lines: 1,
max_lines: Some(1024),
EditorMode::Full {
scale_ui_elements_with_buffer_font_size: false,
show_active_line_background: false,
sizing_behavior: SizingBehavior::SizeByContent,
},
multi_buffer,
None,
Expand All @@ -378,6 +380,7 @@ impl MarkdownCell {

editor.set_show_gutter(false, cx);
editor.set_text_style_refinement(refinement);
editor.set_use_modal_editing(true);
editor
});

Expand Down Expand Up @@ -625,9 +628,10 @@ impl CodeCell {

let editor_view = cx.new(|cx| {
let mut editor = Editor::new(
EditorMode::AutoHeight {
min_lines: 1,
max_lines: Some(1024),
EditorMode::Full {
scale_ui_elements_with_buffer_font_size: false,
show_active_line_background: false,
sizing_behavior: SizingBehavior::SizeByContent,
},
multi_buffer,
None,
Expand All @@ -646,6 +650,7 @@ impl CodeCell {

editor.set_show_gutter(false, cx);
editor.set_text_style_refinement(refinement);
editor.set_use_modal_editing(true);
editor
});

Expand Down Expand Up @@ -700,9 +705,10 @@ impl CodeCell {

let editor_view = cx.new(|cx| {
let mut editor = Editor::new(
EditorMode::AutoHeight {
min_lines: 1,
max_lines: Some(1024),
EditorMode::Full {
scale_ui_elements_with_buffer_font_size: false,
show_active_line_background: false,
sizing_behavior: SizingBehavior::SizeByContent,
},
multi_buffer,
None,
Expand All @@ -722,6 +728,7 @@ impl CodeCell {
editor.set_text(source.clone(), window, cx);
editor.set_show_gutter(false, cx);
editor.set_text_style_refinement(refinement);
editor.set_use_modal_editing(true);
editor
});

Expand Down Expand Up @@ -1117,71 +1124,6 @@ impl Render for CodeCell {
),
),
)
// Output portion
.child(
h_flex()
.w_full()
.pr_6()
.rounded_xs()
.items_start()
.gap(DynamicSpacing::Base08.rems(cx))
.bg(self.selected_bg_color(window, cx))
.child(self.gutter_output(window, cx))
.child(
div().py_1p5().w_full().child(
div()
.flex()
.size_full()
.flex_1()
.py_3()
.px_5()
.rounded_lg()
.border_1()
.child(
div()
.id((ElementId::from(self.id.to_string()), "output-scroll"))
.w_full()
.when_some(output_max_width, |div, max_w| {
div.max_w(max_w).overflow_x_scroll()
})
.when_some(output_max_height, |div, max_h| {
div.max_h(max_h).overflow_y_scroll()
})
.children(self.outputs.iter().map(|output| {
let content = match output {
Output::Plain { content, .. } => {
Some(content.clone().into_any_element())
}
Output::Markdown { content, .. } => {
Some(content.clone().into_any_element())
}
Output::Stream { content, .. } => {
Some(content.clone().into_any_element())
}
Output::Image { content, .. } => {
Some(content.clone().into_any_element())
}
Output::Message(message) => Some(
div().child(message.clone()).into_any_element(),
),
Output::Table { content, .. } => {
Some(content.clone().into_any_element())
}
Output::Json { content, .. } => {
Some(content.clone().into_any_element())
}
Output::ErrorOutput(error_view) => {
error_view.render(window, cx)
}
Output::ClearOutputWaitMarker => None,
};

div().children(content)
})),
),
),
),
)
.when(
self.has_outputs() || self.execution_duration.is_some() || self.is_executing,
|this| {
Expand Down
123 changes: 123 additions & 0 deletions crates/repl/src/notebook/notebook_ui.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ use std::{path::PathBuf, sync::Arc};
use anyhow::{Context as _, Result};
use client::proto::ViewId;
use collections::HashMap;
use editor::DisplayPoint;
use feature_flags::{FeatureFlagAppExt as _, NotebookFeatureFlag};
use futures::FutureExt;
use futures::future::Shared;
Expand Down Expand Up @@ -39,6 +40,7 @@ use picker::Picker;
use runtimelib::{ExecuteRequest, JupyterMessage, JupyterMessageContent};
use ui::PopoverMenuHandle;
use zed_actions::editor::{MoveDown, MoveUp};
use zed_actions::notebook::{NotebookMoveDown, NotebookMoveUp};

actions!(
notebook,
Expand Down Expand Up @@ -1273,6 +1275,127 @@ impl Render for NotebookEditor {
}
}
}))
.on_action(cx.listener(|this, _: &NotebookMoveDown, window, cx| {
let Some(cell_id) = this.cell_order.get(this.selected_cell_index) else {
return;
};
let Some(cell) = this.cell_map.get(cell_id) else {
return;
};

let editor = match cell {
Cell::Code(cell) => cell.read(cx).editor().clone(),
Cell::Markdown(cell) => cell.read(cx).editor().clone(),
_ => return,
};

let is_at_last_line = editor.update(cx, |editor, cx| {
let display_snapshot = editor.display_snapshot(cx);
let selections = editor.selections.all_display(&display_snapshot);
if let Some(selection) = selections.last() {
let head = selection.head();
let cursor_row = head.row();
let max_row = display_snapshot.max_point().row();

cursor_row >= max_row
} else {
false
}
});

if is_at_last_line {
this.select_next(&menu::SelectNext, window, cx);
if let Some(cell_id) = this.cell_order.get(this.selected_cell_index) {
if let Some(cell) = this.cell_map.get(cell_id) {
match cell {
Cell::Code(cell) => {
let editor = cell.read(cx).editor().clone();
editor.update(cx, |editor, cx| {
editor.move_to_beginning(&Default::default(), window, cx);
});
editor.focus_handle(cx).focus(window, cx);
}
Cell::Markdown(cell) => {
cell.update(cx, |cell, cx| {
cell.set_editing(true);
cx.notify();
});
let editor = cell.read(cx).editor().clone();
editor.update(cx, |editor, cx| {
editor.move_to_beginning(&Default::default(), window, cx);
});
editor.focus_handle(cx).focus(window, cx);
}
_ => {}
}
}
}
} else {
editor.update(cx, |editor, cx| {
editor.move_down(&Default::default(), window, cx);
});
}
}))
.on_action(cx.listener(|this, _: &NotebookMoveUp, window, cx| {
let Some(cell_id) = this.cell_order.get(this.selected_cell_index) else {
return;
};
let Some(cell) = this.cell_map.get(cell_id) else {
return;
};

let editor = match cell {
Cell::Code(cell) => cell.read(cx).editor().clone(),
Cell::Markdown(cell) => cell.read(cx).editor().clone(),
_ => return,
};

let is_at_first_line = editor.update(cx, |editor, cx| {
let display_snapshot = editor.display_snapshot(cx);
let selections = editor.selections.all_display(&display_snapshot);
if let Some(selection) = selections.first() {
let head = selection.head();
let cursor_row = head.row();

cursor_row.0 == 0
} else {
false
}
});

if is_at_first_line {
this.select_previous(&menu::SelectPrevious, window, cx);
if let Some(cell_id) = this.cell_order.get(this.selected_cell_index) {
if let Some(cell) = this.cell_map.get(cell_id) {
match cell {
Cell::Code(cell) => {
let editor = cell.read(cx).editor().clone();
editor.update(cx, |editor, cx| {
editor.move_to_end(&Default::default(), window, cx);
});
editor.focus_handle(cx).focus(window, cx);
}
Cell::Markdown(cell) => {
cell.update(cx, |cell, cx| {
cell.set_editing(true);
cx.notify();
});
let editor = cell.read(cx).editor().clone();
editor.update(cx, |editor, cx| {
editor.move_to_end(&Default::default(), window, cx);
});
editor.focus_handle(cx).focus(window, cx);
}
_ => {}
}
}
}
} else {
editor.update(cx, |editor, cx| {
editor.move_up(&Default::default(), window, cx);
});
}
}))
.on_action(
cx.listener(|this, action, window, cx| this.restart_kernel(action, window, cx)),
)
Expand Down
14 changes: 14 additions & 0 deletions crates/zed_actions/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -729,3 +729,17 @@ pub mod preview {
);
}
}

pub mod notebook {
use gpui::actions;

actions!(
notebook,
[
/// Move to down in cells
NotebookMoveDown,
/// Move to up in cells
NotebookMoveUp,
]
);
}