mirror of
https://github.com/zed-industries/zed.git
synced 2024-09-19 10:29:35 +03:00
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:
parent
58e9952d7b
commit
2c545ce0bc
@ -17,7 +17,9 @@ use client::telemetry::Telemetry;
|
|||||||
use collections::{BTreeSet, HashMap, HashSet};
|
use collections::{BTreeSet, HashMap, HashSet};
|
||||||
use editor::{
|
use editor::{
|
||||||
actions::{FoldAt, MoveToEndOfLine, Newline, ShowCompletions, UnfoldAt},
|
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},
|
scroll::{Autoscroll, AutoscrollStrategy},
|
||||||
Anchor, Editor, EditorEvent, RowExt, ToOffset as _, ToPoint,
|
Anchor, Editor, EditorEvent, RowExt, ToOffset as _, ToPoint,
|
||||||
};
|
};
|
||||||
@ -2200,6 +2202,7 @@ pub struct ContextEditor {
|
|||||||
blocks: HashSet<BlockId>,
|
blocks: HashSet<BlockId>,
|
||||||
scroll_position: Option<ScrollPosition>,
|
scroll_position: Option<ScrollPosition>,
|
||||||
pending_slash_command_creases: HashMap<Range<language::Anchor>, CreaseId>,
|
pending_slash_command_creases: HashMap<Range<language::Anchor>, CreaseId>,
|
||||||
|
pending_slash_command_blocks: HashMap<Range<language::Anchor>, BlockId>,
|
||||||
_subscriptions: Vec<Subscription>,
|
_subscriptions: Vec<Subscription>,
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2273,6 +2276,7 @@ impl ContextEditor {
|
|||||||
fs,
|
fs,
|
||||||
workspace: workspace.downgrade(),
|
workspace: workspace.downgrade(),
|
||||||
pending_slash_command_creases: HashMap::default(),
|
pending_slash_command_creases: HashMap::default(),
|
||||||
|
pending_slash_command_blocks: HashMap::default(),
|
||||||
_subscriptions,
|
_subscriptions,
|
||||||
};
|
};
|
||||||
this.update_message_headers(cx);
|
this.update_message_headers(cx);
|
||||||
@ -2534,7 +2538,8 @@ impl ContextEditor {
|
|||||||
ContextEvent::PendingSlashCommandsUpdated { removed, updated } => {
|
ContextEvent::PendingSlashCommandsUpdated { removed, updated } => {
|
||||||
self.editor.update(cx, |editor, cx| {
|
self.editor.update(cx, |editor, cx| {
|
||||||
let buffer = editor.buffer().read(cx).snapshot(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(
|
editor.remove_creases(
|
||||||
removed
|
removed
|
||||||
@ -2543,6 +2548,16 @@ impl ContextEditor {
|
|||||||
cx,
|
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(
|
let crease_ids = editor.insert_creases(
|
||||||
updated.iter().map(|command| {
|
updated.iter().map(|command| {
|
||||||
let workspace = self.workspace.clone();
|
let workspace = self.workspace.clone();
|
||||||
@ -2575,7 +2590,7 @@ impl ContextEditor {
|
|||||||
move |row, _, _, _cx: &mut WindowContext| {
|
move |row, _, _, _cx: &mut WindowContext| {
|
||||||
render_pending_slash_command_gutter_decoration(
|
render_pending_slash_command_gutter_decoration(
|
||||||
row,
|
row,
|
||||||
command.status.clone(),
|
&command.status,
|
||||||
confirm_command.clone(),
|
confirm_command.clone(),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
@ -2609,12 +2624,43 @@ impl ContextEditor {
|
|||||||
cx,
|
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(
|
self.pending_slash_command_creases.extend(
|
||||||
updated
|
updated
|
||||||
.iter()
|
.iter()
|
||||||
.map(|command| command.source_range.clone())
|
.map(|command| command.source_range.clone())
|
||||||
.zip(crease_ids),
|
.zip(crease_ids),
|
||||||
);
|
);
|
||||||
|
|
||||||
|
self.pending_slash_command_blocks.extend(
|
||||||
|
updated
|
||||||
|
.iter()
|
||||||
|
.map(|command| command.source_range.clone())
|
||||||
|
.zip(block_ids),
|
||||||
|
);
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
ContextEvent::SlashCommandFinished {
|
ContextEvent::SlashCommandFinished {
|
||||||
@ -3204,7 +3250,7 @@ fn render_slash_command_output_toggle(
|
|||||||
|
|
||||||
fn render_pending_slash_command_gutter_decoration(
|
fn render_pending_slash_command_gutter_decoration(
|
||||||
row: MultiBufferRow,
|
row: MultiBufferRow,
|
||||||
status: PendingSlashCommandStatus,
|
status: &PendingSlashCommandStatus,
|
||||||
confirm_command: Arc<dyn Fn(&mut WindowContext)>,
|
confirm_command: Arc<dyn Fn(&mut WindowContext)>,
|
||||||
) -> AnyElement {
|
) -> AnyElement {
|
||||||
let mut icon = IconButton::new(
|
let mut icon = IconButton::new(
|
||||||
@ -3222,11 +3268,7 @@ fn render_pending_slash_command_gutter_decoration(
|
|||||||
PendingSlashCommandStatus::Running { .. } => {
|
PendingSlashCommandStatus::Running { .. } => {
|
||||||
icon = icon.selected(true);
|
icon = icon.selected(true);
|
||||||
}
|
}
|
||||||
PendingSlashCommandStatus::Error(error) => {
|
PendingSlashCommandStatus::Error(_) => icon = icon.icon_color(Color::Error),
|
||||||
icon = icon
|
|
||||||
.icon_color(Color::Error)
|
|
||||||
.tooltip(move |cx| Tooltip::text(format!("error: {error}"), cx));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
icon.into_any_element()
|
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)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use super::*;
|
use super::*;
|
||||||
|
Loading…
Reference in New Issue
Block a user