mirror of
https://github.com/carlrobertoh/ProxyAI.git
synced 2026-05-20 09:24:08 +00:00
feat: new 'Insert at Caret' toolwindow editor action
This commit is contained in:
parent
4b80fa2a9d
commit
baa99d97d1
12 changed files with 109 additions and 9 deletions
|
|
@ -8,7 +8,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|||
|
||||
### Added
|
||||
|
||||
- 'Direct Apply' and 'Compare with Original' tool window editor actions for generated code
|
||||
- Multiple tool window editor actions for generated code:
|
||||
- Direct apply: Directly replaces the highlighted code in the main editor with the generated code
|
||||
- Compare with Original: Opens a diff view to compare the generated code with the highlighted code
|
||||
- Insert at Caret: Inserts the generated code at the exact location of the caret in the main editor
|
||||
- Vision support for Azure models
|
||||
- General improvements to code completions, including:
|
||||
- Proper streaming support
|
||||
|
|
|
|||
|
|
@ -27,4 +27,6 @@ public final class Icons {
|
|||
public static final Icon Upload = IconLoader.getIcon("/icons/upload.svg", Icons.class);
|
||||
public static final Icon GreenCheckmark =
|
||||
IconLoader.getIcon("/icons/greenCheckmark.svg", Icons.class);
|
||||
public static final Icon SendToTheLeft =
|
||||
IconLoader.getIcon("/icons/sendToTheLeft.svg", Icons.class);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -13,6 +13,7 @@ public enum ActionType {
|
|||
CREATE_NEW_FILE,
|
||||
COPY_CODE,
|
||||
REPLACE_IN_MAIN_EDITOR,
|
||||
INSERT_AT_CARET,
|
||||
RELOAD_MESSAGE,
|
||||
CHANGE_PROVIDER
|
||||
}
|
||||
|
|
|
|||
|
|
@ -14,7 +14,7 @@ import org.jetbrains.annotations.NotNull;
|
|||
public class ReplaceCodeInMainEditorAction extends AnAction {
|
||||
|
||||
public ReplaceCodeInMainEditorAction() {
|
||||
super("Replace in Main Editor", "Replace code in main editor", AllIcons.Actions.Replace);
|
||||
super("Replace Selection", "Replace selected code in main editor", AllIcons.Actions.Replace);
|
||||
EditorActionsUtil.registerAction(this);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -33,6 +33,7 @@ import ee.carlrobert.codegpt.toolwindow.chat.DirectApplyActionLink;
|
|||
import ee.carlrobert.codegpt.toolwindow.chat.editor.actions.CopyAction;
|
||||
import ee.carlrobert.codegpt.toolwindow.chat.editor.actions.DiffAction;
|
||||
import ee.carlrobert.codegpt.toolwindow.chat.editor.actions.EditAction;
|
||||
import ee.carlrobert.codegpt.toolwindow.chat.editor.actions.InsertAtCaretAction;
|
||||
import ee.carlrobert.codegpt.toolwindow.chat.editor.actions.NewFileAction;
|
||||
import ee.carlrobert.codegpt.toolwindow.chat.editor.actions.ReplaceSelectionAction;
|
||||
import ee.carlrobert.codegpt.ui.IconActionButton;
|
||||
|
|
@ -82,9 +83,9 @@ public class ResponseEditorPanel extends JPanel implements Disposable {
|
|||
|
||||
if (highlightedText != null && !highlightedText.isEmpty()) {
|
||||
directLinksPanel.setVisible(false);
|
||||
directLinksPanel.setBorder(JBUI.Borders.emptyTop(4));
|
||||
directLinksPanel.setBorder(JBUI.Borders.emptyTop(8));
|
||||
directLinksPanel.add(new CompareWithOriginalActionLink(project, editor, highlightedText));
|
||||
directLinksPanel.add(Box.createHorizontalStrut(8));
|
||||
directLinksPanel.add(Box.createHorizontalStrut(12));
|
||||
directLinksPanel.add(new DirectApplyActionLink(project, editor, highlightedText));
|
||||
add(directLinksPanel, BorderLayout.SOUTH);
|
||||
}
|
||||
|
|
@ -179,6 +180,7 @@ public class ResponseEditorPanel extends JPanel implements Disposable {
|
|||
var actionGroup = new DefaultCompactActionGroup("EDITOR_TOOLBAR_ACTION_GROUP", false);
|
||||
actionGroup.add(new CopyAction(editor));
|
||||
actionGroup.add(new ReplaceSelectionAction(editor));
|
||||
actionGroup.add(new InsertAtCaretAction(editor));
|
||||
actionGroup.addSeparator();
|
||||
|
||||
var wrapper = new JPanel(new FlowLayout(FlowLayout.LEFT, 0, 0));
|
||||
|
|
|
|||
|
|
@ -15,18 +15,18 @@ import org.jetbrains.annotations.Nullable;
|
|||
|
||||
public class DiffAction extends AbstractAction {
|
||||
|
||||
private final EditorEx toolwindowEditor;
|
||||
private final EditorEx editor;
|
||||
private final Point locationOnScreen;
|
||||
|
||||
public DiffAction(EditorEx toolwindowEditor, @Nullable Point locationOnScreen) {
|
||||
public DiffAction(EditorEx editor, @Nullable Point locationOnScreen) {
|
||||
super("Diff", Actions.DiffWithClipboard);
|
||||
this.toolwindowEditor = toolwindowEditor;
|
||||
this.editor = editor;
|
||||
this.locationOnScreen = locationOnScreen;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent event) {
|
||||
var project = requireNonNull(toolwindowEditor.getProject());
|
||||
var project = requireNonNull(editor.getProject());
|
||||
var mainEditor = FileEditorManager.getInstance(project).getSelectedTextEditor();
|
||||
if (mainEditor != null && !EditorUtil.hasSelection(mainEditor) && locationOnScreen != null) {
|
||||
OverlayUtil.showSelectedEditorSelectionWarning(project, locationOnScreen);
|
||||
|
|
@ -35,7 +35,7 @@ public class DiffAction extends AbstractAction {
|
|||
|
||||
EditorDiffUtil.showDiff(
|
||||
project,
|
||||
toolwindowEditor,
|
||||
editor,
|
||||
mainEditor.getSelectionModel().getSelectedText());
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,70 @@
|
|||
package ee.carlrobert.codegpt.toolwindow.chat.editor.actions;
|
||||
|
||||
import static com.intellij.openapi.application.ActionsKt.runUndoTransparentWriteAction;
|
||||
|
||||
import com.intellij.openapi.actionSystem.AnActionEvent;
|
||||
import com.intellij.openapi.editor.Editor;
|
||||
import com.intellij.openapi.fileEditor.FileEditorManager;
|
||||
import ee.carlrobert.codegpt.CodeGPTBundle;
|
||||
import ee.carlrobert.codegpt.Icons;
|
||||
import ee.carlrobert.codegpt.actions.ActionType;
|
||||
import ee.carlrobert.codegpt.actions.TrackableAction;
|
||||
import ee.carlrobert.codegpt.ui.OverlayUtil;
|
||||
import java.awt.Point;
|
||||
import java.util.Optional;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
public class InsertAtCaretAction extends TrackableAction {
|
||||
|
||||
public InsertAtCaretAction(@NotNull Editor editor) {
|
||||
super(
|
||||
editor,
|
||||
CodeGPTBundle.get("toolwindow.chat.editor.action.insertAtCaret.title"),
|
||||
CodeGPTBundle.get("toolwindow.chat.editor.action.insertAtCaret.description"),
|
||||
Icons.SendToTheLeft,
|
||||
ActionType.INSERT_AT_CARET);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handleAction(@NotNull AnActionEvent event) {
|
||||
Point locationOnScreen = getLocationOnScreen(event);
|
||||
Editor mainEditor = getSelectedTextEditor();
|
||||
|
||||
if (mainEditor == null) {
|
||||
OverlayUtil.showWarningBalloon("Active editor not found", locationOnScreen);
|
||||
return;
|
||||
}
|
||||
|
||||
insertTextAtCaret(mainEditor, locationOnScreen);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private Point getLocationOnScreen(AnActionEvent event) {
|
||||
return Optional.ofNullable(event.getInputEvent())
|
||||
.map(inputEvent -> inputEvent.getComponent().getLocationOnScreen())
|
||||
.orElse(null);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private Editor getSelectedTextEditor() {
|
||||
return Optional.ofNullable(editor.getProject())
|
||||
.map(FileEditorManager::getInstance)
|
||||
.map(FileEditorManager::getSelectedTextEditor)
|
||||
.orElse(null);
|
||||
}
|
||||
|
||||
private void insertTextAtCaret(Editor mainEditor, @Nullable Point locationOnScreen) {
|
||||
runUndoTransparentWriteAction(() -> {
|
||||
mainEditor.getDocument().insertString(
|
||||
mainEditor.getCaretModel().getOffset(),
|
||||
editor.getDocument().getText());
|
||||
if (locationOnScreen != null) {
|
||||
OverlayUtil.showInfoBalloon(
|
||||
"Text successfully inserted at the current cursor position.",
|
||||
locationOnScreen);
|
||||
}
|
||||
return null;
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
@ -1,5 +1,6 @@
|
|||
package ee.carlrobert.codegpt.toolwindow.chat
|
||||
|
||||
import com.intellij.icons.AllIcons.Actions
|
||||
import com.intellij.openapi.actionSystem.AnAction
|
||||
import com.intellij.openapi.actionSystem.AnActionEvent
|
||||
import com.intellij.openapi.editor.Editor
|
||||
|
|
@ -18,6 +19,10 @@ class CompareWithOriginalActionLink(
|
|||
highlightedText
|
||||
) {
|
||||
|
||||
init {
|
||||
setIcon(Actions.Diff)
|
||||
}
|
||||
|
||||
class CompareWithOriginalAction(
|
||||
private val project: Project,
|
||||
private val toolwindowEditor: Editor,
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
package ee.carlrobert.codegpt.toolwindow.chat
|
||||
|
||||
import com.intellij.icons.AllIcons.Actions
|
||||
import com.intellij.openapi.actionSystem.AnAction
|
||||
import com.intellij.openapi.actionSystem.AnActionEvent
|
||||
import com.intellij.openapi.command.WriteCommandAction
|
||||
|
|
@ -20,6 +21,10 @@ class DirectApplyActionLink(
|
|||
highlightedText
|
||||
) {
|
||||
|
||||
init {
|
||||
setIcon(Actions.Selectall)
|
||||
}
|
||||
|
||||
class DirectApplyAction(
|
||||
private val project: Project,
|
||||
private val toolwindowEditor: Editor,
|
||||
|
|
|
|||
5
src/main/resources/icons/sendToTheLeft.svg
Normal file
5
src/main/resources/icons/sendToTheLeft.svg
Normal file
|
|
@ -0,0 +1,5 @@
|
|||
<!-- Copyright 2000-2024 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license. -->
|
||||
<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M8.85355 3.14742C9.04882 3.34269 9.04882 3.65927 8.85355 3.85453L5.70735 7.00074L13.5009 7.00074C13.777 7.00074 14.0009 7.2246 14.0009 7.50074C14.0009 7.77688 13.777 8.00074 13.5009 8.00074L5.70687 8.00074L8.85356 11.1474C9.04882 11.3427 9.04882 11.6593 8.85356 11.8545C8.65829 12.0498 8.34171 12.0498 8.14645 11.8545L4.14645 7.85453C4.05268 7.76076 4 7.63359 4 7.50098C4 7.36837 4.05268 7.24119 4.14645 7.14742L8.14645 3.14742C8.34171 2.95216 8.65829 2.95216 8.85355 3.14742Z" fill="#3574F0"/>
|
||||
<path d="M2.5 11.5V3.5" stroke="#6C707E" stroke-linecap="round" stroke-linejoin="round"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 824 B |
5
src/main/resources/icons/sendToTheLeft_dark.svg
Normal file
5
src/main/resources/icons/sendToTheLeft_dark.svg
Normal file
|
|
@ -0,0 +1,5 @@
|
|||
<!-- Copyright 2000-2024 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license. -->
|
||||
<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M8.85355 3.14742C9.04882 3.34269 9.04882 3.65927 8.85355 3.85453L5.70735 7.00074L13.5009 7.00074C13.777 7.00074 14.0009 7.2246 14.0009 7.50074C14.0009 7.77688 13.777 8.00074 13.5009 8.00074L5.70687 8.00074L8.85356 11.1474C9.04882 11.3427 9.04882 11.6593 8.85356 11.8545C8.65829 12.0498 8.34171 12.0498 8.14645 11.8545L4.14645 7.85453C4.05268 7.76076 4 7.63359 4 7.50098C4 7.36837 4.05268 7.24119 4.14645 7.14742L8.14645 3.14742C8.34171 2.95216 8.65829 2.95216 8.85355 3.14742Z" fill="#548AF7"/>
|
||||
<path d="M2.5 11.5V3.5" stroke="#CED0D6" stroke-linecap="round" stroke-linejoin="round"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 824 B |
|
|
@ -181,6 +181,8 @@ toolwindow.chat.editor.action.newFile.title=New File
|
|||
toolwindow.chat.editor.action.newFile.description=Create new file from generated code
|
||||
toolwindow.chat.editor.action.replaceSelection.title=Replace Selection
|
||||
toolwindow.chat.editor.action.replaceSelection.description=Replace main editor selected code
|
||||
toolwindow.chat.editor.action.insertAtCaret.title=Insert at Caret
|
||||
toolwindow.chat.editor.action.insertAtCaret.description=Insert generated code after main editor caret position
|
||||
toolwindow.chat.editor.action.expand=Show More (+%s rows)
|
||||
toolwindow.chat.editor.action.collapse=Show Less
|
||||
toolwindow.chat.response.action.reloadResponse.text=Reload Response
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue