feat: new 'Insert at Caret' toolwindow editor action

This commit is contained in:
Carl-Robert Linnupuu 2024-09-05 01:21:28 +03:00
parent 0b794ac41b
commit ebc838bc06
12 changed files with 109 additions and 9 deletions

View file

@ -28,5 +28,7 @@ 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);
public static final Icon StatusBarCompletionInProgress = new AnimatedIcon.Default();
}

View file

@ -13,6 +13,7 @@ public enum ActionType {
CREATE_NEW_FILE,
COPY_CODE,
REPLACE_IN_MAIN_EDITOR,
INSERT_AT_CARET,
RELOAD_MESSAGE,
CHANGE_PROVIDER
}

View file

@ -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);
}

View file

@ -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));

View file

@ -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());
}
}

View file

@ -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;
});
}
}