diff --git a/extensions/intellij/src/main/kotlin/com/github/continuedev/continueintellijextension/editor/InlineEditAction.kt b/extensions/intellij/src/main/kotlin/com/github/continuedev/continueintellijextension/editor/InlineEditAction.kt index ce2c260e14..9f314ede6e 100644 --- a/extensions/intellij/src/main/kotlin/com/github/continuedev/continueintellijextension/editor/InlineEditAction.kt +++ b/extensions/intellij/src/main/kotlin/com/github/continuedev/continueintellijextension/editor/InlineEditAction.kt @@ -4,6 +4,7 @@ import com.github.continuedev.continueintellijextension.`continue`.GetTheme import com.github.continuedev.continueintellijextension.services.ContinueExtensionSettings import com.github.continuedev.continueintellijextension.services.ContinuePluginService import com.github.continuedev.continueintellijextension.utils.getMetaKeyLabel +import com.github.continuedev.continueintellijextension.utils.getShiftKeyLabel import com.intellij.openapi.Disposable import com.intellij.openapi.actionSystem.ActionUpdateThread import com.intellij.openapi.actionSystem.AnAction @@ -130,7 +131,8 @@ fun openInlineEdit(project: Project?, editor: Editor) { val modelTitles = mutableListOf() continuePluginService.coreMessenger?.request("config/getSerializedProfileInfo", null, null) { response -> - val result = (response as Map)["result"] as Map + val content = (response as Map)["content"] as Map + val result = content["result"] as Map val config = result["config"] as Map val models = config["models"] as List> modelTitles.addAll(models.map { it["title"] as String }) @@ -166,13 +168,13 @@ fun openInlineEdit(project: Project?, editor: Editor) { val prefix = editor.document.getText(TextRange(0, startOffset)) val highlighted = editor.document.getText(TextRange(startOffset, endOffset)) val suffix = editor.document.getText(TextRange(endOffset, editor.document.textLength)) - val lineNumber = max(0, startLineNumber - 1) + val lineNumber = if (startLineNumber == 0) 0 else max(0, startLineNumber - 1) // Un-highlight the selected text selectionModel.removeSelection() // Get indentation width in pixels - val indentationLineNum = lineNumber + 1 + val indentationLineNum = if (startLineNumber == 0) 0 else lineNumber + 1 val lineStart = editor.document.getLineStartOffset(indentationLineNum) val lineEnd = editor.document.getLineEndOffset(indentationLineNum) val text = editor.document.getText(TextRange(lineStart, lineEnd)) @@ -488,14 +490,14 @@ class CustomPanel( } val leftButton = - CustomButton("Reject All (${getMetaKeyLabel()}⇧⌫)") { onReject() } + CustomButton("Reject All (${getMetaKeyLabel()}${getShiftKeyLabel()}⌫)") { onReject() } .apply { background = JBColor(0x30FF0000.toInt(), 0x30FF0000.toInt()) foreground = JBColor(0xF5F5F5.toInt(), 0xF5F5F5.toInt()) } val rightButton = - CustomButton("Accept All (${getMetaKeyLabel()}⇧⏎)") { onAccept() } + CustomButton("Accept All (${getMetaKeyLabel()}${getShiftKeyLabel()}⏎)") { onAccept() } .apply { background = JBColor(0x3000FF00.toInt(), 0x3000FF00.toInt()) foreground = JBColor(0xF5F5F5.toInt(), 0xF5F5F5.toInt()) diff --git a/extensions/intellij/src/test/kotlin/com/github/continuedev/continueintellijextension/e2e/InlineEdit.kt b/extensions/intellij/src/test/kotlin/com/github/continuedev/continueintellijextension/e2e/InlineEdit.kt new file mode 100644 index 0000000000..d153deda52 --- /dev/null +++ b/extensions/intellij/src/test/kotlin/com/github/continuedev/continueintellijextension/e2e/InlineEdit.kt @@ -0,0 +1,94 @@ +package com.github.continuedev.continueintellijextension.e2e + +import com.automation.remarks.junit5.Video +import com.github.continuedev.continueintellijextension.fixtures.dialog +import com.github.continuedev.continueintellijextension.fixtures.idea +import com.github.continuedev.continueintellijextension.fixtures.welcomeFrame +import com.github.continuedev.continueintellijextension.utils.RemoteRobotExtension +import com.github.continuedev.continueintellijextension.utils.StepsLogger +import com.github.continuedev.continueintellijextension.utils.* +import com.intellij.remoterobot.RemoteRobot +import com.intellij.remoterobot.fixtures.ComponentFixture +import com.intellij.remoterobot.search.locators.byXpath +import com.intellij.remoterobot.steps.CommonSteps +import com.intellij.remoterobot.utils.keyboard +import com.intellij.remoterobot.utils.waitFor +import com.intellij.remoterobot.utils.waitForIgnoringError +import org.junit.jupiter.api.AfterEach +import org.junit.jupiter.api.BeforeEach +import org.junit.jupiter.api.Test +import org.junit.jupiter.api.extension.ExtendWith +import java.awt.event.KeyEvent.VK_I +import java.time.Duration.ofMinutes +import java.time.Duration.ofSeconds + +@ExtendWith(RemoteRobotExtension::class) +class InlineEdit { + init { + StepsLogger.init() + } + + @BeforeEach + fun waitForIde(remoteRobot: RemoteRobot) { + waitForIgnoringError(ofMinutes(3)) { remoteRobot.callJs("true") } + } + + @AfterEach + fun closeProject(remoteRobot: RemoteRobot) = CommonSteps(remoteRobot).closeProject() + + @Test + @Video + fun submitInlineEdit(remoteRobot: RemoteRobot): Unit = with(remoteRobot) { + welcomeFrame { + createNewProjectLink.click() + dialog("New Project") { + findText("Java").click() + checkBox("Add sample code").select() + button("Create").click() + } + } + + // Wait for the default "Main.java" tab to load + // Our "continue_tutorial.java.ft" tab loads first, but then "Main.java" takes focus. + waitFor(ofSeconds(20)) { + findAll( + byXpath("//div[@accessiblename='Main.java' and @class='SingleHeightLabel']") + ).isNotEmpty() + } + + idea { + with(textEditor()) { + val userMsg = "TEST_USER_MESSAGE_0" + editor.insertTextAtLine(0, 0, userMsg) + editor.selectText(userMsg) + + keyboard { + hotKey(getMetaKey(), VK_I) + } + + val textArea = find(byXpath("//div[@class='CustomTextArea']")) + textArea.hasText("Enter instructions...") + + val modelSelect = find(byXpath("//div[@class='JComboBox']")) + modelSelect.hasText("TEST LLM") + + keyboard { + enterText("Hello world!") + } + + val enterBtn = find(byXpath("//div[@class='CustomButton']")) + enterBtn.click() + + val rejectText = "${getAltKeyLabel()}${getShiftKeyLabel()}N" + val acceptText = "${getAltKeyLabel()}${getShiftKeyLabel()}Y" + val acceptAllText = "Accept All (${getMetaKeyLabel()}${getShiftKeyLabel()}⏎)" + val rejectAllText = "Reject All (${getMetaKeyLabel()}${getShiftKeyLabel()}⌫)" + + find(byXpath("//div[@text='$rejectText']")).isShowing + find(byXpath("//div[@text='$acceptText']")).isShowing + find(byXpath("//div[@text='$acceptAllText']")).isShowing + find(byXpath("//div[@text='$rejectAllText']")).isShowing + } + } + } +} \ No newline at end of file