Show annotations more like the inline assistant (#11530)

* compute gutter width
* show the AI icon
* borders, background, and text color for annotations

<img width="1840" alt="image"
src="https://github.com/zed-industries/zed/assets/836375/93f2e9b8-d7f7-4c25-b3e2-cf77a0c4ca36">

Release Notes:

- N/A
This commit is contained in:
Kyle Kelley 2024-05-07 19:16:35 -07:00 committed by GitHub
parent 1cf40d77e2
commit 6ddcff25e3
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
4 changed files with 49 additions and 29 deletions

View file

@ -14,51 +14,51 @@ use ui::prelude::*;
use util::ResultExt;
use workspace::Workspace;
pub struct OpenBufferTool {
pub struct AnnotationTool {
workspace: WeakView<Workspace>,
project: Model<Project>,
}
impl OpenBufferTool {
impl AnnotationTool {
pub fn new(workspace: WeakView<Workspace>, project: Model<Project>) -> Self {
Self { workspace, project }
}
}
#[derive(Debug, Deserialize, JsonSchema, Clone)]
pub struct ExplainInput {
/// Name for this set of excerpts
pub struct AnnotationInput {
/// Name for this set of annotations
title: String,
excerpts: Vec<ExplainedExcerpt>,
annotations: Vec<Annotation>,
}
#[derive(Debug, Deserialize, JsonSchema, Clone)]
struct ExplainedExcerpt {
struct Annotation {
/// Path to the file
path: String,
/// Name of a symbol in the buffer to show
/// Name of a symbol in the code
symbol_name: String,
/// Text to display near the symbol definition
comment: String,
text: String,
}
impl LanguageModelTool for OpenBufferTool {
type Input = ExplainInput;
impl LanguageModelTool for AnnotationTool {
type Input = AnnotationInput;
type Output = String;
type View = OpenBufferView;
type View = AnnotationResultView;
fn name(&self) -> String {
"explain_code".to_string()
"annotate_code".to_string()
}
fn description(&self) -> String {
"Show and explain one or more code snippets from files in the current project. Code snippets are identified using a file path and the name of a symbol defined in that file.".to_string()
"Dynamically annotate symbols in the current codebase. Opens a buffer in a panel in their editor, to the side of the conversation. The annotations are shown in the editor as a block decoration.".to_string()
}
fn execute(&self, input: &Self::Input, cx: &mut WindowContext) -> Task<Result<Self::Output>> {
let workspace = self.workspace.clone();
let project = self.project.clone();
let excerpts = input.excerpts.clone();
let excerpts = input.annotations.clone();
let title = input.title.clone();
let worktree_id = project.update(cx, |project, cx| {
@ -115,11 +115,11 @@ impl LanguageModelTool for OpenBufferTool {
cx,
)
});
let explanation = SharedString::from(excerpt.comment.clone());
let explanation = SharedString::from(excerpt.text.clone());
editor.insert_blocks(
[BlockProperties {
position: ranges[0].start,
height: 1,
height: 2,
style: BlockStyle::Fixed,
render: Box::new(move |cx| {
Self::render_note_block(&explanation, cx)
@ -149,21 +149,41 @@ impl LanguageModelTool for OpenBufferTool {
output: Result<Self::Output>,
cx: &mut WindowContext,
) -> View<Self::View> {
cx.new_view(|_cx| OpenBufferView { output })
cx.new_view(|_cx| AnnotationResultView { output })
}
}
impl OpenBufferTool {
fn render_note_block(explanation: &SharedString, _cx: &mut BlockContext) -> AnyElement {
div().child(explanation.clone()).into_any_element()
impl AnnotationTool {
fn render_note_block(explanation: &SharedString, cx: &mut BlockContext) -> AnyElement {
let anchor_x = cx.anchor_x;
let gutter_width = cx.gutter_dimensions.width;
h_flex()
.w_full()
.py_2()
.border_y_1()
.border_color(cx.theme().colors().border)
.child(
h_flex()
.justify_center()
.w(gutter_width)
.child(Icon::new(IconName::Ai).color(Color::Hint)),
)
.child(
h_flex()
.w_full()
.ml(anchor_x - gutter_width)
.child(explanation.clone()),
)
.into_any_element()
}
}
pub struct OpenBufferView {
pub struct AnnotationResultView {
output: Result<String>,
}
impl Render for OpenBufferView {
impl Render for AnnotationResultView {
fn render(&mut self, _cx: &mut ViewContext<Self>) -> impl IntoElement {
match &self.output {
Ok(output) => div().child(output.clone().into_any_element()),
@ -172,7 +192,7 @@ impl Render for OpenBufferView {
}
}
impl ToolOutput for OpenBufferView {
impl ToolOutput for AnnotationResultView {
fn generate(&self, _: &mut ProjectContext, _: &mut WindowContext) -> String {
match &self.output {
Ok(output) => output.clone(),