From 4688a1c8d04a2aa3c23738a15a52c599c79b4048 Mon Sep 17 00:00:00 2001 From: Carl-Robert Linnupuu Date: Sun, 7 Apr 2024 15:35:15 +0300 Subject: [PATCH] refactor: remove 'Standard' prefix from toolwindow component class names, and other minor cleanup --- .../ProjectCompilationStatusListener.java | 4 +- .../codegpt/actions/editor/AskAction.java | 4 +- .../actions/editor/CustomPromptAction.java | 4 +- .../actions/editor/EditorActionsUtil.java | 4 +- .../DeleteAllConversationsAction.java | 4 +- .../settings/GeneralSettingsConfigurable.java | 4 +- .../toolwindow/ProjectToolWindowFactory.java | 4 +- ...java => ChatToolWindowContentManager.java} | 25 ++-- ...dowPanel.java => ChatToolWindowPanel.java} | 22 ++-- .../chat/ChatToolWindowTabPanel.java | 109 +++++++++++++----- ...ane.java => ChatToolWindowTabbedPane.java} | 20 ++-- .../chat/standard/EditorAction.java | 46 -------- .../chat/standard/EditorActionEvent.java | 9 -- .../StandardChatToolWindowLandingPanel.java | 70 ----------- .../StandardChatToolWindowTabPanel.java | 84 -------------- .../conversations/ConversationPanel.java | 6 +- .../{ => chat}/ChatToolWindowListener.kt | 5 +- .../ui/ChatToolWindowLandingPanel.kt | 100 ++++++++++++++++ src/main/resources/META-INF/plugin.xml | 2 +- ...t.java => ChatToolWindowTabPanelTest.java} | 13 +-- ...java => ChatToolWindowTabbedPaneTest.java} | 16 ++- 21 files changed, 249 insertions(+), 306 deletions(-) rename src/main/java/ee/carlrobert/codegpt/toolwindow/chat/{standard/StandardChatToolWindowContentManager.java => ChatToolWindowContentManager.java} (81%) rename src/main/java/ee/carlrobert/codegpt/toolwindow/chat/{standard/StandardChatToolWindowPanel.java => ChatToolWindowPanel.java} (89%) rename src/main/java/ee/carlrobert/codegpt/toolwindow/chat/{standard/StandardChatToolWindowTabbedPane.java => ChatToolWindowTabbedPane.java} (88%) delete mode 100644 src/main/java/ee/carlrobert/codegpt/toolwindow/chat/standard/EditorAction.java delete mode 100644 src/main/java/ee/carlrobert/codegpt/toolwindow/chat/standard/EditorActionEvent.java delete mode 100644 src/main/java/ee/carlrobert/codegpt/toolwindow/chat/standard/StandardChatToolWindowLandingPanel.java delete mode 100644 src/main/java/ee/carlrobert/codegpt/toolwindow/chat/standard/StandardChatToolWindowTabPanel.java rename src/main/kotlin/ee/carlrobert/codegpt/toolwindow/{ => chat}/ChatToolWindowListener.kt (74%) create mode 100644 src/main/kotlin/ee/carlrobert/codegpt/toolwindow/ui/ChatToolWindowLandingPanel.kt rename src/test/java/ee/carlrobert/codegpt/toolwindow/chat/{StandardChatToolWindowTabPanelTest.java => ChatToolWindowTabPanelTest.java} (96%) rename src/test/java/ee/carlrobert/codegpt/toolwindow/chat/{StandardChatToolWindowTabbedPaneTest.java => ChatToolWindowTabbedPaneTest.java} (64%) diff --git a/src/main/java/ee/carlrobert/codegpt/ProjectCompilationStatusListener.java b/src/main/java/ee/carlrobert/codegpt/ProjectCompilationStatusListener.java index b1b86157..1563d497 100644 --- a/src/main/java/ee/carlrobert/codegpt/ProjectCompilationStatusListener.java +++ b/src/main/java/ee/carlrobert/codegpt/ProjectCompilationStatusListener.java @@ -16,7 +16,7 @@ import com.intellij.openapi.project.Project; import ee.carlrobert.codegpt.completions.CompletionRequestProvider; import ee.carlrobert.codegpt.conversations.message.Message; import ee.carlrobert.codegpt.settings.configuration.ConfigurationSettings; -import ee.carlrobert.codegpt.toolwindow.chat.standard.StandardChatToolWindowContentManager; +import ee.carlrobert.codegpt.toolwindow.chat.ChatToolWindowContentManager; import ee.carlrobert.codegpt.ui.OverlayUtil; import java.io.File; import java.util.ArrayList; @@ -50,7 +50,7 @@ public class ProjectCompilationStatusListener implements CompilationStatusListen NotificationType.INFORMATION) .addAction(NotificationAction.createSimpleExpiring( CodeGPTBundle.get("notification.compilationError.okLabel"), - () -> project.getService(StandardChatToolWindowContentManager.class) + () -> project.getService(ChatToolWindowContentManager.class) .sendMessage(getMultiFileMessage(compileContext), FIX_COMPILE_ERRORS))) .addAction(NotificationAction.createSimpleExpiring( CodeGPTBundle.get("shared.notification.doNotShowAgain"), diff --git a/src/main/java/ee/carlrobert/codegpt/actions/editor/AskAction.java b/src/main/java/ee/carlrobert/codegpt/actions/editor/AskAction.java index f0d5836d..b83f4b88 100644 --- a/src/main/java/ee/carlrobert/codegpt/actions/editor/AskAction.java +++ b/src/main/java/ee/carlrobert/codegpt/actions/editor/AskAction.java @@ -5,7 +5,7 @@ import com.intellij.openapi.actionSystem.AnAction; import com.intellij.openapi.actionSystem.AnActionEvent; import ee.carlrobert.codegpt.Icons; import ee.carlrobert.codegpt.conversations.ConversationsState; -import ee.carlrobert.codegpt.toolwindow.chat.standard.StandardChatToolWindowContentManager; +import ee.carlrobert.codegpt.toolwindow.chat.ChatToolWindowContentManager; import org.jetbrains.annotations.NotNull; public class AskAction extends AnAction { @@ -26,7 +26,7 @@ public class AskAction extends AnAction { if (project != null) { ConversationsState.getInstance().setCurrentConversation(null); var tabPanel = - project.getService(StandardChatToolWindowContentManager.class).createNewTabPanel(); + project.getService(ChatToolWindowContentManager.class).createNewTabPanel(); if (tabPanel != null) { tabPanel.displayLandingView(); } diff --git a/src/main/java/ee/carlrobert/codegpt/actions/editor/CustomPromptAction.java b/src/main/java/ee/carlrobert/codegpt/actions/editor/CustomPromptAction.java index f870f0b3..05db8729 100644 --- a/src/main/java/ee/carlrobert/codegpt/actions/editor/CustomPromptAction.java +++ b/src/main/java/ee/carlrobert/codegpt/actions/editor/CustomPromptAction.java @@ -11,7 +11,7 @@ import com.intellij.util.ui.FormBuilder; import com.intellij.util.ui.JBUI; import com.intellij.util.ui.UI; import ee.carlrobert.codegpt.conversations.message.Message; -import ee.carlrobert.codegpt.toolwindow.chat.standard.StandardChatToolWindowContentManager; +import ee.carlrobert.codegpt.toolwindow.chat.ChatToolWindowContentManager; import ee.carlrobert.codegpt.ui.UIUtil; import ee.carlrobert.codegpt.util.file.FileUtil; import java.awt.event.ActionEvent; @@ -42,7 +42,7 @@ public class CustomPromptAction extends BaseEditorAction { format("%s\n```%s\n%s\n```", previousUserPrompt, fileExtension, selectedText)); message.setUserMessage(previousUserPrompt); SwingUtilities.invokeLater(() -> - project.getService(StandardChatToolWindowContentManager.class).sendMessage(message)); + project.getService(ChatToolWindowContentManager.class).sendMessage(message)); } } } diff --git a/src/main/java/ee/carlrobert/codegpt/actions/editor/EditorActionsUtil.java b/src/main/java/ee/carlrobert/codegpt/actions/editor/EditorActionsUtil.java index 06d02345..5c242df7 100644 --- a/src/main/java/ee/carlrobert/codegpt/actions/editor/EditorActionsUtil.java +++ b/src/main/java/ee/carlrobert/codegpt/actions/editor/EditorActionsUtil.java @@ -14,7 +14,7 @@ import ee.carlrobert.codegpt.CodeGPTKeys; import ee.carlrobert.codegpt.ReferencedFile; import ee.carlrobert.codegpt.conversations.message.Message; import ee.carlrobert.codegpt.settings.configuration.ConfigurationSettings; -import ee.carlrobert.codegpt.toolwindow.chat.standard.StandardChatToolWindowContentManager; +import ee.carlrobert.codegpt.toolwindow.chat.ChatToolWindowContentManager; import ee.carlrobert.codegpt.util.file.FileUtil; import java.util.Collection; import java.util.LinkedHashMap; @@ -65,7 +65,7 @@ public class EditorActionsUtil { format("\n```%s\n%s\n```", fileExtension, selectedText))); message.setUserMessage(prompt.replace("{{selectedCode}}", "")); var toolWindowContentManager = - project.getService(StandardChatToolWindowContentManager.class); + project.getService(ChatToolWindowContentManager.class); toolWindowContentManager.getToolWindow().show(); message.setReferencedFilePaths( diff --git a/src/main/java/ee/carlrobert/codegpt/actions/toolwindow/DeleteAllConversationsAction.java b/src/main/java/ee/carlrobert/codegpt/actions/toolwindow/DeleteAllConversationsAction.java index d9f7d71f..6490853a 100644 --- a/src/main/java/ee/carlrobert/codegpt/actions/toolwindow/DeleteAllConversationsAction.java +++ b/src/main/java/ee/carlrobert/codegpt/actions/toolwindow/DeleteAllConversationsAction.java @@ -11,7 +11,7 @@ import ee.carlrobert.codegpt.actions.ActionType; import ee.carlrobert.codegpt.actions.editor.EditorActionsUtil; import ee.carlrobert.codegpt.conversations.ConversationService; import ee.carlrobert.codegpt.telemetry.TelemetryAction; -import ee.carlrobert.codegpt.toolwindow.chat.standard.StandardChatToolWindowContentManager; +import ee.carlrobert.codegpt.toolwindow.chat.ChatToolWindowContentManager; import org.jetbrains.annotations.NotNull; public class DeleteAllConversationsAction extends AnAction { @@ -44,7 +44,7 @@ public class DeleteAllConversationsAction extends AnAction { if (project != null) { try { ConversationService.getInstance().clearAll(); - project.getService(StandardChatToolWindowContentManager.class).resetAll(); + project.getService(ChatToolWindowContentManager.class).resetAll(); } finally { TelemetryAction.IDE_ACTION.createActionMessage() .property("action", ActionType.DELETE_ALL_CONVERSATIONS.name()) diff --git a/src/main/java/ee/carlrobert/codegpt/settings/GeneralSettingsConfigurable.java b/src/main/java/ee/carlrobert/codegpt/settings/GeneralSettingsConfigurable.java index 11063a53..b9d781bc 100644 --- a/src/main/java/ee/carlrobert/codegpt/settings/GeneralSettingsConfigurable.java +++ b/src/main/java/ee/carlrobert/codegpt/settings/GeneralSettingsConfigurable.java @@ -26,7 +26,7 @@ import ee.carlrobert.codegpt.settings.service.openai.OpenAISettingsForm; import ee.carlrobert.codegpt.settings.service.you.YouSettings; import ee.carlrobert.codegpt.settings.service.you.YouSettingsForm; import ee.carlrobert.codegpt.telemetry.TelemetryAction; -import ee.carlrobert.codegpt.toolwindow.chat.standard.StandardChatToolWindowContentManager; +import ee.carlrobert.codegpt.toolwindow.chat.ChatToolWindowContentManager; import ee.carlrobert.codegpt.util.ApplicationUtil; import javax.swing.JComponent; import org.jetbrains.annotations.Nls; @@ -160,6 +160,6 @@ public class GeneralSettingsConfigurable implements Configurable { throw new RuntimeException("Could not find current project."); } - project.getService(StandardChatToolWindowContentManager.class).resetAll(); + project.getService(ChatToolWindowContentManager.class).resetAll(); } } diff --git a/src/main/java/ee/carlrobert/codegpt/toolwindow/ProjectToolWindowFactory.java b/src/main/java/ee/carlrobert/codegpt/toolwindow/ProjectToolWindowFactory.java index e3c43b2c..655cdc68 100644 --- a/src/main/java/ee/carlrobert/codegpt/toolwindow/ProjectToolWindowFactory.java +++ b/src/main/java/ee/carlrobert/codegpt/toolwindow/ProjectToolWindowFactory.java @@ -6,7 +6,7 @@ import com.intellij.openapi.wm.ToolWindow; import com.intellij.openapi.wm.ToolWindowFactory; import com.intellij.ui.content.ContentManagerEvent; import com.intellij.ui.content.ContentManagerListener; -import ee.carlrobert.codegpt.toolwindow.chat.standard.StandardChatToolWindowPanel; +import ee.carlrobert.codegpt.toolwindow.chat.ChatToolWindowPanel; import ee.carlrobert.codegpt.toolwindow.conversations.ConversationsToolWindow; import javax.swing.JComponent; import org.jetbrains.annotations.NotNull; @@ -14,7 +14,7 @@ import org.jetbrains.annotations.NotNull; public class ProjectToolWindowFactory implements ToolWindowFactory, DumbAware { public void createToolWindowContent(@NotNull Project project, @NotNull ToolWindow toolWindow) { - var chatToolWindowPanel = new StandardChatToolWindowPanel(project, toolWindow.getDisposable()); + var chatToolWindowPanel = new ChatToolWindowPanel(project, toolWindow.getDisposable()); var conversationsToolWindow = new ConversationsToolWindow(project); addContent(toolWindow, chatToolWindowPanel, "Chat"); diff --git a/src/main/java/ee/carlrobert/codegpt/toolwindow/chat/standard/StandardChatToolWindowContentManager.java b/src/main/java/ee/carlrobert/codegpt/toolwindow/chat/ChatToolWindowContentManager.java similarity index 81% rename from src/main/java/ee/carlrobert/codegpt/toolwindow/chat/standard/StandardChatToolWindowContentManager.java rename to src/main/java/ee/carlrobert/codegpt/toolwindow/chat/ChatToolWindowContentManager.java index 27ea30bd..b66814c9 100644 --- a/src/main/java/ee/carlrobert/codegpt/toolwindow/chat/standard/StandardChatToolWindowContentManager.java +++ b/src/main/java/ee/carlrobert/codegpt/toolwindow/chat/ChatToolWindowContentManager.java @@ -1,4 +1,4 @@ -package ee.carlrobert.codegpt.toolwindow.chat.standard; +package ee.carlrobert.codegpt.toolwindow.chat; import static java.util.Objects.requireNonNull; @@ -22,11 +22,11 @@ import java.util.Optional; import org.jetbrains.annotations.NotNull; @Service(Service.Level.PROJECT) -public final class StandardChatToolWindowContentManager { +public final class ChatToolWindowContentManager { private final Project project; - public StandardChatToolWindowContentManager(Project project) { + public ChatToolWindowContentManager(Project project) { this.project = project; } @@ -55,15 +55,14 @@ public final class StandardChatToolWindowContentManager { .ifPresent(tabbedPane -> tabbedPane.tryFindTabTitle(conversation.getId()) .ifPresentOrElse( title -> tabbedPane.setSelectedIndex(tabbedPane.indexOfTab(title)), - () -> tabbedPane.addNewTab( - new StandardChatToolWindowTabPanel(project, conversation)))); + () -> tabbedPane.addNewTab(new ChatToolWindowTabPanel(project, conversation)))); } - public StandardChatToolWindowTabPanel createNewTabPanel() { + public ChatToolWindowTabPanel createNewTabPanel() { displayChatTab(); return tryFindChatTabbedPane() .map(item -> { - var panel = new StandardChatToolWindowTabPanel( + var panel = new ChatToolWindowTabPanel( project, ConversationService.getInstance().startConversation()); item.addNewTab(panel); @@ -83,26 +82,26 @@ public final class StandardChatToolWindowContentManager { ); } - public Optional tryFindChatTabbedPane() { + public Optional tryFindChatTabbedPane() { var chatTabContent = tryFindFirstChatTabContent(); if (chatTabContent.isPresent()) { - var chatToolWindowPanel = (StandardChatToolWindowPanel) chatTabContent.get().getComponent(); + var chatToolWindowPanel = (ChatToolWindowPanel) chatTabContent.get().getComponent(); return Optional.of(chatToolWindowPanel.getChatTabbedPane()); } return Optional.empty(); } - public Optional tryFindChatToolWindowPanel() { + public Optional tryFindChatToolWindowPanel() { return tryFindFirstChatTabContent() .map(ComponentContainer::getComponent) - .filter(component -> component instanceof StandardChatToolWindowPanel) - .map(component -> (StandardChatToolWindowPanel) component); + .filter(component -> component instanceof ChatToolWindowPanel) + .map(component -> (ChatToolWindowPanel) component); } public void resetAll() { tryFindChatTabbedPane().ifPresent(tabbedPane -> { tabbedPane.clearAll(); - tabbedPane.addNewTab(new StandardChatToolWindowTabPanel( + tabbedPane.addNewTab(new ChatToolWindowTabPanel( project, ConversationService.getInstance().startConversation())); }); diff --git a/src/main/java/ee/carlrobert/codegpt/toolwindow/chat/standard/StandardChatToolWindowPanel.java b/src/main/java/ee/carlrobert/codegpt/toolwindow/chat/ChatToolWindowPanel.java similarity index 89% rename from src/main/java/ee/carlrobert/codegpt/toolwindow/chat/standard/StandardChatToolWindowPanel.java rename to src/main/java/ee/carlrobert/codegpt/toolwindow/chat/ChatToolWindowPanel.java index 178c024e..ea40de64 100644 --- a/src/main/java/ee/carlrobert/codegpt/toolwindow/chat/standard/StandardChatToolWindowPanel.java +++ b/src/main/java/ee/carlrobert/codegpt/toolwindow/chat/ChatToolWindowPanel.java @@ -1,4 +1,4 @@ -package ee.carlrobert.codegpt.toolwindow.chat.standard; +package ee.carlrobert.codegpt.toolwindow.chat; import static java.lang.String.format; import static java.util.Collections.emptyList; @@ -30,13 +30,13 @@ import javax.swing.BoxLayout; import javax.swing.JPanel; import org.jetbrains.annotations.NotNull; -public class StandardChatToolWindowPanel extends SimpleToolWindowPanel { +public class ChatToolWindowPanel extends SimpleToolWindowPanel { private final ToolWindowFooterNotification selectedFilesNotification; private final ToolWindowFooterNotification imageFileAttachmentNotification; - private StandardChatToolWindowTabbedPane tabbedPane; + private ChatToolWindowTabbedPane tabbedPane; - public StandardChatToolWindowPanel( + public ChatToolWindowPanel( @NotNull Project project, @NotNull Disposable parentDisposable) { super(true); @@ -58,7 +58,7 @@ public class StandardChatToolWindowPanel extends SimpleToolWindowPanel { "File path: " + filePath)); } - public StandardChatToolWindowTabbedPane getChatTabbedPane() { + public ChatToolWindowTabbedPane getChatTabbedPane() { return tabbedPane; } @@ -96,10 +96,10 @@ public class StandardChatToolWindowPanel extends SimpleToolWindowPanel { conversation = ConversationService.getInstance().startConversation(); } - var tabPanel = new StandardChatToolWindowTabPanel(project, conversation); + var tabPanel = new ChatToolWindowTabPanel(project, conversation); tabbedPane = createTabbedPane(tabPanel, parentDisposable); Runnable onAddNewTab = () -> { - tabbedPane.addNewTab(new StandardChatToolWindowTabPanel( + tabbedPane.addNewTab(new ChatToolWindowTabPanel( project, ConversationService.getInstance().startConversation())); repaint(); @@ -122,7 +122,7 @@ public class StandardChatToolWindowPanel extends SimpleToolWindowPanel { private ActionToolbar createActionToolbar( Project project, - StandardChatToolWindowTabbedPane tabbedPane, + ChatToolWindowTabbedPane tabbedPane, Runnable onAddNewTab) { var actionGroup = new DefaultCompactActionGroup("TOOLBAR_ACTION_GROUP", false); actionGroup.add(new CreateNewConversationAction(onAddNewTab)); @@ -137,10 +137,10 @@ public class StandardChatToolWindowPanel extends SimpleToolWindowPanel { return toolbar; } - private StandardChatToolWindowTabbedPane createTabbedPane( - StandardChatToolWindowTabPanel tabPanel, + private ChatToolWindowTabbedPane createTabbedPane( + ChatToolWindowTabPanel tabPanel, Disposable parentDisposable) { - var tabbedPane = new StandardChatToolWindowTabbedPane(parentDisposable); + var tabbedPane = new ChatToolWindowTabbedPane(parentDisposable); tabbedPane.addNewTab(tabPanel); return tabbedPane; } diff --git a/src/main/java/ee/carlrobert/codegpt/toolwindow/chat/ChatToolWindowTabPanel.java b/src/main/java/ee/carlrobert/codegpt/toolwindow/chat/ChatToolWindowTabPanel.java index 3a9194b9..95cf70a8 100644 --- a/src/main/java/ee/carlrobert/codegpt/toolwindow/chat/ChatToolWindowTabPanel.java +++ b/src/main/java/ee/carlrobert/codegpt/toolwindow/chat/ChatToolWindowTabPanel.java @@ -26,8 +26,8 @@ import ee.carlrobert.codegpt.conversations.ConversationService; import ee.carlrobert.codegpt.conversations.message.Message; import ee.carlrobert.codegpt.settings.GeneralSettings; import ee.carlrobert.codegpt.settings.service.ServiceType; +import ee.carlrobert.codegpt.settings.service.you.YouSettings; import ee.carlrobert.codegpt.telemetry.TelemetryAction; -import ee.carlrobert.codegpt.toolwindow.chat.standard.StandardChatToolWindowContentManager; import ee.carlrobert.codegpt.toolwindow.chat.ui.ChatMessageResponseBody; import ee.carlrobert.codegpt.toolwindow.chat.ui.ChatToolWindowScrollablePanel; import ee.carlrobert.codegpt.toolwindow.chat.ui.ResponsePanel; @@ -36,6 +36,8 @@ import ee.carlrobert.codegpt.toolwindow.chat.ui.textarea.ModelComboBoxAction; import ee.carlrobert.codegpt.toolwindow.chat.ui.textarea.TotalTokensDetails; import ee.carlrobert.codegpt.toolwindow.chat.ui.textarea.TotalTokensPanel; import ee.carlrobert.codegpt.toolwindow.chat.ui.textarea.UserPromptTextArea; +import ee.carlrobert.codegpt.toolwindow.ui.ChatToolWindowLandingPanel; +import ee.carlrobert.codegpt.ui.OverlayUtil; import ee.carlrobert.codegpt.util.EditorUtil; import ee.carlrobert.codegpt.util.file.FileUtil; import java.awt.BorderLayout; @@ -48,23 +50,21 @@ import java.util.UUID; import javax.swing.JComponent; import javax.swing.JPanel; import javax.swing.SwingUtilities; +import kotlin.Unit; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; -public abstract class ChatToolWindowTabPanel implements Disposable { +public class ChatToolWindowTabPanel implements Disposable { private static final Logger LOG = Logger.getInstance(ChatToolWindowTabPanel.class); + private final Project project; private final JPanel rootPanel; private final Conversation conversation; private final UserPromptTextArea userPromptTextArea; private final ConversationService conversationService; - - protected final Project project; - protected final TotalTokensPanel totalTokensPanel; - protected final ChatToolWindowScrollablePanel toolWindowScrollablePanel; - - protected abstract JComponent getLandingView(); + private final TotalTokensPanel totalTokensPanel; + private final ChatToolWindowScrollablePanel toolWindowScrollablePanel; public ChatToolWindowTabPanel(@NotNull Project project, @NotNull Conversation conversation) { this.project = project; @@ -80,6 +80,12 @@ public abstract class ChatToolWindowTabPanel implements Disposable { rootPanel = createRootPanel(); userPromptTextArea.requestFocusInWindow(); userPromptTextArea.requestFocus(); + + if (conversation.getMessages().isEmpty()) { + displayLandingView(); + } else { + displayConversation(conversation); + } } public void dispose() { @@ -94,6 +100,19 @@ public abstract class ChatToolWindowTabPanel implements Disposable { return conversation; } + public TotalTokensDetails getTokenDetails() { + return totalTokensPanel.getTokenDetails(); + } + + public void requestFocusForTextArea() { + userPromptTextArea.focus(); + } + + public void displayLandingView() { + toolWindowScrollablePanel.displayLandingView(getLandingView()); + totalTokensPanel.updateConversationTokens(conversation); + } + public void sendMessage(Message message) { sendMessage(message, ConversationType.DEFAULT); } @@ -101,7 +120,7 @@ public abstract class ChatToolWindowTabPanel implements Disposable { public void sendMessage(Message message, ConversationType conversationType) { SwingUtilities.invokeLater(() -> { var referencedFiles = project.getUserData(CodeGPTKeys.SELECTED_FILES); - var chatToolWindowPanel = project.getService(StandardChatToolWindowContentManager.class) + var chatToolWindowPanel = project.getService(ChatToolWindowContentManager.class) .tryFindChatToolWindowPanel(); if (referencedFiles != null && !referencedFiles.isEmpty()) { var referencedFilePaths = referencedFiles.stream() @@ -164,20 +183,7 @@ public abstract class ChatToolWindowTabPanel implements Disposable { .addContent(new ChatMessageResponseBody(project, true, this)); } - public TotalTokensDetails getTokenDetails() { - return totalTokensPanel.getTokenDetails(); - } - - public void requestFocusForTextArea() { - userPromptTextArea.focus(); - } - - public void displayLandingView() { - toolWindowScrollablePanel.displayLandingView(getLandingView()); - totalTokensPanel.updateConversationTokens(conversation); - } - - protected void reloadMessage( + private void reloadMessage( Message message, Conversation conversation, ConversationType conversationType) { @@ -205,7 +211,7 @@ public abstract class ChatToolWindowTabPanel implements Disposable { } } - protected void removeMessage(UUID messageId, Conversation conversation) { + private void removeMessage(UUID messageId, Conversation conversation) { toolWindowScrollablePanel.removeMessage(messageId); conversation.removeMessage(messageId); conversationService.saveConversation(conversation); @@ -216,7 +222,7 @@ public abstract class ChatToolWindowTabPanel implements Disposable { } } - protected void clearWindow() { + private void clearWindow() { toolWindowScrollablePanel.clearAll(); totalTokensPanel.updateConversationTokens(conversation); } @@ -268,7 +274,7 @@ public abstract class ChatToolWindowTabPanel implements Disposable { panel.setBorder(JBUI.Borders.compound( JBUI.Borders.customLine(JBColor.border(), 1, 0, 0, 0), JBUI.Borders.empty(8))); - var contentManager = project.getService(StandardChatToolWindowContentManager.class); + var contentManager = project.getService(ChatToolWindowContentManager.class); panel.add(JBUI.Panels.simplePanel(createUserPromptTextAreaHeader( selectedService, () -> { @@ -290,6 +296,57 @@ public abstract class ChatToolWindowTabPanel implements Disposable { .createCustomComponent(ActionPlaces.UNKNOWN)); } + private JComponent getLandingView() { + return new ChatToolWindowLandingPanel((action, locationOnScreen) -> { + var editor = EditorUtil.getSelectedEditor(project); + if (editor == null || !editor.getSelectionModel().hasSelection()) { + OverlayUtil.showWarningBalloon( + editor == null ? "Unable to locate a selected editor" + : "Please select a target code before proceeding", + locationOnScreen); + return Unit.INSTANCE; + } + + var fileExtension = FileUtil.getFileExtension( + ((EditorImpl) editor).getVirtualFile().getName()); + var message = new Message(action.getPrompt().replace( + "{{selectedCode}}", + format("\n```%s\n%s\n```", fileExtension, editor.getSelectionModel().getSelectedText()))); + message.setUserMessage(action.getUserMessage()); + + sendMessage(message, ConversationType.DEFAULT); + return Unit.INSTANCE; + }); + } + + private void displayConversation(@NotNull Conversation conversation) { + clearWindow(); + conversation.getMessages().forEach(message -> { + var messageResponseBody = + new ChatMessageResponseBody(project, this).withResponse(message.getResponse()); + + var serpResults = message.getSerpResults(); + if (YouSettings.getCurrentState().isDisplayWebSearchResults() + && serpResults != null && !serpResults.isEmpty()) { + messageResponseBody.displaySerpResults(serpResults); + } + messageResponseBody.hideCaret(); + + var userMessagePanel = new UserMessagePanel(project, message, this); + var imageFilePath = message.getImageFilePath(); + if (imageFilePath != null && !imageFilePath.isEmpty()) { + userMessagePanel.displayImage(imageFilePath); + } + + var messagePanel = toolWindowScrollablePanel.addMessage(message.getId()); + messagePanel.add(userMessagePanel); + messagePanel.add(new ResponsePanel() + .withReloadAction(() -> reloadMessage(message, conversation, ConversationType.DEFAULT)) + .withDeleteAction(() -> removeMessage(message.getId(), conversation)) + .addContent(messageResponseBody)); + }); + } + private JPanel createRootPanel() { var gbc = new GridBagConstraints(); gbc.fill = GridBagConstraints.BOTH; diff --git a/src/main/java/ee/carlrobert/codegpt/toolwindow/chat/standard/StandardChatToolWindowTabbedPane.java b/src/main/java/ee/carlrobert/codegpt/toolwindow/chat/ChatToolWindowTabbedPane.java similarity index 88% rename from src/main/java/ee/carlrobert/codegpt/toolwindow/chat/standard/StandardChatToolWindowTabbedPane.java rename to src/main/java/ee/carlrobert/codegpt/toolwindow/chat/ChatToolWindowTabbedPane.java index d623b032..ca7551f5 100644 --- a/src/main/java/ee/carlrobert/codegpt/toolwindow/chat/standard/StandardChatToolWindowTabbedPane.java +++ b/src/main/java/ee/carlrobert/codegpt/toolwindow/chat/ChatToolWindowTabbedPane.java @@ -1,4 +1,4 @@ -package ee.carlrobert.codegpt.toolwindow.chat.standard; +package ee.carlrobert.codegpt.toolwindow.chat; import com.intellij.icons.AllIcons; import com.intellij.openapi.Disposable; @@ -25,9 +25,9 @@ import javax.swing.JPanel; import javax.swing.JPopupMenu; import javax.swing.SwingUtilities; -public class StandardChatToolWindowTabbedPane extends JBTabbedPane { +public class ChatToolWindowTabbedPane extends JBTabbedPane { - private final Map activeTabMapping = new TreeMap<>( + private final Map activeTabMapping = new TreeMap<>( (o1, o2) -> { int n1 = Integer.parseInt(o1.replaceAll("\\D", "")); int n2 = Integer.parseInt(o2.replaceAll("\\D", "")); @@ -35,18 +35,18 @@ public class StandardChatToolWindowTabbedPane extends JBTabbedPane { }); private final Disposable parentDisposable; - public StandardChatToolWindowTabbedPane(Disposable parentDisposable) { + public ChatToolWindowTabbedPane(Disposable parentDisposable) { this.parentDisposable = parentDisposable; setTabComponentInsets(null); setComponentPopupMenu(new TabPopupMenu()); addChangeListener(e -> refreshTabState()); } - public Map getActiveTabMapping() { + public Map getActiveTabMapping() { return activeTabMapping; } - public void addNewTab(StandardChatToolWindowTabPanel toolWindowPanel) { + public void addNewTab(ChatToolWindowTabPanel toolWindowPanel) { var tabIndices = activeTabMapping.keySet().toArray(new String[0]); var nextIndex = 0; for (String title : tabIndices) { @@ -81,7 +81,7 @@ public class StandardChatToolWindowTabbedPane extends JBTabbedPane { .map(Map.Entry::getKey); } - public Optional tryFindActiveTabPanel() { + public Optional tryFindActiveTabPanel() { var selectedIndex = getSelectedIndex(); if (selectedIndex == -1) { return Optional.empty(); @@ -116,7 +116,7 @@ public class StandardChatToolWindowTabbedPane extends JBTabbedPane { Disposer.dispose(tabPanel); activeTabMapping.remove(getTitleAt(getSelectedIndex())); removeTabAt(getSelectedIndex()); - addNewTab(new StandardChatToolWindowTabPanel( + addNewTab(new ChatToolWindowTabPanel( project, ConversationService.getInstance().startConversation())); repaint(); @@ -180,8 +180,8 @@ public class StandardChatToolWindowTabbedPane extends JBTabbedPane { @Override public void show(Component invoker, int x, int y) { - selectedPopupTabIndex = StandardChatToolWindowTabbedPane.this.getUI() - .tabForCoordinate(StandardChatToolWindowTabbedPane.this, x, y); + selectedPopupTabIndex = ChatToolWindowTabbedPane.this.getUI() + .tabForCoordinate(ChatToolWindowTabbedPane.this, x, y); if (selectedPopupTabIndex > 0) { super.show(invoker, x, y); } diff --git a/src/main/java/ee/carlrobert/codegpt/toolwindow/chat/standard/EditorAction.java b/src/main/java/ee/carlrobert/codegpt/toolwindow/chat/standard/EditorAction.java deleted file mode 100644 index 5baf396d..00000000 --- a/src/main/java/ee/carlrobert/codegpt/toolwindow/chat/standard/EditorAction.java +++ /dev/null @@ -1,46 +0,0 @@ -package ee.carlrobert.codegpt.toolwindow.chat.standard; - -enum EditorAction { - FIND_BUGS( - "Find Bugs", - "Find bugs in the selected code", - "Find bugs and output code with bugs fixed in the selected code: {{selectedCode}}"), - WRITE_TESTS( - "Write Tests", - "Write unit tests for the selected code", - "Write unit tests for the selected code: {{selectedCode}}"), - EXPLAIN( - "Explain", - "Explain the selected code", - "Explain the selected code: {{selectedCode}}"), - REFACTOR( - "Refactor", - "Refactor the selected code", - "Refactor the selected code: {{selectedCode}}"), - OPTIMIZE( - "Optimize", - "Optimize the selected code", - "Optimize the selected code: {{selectedCode}}"); - - private final String label; - private final String userMessage; - private final String prompt; - - EditorAction(String label, String userMessage, String prompt) { - this.label = label; - this.userMessage = userMessage; - this.prompt = prompt; - } - - public String getLabel() { - return label; - } - - public String getPrompt() { - return prompt; - } - - public String getUserMessage() { - return userMessage; - } -} diff --git a/src/main/java/ee/carlrobert/codegpt/toolwindow/chat/standard/EditorActionEvent.java b/src/main/java/ee/carlrobert/codegpt/toolwindow/chat/standard/EditorActionEvent.java deleted file mode 100644 index c8af738c..00000000 --- a/src/main/java/ee/carlrobert/codegpt/toolwindow/chat/standard/EditorActionEvent.java +++ /dev/null @@ -1,9 +0,0 @@ -package ee.carlrobert.codegpt.toolwindow.chat.standard; - -import java.awt.Point; - -@FunctionalInterface -public interface EditorActionEvent { - - void handleAction(EditorAction action, Point locationOnScreen); -} diff --git a/src/main/java/ee/carlrobert/codegpt/toolwindow/chat/standard/StandardChatToolWindowLandingPanel.java b/src/main/java/ee/carlrobert/codegpt/toolwindow/chat/standard/StandardChatToolWindowLandingPanel.java deleted file mode 100644 index eab81f22..00000000 --- a/src/main/java/ee/carlrobert/codegpt/toolwindow/chat/standard/StandardChatToolWindowLandingPanel.java +++ /dev/null @@ -1,70 +0,0 @@ -package ee.carlrobert.codegpt.toolwindow.chat.standard; - -import static java.lang.String.format; - -import com.intellij.ui.components.ActionLink; -import com.intellij.util.ui.JBUI; -import ee.carlrobert.codegpt.Icons; -import ee.carlrobert.codegpt.settings.GeneralSettings; -import ee.carlrobert.codegpt.toolwindow.chat.ui.ResponsePanel; -import ee.carlrobert.codegpt.ui.UIUtil; -import java.awt.BorderLayout; -import javax.swing.Box; -import javax.swing.BoxLayout; -import javax.swing.JPanel; - -class StandardChatToolWindowLandingPanel extends ResponsePanel { - - StandardChatToolWindowLandingPanel(EditorActionEvent onAction) { - addContent(createContent(onAction)); - } - - private ActionLink createEditorActionLink(EditorAction action, EditorActionEvent onAction) { - var link = new ActionLink(action.getUserMessage(), event -> { - onAction.handleAction(action, ((ActionLink) event.getSource()).getLocationOnScreen()); - }); - link.setIcon(Icons.Sparkle); - return link; - } - - private JPanel createContent(EditorActionEvent onAction) { - var panel = new JPanel(new BorderLayout()); - panel.add(UIUtil.createTextPane( - "" - + format( - "

" - + "Welcome %s, I'm your intelligent code companion, here to be" - + " your partner-in-crime for getting things done in a flash." - + "

", GeneralSettings.getCurrentState().getDisplayName()) - + "

" - + "Feel free to ask me anything you'd like, but my true superpower lies in assisting " - + "you with your code! Here are a few examples of how I can assist you:" - + "

" - + "", - false), BorderLayout.NORTH); - panel.add(createEditorActionsListPanel(onAction), BorderLayout.CENTER); - panel.add(UIUtil.createTextPane( - "" - + "

" - + "Being an AI-powered assistant, I may occasionally have surprises or make mistakes. " - + "Therefore, it's wise to double-check any code or suggestions I provide." - + "

" - + "", - false), BorderLayout.SOUTH); - return panel; - } - - private JPanel createEditorActionsListPanel(EditorActionEvent onAction) { - var listPanel = new JPanel(); - listPanel.setLayout(new BoxLayout(listPanel, BoxLayout.PAGE_AXIS)); - listPanel.setBorder(JBUI.Borders.emptyLeft(4)); - listPanel.add(Box.createVerticalStrut(4)); - listPanel.add(createEditorActionLink(EditorAction.WRITE_TESTS, onAction)); - listPanel.add(Box.createVerticalStrut(4)); - listPanel.add(createEditorActionLink(EditorAction.EXPLAIN, onAction)); - listPanel.add(Box.createVerticalStrut(4)); - listPanel.add(createEditorActionLink(EditorAction.FIND_BUGS, onAction)); - listPanel.add(Box.createVerticalStrut(4)); - return listPanel; - } -} diff --git a/src/main/java/ee/carlrobert/codegpt/toolwindow/chat/standard/StandardChatToolWindowTabPanel.java b/src/main/java/ee/carlrobert/codegpt/toolwindow/chat/standard/StandardChatToolWindowTabPanel.java deleted file mode 100644 index 5b8645cf..00000000 --- a/src/main/java/ee/carlrobert/codegpt/toolwindow/chat/standard/StandardChatToolWindowTabPanel.java +++ /dev/null @@ -1,84 +0,0 @@ -package ee.carlrobert.codegpt.toolwindow.chat.standard; - -import static java.lang.String.format; - -import com.intellij.openapi.editor.impl.EditorImpl; -import com.intellij.openapi.project.Project; -import ee.carlrobert.codegpt.completions.ConversationType; -import ee.carlrobert.codegpt.conversations.Conversation; -import ee.carlrobert.codegpt.conversations.message.Message; -import ee.carlrobert.codegpt.settings.service.you.YouSettings; -import ee.carlrobert.codegpt.toolwindow.chat.ChatToolWindowTabPanel; -import ee.carlrobert.codegpt.toolwindow.chat.ui.ChatMessageResponseBody; -import ee.carlrobert.codegpt.toolwindow.chat.ui.ResponsePanel; -import ee.carlrobert.codegpt.toolwindow.chat.ui.UserMessagePanel; -import ee.carlrobert.codegpt.ui.OverlayUtil; -import ee.carlrobert.codegpt.util.EditorUtil; -import ee.carlrobert.codegpt.util.file.FileUtil; -import javax.swing.JComponent; -import org.jetbrains.annotations.NotNull; - -public class StandardChatToolWindowTabPanel extends ChatToolWindowTabPanel { - - public StandardChatToolWindowTabPanel( - @NotNull Project project, - @NotNull Conversation conversation) { - super(project, conversation); - if (conversation.getMessages().isEmpty()) { - displayLandingView(); - } else { - displayConversation(conversation); - } - } - - @Override - protected JComponent getLandingView() { - return new StandardChatToolWindowLandingPanel((action, locationOnScreen) -> { - var editor = EditorUtil.getSelectedEditor(project); - if (editor == null || !editor.getSelectionModel().hasSelection()) { - OverlayUtil.showWarningBalloon( - editor == null ? "Unable to locate a selected editor" - : "Please select a target code before proceeding", - locationOnScreen); - return; - } - - var fileExtension = FileUtil.getFileExtension( - ((EditorImpl) editor).getVirtualFile().getName()); - var message = new Message(action.getPrompt().replace( - "{{selectedCode}}", - format("\n```%s\n%s\n```", fileExtension, editor.getSelectionModel().getSelectedText()))); - message.setUserMessage(action.getUserMessage()); - - sendMessage(message, ConversationType.DEFAULT); - }); - } - - private void displayConversation(@NotNull Conversation conversation) { - clearWindow(); - conversation.getMessages().forEach(message -> { - var messageResponseBody = - new ChatMessageResponseBody(project, this).withResponse(message.getResponse()); - - var serpResults = message.getSerpResults(); - if (YouSettings.getCurrentState().isDisplayWebSearchResults() - && serpResults != null && !serpResults.isEmpty()) { - messageResponseBody.displaySerpResults(serpResults); - } - messageResponseBody.hideCaret(); - - var userMessagePanel = new UserMessagePanel(project, message, this); - var imageFilePath = message.getImageFilePath(); - if (imageFilePath != null && !imageFilePath.isEmpty()) { - userMessagePanel.displayImage(imageFilePath); - } - - var messagePanel = toolWindowScrollablePanel.addMessage(message.getId()); - messagePanel.add(userMessagePanel); - messagePanel.add(new ResponsePanel() - .withReloadAction(() -> reloadMessage(message, conversation, ConversationType.DEFAULT)) - .withDeleteAction(() -> removeMessage(message.getId(), conversation)) - .addContent(messageResponseBody)); - }); - } -} diff --git a/src/main/java/ee/carlrobert/codegpt/toolwindow/conversations/ConversationPanel.java b/src/main/java/ee/carlrobert/codegpt/toolwindow/conversations/ConversationPanel.java index 4e82f767..d3386062 100644 --- a/src/main/java/ee/carlrobert/codegpt/toolwindow/conversations/ConversationPanel.java +++ b/src/main/java/ee/carlrobert/codegpt/toolwindow/conversations/ConversationPanel.java @@ -9,7 +9,7 @@ import ee.carlrobert.codegpt.actions.toolwindow.DeleteConversationAction; import ee.carlrobert.codegpt.conversations.Conversation; import ee.carlrobert.codegpt.conversations.ConversationsState; import ee.carlrobert.codegpt.settings.GeneralSettings; -import ee.carlrobert.codegpt.toolwindow.chat.standard.StandardChatToolWindowContentManager; +import ee.carlrobert.codegpt.toolwindow.chat.ChatToolWindowContentManager; import ee.carlrobert.codegpt.ui.IconActionButton; import ee.carlrobert.codegpt.ui.ModelIconLabel; import java.awt.BorderLayout; @@ -30,12 +30,12 @@ class ConversationPanel extends JPanel { @NotNull Conversation conversation, @NotNull Runnable onDelete) { super(new BorderLayout()); - var toolWindowContentManager = project.getService(StandardChatToolWindowContentManager.class); + var toolWindowContentManager = project.getService(ChatToolWindowContentManager.class); init(toolWindowContentManager, conversation, onDelete); } private void init( - StandardChatToolWindowContentManager toolWindowContentManager, + ChatToolWindowContentManager toolWindowContentManager, Conversation conversation, Runnable onDelete) { setBackground(JBColor.background()); diff --git a/src/main/kotlin/ee/carlrobert/codegpt/toolwindow/ChatToolWindowListener.kt b/src/main/kotlin/ee/carlrobert/codegpt/toolwindow/chat/ChatToolWindowListener.kt similarity index 74% rename from src/main/kotlin/ee/carlrobert/codegpt/toolwindow/ChatToolWindowListener.kt rename to src/main/kotlin/ee/carlrobert/codegpt/toolwindow/chat/ChatToolWindowListener.kt index 73981d27..6c15f218 100644 --- a/src/main/kotlin/ee/carlrobert/codegpt/toolwindow/ChatToolWindowListener.kt +++ b/src/main/kotlin/ee/carlrobert/codegpt/toolwindow/chat/ChatToolWindowListener.kt @@ -1,9 +1,8 @@ -package ee.carlrobert.codegpt.toolwindow; +package ee.carlrobert.codegpt.toolwindow.chat import com.intellij.openapi.project.Project import com.intellij.openapi.wm.ToolWindow import com.intellij.openapi.wm.ex.ToolWindowManagerListener -import ee.carlrobert.codegpt.toolwindow.chat.standard.StandardChatToolWindowContentManager class ChatToolWindowListener : ToolWindowManagerListener { @@ -14,7 +13,7 @@ class ChatToolWindowListener : ToolWindowManagerListener { } private fun requestFocusForTextArea(project: Project) { - val contentManager = project.getService(StandardChatToolWindowContentManager::class.java) + val contentManager = project.getService(ChatToolWindowContentManager::class.java) contentManager.tryFindChatTabbedPane().ifPresent { tabbedPane -> tabbedPane.tryFindActiveTabPanel().ifPresent { tabPanel -> tabPanel.requestFocusForTextArea() diff --git a/src/main/kotlin/ee/carlrobert/codegpt/toolwindow/ui/ChatToolWindowLandingPanel.kt b/src/main/kotlin/ee/carlrobert/codegpt/toolwindow/ui/ChatToolWindowLandingPanel.kt new file mode 100644 index 00000000..7318ea3b --- /dev/null +++ b/src/main/kotlin/ee/carlrobert/codegpt/toolwindow/ui/ChatToolWindowLandingPanel.kt @@ -0,0 +1,100 @@ +package ee.carlrobert.codegpt.toolwindow.ui + +import com.intellij.ui.components.ActionLink +import com.intellij.util.ui.JBUI +import ee.carlrobert.codegpt.Icons +import ee.carlrobert.codegpt.settings.GeneralSettings +import ee.carlrobert.codegpt.toolwindow.chat.ui.ResponsePanel +import ee.carlrobert.codegpt.ui.UIUtil.createTextPane +import java.awt.BorderLayout +import java.awt.Point +import java.awt.event.ActionListener +import javax.swing.Box +import javax.swing.BoxLayout +import javax.swing.JPanel + +class ChatToolWindowLandingPanel(onAction: (LandingPanelAction, Point) -> Unit) : ResponsePanel() { + + init { + addContent(createContent(onAction)) + } + + private fun createContent(onAction: (LandingPanelAction, Point) -> Unit): JPanel { + return JPanel(BorderLayout()).apply { + add(createTextPane(getWelcomeMessage(), false), BorderLayout.NORTH) + add(createActionsListPanel(onAction), BorderLayout.CENTER) + add(createTextPane(getCautionMessage(), false), BorderLayout.SOUTH) + } + } + + private fun createActionsListPanel(onAction: (LandingPanelAction, Point) -> Unit): JPanel { + val listPanel = JPanel() + listPanel.layout = BoxLayout(listPanel, BoxLayout.PAGE_AXIS) + listPanel.border = JBUI.Borders.emptyLeft(4) + listPanel.add(Box.createVerticalStrut(4)) + listPanel.add(createEditorActionLink(LandingPanelAction.WRITE_TESTS, onAction)) + listPanel.add(Box.createVerticalStrut(4)) + listPanel.add(createEditorActionLink(LandingPanelAction.EXPLAIN, onAction)) + listPanel.add(Box.createVerticalStrut(4)) + listPanel.add(createEditorActionLink(LandingPanelAction.FIND_BUGS, onAction)) + listPanel.add(Box.createVerticalStrut(4)) + return listPanel + } + + private fun createEditorActionLink( + action: LandingPanelAction, + onAction: (LandingPanelAction, Point) -> Unit + ): ActionLink { + return ActionLink(action.userMessage, ActionListener { event -> + onAction(action, (event.source as ActionLink).locationOnScreen) + }).apply { + icon = Icons.Sparkle + } + } + + private fun getWelcomeMessage(): String { + return """ + +

+ Welcome ${GeneralSettings.getCurrentState().displayName}, I'm your intelligent code companion, here to be your partner-in-crime for getting things done in a flash. +

+

+ Feel free to ask me anything you'd like, but my true superpower lies in assisting you with your code! Here are a few examples of how I can assist you: +

+ + """.trimIndent() + } + + private fun getCautionMessage(): String { + return """ + +

+ Being an AI-powered assistant, I may occasionally have surprises or make mistakes. Therefore, it's wise to double-check any code or suggestions I provide. +

+ + """.trimIndent() + } +} + +enum class LandingPanelAction( + val label: String, + val userMessage: String, + val prompt: String +) { + FIND_BUGS( + "Find Bugs", + "Find bugs in the selected code", + "Find bugs and output code with bugs fixed in the selected code: {{selectedCode}}" + ), + WRITE_TESTS( + "Write Tests", + "Write unit tests for the selected code", + "Write unit tests for the selected code: {{selectedCode}}" + ), + EXPLAIN( + "Explain", + "Explain the selected code", + "Explain the selected code: {{selectedCode}}" + ) +} + diff --git a/src/main/resources/META-INF/plugin.xml b/src/main/resources/META-INF/plugin.xml index b2cb1b3a..554d81b9 100644 --- a/src/main/resources/META-INF/plugin.xml +++ b/src/main/resources/META-INF/plugin.xml @@ -9,7 +9,7 @@ - diff --git a/src/test/java/ee/carlrobert/codegpt/toolwindow/chat/StandardChatToolWindowTabPanelTest.java b/src/test/java/ee/carlrobert/codegpt/toolwindow/chat/ChatToolWindowTabPanelTest.java similarity index 96% rename from src/test/java/ee/carlrobert/codegpt/toolwindow/chat/StandardChatToolWindowTabPanelTest.java rename to src/test/java/ee/carlrobert/codegpt/toolwindow/chat/ChatToolWindowTabPanelTest.java index 3aba409d..4835894b 100644 --- a/src/test/java/ee/carlrobert/codegpt/toolwindow/chat/StandardChatToolWindowTabPanelTest.java +++ b/src/test/java/ee/carlrobert/codegpt/toolwindow/chat/ChatToolWindowTabPanelTest.java @@ -20,7 +20,6 @@ import ee.carlrobert.codegpt.conversations.ConversationService; import ee.carlrobert.codegpt.conversations.message.Message; import ee.carlrobert.codegpt.settings.configuration.ConfigurationSettings; import ee.carlrobert.codegpt.settings.service.llama.LlamaSettings; -import ee.carlrobert.codegpt.toolwindow.chat.standard.StandardChatToolWindowTabPanel; import ee.carlrobert.llm.client.http.exchange.StreamHttpExchange; import java.io.IOException; import java.nio.file.Files; @@ -30,14 +29,14 @@ import java.util.List; import java.util.Map; import testsupport.IntegrationTest; -public class StandardChatToolWindowTabPanelTest extends IntegrationTest { +public class ChatToolWindowTabPanelTest extends IntegrationTest { public void testSendingOpenAIMessage() { useOpenAIService(); ConfigurationSettings.getCurrentState().setSystemPrompt(COMPLETION_SYSTEM_PROMPT); var message = new Message("Hello!"); var conversation = ConversationService.getInstance().startConversation(); - var panel = new StandardChatToolWindowTabPanel(getProject(), conversation); + var panel = new ChatToolWindowTabPanel(getProject(), conversation); expectOpenAI((StreamHttpExchange) request -> { assertThat(request.getUri().getPath()).isEqualTo("/v1/chat/completions"); assertThat(request.getMethod()).isEqualTo("POST"); @@ -102,7 +101,7 @@ public class StandardChatToolWindowTabPanelTest extends IntegrationTest { message.setReferencedFilePaths( List.of("TEST_FILE_PATH_1", "TEST_FILE_PATH_2", "TEST_FILE_PATH_3")); var conversation = ConversationService.getInstance().startConversation(); - var panel = new StandardChatToolWindowTabPanel(getProject(), conversation); + var panel = new ChatToolWindowTabPanel(getProject(), conversation); expectOpenAI((StreamHttpExchange) request -> { assertThat(request.getUri().getPath()).isEqualTo("/v1/chat/completions"); assertThat(request.getMethod()).isEqualTo("POST"); @@ -188,7 +187,7 @@ public class StandardChatToolWindowTabPanelTest extends IntegrationTest { ConfigurationSettings.getCurrentState().setSystemPrompt(COMPLETION_SYSTEM_PROMPT); var message = new Message("TEST_MESSAGE"); var conversation = ConversationService.getInstance().startConversation(); - var panel = new StandardChatToolWindowTabPanel(getProject(), conversation); + var panel = new ChatToolWindowTabPanel(getProject(), conversation); expectOpenAI((StreamHttpExchange) request -> { assertThat(request.getUri().getPath()).isEqualTo("/v1/chat/completions"); assertThat(request.getMethod()).isEqualTo("POST"); @@ -266,7 +265,7 @@ public class StandardChatToolWindowTabPanelTest extends IntegrationTest { message.setReferencedFilePaths( List.of("TEST_FILE_PATH_1", "TEST_FILE_PATH_2", "TEST_FILE_PATH_3")); var conversation = ConversationService.getInstance().startConversation(); - var panel = new StandardChatToolWindowTabPanel(getProject(), conversation); + var panel = new ChatToolWindowTabPanel(getProject(), conversation); expectOpenAI((StreamHttpExchange) request -> { assertThat(request.getUri().getPath()).isEqualTo("/v1/chat/completions"); assertThat(request.getMethod()).isEqualTo("POST"); @@ -360,7 +359,7 @@ public class StandardChatToolWindowTabPanelTest extends IntegrationTest { llamaSettings.setRepeatPenalty(1.3); var message = new Message("TEST_PROMPT"); var conversation = ConversationService.getInstance().startConversation(); - var panel = new StandardChatToolWindowTabPanel(getProject(), conversation); + var panel = new ChatToolWindowTabPanel(getProject(), conversation); expectLlama((StreamHttpExchange) request -> { assertThat(request.getUri().getPath()).isEqualTo("/completion"); assertThat(request.getBody()) diff --git a/src/test/java/ee/carlrobert/codegpt/toolwindow/chat/StandardChatToolWindowTabbedPaneTest.java b/src/test/java/ee/carlrobert/codegpt/toolwindow/chat/ChatToolWindowTabbedPaneTest.java similarity index 64% rename from src/test/java/ee/carlrobert/codegpt/toolwindow/chat/StandardChatToolWindowTabbedPaneTest.java rename to src/test/java/ee/carlrobert/codegpt/toolwindow/chat/ChatToolWindowTabbedPaneTest.java index 17411989..0746f538 100644 --- a/src/test/java/ee/carlrobert/codegpt/toolwindow/chat/StandardChatToolWindowTabbedPaneTest.java +++ b/src/test/java/ee/carlrobert/codegpt/toolwindow/chat/ChatToolWindowTabbedPaneTest.java @@ -6,13 +6,11 @@ import com.intellij.openapi.util.Disposer; import com.intellij.testFramework.fixtures.BasePlatformTestCase; import ee.carlrobert.codegpt.conversations.ConversationService; import ee.carlrobert.codegpt.conversations.message.Message; -import ee.carlrobert.codegpt.toolwindow.chat.standard.StandardChatToolWindowTabPanel; -import ee.carlrobert.codegpt.toolwindow.chat.standard.StandardChatToolWindowTabbedPane; -public class StandardChatToolWindowTabbedPaneTest extends BasePlatformTestCase { +public class ChatToolWindowTabbedPaneTest extends BasePlatformTestCase { public void testClearAllTabs() { - var tabbedPane = new StandardChatToolWindowTabbedPane(Disposer.newDisposable()); + var tabbedPane = new ChatToolWindowTabbedPane(Disposer.newDisposable()); tabbedPane.addNewTab(createNewTabPanel()); tabbedPane.clearAll(); @@ -22,7 +20,7 @@ public class StandardChatToolWindowTabbedPaneTest extends BasePlatformTestCase { public void testAddingNewTabs() { - var tabbedPane = new StandardChatToolWindowTabbedPane(Disposer.newDisposable()); + var tabbedPane = new ChatToolWindowTabbedPane(Disposer.newDisposable()); tabbedPane.addNewTab(createNewTabPanel()); tabbedPane.addNewTab(createNewTabPanel()); @@ -33,10 +31,10 @@ public class StandardChatToolWindowTabbedPaneTest extends BasePlatformTestCase { } public void testResetCurrentlyActiveTabPanel() { - var tabbedPane = new StandardChatToolWindowTabbedPane(Disposer.newDisposable()); + var tabbedPane = new ChatToolWindowTabbedPane(Disposer.newDisposable()); var conversation = ConversationService.getInstance().startConversation(); conversation.addMessage(new Message("TEST_PROMPT", "TEST_RESPONSE")); - tabbedPane.addNewTab(new StandardChatToolWindowTabPanel(getProject(), conversation)); + tabbedPane.addNewTab(new ChatToolWindowTabPanel(getProject(), conversation)); tabbedPane.resetCurrentlyActiveTabPanel(getProject()); @@ -44,8 +42,8 @@ public class StandardChatToolWindowTabbedPaneTest extends BasePlatformTestCase { assertThat(tabPanel.getConversation().getMessages()).isEmpty(); } - private StandardChatToolWindowTabPanel createNewTabPanel() { - return new StandardChatToolWindowTabPanel( + private ChatToolWindowTabPanel createNewTabPanel() { + return new ChatToolWindowTabPanel( getProject(), ConversationService.getInstance().startConversation()); }