agent: Adjust codeblock design across edit file tool call card and Markdown (#30931)
This PR makes the edit tool call codeblock cards expanded by default, to be consistent with https://github.com/zed-industries/zed/pull/30806. Also, I am removing the collapsing behavior of Markdown codeblocks where we'd add a gradient while capping the container's height based on an arbitrary number of lines. Figured if they're all now initially expanded, we could simplify how the design/code operates here altogether. Open for feedback, as I can see an argument where the previous Markdown codeblock design of "collapsed but not fully; it shows a preview" should stay as it is useful. Release Notes: - N/A
This commit is contained in:
parent
a829281841
commit
e1a2e8a3aa
2 changed files with 55 additions and 75 deletions
|
@ -333,7 +333,6 @@ fn tool_use_markdown_style(window: &Window, cx: &mut App) -> MarkdownStyle {
|
||||||
}
|
}
|
||||||
|
|
||||||
const CODEBLOCK_CONTAINER_GROUP: &str = "codeblock_container";
|
const CODEBLOCK_CONTAINER_GROUP: &str = "codeblock_container";
|
||||||
const MAX_UNCOLLAPSED_LINES_IN_CODE_BLOCK: usize = 10;
|
|
||||||
|
|
||||||
fn render_markdown_code_block(
|
fn render_markdown_code_block(
|
||||||
message_id: MessageId,
|
message_id: MessageId,
|
||||||
|
@ -346,17 +345,20 @@ fn render_markdown_code_block(
|
||||||
_window: &Window,
|
_window: &Window,
|
||||||
cx: &App,
|
cx: &App,
|
||||||
) -> Div {
|
) -> Div {
|
||||||
|
let label_size = rems(0.8125);
|
||||||
|
|
||||||
let label = match kind {
|
let label = match kind {
|
||||||
CodeBlockKind::Indented => None,
|
CodeBlockKind::Indented => None,
|
||||||
CodeBlockKind::Fenced => Some(
|
CodeBlockKind::Fenced => Some(
|
||||||
h_flex()
|
h_flex()
|
||||||
|
.px_1()
|
||||||
.gap_1()
|
.gap_1()
|
||||||
.child(
|
.child(
|
||||||
Icon::new(IconName::Code)
|
Icon::new(IconName::Code)
|
||||||
.color(Color::Muted)
|
.color(Color::Muted)
|
||||||
.size(IconSize::XSmall),
|
.size(IconSize::XSmall),
|
||||||
)
|
)
|
||||||
.child(Label::new("untitled").size(LabelSize::Small))
|
.child(div().text_size(label_size).child("Plain Text"))
|
||||||
.into_any_element(),
|
.into_any_element(),
|
||||||
),
|
),
|
||||||
CodeBlockKind::FencedLang(raw_language_name) => Some(render_code_language(
|
CodeBlockKind::FencedLang(raw_language_name) => Some(render_code_language(
|
||||||
|
@ -393,7 +395,7 @@ fn render_markdown_code_block(
|
||||||
.id(("code-block-header-label", ix))
|
.id(("code-block-header-label", ix))
|
||||||
.ml_1()
|
.ml_1()
|
||||||
.gap_1()
|
.gap_1()
|
||||||
.child(Label::new(file_name).size(LabelSize::Small))
|
.child(div().text_size(label_size).child(file_name))
|
||||||
.child(Label::new(path).color(Color::Muted).size(LabelSize::Small))
|
.child(Label::new(path).color(Color::Muted).size(LabelSize::Small))
|
||||||
.tooltip(move |window, cx| {
|
.tooltip(move |window, cx| {
|
||||||
Tooltip::with_meta(
|
Tooltip::with_meta(
|
||||||
|
@ -406,9 +408,10 @@ fn render_markdown_code_block(
|
||||||
})
|
})
|
||||||
.into_any_element()
|
.into_any_element()
|
||||||
} else {
|
} else {
|
||||||
Label::new(path_range.path.to_string_lossy().to_string())
|
div()
|
||||||
.size(LabelSize::Small)
|
|
||||||
.ml_1()
|
.ml_1()
|
||||||
|
.text_size(label_size)
|
||||||
|
.child(path_range.path.to_string_lossy().to_string())
|
||||||
.into_any_element()
|
.into_any_element()
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -456,19 +459,13 @@ fn render_markdown_code_block(
|
||||||
.copied_code_block_ids
|
.copied_code_block_ids
|
||||||
.contains(&(message_id, ix));
|
.contains(&(message_id, ix));
|
||||||
|
|
||||||
let can_expand = metadata.line_count >= MAX_UNCOLLAPSED_LINES_IN_CODE_BLOCK;
|
let is_expanded = active_thread.read(cx).is_codeblock_expanded(message_id, ix);
|
||||||
|
|
||||||
let is_expanded = if can_expand {
|
|
||||||
active_thread.read(cx).is_codeblock_expanded(message_id, ix)
|
|
||||||
} else {
|
|
||||||
false
|
|
||||||
};
|
|
||||||
|
|
||||||
let codeblock_header_bg = cx
|
let codeblock_header_bg = cx
|
||||||
.theme()
|
.theme()
|
||||||
.colors()
|
.colors()
|
||||||
.element_background
|
.element_background
|
||||||
.blend(cx.theme().colors().editor_foreground.opacity(0.01));
|
.blend(cx.theme().colors().editor_foreground.opacity(0.025));
|
||||||
|
|
||||||
let control_buttons = h_flex()
|
let control_buttons = h_flex()
|
||||||
.visible_on_hover(CODEBLOCK_CONTAINER_GROUP)
|
.visible_on_hover(CODEBLOCK_CONTAINER_GROUP)
|
||||||
|
@ -519,44 +516,48 @@ fn render_markdown_code_block(
|
||||||
}
|
}
|
||||||
}),
|
}),
|
||||||
)
|
)
|
||||||
.when(can_expand, |header| {
|
.child(
|
||||||
header.child(
|
IconButton::new(
|
||||||
IconButton::new(
|
("expand-collapse-code", ix),
|
||||||
("expand-collapse-code", ix),
|
if is_expanded {
|
||||||
if is_expanded {
|
IconName::ChevronUp
|
||||||
IconName::ChevronUp
|
|
||||||
} else {
|
|
||||||
IconName::ChevronDown
|
|
||||||
},
|
|
||||||
)
|
|
||||||
.icon_color(Color::Muted)
|
|
||||||
.shape(ui::IconButtonShape::Square)
|
|
||||||
.tooltip(Tooltip::text(if is_expanded {
|
|
||||||
"Collapse Code"
|
|
||||||
} else {
|
} else {
|
||||||
"Expand Code"
|
IconName::ChevronDown
|
||||||
}))
|
},
|
||||||
.on_click({
|
|
||||||
let active_thread = active_thread.clone();
|
|
||||||
move |_event, _window, cx| {
|
|
||||||
active_thread.update(cx, |this, cx| {
|
|
||||||
this.toggle_codeblock_expanded(message_id, ix);
|
|
||||||
cx.notify();
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}),
|
|
||||||
)
|
)
|
||||||
});
|
.icon_color(Color::Muted)
|
||||||
|
.shape(ui::IconButtonShape::Square)
|
||||||
|
.tooltip(Tooltip::text(if is_expanded {
|
||||||
|
"Collapse Code"
|
||||||
|
} else {
|
||||||
|
"Expand Code"
|
||||||
|
}))
|
||||||
|
.on_click({
|
||||||
|
let active_thread = active_thread.clone();
|
||||||
|
move |_event, _window, cx| {
|
||||||
|
active_thread.update(cx, |this, cx| {
|
||||||
|
this.toggle_codeblock_expanded(message_id, ix);
|
||||||
|
cx.notify();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}),
|
||||||
|
);
|
||||||
|
|
||||||
let codeblock_header = h_flex()
|
let codeblock_header = h_flex()
|
||||||
.relative()
|
.relative()
|
||||||
.p_1()
|
.p_1()
|
||||||
.gap_1()
|
.gap_1()
|
||||||
.justify_between()
|
.justify_between()
|
||||||
.border_b_1()
|
|
||||||
.border_color(cx.theme().colors().border.opacity(0.6))
|
|
||||||
.bg(codeblock_header_bg)
|
.bg(codeblock_header_bg)
|
||||||
.rounded_t_md()
|
.map(|this| {
|
||||||
|
if !is_expanded {
|
||||||
|
this.rounded_md()
|
||||||
|
} else {
|
||||||
|
this.rounded_t_md()
|
||||||
|
.border_b_1()
|
||||||
|
.border_color(cx.theme().colors().border.opacity(0.6))
|
||||||
|
}
|
||||||
|
})
|
||||||
.children(label)
|
.children(label)
|
||||||
.child(control_buttons);
|
.child(control_buttons);
|
||||||
|
|
||||||
|
@ -564,12 +565,12 @@ fn render_markdown_code_block(
|
||||||
.group(CODEBLOCK_CONTAINER_GROUP)
|
.group(CODEBLOCK_CONTAINER_GROUP)
|
||||||
.my_2()
|
.my_2()
|
||||||
.overflow_hidden()
|
.overflow_hidden()
|
||||||
.rounded_lg()
|
.rounded_md()
|
||||||
.border_1()
|
.border_1()
|
||||||
.border_color(cx.theme().colors().border.opacity(0.6))
|
.border_color(cx.theme().colors().border.opacity(0.6))
|
||||||
.bg(cx.theme().colors().editor_background)
|
.bg(cx.theme().colors().editor_background)
|
||||||
.child(codeblock_header)
|
.child(codeblock_header)
|
||||||
.when(can_expand && !is_expanded, |this| this.max_h_80())
|
.when(!is_expanded, |this| this.h(rems_from_px(31.)))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn open_path(
|
fn open_path(
|
||||||
|
@ -630,10 +631,13 @@ fn render_code_language(
|
||||||
.map(|language| language.name().into())
|
.map(|language| language.name().into())
|
||||||
.unwrap_or(name_fallback);
|
.unwrap_or(name_fallback);
|
||||||
|
|
||||||
|
let label_size = rems(0.8125);
|
||||||
|
|
||||||
h_flex()
|
h_flex()
|
||||||
.gap_1()
|
.px_1()
|
||||||
.children(icon_path.map(|icon| icon.color(Color::Muted).size(IconSize::Small)))
|
.gap_1p5()
|
||||||
.child(Label::new(language_label).size(LabelSize::Small))
|
.children(icon_path.map(|icon| icon.color(Color::Muted).size(IconSize::XSmall)))
|
||||||
|
.child(div().text_size(label_size).child(language_label))
|
||||||
.into_any_element()
|
.into_any_element()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2369,41 +2373,17 @@ impl ActiveThread {
|
||||||
}),
|
}),
|
||||||
transform: Some(Arc::new({
|
transform: Some(Arc::new({
|
||||||
let active_thread = cx.entity();
|
let active_thread = cx.entity();
|
||||||
let editor_bg = cx.theme().colors().editor_background;
|
|
||||||
|
|
||||||
move |el, range, metadata, _, cx| {
|
|
||||||
let can_expand = metadata.line_count
|
|
||||||
>= MAX_UNCOLLAPSED_LINES_IN_CODE_BLOCK;
|
|
||||||
|
|
||||||
if !can_expand {
|
|
||||||
return el;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
move |element, range, _, _, cx| {
|
||||||
let is_expanded = active_thread
|
let is_expanded = active_thread
|
||||||
.read(cx)
|
.read(cx)
|
||||||
.is_codeblock_expanded(message_id, range.start);
|
.is_codeblock_expanded(message_id, range.start);
|
||||||
|
|
||||||
if is_expanded {
|
if is_expanded {
|
||||||
return el;
|
return element;
|
||||||
}
|
}
|
||||||
|
|
||||||
el.child(
|
element
|
||||||
div()
|
|
||||||
.absolute()
|
|
||||||
.bottom_0()
|
|
||||||
.left_0()
|
|
||||||
.w_full()
|
|
||||||
.h_1_4()
|
|
||||||
.rounded_b_lg()
|
|
||||||
.bg(linear_gradient(
|
|
||||||
0.,
|
|
||||||
linear_color_stop(editor_bg, 0.),
|
|
||||||
linear_color_stop(
|
|
||||||
editor_bg.opacity(0.),
|
|
||||||
1.,
|
|
||||||
),
|
|
||||||
)),
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
})),
|
})),
|
||||||
},
|
},
|
||||||
|
|
|
@ -400,7 +400,7 @@ impl EditFileToolCard {
|
||||||
diff_task: None,
|
diff_task: None,
|
||||||
preview_expanded: true,
|
preview_expanded: true,
|
||||||
error_expanded: None,
|
error_expanded: None,
|
||||||
full_height_expanded: false,
|
full_height_expanded: true,
|
||||||
total_lines: None,
|
total_lines: None,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue