mirror of
https://github.com/carlrobertoh/ProxyAI.git
synced 2026-05-19 16:28:46 +00:00
feat: add open code assistant diff in editor action
This commit is contained in:
parent
c3031bbda8
commit
f2bb264244
5 changed files with 103 additions and 13 deletions
|
|
@ -7,6 +7,7 @@ import com.intellij.openapi.actionSystem.CommonDataKeys
|
|||
import com.intellij.openapi.actionSystem.DataContext
|
||||
import ee.carlrobert.codegpt.codecompletions.AcceptNextLineInlayAction
|
||||
import ee.carlrobert.codegpt.codecompletions.AcceptNextWordInlayAction
|
||||
import ee.carlrobert.codegpt.predictions.OpenPredictionAction
|
||||
import ee.carlrobert.codegpt.predictions.TriggerCustomPredictionAction
|
||||
|
||||
class InlayActionPromoter : ActionPromoter {
|
||||
|
|
@ -14,6 +15,7 @@ class InlayActionPromoter : ActionPromoter {
|
|||
val editor = CommonDataKeys.EDITOR.getData(context) ?: return emptyList()
|
||||
|
||||
actions.filterIsInstance<TriggerCustomPredictionAction>().takeIf { it.isNotEmpty() }?.let { return it }
|
||||
actions.filterIsInstance<OpenPredictionAction>().takeIf { it.isNotEmpty() }?.let { return it }
|
||||
|
||||
if (InlineCompletionContext.getOrNull(editor) == null) {
|
||||
return emptyList()
|
||||
|
|
|
|||
|
|
@ -13,6 +13,7 @@ import com.intellij.diff.util.DiffUtil
|
|||
import com.intellij.ide.plugins.newui.TagComponent
|
||||
import com.intellij.openapi.Disposable
|
||||
import com.intellij.openapi.actionSystem.ActionManager
|
||||
import com.intellij.openapi.components.service
|
||||
import com.intellij.openapi.editor.Document
|
||||
import com.intellij.openapi.editor.Editor
|
||||
import com.intellij.openapi.editor.LogicalPosition
|
||||
|
|
@ -30,11 +31,14 @@ import com.intellij.openapi.util.TextRange
|
|||
import com.intellij.openapi.util.UserDataHolder
|
||||
import com.intellij.openapi.util.UserDataHolderBase
|
||||
import com.intellij.testFramework.LightVirtualFile
|
||||
import com.intellij.ui.components.JBLabel
|
||||
import com.intellij.ui.components.JBScrollPane
|
||||
import com.intellij.util.concurrency.annotations.RequiresEdt
|
||||
import com.intellij.util.ui.JBUI
|
||||
import com.intellij.util.ui.components.BorderLayoutPanel
|
||||
import ee.carlrobert.codegpt.CodeGPTBundle
|
||||
import ee.carlrobert.codegpt.CodeGPTKeys
|
||||
import java.awt.BorderLayout
|
||||
import java.awt.Dimension
|
||||
import java.awt.FlowLayout
|
||||
import java.awt.Point
|
||||
|
|
@ -157,17 +161,24 @@ class CodeSuggestionDiffViewer(
|
|||
}
|
||||
|
||||
private fun getTagPanel(): JComponent {
|
||||
val tagPanel = JPanel(FlowLayout(FlowLayout.LEADING, 0, 0))
|
||||
if (!isManuallyOpened) {
|
||||
tagPanel.add(
|
||||
TagComponent(
|
||||
"Trigger manually: ${getShortcutText(TriggerCustomPredictionAction.ID)}"
|
||||
).apply {
|
||||
font = JBUI.Fonts.smallFont()
|
||||
}
|
||||
)
|
||||
tagPanel.add(Box.createHorizontalStrut(6))
|
||||
val tagPanel = JPanel(FlowLayout(FlowLayout.LEADING, 0, 0)).apply {
|
||||
isOpaque = false
|
||||
}
|
||||
tagPanel.add(
|
||||
TagComponent(
|
||||
"Open: ${getShortcutText(OpenPredictionAction.ID)}"
|
||||
).apply {
|
||||
setListener({ _, _ ->
|
||||
service<PredictionService>().openDirectPrediction(
|
||||
mainEditor,
|
||||
content2.document.text
|
||||
)
|
||||
popup.dispose()
|
||||
}, component)
|
||||
font = JBUI.Fonts.smallFont()
|
||||
}
|
||||
)
|
||||
tagPanel.add(Box.createHorizontalStrut(6))
|
||||
tagPanel.add(TagComponent("Accept: ${getShortcutText(AcceptNextPredictionRevisionAction.ID)}").apply {
|
||||
setListener({ _, _ ->
|
||||
applyChanges()
|
||||
|
|
@ -183,6 +194,25 @@ class CodeSuggestionDiffViewer(
|
|||
.andTransparent()
|
||||
.withBorder(JBUI.Borders.empty(4))
|
||||
.addToRight(getTagPanel())
|
||||
|
||||
val footerText = if (isManuallyOpened) {
|
||||
CodeGPTBundle.get("shared.escToCancel")
|
||||
} else {
|
||||
"Trigger manually: ${getShortcutText(OpenPredictionAction.ID)} · ${CodeGPTBundle.get("shared.escToCancel")}"
|
||||
}
|
||||
|
||||
myEditor.component.add(
|
||||
BorderLayoutPanel()
|
||||
.addToRight(JBLabel(footerText)
|
||||
.apply {
|
||||
font = JBUI.Fonts.miniFont()
|
||||
})
|
||||
.apply {
|
||||
background = editor.backgroundColor
|
||||
border = JBUI.Borders.empty(4)
|
||||
},
|
||||
BorderLayout.SOUTH
|
||||
)
|
||||
}
|
||||
|
||||
private fun getVisibleAreaListener(): VisibleAreaListener {
|
||||
|
|
|
|||
|
|
@ -0,0 +1,30 @@
|
|||
package ee.carlrobert.codegpt.predictions
|
||||
|
||||
import com.intellij.codeInsight.hint.HintManagerImpl
|
||||
import com.intellij.openapi.actionSystem.DataContext
|
||||
import com.intellij.openapi.application.runInEdt
|
||||
import com.intellij.openapi.components.service
|
||||
import com.intellij.openapi.editor.Caret
|
||||
import com.intellij.openapi.editor.Editor
|
||||
import com.intellij.openapi.editor.actionSystem.EditorAction
|
||||
import com.intellij.openapi.editor.actionSystem.EditorWriteActionHandler
|
||||
import ee.carlrobert.codegpt.CodeGPTKeys.EDITOR_PREDICTION_DIFF_VIEWER
|
||||
|
||||
class OpenPredictionAction : EditorAction(Handler()), HintManagerImpl.ActionToIgnore {
|
||||
|
||||
companion object {
|
||||
const val ID = "codegpt.openPrediction"
|
||||
}
|
||||
|
||||
private class Handler : EditorWriteActionHandler() {
|
||||
|
||||
override fun doExecute(editor: Editor, caret: Caret?, dataContext: DataContext?) {
|
||||
val diffViewer = EDITOR_PREDICTION_DIFF_VIEWER.get(editor) ?: return
|
||||
val nextRevision = diffViewer.content2.document.text
|
||||
runInEdt {
|
||||
diffViewer.dispose()
|
||||
}
|
||||
service<PredictionService>().openDirectPrediction(editor, nextRevision)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,6 +1,7 @@
|
|||
package ee.carlrobert.codegpt.predictions
|
||||
|
||||
import com.intellij.codeInsight.lookup.LookupEvent
|
||||
import com.intellij.diff.DiffManager
|
||||
import com.intellij.notification.NotificationListener
|
||||
import com.intellij.notification.NotificationType
|
||||
import com.intellij.openapi.application.runInEdt
|
||||
|
|
@ -8,6 +9,8 @@ import com.intellij.openapi.application.runReadAction
|
|||
import com.intellij.openapi.components.Service
|
||||
import com.intellij.openapi.components.service
|
||||
import com.intellij.openapi.editor.Editor
|
||||
import com.intellij.openapi.project.Project
|
||||
import com.intellij.testFramework.LightVirtualFile
|
||||
import ee.carlrobert.codegpt.CodeGPTKeys
|
||||
import ee.carlrobert.codegpt.CodeGPTKeys.IS_FETCHING_COMPLETION
|
||||
import ee.carlrobert.codegpt.CodeGPTKeys.PENDING_PREDICTION_CALL
|
||||
|
|
@ -18,6 +21,7 @@ import ee.carlrobert.codegpt.settings.prompts.PromptsSettings
|
|||
import ee.carlrobert.codegpt.settings.service.codegpt.CodeGPTServiceSettings
|
||||
import ee.carlrobert.codegpt.ui.OverlayUtil
|
||||
import ee.carlrobert.codegpt.ui.OverlayUtil.getDefaultNotification
|
||||
import ee.carlrobert.codegpt.util.EditorDiffUtil.createDiffRequest
|
||||
import ee.carlrobert.codegpt.util.EditorUtil
|
||||
import ee.carlrobert.codegpt.util.GitUtil
|
||||
import ee.carlrobert.llm.client.codegpt.request.prediction.AutocompletionPredictionRequest
|
||||
|
|
@ -35,7 +39,7 @@ class PredictionService {
|
|||
fun displayDirectPrediction(editor: Editor) {
|
||||
val request = CompletionClientProvider.getCodeGPTClient()
|
||||
.buildDirectPredictionRequest(createDirectPredictionRequest(editor))
|
||||
displayInlineDiff(editor, request)
|
||||
displayInlineDiff(editor, request, true)
|
||||
}
|
||||
|
||||
fun displayAutocompletePrediction(editor: Editor, textToInsert: String, beforeApply: String) {
|
||||
|
|
@ -78,11 +82,19 @@ class PredictionService {
|
|||
}
|
||||
}
|
||||
|
||||
private fun displayInlineDiff(editor: Editor, request: Request) {
|
||||
private fun displayInlineDiff(
|
||||
editor: Editor,
|
||||
request: Request,
|
||||
isManuallyOpened: Boolean = false
|
||||
) {
|
||||
val prediction = getPrediction(editor, request)
|
||||
if (prediction != null && !prediction.nextRevision.isNullOrEmpty()) {
|
||||
runInEdt {
|
||||
CodeSuggestionDiffViewer.displayInlineDiff(editor, prediction.nextRevision)
|
||||
CodeSuggestionDiffViewer.displayInlineDiff(
|
||||
editor,
|
||||
prediction.nextRevision,
|
||||
isManuallyOpened
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -169,4 +181,13 @@ class PredictionService {
|
|||
conversationMessages = messages.toList()
|
||||
}
|
||||
}
|
||||
|
||||
fun openDirectPrediction(editor: Editor, nextRevision: String) {
|
||||
val project: Project = editor.project ?: return
|
||||
val tempDiffFile = LightVirtualFile(editor.virtualFile.name, nextRevision)
|
||||
val diffRequest = createDiffRequest(project, tempDiffFile, editor)
|
||||
runInEdt {
|
||||
service<DiffManager>().showDiff(project, diffRequest)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -108,6 +108,13 @@
|
|||
<keyboard-shortcut first-keystroke="ctrl ENTER" keymap="$default"/>
|
||||
</action>
|
||||
|
||||
<action
|
||||
id="codegpt.openPrediction"
|
||||
text="Open Prediction"
|
||||
class="ee.carlrobert.codegpt.predictions.OpenPredictionAction">
|
||||
<keyboard-shortcut first-keystroke="ctrl O" keymap="$default"/>
|
||||
</action>
|
||||
|
||||
<action
|
||||
id="codegpt.acceptNextInlayWord"
|
||||
text="Apply next word"
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue