mirror of
https://github.com/carlrobertoh/ProxyAI.git
synced 2026-07-09 17:28:59 +00:00
chore: upgrade to 2025.1 and align dependencies
This commit is contained in:
parent
c15976d4d9
commit
e5785180c6
11 changed files with 7 additions and 299 deletions
|
|
@ -63,7 +63,7 @@ dependencies {
|
|||
bundledPlugin("com.intellij.java")
|
||||
bundledPlugin("org.jetbrains.kotlin")
|
||||
bundledPlugin("Git4Idea")
|
||||
plugin("PythonCore:241.14494.240")
|
||||
plugin("PythonCore:251.25410.109")
|
||||
|
||||
testFramework(TestFrameworkType.Platform)
|
||||
testFramework(TestFrameworkType.JUnit5)
|
||||
|
|
|
|||
|
|
@ -8,11 +8,11 @@ pluginVersion = 3.6.4
|
|||
|
||||
# Supported build number ranges and IntelliJ Platform versions -> https://plugins.jetbrains.com/docs/intellij/build-number-ranges.html
|
||||
pluginSinceBuild = 241.1
|
||||
pluginUntilBuild = 252.*
|
||||
pluginUntilBuild = 253.*
|
||||
|
||||
# IntelliJ Platform Properties -> https://plugins.jetbrains.com/docs/intellij/tools-gradle-intellij-plugin.html#configuration-intellij-extension
|
||||
platformType = IC
|
||||
platformVersion = 2024.1.2
|
||||
platformVersion = 2025.1.1
|
||||
|
||||
# Plugin Dependencies -> https://plugins.jetbrains.com/docs/intellij/plugin-dependencies.html
|
||||
# Example: platformPlugins = com.intellij.java, com.jetbrains.php:203.4449.22
|
||||
|
|
|
|||
|
|
@ -1,20 +1,17 @@
|
|||
package ee.carlrobert.codegpt.actions
|
||||
|
||||
import com.intellij.codeInsight.inline.completion.session.InlineCompletionContext
|
||||
import com.intellij.openapi.actionSystem.ActionPromoter
|
||||
import com.intellij.openapi.actionSystem.AnAction
|
||||
import com.intellij.openapi.actionSystem.CommonDataKeys
|
||||
import com.intellij.openapi.actionSystem.DataContext
|
||||
import ee.carlrobert.codegpt.CodeGPTKeys
|
||||
import ee.carlrobert.codegpt.codecompletions.AcceptNextLineInlayAction
|
||||
import ee.carlrobert.codegpt.codecompletions.AcceptNextWordInlayAction
|
||||
import ee.carlrobert.codegpt.predictions.OpenPredictionAction
|
||||
import ee.carlrobert.codegpt.predictions.TriggerCustomPredictionAction
|
||||
import ee.carlrobert.codegpt.inlineedit.AcceptCurrentInlineEditAction
|
||||
import ee.carlrobert.codegpt.actions.editor.AcceptInlineEditAction
|
||||
import ee.carlrobert.codegpt.actions.editor.InlineEditContextMenuAction
|
||||
import ee.carlrobert.codegpt.actions.editor.InlineEditFloatingMenuAction
|
||||
import ee.carlrobert.codegpt.inlineedit.AcceptCurrentInlineEditAction
|
||||
import ee.carlrobert.codegpt.inlineedit.RejectCurrentInlineEditAction
|
||||
import ee.carlrobert.codegpt.predictions.OpenPredictionAction
|
||||
import ee.carlrobert.codegpt.predictions.TriggerCustomPredictionAction
|
||||
|
||||
class InlayActionPromoter : ActionPromoter {
|
||||
override fun promote(actions: List<AnAction>, context: DataContext): List<AnAction> {
|
||||
|
|
@ -36,10 +33,6 @@ class InlayActionPromoter : ActionPromoter {
|
|||
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()
|
||||
|
||||
actions.filterIsInstance<AcceptNextWordInlayAction>().takeIf { it.isNotEmpty() }?.let { return it }
|
||||
actions.filterIsInstance<AcceptNextLineInlayAction>().takeIf { it.isNotEmpty() }?.let { return it }
|
||||
return emptyList()
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,68 +0,0 @@
|
|||
package ee.carlrobert.codegpt.codecompletions
|
||||
|
||||
import com.intellij.codeInsight.inline.completion.InlineCompletion
|
||||
import com.intellij.codeInsight.inline.completion.InlineCompletionEvent
|
||||
import com.intellij.codeInsight.inline.completion.InlineCompletionHandler
|
||||
import com.intellij.codeInsight.inline.completion.InlineCompletionRequest
|
||||
import com.intellij.codeInsight.inline.completion.session.InlineCompletionSession
|
||||
import com.intellij.openapi.actionSystem.DataContext
|
||||
import com.intellij.openapi.application.runWriteAction
|
||||
import com.intellij.openapi.editor.Caret
|
||||
import com.intellij.openapi.editor.Editor
|
||||
import com.intellij.openapi.editor.actionSystem.EditorWriteActionHandler
|
||||
import com.intellij.openapi.util.TextRange
|
||||
|
||||
abstract class AbstractInlayActionHandler : EditorWriteActionHandler() {
|
||||
|
||||
abstract fun InlineCompletionSession.getTextToInsert(): String
|
||||
abstract fun InlineCompletionHandler.invoke(request: InlineCompletionRequest, range: TextRange)
|
||||
|
||||
override fun doExecute(editor: Editor, caret: Caret?, dataContext: DataContext?) {
|
||||
InlineCompletionSession.getOrNull(editor)?.let { session ->
|
||||
if (!session.isActive() || !session.context.isCurrentlyDisplaying()) return
|
||||
|
||||
// TODO: Implement brace matching
|
||||
InlineCompletion.getHandlerOrNull(editor)?.apply {
|
||||
val startOffset = editor.caretModel.offset
|
||||
val textToInsert = session.getTextToInsert()
|
||||
|
||||
withIgnoringDocumentChanges {
|
||||
val suggestionTextRange =
|
||||
TextRange(startOffset - textToInsert.length, startOffset)
|
||||
invoke(session.request, suggestionTextRange)
|
||||
|
||||
runWriteAction {
|
||||
editor.document.insertString(startOffset, textToInsert)
|
||||
editor.caretModel.moveToOffset(startOffset + textToInsert.length)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override fun isEnabledForCaret(
|
||||
editor: Editor,
|
||||
caret: Caret,
|
||||
dataContext: DataContext?
|
||||
): Boolean = InlineCompletionSession.getOrNull(editor)?.let {
|
||||
it.isActive() && it.context.isCurrentlyDisplaying()
|
||||
} ?: false
|
||||
}
|
||||
|
||||
internal abstract class ApplyNextInlaySuggestionEvent(
|
||||
private val originalRequest: InlineCompletionRequest,
|
||||
private val textRange: TextRange
|
||||
) : InlineCompletionEvent {
|
||||
|
||||
override fun toRequest(): InlineCompletionRequest {
|
||||
return InlineCompletionRequest(
|
||||
this,
|
||||
originalRequest.file,
|
||||
originalRequest.editor,
|
||||
originalRequest.document,
|
||||
textRange.startOffset,
|
||||
textRange.endOffset,
|
||||
originalRequest.lookupElement
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
@ -1,45 +0,0 @@
|
|||
package ee.carlrobert.codegpt.codecompletions
|
||||
|
||||
import ai.grazie.nlp.utils.takeWhitespaces
|
||||
import com.intellij.codeInsight.hint.HintManagerImpl
|
||||
import com.intellij.codeInsight.inline.completion.InlineCompletionHandler
|
||||
import com.intellij.codeInsight.inline.completion.InlineCompletionRequest
|
||||
import com.intellij.codeInsight.inline.completion.session.InlineCompletionSession
|
||||
import com.intellij.openapi.editor.actionSystem.EditorAction
|
||||
import com.intellij.openapi.util.TextRange
|
||||
|
||||
class AcceptNextLineInlayAction : EditorAction(Handler()), HintManagerImpl.ActionToIgnore {
|
||||
|
||||
companion object {
|
||||
const val ID = "codegpt.acceptNextInlayLine"
|
||||
}
|
||||
|
||||
private class Handler : AbstractInlayActionHandler() {
|
||||
|
||||
override fun InlineCompletionSession.getTextToInsert(): String {
|
||||
val completionText = context.textToInsert()
|
||||
val lineBreakIndex = completionText.indexOfFirst { it == '\n' }
|
||||
|
||||
return if (lineBreakIndex == -1) {
|
||||
completionText
|
||||
} else {
|
||||
val nextLineStart = lineBreakIndex + 1
|
||||
val whitespacesLength =
|
||||
completionText.substring(nextLineStart).takeWhitespaces().length
|
||||
completionText.substring(0, nextLineStart + whitespacesLength)
|
||||
}
|
||||
}
|
||||
|
||||
override fun InlineCompletionHandler.invoke(
|
||||
request: InlineCompletionRequest,
|
||||
range: TextRange
|
||||
) {
|
||||
invokeEvent(ApplyNextLineInlaySuggestionEvent(request, range))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
internal class ApplyNextLineInlaySuggestionEvent(
|
||||
originalRequest: InlineCompletionRequest,
|
||||
textRange: TextRange
|
||||
) : ApplyNextInlaySuggestionEvent(originalRequest, textRange)
|
||||
|
|
@ -1,34 +0,0 @@
|
|||
package ee.carlrobert.codegpt.codecompletions
|
||||
|
||||
import com.intellij.codeInsight.hint.HintManagerImpl
|
||||
import com.intellij.codeInsight.inline.completion.InlineCompletionHandler
|
||||
import com.intellij.codeInsight.inline.completion.InlineCompletionRequest
|
||||
import com.intellij.codeInsight.inline.completion.session.InlineCompletionSession
|
||||
import com.intellij.openapi.editor.actionSystem.EditorAction
|
||||
import com.intellij.openapi.util.TextRange
|
||||
|
||||
class AcceptNextWordInlayAction : EditorAction(Handler()), HintManagerImpl.ActionToIgnore {
|
||||
|
||||
companion object {
|
||||
const val ID = "codegpt.acceptNextInlayWord"
|
||||
}
|
||||
|
||||
private class Handler : AbstractInlayActionHandler() {
|
||||
|
||||
override fun InlineCompletionSession.getTextToInsert(): String {
|
||||
return CompletionSplitter.split(context.textToInsert())
|
||||
}
|
||||
|
||||
override fun InlineCompletionHandler.invoke(
|
||||
request: InlineCompletionRequest,
|
||||
range: TextRange
|
||||
) {
|
||||
invokeEvent(ApplyNextWordInlaySuggestionEvent(request, range))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
internal class ApplyNextWordInlaySuggestionEvent(
|
||||
originalRequest: InlineCompletionRequest,
|
||||
textRange: TextRange
|
||||
) : ApplyNextInlaySuggestionEvent(originalRequest, textRange)
|
||||
|
|
@ -1,9 +1,7 @@
|
|||
package ee.carlrobert.codegpt.codecompletions
|
||||
|
||||
import com.intellij.codeInsight.inline.completion.InlineCompletionProviderPresentation
|
||||
import com.intellij.openapi.actionSystem.ActionManager
|
||||
import com.intellij.openapi.components.service
|
||||
import com.intellij.openapi.keymap.KeymapUtil
|
||||
import com.intellij.openapi.project.Project
|
||||
import com.intellij.ui.components.JBLabel
|
||||
import ee.carlrobert.codegpt.Icons
|
||||
|
|
@ -17,9 +15,7 @@ class CodeCompletionProviderPresentation : InlineCompletionProviderPresentation
|
|||
project?.service<CodeCompletionService>()?.getSelectedModelCode() ?: ""
|
||||
val text = if (selectedModelCode.isNotEmpty()) {
|
||||
buildString {
|
||||
append("<html>Model: (<strong>$selectedModelCode</strong>) | ")
|
||||
append("Accept Word: (<strong>${getShortcutText(AcceptNextWordInlayAction.ID)}</strong>) | ")
|
||||
append("Accept Line: (<strong>${getShortcutText(AcceptNextLineInlayAction.ID)}</strong>)</html>")
|
||||
append("<html>Model: (<strong>$selectedModelCode</strong>)</html>")
|
||||
}
|
||||
} else {
|
||||
"ProxyAI"
|
||||
|
|
@ -27,10 +23,4 @@ class CodeCompletionProviderPresentation : InlineCompletionProviderPresentation
|
|||
|
||||
return JBLabel(text, Icons.DefaultSmall, SwingConstants.LEADING)
|
||||
}
|
||||
|
||||
private fun getShortcutText(actionId: String): String {
|
||||
return KeymapUtil.getFirstKeyboardShortcutText(
|
||||
ActionManager.getInstance().getAction(actionId)
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
@ -1,12 +1,8 @@
|
|||
package ee.carlrobert.codegpt.codecompletions
|
||||
|
||||
import ai.grazie.nlp.utils.takeWhitespaces
|
||||
import com.intellij.codeInsight.inline.completion.InlineCompletionEvent
|
||||
import com.intellij.codeInsight.inline.completion.elements.InlineCompletionGrayTextElement
|
||||
import com.intellij.codeInsight.inline.completion.suggestion.InlineCompletionSuggestionUpdateManager
|
||||
import com.intellij.codeInsight.inline.completion.suggestion.InlineCompletionSuggestionUpdateManager.UpdateResult
|
||||
import com.intellij.codeInsight.inline.completion.suggestion.InlineCompletionSuggestionUpdateManager.UpdateResult.Changed
|
||||
import com.intellij.codeInsight.inline.completion.suggestion.InlineCompletionSuggestionUpdateManager.UpdateResult.Invalidated
|
||||
import com.intellij.codeInsight.inline.completion.suggestion.InlineCompletionVariant
|
||||
import com.intellij.openapi.editor.Editor
|
||||
import ee.carlrobert.codegpt.CodeGPTKeys.REMAINING_EDITOR_COMPLETION
|
||||
|
|
@ -22,61 +18,6 @@ class CodeCompletionSuggestionUpdateAdapter :
|
|||
return super.onDocumentChange(event, variant)
|
||||
}
|
||||
|
||||
override fun onCustomEvent(
|
||||
event: InlineCompletionEvent,
|
||||
variant: InlineCompletionVariant.Snapshot
|
||||
): UpdateResult {
|
||||
if (variant.elements.isEmpty()) return Invalidated
|
||||
|
||||
val completionText = variant.elements.joinToString("") { it.text }
|
||||
return when (event) {
|
||||
is ApplyNextWordInlaySuggestionEvent -> handleNextWordEvent(event, variant, completionText)
|
||||
is ApplyNextLineInlaySuggestionEvent -> handleNextLineEvent(event, variant, completionText)
|
||||
else -> Invalidated
|
||||
}
|
||||
}
|
||||
|
||||
private fun handleNextWordEvent(
|
||||
event: ApplyNextWordInlaySuggestionEvent,
|
||||
variant: InlineCompletionVariant.Snapshot,
|
||||
completionText: String
|
||||
): UpdateResult {
|
||||
val textToInsert = CompletionSplitter.split(completionText)
|
||||
return createUpdatedVariant(event.toRequest().editor, variant, completionText, textToInsert)
|
||||
}
|
||||
|
||||
private fun handleNextLineEvent(
|
||||
event: ApplyNextLineInlaySuggestionEvent,
|
||||
variant: InlineCompletionVariant.Snapshot,
|
||||
completionText: String
|
||||
): UpdateResult {
|
||||
val lineBreakIndex = completionText.indexOf('\n')
|
||||
if (lineBreakIndex == -1) return Invalidated
|
||||
|
||||
val nextLineStart = lineBreakIndex + 1
|
||||
val whitespacesLength = completionText
|
||||
.substring(nextLineStart)
|
||||
.takeWhitespaces()
|
||||
.length
|
||||
val textToInsert = completionText.substring(0, nextLineStart + whitespacesLength)
|
||||
|
||||
return createUpdatedVariant(event.toRequest().editor, variant, completionText, textToInsert)
|
||||
}
|
||||
|
||||
private fun createUpdatedVariant(
|
||||
editor: Editor,
|
||||
variant: InlineCompletionVariant.Snapshot,
|
||||
completionText: String,
|
||||
textToInsert: String
|
||||
): UpdateResult {
|
||||
updateRemainingCompletion(editor, textToInsert)
|
||||
return Changed(
|
||||
variant.copy(
|
||||
listOf(InlineCompletionGrayTextElement(completionText.removePrefix(textToInsert)))
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
private fun updateRemainingCompletion(editor: Editor, textToInsert: String) {
|
||||
val remainingCompletion = REMAINING_EDITOR_COMPLETION.get(editor) ?: ""
|
||||
if (remainingCompletion.isNotEmpty()) {
|
||||
|
|
|
|||
|
|
@ -86,7 +86,6 @@ class PromptTextField(
|
|||
document.putUserData(PROMPT_FIELD_KEY, this)
|
||||
setPlaceholder(CodeGPTBundle.get("toolwindow.chat.textArea.emptyText"))
|
||||
|
||||
putClientProperty(UIUtil.HIDE_EDITOR_FROM_DATA_CONTEXT_PROPERTY, true)
|
||||
installPasteHandler()
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -143,18 +143,6 @@
|
|||
<keyboard-shortcut first-keystroke="ctrl ENTER" keymap="$default"/>
|
||||
</action>
|
||||
|
||||
<action
|
||||
id="codegpt.acceptNextInlayWord"
|
||||
text="Apply next word"
|
||||
use-shortcut-of="EditorNextWord"
|
||||
class="ee.carlrobert.codegpt.codecompletions.AcceptNextWordInlayAction"/>
|
||||
|
||||
<action
|
||||
id="codegpt.acceptNextInlayLine"
|
||||
text="Apply next line"
|
||||
use-shortcut-of="EditorLineEnd"
|
||||
class="ee.carlrobert.codegpt.codecompletions.AcceptNextLineInlayAction"/>
|
||||
|
||||
<group id="CodeGPTEditorPopup">
|
||||
<group id="action.editor.group.EditorActionGroup"
|
||||
text="ProxyAI"
|
||||
|
|
|
|||
|
|
@ -102,62 +102,6 @@ class CodeCompletionServiceTest : IntegrationTest() {
|
|||
}
|
||||
}
|
||||
|
||||
fun `test apply next partial completion word`() {
|
||||
useLlamaService(true, FeatureType.CODE_COMPLETION)
|
||||
service<CodeGPTServiceSettings>().state.nextEditsEnabled = false
|
||||
myFixture.configureByText(
|
||||
"CompletionTest.java",
|
||||
FileUtil.getResourceContent("/codecompletions/code-completion-file.txt")
|
||||
)
|
||||
myFixture.editor.caretModel.moveToVisualPosition(VisualPosition(3, 0))
|
||||
project.service<CodeCompletionCacheService>().clear()
|
||||
val expectedCompletion = "public void main"
|
||||
val prefix = """
|
||||
xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
|
||||
zzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzz
|
||||
[INPUT]
|
||||
c
|
||||
""".trimIndent()
|
||||
val suffix = """
|
||||
|
||||
[\INPUT]
|
||||
zzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzz
|
||||
xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
|
||||
""".trimIndent()
|
||||
expectLlama(StreamHttpExchange { request: RequestEntity ->
|
||||
assertThat(request.uri.path).isEqualTo("/completion")
|
||||
assertThat(request.method).isEqualTo("POST")
|
||||
assertThat(request.body)
|
||||
.extracting("prompt")
|
||||
.isEqualTo(
|
||||
InfillPromptTemplate.CODE_LLAMA.buildPrompt(
|
||||
InfillRequest.Builder(prefix, suffix, 0).build()
|
||||
)
|
||||
)
|
||||
listOf(
|
||||
jsonMapResponse(
|
||||
e("content", expectedCompletion),
|
||||
e("stop", true)
|
||||
)
|
||||
)
|
||||
})
|
||||
myFixture.type('c')
|
||||
assertInlineSuggestion("Failed to display initial inline suggestion.") {
|
||||
expectedCompletion == it
|
||||
}
|
||||
val offsetBeforeApply = myFixture.editor.caretModel.offset
|
||||
|
||||
myFixture.performEditorAction(AcceptNextWordInlayAction.ID)
|
||||
|
||||
assertInlineSuggestion("Failed to display next partial inline suggestion.") {
|
||||
myFixture.run {
|
||||
val appliedText =
|
||||
editor.document.getText(TextRange(offsetBeforeApply, editor.caretModel.offset))
|
||||
"public" == appliedText && " void main" == it
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun `_test apply inline suggestions without initial following text`() {
|
||||
useCodeGPTService(FeatureType.CODE_COMPLETION)
|
||||
service<CodeGPTServiceSettings>().state.nextEditsEnabled = false
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue