Start on assistant::QuoteSelection
This commit is contained in:
parent
dc365472a6
commit
69e8a166e4
4 changed files with 101 additions and 3 deletions
|
@ -199,7 +199,8 @@
|
|||
"context": "ContextEditor > Editor",
|
||||
"bindings": {
|
||||
"cmd-enter": "assistant::Assist",
|
||||
"escape": "assistant::CancelLastAssist"
|
||||
"escape": "assistant::CancelLastAssist",
|
||||
"cmd-?": "assistant::QuoteSelection"
|
||||
}
|
||||
},
|
||||
{
|
||||
|
|
|
@ -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(¶ms.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 {
|
||||
|
|
|
@ -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()
|
||||
|
|
|
@ -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));
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue