Add a workflow step resolution view (#16315)

You can now click on a step header (the words `Step 3`, etc) to open a
new tab containing a dedicated view for the resolution of that step.
This view looks similar to a context editor, and has sections for the
step input, the streaming tool output, and the interpreted results.

Hitting `cmd-enter` in this view re-resolves the step.


https://github.com/user-attachments/assets/64d82cdb-e70f-4204-8697-b30df5a645d5



Release Notes:

- N/A

---------

Co-authored-by: Nathan <nathan@zed.dev>
This commit is contained in:
Max Brunsfeld 2024-08-15 14:16:58 -07:00 committed by GitHub
parent 583959f82a
commit 776442f3ae
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
7 changed files with 525 additions and 79 deletions

View file

@ -71,7 +71,7 @@ pub use language_registry::{
PendingLanguageServer, QUERY_FILENAME_PREFIXES,
};
pub use lsp::LanguageServerId;
pub use outline::{render_item, Outline, OutlineItem};
pub use outline::*;
pub use syntax_map::{OwnedSyntaxLayer, SyntaxLayer};
pub use text::{AnchorRangeExt, LineEnding};
pub use tree_sitter::{Node, Parser, Tree, TreeCursor};

View file

@ -25,6 +25,9 @@ pub struct OutlineItem<T> {
pub annotation_range: Option<Range<T>>,
}
#[derive(Clone, Debug, Eq, PartialEq)]
pub struct SymbolPath(pub String);
impl<T: ToPoint> OutlineItem<T> {
/// Converts to an equivalent outline item, but with parameterized over Points.
pub fn to_point(&self, buffer: &BufferSnapshot) -> OutlineItem<Point> {
@ -85,7 +88,7 @@ impl<T> Outline<T> {
}
/// Find the most similar symbol to the provided query using normalized Levenshtein distance.
pub fn find_most_similar(&self, query: &str) -> Option<&OutlineItem<T>> {
pub fn find_most_similar(&self, query: &str) -> Option<(SymbolPath, &OutlineItem<T>)> {
const SIMILARITY_THRESHOLD: f64 = 0.6;
let (position, similarity) = self
@ -99,8 +102,10 @@ impl<T> Outline<T> {
.max_by(|(_, a), (_, b)| a.partial_cmp(b).unwrap())?;
if similarity >= SIMILARITY_THRESHOLD {
let item = self.items.get(position)?;
Some(item)
self.path_candidates
.get(position)
.map(|candidate| SymbolPath(candidate.string.clone()))
.zip(self.items.get(position))
} else {
None
}
@ -250,15 +255,15 @@ mod tests {
]);
assert_eq!(
outline.find_most_similar("pub fn process"),
Some(&outline.items[0])
Some((SymbolPath("fn process".into()), &outline.items[0]))
);
assert_eq!(
outline.find_most_similar("async fn process"),
Some(&outline.items[0])
Some((SymbolPath("fn process".into()), &outline.items[0])),
);
assert_eq!(
outline.find_most_similar("struct Processor"),
Some(&outline.items[1])
Some((SymbolPath("struct DataProcessor".into()), &outline.items[1]))
);
assert_eq!(outline.find_most_similar("struct User"), None);
assert_eq!(outline.find_most_similar("struct"), None);