create_buffer.rs

  1use anyhow::Result;
  2use assistant_tooling::LanguageModelTool;
  3use editor::Editor;
  4use gpui::{prelude::*, Model, Task, View, WeakView};
  5use project::Project;
  6use schemars::JsonSchema;
  7use serde::Deserialize;
  8use ui::prelude::*;
  9use util::ResultExt;
 10use workspace::Workspace;
 11
 12pub struct CreateBufferTool {
 13    workspace: WeakView<Workspace>,
 14    project: Model<Project>,
 15}
 16
 17impl CreateBufferTool {
 18    pub fn new(workspace: WeakView<Workspace>, project: Model<Project>) -> Self {
 19        Self { workspace, project }
 20    }
 21}
 22
 23#[derive(Debug, Deserialize, JsonSchema)]
 24pub struct CreateBufferInput {
 25    /// The contents of the buffer.
 26    text: String,
 27
 28    /// The name of the language to use for the buffer.
 29    ///
 30    /// This should be a human-readable name, like "Rust", "JavaScript", or "Python".
 31    language: String,
 32}
 33
 34pub struct CreateBufferOutput {}
 35
 36impl LanguageModelTool for CreateBufferTool {
 37    type Input = CreateBufferInput;
 38    type Output = CreateBufferOutput;
 39    type View = CreateBufferView;
 40
 41    fn name(&self) -> String {
 42        "create_buffer".to_string()
 43    }
 44
 45    fn description(&self) -> String {
 46        "Create a new buffer in the current codebase".to_string()
 47    }
 48
 49    fn execute(&self, input: &Self::Input, cx: &mut WindowContext) -> Task<Result<Self::Output>> {
 50        cx.spawn({
 51            let workspace = self.workspace.clone();
 52            let project = self.project.clone();
 53            let text = input.text.clone();
 54            let language_name = input.language.clone();
 55            |mut cx| async move {
 56                let language = cx
 57                    .update(|cx| {
 58                        project
 59                            .read(cx)
 60                            .languages()
 61                            .language_for_name(&language_name)
 62                    })?
 63                    .await?;
 64
 65                let buffer = cx
 66                    .update(|cx| project.update(cx, |project, cx| project.create_buffer(cx)))?
 67                    .await?;
 68
 69                buffer.update(&mut cx, |buffer, cx| {
 70                    buffer.edit([(0..0, text)], None, cx);
 71                    buffer.set_language(Some(language), cx)
 72                })?;
 73
 74                workspace
 75                    .update(&mut cx, |workspace, cx| {
 76                        workspace.add_item_to_active_pane(
 77                            Box::new(
 78                                cx.new_view(|cx| Editor::for_buffer(buffer, Some(project), cx)),
 79                            ),
 80                            None,
 81                            cx,
 82                        );
 83                    })
 84                    .log_err();
 85
 86                Ok(CreateBufferOutput {})
 87            }
 88        })
 89    }
 90
 91    fn format(input: &Self::Input, output: &Result<Self::Output>) -> String {
 92        match output {
 93            Ok(_) => format!("Created a new {} buffer", input.language),
 94            Err(err) => format!("Failed to create buffer: {err:?}"),
 95        }
 96    }
 97
 98    fn output_view(
 99        _tool_call_id: String,
100        _input: Self::Input,
101        _output: Result<Self::Output>,
102        cx: &mut WindowContext,
103    ) -> View<Self::View> {
104        cx.new_view(|_cx| CreateBufferView {})
105    }
106}
107
108pub struct CreateBufferView {}
109
110impl Render for CreateBufferView {
111    fn render(&mut self, _cx: &mut ViewContext<Self>) -> impl IntoElement {
112        div().child("Opening a buffer")
113    }
114}