assistant: Improve discoverability of slash command errors (#13331)

https://github.com/zed-industries/zed/assets/53836821/fca5deef-3a4b-4670-8b92-79f052ea8417



Release Notes:

- N/A
This commit is contained in:
Bennet Bo Fenner 2024-06-20 21:39:53 +02:00 committed by GitHub
parent 58e9952d7b
commit 2c545ce0bc
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194

View File

@ -17,7 +17,9 @@ use client::telemetry::Telemetry;
use collections::{BTreeSet, HashMap, HashSet};
use editor::{
actions::{FoldAt, MoveToEndOfLine, Newline, ShowCompletions, UnfoldAt},
display_map::{BlockDisposition, BlockId, BlockProperties, BlockStyle, Crease, ToDisplayPoint},
display_map::{
BlockDisposition, BlockId, BlockProperties, BlockStyle, Crease, RenderBlock, ToDisplayPoint,
},
scroll::{Autoscroll, AutoscrollStrategy},
Anchor, Editor, EditorEvent, RowExt, ToOffset as _, ToPoint,
};
@ -2200,6 +2202,7 @@ pub struct ContextEditor {
blocks: HashSet<BlockId>,
scroll_position: Option<ScrollPosition>,
pending_slash_command_creases: HashMap<Range<language::Anchor>, CreaseId>,
pending_slash_command_blocks: HashMap<Range<language::Anchor>, BlockId>,
_subscriptions: Vec<Subscription>,
}
@ -2273,6 +2276,7 @@ impl ContextEditor {
fs,
workspace: workspace.downgrade(),
pending_slash_command_creases: HashMap::default(),
pending_slash_command_blocks: HashMap::default(),
_subscriptions,
};
this.update_message_headers(cx);
@ -2534,7 +2538,8 @@ impl ContextEditor {
ContextEvent::PendingSlashCommandsUpdated { removed, updated } => {
self.editor.update(cx, |editor, cx| {
let buffer = editor.buffer().read(cx).snapshot(cx);
let excerpt_id = *buffer.as_singleton().unwrap().0;
let (excerpt_id, buffer_id, _) = buffer.as_singleton().unwrap();
let excerpt_id = *excerpt_id;
editor.remove_creases(
removed
@ -2543,6 +2548,16 @@ impl ContextEditor {
cx,
);
editor.remove_blocks(
HashSet::from_iter(
removed.iter().filter_map(|range| {
self.pending_slash_command_blocks.remove(range)
}),
),
None,
cx,
);
let crease_ids = editor.insert_creases(
updated.iter().map(|command| {
let workspace = self.workspace.clone();
@ -2575,7 +2590,7 @@ impl ContextEditor {
move |row, _, _, _cx: &mut WindowContext| {
render_pending_slash_command_gutter_decoration(
row,
command.status.clone(),
&command.status,
confirm_command.clone(),
)
}
@ -2609,12 +2624,43 @@ impl ContextEditor {
cx,
);
let block_ids = editor.insert_blocks(
updated
.iter()
.filter_map(|command| match &command.status {
PendingSlashCommandStatus::Error(error) => {
Some((command, error.clone()))
}
_ => None,
})
.map(|(command, error_message)| BlockProperties {
style: BlockStyle::Fixed,
position: Anchor {
buffer_id: Some(buffer_id),
excerpt_id,
text_anchor: command.source_range.start,
},
height: 1,
disposition: BlockDisposition::Below,
render: slash_command_error_block_renderer(error_message),
}),
None,
cx,
);
self.pending_slash_command_creases.extend(
updated
.iter()
.map(|command| command.source_range.clone())
.zip(crease_ids),
);
self.pending_slash_command_blocks.extend(
updated
.iter()
.map(|command| command.source_range.clone())
.zip(block_ids),
);
})
}
ContextEvent::SlashCommandFinished {
@ -3204,7 +3250,7 @@ fn render_slash_command_output_toggle(
fn render_pending_slash_command_gutter_decoration(
row: MultiBufferRow,
status: PendingSlashCommandStatus,
status: &PendingSlashCommandStatus,
confirm_command: Arc<dyn Fn(&mut WindowContext)>,
) -> AnyElement {
let mut icon = IconButton::new(
@ -3222,11 +3268,7 @@ fn render_pending_slash_command_gutter_decoration(
PendingSlashCommandStatus::Running { .. } => {
icon = icon.selected(true);
}
PendingSlashCommandStatus::Error(error) => {
icon = icon
.icon_color(Color::Error)
.tooltip(move |cx| Tooltip::text(format!("error: {error}"), cx));
}
PendingSlashCommandStatus::Error(_) => icon = icon.icon_color(Color::Error),
}
icon.into_any_element()
@ -3277,6 +3319,19 @@ fn make_lsp_adapter_delegate(
})
}
fn slash_command_error_block_renderer(message: String) -> RenderBlock {
Box::new(move |_| {
div()
.pl_6()
.child(
Label::new(format!("error: {}", message))
.single_line()
.color(Color::Error),
)
.into_any()
})
}
#[cfg(test)]
mod tests {
use super::*;