Skip to content

Commit 4489058

Browse files
authored
Add cursor position to chat request (#5562)
Add selected character position to chat request
1 parent 20c045b commit 4489058

File tree

16 files changed

+116
-103
lines changed

16 files changed

+116
-103
lines changed

plugins/amazonq/chat/jetbrains-community/src/software/aws/toolkits/jetbrains/services/amazonq/toolwindow/AmazonQPanel.kt

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -56,9 +56,7 @@ class AmazonQPanel(val project: Project, private val scope: CoroutineScope) : Di
5656
AsyncChatUiListener.TOPIC,
5757
object : AsyncChatUiListener {
5858
override fun onChange(message: String) {
59-
runInEdt {
60-
browser.get()?.postChat(message)
61-
}
59+
browser.get()?.postChat(message)
6260
}
6361
}
6462
)

plugins/amazonq/chat/jetbrains-community/src/software/aws/toolkits/jetbrains/services/amazonq/webview/BrowserConnector.kt

Lines changed: 7 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ import com.google.gson.Gson
88
import com.intellij.ide.BrowserUtil
99
import com.intellij.ide.util.RunOnceUtil
1010
import com.intellij.openapi.application.runInEdt
11+
import com.intellij.openapi.fileEditor.FileEditorManager
1112
import com.intellij.openapi.options.ShowSettingsUtil
1213
import com.intellij.openapi.project.Project
1314
import com.intellij.ui.jcef.JBCefJSQuery.Response
@@ -22,8 +23,7 @@ import kotlinx.coroutines.flow.merge
2223
import kotlinx.coroutines.flow.onEach
2324
import kotlinx.coroutines.launch
2425
import org.cef.browser.CefBrowser
25-
import org.eclipse.lsp4j.Position
26-
import org.eclipse.lsp4j.Range
26+
import org.eclipse.lsp4j.TextDocumentIdentifier
2727
import software.aws.toolkits.core.utils.error
2828
import software.aws.toolkits.core.utils.getLogger
2929
import software.aws.toolkits.core.utils.warn
@@ -34,7 +34,6 @@ import software.aws.toolkits.jetbrains.services.amazonq.lsp.AmazonQLspService
3434
import software.aws.toolkits.jetbrains.services.amazonq.lsp.encryption.JwtEncryptionManager
3535
import software.aws.toolkits.jetbrains.services.amazonq.lsp.flareChat.AwsServerCapabilitiesProvider
3636
import software.aws.toolkits.jetbrains.services.amazonq.lsp.flareChat.ChatCommunicationManager
37-
import software.aws.toolkits.jetbrains.services.amazonq.lsp.flareChat.getTextDocumentIdentifier
3837
import software.aws.toolkits.jetbrains.services.amazonq.lsp.model.aws.chat.AUTH_FOLLOW_UP_CLICKED
3938
import software.aws.toolkits.jetbrains.services.amazonq.lsp.model.aws.chat.AuthFollowUpClickNotification
4039
import software.aws.toolkits.jetbrains.services.amazonq.lsp.model.aws.chat.ButtonClickNotification
@@ -71,7 +70,6 @@ import software.aws.toolkits.jetbrains.services.amazonq.lsp.model.aws.chat.CopyC
7170
import software.aws.toolkits.jetbrains.services.amazonq.lsp.model.aws.chat.CopyCodeToClipboardParams
7271
import software.aws.toolkits.jetbrains.services.amazonq.lsp.model.aws.chat.CreatePromptNotification
7372
import software.aws.toolkits.jetbrains.services.amazonq.lsp.model.aws.chat.CreatePromptParams
74-
import software.aws.toolkits.jetbrains.services.amazonq.lsp.model.aws.chat.CursorState
7573
import software.aws.toolkits.jetbrains.services.amazonq.lsp.model.aws.chat.EncryptedChatParams
7674
import software.aws.toolkits.jetbrains.services.amazonq.lsp.model.aws.chat.EncryptedQuickActionChatParams
7775
import software.aws.toolkits.jetbrains.services.amazonq.lsp.model.aws.chat.FeedbackNotification
@@ -107,6 +105,8 @@ import software.aws.toolkits.jetbrains.services.amazonq.lsp.model.aws.chat.TabBa
107105
import software.aws.toolkits.jetbrains.services.amazonq.lsp.model.aws.chat.TabBarActionRequest
108106
import software.aws.toolkits.jetbrains.services.amazonq.lsp.model.aws.chat.TabEventParams
109107
import software.aws.toolkits.jetbrains.services.amazonq.lsp.model.aws.chat.TabEventRequest
108+
import software.aws.toolkits.jetbrains.services.amazonq.lsp.util.LspEditorUtil
109+
import software.aws.toolkits.jetbrains.services.amazonq.lsp.util.LspEditorUtil.toUriString
110110
import software.aws.toolkits.jetbrains.services.amazonq.util.command
111111
import software.aws.toolkits.jetbrains.services.amazonq.util.tabType
112112
import software.aws.toolkits.jetbrains.services.amazonq.webview.theme.AmazonQTheme
@@ -236,19 +236,9 @@ class BrowserConnector(
236236
requestFromUi.params.prompt.escapedPrompt,
237237
node.command
238238
)
239-
val textDocumentIdentifier = getTextDocumentIdentifier(project)
240-
val cursorState = CursorState(
241-
Range(
242-
Position(
243-
0,
244-
0
245-
),
246-
Position(
247-
1,
248-
1
249-
)
250-
)
251-
)
239+
val editor = FileEditorManager.getInstance(project).selectedTextEditor
240+
val textDocumentIdentifier = editor?.let { TextDocumentIdentifier(toUriString(it.virtualFile)) }
241+
val cursorState = editor?.let { LspEditorUtil.getCursorState(it) }
252242

