Start on assistant::QuoteSelection

This commit is contained in:
Antonio Scandurra 2023-05-30 15:25:53 +02:00
parent dc365472a6
commit 69e8a166e4
4 changed files with 101 additions and 3 deletions

View file

@ -199,7 +199,8 @@
"context": "ContextEditor > Editor",
"bindings": {
"cmd-enter": "assistant::Assist",
"escape": "assistant::CancelLastAssist"
"escape": "assistant::CancelLastAssist",
"cmd-?": "assistant::QuoteSelection"
}
},
{

View file

@ -19,11 +19,15 @@ use workspace::{
pane, Pane, Workspace,
};
actions!(assistant, [NewContext, Assist, CancelLastAssist]);
actions!(
assistant,
[NewContext, Assist, CancelLastAssist, QuoteSelection]
);
pub fn init(cx: &mut AppContext) {
cx.add_action(AssistantEditor::assist);
cx.capture_action(AssistantEditor::cancel_last_assist);
cx.add_action(AssistantEditor::quote_selection);
}
pub enum AssistantPanelEvent {
@ -136,6 +140,12 @@ impl View for AssistantPanel {
fn render(&mut self, cx: &mut ViewContext<Self>) -> AnyElement<Self> {
ChildView::new(&self.pane, cx).into_any()
}
fn focus_in(&mut self, _: gpui::AnyViewHandle, cx: &mut ViewContext<Self>) {
if cx.is_self_focused() {
cx.focus(&self.pane);
}
}
}
impl Panel for AssistantPanel {
@ -361,7 +371,7 @@ impl AssistantEditor {
editor.set_render_excerpt_header(
{
let assistant = assistant.clone();
move |editor, params: editor::RenderExcerptHeaderParams, cx| {
move |_editor, params: editor::RenderExcerptHeaderParams, cx| {
let style = &theme::current(cx).assistant;
if let Some(message) = assistant.read(cx).messages_by_id.get(&params.id) {
let sender = match message.role {
@ -421,6 +431,71 @@ impl AssistantEditor {
cx.propagate_action();
}
}
fn quote_selection(
workspace: &mut Workspace,
_: &QuoteSelection,
cx: &mut ViewContext<Workspace>,
) {
let Some(panel) = workspace.panel::<AssistantPanel>(cx) else {
return;
};
let Some(editor) = workspace.active_item(cx).and_then(|item| item.downcast::<Editor>()) else {
return;
};
let text = editor.read_with(cx, |editor, cx| {
let range = editor.selections.newest::<usize>(cx).range();
let buffer = editor.buffer().read(cx).snapshot(cx);
let start_language = buffer.language_at(range.start);
let end_language = buffer.language_at(range.end);
let language_name = if start_language == end_language {
start_language.map(|language| language.name())
} else {
None
};
let language_name = language_name.as_deref().unwrap_or("").to_lowercase();
let selected_text = buffer.text_for_range(range).collect::<String>();
if selected_text.is_empty() {
None
} else {
Some(if language_name == "markdown" {
selected_text
.lines()
.map(|line| format!("> {}", line))
.collect::<Vec<_>>()
.join("\n")
} else {
format!("```{language_name}\n{selected_text}\n```")
})
}
});
// Activate the panel
if !panel.read(cx).has_focus(cx) {
workspace.toggle_panel_focus::<AssistantPanel>(cx);
}
if let Some(text) = text {
panel.update(cx, |panel, cx| {
if let Some(assistant) = panel
.pane
.read(cx)
.active_item()
.and_then(|item| item.downcast::<AssistantEditor>())
.ok_or_else(|| anyhow!("no active context"))
.log_err()
{
assistant.update(cx, |assistant, cx| {
assistant
.editor
.update(cx, |editor, cx| editor.insert(&text, cx))
});
}
});
}
}
}
impl Entity for AssistantEditor {
@ -440,6 +515,12 @@ impl View for AssistantEditor {
.with_style(theme.container)
.into_any()
}
fn focus_in(&mut self, _: gpui::AnyViewHandle, cx: &mut ViewContext<Self>) {
if cx.is_self_focused() {
cx.focus(&self.editor);
}
}
}
impl Item for AssistantEditor {

View file

@ -184,6 +184,12 @@ impl Dock {
.map_or(false, |panel| panel.has_focus(cx))
}
pub fn panel<T: Panel>(&self) -> Option<ViewHandle<T>> {
self.panel_entries
.iter()
.find_map(|entry| entry.panel.as_any().clone().downcast())
}
pub fn panel_index_for_type<T: Panel>(&self) -> Option<usize> {
self.panel_entries
.iter()

View file

@ -1678,6 +1678,16 @@ impl Workspace {
}
}
pub fn panel<T: Panel>(&self, cx: &WindowContext) -> Option<ViewHandle<T>> {
for dock in [&self.left_dock, &self.bottom_dock, &self.right_dock] {
let dock = dock.read(cx);
if let Some(panel) = dock.panel::<T>() {
return Some(panel);
}
}
None
}
fn zoom_out(&mut self, cx: &mut ViewContext<Self>) {
for pane in &self.panes {
pane.update(cx, |pane, cx| pane.set_zoomed(false, cx));