From dfa551806b9c80a0cc36844dc4887aa3a7eb59d4 Mon Sep 17 00:00:00 2001 From: Carl-Robert Linnupuu Date: Mon, 28 Oct 2024 23:59:51 +0000 Subject: [PATCH] feat: additional validation for Auto Apply action --- .../chat/editor/actions/AutoApplyAction.kt | 61 ++++++++++++++----- .../resources/messages/codegpt.properties | 9 ++- 2 files changed, 55 insertions(+), 15 deletions(-) diff --git a/src/main/kotlin/ee/carlrobert/codegpt/toolwindow/chat/editor/actions/AutoApplyAction.kt b/src/main/kotlin/ee/carlrobert/codegpt/toolwindow/chat/editor/actions/AutoApplyAction.kt index 0e8277b1..617e0969 100644 --- a/src/main/kotlin/ee/carlrobert/codegpt/toolwindow/chat/editor/actions/AutoApplyAction.kt +++ b/src/main/kotlin/ee/carlrobert/codegpt/toolwindow/chat/editor/actions/AutoApplyAction.kt @@ -6,6 +6,7 @@ import com.intellij.diff.editor.ChainDiffVirtualFile import com.intellij.notification.NotificationType import com.intellij.openapi.actionSystem.ActionUpdateThread import com.intellij.openapi.actionSystem.AnActionEvent +import com.intellij.openapi.actionSystem.Presentation import com.intellij.openapi.application.runInEdt import com.intellij.openapi.components.service import com.intellij.openapi.editor.Editor @@ -20,6 +21,7 @@ import com.intellij.ui.components.ActionLink import com.intellij.ui.components.JBLabel import com.intellij.util.ui.JBUI import ee.carlrobert.codegpt.CodeGPTBundle +import ee.carlrobert.codegpt.EncodingManager import ee.carlrobert.codegpt.Icons import ee.carlrobert.codegpt.actions.ActionType import ee.carlrobert.codegpt.actions.TrackableAction @@ -55,15 +57,10 @@ class AutoApplyAction( override fun update(e: AnActionEvent) { val isCodeGPTSelected = GeneralSettings.getSelectedService() == ServiceType.CODEGPT - - e.presentation.apply { - isEnabled = isCodeGPTSelected - icon = if (isCodeGPTSelected) Icons.Lightning else Icons.LightningDisabled - text = if (isCodeGPTSelected) { - CodeGPTBundle.get("toolwindow.chat.editor.action.autoApply.title") - } else { - CodeGPTBundle.get("toolwindow.chat.editor.action.autoApply.disabledTitle") - } + if (isCodeGPTSelected) { + validateAndUpdatePresentation(e) + } else { + e.presentation.disableAction(CodeGPTBundle.get("toolwindow.chat.editor.action.autoApply.disabledTitle")) } } @@ -77,8 +74,10 @@ class AutoApplyAction( headerPanel.getComponent(1).isVisible = false - val acceptLink = createDisabledActionLink("Accept") - val rejectLink = createDisabledActionLink("Reject") + val acceptLink = + createDisabledActionLink(CodeGPTBundle.get("toolwindow.chat.editor.action.autoApply.accept")) + val rejectLink = + createDisabledActionLink(CodeGPTBundle.get("toolwindow.chat.editor.action.autoApply.reject")) val actionsPanel = JPanel(FlowLayout(FlowLayout.TRAILING, 8, 0)).apply { border = JBUI.Borders.empty(4, 0) @@ -103,7 +102,10 @@ class AutoApplyAction( val errorMessage = if (it is CodeGPTException) { it.detail } else { - "Something went wrong while applying changes. ${it.message}" + CodeGPTBundle.get( + "toolwindow.chat.editor.action.autoApply.error", + it.message + ) } OverlayUtil.showNotification(errorMessage, NotificationType.ERROR) resetState(mainEditor, actionsPanel) @@ -115,6 +117,33 @@ class AutoApplyAction( return ActionUpdateThread.EDT } + private fun validateAndUpdatePresentation(e: AnActionEvent) { + val activeEditor = e.project?.let { getSelectedEditor(project) } + if (activeEditor == null) { + e.presentation.disableAction(CodeGPTBundle.get("toolwindow.chat.editor.action.autoApply.noActiveFile")) + return + } + + val fileTokenCount = service().countTokens(activeEditor.document.text) + if (fileTokenCount > 4096) { + e.presentation.disableAction(CodeGPTBundle.get("toolwindow.chat.editor.action.autoApply.fileTooLarge")) + } else { + e.presentation.enableAction() + } + } + + private fun Presentation.disableAction(disabledText: String) { + isEnabled = false + icon = Icons.LightningDisabled + text = disabledText + } + + private fun Presentation.enableAction() { + isEnabled = true + icon = Icons.Lightning + text = CodeGPTBundle.get("toolwindow.chat.editor.action.autoApply.title") + } + private fun JButton.setupLink( mainEditor: Editor, actionsPanel: JPanel, @@ -171,12 +200,16 @@ internal class ApplyChangesBackgroundTask( private val request: AutoApplyRequest, private val onSuccess: (modifiedFileContent: String) -> Unit, private val onFailure: (ex: Exception) -> Unit, -) : Task.Backgroundable(project, "Apply changes", true) { +) : Task.Backgroundable( + project, + CodeGPTBundle.get("toolwindow.chat.editor.action.autoApply.taskTitle"), + true +) { override fun run(indicator: ProgressIndicator) { indicator.isIndeterminate = false indicator.fraction = 1.0 - indicator.text = "CodeGPT: Applying changes" + indicator.text = CodeGPTBundle.get("toolwindow.chat.editor.action.autoApply.loadingMessage") try { val modifiedFileContent = CompletionClientProvider.getCodeGPTClient() diff --git a/src/main/resources/messages/codegpt.properties b/src/main/resources/messages/codegpt.properties index b8894506..34a51295 100644 --- a/src/main/resources/messages/codegpt.properties +++ b/src/main/resources/messages/codegpt.properties @@ -173,8 +173,15 @@ toolwindow.chat.editor.action.copy.title=Copy toolwindow.chat.editor.action.copy.description=Copy generated code toolwindow.chat.editor.action.copy.success=Code copied! toolwindow.chat.editor.action.autoApply.title=Auto Apply -toolwindow.chat.editor.action.autoApply.disabledTitle=Auto Apply is only available with CodeGPT provider +toolwindow.chat.editor.action.autoApply.disabledTitle=This action is only available with CodeGPT provider toolwindow.chat.editor.action.autoApply.description=Apply suggested changes automatically +toolwindow.chat.editor.action.autoApply.noActiveFile=Active file not found +toolwindow.chat.editor.action.autoApply.fileTooLarge=Active file too large to process +toolwindow.chat.editor.action.autoApply.accept=Accept +toolwindow.chat.editor.action.autoApply.reject=Reject +toolwindow.chat.editor.action.autoApply.error=Something went wrong while applying changes. {0} +toolwindow.chat.editor.action.autoApply.taskTitle=Apply changes +toolwindow.chat.editor.action.autoApply.loadingMessage=CodeGPT: Applying changes toolwindow.chat.editor.action.diff.description=Diff editor code against the generated one toolwindow.chat.editor.action.edit.title=Edit Source toolwindow.chat.editor.action.disableEditing.title=Disable Editing