refactor: remove 'Standard' prefix from toolwindow component class names, and other minor cleanup

This commit is contained in:
Carl-Robert Linnupuu 2024-04-07 15:35:15 +03:00
parent 7f505e2c30
commit 4688a1c8d0
21 changed files with 249 additions and 306 deletions

View file

@ -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"),

View file

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

View file

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

View file

@ -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(

View file

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

View file

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

View file

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

View file

@ -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<StandardChatToolWindowTabbedPane> tryFindChatTabbedPane() {
public Optional<ChatToolWindowTabbedPane> 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<StandardChatToolWindowPanel> tryFindChatToolWindowPanel() {
public Optional<ChatToolWindowPanel> 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()));
});

View file

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

View file

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

View file

@ -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<String, StandardChatToolWindowTabPanel> activeTabMapping = new TreeMap<>(
private final Map<String, ChatToolWindowTabPanel> 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<String, StandardChatToolWindowTabPanel> getActiveTabMapping() {
public Map<String, ChatToolWindowTabPanel> 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<StandardChatToolWindowTabPanel> tryFindActiveTabPanel() {
public Optional<ChatToolWindowTabPanel> 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);
}

View file

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

View file

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

View file

@ -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(
"<html>"
+ format(
"<p style=\"margin-top: 4px; margin-bottom: 4px;\">"
+ "Welcome <strong>%s</strong>, I'm your intelligent code companion, here to be"
+ " your partner-in-crime for getting things done in a flash."
+ "</p>", GeneralSettings.getCurrentState().getDisplayName())
+ "<p style=\"margin-top: 4px; margin-bottom: 4px;\">"
+ "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:"
+ "</p>"
+ "</html>",
false), BorderLayout.NORTH);
panel.add(createEditorActionsListPanel(onAction), BorderLayout.CENTER);
panel.add(UIUtil.createTextPane(
"<html>"
+ "<p style=\"margin-top: 4px; margin-bottom: 4px;\">"
+ "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."
+ "</p>"
+ "</html>",
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;
}
}

View file

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

View file

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