From 39f2f5bc921a8f005da494eb45a2396ef0d821f3 Mon Sep 17 00:00:00 2001 From: samgst-amazon Date: Mon, 17 Mar 2025 10:12:42 -0700 Subject: [PATCH 01/15] add message and data classes --- .../services/amazonq/lsp/AmazonQLanguageServer.kt | 5 +++++ .../lsp/model/aws/GetConfigurationFromServerParams.kt | 8 ++++++++ .../amazonq/lsp/model/aws/LspServerConfigurations.kt | 7 +++++++ 3 files changed, 20 insertions(+) create mode 100644 plugins/amazonq/shared/jetbrains-community/src/software/aws/toolkits/jetbrains/services/amazonq/lsp/model/aws/GetConfigurationFromServerParams.kt create mode 100644 plugins/amazonq/shared/jetbrains-community/src/software/aws/toolkits/jetbrains/services/amazonq/lsp/model/aws/LspServerConfigurations.kt diff --git a/plugins/amazonq/shared/jetbrains-community/src/software/aws/toolkits/jetbrains/services/amazonq/lsp/AmazonQLanguageServer.kt b/plugins/amazonq/shared/jetbrains-community/src/software/aws/toolkits/jetbrains/services/amazonq/lsp/AmazonQLanguageServer.kt index 0921d0e8eeb..2b947de065f 100644 --- a/plugins/amazonq/shared/jetbrains-community/src/software/aws/toolkits/jetbrains/services/amazonq/lsp/AmazonQLanguageServer.kt +++ b/plugins/amazonq/shared/jetbrains-community/src/software/aws/toolkits/jetbrains/services/amazonq/lsp/AmazonQLanguageServer.kt @@ -7,6 +7,8 @@ import org.eclipse.lsp4j.jsonrpc.messages.ResponseMessage import org.eclipse.lsp4j.jsonrpc.services.JsonNotification import org.eclipse.lsp4j.jsonrpc.services.JsonRequest import org.eclipse.lsp4j.services.LanguageServer +import software.aws.toolkits.jetbrains.services.amazonq.lsp.model.aws.GetConfigurationFromServerParams +import software.aws.toolkits.jetbrains.services.amazonq.lsp.model.aws.LspServerConfigurations import software.aws.toolkits.jetbrains.services.amazonq.lsp.model.aws.credentials.UpdateCredentialsPayload import software.aws.toolkits.jetbrains.services.amazonq.lsp.model.aws.dependencies.SyncModuleDependenciesParams import java.util.concurrent.CompletableFuture @@ -24,4 +26,7 @@ interface AmazonQLanguageServer : LanguageServer { @JsonNotification("aws/credentials/token/delete") fun deleteTokenCredentials(): CompletableFuture + + @JsonRequest("aws/getConfigurationFromServer") + fun getConfigurationFromServer(params: GetConfigurationFromServerParams): CompletableFuture } diff --git a/plugins/amazonq/shared/jetbrains-community/src/software/aws/toolkits/jetbrains/services/amazonq/lsp/model/aws/GetConfigurationFromServerParams.kt b/plugins/amazonq/shared/jetbrains-community/src/software/aws/toolkits/jetbrains/services/amazonq/lsp/model/aws/GetConfigurationFromServerParams.kt new file mode 100644 index 00000000000..d948209e3a9 --- /dev/null +++ b/plugins/amazonq/shared/jetbrains-community/src/software/aws/toolkits/jetbrains/services/amazonq/lsp/model/aws/GetConfigurationFromServerParams.kt @@ -0,0 +1,8 @@ +// Copyright 2025 Amazon.com, Inc. or its affiliates. All Rights Reserved. +// SPDX-License-Identifier: Apache-2.0 + +package software.aws.toolkits.jetbrains.services.amazonq.lsp.model.aws + +class GetConfigurationFromServerParams( + val section: String +) diff --git a/plugins/amazonq/shared/jetbrains-community/src/software/aws/toolkits/jetbrains/services/amazonq/lsp/model/aws/LspServerConfigurations.kt b/plugins/amazonq/shared/jetbrains-community/src/software/aws/toolkits/jetbrains/services/amazonq/lsp/model/aws/LspServerConfigurations.kt new file mode 100644 index 00000000000..2a76ada4e5b --- /dev/null +++ b/plugins/amazonq/shared/jetbrains-community/src/software/aws/toolkits/jetbrains/services/amazonq/lsp/model/aws/LspServerConfigurations.kt @@ -0,0 +1,7 @@ +// Copyright 2025 Amazon.com, Inc. or its affiliates. All Rights Reserved. +// SPDX-License-Identifier: Apache-2.0 + +package software.aws.toolkits.jetbrains.services.amazonq.lsp.model.aws + +class LspServerConfigurations { +} From 7b4161695135d61b38200f0808487ac5778fe6ea Mon Sep 17 00:00:00 2001 From: Sam Stewart Date: Tue, 18 Mar 2025 09:11:42 -0700 Subject: [PATCH 02/15] Update plugins/amazonq/shared/jetbrains-community/src/software/aws/toolkits/jetbrains/services/amazonq/lsp/AmazonQLanguageClientImpl.kt Co-authored-by: Richard Li <742829+rli@users.noreply.github.com> --- .../jetbrains/services/amazonq/lsp/AmazonQLanguageClientImpl.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/amazonq/shared/jetbrains-community/src/software/aws/toolkits/jetbrains/services/amazonq/lsp/AmazonQLanguageClientImpl.kt b/plugins/amazonq/shared/jetbrains-community/src/software/aws/toolkits/jetbrains/services/amazonq/lsp/AmazonQLanguageClientImpl.kt index 374422999d9..c8aaca62921 100644 --- a/plugins/amazonq/shared/jetbrains-community/src/software/aws/toolkits/jetbrains/services/amazonq/lsp/AmazonQLanguageClientImpl.kt +++ b/plugins/amazonq/shared/jetbrains-community/src/software/aws/toolkits/jetbrains/services/amazonq/lsp/AmazonQLanguageClientImpl.kt @@ -65,7 +65,7 @@ class AmazonQLanguageClientImpl : AmazonQLanguageClient { add( CodeWhispererLspConfiguration( shouldShareData = CodeWhispererSettings.getInstance().isMetricOptIn(), - shouldShareCodeReferences = CodeWhispererSettings.getInstance().isIncludeCodeWithReference() + shouldShareCodeReferences = CodeWhispererSettings.getInstance().isIncludeCodeWithReference(), ) ) } From 430bf1b74392d17a53f7657d75996614ef4c060c Mon Sep 17 00:00:00 2001 From: samgst-amazon Date: Tue, 18 Mar 2025 10:51:29 -0700 Subject: [PATCH 03/15] data classes --- .../services/amazonq/lsp/AmazonQLanguageServer.kt | 5 +++++ .../aws/textDocument/InlineCompletionContext.kt | 9 +++++++++ .../model/aws/textDocument/InlineCompletionItem.kt | 10 ++++++++++ .../InlineCompletionListWithReferences.kt | 9 +++++++++ .../aws/textDocument/InlineCompletionReference.kt | 11 +++++++++++ .../InlineCompletionReferencePosition.kt | 10 ++++++++++ .../aws/textDocument/InlineCompletionTriggerKind.kt | 10 ++++++++++ .../InlineCompletionWithReferencesParams.kt | 10 ++++++++++ .../aws/textDocument/SelectedCompletionInfo.kt | 13 +++++++++++++ 9 files changed, 87 insertions(+) create mode 100644 plugins/amazonq/shared/jetbrains-community/src/software/aws/toolkits/jetbrains/services/amazonq/lsp/model/aws/textDocument/InlineCompletionContext.kt create mode 100644 plugins/amazonq/shared/jetbrains-community/src/software/aws/toolkits/jetbrains/services/amazonq/lsp/model/aws/textDocument/InlineCompletionItem.kt create mode 100644 plugins/amazonq/shared/jetbrains-community/src/software/aws/toolkits/jetbrains/services/amazonq/lsp/model/aws/textDocument/InlineCompletionListWithReferences.kt create mode 100644 plugins/amazonq/shared/jetbrains-community/src/software/aws/toolkits/jetbrains/services/amazonq/lsp/model/aws/textDocument/InlineCompletionReference.kt create mode 100644 plugins/amazonq/shared/jetbrains-community/src/software/aws/toolkits/jetbrains/services/amazonq/lsp/model/aws/textDocument/InlineCompletionReferencePosition.kt create mode 100644 plugins/amazonq/shared/jetbrains-community/src/software/aws/toolkits/jetbrains/services/amazonq/lsp/model/aws/textDocument/InlineCompletionTriggerKind.kt create mode 100644 plugins/amazonq/shared/jetbrains-community/src/software/aws/toolkits/jetbrains/services/amazonq/lsp/model/aws/textDocument/InlineCompletionWithReferencesParams.kt create mode 100644 plugins/amazonq/shared/jetbrains-community/src/software/aws/toolkits/jetbrains/services/amazonq/lsp/model/aws/textDocument/SelectedCompletionInfo.kt diff --git a/plugins/amazonq/shared/jetbrains-community/src/software/aws/toolkits/jetbrains/services/amazonq/lsp/AmazonQLanguageServer.kt b/plugins/amazonq/shared/jetbrains-community/src/software/aws/toolkits/jetbrains/services/amazonq/lsp/AmazonQLanguageServer.kt index 0921d0e8eeb..9eea5ce2906 100644 --- a/plugins/amazonq/shared/jetbrains-community/src/software/aws/toolkits/jetbrains/services/amazonq/lsp/AmazonQLanguageServer.kt +++ b/plugins/amazonq/shared/jetbrains-community/src/software/aws/toolkits/jetbrains/services/amazonq/lsp/AmazonQLanguageServer.kt @@ -9,6 +9,8 @@ import org.eclipse.lsp4j.jsonrpc.services.JsonRequest import org.eclipse.lsp4j.services.LanguageServer import software.aws.toolkits.jetbrains.services.amazonq.lsp.model.aws.credentials.UpdateCredentialsPayload import software.aws.toolkits.jetbrains.services.amazonq.lsp.model.aws.dependencies.SyncModuleDependenciesParams +import software.aws.toolkits.jetbrains.services.amazonq.lsp.model.aws.textDocument.InlineCompletionListWithReferences +import software.aws.toolkits.jetbrains.services.amazonq.lsp.model.aws.textDocument.InlineCompletionWithReferencesParams import java.util.concurrent.CompletableFuture /** @@ -16,6 +18,9 @@ import java.util.concurrent.CompletableFuture */ @Suppress("unused") interface AmazonQLanguageServer : LanguageServer { + @JsonRequest("aws/textDocument/inlineCompletionWithReferences") + fun inlineCompletionWithReferences(params: InlineCompletionWithReferencesParams): CompletableFuture + @JsonNotification("aws/syncModuleDependencies") fun syncModuleDependencies(params: SyncModuleDependenciesParams): CompletableFuture diff --git a/plugins/amazonq/shared/jetbrains-community/src/software/aws/toolkits/jetbrains/services/amazonq/lsp/model/aws/textDocument/InlineCompletionContext.kt b/plugins/amazonq/shared/jetbrains-community/src/software/aws/toolkits/jetbrains/services/amazonq/lsp/model/aws/textDocument/InlineCompletionContext.kt new file mode 100644 index 00000000000..c32dcbe50ee --- /dev/null +++ b/plugins/amazonq/shared/jetbrains-community/src/software/aws/toolkits/jetbrains/services/amazonq/lsp/model/aws/textDocument/InlineCompletionContext.kt @@ -0,0 +1,9 @@ +// Copyright 2025 Amazon.com, Inc. or its affiliates. All Rights Reserved. +// SPDX-License-Identifier: Apache-2.0 + +package software.aws.toolkits.jetbrains.services.amazonq.lsp.model.aws.textDocument + +data class InlineCompletionContext( + var triggerKind: InlineCompletionTriggerKind, + var selectedCompletionInfo: SelectedCompletionInfo? = null +) diff --git a/plugins/amazonq/shared/jetbrains-community/src/software/aws/toolkits/jetbrains/services/amazonq/lsp/model/aws/textDocument/InlineCompletionItem.kt b/plugins/amazonq/shared/jetbrains-community/src/software/aws/toolkits/jetbrains/services/amazonq/lsp/model/aws/textDocument/InlineCompletionItem.kt new file mode 100644 index 00000000000..106e65c1609 --- /dev/null +++ b/plugins/amazonq/shared/jetbrains-community/src/software/aws/toolkits/jetbrains/services/amazonq/lsp/model/aws/textDocument/InlineCompletionItem.kt @@ -0,0 +1,10 @@ +// Copyright 2025 Amazon.com, Inc. or its affiliates. All Rights Reserved. +// SPDX-License-Identifier: Apache-2.0 + +package software.aws.toolkits.jetbrains.services.amazonq.lsp.model.aws.textDocument + +data class InlineCompletionItem( + var itemId: String, + var insertText: String, + var references: Array, +) diff --git a/plugins/amazonq/shared/jetbrains-community/src/software/aws/toolkits/jetbrains/services/amazonq/lsp/model/aws/textDocument/InlineCompletionListWithReferences.kt b/plugins/amazonq/shared/jetbrains-community/src/software/aws/toolkits/jetbrains/services/amazonq/lsp/model/aws/textDocument/InlineCompletionListWithReferences.kt new file mode 100644 index 00000000000..645ff79c67c --- /dev/null +++ b/plugins/amazonq/shared/jetbrains-community/src/software/aws/toolkits/jetbrains/services/amazonq/lsp/model/aws/textDocument/InlineCompletionListWithReferences.kt @@ -0,0 +1,9 @@ +// Copyright 2025 Amazon.com, Inc. or its affiliates. All Rights Reserved. +// SPDX-License-Identifier: Apache-2.0 + +package software.aws.toolkits.jetbrains.services.amazonq.lsp.model.aws.textDocument + +data class InlineCompletionListWithReferences( + var items: List, + var sessionId: String +) diff --git a/plugins/amazonq/shared/jetbrains-community/src/software/aws/toolkits/jetbrains/services/amazonq/lsp/model/aws/textDocument/InlineCompletionReference.kt b/plugins/amazonq/shared/jetbrains-community/src/software/aws/toolkits/jetbrains/services/amazonq/lsp/model/aws/textDocument/InlineCompletionReference.kt new file mode 100644 index 00000000000..1d9784477cf --- /dev/null +++ b/plugins/amazonq/shared/jetbrains-community/src/software/aws/toolkits/jetbrains/services/amazonq/lsp/model/aws/textDocument/InlineCompletionReference.kt @@ -0,0 +1,11 @@ +// Copyright 2025 Amazon.com, Inc. or its affiliates. All Rights Reserved. +// SPDX-License-Identifier: Apache-2.0 + +package software.aws.toolkits.jetbrains.services.amazonq.lsp.model.aws.textDocument + +data class InlineCompletionReference( + var referenceName: String, + var referenceUrl: String, + var licenseName: String, + var position: InlineCompletionReferencePosition +) diff --git a/plugins/amazonq/shared/jetbrains-community/src/software/aws/toolkits/jetbrains/services/amazonq/lsp/model/aws/textDocument/InlineCompletionReferencePosition.kt b/plugins/amazonq/shared/jetbrains-community/src/software/aws/toolkits/jetbrains/services/amazonq/lsp/model/aws/textDocument/InlineCompletionReferencePosition.kt new file mode 100644 index 00000000000..6802c2283d5 --- /dev/null +++ b/plugins/amazonq/shared/jetbrains-community/src/software/aws/toolkits/jetbrains/services/amazonq/lsp/model/aws/textDocument/InlineCompletionReferencePosition.kt @@ -0,0 +1,10 @@ +// Copyright 2025 Amazon.com, Inc. or its affiliates. All Rights Reserved. +// SPDX-License-Identifier: Apache-2.0 + +package software.aws.toolkits.jetbrains.services.amazonq.lsp.model.aws.textDocument + +data class InlineCompletionReferencePosition( + var startCharacter: Int = 0, + var endCharacter: Int = 0 +) + diff --git a/plugins/amazonq/shared/jetbrains-community/src/software/aws/toolkits/jetbrains/services/amazonq/lsp/model/aws/textDocument/InlineCompletionTriggerKind.kt b/plugins/amazonq/shared/jetbrains-community/src/software/aws/toolkits/jetbrains/services/amazonq/lsp/model/aws/textDocument/InlineCompletionTriggerKind.kt new file mode 100644 index 00000000000..94cc50622cd --- /dev/null +++ b/plugins/amazonq/shared/jetbrains-community/src/software/aws/toolkits/jetbrains/services/amazonq/lsp/model/aws/textDocument/InlineCompletionTriggerKind.kt @@ -0,0 +1,10 @@ +// Copyright 2025 Amazon.com, Inc. or its affiliates. All Rights Reserved. +// SPDX-License-Identifier: Apache-2.0 + +package software.aws.toolkits.jetbrains.services.amazonq.lsp.model.aws.textDocument + +enum class InlineCompletionTriggerKind(val value: Int) { + Invoke(0), + Automatic(1) +} + diff --git a/plugins/amazonq/shared/jetbrains-community/src/software/aws/toolkits/jetbrains/services/amazonq/lsp/model/aws/textDocument/InlineCompletionWithReferencesParams.kt b/plugins/amazonq/shared/jetbrains-community/src/software/aws/toolkits/jetbrains/services/amazonq/lsp/model/aws/textDocument/InlineCompletionWithReferencesParams.kt new file mode 100644 index 00000000000..c33d9973a08 --- /dev/null +++ b/plugins/amazonq/shared/jetbrains-community/src/software/aws/toolkits/jetbrains/services/amazonq/lsp/model/aws/textDocument/InlineCompletionWithReferencesParams.kt @@ -0,0 +1,10 @@ +// Copyright 2025 Amazon.com, Inc. or its affiliates. All Rights Reserved. +// SPDX-License-Identifier: Apache-2.0 + +package software.aws.toolkits.jetbrains.services.amazonq.lsp.model.aws.textDocument + +import org.eclipse.lsp4j.TextDocumentPositionAndWorkDoneProgressParams + +data class InlineCompletionWithReferencesParams( + var context: InlineCompletionContext +) : TextDocumentPositionAndWorkDoneProgressParams() diff --git a/plugins/amazonq/shared/jetbrains-community/src/software/aws/toolkits/jetbrains/services/amazonq/lsp/model/aws/textDocument/SelectedCompletionInfo.kt b/plugins/amazonq/shared/jetbrains-community/src/software/aws/toolkits/jetbrains/services/amazonq/lsp/model/aws/textDocument/SelectedCompletionInfo.kt new file mode 100644 index 00000000000..650a4866e9f --- /dev/null +++ b/plugins/amazonq/shared/jetbrains-community/src/software/aws/toolkits/jetbrains/services/amazonq/lsp/model/aws/textDocument/SelectedCompletionInfo.kt @@ -0,0 +1,13 @@ +// Copyright 2025 Amazon.com, Inc. or its affiliates. All Rights Reserved. +// SPDX-License-Identifier: Apache-2.0 + +package software.aws.toolkits.jetbrains.services.amazonq.lsp.model.aws.textDocument + +import org.eclipse.lsp4j.Range; + +data class SelectedCompletionInfo( + var text: String, + var range: Range +) + + From 0b95441d45b49b9a4f269ea8572ee10fc6989145 Mon Sep 17 00:00:00 2001 From: samgst-amazon Date: Tue, 18 Mar 2025 13:52:26 -0700 Subject: [PATCH 04/15] send inlineCompletionParams to lsp --- .../service/CodeWhispererService.kt | 20 +++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/plugins/amazonq/codewhisperer/jetbrains-community/src/software/aws/toolkits/jetbrains/services/codewhisperer/service/CodeWhispererService.kt b/plugins/amazonq/codewhisperer/jetbrains-community/src/software/aws/toolkits/jetbrains/services/codewhisperer/service/CodeWhispererService.kt index 111ccdc509f..2a659225f63 100644 --- a/plugins/amazonq/codewhisperer/jetbrains-community/src/software/aws/toolkits/jetbrains/services/codewhisperer/service/CodeWhispererService.kt +++ b/plugins/amazonq/codewhisperer/jetbrains-community/src/software/aws/toolkits/jetbrains/services/codewhisperer/service/CodeWhispererService.kt @@ -29,6 +29,8 @@ import kotlinx.coroutines.delay import kotlinx.coroutines.isActive import kotlinx.coroutines.launch import kotlinx.coroutines.withContext +import org.eclipse.lsp4j.Position +import org.eclipse.lsp4j.TextDocumentIdentifier import software.amazon.awssdk.core.exception.SdkServiceException import software.amazon.awssdk.core.util.DefaultSdkAutoConstructList import software.amazon.awssdk.services.codewhispererruntime.model.CodeWhispererRuntimeException @@ -53,6 +55,9 @@ import software.aws.toolkits.jetbrains.core.credentials.ToolkitConnection import software.aws.toolkits.jetbrains.core.credentials.ToolkitConnectionManager import software.aws.toolkits.jetbrains.core.credentials.pinning.CodeWhispererConnection import software.aws.toolkits.jetbrains.services.amazonq.SUPPLEMENTAL_CONTEXT_TIMEOUT +import software.aws.toolkits.jetbrains.services.amazonq.lsp.model.aws.textDocument.InlineCompletionContext +import software.aws.toolkits.jetbrains.services.amazonq.lsp.model.aws.textDocument.InlineCompletionTriggerKind +import software.aws.toolkits.jetbrains.services.amazonq.lsp.model.aws.textDocument.InlineCompletionWithReferencesParams import software.aws.toolkits.jetbrains.services.codewhisperer.credentials.CodeWhispererClientAdaptor import software.aws.toolkits.jetbrains.services.codewhisperer.customization.CodeWhispererModelConfigurator import software.aws.toolkits.jetbrains.services.codewhisperer.editor.CodeWhispererEditorManager @@ -775,6 +780,21 @@ class CodeWhispererService(private val cs: CoroutineScope) : Disposable { } } + private fun buildInlineCompletionParams(requestContext: RequestContext): InlineCompletionWithReferencesParams { + return InlineCompletionWithReferencesParams( + context = InlineCompletionContext( + triggerKind = when (requestContext.triggerTypeInfo.triggerType) { + CodewhispererTriggerType.OnDemand -> InlineCompletionTriggerKind.Invoke + CodewhispererTriggerType.AutoTrigger -> InlineCompletionTriggerKind.Automatic + else -> InlineCompletionTriggerKind.Invoke + } + ) + ).apply { + textDocument = TextDocumentIdentifier(requestContext.fileContextInfo.filename) + position = Position(requestContext.caretPosition.line, requestContext.caretPosition.column) + } + } + override fun dispose() {} companion object { From dad393e1647d3efc787562d45e8fcf5b6dcbc05d Mon Sep 17 00:00:00 2001 From: samgst-amazon Date: Wed, 19 Mar 2025 15:08:49 -0700 Subject: [PATCH 05/15] handler for aws/textDocument --- .../AWSTextDocumentServiceHandler.kt | 78 +++++++++++++++++++ 1 file changed, 78 insertions(+) create mode 100644 plugins/amazonq/shared/jetbrains-community/src/software/aws/toolkits/jetbrains/services/amazonq/lsp/codewhisperer/AWSTextDocumentServiceHandler.kt diff --git a/plugins/amazonq/shared/jetbrains-community/src/software/aws/toolkits/jetbrains/services/amazonq/lsp/codewhisperer/AWSTextDocumentServiceHandler.kt b/plugins/amazonq/shared/jetbrains-community/src/software/aws/toolkits/jetbrains/services/amazonq/lsp/codewhisperer/AWSTextDocumentServiceHandler.kt new file mode 100644 index 00000000000..9cd2021fb12 --- /dev/null +++ b/plugins/amazonq/shared/jetbrains-community/src/software/aws/toolkits/jetbrains/services/amazonq/lsp/codewhisperer/AWSTextDocumentServiceHandler.kt @@ -0,0 +1,78 @@ +// Copyright 2025 Amazon.com, Inc. or its affiliates. All Rights Reserved. +// SPDX-License-Identifier: Apache-2.0 + +package software.aws.toolkits.jetbrains.services.amazonq.lsp.codewhisperer + +import com.intellij.codeInsight.lookup.Lookup +import com.intellij.codeInsight.lookup.LookupEvent +import com.intellij.codeInsight.lookup.LookupListener +import com.intellij.codeInsight.lookup.LookupManagerListener +import com.intellij.codeInsight.lookup.impl.LookupImpl +import software.aws.toolkits.jetbrains.services.amazonq.lsp.AmazonQLspService +import software.aws.toolkits.jetbrains.services.amazonq.lsp.model.aws.textDocument.InlineCompletionContext +import software.aws.toolkits.jetbrains.services.amazonq.lsp.model.aws.textDocument.InlineCompletionListWithReferences +import software.aws.toolkits.jetbrains.services.amazonq.lsp.model.aws.textDocument.InlineCompletionTriggerKind +import software.aws.toolkits.jetbrains.services.amazonq.lsp.model.aws.textDocument.InlineCompletionWithReferencesParams +import com.intellij.openapi.Disposable +import com.intellij.openapi.editor.Editor +import org.eclipse.lsp4j.Position +import org.eclipse.lsp4j.TextDocumentIdentifier +import com.intellij.openapi.project.Project + +class AWSTextDocumentServiceHandler( + private val project: Project, + serverInstance: Disposable +) : LookupManagerListener { + + init { + project.messageBus.connect(serverInstance).subscribe( + LookupManagerListener.TOPIC, + this + ) + } + + override fun activeLookupChanged(oldLookup: Lookup?, newLookup: Lookup?) { + if (oldLookup != null || newLookup == null) return + + newLookup.addLookupListener(object : LookupListener { + override fun itemSelected(event: LookupEvent) { + val editor = event.lookup.editor + if (!(event.lookup as LookupImpl).isShown) { + cleanup() + return + } + + handleInlineCompletion(editor) + cleanup() + } + + override fun lookupCanceled(event: LookupEvent) { + cleanup() + } + + private fun cleanup() { + newLookup.removeLookupListener(this) + } + }) + } + + private fun handleInlineCompletion(editor: Editor) { + AmazonQLspService.executeIfRunning(project) { server -> + val params = buildInlineCompletionParams(editor) + server.inlineCompletionWithReferences(params) + } + } + + private fun buildInlineCompletionParams(editor: Editor): InlineCompletionWithReferencesParams { + return InlineCompletionWithReferencesParams().apply { + textDocument = TextDocumentIdentifier(getDocumentUri(editor)) + position = Position( + editor.caretModel.logicalPosition.line, + editor.caretModel.logicalPosition.column + ) + context = InlineCompletionContext().apply { + triggerKind = InlineCompletionTriggerKind.Invoke + } + } + } +} From 8a93408a07ec458894bc06e7b9255119efdc23b2 Mon Sep 17 00:00:00 2001 From: samgst-amazon Date: Wed, 19 Mar 2025 16:13:16 -0700 Subject: [PATCH 06/15] add to existing textDocumentServiceHandler --- .../service/CodeWhispererService.kt | 15 ---- .../AWSTextDocumentServiceHandler.kt | 78 ------------------- .../TextDocumentServiceHandler.kt | 65 +++++++++++++++- 3 files changed, 64 insertions(+), 94 deletions(-) delete mode 100644 plugins/amazonq/shared/jetbrains-community/src/software/aws/toolkits/jetbrains/services/amazonq/lsp/codewhisperer/AWSTextDocumentServiceHandler.kt diff --git a/plugins/amazonq/codewhisperer/jetbrains-community/src/software/aws/toolkits/jetbrains/services/codewhisperer/service/CodeWhispererService.kt b/plugins/amazonq/codewhisperer/jetbrains-community/src/software/aws/toolkits/jetbrains/services/codewhisperer/service/CodeWhispererService.kt index 2a659225f63..74c42c48f22 100644 --- a/plugins/amazonq/codewhisperer/jetbrains-community/src/software/aws/toolkits/jetbrains/services/codewhisperer/service/CodeWhispererService.kt +++ b/plugins/amazonq/codewhisperer/jetbrains-community/src/software/aws/toolkits/jetbrains/services/codewhisperer/service/CodeWhispererService.kt @@ -780,21 +780,6 @@ class CodeWhispererService(private val cs: CoroutineScope) : Disposable { } } - private fun buildInlineCompletionParams(requestContext: RequestContext): InlineCompletionWithReferencesParams { - return InlineCompletionWithReferencesParams( - context = InlineCompletionContext( - triggerKind = when (requestContext.triggerTypeInfo.triggerType) { - CodewhispererTriggerType.OnDemand -> InlineCompletionTriggerKind.Invoke - CodewhispererTriggerType.AutoTrigger -> InlineCompletionTriggerKind.Automatic - else -> InlineCompletionTriggerKind.Invoke - } - ) - ).apply { - textDocument = TextDocumentIdentifier(requestContext.fileContextInfo.filename) - position = Position(requestContext.caretPosition.line, requestContext.caretPosition.column) - } - } - override fun dispose() {} companion object { diff --git a/plugins/amazonq/shared/jetbrains-community/src/software/aws/toolkits/jetbrains/services/amazonq/lsp/codewhisperer/AWSTextDocumentServiceHandler.kt b/plugins/amazonq/shared/jetbrains-community/src/software/aws/toolkits/jetbrains/services/amazonq/lsp/codewhisperer/AWSTextDocumentServiceHandler.kt deleted file mode 100644 index 9cd2021fb12..00000000000 --- a/plugins/amazonq/shared/jetbrains-community/src/software/aws/toolkits/jetbrains/services/amazonq/lsp/codewhisperer/AWSTextDocumentServiceHandler.kt +++ /dev/null @@ -1,78 +0,0 @@ -// Copyright 2025 Amazon.com, Inc. or its affiliates. All Rights Reserved. -// SPDX-License-Identifier: Apache-2.0 - -package software.aws.toolkits.jetbrains.services.amazonq.lsp.codewhisperer - -import com.intellij.codeInsight.lookup.Lookup -import com.intellij.codeInsight.lookup.LookupEvent -import com.intellij.codeInsight.lookup.LookupListener -import com.intellij.codeInsight.lookup.LookupManagerListener -import com.intellij.codeInsight.lookup.impl.LookupImpl -import software.aws.toolkits.jetbrains.services.amazonq.lsp.AmazonQLspService -import software.aws.toolkits.jetbrains.services.amazonq.lsp.model.aws.textDocument.InlineCompletionContext -import software.aws.toolkits.jetbrains.services.amazonq.lsp.model.aws.textDocument.InlineCompletionListWithReferences -import software.aws.toolkits.jetbrains.services.amazonq.lsp.model.aws.textDocument.InlineCompletionTriggerKind -import software.aws.toolkits.jetbrains.services.amazonq.lsp.model.aws.textDocument.InlineCompletionWithReferencesParams -import com.intellij.openapi.Disposable -import com.intellij.openapi.editor.Editor -import org.eclipse.lsp4j.Position -import org.eclipse.lsp4j.TextDocumentIdentifier -import com.intellij.openapi.project.Project - -class AWSTextDocumentServiceHandler( - private val project: Project, - serverInstance: Disposable -) : LookupManagerListener { - - init { - project.messageBus.connect(serverInstance).subscribe( - LookupManagerListener.TOPIC, - this - ) - } - - override fun activeLookupChanged(oldLookup: Lookup?, newLookup: Lookup?) { - if (oldLookup != null || newLookup == null) return - - newLookup.addLookupListener(object : LookupListener { - override fun itemSelected(event: LookupEvent) { - val editor = event.lookup.editor - if (!(event.lookup as LookupImpl).isShown) { - cleanup() - return - } - - handleInlineCompletion(editor) - cleanup() - } - - override fun lookupCanceled(event: LookupEvent) { - cleanup() - } - - private fun cleanup() { - newLookup.removeLookupListener(this) - } - }) - } - - private fun handleInlineCompletion(editor: Editor) { - AmazonQLspService.executeIfRunning(project) { server -> - val params = buildInlineCompletionParams(editor) - server.inlineCompletionWithReferences(params) - } - } - - private fun buildInlineCompletionParams(editor: Editor): InlineCompletionWithReferencesParams { - return InlineCompletionWithReferencesParams().apply { - textDocument = TextDocumentIdentifier(getDocumentUri(editor)) - position = Position( - editor.caretModel.logicalPosition.line, - editor.caretModel.logicalPosition.column - ) - context = InlineCompletionContext().apply { - triggerKind = InlineCompletionTriggerKind.Invoke - } - } - } -} diff --git a/plugins/amazonq/shared/jetbrains-community/src/software/aws/toolkits/jetbrains/services/amazonq/lsp/textdocument/TextDocumentServiceHandler.kt b/plugins/amazonq/shared/jetbrains-community/src/software/aws/toolkits/jetbrains/services/amazonq/lsp/textdocument/TextDocumentServiceHandler.kt index 80a63f3d953..78b7cc42f08 100644 --- a/plugins/amazonq/shared/jetbrains-community/src/software/aws/toolkits/jetbrains/services/amazonq/lsp/textdocument/TextDocumentServiceHandler.kt +++ b/plugins/amazonq/shared/jetbrains-community/src/software/aws/toolkits/jetbrains/services/amazonq/lsp/textdocument/TextDocumentServiceHandler.kt @@ -3,8 +3,14 @@ package software.aws.toolkits.jetbrains.services.amazonq.lsp.textdocument +import com.intellij.codeInsight.lookup.Lookup +import com.intellij.codeInsight.lookup.LookupEvent +import com.intellij.codeInsight.lookup.LookupListener +import com.intellij.codeInsight.lookup.LookupManagerListener +import com.intellij.codeInsight.lookup.impl.LookupImpl import com.intellij.openapi.Disposable import com.intellij.openapi.editor.Document +import com.intellij.openapi.editor.Editor import com.intellij.openapi.fileEditor.FileDocumentManager import com.intellij.openapi.fileEditor.FileDocumentManagerListener import com.intellij.openapi.fileEditor.FileEditorManager @@ -19,11 +25,15 @@ import org.eclipse.lsp4j.DidChangeTextDocumentParams import org.eclipse.lsp4j.DidCloseTextDocumentParams import org.eclipse.lsp4j.DidOpenTextDocumentParams import org.eclipse.lsp4j.DidSaveTextDocumentParams +import org.eclipse.lsp4j.Position import org.eclipse.lsp4j.TextDocumentContentChangeEvent import org.eclipse.lsp4j.TextDocumentIdentifier import org.eclipse.lsp4j.TextDocumentItem import org.eclipse.lsp4j.VersionedTextDocumentIdentifier import software.aws.toolkits.jetbrains.services.amazonq.lsp.AmazonQLspService +import software.aws.toolkits.jetbrains.services.amazonq.lsp.model.aws.textDocument.InlineCompletionContext +import software.aws.toolkits.jetbrains.services.amazonq.lsp.model.aws.textDocument.InlineCompletionTriggerKind +import software.aws.toolkits.jetbrains.services.amazonq.lsp.model.aws.textDocument.InlineCompletionWithReferencesParams import software.aws.toolkits.jetbrains.services.amazonq.lsp.util.FileUriUtil.toUriString import software.aws.toolkits.jetbrains.utils.pluginAwareExecuteOnPooledThread @@ -32,7 +42,8 @@ class TextDocumentServiceHandler( serverInstance: Disposable, ) : FileDocumentManagerListener, FileEditorManagerListener, - BulkFileListener { + BulkFileListener, + LookupManagerListener { init { // didOpen & didClose events @@ -52,6 +63,58 @@ class TextDocumentServiceHandler( FileDocumentManagerListener.TOPIC, this ) + + // aws/textDocument/inlineCompletionWithReferences events + project.messageBus.connect(serverInstance).subscribe( + LookupManagerListener.TOPIC, + this + ) + } + + override fun activeLookupChanged(oldLookup: Lookup?, newLookup: Lookup?) { + if (oldLookup != null || newLookup == null) return + + newLookup.addLookupListener(object : LookupListener { + override fun itemSelected(event: LookupEvent) { + val editor = event.lookup.editor + if (!(event.lookup as LookupImpl).isShown) { + cleanup() + return + } + + handleInlineCompletion(editor) + cleanup() + } + + override fun lookupCanceled(event: LookupEvent) { + cleanup() + } + + private fun cleanup() { + newLookup.removeLookupListener(this) + } + }) + } + + private fun handleInlineCompletion(editor: Editor) { + AmazonQLspService.executeIfRunning(project) { server -> + val params = buildInlineCompletionParams(editor) + server.inlineCompletionWithReferences(params) + } + } + + private fun buildInlineCompletionParams(editor: Editor): InlineCompletionWithReferencesParams { + return InlineCompletionWithReferencesParams( + context = InlineCompletionContext( + triggerKind = InlineCompletionTriggerKind.Invoke + ) + ).apply { + textDocument = TextDocumentIdentifier(toUriString(editor.getVirtualFile())) + position = Position( + editor.caretModel.primaryCaret.visualPosition.line, + editor.caretModel.primaryCaret.offset + ) + } } override fun beforeDocumentSaving(document: Document) { From 37c88e382f8ff2ae61a86ad7458b57fec69026df Mon Sep 17 00:00:00 2001 From: samgst-amazon Date: Wed, 19 Mar 2025 17:06:09 -0700 Subject: [PATCH 07/15] detekt --- .../services/codewhisperer/service/CodeWhispererService.kt | 5 ----- .../lsp/model/aws/textDocument/InlineCompletionContext.kt | 2 +- .../aws/textDocument/InlineCompletionListWithReferences.kt | 2 +- .../lsp/model/aws/textDocument/InlineCompletionReference.kt | 2 +- .../aws/textDocument/InlineCompletionReferencePosition.kt | 3 +-- .../model/aws/textDocument/InlineCompletionTriggerKind.kt | 3 +-- .../textDocument/InlineCompletionWithReferencesParams.kt | 2 +- .../lsp/model/aws/textDocument/SelectedCompletionInfo.kt | 6 ++---- .../amazonq/lsp/textdocument/TextDocumentServiceHandler.kt | 5 ++--- 9 files changed, 10 insertions(+), 20 deletions(-) diff --git a/plugins/amazonq/codewhisperer/jetbrains-community/src/software/aws/toolkits/jetbrains/services/codewhisperer/service/CodeWhispererService.kt b/plugins/amazonq/codewhisperer/jetbrains-community/src/software/aws/toolkits/jetbrains/services/codewhisperer/service/CodeWhispererService.kt index 74c42c48f22..111ccdc509f 100644 --- a/plugins/amazonq/codewhisperer/jetbrains-community/src/software/aws/toolkits/jetbrains/services/codewhisperer/service/CodeWhispererService.kt +++ b/plugins/amazonq/codewhisperer/jetbrains-community/src/software/aws/toolkits/jetbrains/services/codewhisperer/service/CodeWhispererService.kt @@ -29,8 +29,6 @@ import kotlinx.coroutines.delay import kotlinx.coroutines.isActive import kotlinx.coroutines.launch import kotlinx.coroutines.withContext -import org.eclipse.lsp4j.Position -import org.eclipse.lsp4j.TextDocumentIdentifier import software.amazon.awssdk.core.exception.SdkServiceException import software.amazon.awssdk.core.util.DefaultSdkAutoConstructList import software.amazon.awssdk.services.codewhispererruntime.model.CodeWhispererRuntimeException @@ -55,9 +53,6 @@ import software.aws.toolkits.jetbrains.core.credentials.ToolkitConnection import software.aws.toolkits.jetbrains.core.credentials.ToolkitConnectionManager import software.aws.toolkits.jetbrains.core.credentials.pinning.CodeWhispererConnection import software.aws.toolkits.jetbrains.services.amazonq.SUPPLEMENTAL_CONTEXT_TIMEOUT -import software.aws.toolkits.jetbrains.services.amazonq.lsp.model.aws.textDocument.InlineCompletionContext -import software.aws.toolkits.jetbrains.services.amazonq.lsp.model.aws.textDocument.InlineCompletionTriggerKind -import software.aws.toolkits.jetbrains.services.amazonq.lsp.model.aws.textDocument.InlineCompletionWithReferencesParams import software.aws.toolkits.jetbrains.services.codewhisperer.credentials.CodeWhispererClientAdaptor import software.aws.toolkits.jetbrains.services.codewhisperer.customization.CodeWhispererModelConfigurator import software.aws.toolkits.jetbrains.services.codewhisperer.editor.CodeWhispererEditorManager diff --git a/plugins/amazonq/shared/jetbrains-community/src/software/aws/toolkits/jetbrains/services/amazonq/lsp/model/aws/textDocument/InlineCompletionContext.kt b/plugins/amazonq/shared/jetbrains-community/src/software/aws/toolkits/jetbrains/services/amazonq/lsp/model/aws/textDocument/InlineCompletionContext.kt index c32dcbe50ee..1edebe61fd0 100644 --- a/plugins/amazonq/shared/jetbrains-community/src/software/aws/toolkits/jetbrains/services/amazonq/lsp/model/aws/textDocument/InlineCompletionContext.kt +++ b/plugins/amazonq/shared/jetbrains-community/src/software/aws/toolkits/jetbrains/services/amazonq/lsp/model/aws/textDocument/InlineCompletionContext.kt @@ -5,5 +5,5 @@ package software.aws.toolkits.jetbrains.services.amazonq.lsp.model.aws.textDocum data class InlineCompletionContext( var triggerKind: InlineCompletionTriggerKind, - var selectedCompletionInfo: SelectedCompletionInfo? = null + var selectedCompletionInfo: SelectedCompletionInfo? = null, ) diff --git a/plugins/amazonq/shared/jetbrains-community/src/software/aws/toolkits/jetbrains/services/amazonq/lsp/model/aws/textDocument/InlineCompletionListWithReferences.kt b/plugins/amazonq/shared/jetbrains-community/src/software/aws/toolkits/jetbrains/services/amazonq/lsp/model/aws/textDocument/InlineCompletionListWithReferences.kt index 645ff79c67c..aa5490b18bc 100644 --- a/plugins/amazonq/shared/jetbrains-community/src/software/aws/toolkits/jetbrains/services/amazonq/lsp/model/aws/textDocument/InlineCompletionListWithReferences.kt +++ b/plugins/amazonq/shared/jetbrains-community/src/software/aws/toolkits/jetbrains/services/amazonq/lsp/model/aws/textDocument/InlineCompletionListWithReferences.kt @@ -5,5 +5,5 @@ package software.aws.toolkits.jetbrains.services.amazonq.lsp.model.aws.textDocum data class InlineCompletionListWithReferences( var items: List, - var sessionId: String + var sessionId: String, ) diff --git a/plugins/amazonq/shared/jetbrains-community/src/software/aws/toolkits/jetbrains/services/amazonq/lsp/model/aws/textDocument/InlineCompletionReference.kt b/plugins/amazonq/shared/jetbrains-community/src/software/aws/toolkits/jetbrains/services/amazonq/lsp/model/aws/textDocument/InlineCompletionReference.kt index 1d9784477cf..149ac6f2a5f 100644 --- a/plugins/amazonq/shared/jetbrains-community/src/software/aws/toolkits/jetbrains/services/amazonq/lsp/model/aws/textDocument/InlineCompletionReference.kt +++ b/plugins/amazonq/shared/jetbrains-community/src/software/aws/toolkits/jetbrains/services/amazonq/lsp/model/aws/textDocument/InlineCompletionReference.kt @@ -7,5 +7,5 @@ data class InlineCompletionReference( var referenceName: String, var referenceUrl: String, var licenseName: String, - var position: InlineCompletionReferencePosition + var position: InlineCompletionReferencePosition, ) diff --git a/plugins/amazonq/shared/jetbrains-community/src/software/aws/toolkits/jetbrains/services/amazonq/lsp/model/aws/textDocument/InlineCompletionReferencePosition.kt b/plugins/amazonq/shared/jetbrains-community/src/software/aws/toolkits/jetbrains/services/amazonq/lsp/model/aws/textDocument/InlineCompletionReferencePosition.kt index 6802c2283d5..5dd3e1cba27 100644 --- a/plugins/amazonq/shared/jetbrains-community/src/software/aws/toolkits/jetbrains/services/amazonq/lsp/model/aws/textDocument/InlineCompletionReferencePosition.kt +++ b/plugins/amazonq/shared/jetbrains-community/src/software/aws/toolkits/jetbrains/services/amazonq/lsp/model/aws/textDocument/InlineCompletionReferencePosition.kt @@ -5,6 +5,5 @@ package software.aws.toolkits.jetbrains.services.amazonq.lsp.model.aws.textDocum data class InlineCompletionReferencePosition( var startCharacter: Int = 0, - var endCharacter: Int = 0 + var endCharacter: Int = 0, ) - diff --git a/plugins/amazonq/shared/jetbrains-community/src/software/aws/toolkits/jetbrains/services/amazonq/lsp/model/aws/textDocument/InlineCompletionTriggerKind.kt b/plugins/amazonq/shared/jetbrains-community/src/software/aws/toolkits/jetbrains/services/amazonq/lsp/model/aws/textDocument/InlineCompletionTriggerKind.kt index 94cc50622cd..c4bbb732f51 100644 --- a/plugins/amazonq/shared/jetbrains-community/src/software/aws/toolkits/jetbrains/services/amazonq/lsp/model/aws/textDocument/InlineCompletionTriggerKind.kt +++ b/plugins/amazonq/shared/jetbrains-community/src/software/aws/toolkits/jetbrains/services/amazonq/lsp/model/aws/textDocument/InlineCompletionTriggerKind.kt @@ -5,6 +5,5 @@ package software.aws.toolkits.jetbrains.services.amazonq.lsp.model.aws.textDocum enum class InlineCompletionTriggerKind(val value: Int) { Invoke(0), - Automatic(1) + Automatic(1), } - diff --git a/plugins/amazonq/shared/jetbrains-community/src/software/aws/toolkits/jetbrains/services/amazonq/lsp/model/aws/textDocument/InlineCompletionWithReferencesParams.kt b/plugins/amazonq/shared/jetbrains-community/src/software/aws/toolkits/jetbrains/services/amazonq/lsp/model/aws/textDocument/InlineCompletionWithReferencesParams.kt index c33d9973a08..a30f2782a3e 100644 --- a/plugins/amazonq/shared/jetbrains-community/src/software/aws/toolkits/jetbrains/services/amazonq/lsp/model/aws/textDocument/InlineCompletionWithReferencesParams.kt +++ b/plugins/amazonq/shared/jetbrains-community/src/software/aws/toolkits/jetbrains/services/amazonq/lsp/model/aws/textDocument/InlineCompletionWithReferencesParams.kt @@ -6,5 +6,5 @@ package software.aws.toolkits.jetbrains.services.amazonq.lsp.model.aws.textDocum import org.eclipse.lsp4j.TextDocumentPositionAndWorkDoneProgressParams data class InlineCompletionWithReferencesParams( - var context: InlineCompletionContext + var context: InlineCompletionContext, ) : TextDocumentPositionAndWorkDoneProgressParams() diff --git a/plugins/amazonq/shared/jetbrains-community/src/software/aws/toolkits/jetbrains/services/amazonq/lsp/model/aws/textDocument/SelectedCompletionInfo.kt b/plugins/amazonq/shared/jetbrains-community/src/software/aws/toolkits/jetbrains/services/amazonq/lsp/model/aws/textDocument/SelectedCompletionInfo.kt index 650a4866e9f..a274f0adbf4 100644 --- a/plugins/amazonq/shared/jetbrains-community/src/software/aws/toolkits/jetbrains/services/amazonq/lsp/model/aws/textDocument/SelectedCompletionInfo.kt +++ b/plugins/amazonq/shared/jetbrains-community/src/software/aws/toolkits/jetbrains/services/amazonq/lsp/model/aws/textDocument/SelectedCompletionInfo.kt @@ -3,11 +3,9 @@ package software.aws.toolkits.jetbrains.services.amazonq.lsp.model.aws.textDocument -import org.eclipse.lsp4j.Range; +import org.eclipse.lsp4j.Range data class SelectedCompletionInfo( var text: String, - var range: Range + var range: Range, ) - - diff --git a/plugins/amazonq/shared/jetbrains-community/src/software/aws/toolkits/jetbrains/services/amazonq/lsp/textdocument/TextDocumentServiceHandler.kt b/plugins/amazonq/shared/jetbrains-community/src/software/aws/toolkits/jetbrains/services/amazonq/lsp/textdocument/TextDocumentServiceHandler.kt index 78b7cc42f08..26d956de19f 100644 --- a/plugins/amazonq/shared/jetbrains-community/src/software/aws/toolkits/jetbrains/services/amazonq/lsp/textdocument/TextDocumentServiceHandler.kt +++ b/plugins/amazonq/shared/jetbrains-community/src/software/aws/toolkits/jetbrains/services/amazonq/lsp/textdocument/TextDocumentServiceHandler.kt @@ -103,8 +103,8 @@ class TextDocumentServiceHandler( } } - private fun buildInlineCompletionParams(editor: Editor): InlineCompletionWithReferencesParams { - return InlineCompletionWithReferencesParams( + private fun buildInlineCompletionParams(editor: Editor): InlineCompletionWithReferencesParams = + InlineCompletionWithReferencesParams( context = InlineCompletionContext( triggerKind = InlineCompletionTriggerKind.Invoke ) @@ -115,7 +115,6 @@ class TextDocumentServiceHandler( editor.caretModel.primaryCaret.offset ) } - } override fun beforeDocumentSaving(document: Document) { AmazonQLspService.executeIfRunning(project) { languageServer -> From ae4489978cba25b3ecbe83685a02c9ca6a4d435e Mon Sep 17 00:00:00 2001 From: samgst-amazon Date: Wed, 19 Mar 2025 17:10:52 -0700 Subject: [PATCH 08/15] code scan --- .../amazonq/lsp/model/aws/textDocument/InlineCompletionItem.kt | 2 +- .../amazonq/lsp/textdocument/TextDocumentServiceHandler.kt | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/plugins/amazonq/shared/jetbrains-community/src/software/aws/toolkits/jetbrains/services/amazonq/lsp/model/aws/textDocument/InlineCompletionItem.kt b/plugins/amazonq/shared/jetbrains-community/src/software/aws/toolkits/jetbrains/services/amazonq/lsp/model/aws/textDocument/InlineCompletionItem.kt index 106e65c1609..2196dc574ee 100644 --- a/plugins/amazonq/shared/jetbrains-community/src/software/aws/toolkits/jetbrains/services/amazonq/lsp/model/aws/textDocument/InlineCompletionItem.kt +++ b/plugins/amazonq/shared/jetbrains-community/src/software/aws/toolkits/jetbrains/services/amazonq/lsp/model/aws/textDocument/InlineCompletionItem.kt @@ -6,5 +6,5 @@ package software.aws.toolkits.jetbrains.services.amazonq.lsp.model.aws.textDocum data class InlineCompletionItem( var itemId: String, var insertText: String, - var references: Array, + var references: List, ) diff --git a/plugins/amazonq/shared/jetbrains-community/src/software/aws/toolkits/jetbrains/services/amazonq/lsp/textdocument/TextDocumentServiceHandler.kt b/plugins/amazonq/shared/jetbrains-community/src/software/aws/toolkits/jetbrains/services/amazonq/lsp/textdocument/TextDocumentServiceHandler.kt index 26d956de19f..c399d49188d 100644 --- a/plugins/amazonq/shared/jetbrains-community/src/software/aws/toolkits/jetbrains/services/amazonq/lsp/textdocument/TextDocumentServiceHandler.kt +++ b/plugins/amazonq/shared/jetbrains-community/src/software/aws/toolkits/jetbrains/services/amazonq/lsp/textdocument/TextDocumentServiceHandler.kt @@ -109,7 +109,7 @@ class TextDocumentServiceHandler( triggerKind = InlineCompletionTriggerKind.Invoke ) ).apply { - textDocument = TextDocumentIdentifier(toUriString(editor.getVirtualFile())) + textDocument = TextDocumentIdentifier(toUriString(editor.virtualFile)) position = Position( editor.caretModel.primaryCaret.visualPosition.line, editor.caretModel.primaryCaret.offset From 4f62d74b3538d2426723f620aafb70549a556b23 Mon Sep 17 00:00:00 2001 From: samgst-amazon Date: Fri, 21 Mar 2025 09:46:17 -0700 Subject: [PATCH 09/15] didOpen captures already open files in IDE --- .../TextDocumentServiceHandler.kt | 34 ++++++++++++------- .../TextDocumentServiceHandlerTest.kt | 26 ++++++++++++++ 2 files changed, 48 insertions(+), 12 deletions(-) diff --git a/plugins/amazonq/shared/jetbrains-community/src/software/aws/toolkits/jetbrains/services/amazonq/lsp/textdocument/TextDocumentServiceHandler.kt b/plugins/amazonq/shared/jetbrains-community/src/software/aws/toolkits/jetbrains/services/amazonq/lsp/textdocument/TextDocumentServiceHandler.kt index 80a63f3d953..49149863b67 100644 --- a/plugins/amazonq/shared/jetbrains-community/src/software/aws/toolkits/jetbrains/services/amazonq/lsp/textdocument/TextDocumentServiceHandler.kt +++ b/plugins/amazonq/shared/jetbrains-community/src/software/aws/toolkits/jetbrains/services/amazonq/lsp/textdocument/TextDocumentServiceHandler.kt @@ -52,6 +52,27 @@ class TextDocumentServiceHandler( FileDocumentManagerListener.TOPIC, this ) + + // open files on startup + val fileEditorManager = FileEditorManager.getInstance(project) + fileEditorManager.openFiles.forEach { file -> + handleFileOpened(file) + } + } + + private fun handleFileOpened(file: VirtualFile) { + AmazonQLspService.executeIfRunning(project) { languageServer -> + toUriString(file)?.let { uri -> + languageServer.textDocumentService.didOpen( + DidOpenTextDocumentParams().apply { + textDocument = TextDocumentItem().apply { + this.uri = uri + text = file.inputStream.readAllBytes().decodeToString() + } + } + ) + } + } } override fun beforeDocumentSaving(document: Document) { @@ -99,18 +120,7 @@ class TextDocumentServiceHandler( source: FileEditorManager, file: VirtualFile, ) { - AmazonQLspService.executeIfRunning(project) { languageServer -> - toUriString(file)?.let { uri -> - languageServer.textDocumentService.didOpen( - DidOpenTextDocumentParams().apply { - textDocument = TextDocumentItem().apply { - this.uri = uri - text = file.inputStream.readAllBytes().decodeToString() - } - } - ) - } - } + handleFileOpened(file) } override fun fileClosed( diff --git a/plugins/amazonq/shared/jetbrains-community/tst/software/aws/toolkits/jetbrains/services/amazonq/lsp/textdocument/TextDocumentServiceHandlerTest.kt b/plugins/amazonq/shared/jetbrains-community/tst/software/aws/toolkits/jetbrains/services/amazonq/lsp/textdocument/TextDocumentServiceHandlerTest.kt index 4e4df327f96..231b8f8bf71 100644 --- a/plugins/amazonq/shared/jetbrains-community/tst/software/aws/toolkits/jetbrains/services/amazonq/lsp/textdocument/TextDocumentServiceHandlerTest.kt +++ b/plugins/amazonq/shared/jetbrains-community/tst/software/aws/toolkits/jetbrains/services/amazonq/lsp/textdocument/TextDocumentServiceHandlerTest.kt @@ -9,6 +9,7 @@ import com.intellij.openapi.application.ApplicationManager import com.intellij.openapi.components.serviceIfCreated import com.intellij.openapi.editor.Document import com.intellij.openapi.fileEditor.FileDocumentManager +import com.intellij.openapi.fileEditor.FileEditorManager import com.intellij.openapi.project.Project import com.intellij.openapi.vfs.VirtualFile import com.intellij.openapi.vfs.newvfs.events.VFileContentChangeEvent @@ -43,6 +44,7 @@ import java.util.concurrent.CompletableFuture class TextDocumentServiceHandlerTest { private lateinit var project: Project + private lateinit var mockFileEditorManager: FileEditorManager private lateinit var mockLanguageServer: AmazonQLanguageServer private lateinit var mockTextDocumentService: TextDocumentService private lateinit var sut: TextDocumentServiceHandler @@ -90,6 +92,11 @@ class TextDocumentServiceHandlerTest { every { messageBus.connect(any()) } returns mockConnection every { mockConnection.subscribe(any(), any()) } just runs + // Mock FileEditorManager + mockFileEditorManager = mockk() + every { mockFileEditorManager.openFiles } returns emptyArray() + every { project.getService(FileEditorManager::class.java) } returns mockFileEditorManager + sut = TextDocumentServiceHandler(project, mockk()) } @@ -126,6 +133,25 @@ class TextDocumentServiceHandlerTest { } } + @Test + fun `didOpen runs on service init`() = runTest { + val uri = URI.create("file:///test/path/file.txt") + val content = "test content" + val file = createMockVirtualFile(uri, content) + + every { mockFileEditorManager.openFiles } returns arrayOf(file) + + sut = TextDocumentServiceHandler(project, mockk()) + + val paramsSlot = slot() + verify { mockTextDocumentService.didOpen(capture(paramsSlot)) } + + with(paramsSlot.captured.textDocument) { + assertEquals(normalizeFileUri(uri.toString()), this.uri) + assertEquals(content, text) + } + } + @Test fun `didOpen runs on fileOpened`() = runTest { // Create test file From a2afd32b296af6402ad6b40c0e3577395ac6596f Mon Sep 17 00:00:00 2001 From: samgst-amazon Date: Mon, 24 Mar 2025 16:00:01 -0700 Subject: [PATCH 10/15] add more listeners to handler --- .../textdocument/AmazonQLspEnterHandler.kt | 20 ++++++++++++++++++ .../TextDocumentServiceHandler.kt | 21 +++++++++++++++++-- 2 files changed, 39 insertions(+), 2 deletions(-) create mode 100644 plugins/amazonq/shared/jetbrains-community/src/software/aws/toolkits/jetbrains/services/amazonq/lsp/textdocument/AmazonQLspEnterHandler.kt diff --git a/plugins/amazonq/shared/jetbrains-community/src/software/aws/toolkits/jetbrains/services/amazonq/lsp/textdocument/AmazonQLspEnterHandler.kt b/plugins/amazonq/shared/jetbrains-community/src/software/aws/toolkits/jetbrains/services/amazonq/lsp/textdocument/AmazonQLspEnterHandler.kt new file mode 100644 index 00000000000..ad4e69ef751 --- /dev/null +++ b/plugins/amazonq/shared/jetbrains-community/src/software/aws/toolkits/jetbrains/services/amazonq/lsp/textdocument/AmazonQLspEnterHandler.kt @@ -0,0 +1,20 @@ +// Copyright 2025 Amazon.com, Inc. or its affiliates. All Rights Reserved. +// SPDX-License-Identifier: Apache-2.0 + +package software.aws.toolkits.jetbrains.services.amazonq.lsp.textdocument + +import com.intellij.codeInsight.editorActions.EnterHandler +import com.intellij.openapi.actionSystem.DataContext +import com.intellij.openapi.editor.Caret +import com.intellij.openapi.editor.Editor +import com.intellij.openapi.editor.actionSystem.EditorActionHandler + +class AmazonQLspEnterHandler( + private val originalHandler: EditorActionHandler, + private val textDocumentHandler: TextDocumentServiceHandler, +) : EnterHandler(originalHandler) { + override fun executeWriteAction(editor: Editor, caret: Caret?, dataContext: DataContext?) { + originalHandler.execute(editor, caret, dataContext) + textDocumentHandler.handleInlineCompletion(editor) + } +} diff --git a/plugins/amazonq/shared/jetbrains-community/src/software/aws/toolkits/jetbrains/services/amazonq/lsp/textdocument/TextDocumentServiceHandler.kt b/plugins/amazonq/shared/jetbrains-community/src/software/aws/toolkits/jetbrains/services/amazonq/lsp/textdocument/TextDocumentServiceHandler.kt index dfc8bf0af18..34fe0384047 100644 --- a/plugins/amazonq/shared/jetbrains-community/src/software/aws/toolkits/jetbrains/services/amazonq/lsp/textdocument/TextDocumentServiceHandler.kt +++ b/plugins/amazonq/shared/jetbrains-community/src/software/aws/toolkits/jetbrains/services/amazonq/lsp/textdocument/TextDocumentServiceHandler.kt @@ -3,14 +3,17 @@ package software.aws.toolkits.jetbrains.services.amazonq.lsp.textdocument +import com.intellij.codeInsight.editorActions.TypedHandlerDelegate import com.intellij.codeInsight.lookup.Lookup import com.intellij.codeInsight.lookup.LookupEvent import com.intellij.codeInsight.lookup.LookupListener import com.intellij.codeInsight.lookup.LookupManagerListener import com.intellij.codeInsight.lookup.impl.LookupImpl import com.intellij.openapi.Disposable +import com.intellij.openapi.actionSystem.IdeActions import com.intellij.openapi.editor.Document import com.intellij.openapi.editor.Editor +import com.intellij.openapi.editor.actionSystem.EditorActionManager import com.intellij.openapi.fileEditor.FileDocumentManager import com.intellij.openapi.fileEditor.FileDocumentManagerListener import com.intellij.openapi.fileEditor.FileEditorManager @@ -21,6 +24,7 @@ import com.intellij.openapi.vfs.VirtualFileManager import com.intellij.openapi.vfs.newvfs.BulkFileListener import com.intellij.openapi.vfs.newvfs.events.VFileContentChangeEvent import com.intellij.openapi.vfs.newvfs.events.VFileEvent +import com.intellij.psi.PsiFile import org.eclipse.lsp4j.DidChangeTextDocumentParams import org.eclipse.lsp4j.DidCloseTextDocumentParams import org.eclipse.lsp4j.DidOpenTextDocumentParams @@ -43,7 +47,8 @@ class TextDocumentServiceHandler( ) : FileDocumentManagerListener, FileEditorManagerListener, BulkFileListener, - LookupManagerListener { + LookupManagerListener, + TypedHandlerDelegate() { init { // didOpen & didClose events @@ -70,6 +75,13 @@ class TextDocumentServiceHandler( this ) + val editorActionManager = EditorActionManager.getInstance() + val originalHandler = editorActionManager.getActionHandler(IdeActions.ACTION_EDITOR_ENTER) + editorActionManager.setActionHandler( + IdeActions.ACTION_EDITOR_ENTER, + AmazonQLspEnterHandler(originalHandler, this) + ) + // open files on startup val fileEditorManager = FileEditorManager.getInstance(project) fileEditorManager.openFiles.forEach { file -> @@ -117,7 +129,12 @@ class TextDocumentServiceHandler( }) } - private fun handleInlineCompletion(editor: Editor) { + override fun charTyped(c: Char, project: Project, editor: Editor, psiFiles: PsiFile): Result { + handleInlineCompletion(editor) + return Result.CONTINUE + } + + fun handleInlineCompletion(editor: Editor) { AmazonQLspService.executeIfRunning(project) { server -> val params = buildInlineCompletionParams(editor) server.inlineCompletionWithReferences(params) From 8af0bb3a83236eb5928342c6bdbebe2b2ac9c71c Mon Sep 17 00:00:00 2001 From: samgst-amazon Date: Wed, 26 Mar 2025 14:02:20 -0700 Subject: [PATCH 11/15] move call into codewhispererService --- .../service/CodeWhispererService.kt | 31 +++++++ .../textdocument/AmazonQLspEnterHandler.kt | 20 ----- .../TextDocumentServiceHandler.kt | 81 +------------------ 3 files changed, 32 insertions(+), 100 deletions(-) delete mode 100644 plugins/amazonq/shared/jetbrains-community/src/software/aws/toolkits/jetbrains/services/amazonq/lsp/textdocument/AmazonQLspEnterHandler.kt diff --git a/plugins/amazonq/codewhisperer/jetbrains-community/src/software/aws/toolkits/jetbrains/services/codewhisperer/service/CodeWhispererService.kt b/plugins/amazonq/codewhisperer/jetbrains-community/src/software/aws/toolkits/jetbrains/services/codewhisperer/service/CodeWhispererService.kt index 111ccdc509f..64d10ba423f 100644 --- a/plugins/amazonq/codewhisperer/jetbrains-community/src/software/aws/toolkits/jetbrains/services/codewhisperer/service/CodeWhispererService.kt +++ b/plugins/amazonq/codewhisperer/jetbrains-community/src/software/aws/toolkits/jetbrains/services/codewhisperer/service/CodeWhispererService.kt @@ -29,6 +29,8 @@ import kotlinx.coroutines.delay import kotlinx.coroutines.isActive import kotlinx.coroutines.launch import kotlinx.coroutines.withContext +import org.eclipse.lsp4j.Position +import org.eclipse.lsp4j.TextDocumentIdentifier import software.amazon.awssdk.core.exception.SdkServiceException import software.amazon.awssdk.core.util.DefaultSdkAutoConstructList import software.amazon.awssdk.services.codewhispererruntime.model.CodeWhispererRuntimeException @@ -53,6 +55,11 @@ import software.aws.toolkits.jetbrains.core.credentials.ToolkitConnection import software.aws.toolkits.jetbrains.core.credentials.ToolkitConnectionManager import software.aws.toolkits.jetbrains.core.credentials.pinning.CodeWhispererConnection import software.aws.toolkits.jetbrains.services.amazonq.SUPPLEMENTAL_CONTEXT_TIMEOUT +import software.aws.toolkits.jetbrains.services.amazonq.lsp.AmazonQLspService +import software.aws.toolkits.jetbrains.services.amazonq.lsp.model.aws.textDocument.InlineCompletionContext +import software.aws.toolkits.jetbrains.services.amazonq.lsp.model.aws.textDocument.InlineCompletionTriggerKind +import software.aws.toolkits.jetbrains.services.amazonq.lsp.model.aws.textDocument.InlineCompletionWithReferencesParams +import software.aws.toolkits.jetbrains.services.amazonq.lsp.util.FileUriUtil.toUriString import software.aws.toolkits.jetbrains.services.codewhisperer.credentials.CodeWhispererClientAdaptor import software.aws.toolkits.jetbrains.services.codewhisperer.customization.CodeWhispererModelConfigurator import software.aws.toolkits.jetbrains.services.codewhisperer.editor.CodeWhispererEditorManager @@ -205,6 +212,8 @@ class CodeWhispererService(private val cs: CoroutineScope) : Disposable { return } + // PUT HERE!!! + // invoke LSP CodeWhisperer invokeCodeWhispererInBackground(requestContext) } @@ -527,6 +536,15 @@ class CodeWhispererService(private val cs: CoroutineScope) : Disposable { return nextStates } + internal fun handleInlineCompletion(editor: Editor) { + editor.project?.let { project -> + AmazonQLspService.executeIfRunning(project) { server -> + val params = buildInlineCompletionParams(editor) + server.inlineCompletionWithReferences(params) + } + } + } + private fun initStates( requestContext: RequestContext, responseContext: ResponseContext, @@ -706,6 +724,19 @@ class CodeWhispererService(private val cs: CoroutineScope) : Disposable { return states } + private fun buildInlineCompletionParams(editor: Editor): InlineCompletionWithReferencesParams = + InlineCompletionWithReferencesParams( + context = InlineCompletionContext( + triggerKind = InlineCompletionTriggerKind.Invoke + ) + ).apply { + textDocument = TextDocumentIdentifier(toUriString(editor.virtualFile)) + position = Position( + editor.caretModel.primaryCaret.visualPosition.line, + editor.caretModel.primaryCaret.offset + ) + } + private fun addPopupChildDisposables(popup: JBPopup) { codeInsightSettingsFacade.disableCodeInsightUntil(popup) diff --git a/plugins/amazonq/shared/jetbrains-community/src/software/aws/toolkits/jetbrains/services/amazonq/lsp/textdocument/AmazonQLspEnterHandler.kt b/plugins/amazonq/shared/jetbrains-community/src/software/aws/toolkits/jetbrains/services/amazonq/lsp/textdocument/AmazonQLspEnterHandler.kt deleted file mode 100644 index ad4e69ef751..00000000000 --- a/plugins/amazonq/shared/jetbrains-community/src/software/aws/toolkits/jetbrains/services/amazonq/lsp/textdocument/AmazonQLspEnterHandler.kt +++ /dev/null @@ -1,20 +0,0 @@ -// Copyright 2025 Amazon.com, Inc. or its affiliates. All Rights Reserved. -// SPDX-License-Identifier: Apache-2.0 - -package software.aws.toolkits.jetbrains.services.amazonq.lsp.textdocument - -import com.intellij.codeInsight.editorActions.EnterHandler -import com.intellij.openapi.actionSystem.DataContext -import com.intellij.openapi.editor.Caret -import com.intellij.openapi.editor.Editor -import com.intellij.openapi.editor.actionSystem.EditorActionHandler - -class AmazonQLspEnterHandler( - private val originalHandler: EditorActionHandler, - private val textDocumentHandler: TextDocumentServiceHandler, -) : EnterHandler(originalHandler) { - override fun executeWriteAction(editor: Editor, caret: Caret?, dataContext: DataContext?) { - originalHandler.execute(editor, caret, dataContext) - textDocumentHandler.handleInlineCompletion(editor) - } -} diff --git a/plugins/amazonq/shared/jetbrains-community/src/software/aws/toolkits/jetbrains/services/amazonq/lsp/textdocument/TextDocumentServiceHandler.kt b/plugins/amazonq/shared/jetbrains-community/src/software/aws/toolkits/jetbrains/services/amazonq/lsp/textdocument/TextDocumentServiceHandler.kt index 34fe0384047..49149863b67 100644 --- a/plugins/amazonq/shared/jetbrains-community/src/software/aws/toolkits/jetbrains/services/amazonq/lsp/textdocument/TextDocumentServiceHandler.kt +++ b/plugins/amazonq/shared/jetbrains-community/src/software/aws/toolkits/jetbrains/services/amazonq/lsp/textdocument/TextDocumentServiceHandler.kt @@ -3,17 +3,8 @@ package software.aws.toolkits.jetbrains.services.amazonq.lsp.textdocument -import com.intellij.codeInsight.editorActions.TypedHandlerDelegate -import com.intellij.codeInsight.lookup.Lookup -import com.intellij.codeInsight.lookup.LookupEvent -import com.intellij.codeInsight.lookup.LookupListener -import com.intellij.codeInsight.lookup.LookupManagerListener -import com.intellij.codeInsight.lookup.impl.LookupImpl import com.intellij.openapi.Disposable -import com.intellij.openapi.actionSystem.IdeActions import com.intellij.openapi.editor.Document -import com.intellij.openapi.editor.Editor -import com.intellij.openapi.editor.actionSystem.EditorActionManager import com.intellij.openapi.fileEditor.FileDocumentManager import com.intellij.openapi.fileEditor.FileDocumentManagerListener import com.intellij.openapi.fileEditor.FileEditorManager @@ -24,20 +15,15 @@ import com.intellij.openapi.vfs.VirtualFileManager import com.intellij.openapi.vfs.newvfs.BulkFileListener import com.intellij.openapi.vfs.newvfs.events.VFileContentChangeEvent import com.intellij.openapi.vfs.newvfs.events.VFileEvent -import com.intellij.psi.PsiFile import org.eclipse.lsp4j.DidChangeTextDocumentParams import org.eclipse.lsp4j.DidCloseTextDocumentParams import org.eclipse.lsp4j.DidOpenTextDocumentParams import org.eclipse.lsp4j.DidSaveTextDocumentParams -import org.eclipse.lsp4j.Position import org.eclipse.lsp4j.TextDocumentContentChangeEvent import org.eclipse.lsp4j.TextDocumentIdentifier import org.eclipse.lsp4j.TextDocumentItem import org.eclipse.lsp4j.VersionedTextDocumentIdentifier import software.aws.toolkits.jetbrains.services.amazonq.lsp.AmazonQLspService -import software.aws.toolkits.jetbrains.services.amazonq.lsp.model.aws.textDocument.InlineCompletionContext -import software.aws.toolkits.jetbrains.services.amazonq.lsp.model.aws.textDocument.InlineCompletionTriggerKind -import software.aws.toolkits.jetbrains.services.amazonq.lsp.model.aws.textDocument.InlineCompletionWithReferencesParams import software.aws.toolkits.jetbrains.services.amazonq.lsp.util.FileUriUtil.toUriString import software.aws.toolkits.jetbrains.utils.pluginAwareExecuteOnPooledThread @@ -46,9 +32,7 @@ class TextDocumentServiceHandler( serverInstance: Disposable, ) : FileDocumentManagerListener, FileEditorManagerListener, - BulkFileListener, - LookupManagerListener, - TypedHandlerDelegate() { + BulkFileListener { init { // didOpen & didClose events @@ -69,19 +53,6 @@ class TextDocumentServiceHandler( this ) - // aws/textDocument/inlineCompletionWithReferences events - project.messageBus.connect(serverInstance).subscribe( - LookupManagerListener.TOPIC, - this - ) - - val editorActionManager = EditorActionManager.getInstance() - val originalHandler = editorActionManager.getActionHandler(IdeActions.ACTION_EDITOR_ENTER) - editorActionManager.setActionHandler( - IdeActions.ACTION_EDITOR_ENTER, - AmazonQLspEnterHandler(originalHandler, this) - ) - // open files on startup val fileEditorManager = FileEditorManager.getInstance(project) fileEditorManager.openFiles.forEach { file -> @@ -104,56 +75,6 @@ class TextDocumentServiceHandler( } } - override fun activeLookupChanged(oldLookup: Lookup?, newLookup: Lookup?) { - if (oldLookup != null || newLookup == null) return - - newLookup.addLookupListener(object : LookupListener { - override fun itemSelected(event: LookupEvent) { - val editor = event.lookup.editor - if (!(event.lookup as LookupImpl).isShown) { - cleanup() - return - } - - handleInlineCompletion(editor) - cleanup() - } - - override fun lookupCanceled(event: LookupEvent) { - cleanup() - } - - private fun cleanup() { - newLookup.removeLookupListener(this) - } - }) - } - - override fun charTyped(c: Char, project: Project, editor: Editor, psiFiles: PsiFile): Result { - handleInlineCompletion(editor) - return Result.CONTINUE - } - - fun handleInlineCompletion(editor: Editor) { - AmazonQLspService.executeIfRunning(project) { server -> - val params = buildInlineCompletionParams(editor) - server.inlineCompletionWithReferences(params) - } - } - - private fun buildInlineCompletionParams(editor: Editor): InlineCompletionWithReferencesParams = - InlineCompletionWithReferencesParams( - context = InlineCompletionContext( - triggerKind = InlineCompletionTriggerKind.Invoke - ) - ).apply { - textDocument = TextDocumentIdentifier(toUriString(editor.virtualFile)) - position = Position( - editor.caretModel.primaryCaret.visualPosition.line, - editor.caretModel.primaryCaret.offset - ) - } - override fun beforeDocumentSaving(document: Document) { AmazonQLspService.executeIfRunning(project) { languageServer -> val file = FileDocumentManager.getInstance().getFile(document) ?: return@executeIfRunning From e60ee131cb09e953f2cd0ae510b467d1eeafcaac Mon Sep 17 00:00:00 2001 From: samgst-amazon Date: Wed, 26 Mar 2025 14:40:38 -0700 Subject: [PATCH 12/15] add call --- .../services/codewhisperer/service/CodeWhispererService.kt | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/plugins/amazonq/codewhisperer/jetbrains-community/src/software/aws/toolkits/jetbrains/services/codewhisperer/service/CodeWhispererService.kt b/plugins/amazonq/codewhisperer/jetbrains-community/src/software/aws/toolkits/jetbrains/services/codewhisperer/service/CodeWhispererService.kt index 64d10ba423f..9752940eafd 100644 --- a/plugins/amazonq/codewhisperer/jetbrains-community/src/software/aws/toolkits/jetbrains/services/codewhisperer/service/CodeWhispererService.kt +++ b/plugins/amazonq/codewhisperer/jetbrains-community/src/software/aws/toolkits/jetbrains/services/codewhisperer/service/CodeWhispererService.kt @@ -212,8 +212,7 @@ class CodeWhispererService(private val cs: CoroutineScope) : Disposable { return } - // PUT HERE!!! - // invoke LSP CodeWhisperer + handleInlineCompletion(editor) invokeCodeWhispererInBackground(requestContext) } From 72d1c1f2b2823d14081f0090fa23b264a9ee8daf Mon Sep 17 00:00:00 2001 From: samgst-amazon Date: Wed, 26 Mar 2025 16:58:02 -0700 Subject: [PATCH 13/15] triggerType passed through --- .../service/CodeWhispererService.kt | 36 +++++++++++-------- 1 file changed, 22 insertions(+), 14 deletions(-) diff --git a/plugins/amazonq/codewhisperer/jetbrains-community/src/software/aws/toolkits/jetbrains/services/codewhisperer/service/CodeWhispererService.kt b/plugins/amazonq/codewhisperer/jetbrains-community/src/software/aws/toolkits/jetbrains/services/codewhisperer/service/CodeWhispererService.kt index 9752940eafd..69b0e34e970 100644 --- a/plugins/amazonq/codewhisperer/jetbrains-community/src/software/aws/toolkits/jetbrains/services/codewhisperer/service/CodeWhispererService.kt +++ b/plugins/amazonq/codewhisperer/jetbrains-community/src/software/aws/toolkits/jetbrains/services/codewhisperer/service/CodeWhispererService.kt @@ -55,6 +55,7 @@ import software.aws.toolkits.jetbrains.core.credentials.ToolkitConnection import software.aws.toolkits.jetbrains.core.credentials.ToolkitConnectionManager import software.aws.toolkits.jetbrains.core.credentials.pinning.CodeWhispererConnection import software.aws.toolkits.jetbrains.services.amazonq.SUPPLEMENTAL_CONTEXT_TIMEOUT +import com.intellij.openapi.application.ReadAction import software.aws.toolkits.jetbrains.services.amazonq.lsp.AmazonQLspService import software.aws.toolkits.jetbrains.services.amazonq.lsp.model.aws.textDocument.InlineCompletionContext import software.aws.toolkits.jetbrains.services.amazonq.lsp.model.aws.textDocument.InlineCompletionTriggerKind @@ -212,7 +213,7 @@ class CodeWhispererService(private val cs: CoroutineScope) : Disposable { return } - handleInlineCompletion(editor) + handleInlineCompletion(editor, triggerTypeInfo) invokeCodeWhispererInBackground(requestContext) } @@ -535,10 +536,10 @@ class CodeWhispererService(private val cs: CoroutineScope) : Disposable { return nextStates } - internal fun handleInlineCompletion(editor: Editor) { + private fun handleInlineCompletion(editor: Editor, triggerType: TriggerTypeInfo) { editor.project?.let { project -> AmazonQLspService.executeIfRunning(project) { server -> - val params = buildInlineCompletionParams(editor) + val params = createInlineCompletionParams(editor, triggerType) server.inlineCompletionWithReferences(params) } } @@ -723,17 +724,24 @@ class CodeWhispererService(private val cs: CoroutineScope) : Disposable { return states } - private fun buildInlineCompletionParams(editor: Editor): InlineCompletionWithReferencesParams = - InlineCompletionWithReferencesParams( - context = InlineCompletionContext( - triggerKind = InlineCompletionTriggerKind.Invoke - ) - ).apply { - textDocument = TextDocumentIdentifier(toUriString(editor.virtualFile)) - position = Position( - editor.caretModel.primaryCaret.visualPosition.line, - editor.caretModel.primaryCaret.offset - ) + private fun createInlineCompletionParams(editor: Editor, triggerTypeInfo: TriggerTypeInfo): InlineCompletionWithReferencesParams = + ReadAction.compute { + InlineCompletionWithReferencesParams( + context = InlineCompletionContext( + // Map the triggerTypeInfo to appropriate InlineCompletionTriggerKind + triggerKind = when (triggerTypeInfo.triggerType) { + CodewhispererTriggerType.OnDemand -> InlineCompletionTriggerKind.Invoke + CodewhispererTriggerType.AutoTrigger -> InlineCompletionTriggerKind.Automatic + else -> InlineCompletionTriggerKind.Invoke + } + ) + ).apply { + textDocument = TextDocumentIdentifier(toUriString(editor.virtualFile)) + position = Position( + editor.caretModel.primaryCaret.visualPosition.line, + editor.caretModel.primaryCaret.offset + ) + } } private fun addPopupChildDisposables(popup: JBPopup) { From bf77c917b72c6ab9e1d58104cf4da6fd32e60e27 Mon Sep 17 00:00:00 2001 From: samgst-amazon Date: Thu, 27 Mar 2025 10:32:27 -0700 Subject: [PATCH 14/15] ReadAction for param building --- .../services/codewhisperer/service/CodeWhispererService.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/amazonq/codewhisperer/jetbrains-community/src/software/aws/toolkits/jetbrains/services/codewhisperer/service/CodeWhispererService.kt b/plugins/amazonq/codewhisperer/jetbrains-community/src/software/aws/toolkits/jetbrains/services/codewhisperer/service/CodeWhispererService.kt index 69b0e34e970..daf5627fa77 100644 --- a/plugins/amazonq/codewhisperer/jetbrains-community/src/software/aws/toolkits/jetbrains/services/codewhisperer/service/CodeWhispererService.kt +++ b/plugins/amazonq/codewhisperer/jetbrains-community/src/software/aws/toolkits/jetbrains/services/codewhisperer/service/CodeWhispererService.kt @@ -8,6 +8,7 @@ import com.intellij.notification.NotificationAction import com.intellij.openapi.Disposable import com.intellij.openapi.application.ApplicationInfo import com.intellij.openapi.application.ApplicationManager +import com.intellij.openapi.application.ReadAction import com.intellij.openapi.application.runInEdt import com.intellij.openapi.application.runReadAction import com.intellij.openapi.components.Service @@ -55,7 +56,6 @@ import software.aws.toolkits.jetbrains.core.credentials.ToolkitConnection import software.aws.toolkits.jetbrains.core.credentials.ToolkitConnectionManager import software.aws.toolkits.jetbrains.core.credentials.pinning.CodeWhispererConnection import software.aws.toolkits.jetbrains.services.amazonq.SUPPLEMENTAL_CONTEXT_TIMEOUT -import com.intellij.openapi.application.ReadAction import software.aws.toolkits.jetbrains.services.amazonq.lsp.AmazonQLspService import software.aws.toolkits.jetbrains.services.amazonq.lsp.model.aws.textDocument.InlineCompletionContext import software.aws.toolkits.jetbrains.services.amazonq.lsp.model.aws.textDocument.InlineCompletionTriggerKind From 2ddd1384e9a4e6bb9e5e07ea9f89e6ea269ebdba Mon Sep 17 00:00:00 2001 From: samgst-amazon Date: Thu, 27 Mar 2025 11:14:35 -0700 Subject: [PATCH 15/15] test --- .../service/CodeWhispererService.kt | 4 +- .../codewhisperer/CodeWhispererServiceTest.kt | 51 +++++++++++++++++++ 2 files changed, 53 insertions(+), 2 deletions(-) diff --git a/plugins/amazonq/codewhisperer/jetbrains-community/src/software/aws/toolkits/jetbrains/services/codewhisperer/service/CodeWhispererService.kt b/plugins/amazonq/codewhisperer/jetbrains-community/src/software/aws/toolkits/jetbrains/services/codewhisperer/service/CodeWhispererService.kt index daf5627fa77..564680aa01b 100644 --- a/plugins/amazonq/codewhisperer/jetbrains-community/src/software/aws/toolkits/jetbrains/services/codewhisperer/service/CodeWhispererService.kt +++ b/plugins/amazonq/codewhisperer/jetbrains-community/src/software/aws/toolkits/jetbrains/services/codewhisperer/service/CodeWhispererService.kt @@ -213,7 +213,7 @@ class CodeWhispererService(private val cs: CoroutineScope) : Disposable { return } - handleInlineCompletion(editor, triggerTypeInfo) + handleLspInlineCompletion(editor, triggerTypeInfo) invokeCodeWhispererInBackground(requestContext) } @@ -536,7 +536,7 @@ class CodeWhispererService(private val cs: CoroutineScope) : Disposable { return nextStates } - private fun handleInlineCompletion(editor: Editor, triggerType: TriggerTypeInfo) { + fun handleLspInlineCompletion(editor: Editor, triggerType: TriggerTypeInfo) { editor.project?.let { project -> AmazonQLspService.executeIfRunning(project) { server -> val params = createInlineCompletionParams(editor, triggerType) diff --git a/plugins/amazonq/codewhisperer/jetbrains-community/tst/software/aws/toolkits/jetbrains/services/codewhisperer/CodeWhispererServiceTest.kt b/plugins/amazonq/codewhisperer/jetbrains-community/tst/software/aws/toolkits/jetbrains/services/codewhisperer/CodeWhispererServiceTest.kt index 1d5646d3869..75e6c33bb98 100644 --- a/plugins/amazonq/codewhisperer/jetbrains-community/tst/software/aws/toolkits/jetbrains/services/codewhisperer/CodeWhispererServiceTest.kt +++ b/plugins/amazonq/codewhisperer/jetbrains-community/tst/software/aws/toolkits/jetbrains/services/codewhisperer/CodeWhispererServiceTest.kt @@ -4,18 +4,22 @@ package software.aws.toolkits.jetbrains.services.codewhisperer import com.intellij.openapi.application.ApplicationManager +import com.intellij.openapi.application.runReadAction import com.intellij.openapi.ui.popup.JBPopup import com.intellij.psi.PsiFile import com.intellij.testFramework.DisposableRule import com.intellij.testFramework.replaceService import com.intellij.testFramework.runInEdtAndWait import kotlinx.coroutines.async +import kotlinx.coroutines.runBlocking import kotlinx.coroutines.test.runTest import org.assertj.core.api.Assertions.assertThat +import org.eclipse.lsp4j.jsonrpc.messages.ResponseMessage import org.junit.Before import org.junit.Ignore import org.junit.Rule import org.junit.Test +import org.mockito.Mockito.mock import org.mockito.kotlin.any import org.mockito.kotlin.argumentCaptor import org.mockito.kotlin.doReturn @@ -31,6 +35,12 @@ import software.amazon.awssdk.services.codewhispererruntime.model.ProgrammingLan import software.amazon.awssdk.services.codewhispererruntime.model.SupplementalContext import software.aws.toolkits.jetbrains.core.credentials.AwsConnectionManager import software.aws.toolkits.jetbrains.core.credentials.ToolkitConnectionManager +import software.aws.toolkits.jetbrains.services.amazonq.lsp.AmazonQLanguageServer +import software.aws.toolkits.jetbrains.services.amazonq.lsp.AmazonQLspService +import software.aws.toolkits.jetbrains.services.amazonq.lsp.model.aws.textDocument.InlineCompletionListWithReferences +import software.aws.toolkits.jetbrains.services.amazonq.lsp.model.aws.textDocument.InlineCompletionTriggerKind +import software.aws.toolkits.jetbrains.services.amazonq.lsp.model.aws.textDocument.InlineCompletionWithReferencesParams +import software.aws.toolkits.jetbrains.services.amazonq.lsp.util.FileUriUtil.toUriString import software.aws.toolkits.jetbrains.services.codewhisperer.credentials.CodeWhispererClientAdaptor import software.aws.toolkits.jetbrains.services.codewhisperer.customization.CodeWhispererCustomization import software.aws.toolkits.jetbrains.services.codewhisperer.customization.CodeWhispererModelConfigurator @@ -51,6 +61,7 @@ import software.aws.toolkits.jetbrains.services.codewhisperer.telemetry.CodeWhis import software.aws.toolkits.jetbrains.services.codewhisperer.util.FileContextProvider import software.aws.toolkits.jetbrains.utils.rules.JavaCodeInsightTestFixtureRule import software.aws.toolkits.telemetry.CodewhispererTriggerType +import java.util.concurrent.CompletableFuture class CodeWhispererServiceTest { @Rule @@ -229,6 +240,46 @@ class CodeWhispererServiceTest { assertThat(firstValue.supplementalContexts()).isEqualTo(mockSupContext.toSdkModel()) } } + + @Test + fun `test handleInlineCompletion creates correct params and sends to server`() = runTest { + val mockLspServer = mock(AmazonQLanguageServer::class.java) + val mockLspService = mock(AmazonQLspService::class.java) + val project = projectRule.project + + project.replaceService( + AmazonQLspService::class.java, + mockLspService, + disposableRule.disposable + ) + whenever(mockLspService.executeSync>(any())).thenAnswer { invocation -> + val func = invocation.getArgument CompletableFuture>(0) + runBlocking { + func.invoke(mockLspService, mockLspServer) + } + } + + val mockEditor = projectRule.fixture.editor + val mockCompletableFuture = CompletableFuture() + + whenever(mockLspServer.inlineCompletionWithReferences(any())).thenReturn(mockCompletableFuture) + val paramsCaptor = argumentCaptor() + + sut.handleLspInlineCompletion( + mockEditor, + TriggerTypeInfo(CodewhispererTriggerType.OnDemand, CodeWhispererAutomatedTriggerType.Unknown()) + ) + + verify(mockLspServer).inlineCompletionWithReferences(paramsCaptor.capture()) + + runReadAction { + val capturedParams = paramsCaptor.firstValue + assertThat(capturedParams.textDocument.uri).isEqualTo(toUriString(file.virtualFile)) + assertThat(capturedParams.position.line).isEqualTo(mockEditor.caretModel.primaryCaret.visualPosition.line) + assertThat(capturedParams.position.character).isEqualTo(mockEditor.caretModel.primaryCaret.offset) + assertThat(capturedParams.context.triggerKind).isEqualTo(InlineCompletionTriggerKind.Invoke) + } + } } private fun CodeWhispererProgrammingLanguage.toSdkModel(): ProgrammingLanguage = ProgrammingLanguage.builder()