Make slash command output streamable (#19632)
This PR adds support for streaming output from slash commands In this PR we are focused primarily on the interface of the `SlashCommand` trait to support streaming the output. We will follow up later with support for extensions and context servers to take advantage of the streaming nature. Release Notes: - N/A --------- Co-authored-by: David Soria Parra <davidsp@anthropic.com> Co-authored-by: Antonio Scandurra <me@as-cii.com> Co-authored-by: David <david@anthropic.com> Co-authored-by: Antonio <antonio@zed.dev> Co-authored-by: Max <max@zed.dev> Co-authored-by: Max Brunsfeld <maxbrunsfeld@gmail.com> Co-authored-by: Will <will@zed.dev>
This commit is contained in:
parent
f6fbf662b4
commit
b129e18396
14 changed files with 1130 additions and 501 deletions
|
@ -36,7 +36,7 @@ use block_map::{BlockRow, BlockSnapshot};
|
|||
use collections::{HashMap, HashSet};
|
||||
pub use crease_map::*;
|
||||
pub use fold_map::{Fold, FoldId, FoldPlaceholder, FoldPoint};
|
||||
use fold_map::{FoldMap, FoldSnapshot};
|
||||
use fold_map::{FoldMap, FoldMapWriter, FoldOffset, FoldSnapshot};
|
||||
use gpui::{
|
||||
AnyElement, Font, HighlightStyle, LineLayout, Model, ModelContext, Pixels, UnderlineStyle,
|
||||
};
|
||||
|
@ -65,7 +65,7 @@ use std::{
|
|||
};
|
||||
use sum_tree::{Bias, TreeMap};
|
||||
use tab_map::{TabMap, TabSnapshot};
|
||||
use text::LineIndent;
|
||||
use text::{Edit, LineIndent};
|
||||
use ui::{div, px, IntoElement, ParentElement, SharedString, Styled, WindowContext};
|
||||
use unicode_segmentation::UnicodeSegmentation;
|
||||
use wrap_map::{WrapMap, WrapSnapshot};
|
||||
|
@ -206,34 +206,41 @@ impl DisplayMap {
|
|||
);
|
||||
}
|
||||
|
||||
/// Creates folds for the given ranges.
|
||||
pub fn fold<T: ToOffset>(
|
||||
&mut self,
|
||||
ranges: impl IntoIterator<Item = (Range<T>, FoldPlaceholder)>,
|
||||
cx: &mut ModelContext<Self>,
|
||||
) {
|
||||
let snapshot = self.buffer.read(cx).snapshot(cx);
|
||||
let edits = self.buffer_subscription.consume().into_inner();
|
||||
let tab_size = Self::tab_size(&self.buffer, cx);
|
||||
let (snapshot, edits) = self.inlay_map.sync(snapshot, edits);
|
||||
let (mut fold_map, snapshot, edits) = self.fold_map.write(snapshot, edits);
|
||||
let (snapshot, edits) = self.tab_map.sync(snapshot, edits, tab_size);
|
||||
let (snapshot, edits) = self
|
||||
.wrap_map
|
||||
.update(cx, |map, cx| map.sync(snapshot, edits, cx));
|
||||
self.block_map.read(snapshot, edits);
|
||||
let (snapshot, edits) = fold_map.fold(ranges);
|
||||
let (snapshot, edits) = self.tab_map.sync(snapshot, edits, tab_size);
|
||||
let (snapshot, edits) = self
|
||||
.wrap_map
|
||||
.update(cx, |map, cx| map.sync(snapshot, edits, cx));
|
||||
self.block_map.read(snapshot, edits);
|
||||
self.update_fold_map(cx, |fold_map| fold_map.fold(ranges))
|
||||
}
|
||||
|
||||
pub fn unfold<T: ToOffset>(
|
||||
/// Removes any folds with the given ranges.
|
||||
pub fn remove_folds_with_type<T: ToOffset>(
|
||||
&mut self,
|
||||
ranges: impl IntoIterator<Item = Range<T>>,
|
||||
type_id: TypeId,
|
||||
cx: &mut ModelContext<Self>,
|
||||
) {
|
||||
self.update_fold_map(cx, |fold_map| fold_map.remove_folds(ranges, type_id))
|
||||
}
|
||||
|
||||
/// Removes any folds whose ranges intersect any of the given ranges.
|
||||
pub fn unfold_intersecting<T: ToOffset>(
|
||||
&mut self,
|
||||
ranges: impl IntoIterator<Item = Range<T>>,
|
||||
inclusive: bool,
|
||||
cx: &mut ModelContext<Self>,
|
||||
) {
|
||||
self.update_fold_map(cx, |fold_map| {
|
||||
fold_map.unfold_intersecting(ranges, inclusive)
|
||||
})
|
||||
}
|
||||
|
||||
fn update_fold_map(
|
||||
&mut self,
|
||||
cx: &mut ModelContext<Self>,
|
||||
callback: impl FnOnce(&mut FoldMapWriter) -> (FoldSnapshot, Vec<Edit<FoldOffset>>),
|
||||
) {
|
||||
let snapshot = self.buffer.read(cx).snapshot(cx);
|
||||
let edits = self.buffer_subscription.consume().into_inner();
|
||||
|
@ -245,7 +252,7 @@ impl DisplayMap {
|
|||
.wrap_map
|
||||
.update(cx, |map, cx| map.sync(snapshot, edits, cx));
|
||||
self.block_map.read(snapshot, edits);
|
||||
let (snapshot, edits) = fold_map.unfold(ranges, inclusive);
|
||||
let (snapshot, edits) = callback(&mut fold_map);
|
||||
let (snapshot, edits) = self.tab_map.sync(snapshot, edits, tab_size);
|
||||
let (snapshot, edits) = self
|
||||
.wrap_map
|
||||
|
@ -1442,7 +1449,7 @@ pub mod tests {
|
|||
if rng.gen() && fold_count > 0 {
|
||||
log::info!("unfolding ranges: {:?}", ranges);
|
||||
map.update(cx, |map, cx| {
|
||||
map.unfold(ranges, true, cx);
|
||||
map.unfold_intersecting(ranges, true, cx);
|
||||
});
|
||||
} else {
|
||||
log::info!("folding ranges: {:?}", ranges);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue