From 8fa367e1474343d84f5d0f7e41d7be0c0810fee5 Mon Sep 17 00:00:00 2001 From: samgst-amazon Date: Tue, 6 May 2025 12:25:03 -0700 Subject: [PATCH 1/3] clicking q chat diff opens diff view in editor --- .../amazonq/lsp/AmazonQLanguageClient.kt | 5 ++ .../amazonq/lsp/AmazonQLanguageClientImpl.kt | 46 +++++++++++++++++++ .../lsp/model/aws/chat/FlareChatCommands.kt | 1 + .../lsp/model/aws/chat/OpenFileDiffParams.kt | 11 +++++ .../resources/MessagesBundle.properties | 1 + 5 files changed, 64 insertions(+) create mode 100644 plugins/amazonq/shared/jetbrains-community/src/software/aws/toolkits/jetbrains/services/amazonq/lsp/model/aws/chat/OpenFileDiffParams.kt diff --git a/plugins/amazonq/shared/jetbrains-community/src/software/aws/toolkits/jetbrains/services/amazonq/lsp/AmazonQLanguageClient.kt b/plugins/amazonq/shared/jetbrains-community/src/software/aws/toolkits/jetbrains/services/amazonq/lsp/AmazonQLanguageClient.kt index a7dad74b179..5cb296926f4 100644 --- a/plugins/amazonq/shared/jetbrains-community/src/software/aws/toolkits/jetbrains/services/amazonq/lsp/AmazonQLanguageClient.kt +++ b/plugins/amazonq/shared/jetbrains-community/src/software/aws/toolkits/jetbrains/services/amazonq/lsp/AmazonQLanguageClient.kt @@ -11,6 +11,8 @@ import software.aws.toolkits.jetbrains.services.amazonq.lsp.model.aws.chat.ChatU import software.aws.toolkits.jetbrains.services.amazonq.lsp.model.aws.chat.GET_SERIALIZED_CHAT_REQUEST_METHOD import software.aws.toolkits.jetbrains.services.amazonq.lsp.model.aws.chat.GetSerializedChatParams import software.aws.toolkits.jetbrains.services.amazonq.lsp.model.aws.chat.GetSerializedChatResult +import software.aws.toolkits.jetbrains.services.amazonq.lsp.model.aws.chat.OPEN_FILE_DIFF +import software.aws.toolkits.jetbrains.services.amazonq.lsp.model.aws.chat.OpenFileDiffParams import software.aws.toolkits.jetbrains.services.amazonq.lsp.model.aws.chat.OpenTabParams import software.aws.toolkits.jetbrains.services.amazonq.lsp.model.aws.chat.OpenTabResult import software.aws.toolkits.jetbrains.services.amazonq.lsp.model.aws.chat.SHOW_SAVE_FILE_DIALOG_REQUEST_METHOD @@ -38,4 +40,7 @@ interface AmazonQLanguageClient : LanguageClient { @JsonNotification(CHAT_SEND_UPDATE) fun sendChatUpdate(params: ChatUpdateParams): CompletableFuture + + @JsonNotification(OPEN_FILE_DIFF) + fun openFileDiff(params: OpenFileDiffParams): CompletableFuture } 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 f389e8b9b77..97745cabe20 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 @@ -4,6 +4,9 @@ package software.aws.toolkits.jetbrains.services.amazonq.lsp import com.google.gson.Gson +import com.intellij.diff.DiffContentFactory +import com.intellij.diff.DiffManager +import com.intellij.diff.requests.SimpleDiffRequest import com.intellij.notification.NotificationType import com.intellij.openapi.application.ApplicationManager import com.intellij.openapi.fileChooser.FileChooserFactory @@ -34,6 +37,7 @@ import software.aws.toolkits.jetbrains.services.amazonq.lsp.model.aws.chat.ChatU import software.aws.toolkits.jetbrains.services.amazonq.lsp.model.aws.chat.GET_SERIALIZED_CHAT_REQUEST_METHOD import software.aws.toolkits.jetbrains.services.amazonq.lsp.model.aws.chat.GetSerializedChatParams import software.aws.toolkits.jetbrains.services.amazonq.lsp.model.aws.chat.GetSerializedChatResult +import software.aws.toolkits.jetbrains.services.amazonq.lsp.model.aws.chat.OpenFileDiffParams import software.aws.toolkits.jetbrains.services.amazonq.lsp.model.aws.chat.OpenTabParams import software.aws.toolkits.jetbrains.services.amazonq.lsp.model.aws.chat.OpenTabResult import software.aws.toolkits.jetbrains.services.amazonq.lsp.model.aws.chat.ShowSaveFileDialogParams @@ -42,6 +46,9 @@ import software.aws.toolkits.jetbrains.services.amazonq.lsp.model.aws.credential import software.aws.toolkits.jetbrains.services.amazonq.lsp.model.aws.credentials.SsoProfileData import software.aws.toolkits.jetbrains.services.codewhisperer.customization.CodeWhispererModelConfigurator import software.aws.toolkits.jetbrains.settings.CodeWhispererSettings +import software.aws.toolkits.resources.message +import java.io.File +import java.nio.file.Paths import java.util.UUID import java.util.concurrent.CompletableFuture import java.util.concurrent.TimeUnit @@ -262,6 +269,45 @@ class AmazonQLanguageClientImpl(private val project: Project) : AmazonQLanguageC return CompletableFuture.completedFuture(Unit) } + override fun openFileDiff(params: OpenFileDiffParams): CompletableFuture = + CompletableFuture.supplyAsync({ + ApplicationManager.getApplication().invokeLater { + try { + val contentFactory = DiffContentFactory.getInstance() + val fileName = Paths.get(params.originalFileUri).fileName.toString() + + val originalContent = params.originalFileContent ?: run { + val file = File(params.originalFileUri) + if (file.exists()) file.readText() else "" + } + val (leftContent, rightContent) = when { + params.isDeleted -> { + // For deleted files, show original on left, empty on right + contentFactory.create(originalContent) to + contentFactory.createEmpty() + } + else -> { + // For new or modified files + val newContent = params.fileContent.orEmpty() + contentFactory.create(originalContent) to + contentFactory.create(newContent) + } + } + val diffRequest = SimpleDiffRequest( + "$fileName ${message("aws.q.lsp.client.diff_message")}", + leftContent, + rightContent, + "Original", + if (params.isDeleted) "Deleted" else "Modified" + ) + DiffManager.getInstance().showDiff(project, diffRequest) + } catch (e: Exception) { + LOG.warn { "Failed to open file diff: ${e.message}" } + } + } + Unit + }) + companion object { private val LOG = getLogger() } diff --git a/plugins/amazonq/shared/jetbrains-community/src/software/aws/toolkits/jetbrains/services/amazonq/lsp/model/aws/chat/FlareChatCommands.kt b/plugins/amazonq/shared/jetbrains-community/src/software/aws/toolkits/jetbrains/services/amazonq/lsp/model/aws/chat/FlareChatCommands.kt index 02934b87db1..ef044e51875 100644 --- a/plugins/amazonq/shared/jetbrains-community/src/software/aws/toolkits/jetbrains/services/amazonq/lsp/model/aws/chat/FlareChatCommands.kt +++ b/plugins/amazonq/shared/jetbrains-community/src/software/aws/toolkits/jetbrains/services/amazonq/lsp/model/aws/chat/FlareChatCommands.kt @@ -31,3 +31,4 @@ const val CHAT_SEND_UPDATE = "aws/chat/sendChatUpdate" const val CHAT_CREATE_PROMPT = "aws/chat/createPrompt" const val SHOW_SAVE_FILE_DIALOG_REQUEST_METHOD = "aws/showSaveFileDialog" const val GET_SERIALIZED_CHAT_REQUEST_METHOD = "aws/chat/getSerializedChat" +const val OPEN_FILE_DIFF = "aws/openFileDiff" diff --git a/plugins/amazonq/shared/jetbrains-community/src/software/aws/toolkits/jetbrains/services/amazonq/lsp/model/aws/chat/OpenFileDiffParams.kt b/plugins/amazonq/shared/jetbrains-community/src/software/aws/toolkits/jetbrains/services/amazonq/lsp/model/aws/chat/OpenFileDiffParams.kt new file mode 100644 index 00000000000..e0eb4870bf4 --- /dev/null +++ b/plugins/amazonq/shared/jetbrains-community/src/software/aws/toolkits/jetbrains/services/amazonq/lsp/model/aws/chat/OpenFileDiffParams.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.chat + +data class OpenFileDiffParams( + val originalFileUri: String, + val originalFileContent: String? = null, + val isDeleted: Boolean, + val fileContent: String? = null, +) diff --git a/plugins/core/resources/resources/software/aws/toolkits/resources/MessagesBundle.properties b/plugins/core/resources/resources/software/aws/toolkits/resources/MessagesBundle.properties index 81a1e774b75..da293b986ee 100644 --- a/plugins/core/resources/resources/software/aws/toolkits/resources/MessagesBundle.properties +++ b/plugins/core/resources/resources/software/aws/toolkits/resources/MessagesBundle.properties @@ -252,6 +252,7 @@ aws.onboarding.getstarted.panel.login_with_iam=Use Professional License aws.onboarding.getstarted.panel.share_feedback=Share Feedback aws.onboarding.getstarted.panel.signup_iam_text=Sign up for free aws.onboarding.getstarted.panel.title=Authenticate with AWS Toolkit +aws.q.lsp.client.diff_message=(Generated by Amazon Q) aws.q.migration.action.install.text=Install aws.q.migration.action.manage_plugins.text=Manage plugins aws.q.migration.action.read_more.text=Read more From 1d04d50578b0f1590ff8470040bfdb92d81482c7 Mon Sep 17 00:00:00 2001 From: samgst-amazon Date: Tue, 6 May 2025 14:45:16 -0700 Subject: [PATCH 2/3] feedback --- .../services/amazonq/lsp/AmazonQLanguageClientImpl.kt | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) 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 97745cabe20..5d891c1e379 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 @@ -271,7 +271,6 @@ class AmazonQLanguageClientImpl(private val project: Project) : AmazonQLanguageC override fun openFileDiff(params: OpenFileDiffParams): CompletableFuture = CompletableFuture.supplyAsync({ - ApplicationManager.getApplication().invokeLater { try { val contentFactory = DiffContentFactory.getInstance() val fileName = Paths.get(params.originalFileUri).fileName.toString() @@ -304,9 +303,9 @@ class AmazonQLanguageClientImpl(private val project: Project) : AmazonQLanguageC } catch (e: Exception) { LOG.warn { "Failed to open file diff: ${e.message}" } } - } - Unit - }) + }, + ApplicationManager.getApplication()::invokeLater + ) companion object { private val LOG = getLogger() From 1ab34894a776433bb2c597f6b6cb56843f203dab Mon Sep 17 00:00:00 2001 From: samgst-amazon Date: Tue, 6 May 2025 14:47:39 -0700 Subject: [PATCH 3/3] detekt --- .../services/amazonq/lsp/AmazonQLanguageClientImpl.kt | 3 ++- 1 file changed, 2 insertions(+), 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 5d891c1e379..f9ba4b44bd1 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 @@ -270,7 +270,8 @@ class AmazonQLanguageClientImpl(private val project: Project) : AmazonQLanguageC } override fun openFileDiff(params: OpenFileDiffParams): CompletableFuture = - CompletableFuture.supplyAsync({ + CompletableFuture.supplyAsync( + { try { val contentFactory = DiffContentFactory.getInstance() val fileName = Paths.get(params.originalFileUri).fileName.toString()