From 083c11f923895d5213f2850534737eb6c856c6ce Mon Sep 17 00:00:00 2001 From: Carl-Robert Linnupuu Date: Wed, 21 Aug 2024 13:39:48 +0300 Subject: [PATCH] refactor: implement ConfigurationSettings as a Kotlin service (#634) --- .../ProjectCompilationStatusListener.java | 4 +- .../actions/editor/EditorActionsUtil.java | 2 +- .../CompletionRequestProvider.java | 18 +- .../completions/CompletionRequestService.java | 2 +- .../completions/MethodNameLookupListener.java | 4 +- .../configuration/ConfigurationComponent.java | 40 ++--- .../ConfigurationConfigurable.java | 9 +- .../configuration/ConfigurationSettings.java | 34 ---- .../configuration/ConfigurationState.java | 160 ------------------ .../chat/ChatToolWindowContentManager.java | 12 +- .../ee/carlrobert/codegpt/ui/OverlayUtil.java | 2 +- .../codegpt/CodeGPTProjectActivity.kt | 4 +- .../codegpt/CodeGPTUpdateActivity.kt | 5 +- .../CodeGPTInlineCompletionProvider.kt | 6 +- .../configuration/CommitMessageTemplate.kt | 4 +- .../configuration/ConfigurationSettings.kt | 42 +++++ .../ee/carlrobert/codegpt/util/EditorUtil.kt | 3 +- src/main/resources/META-INF/plugin.xml | 1 - .../DefaultCompletionRequestHandlerTest.kt | 4 +- .../chat/ChatToolWindowTabPanelTest.kt | 6 +- 20 files changed, 108 insertions(+), 254 deletions(-) delete mode 100644 src/main/java/ee/carlrobert/codegpt/settings/configuration/ConfigurationSettings.java delete mode 100644 src/main/java/ee/carlrobert/codegpt/settings/configuration/ConfigurationState.java create mode 100644 src/main/kotlin/ee/carlrobert/codegpt/settings/configuration/ConfigurationSettings.kt diff --git a/src/main/java/ee/carlrobert/codegpt/ProjectCompilationStatusListener.java b/src/main/java/ee/carlrobert/codegpt/ProjectCompilationStatusListener.java index 043d887d..e4e0930d 100644 --- a/src/main/java/ee/carlrobert/codegpt/ProjectCompilationStatusListener.java +++ b/src/main/java/ee/carlrobert/codegpt/ProjectCompilationStatusListener.java @@ -38,7 +38,7 @@ public class ProjectCompilationStatusListener implements CompilationStatusListen int errors, int warnings, @NotNull CompileContext compileContext) { - var success = !ConfigurationSettings.getCurrentState().isCaptureCompileErrors() + var success = !ConfigurationSettings.getState().getCaptureCompileErrors() || (!aborted && errors == 0 && warnings == 0); if (success) { return; @@ -53,7 +53,7 @@ public class ProjectCompilationStatusListener implements CompilationStatusListen .sendMessage(getMultiFileMessage(compileContext), FIX_COMPILE_ERRORS))) .addAction(NotificationAction.createSimpleExpiring( CodeGPTBundle.get("shared.notification.doNotShowAgain"), - () -> ConfigurationSettings.getCurrentState().setCaptureCompileErrors(false))) + () -> ConfigurationSettings.getState().setCaptureCompileErrors(false))) .notify(project); } } 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 ab199481..58e3c60d 100644 --- a/src/main/java/ee/carlrobert/codegpt/actions/editor/EditorActionsUtil.java +++ b/src/main/java/ee/carlrobert/codegpt/actions/editor/EditorActionsUtil.java @@ -51,7 +51,7 @@ public class EditorActionsUtil { group.add(new CustomPromptAction()); group.addSeparator(); - var configuredActions = ConfigurationSettings.getCurrentState().getTableData(); + var configuredActions = ConfigurationSettings.getState().getTableData(); configuredActions.forEach((label, prompt) -> { // using label as action description to prevent com.intellij.diagnostic.PluginException // https://github.com/carlrobertoh/CodeGPT/issues/95 diff --git a/src/main/java/ee/carlrobert/codegpt/completions/CompletionRequestProvider.java b/src/main/java/ee/carlrobert/codegpt/completions/CompletionRequestProvider.java index e1d21b66..9886b420 100644 --- a/src/main/java/ee/carlrobert/codegpt/completions/CompletionRequestProvider.java +++ b/src/main/java/ee/carlrobert/codegpt/completions/CompletionRequestProvider.java @@ -134,7 +134,7 @@ public class CompletionRequestProvider { new OpenAIChatCompletionStandardMessage("user", context))) .setModel(model) .setStream(true) - .setMaxTokens(ConfigurationSettings.getCurrentState().getMaxTokens()) + .setMaxTokens(ConfigurationSettings.getState().getMaxTokens()) .build(); } @@ -202,7 +202,7 @@ public class CompletionRequestProvider { systemPrompt, message.getPrompt(), conversation.getMessages()); - var configuration = ConfigurationSettings.getCurrentState(); + var configuration = ConfigurationSettings.getState(); return new LlamaCompletionRequest.Builder(prompt) .setN_predict(configuration.getMaxTokens()) .setTemperature(configuration.getTemperature()) @@ -217,7 +217,7 @@ public class CompletionRequestProvider { public OpenAIChatCompletionRequest buildOpenAIChatCompletionRequest( @Nullable String model, CallParameters callParameters) { - var configuration = ConfigurationSettings.getCurrentState(); + var configuration = ConfigurationSettings.getState(); var requestBuilder = new OpenAIChatCompletionRequest.Builder( buildOpenAIMessages(model, callParameters)) .setModel(model) @@ -242,7 +242,7 @@ public class CompletionRequestProvider { public GoogleCompletionRequest buildGoogleChatCompletionRequest( @Nullable String model, CallParameters callParameters) { - var configuration = ConfigurationSettings.getCurrentState(); + var configuration = ConfigurationSettings.getState(); return new GoogleCompletionRequest.Builder(buildGoogleMessages(model, callParameters)) .generationConfig(new GoogleGenerationConfig.Builder() .maxOutputTokens(configuration.getMaxTokens()) @@ -309,7 +309,7 @@ public class CompletionRequestProvider { public ClaudeCompletionRequest buildAnthropicChatCompletionRequest( CallParameters callParameters) { - var configuration = ConfigurationSettings.getCurrentState(); + var configuration = ConfigurationSettings.getState(); var settings = AnthropicSettings.getCurrentState(); var request = new ClaudeCompletionRequest(); request.setModel(settings.getModel()); @@ -342,14 +342,14 @@ public class CompletionRequestProvider { public OllamaChatCompletionRequest buildOllamaChatCompletionRequest( CallParameters callParameters ) { - var configuration = ConfigurationSettings.getCurrentState(); + var configuration = ConfigurationSettings.getState(); var settings = ApplicationManager.getApplication().getService(OllamaSettings.class).getState(); return new OllamaChatCompletionRequest .Builder(settings.getModel(), buildOllamaMessages(callParameters)) .setStream(true) .setOptions(new OllamaParameters.Builder() .numPredict(configuration.getMaxTokens()) - .temperature(configuration.getTemperature()) + .temperature((double) configuration.getTemperature()) .build()) .build(); } @@ -474,7 +474,7 @@ public class CompletionRequestProvider { int totalUsage = messages.parallelStream() .mapToInt(encodingManager::countMessageTokens) - .sum() + ConfigurationSettings.getCurrentState().getMaxTokens(); + .sum() + ConfigurationSettings.getState().getMaxTokens(); int modelMaxTokens; try { modelMaxTokens = OpenAIChatCompletionModel.findByCode(model).getMaxTokens(); @@ -550,7 +550,7 @@ public class CompletionRequestProvider { int totalUsage = messages.parallelStream() .mapToInt(message -> encodingManager.countMessageTokens(message.getRole(), String.join(",", message.getParts().stream().map(GoogleContentPart::getText).toList()))) - .sum() + ConfigurationSettings.getCurrentState().getMaxTokens(); + .sum() + ConfigurationSettings.getState().getMaxTokens(); int modelMaxTokens; try { modelMaxTokens = GoogleModel.findByCode(model).getMaxTokens(); diff --git a/src/main/java/ee/carlrobert/codegpt/completions/CompletionRequestService.java b/src/main/java/ee/carlrobert/codegpt/completions/CompletionRequestService.java index f84c42d8..56066bad 100644 --- a/src/main/java/ee/carlrobert/codegpt/completions/CompletionRequestService.java +++ b/src/main/java/ee/carlrobert/codegpt/completions/CompletionRequestService.java @@ -133,7 +133,7 @@ public final class CompletionRequestService { String systemPrompt, String gitDiff, CompletionEventListener eventListener) { - var configuration = ConfigurationSettings.getCurrentState(); + var configuration = ConfigurationSettings.getState(); var openaiRequestBuilder = new Builder(List.of( new OpenAIChatCompletionStandardMessage("system", systemPrompt), new OpenAIChatCompletionStandardMessage("user", gitDiff))) diff --git a/src/main/java/ee/carlrobert/codegpt/completions/MethodNameLookupListener.java b/src/main/java/ee/carlrobert/codegpt/completions/MethodNameLookupListener.java index c95e3055..35104283 100644 --- a/src/main/java/ee/carlrobert/codegpt/completions/MethodNameLookupListener.java +++ b/src/main/java/ee/carlrobert/codegpt/completions/MethodNameLookupListener.java @@ -18,8 +18,8 @@ public class MethodNameLookupListener implements LookupManagerListener { @Override public void activeLookupChanged(@Nullable Lookup oldLookup, @Nullable Lookup newLookup) { - if (!ConfigurationSettings.getCurrentState().isMethodNameGenerationEnabled() - || !CompletionRequestService.getInstance().isRequestAllowed() + if (!ConfigurationSettings.getState().getMethodNameGenerationEnabled() + || !CompletionRequestService.isRequestAllowed() || !(newLookup instanceof LookupImpl lookup)) { return; } diff --git a/src/main/java/ee/carlrobert/codegpt/settings/configuration/ConfigurationComponent.java b/src/main/java/ee/carlrobert/codegpt/settings/configuration/ConfigurationComponent.java index eaf67309..6f921848 100644 --- a/src/main/java/ee/carlrobert/codegpt/settings/configuration/ConfigurationComponent.java +++ b/src/main/java/ee/carlrobert/codegpt/settings/configuration/ConfigurationComponent.java @@ -52,7 +52,9 @@ public class ConfigurationComponent { private final IntegerField maxTokensField; private final JBTextField temperatureField; - public ConfigurationComponent(Disposable parentDisposable, ConfigurationState configuration) { + public ConfigurationComponent( + Disposable parentDisposable, + ConfigurationSettingsState configuration) { table = new JBTable(new DefaultTableModel( EditorActionsUtil.toArray(configuration.getTableData()), new String[]{ @@ -99,26 +101,26 @@ public class ConfigurationComponent { checkForPluginUpdatesCheckBox = new JBCheckBox( CodeGPTBundle.get("configurationConfigurable.checkForPluginUpdates.label"), - configuration.isCheckForPluginUpdates()); + configuration.getCheckForPluginUpdates()); checkForNewScreenshotsCheckBox = new JBCheckBox( CodeGPTBundle.get("configurationConfigurable.checkForNewScreenshots.label"), - configuration.isCheckForNewScreenshots()); + configuration.getCheckForNewScreenshots()); openNewTabCheckBox = new JBCheckBox( CodeGPTBundle.get("configurationConfigurable.openNewTabCheckBox.label"), - configuration.isCreateNewChatOnEachAction()); + configuration.getCreateNewChatOnEachAction()); methodNameGenerationCheckBox = new JBCheckBox( CodeGPTBundle.get("configurationConfigurable.enableMethodNameGeneration.label"), - configuration.isMethodNameGenerationEnabled()); + configuration.getMethodNameGenerationEnabled()); autoFormattingCheckBox = new JBCheckBox( CodeGPTBundle.get("configurationConfigurable.autoFormatting.label"), - configuration.isAutoFormattingEnabled()); + configuration.getAutoFormattingEnabled()); autocompletionPostProcessingCheckBox = new JBCheckBox( CodeGPTBundle.get("configurationConfigurable.autocompletionPostProcessing.label"), - configuration.isAutocompletionPostProcessingEnabled() + configuration.getAutocompletionPostProcessingEnabled() ); autocompletionContextAwareCheckBox = new JBCheckBox( CodeGPTBundle.get("configurationConfigurable.autocompletionContextAwareCheckBox.label"), - configuration.isAutocompletionPostProcessingEnabled() + configuration.getAutocompletionContextAwareEnabled() ); mainPanel = FormBuilder.createFormBuilder() @@ -146,11 +148,11 @@ public class ConfigurationComponent { return mainPanel; } - public ConfigurationState getCurrentFormState() { - var state = new ConfigurationState(); + public ConfigurationSettingsState getCurrentFormState() { + var state = new ConfigurationSettingsState(); state.setTableData(getTableData()); state.setMaxTokens(maxTokensField.getValue()); - state.setTemperature(Double.parseDouble(temperatureField.getText())); + state.setTemperature(Float.parseFloat(temperatureField.getText())); state.setCommitMessagePrompt(commitMessagePromptTextArea.getText()); state.setCheckForPluginUpdates(checkForPluginUpdatesCheckBox.isSelected()); state.setCheckForNewScreenshots(checkForNewScreenshotsCheckBox.isSelected()); @@ -163,20 +165,20 @@ public class ConfigurationComponent { } public void resetForm() { - var configuration = ConfigurationSettings.getCurrentState(); + var configuration = ConfigurationSettings.getState(); setTableData(configuration.getTableData()); maxTokensField.setValue(configuration.getMaxTokens()); temperatureField.setText(String.valueOf(configuration.getTemperature())); commitMessagePromptTextArea.setText(configuration.getCommitMessagePrompt()); - checkForPluginUpdatesCheckBox.setSelected(configuration.isCheckForPluginUpdates()); - checkForNewScreenshotsCheckBox.setSelected(configuration.isCheckForNewScreenshots()); - openNewTabCheckBox.setSelected(configuration.isCreateNewChatOnEachAction()); - methodNameGenerationCheckBox.setSelected(configuration.isMethodNameGenerationEnabled()); - autoFormattingCheckBox.setSelected(configuration.isAutoFormattingEnabled()); + checkForPluginUpdatesCheckBox.setSelected(configuration.getCheckForPluginUpdates()); + checkForNewScreenshotsCheckBox.setSelected(configuration.getCheckForNewScreenshots()); + openNewTabCheckBox.setSelected(configuration.getCreateNewChatOnEachAction()); + methodNameGenerationCheckBox.setSelected(configuration.getMethodNameGenerationEnabled()); + autoFormattingCheckBox.setSelected(configuration.getAutoFormattingEnabled()); autocompletionPostProcessingCheckBox.setSelected( - configuration.isAutocompletionPostProcessingEnabled()); + configuration.getAutocompletionPostProcessingEnabled()); autocompletionContextAwareCheckBox.setSelected( - configuration.isAutocompletionContextAwareEnabled()); + configuration.getAutocompletionContextAwareEnabled()); } private Map getTableData() { diff --git a/src/main/java/ee/carlrobert/codegpt/settings/configuration/ConfigurationConfigurable.java b/src/main/java/ee/carlrobert/codegpt/settings/configuration/ConfigurationConfigurable.java index 9dc85840..6c286e1b 100644 --- a/src/main/java/ee/carlrobert/codegpt/settings/configuration/ConfigurationConfigurable.java +++ b/src/main/java/ee/carlrobert/codegpt/settings/configuration/ConfigurationConfigurable.java @@ -1,6 +1,7 @@ package ee.carlrobert.codegpt.settings.configuration; import com.intellij.openapi.Disposable; +import com.intellij.openapi.application.ApplicationManager; import com.intellij.openapi.options.Configurable; import com.intellij.openapi.util.Disposer; import ee.carlrobert.codegpt.CodeGPTBundle; @@ -27,19 +28,19 @@ public class ConfigurationConfigurable implements Configurable { parentDisposable = Disposer.newDisposable(); component = new ConfigurationComponent( parentDisposable, - ConfigurationSettings.getCurrentState()); + ConfigurationSettings.getState()); return component.getPanel(); } @Override public boolean isModified() { - return !component.getCurrentFormState() - .equals(ConfigurationSettings.getCurrentState()); + return !component.getCurrentFormState().equals(ConfigurationSettings.getState()); } @Override public void apply() { - ConfigurationSettings.getInstance().loadState(component.getCurrentFormState()); + ApplicationManager.getApplication().getService(ConfigurationSettings.class) + .loadState(component.getCurrentFormState()); EditorActionsUtil.refreshActions(); } diff --git a/src/main/java/ee/carlrobert/codegpt/settings/configuration/ConfigurationSettings.java b/src/main/java/ee/carlrobert/codegpt/settings/configuration/ConfigurationSettings.java deleted file mode 100644 index abcce780..00000000 --- a/src/main/java/ee/carlrobert/codegpt/settings/configuration/ConfigurationSettings.java +++ /dev/null @@ -1,34 +0,0 @@ -package ee.carlrobert.codegpt.settings.configuration; - -import com.intellij.openapi.application.ApplicationManager; -import com.intellij.openapi.components.PersistentStateComponent; -import com.intellij.openapi.components.State; -import com.intellij.openapi.components.Storage; -import org.jetbrains.annotations.NotNull; - -@State( - name = "CodeGPT_ConfigurationSettings_210", - storages = @Storage("CodeGPT_ConfigurationSettings_210.xml")) -public class ConfigurationSettings implements PersistentStateComponent { - - private ConfigurationState state = new ConfigurationState(); - - @Override - @NotNull - public ConfigurationState getState() { - return state; - } - - @Override - public void loadState(@NotNull ConfigurationState state) { - this.state = state; - } - - public static ConfigurationState getCurrentState() { - return getInstance().getState(); - } - - public static ConfigurationSettings getInstance() { - return ApplicationManager.getApplication().getService(ConfigurationSettings.class); - } -} diff --git a/src/main/java/ee/carlrobert/codegpt/settings/configuration/ConfigurationState.java b/src/main/java/ee/carlrobert/codegpt/settings/configuration/ConfigurationState.java deleted file mode 100644 index 1331750f..00000000 --- a/src/main/java/ee/carlrobert/codegpt/settings/configuration/ConfigurationState.java +++ /dev/null @@ -1,160 +0,0 @@ -package ee.carlrobert.codegpt.settings.configuration; - -import static ee.carlrobert.codegpt.completions.CompletionRequestProvider.GENERATE_COMMIT_MESSAGE_SYSTEM_PROMPT; - -import ee.carlrobert.codegpt.actions.editor.EditorActionsUtil; -import java.util.Map; -import java.util.Objects; - -public class ConfigurationState { - - private String commitMessagePrompt = GENERATE_COMMIT_MESSAGE_SYSTEM_PROMPT; - private int maxTokens = 2048; - private double temperature = 0.1; - private boolean checkForPluginUpdates = true; - private boolean checkForNewScreenshots = false; - private boolean createNewChatOnEachAction; - private boolean ignoreGitCommitTokenLimit; - private boolean methodNameGenerationEnabled = true; - private boolean captureCompileErrors = true; - private boolean autoFormattingEnabled = true; - private boolean autocompletionPostProcessingEnabled = false; - private boolean autocompletionContextAwareEnabled = false; - private Map tableData = EditorActionsUtil.DEFAULT_ACTIONS; - - public String getCommitMessagePrompt() { - return commitMessagePrompt; - } - - public void setCommitMessagePrompt(String commitMessagePrompt) { - this.commitMessagePrompt = commitMessagePrompt; - } - - public int getMaxTokens() { - return maxTokens; - } - - public void setMaxTokens(int maxTokens) { - this.maxTokens = maxTokens; - } - - public double getTemperature() { - return temperature; - } - - public void setTemperature(double temperature) { - this.temperature = temperature; - } - - public boolean isCreateNewChatOnEachAction() { - return createNewChatOnEachAction; - } - - public void setCreateNewChatOnEachAction(boolean createNewChatOnEachAction) { - this.createNewChatOnEachAction = createNewChatOnEachAction; - } - - public boolean isCheckForNewScreenshots() { - return checkForNewScreenshots; - } - - public void setCheckForNewScreenshots(boolean checkForNewScreenshots) { - this.checkForNewScreenshots = checkForNewScreenshots; - } - - public Map getTableData() { - return tableData; - } - - public void setTableData(Map tableData) { - this.tableData = tableData; - } - - public boolean isCheckForPluginUpdates() { - return checkForPluginUpdates; - } - - public void setCheckForPluginUpdates(boolean checkForPluginUpdates) { - this.checkForPluginUpdates = checkForPluginUpdates; - } - - public boolean isIgnoreGitCommitTokenLimit() { - return ignoreGitCommitTokenLimit; - } - - public void setIgnoreGitCommitTokenLimit(boolean ignoreGitCommitTokenLimit) { - this.ignoreGitCommitTokenLimit = ignoreGitCommitTokenLimit; - } - - public boolean isMethodNameGenerationEnabled() { - return methodNameGenerationEnabled; - } - - public void setMethodNameGenerationEnabled(boolean methodNameGenerationEnabled) { - this.methodNameGenerationEnabled = methodNameGenerationEnabled; - } - - public boolean isCaptureCompileErrors() { - return captureCompileErrors; - } - - public void setCaptureCompileErrors(boolean captureCompileErrors) { - this.captureCompileErrors = captureCompileErrors; - } - - public boolean isAutoFormattingEnabled() { - return autoFormattingEnabled; - } - - public void setAutoFormattingEnabled(boolean autoFormattingEnabled) { - this.autoFormattingEnabled = autoFormattingEnabled; - } - - public boolean isAutocompletionPostProcessingEnabled() { - return autocompletionPostProcessingEnabled; - } - - public void setAutocompletionPostProcessingEnabled(boolean autocompletionPostProcessingEnabled) { - this.autocompletionPostProcessingEnabled = autocompletionPostProcessingEnabled; - } - - public boolean isAutocompletionContextAwareEnabled() { - return autocompletionContextAwareEnabled; - } - - public void setAutocompletionContextAwareEnabled(boolean autocompletionContextAwareEnabled) { - this.autocompletionContextAwareEnabled = autocompletionContextAwareEnabled; - } - - @Override - public boolean equals(Object o) { - if (this == o) { - return true; - } - if (!(o instanceof ConfigurationState that)) { - return false; - } - return maxTokens == that.maxTokens - && Double.compare(temperature, that.temperature) == 0 - && checkForPluginUpdates == that.checkForPluginUpdates - && checkForNewScreenshots == that.checkForNewScreenshots - && createNewChatOnEachAction == that.createNewChatOnEachAction - && ignoreGitCommitTokenLimit == that.ignoreGitCommitTokenLimit - && methodNameGenerationEnabled == that.methodNameGenerationEnabled - && captureCompileErrors == that.captureCompileErrors - && autoFormattingEnabled == that.autoFormattingEnabled - && autocompletionPostProcessingEnabled == that.autocompletionPostProcessingEnabled - && autocompletionContextAwareEnabled == that.autocompletionContextAwareEnabled - && Objects.equals(commitMessagePrompt, that.commitMessagePrompt) - && Objects.equals(tableData, that.tableData); - } - - @Override - public int hashCode() { - return Objects.hash(commitMessagePrompt, maxTokens, temperature, - checkForPluginUpdates, checkForNewScreenshots, createNewChatOnEachAction, - ignoreGitCommitTokenLimit, methodNameGenerationEnabled, captureCompileErrors, - autoFormattingEnabled, autocompletionPostProcessingEnabled, - autocompletionContextAwareEnabled, tableData); - } -} diff --git a/src/main/java/ee/carlrobert/codegpt/toolwindow/chat/ChatToolWindowContentManager.java b/src/main/java/ee/carlrobert/codegpt/toolwindow/chat/ChatToolWindowContentManager.java index b5ba9d70..c1f265f0 100644 --- a/src/main/java/ee/carlrobert/codegpt/toolwindow/chat/ChatToolWindowContentManager.java +++ b/src/main/java/ee/carlrobert/codegpt/toolwindow/chat/ChatToolWindowContentManager.java @@ -38,7 +38,7 @@ public final class ChatToolWindowContentManager { public void sendMessage(Message message, ConversationType conversationType) { getToolWindow().show(); - if (ConfigurationSettings.getCurrentState().isCreateNewChatOnEachAction() + if (ConfigurationSettings.getState().getCreateNewChatOnEachAction() || ConversationsState.getCurrentConversation() == null) { createNewTabPanel().sendMessage(message, conversationType); return; @@ -113,11 +113,11 @@ public final class ChatToolWindowContentManager { var toolWindow = toolWindowManager.getToolWindow("CodeGPT"); // https://intellij-support.jetbrains.com/hc/en-us/community/posts/11533368171026/comments/11538403084562 return Objects.requireNonNullElseGet(toolWindow, () -> toolWindowManager - .registerToolWindow(RegisterToolWindowTask.closable( - "CodeGPT", - () -> "CodeGPT", - Icons.DefaultSmall, - ToolWindowAnchor.RIGHT))); + .registerToolWindow(RegisterToolWindowTask.closable( + "CodeGPT", + () -> "CodeGPT", + Icons.DefaultSmall, + ToolWindowAnchor.RIGHT))); } private Optional tryFindFirstChatTabContent() { diff --git a/src/main/java/ee/carlrobert/codegpt/ui/OverlayUtil.java b/src/main/java/ee/carlrobert/codegpt/ui/OverlayUtil.java index a0a27f5a..2a5b3335 100644 --- a/src/main/java/ee/carlrobert/codegpt/ui/OverlayUtil.java +++ b/src/main/java/ee/carlrobert/codegpt/ui/OverlayUtil.java @@ -138,7 +138,7 @@ public class OverlayUtil { @Override public void rememberChoice(boolean isSelected, int exitCode) { if (isSelected) { - ConfigurationSettings.getCurrentState().setIgnoreGitCommitTokenLimit(true); + ConfigurationSettings.getState().setIgnoreGitCommitTokenLimit(true); } } diff --git a/src/main/kotlin/ee/carlrobert/codegpt/CodeGPTProjectActivity.kt b/src/main/kotlin/ee/carlrobert/codegpt/CodeGPTProjectActivity.kt index 03e40e21..c0d31bfb 100644 --- a/src/main/kotlin/ee/carlrobert/codegpt/CodeGPTProjectActivity.kt +++ b/src/main/kotlin/ee/carlrobert/codegpt/CodeGPTProjectActivity.kt @@ -30,7 +30,7 @@ class CodeGPTProjectActivity : ProjectActivity { } if (!ApplicationManager.getApplication().isUnitTestMode - && ConfigurationSettings.getCurrentState().isCheckForNewScreenshots + && service().state.checkForPluginUpdates ) { val desktopPath = Paths.get(System.getProperty("user.home"), "Desktop") project.service().watch(desktopPath) { @@ -62,7 +62,7 @@ class CodeGPTProjectActivity : ProjectActivity { .addAction(NotificationAction.createSimpleExpiring( CodeGPTBundle.get("shared.notification.doNotShowAgain") ) { - ConfigurationSettings.getCurrentState().isCheckForNewScreenshots = false + service().state.checkForNewScreenshots = false }) .notify(project) } diff --git a/src/main/kotlin/ee/carlrobert/codegpt/CodeGPTUpdateActivity.kt b/src/main/kotlin/ee/carlrobert/codegpt/CodeGPTUpdateActivity.kt index 505c5bea..39fd46be 100644 --- a/src/main/kotlin/ee/carlrobert/codegpt/CodeGPTUpdateActivity.kt +++ b/src/main/kotlin/ee/carlrobert/codegpt/CodeGPTUpdateActivity.kt @@ -4,6 +4,7 @@ import com.intellij.ide.plugins.InstalledPluginsState import com.intellij.notification.NotificationAction import com.intellij.notification.NotificationType import com.intellij.openapi.application.ApplicationManager +import com.intellij.openapi.components.service import com.intellij.openapi.progress.ProgressIndicator import com.intellij.openapi.progress.Task import com.intellij.openapi.project.Project @@ -27,7 +28,7 @@ class CodeGPTUpdateActivity : ProjectActivity { private fun schedulePluginUpdateChecks(project: Project) { val command = { - if (ConfigurationSettings.getCurrentState().isCheckForPluginUpdates) { + if (service().state.checkForPluginUpdates) { CheckForUpdatesTask(project).queue() } } @@ -57,7 +58,7 @@ class CodeGPTUpdateActivity : ProjectActivity { .addAction(NotificationAction.createSimpleExpiring( CodeGPTBundle.get("shared.notification.doNotShowAgain") ) { - ConfigurationSettings.getCurrentState().isCheckForPluginUpdates = false + service().state.checkForPluginUpdates = false }) .notify(project) } diff --git a/src/main/kotlin/ee/carlrobert/codegpt/codecompletions/CodeGPTInlineCompletionProvider.kt b/src/main/kotlin/ee/carlrobert/codegpt/codecompletions/CodeGPTInlineCompletionProvider.kt index 8cb78ff5..6fbe8d06 100644 --- a/src/main/kotlin/ee/carlrobert/codegpt/codecompletions/CodeGPTInlineCompletionProvider.kt +++ b/src/main/kotlin/ee/carlrobert/codegpt/codecompletions/CodeGPTInlineCompletionProvider.kt @@ -53,7 +53,7 @@ class CodeGPTInlineCompletionProvider : DebouncedInlineCompletionProvider() { return InlineCompletionSuggestion.Default(channelFlow { val caretOffset = withContext(Dispatchers.EDT) { editor.caretModel.offset } val infillContext = - if (service().state.isAutocompletionContextAwareEnabled) + if (service().state.autocompletionContextAwareEnabled) service().findContext(editor, caretOffset) else null val infillRequest = if (infillContext == null) { @@ -85,7 +85,7 @@ class CodeGPTInlineCompletionProvider : DebouncedInlineCompletionProvider() { val settings = service().state try { var inlineText = it.toString() - if (settings.isAutocompletionPostProcessingEnabled) { + if (settings.autocompletionPostProcessingEnabled) { inlineText = CodeCompletionParserFactory .getParserForFileExtension(request.file.virtualFile.extension) .parse( @@ -106,7 +106,7 @@ class CodeGPTInlineCompletionProvider : DebouncedInlineCompletionProvider() { } } catch (t: Throwable) { logger.error(t) - settings.isAutocompletionPostProcessingEnabled = false + settings.autocompletionPostProcessingEnabled = false } } ) diff --git a/src/main/kotlin/ee/carlrobert/codegpt/settings/configuration/CommitMessageTemplate.kt b/src/main/kotlin/ee/carlrobert/codegpt/settings/configuration/CommitMessageTemplate.kt index f074c2c9..234a72e3 100644 --- a/src/main/kotlin/ee/carlrobert/codegpt/settings/configuration/CommitMessageTemplate.kt +++ b/src/main/kotlin/ee/carlrobert/codegpt/settings/configuration/CommitMessageTemplate.kt @@ -34,7 +34,9 @@ class CommitMessageTemplate private constructor(project: Project) { fun getSystemPrompt(): String = service().state.commitMessagePrompt.let { template -> - placeholderStrategyMapping.entries.fold(template) { acc, (placeholder, strategy) -> + placeholderStrategyMapping.entries.fold( + template ?: "" + ) { acc, (placeholder, strategy) -> acc.replace("{${placeholder.name}}", strategy.getReplacementValue()) } } diff --git a/src/main/kotlin/ee/carlrobert/codegpt/settings/configuration/ConfigurationSettings.kt b/src/main/kotlin/ee/carlrobert/codegpt/settings/configuration/ConfigurationSettings.kt new file mode 100644 index 00000000..c1892f8a --- /dev/null +++ b/src/main/kotlin/ee/carlrobert/codegpt/settings/configuration/ConfigurationSettings.kt @@ -0,0 +1,42 @@ +package ee.carlrobert.codegpt.settings.configuration + +import com.intellij.openapi.components.* +import ee.carlrobert.codegpt.actions.editor.EditorActionsUtil +import ee.carlrobert.codegpt.completions.CompletionRequestProvider.GENERATE_COMMIT_MESSAGE_SYSTEM_PROMPT +import kotlin.math.max +import kotlin.math.min + +@Service +@State( + name = "CodeGPT_ConfigurationSettings_210", + storages = [Storage("CodeGPT_ConfigurationSettings_210.xml")] +) +class ConfigurationSettings : + SimplePersistentStateComponent(ConfigurationSettingsState()) { + companion object { + @JvmStatic + fun getState(): ConfigurationSettingsState { + return service().state + } + } +} + +class ConfigurationSettingsState : BaseState() { + var commitMessagePrompt by string(GENERATE_COMMIT_MESSAGE_SYSTEM_PROMPT) + var maxTokens by property(2048) + var temperature by property(0.1f) { max(0f, min(1f, it)) } + var checkForPluginUpdates by property(true) + var checkForNewScreenshots by property(false) + var createNewChatOnEachAction by property(false) + var ignoreGitCommitTokenLimit by property(false) + var methodNameGenerationEnabled by property(true) + var captureCompileErrors by property(true) + var autoFormattingEnabled by property(true) + var autocompletionPostProcessingEnabled by property(false) + var autocompletionContextAwareEnabled by property(false) + var tableData by map() + + init { + tableData.putAll(EditorActionsUtil.DEFAULT_ACTIONS) + } +} \ No newline at end of file diff --git a/src/main/kotlin/ee/carlrobert/codegpt/util/EditorUtil.kt b/src/main/kotlin/ee/carlrobert/codegpt/util/EditorUtil.kt index 1cfc0c56..43c71099 100644 --- a/src/main/kotlin/ee/carlrobert/codegpt/util/EditorUtil.kt +++ b/src/main/kotlin/ee/carlrobert/codegpt/util/EditorUtil.kt @@ -5,6 +5,7 @@ import com.intellij.openapi.application.ApplicationManager import com.intellij.openapi.application.PathManager import com.intellij.openapi.application.runUndoTransparentWriteAction import com.intellij.openapi.command.WriteCommandAction +import com.intellij.openapi.components.service import com.intellij.openapi.editor.Document import com.intellij.openapi.editor.Editor import com.intellij.openapi.editor.EditorFactory @@ -155,7 +156,7 @@ object EditorUtil { StringUtil.convertLineSeparators(newText) ) - if (ConfigurationSettings.getCurrentState().isAutoFormattingEnabled) { + if (service().state.autoFormattingEnabled) { reformatDocument( project, document, diff --git a/src/main/resources/META-INF/plugin.xml b/src/main/resources/META-INF/plugin.xml index 7f6a92f1..cd8c3663 100644 --- a/src/main/resources/META-INF/plugin.xml +++ b/src/main/resources/META-INF/plugin.xml @@ -67,7 +67,6 @@ - diff --git a/src/test/kotlin/ee/carlrobert/codegpt/completions/DefaultCompletionRequestHandlerTest.kt b/src/test/kotlin/ee/carlrobert/codegpt/completions/DefaultCompletionRequestHandlerTest.kt index 9e9c08c4..470ca072 100644 --- a/src/test/kotlin/ee/carlrobert/codegpt/completions/DefaultCompletionRequestHandlerTest.kt +++ b/src/test/kotlin/ee/carlrobert/codegpt/completions/DefaultCompletionRequestHandlerTest.kt @@ -86,7 +86,7 @@ class DefaultCompletionRequestHandlerTest : IntegrationTest() { fun testLlamaChatCompletionCall() { useLlamaService() - ConfigurationSettings.getCurrentState().maxTokens = 99 + service().state.maxTokens = 99 service().state.selectedPersona.instructions = "TEST_SYSTEM_PROMPT" val message = Message("TEST_PROMPT") val conversation = ConversationService.getInstance().startConversation() @@ -121,7 +121,7 @@ class DefaultCompletionRequestHandlerTest : IntegrationTest() { fun testOllamaChatCompletionCall() { useOllamaService() - ConfigurationSettings.getCurrentState().maxTokens = 99 + service().state.maxTokens = 99 service().state.selectedPersona.instructions = "TEST_SYSTEM_PROMPT" val message = Message("TEST_PROMPT") val conversation = ConversationService.getInstance().startConversation() diff --git a/src/test/kotlin/ee/carlrobert/codegpt/toolwindow/chat/ChatToolWindowTabPanelTest.kt b/src/test/kotlin/ee/carlrobert/codegpt/toolwindow/chat/ChatToolWindowTabPanelTest.kt index f282f6bd..a15274ff 100644 --- a/src/test/kotlin/ee/carlrobert/codegpt/toolwindow/chat/ChatToolWindowTabPanelTest.kt +++ b/src/test/kotlin/ee/carlrobert/codegpt/toolwindow/chat/ChatToolWindowTabPanelTest.kt @@ -346,10 +346,10 @@ class ChatToolWindowTabPanelTest : IntegrationTest() { fun testSendingLlamaMessage() { useLlamaService() - val configurationState = ConfigurationSettings.getCurrentState() + val configurationState = service().state service().state.selectedPersona.instructions = "TEST_SYSTEM_PROMPT" configurationState.maxTokens = 1000 - configurationState.temperature = 0.1 + configurationState.temperature = 0.1f val llamaSettings = LlamaSettings.getCurrentState() llamaSettings.isUseCustomModel = false llamaSettings.huggingFaceModel = HuggingFaceModel.CODE_LLAMA_7B_Q4 @@ -379,7 +379,7 @@ class ChatToolWindowTabPanelTest : IntegrationTest() { conversation.messages), configurationState.maxTokens, true, - configurationState.temperature, + configurationState.temperature.toDouble(), llamaSettings.topK, llamaSettings.topP, llamaSettings.minP,