Start on a refactoring assistant

Antonio Scandurra created

Change summary

crates/ai/src/ai.rs       |  1 
crates/ai/src/refactor.rs | 88 +++++++++++++++++++++++++++++++++++++++++
prompt.md                 | 11 +++++
3 files changed, 100 insertions(+)

Detailed changes

crates/ai/src/ai.rs 🔗

@@ -1,5 +1,6 @@
 pub mod assistant;
 mod assistant_settings;
+mod refactor;
 
 use anyhow::Result;
 pub use assistant::AssistantPanel;

crates/ai/src/refactor.rs 🔗

@@ -0,0 +1,88 @@
+use collections::HashMap;
+use editor::Editor;
+use gpui::{
+    actions, elements::*, AnyViewHandle, AppContext, Entity, Task, View, ViewContext, ViewHandle,
+};
+use std::sync::Arc;
+use workspace::{Modal, Workspace};
+
+actions!(assistant, [Refactor]);
+
+fn init(cx: &mut AppContext) {
+    cx.set_global(RefactoringAssistant::new());
+    cx.add_action(RefactoringModal::deploy);
+}
+
+pub struct RefactoringAssistant {
+    pending_edits_by_editor: HashMap<usize, Task<Option<()>>>,
+}
+
+impl RefactoringAssistant {
+    fn new() -> Self {
+        Self {
+            pending_edits_by_editor: Default::default(),
+        }
+    }
+
+    fn refactor(&mut self, editor: &ViewHandle<Editor>, prompt: &str, cx: &mut AppContext) {}
+}
+
+struct RefactoringModal {
+    prompt_editor: ViewHandle<Editor>,
+    has_focus: bool,
+}
+
+impl Entity for RefactoringModal {
+    type Event = ();
+}
+
+impl View for RefactoringModal {
+    fn ui_name() -> &'static str {
+        "RefactoringModal"
+    }
+
+    fn render(&mut self, cx: &mut ViewContext<Self>) -> AnyElement<Self> {
+        todo!()
+    }
+
+    fn focus_in(&mut self, _: AnyViewHandle, _: &mut ViewContext<Self>) {
+        self.has_focus = true;
+    }
+
+    fn focus_out(&mut self, _: AnyViewHandle, _: &mut ViewContext<Self>) {
+        self.has_focus = false;
+    }
+}
+
+impl Modal for RefactoringModal {
+    fn has_focus(&self) -> bool {
+        self.has_focus
+    }
+
+    fn dismiss_on_event(event: &Self::Event) -> bool {
+        todo!()
+    }
+}
+
+impl RefactoringModal {
+    fn deploy(workspace: &mut Workspace, _: &Refactor, cx: &mut ViewContext<Workspace>) {
+        workspace.toggle_modal(cx, |_, cx| {
+            let prompt_editor = cx.add_view(|cx| {
+                Editor::auto_height(
+                    4,
+                    Some(Arc::new(|theme| theme.search.editor.input.clone())),
+                    cx,
+                )
+            });
+            cx.add_view(|_| RefactoringModal {
+                prompt_editor,
+                has_focus: false,
+            })
+        });
+    }
+}
+
+// ABCDEFG
+// XCDEFG
+//
+//

prompt.md 🔗

@@ -0,0 +1,11 @@
+Given a snippet as the input, you must produce an array of edits. An edit has the following structure:
+
+{ skip: "skip", delete: "delete", insert: "insert" }
+
+`skip` is a string in the input that should be left unchanged. `delete` is a string in the input located right after the skipped text that should be deleted. `insert` is a new string that should be inserted after the end of the text in `skip`. It's crucial that a string in the input can only be skipped or deleted once and only once.
+
+Your task is to produce an array of edits. `delete` and `insert` can be empty if nothing changed. When `skip`, `delete` or `insert` are longer than 20 characters, split them into multiple edits.
+
+Check your reasoning by concatenating all the strings in `skip` and `delete`. If the text is the same as the input snippet then the edits are valid.
+
+It's crucial that you reply only with edits. No prose or remarks.