fix: revert direct auto apply

This commit is contained in:
Carl-Robert Linnupuu 2025-07-21 11:43:59 +01:00
parent c2747b07af
commit a515bfc99e
2 changed files with 71 additions and 23 deletions

View file

@ -10,17 +10,22 @@ import com.intellij.openapi.editor.event.BulkAwareDocumentListener
import com.intellij.openapi.editor.event.DocumentEvent
import com.intellij.openapi.editor.ex.EditorEx
import com.intellij.openapi.project.Project
import com.intellij.openapi.application.ApplicationManager
import com.intellij.openapi.util.Disposer
import com.intellij.openapi.util.Key
import com.intellij.openapi.vfs.VirtualFile
import com.intellij.openapi.diagnostic.thisLogger
import com.intellij.openapi.vfs.readText
import com.intellij.util.ui.JBUI
import com.intellij.util.ui.components.BorderLayoutPanel
import ee.carlrobert.codegpt.codecompletions.CompletionProgressNotifier
import ee.carlrobert.codegpt.completions.AutoApplyParameters
import ee.carlrobert.codegpt.completions.CompletionRequestService
import ee.carlrobert.codegpt.toolwindow.chat.editor.diff.DiffSyncManager
import ee.carlrobert.codegpt.toolwindow.chat.editor.factory.ComponentFactory
import ee.carlrobert.codegpt.toolwindow.chat.editor.factory.ComponentFactory.EXPANDED_KEY
import ee.carlrobert.codegpt.toolwindow.chat.editor.factory.ComponentFactory.MIN_LINES_FOR_EXPAND
import ee.carlrobert.codegpt.toolwindow.chat.editor.header.DiffHeaderPanel
import ee.carlrobert.codegpt.toolwindow.chat.editor.state.EditorState
import ee.carlrobert.codegpt.toolwindow.chat.editor.state.EditorStateManager
import ee.carlrobert.codegpt.toolwindow.chat.parser.ReplaceWaiting
@ -42,6 +47,7 @@ class ResponseEditorPanel(
val RESPONSE_EDITOR_STATE_KEY = Key.create<EditorState>("proxyai.responseEditorState")
}
private val logger = thisLogger()
private val stateManager = EditorStateManager(project)
private var searchReplaceHandler: SearchReplaceHandler
@ -101,6 +107,66 @@ class ResponseEditorPanel(
responseEditorPanel.replaceEditor(oldEditor, newEditor)
})
}
internal fun createReplaceWaitingSegment(searchContent: String, replaceContent: String, virtualFile: VirtualFile): ReplaceWaiting {
return ReplaceWaiting(
search = searchContent,
replace = replaceContent,
language = virtualFile.extension ?: "text",
filePath = virtualFile.path
)
}
fun createDiffEditorForDirectApply(searchContent: String, replaceContent: String, virtualFile: VirtualFile) {
try {
val segment = createReplaceWaitingSegment(searchContent, "", virtualFile)
val oldEditor = stateManager.getCurrentState()?.editor
if (oldEditor == null) {
logger.warn("No current editor state found for direct apply")
return
}
val currentText = try {
virtualFile.readText()
} catch (e: Exception) {
logger.error("Failed to read file content for direct apply", e)
return
}
val containsText = currentText.contains(segment.search.trim())
val newState = if (containsText) {
stateManager.createFromSegment(segment)
} else {
stateManager.transitionToFailedDiffState(
segment.search,
segment.replace,
virtualFile
) ?: run {
logger.warn("Failed to transition to failed diff state")
return
}
}
replaceEditor(oldEditor, newState.editor)
val finalSegment = createReplaceWaitingSegment(searchContent, replaceContent, virtualFile)
newState.updateContent(finalSegment)
val currentEditor = newState.editor
val headerPanel = currentEditor.permanentHeaderComponent as? DiffHeaderPanel
ApplicationManager.getApplication().invokeLater {
if (!project.isDisposed) {
headerPanel?.handleDone()
CompletionProgressNotifier.update(project, false)
}
}
} catch (e: Exception) {
logger.error("Unexpected error during direct apply", e)
}
}
override fun dispose() {
val state = stateManager.getCurrentState()

View file

@ -3,17 +3,12 @@ package ee.carlrobert.codegpt.toolwindow.chat.editor.header
import com.intellij.icons.AllIcons
import com.intellij.openapi.actionSystem.*
import com.intellij.openapi.application.runInEdt
import com.intellij.openapi.application.runUndoTransparentWriteAction
import com.intellij.openapi.editor.ex.EditorEx
import com.intellij.openapi.project.Project
import com.intellij.openapi.ui.JBMenuItem
import com.intellij.openapi.ui.JBPopupMenu
import com.intellij.openapi.ui.MessageType
import com.intellij.openapi.ui.popup.JBPopupFactory
import com.intellij.openapi.vfs.readText
import com.intellij.openapi.vfs.writeText
import com.intellij.ui.AnimatedIcon
import com.intellij.ui.components.AnActionLink
import com.intellij.ui.components.JBLabel
import com.intellij.util.ui.JBUI
import ee.carlrobert.codegpt.CodeGPTBundle
@ -66,7 +61,7 @@ class DefaultHeaderPanel(config: HeaderConfig) : HeaderPanel(config) {
actionGroup.add(CopyAction(editor))
} else {
actionGroup.add(AutoApplyAction(project, editor, config.filePath, virtualFile) {
handleApply(project, editor, it)
handleApply(project, editor)
})
actionGroup.add(CopyAction(editor))
actionGroup.addSeparator()
@ -75,7 +70,7 @@ class DefaultHeaderPanel(config: HeaderConfig) : HeaderPanel(config) {
return createToolbar(actionGroup)
}
private fun handleApply(project: Project, editor: EditorEx, link: AnActionLink) {
private fun handleApply(project: Project, editor: EditorEx) {
val file = virtualFile
?: EditorUtil.getSelectedEditor(project)?.virtualFile
?: throw IllegalStateException("Virtual file is null")
@ -83,22 +78,9 @@ class DefaultHeaderPanel(config: HeaderConfig) : HeaderPanel(config) {
val directApplyThreshold = 0.85
val coefficient = StringUtil.getDiceCoefficient(editor.document.text, file.readText())
if (coefficient > directApplyThreshold) {
runUndoTransparentWriteAction {
file.writeText(
com.intellij.openapi.util.text.StringUtil.convertLineSeparators(
editor.document.text
)
)
}
val balloon = JBPopupFactory.getInstance()
.createHtmlTextBalloonBuilder(
CodeGPTBundle.get("toolwindow.chat.editor.action.autoApply.successMessage"),
MessageType.INFO,
null
)
.setFadeoutTime(3000)
.createBalloon()
balloon.showInCenterOf(link)
val responseEditorPanel = editor.component.parent as? ResponseEditorPanel
?: throw IllegalStateException("Could not find corresponding ResponseEditorPanel")
responseEditorPanel.createDiffEditorForDirectApply(file.readText(), editor.document.text, file)
return
}