Skip to content

Commit 91e6831

Browse files
committed
feat: replace custom suggestions UI logic with editor lookup API
1 parent 3de3c65 commit 91e6831

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

47 files changed

+1171
-1219
lines changed

src/main/java/ee/carlrobert/codegpt/Icons.java

+1
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ public final class Icons {
1818
public static final Icon Google = IconLoader.getIcon("/icons/google.svg", Icons.class);
1919
public static final Icon Llama = IconLoader.getIcon("/icons/llama.svg", Icons.class);
2020
public static final Icon OpenAI = IconLoader.getIcon("/icons/openai.svg", Icons.class);
21+
public static final Icon MCP = IconLoader.getIcon("/icons/mcp.svg", Icons.class);
2122
public static final Icon Meta = IconLoader.getIcon("/icons/meta.svg", Icons.class);
2223
public static final Icon Mistral = IconLoader.getIcon("/icons/mistral.svg", Icons.class);
2324
public static final Icon Send = IconLoader.getIcon("/icons/send.svg", Icons.class);

src/main/java/ee/carlrobert/codegpt/toolwindow/chat/ui/SelectedFilesAccordion.java

+8-26
Original file line numberDiff line numberDiff line change
@@ -3,16 +3,11 @@
33
import static java.lang.String.format;
44

55
import com.intellij.icons.AllIcons.General;
6-
import com.intellij.openapi.fileEditor.FileEditorManager;
7-
import com.intellij.openapi.project.Project;
8-
import com.intellij.openapi.vfs.VirtualFile;
96
import com.intellij.ui.components.ActionLink;
107
import com.intellij.util.ui.JBUI;
118
import java.awt.BorderLayout;
129
import java.awt.event.ItemEvent;
13-
import java.nio.file.Paths;
1410
import java.util.List;
15-
import java.util.Objects;
1611
import javax.swing.Box;
1712
import javax.swing.BoxLayout;
1813
import javax.swing.JPanel;
@@ -22,38 +17,25 @@
2217

2318
public class SelectedFilesAccordion extends JPanel {
2419

25-
public SelectedFilesAccordion(
26-
@NotNull Project project,
27-
@NotNull List<VirtualFile> referencedFiles) {
20+
public SelectedFilesAccordion(@NotNull List<ActionLink> links) {
2821
super(new BorderLayout());
2922
setOpaque(false);
3023

31-
var contentPanel = createContentPanel(project, referencedFiles);
32-
add(createToggleButton(contentPanel, referencedFiles.size()), BorderLayout.NORTH);
24+
var contentPanel = createContentPanel(links);
25+
add(createToggleButton(contentPanel, links.size()), BorderLayout.NORTH);
3326
add(contentPanel, BorderLayout.CENTER);
3427
}
3528

36-
private JPanel createContentPanel(Project project, List<VirtualFile> referencedFiles) {
29+
private JPanel createContentPanel(List<ActionLink> links) {
3730
var panel = new JPanel();
3831
panel.setOpaque(false);
3932
panel.setVisible(true);
4033
panel.setLayout(new BoxLayout(panel, BoxLayout.Y_AXIS));
4134
panel.setBorder(JBUI.Borders.empty(4, 0));
42-
referencedFiles.stream()
43-
.map(virtualFile -> {
44-
var actionLink = new ActionLink(
45-
Paths.get(virtualFile.getPath()).getFileName().toString(),
46-
event -> {
47-
FileEditorManager.getInstance(project)
48-
.openFile(Objects.requireNonNull(virtualFile), true);
49-
});
50-
actionLink.setIcon(virtualFile.getFileType().getIcon());
51-
return actionLink;
52-
})
53-
.forEach(link -> {
54-
panel.add(link);
55-
panel.add(Box.createVerticalStrut(4));
56-
});
35+
links.forEach(link -> {
36+
panel.add(link);
37+
panel.add(Box.createVerticalStrut(4));
38+
});
5739
return panel;
5840
}
5941

src/main/kotlin/ee/carlrobert/codegpt/CodeGPTLookupListener.kt

+13
Original file line numberDiff line numberDiff line change
@@ -5,13 +5,16 @@ import com.intellij.codeInsight.lookup.LookupEvent
55
import com.intellij.codeInsight.lookup.LookupListener
66
import com.intellij.codeInsight.lookup.LookupManagerListener
77
import com.intellij.codeInsight.lookup.impl.LookupImpl
8+
import com.intellij.notification.NotificationType
89
import com.intellij.openapi.application.ApplicationManager
910
import com.intellij.openapi.application.runReadAction
1011
import com.intellij.openapi.components.service
12+
import com.intellij.openapi.editor.EditorKind
1113
import ee.carlrobert.codegpt.predictions.PredictionService
1214
import ee.carlrobert.codegpt.settings.GeneralSettings
1315
import ee.carlrobert.codegpt.settings.service.ServiceType
1416
import ee.carlrobert.codegpt.settings.service.codegpt.CodeGPTServiceSettings
17+
import ee.carlrobert.codegpt.ui.OverlayUtil
1518

1619
class CodeGPTLookupListener : LookupManagerListener {
1720
override fun activeLookupChanged(oldLookup: Lookup?, newLookup: Lookup?) {
@@ -34,10 +37,20 @@ class CodeGPTLookupListener : LookupManagerListener {
3437
val editor = newLookup.editor
3538
if (GeneralSettings.getSelectedService() != ServiceType.CODEGPT
3639
|| !service<CodeGPTServiceSettings>().state.nextEditsEnabled
40+
|| editor.editorKind != EditorKind.MAIN_EDITOR
3741
) {
3842
return
3943
}
4044

45+
val settings = service<CodeGPTServiceSettings>().state
46+
if (settings.codeCompletionSettings.codeCompletionsEnabled) {
47+
settings.codeCompletionSettings.codeCompletionsEnabled = false
48+
OverlayUtil.showNotification(
49+
"Code completions and multi-line edits cannot be active simultaneously.",
50+
NotificationType.WARNING
51+
)
52+
}
53+
4154
ApplicationManager.getApplication().executeOnPooledThread {
4255
service<PredictionService>().displayInlineDiff(editor)
4356
}

src/main/kotlin/ee/carlrobert/codegpt/codecompletions/DebouncedCodeCompletionProvider.kt

+5-5
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ import com.intellij.openapi.diagnostic.thisLogger
1212
import com.intellij.openapi.project.Project
1313
import com.intellij.openapi.util.TextRange
1414
import ee.carlrobert.codegpt.CodeGPTKeys.REMAINING_EDITOR_COMPLETION
15-
import ee.carlrobert.codegpt.codecompletions.edit.GrpcClientService
15+
import ee.carlrobert.codegpt.predictions.PredictionService
1616
import ee.carlrobert.codegpt.settings.GeneralSettings
1717
import ee.carlrobert.codegpt.settings.configuration.ConfigurationSettings
1818
import ee.carlrobert.codegpt.settings.service.ServiceType
@@ -56,8 +56,7 @@ class DebouncedCodeCompletionProvider : DebouncedInlineCompletionProvider() {
5656

5757
override suspend fun getSuggestionDebounced(request: InlineCompletionRequest): InlineCompletionSuggestion {
5858
val codegptSettings = service<CodeGPTServiceSettings>().state
59-
if (GeneralSettings.getSelectedService() == ServiceType.CODEGPT && codegptSettings.nextEditsEnabled
60-
) {
59+
if (GeneralSettings.getSelectedService() == ServiceType.CODEGPT && codegptSettings.nextEditsEnabled) {
6160
if (codegptSettings.codeCompletionSettings.codeCompletionsEnabled) {
6261
codegptSettings.codeCompletionSettings.codeCompletionsEnabled = false
6362
OverlayUtil.showNotification(
@@ -81,7 +80,7 @@ class DebouncedCodeCompletionProvider : DebouncedInlineCompletionProvider() {
8180
val project = request.editor.project ?: return
8281
try {
8382
CompletionProgressNotifier.update(project, true)
84-
project.service<GrpcClientService>().getNextEdit(request.editor)
83+
project.service<PredictionService>().displayInlineDiff(request.editor)
8584
} catch (ex: Exception) {
8685
logger.error("Error communicating with server: ${ex.message}")
8786
}
@@ -177,7 +176,8 @@ class DebouncedCodeCompletionProvider : DebouncedInlineCompletionProvider() {
177176
REMAINING_EDITOR_COMPLETION.get(event.toRequest()?.editor)?.isNotEmpty() ?: false
178177

179178
if (!codeCompletionsEnabled) {
180-
return selectedService == ServiceType.CODEGPT
179+
return event is InlineCompletionEvent.DocumentChange
180+
&& selectedService == ServiceType.CODEGPT
181181
&& service<CodeGPTServiceSettings>().state.nextEditsEnabled
182182
&& !hasActiveCompletion
183183
}

src/main/kotlin/ee/carlrobert/codegpt/toolwindow/ui/UserMessagePanel.kt

+20-4
Original file line numberDiff line numberDiff line change
@@ -5,11 +5,13 @@ import com.intellij.icons.AllIcons.Actions
55
import com.intellij.openapi.Disposable
66
import com.intellij.openapi.actionSystem.AnAction
77
import com.intellij.openapi.actionSystem.AnActionEvent
8+
import com.intellij.openapi.fileEditor.FileEditorManager
89
import com.intellij.openapi.project.Project
910
import com.intellij.openapi.vfs.LocalFileSystem
1011
import com.intellij.ui.ColorUtil
1112
import com.intellij.ui.JBColor
1213
import com.intellij.ui.RoundedIcon
14+
import com.intellij.ui.components.ActionLink
1315
import com.intellij.ui.components.JBLabel
1416
import com.intellij.util.ui.JBFont
1517
import com.intellij.util.ui.JBUI
@@ -28,6 +30,8 @@ import kotlinx.coroutines.Dispatchers
2830
import kotlinx.coroutines.launch
2931
import kotlinx.coroutines.withContext
3032
import java.awt.Image
33+
import java.awt.event.ActionEvent
34+
import java.awt.event.ActionListener
3135
import java.io.IOException
3236
import java.nio.file.Files
3337
import java.nio.file.Paths
@@ -194,11 +198,23 @@ class UserMessagePanel(
194198

195199
if (referencedFilePaths.isNotEmpty()) {
196200
CoroutineScope(Dispatchers.IO).launch {
197-
val referencedFiles = referencedFilePaths.mapNotNull {
198-
LocalFileSystem.getInstance().findFileByPath(it)
199-
}
201+
val links = referencedFilePaths
202+
.mapNotNull {
203+
LocalFileSystem.getInstance().findFileByPath(it)
204+
}
205+
.map {
206+
val actionLink = ActionLink(
207+
Paths.get(it.path).fileName.toString(),
208+
ActionListener { _: ActionEvent ->
209+
FileEditorManager.getInstance(project)
210+
.openFile(Objects.requireNonNull(it), true)
211+
})
212+
actionLink.icon = it.fileType.icon
213+
actionLink
214+
}
215+
.toList()
200216
withContext(Dispatchers.Main) {
201-
additionalContextPanel.add(SelectedFilesAccordion(project, referencedFiles))
217+
additionalContextPanel.add(SelectedFilesAccordion(links))
202218
}
203219
}
204220
}

0 commit comments

Comments
 (0)