From 3bbe57434163ea4ad674ec74a66458b279b2ebc1 Mon Sep 17 00:00:00 2001 From: Richard Feldman Date: Tue, 2 Jul 2024 08:13:14 -0400 Subject: [PATCH] Introduce a New `assistant: insert into editor` Action (#13467) This implements the functionality (paired with @as-cii), but we weren't sure what the clearest name would be for the action. It's essentially the inverse of "quote selection" - but what's the opposite of quoting the selection? One idea: * Rename "quote selection" to "Insert **into** assistant" * Name this "Insert **from** assistant" Release Notes: - Added action to insert from assistant into editor (default keybinding: `cmd-<` on macOS, `ctrl-<` on Linux) --------- Co-authored-by: Antonio Scandurra Co-authored-by: Bennet --- assets/keymaps/default-linux.json | 2 ++ assets/keymaps/default-macos.json | 2 ++ crates/assistant/src/assistant.rs | 1 + crates/assistant/src/assistant_panel.rs | 46 ++++++++++++++++++++++--- 4 files changed, 47 insertions(+), 4 deletions(-) diff --git a/assets/keymaps/default-linux.json b/assets/keymaps/default-linux.json index 6555370cf9..bf64bcc88a 100644 --- a/assets/keymaps/default-linux.json +++ b/assets/keymaps/default-linux.json @@ -155,6 +155,7 @@ // } // ], "ctrl->": "assistant::QuoteSelection", + "ctrl-<": "assistant::InsertIntoEditor", "ctrl-alt-e": "editor::SelectEnclosingSymbol" } }, @@ -548,6 +549,7 @@ "ctrl-enter": "assistant::Assist", "ctrl-s": "workspace::Save", "ctrl->": "assistant::QuoteSelection", + "ctrl-<": "assistant::InsertIntoEditor", "shift-enter": "assistant::Split", "ctrl-r": "assistant::CycleMessageRole", "enter": "assistant::ConfirmCommand", diff --git a/assets/keymaps/default-macos.json b/assets/keymaps/default-macos.json index e4ac33b03c..ce249b8965 100644 --- a/assets/keymaps/default-macos.json +++ b/assets/keymaps/default-macos.json @@ -193,6 +193,7 @@ } ], "cmd->": "assistant::QuoteSelection", + "cmd-<": "assistant::InsertIntoEditor", "cmd-alt-e": "editor::SelectEnclosingSymbol" } }, @@ -238,6 +239,7 @@ "cmd-enter": "assistant::Assist", "cmd-s": "workspace::Save", "cmd->": "assistant::QuoteSelection", + "cmd-<": "assistant::InsertIntoEditor", "shift-enter": "assistant::Split", "ctrl-r": "assistant::CycleMessageRole", "enter": "assistant::ConfirmCommand", diff --git a/crates/assistant/src/assistant.rs b/crates/assistant/src/assistant.rs index 44d27c825e..8a2bbcb0f0 100644 --- a/crates/assistant/src/assistant.rs +++ b/crates/assistant/src/assistant.rs @@ -43,6 +43,7 @@ actions!( Split, CycleMessageRole, QuoteSelection, + InsertIntoEditor, ToggleFocus, ResetKey, InlineAssist, diff --git a/crates/assistant/src/assistant_panel.rs b/crates/assistant/src/assistant_panel.rs index 9c169b9861..c99abb7cf9 100644 --- a/crates/assistant/src/assistant_panel.rs +++ b/crates/assistant/src/assistant_panel.rs @@ -9,9 +9,10 @@ use crate::{ }, terminal_inline_assistant::TerminalInlineAssistant, ApplyEdit, Assist, CompletionProvider, ConfirmCommand, ContextStore, CycleMessageRole, - InlineAssist, InlineAssistant, LanguageModelRequest, LanguageModelRequestMessage, MessageId, - MessageMetadata, MessageStatus, ModelSelector, QuoteSelection, ResetKey, Role, SavedContext, - SavedContextMetadata, SavedMessage, Split, ToggleFocus, ToggleHistory, ToggleModelSelector, + InlineAssist, InlineAssistant, InsertIntoEditor, LanguageModelRequest, + LanguageModelRequestMessage, MessageId, MessageMetadata, MessageStatus, ModelSelector, + QuoteSelection, ResetKey, Role, SavedContext, SavedContextMetadata, SavedMessage, Split, + ToggleFocus, ToggleHistory, ToggleModelSelector, }; use anyhow::{anyhow, Result}; use assistant_slash_command::{SlashCommand, SlashCommandOutput, SlashCommandOutputSection}; @@ -86,7 +87,8 @@ pub fn init(cx: &mut AppContext) { workspace.toggle_panel_focus::(cx); }) .register_action(AssistantPanel::inline_assist) - .register_action(ContextEditor::quote_selection); + .register_action(ContextEditor::quote_selection) + .register_action(ContextEditor::insert_selection); }, ) .detach(); @@ -2975,6 +2977,42 @@ impl ContextEditor { }); } + fn insert_selection( + workspace: &mut Workspace, + _: &InsertIntoEditor, + cx: &mut ViewContext, + ) { + let Some(panel) = workspace.panel::(cx) else { + return; + }; + let Some(context_editor_view) = panel.read(cx).active_context_editor().cloned() else { + return; + }; + let Some(active_editor_view) = workspace + .active_item(cx) + .and_then(|item| item.act_as::(cx)) + else { + return; + }; + + let context_editor = context_editor_view.read(cx).editor.read(cx); + let anchor = context_editor.selections.newest_anchor(); + let text = context_editor + .buffer() + .read(cx) + .read(cx) + .text_for_range(anchor.range()) + .collect::(); + + // If nothing is selected, don't delete the current selection; instead, be a no-op. + if !text.is_empty() { + active_editor_view.update(cx, |editor, cx| { + editor.insert(&text, cx); + editor.focus(cx); + }) + } + } + fn quote_selection( workspace: &mut Workspace, _: &QuoteSelection,