253243
val chatParams = ChatParams(
254244
requestFromUi.params.tabId,

plugins/amazonq/codewhisperer/jetbrains-community/src/software/aws/toolkits/jetbrains/services/codewhisperer/service/CodeWhispererService.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@ import software.aws.toolkits.jetbrains.services.amazonq.lsp.model.aws.textDocume
4848
import software.aws.toolkits.jetbrains.services.amazonq.lsp.model.aws.textDocument.InlineCompletionListWithReferences
4949
import software.aws.toolkits.jetbrains.services.amazonq.lsp.model.aws.textDocument.InlineCompletionTriggerKind
5050
import software.aws.toolkits.jetbrains.services.amazonq.lsp.model.aws.textDocument.InlineCompletionWithReferencesParams
51-
import software.aws.toolkits.jetbrains.services.amazonq.lsp.util.FileUriUtil.toUriString
51+
import software.aws.toolkits.jetbrains.services.amazonq.lsp.util.LspEditorUtil.toUriString
5252
import software.aws.toolkits.jetbrains.services.codewhisperer.customization.CodeWhispererModelConfigurator
5353
import software.aws.toolkits.jetbrains.services.codewhisperer.editor.CodeWhispererEditorManager
5454
import software.aws.toolkits.jetbrains.services.codewhisperer.editor.CodeWhispererEditorUtil.getCaretPosition

plugins/amazonq/codewhisperer/jetbrains-community/src/software/aws/toolkits/jetbrains/services/codewhisperer/service/CodeWhispererServiceNew.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@ import software.aws.toolkits.jetbrains.services.amazonq.lsp.model.aws.textDocume
4646
import software.aws.toolkits.jetbrains.services.amazonq.lsp.model.aws.textDocument.InlineCompletionListWithReferences
4747
import software.aws.toolkits.jetbrains.services.amazonq.lsp.model.aws.textDocument.InlineCompletionTriggerKind
4848
import software.aws.toolkits.jetbrains.services.amazonq.lsp.model.aws.textDocument.InlineCompletionWithReferencesParams
49-
import software.aws.toolkits.jetbrains.services.amazonq.lsp.util.FileUriUtil.toUriString
49+
import software.aws.toolkits.jetbrains.services.amazonq.lsp.util.LspEditorUtil.toUriString
5050
import software.aws.toolkits.jetbrains.services.codewhisperer.editor.CodeWhispererEditorManagerNew
5151
import software.aws.toolkits.jetbrains.services.codewhisperer.editor.CodeWhispererEditorUtil.getCaretPosition
5252
import software.aws.toolkits.jetbrains.services.codewhisperer.explorer.CodeWhispererExplorerActionManager

plugins/amazonq/codewhisperer/jetbrains-community/tst/software/aws/toolkits/jetbrains/services/codewhisperer/CodeWhispererServiceTest.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ import org.mockito.kotlin.spy
1919
import org.mockito.kotlin.stub
2020
import org.mockito.kotlin.whenever
2121
import software.aws.toolkits.jetbrains.services.amazonq.lsp.model.aws.textDocument.InlineCompletionTriggerKind
22-
import software.aws.toolkits.jetbrains.services.amazonq.lsp.util.FileUriUtil.toUriString
22+
import software.aws.toolkits.jetbrains.services.amazonq.lsp.util.LspEditorUtil.toUriString
2323
import software.aws.toolkits.jetbrains.services.codewhisperer.customization.CodeWhispererCustomization
2424
import software.aws.toolkits.jetbrains.services.codewhisperer.customization.CodeWhispererModelConfigurator
2525
import software.aws.toolkits.jetbrains.services.codewhisperer.language.languages.CodeWhispererJava

plugins/amazonq/shared/jetbrains-community/src/software/aws/toolkits/jetbrains/services/amazonq/lsp/dependencies/ModuleDependencyProvider.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ import com.intellij.openapi.module.Module
88
import com.intellij.openapi.roots.ModuleRootManager
99
import com.intellij.openapi.vfs.VirtualFile
1010
import software.aws.toolkits.jetbrains.services.amazonq.lsp.model.aws.dependencies.DidChangeDependencyPathsParams
11-
import software.aws.toolkits.jetbrains.services.amazonq.lsp.util.FileUriUtil.toUriString
11+
import software.aws.toolkits.jetbrains.services.amazonq.lsp.util.LspEditorUtil.toUriString
1212

1313
interface ModuleDependencyProvider {
1414
companion object {

plugins/amazonq/shared/jetbrains-community/src/software/aws/toolkits/jetbrains/services/amazonq/lsp/flareChat/ChatEditorUtils.kt

Lines changed: 0 additions & 15 deletions
This file was deleted.

plugins/amazonq/shared/jetbrains-community/src/software/aws/toolkits/jetbrains/services/amazonq/lsp/model/aws/chat/CursorState.kt

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,15 @@
33

44
package software.aws.toolkits.jetbrains.services.amazonq.lsp.model.aws.chat
55

6+
import org.eclipse.lsp4j.Position
67
import org.eclipse.lsp4j.Range
78

8-
data class CursorState(
9+
sealed interface CursorState
10+
11+
data class CursorPosition(
12+
val position: Position,
13+
) : CursorState
14+
15+
data class CursorRange(
916
val range: Range,
10-
)
17+
) : CursorState

plugins/amazonq/shared/jetbrains-community/src/software/aws/toolkits/jetbrains/services/amazonq/lsp/model/aws/chat/SendChatPrompt.kt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,8 @@ import software.aws.toolkits.jetbrains.services.amazonq.lsp.flareChat.ContextCom
99
data class ChatParams(
1010
val tabId: String,
1111
val prompt: ChatPrompt,
12-
val textDocument: TextDocumentIdentifier,
13-
val cursorState: CursorState,
12+
val textDocument: TextDocumentIdentifier?,
13+
val cursorState: CursorState?,
1414
val context: List<ContextCommand>?,
1515
)
1616

plugins/amazonq/shared/jetbrains-community/src/software/aws/toolkits/jetbrains/services/amazonq/lsp/textdocument/TextDocumentServiceHandler.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ import org.eclipse.lsp4j.TextDocumentIdentifier
2727
import org.eclipse.lsp4j.TextDocumentItem
2828
import org.eclipse.lsp4j.VersionedTextDocumentIdentifier
2929
import software.aws.toolkits.jetbrains.services.amazonq.lsp.AmazonQLspService
30-
import software.aws.toolkits.jetbrains.services.amazonq.lsp.util.FileUriUtil.toUriString
30+
import software.aws.toolkits.jetbrains.services.amazonq.lsp.util.LspEditorUtil.toUriString
3131
import software.aws.toolkits.jetbrains.utils.pluginAwareExecuteOnPooledThread
3232

3333
class TextDocumentServiceHandler(

plugins/amazonq/shared/jetbrains-community/src/software/aws/toolkits/jetbrains/services/amazonq/lsp/util/FileUriUtil.kt

Lines changed: 0 additions & 42 deletions
This file was deleted.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
// Copyright 2025 Amazon.com, Inc. or its affiliates. All Rights Reserved.
2+
// SPDX-License-Identifier: Apache-2.0
3+
4+
package software.aws.toolkits.jetbrains.services.amazonq.lsp.util
5+
6+
import com.intellij.openapi.application.runReadAction
7+
import com.intellij.openapi.editor.Editor
8+
import com.intellij.openapi.vfs.VfsUtilCore
9+
import com.intellij.openapi.vfs.VirtualFile
10+
import org.eclipse.lsp4j.Position
11+
import org.eclipse.lsp4j.Range
12+
import software.aws.toolkits.core.utils.getLogger
13+
import software.aws.toolkits.core.utils.warn
14+
import software.aws.toolkits.jetbrains.services.amazonq.lsp.model.aws.chat.CursorPosition
15+
import software.aws.toolkits.jetbrains.services.amazonq.lsp.model.aws.chat.CursorRange
16+
import software.aws.toolkits.jetbrains.services.amazonq.lsp.model.aws.chat.CursorState
17+
import java.io.File
18+
import java.net.URI
19+
import java.net.URISyntaxException
20+
21+
object LspEditorUtil {
22+
23+
fun toUriString(virtualFile: VirtualFile): String? {
24+
val protocol = virtualFile.fileSystem.protocol
25+
val uri = when (protocol) {
26+
"jar" -> VfsUtilCore.convertToURL(virtualFile.url)?.toExternalForm()
27+
"jrt" -> virtualFile.url
28+
else -> toUri(VfsUtilCore.virtualToIoFile(virtualFile)).toASCIIString()
29+
} ?: return null
30+
31+
return if (virtualFile.isDirectory) {
32+
uri.trimEnd('/', '\\')
33+
} else {
34+
uri
35+
}
36+
}
37+
38+
private fun toUri(file: File): URI {
39+
try {
40+
// URI scheme specified by language server protocol
41+
return URI("file", "", file.absoluteFile.toURI().path, null)
42+
} catch (e: URISyntaxException) {
43+
LOG.warn { "${e.localizedMessage}: $e" }
44+
return file.absoluteFile.toURI()
45+
}
46+
}
47+
48+
/**
49+
* Works but is divergent from [FocusAreaContextExtrator]
50+
*/
51+
fun getCursorState(editor: Editor): CursorState =
52+
runReadAction {
53+
val selectionModel = editor.selectionModel
54+
if (selectionModel.hasSelection()) {
55+
val selectedStartPos = editor.offsetToLogicalPosition(selectionModel.selectionStart)
56+
val selectedEndPos = editor.offsetToLogicalPosition(selectionModel.selectionEnd)
57+
58+
return@runReadAction CursorRange(
59+
Range(
60+
Position(selectedStartPos.line, selectedStartPos.column),
61+
Position(selectedEndPos.line, selectedEndPos.column)
62+
)
63+
)
64+
} else {
65+
return@runReadAction CursorPosition(
66+
Position(
67+
editor.caretModel.primaryCaret.logicalPosition.line,
68+
editor.caretModel.primaryCaret.logicalPosition.column
69+
)
70+
)
71+
}
72+
}
73+
74+
private val LOG = getLogger<LspEditorUtil>()
75+
}

plugins/amazonq/shared/jetbrains-community/src/software/aws/toolkits/jetbrains/services/amazonq/lsp/util/WorkspaceFolderUtil.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ import com.intellij.openapi.module.ModuleManager
77
import com.intellij.openapi.project.Project
88
import com.intellij.openapi.roots.ModuleRootManager
99
import org.eclipse.lsp4j.WorkspaceFolder
10-
import software.aws.toolkits.jetbrains.services.amazonq.lsp.util.FileUriUtil.toUriString
10+
import software.aws.toolkits.jetbrains.services.amazonq.lsp.util.LspEditorUtil.toUriString
1111

1212
object WorkspaceFolderUtil {
1313
fun createWorkspaceFolders(project: Project): List<WorkspaceFolder> =

plugins/amazonq/shared/jetbrains-community/src/software/aws/toolkits/jetbrains/services/amazonq/lsp/workspace/WorkspaceServiceHandler.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ import org.eclipse.lsp4j.TextDocumentItem
3535
import org.eclipse.lsp4j.WorkspaceFolder
3636
import org.eclipse.lsp4j.WorkspaceFoldersChangeEvent
3737
import software.aws.toolkits.jetbrains.services.amazonq.lsp.AmazonQLspService
38-
import software.aws.toolkits.jetbrains.services.amazonq.lsp.util.FileUriUtil.toUriString
38+
import software.aws.toolkits.jetbrains.services.amazonq.lsp.util.LspEditorUtil.toUriString
3939
import software.aws.toolkits.jetbrains.services.amazonq.lsp.util.WorkspaceFolderUtil.createWorkspaceFolders
4040
import software.aws.toolkits.jetbrains.utils.pluginAwareExecuteOnPooledThread
4141
import java.nio.file.FileSystems

plugins/amazonq/shared/jetbrains-community/tst/software/aws/toolkits/jetbrains/services/amazonq/lsp/textdocument/TextDocumentServiceHandlerTest.kt

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ import org.junit.Rule
4040
import org.junit.Test
4141
import software.aws.toolkits.jetbrains.services.amazonq.lsp.AmazonQLanguageServer
4242
import software.aws.toolkits.jetbrains.services.amazonq.lsp.AmazonQLspService
43-
import software.aws.toolkits.jetbrains.services.amazonq.lsp.util.FileUriUtil
43+
import software.aws.toolkits.jetbrains.services.amazonq.lsp.util.LspEditorUtil
4444
import java.net.URI
4545
import java.nio.file.Path
4646
import java.util.concurrent.CompletableFuture
@@ -230,8 +230,8 @@ class TextDocumentServiceHandlerTest {
230230
val document = mockk<Document>()
231231
val file = createMockVirtualFile(URI.create(""))
232232

233-
mockkObject(FileUriUtil) {
234-
every { FileUriUtil.toUriString(file) } returns null
233+
mockkObject(LspEditorUtil) {
234+
every { LspEditorUtil.toUriString(file) } returns null
235235

236236
val fileDocumentManager = mockk<FileDocumentManager> {
237237
every { getFile(document) } returns file

0 commit comments

Comments
 (0)