mirror of
https://github.com/zed-industries/zed.git
synced 2024-11-08 07:35:01 +03:00
repl: Push button to clear outputs (#14873)
This commit is contained in:
parent
a1670551bf
commit
6dfb0a4a70
@ -503,29 +503,38 @@ impl ExecutionView {
|
||||
impl Render for ExecutionView {
|
||||
fn render(&mut self, cx: &mut ViewContext<Self>) -> impl IntoElement {
|
||||
if self.outputs.len() == 0 {
|
||||
return match &self.status {
|
||||
ExecutionStatus::ConnectingToKernel => {
|
||||
div().child(Label::new("Connecting to kernel...").color(Color::Muted))
|
||||
}
|
||||
ExecutionStatus::Executing => {
|
||||
div().child(Label::new("Executing...").color(Color::Muted))
|
||||
}
|
||||
ExecutionStatus::Finished => div().child(Icon::new(IconName::Check)),
|
||||
ExecutionStatus::Unknown => {
|
||||
div().child(div().child(Label::new("Unknown status").color(Color::Muted)))
|
||||
}
|
||||
ExecutionStatus::ShuttingDown => {
|
||||
div().child(Label::new("Kernel shutting down...").color(Color::Muted))
|
||||
}
|
||||
ExecutionStatus::Shutdown => {
|
||||
div().child(Label::new("Kernel shutdown").color(Color::Muted))
|
||||
}
|
||||
ExecutionStatus::Queued => div().child(Label::new("Queued").color(Color::Muted)),
|
||||
ExecutionStatus::KernelErrored(error) => {
|
||||
div().child(Label::new(format!("Kernel error: {}", error)).color(Color::Error))
|
||||
}
|
||||
}
|
||||
.into_any_element();
|
||||
return v_flex()
|
||||
.min_h(cx.line_height())
|
||||
.justify_center()
|
||||
.child(match &self.status {
|
||||
ExecutionStatus::ConnectingToKernel => Label::new("Connecting to kernel...")
|
||||
.color(Color::Muted)
|
||||
.into_any_element(),
|
||||
ExecutionStatus::Executing => Label::new("Executing...")
|
||||
.color(Color::Muted)
|
||||
.into_any_element(),
|
||||
ExecutionStatus::Finished => Icon::new(IconName::Check)
|
||||
.size(IconSize::Small)
|
||||
.into_any_element(),
|
||||
ExecutionStatus::Unknown => Label::new("Unknown status")
|
||||
.color(Color::Muted)
|
||||
.into_any_element(),
|
||||
ExecutionStatus::ShuttingDown => Label::new("Kernel shutting down...")
|
||||
.color(Color::Muted)
|
||||
.into_any_element(),
|
||||
ExecutionStatus::Shutdown => Label::new("Kernel shutdown")
|
||||
.color(Color::Muted)
|
||||
.into_any_element(),
|
||||
ExecutionStatus::Queued => {
|
||||
Label::new("Queued").color(Color::Muted).into_any_element()
|
||||
}
|
||||
ExecutionStatus::KernelErrored(error) => {
|
||||
Label::new(format!("Kernel error: {}", error))
|
||||
.color(Color::Error)
|
||||
.into_any_element()
|
||||
}
|
||||
})
|
||||
.into_any_element();
|
||||
}
|
||||
|
||||
div()
|
||||
|
@ -5,14 +5,16 @@ use crate::{
|
||||
use collections::{HashMap, HashSet};
|
||||
use editor::{
|
||||
display_map::{
|
||||
BlockContext, BlockDisposition, BlockProperties, BlockStyle, CustomBlockId, RenderBlock,
|
||||
BlockContext, BlockDisposition, BlockId, BlockProperties, BlockStyle, CustomBlockId,
|
||||
RenderBlock,
|
||||
},
|
||||
scroll::Autoscroll,
|
||||
Anchor, AnchorRangeExt as _, Editor, MultiBuffer, ToPoint,
|
||||
};
|
||||
use futures::{FutureExt as _, StreamExt as _};
|
||||
use gpui::{
|
||||
div, prelude::*, EventEmitter, Model, Render, Subscription, Task, View, ViewContext, WeakView,
|
||||
div, prelude::*, EntityId, EventEmitter, Model, Render, Subscription, Task, View, ViewContext,
|
||||
WeakView,
|
||||
};
|
||||
use language::Point;
|
||||
use project::Fs;
|
||||
@ -22,7 +24,7 @@ use runtimelib::{
|
||||
use settings::Settings as _;
|
||||
use std::{env::temp_dir, ops::Range, path::PathBuf, sync::Arc, time::Duration};
|
||||
use theme::{ActiveTheme, ThemeSettings};
|
||||
use ui::{h_flex, prelude::*, v_flex, ButtonLike, ButtonStyle, Label};
|
||||
use ui::{h_flex, prelude::*, v_flex, ButtonLike, ButtonStyle, IconButtonShape, Label, Tooltip};
|
||||
|
||||
pub struct Session {
|
||||
pub editor: WeakView<Editor>,
|
||||
@ -39,13 +41,18 @@ struct EditorBlock {
|
||||
invalidation_anchor: Anchor,
|
||||
block_id: CustomBlockId,
|
||||
execution_view: View<ExecutionView>,
|
||||
on_close: CloseBlockFn,
|
||||
}
|
||||
|
||||
type CloseBlockFn =
|
||||
Arc<dyn for<'a> Fn(CustomBlockId, &'a mut WindowContext) + Send + Sync + 'static>;
|
||||
|
||||
impl EditorBlock {
|
||||
fn new(
|
||||
editor: WeakView<Editor>,
|
||||
code_range: Range<Anchor>,
|
||||
status: ExecutionStatus,
|
||||
on_close: CloseBlockFn,
|
||||
cx: &mut ViewContext<Session>,
|
||||
) -> anyhow::Result<Self> {
|
||||
let execution_view = cx.new_view(|cx| ExecutionView::new(status, cx));
|
||||
@ -73,7 +80,7 @@ impl EditorBlock {
|
||||
position: code_range.end,
|
||||
height: execution_view.num_lines(cx).saturating_add(1),
|
||||
style: BlockStyle::Sticky,
|
||||
render: Self::create_output_area_render(execution_view.clone()),
|
||||
render: Self::create_output_area_render(execution_view.clone(), on_close.clone()),
|
||||
disposition: BlockDisposition::Below,
|
||||
};
|
||||
|
||||
@ -87,6 +94,7 @@ impl EditorBlock {
|
||||
invalidation_anchor,
|
||||
block_id,
|
||||
execution_view,
|
||||
on_close,
|
||||
})
|
||||
}
|
||||
|
||||
@ -98,11 +106,15 @@ impl EditorBlock {
|
||||
self.editor
|
||||
.update(cx, |editor, cx| {
|
||||
let mut replacements = HashMap::default();
|
||||
|
||||
replacements.insert(
|
||||
self.block_id,
|
||||
(
|
||||
Some(self.execution_view.num_lines(cx).saturating_add(1)),
|
||||
Self::create_output_area_render(self.execution_view.clone()),
|
||||
Self::create_output_area_render(
|
||||
self.execution_view.clone(),
|
||||
self.on_close.clone(),
|
||||
),
|
||||
),
|
||||
);
|
||||
editor.replace_blocks(replacements, None, cx);
|
||||
@ -110,31 +122,74 @@ impl EditorBlock {
|
||||
.ok();
|
||||
}
|
||||
|
||||
fn create_output_area_render(execution_view: View<ExecutionView>) -> RenderBlock {
|
||||
fn create_output_area_render(
|
||||
execution_view: View<ExecutionView>,
|
||||
on_close: CloseBlockFn,
|
||||
) -> RenderBlock {
|
||||
let render = move |cx: &mut BlockContext| {
|
||||
let execution_view = execution_view.clone();
|
||||
let text_font = ThemeSettings::get_global(cx).buffer_font.family.clone();
|
||||
let text_font_size = ThemeSettings::get_global(cx).buffer_font_size;
|
||||
// Note: we'll want to use `cx.anchor_x` when someone runs something with no output -- just show a checkmark and not make the full block below the line
|
||||
|
||||
let gutter_width = cx.gutter_dimensions.width;
|
||||
let gutter = cx.gutter_dimensions;
|
||||
let close_button_size = IconSize::XSmall;
|
||||
|
||||
h_flex()
|
||||
let block_id = cx.block_id;
|
||||
let on_close = on_close.clone();
|
||||
|
||||
let rem_size = cx.rem_size();
|
||||
let line_height = cx.text_style().line_height_in_pixels(rem_size);
|
||||
|
||||
let (close_button_width, close_button_padding) =
|
||||
close_button_size.square_components(cx);
|
||||
|
||||
div()
|
||||
.min_h(line_height)
|
||||
.flex()
|
||||
.flex_row()
|
||||
.items_start()
|
||||
.w_full()
|
||||
.bg(cx.theme().colors().background)
|
||||
.border_y_1()
|
||||
.border_color(cx.theme().colors().border)
|
||||
.pl(gutter_width)
|
||||
.child(
|
||||
v_flex().min_h(cx.line_height()).justify_center().child(
|
||||
h_flex()
|
||||
.w(gutter.full_width())
|
||||
.justify_end()
|
||||
.pt(line_height / 2.)
|
||||
.child(
|
||||
h_flex()
|
||||
.pr(gutter.width / 2. - close_button_width
|
||||
+ close_button_padding / 2.)
|
||||
.child(
|
||||
IconButton::new(
|
||||
("close_output_area", EntityId::from(cx.block_id)),
|
||||
IconName::Close,
|
||||
)
|
||||
.shape(IconButtonShape::Square)
|
||||
.icon_size(close_button_size)
|
||||
.icon_color(Color::Muted)
|
||||
.tooltip(|cx| Tooltip::text("Close output area", cx))
|
||||
.on_click(
|
||||
move |_, cx| {
|
||||
if let BlockId::Custom(block_id) = block_id {
|
||||
(on_close)(block_id, cx)
|
||||
}
|
||||
},
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
)
|
||||
.child(
|
||||
div()
|
||||
.flex_1()
|
||||
.size_full()
|
||||
.my_2()
|
||||
.mr(gutter.width)
|
||||
.text_size(text_font_size)
|
||||
.font_family(text_font)
|
||||
// .ml(gutter_width)
|
||||
.mx_1()
|
||||
.my_2()
|
||||
.h_full()
|
||||
.w_full()
|
||||
.mr(gutter_width)
|
||||
.child(execution_view),
|
||||
)
|
||||
.into_any_element()
|
||||
@ -373,8 +428,30 @@ impl Session {
|
||||
Kernel::Shutdown => ExecutionStatus::Shutdown,
|
||||
};
|
||||
|
||||
let parent_message_id = message.header.msg_id.clone();
|
||||
let session_view = cx.view().downgrade();
|
||||
let weak_editor = self.editor.clone();
|
||||
|
||||
let on_close: CloseBlockFn =
|
||||
Arc::new(move |block_id: CustomBlockId, cx: &mut WindowContext| {
|
||||
if let Some(session) = session_view.upgrade() {
|
||||
session.update(cx, |session, cx| {
|
||||
session.blocks.remove(&parent_message_id);
|
||||
cx.notify();
|
||||
});
|
||||
}
|
||||
|
||||
if let Some(editor) = weak_editor.upgrade() {
|
||||
editor.update(cx, |editor, cx| {
|
||||
let mut block_ids = HashSet::default();
|
||||
block_ids.insert(block_id);
|
||||
editor.remove_blocks(block_ids, None, cx);
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
let editor_block = if let Ok(editor_block) =
|
||||
EditorBlock::new(self.editor.clone(), anchor_range, status, cx)
|
||||
EditorBlock::new(self.editor.clone(), anchor_range, status, on_close, cx)
|
||||
{
|
||||
editor_block
|
||||
} else {
|
||||
|
@ -76,8 +76,12 @@ impl IconSize {
|
||||
}
|
||||
}
|
||||
|
||||
/// Returns the length of a side of the square that contains this [`IconSize`], with padding.
|
||||
pub(crate) fn square(&self, cx: &mut WindowContext) -> Pixels {
|
||||
/// Returns the individual components of the square that contains this [`IconSize`].
|
||||
///
|
||||
/// The returned tuple contains:
|
||||
/// 1. The length of one side of the square
|
||||
/// 2. The padding of one side of the square
|
||||
pub fn square_components(&self, cx: &mut WindowContext) -> (Pixels, Pixels) {
|
||||
let icon_size = self.rems() * cx.rem_size();
|
||||
let padding = match self {
|
||||
IconSize::Indicator => Spacing::None.px(cx),
|
||||
@ -86,6 +90,13 @@ impl IconSize {
|
||||
IconSize::Medium => Spacing::XSmall.px(cx),
|
||||
};
|
||||
|
||||
(icon_size, padding)
|
||||
}
|
||||
|
||||
/// Returns the length of a side of the square that contains this [`IconSize`], with padding.
|
||||
pub fn square(&self, cx: &mut WindowContext) -> Pixels {
|
||||
let (icon_size, padding) = self.square_components(cx);
|
||||
|
||||
icon_size + padding * 2.
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user