Skip to content

fix(amazonq): update diff view with syntax highlights and proper new file view #5679

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 9 commits into from
May 8, 2025
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,15 @@
import com.google.gson.Gson
import com.intellij.diff.DiffContentFactory
import com.intellij.diff.DiffManager
import com.intellij.diff.DiffManagerEx
import com.intellij.diff.requests.SimpleDiffRequest
import com.intellij.notification.NotificationType
import com.intellij.openapi.application.ApplicationManager
import com.intellij.openapi.fileChooser.FileChooserFactory
import com.intellij.openapi.fileChooser.FileSaverDescriptor
import com.intellij.openapi.fileEditor.FileEditorManager
import com.intellij.openapi.project.Project
import com.intellij.openapi.vfs.LocalFileSystem
import com.intellij.openapi.vfs.VirtualFileManager
import migration.software.aws.toolkits.jetbrains.settings.AwsSettings
import org.eclipse.lsp4j.ConfigurationParams
Expand Down Expand Up @@ -48,6 +50,7 @@
import software.aws.toolkits.jetbrains.settings.CodeWhispererSettings
import software.aws.toolkits.resources.message
import java.io.File
import java.nio.file.Files
import java.nio.file.Paths
import java.util.UUID
import java.util.concurrent.CompletableFuture
Expand Down Expand Up @@ -269,40 +272,69 @@
return CompletableFuture.completedFuture(Unit)
}

private fun File.toVirtualFile() = LocalFileSystem.getInstance().findFileByIoFile(this)

Check warning on line 275 in plugins/amazonq/shared/jetbrains-community/src/software/aws/toolkits/jetbrains/services/amazonq/lsp/AmazonQLanguageClientImpl.kt

View check run for this annotation

Codecov / codecov/patch

plugins/amazonq/shared/jetbrains-community/src/software/aws/toolkits/jetbrains/services/amazonq/lsp/AmazonQLanguageClientImpl.kt#L275

Added line #L275 was not covered by tests

override fun openFileDiff(params: OpenFileDiffParams): CompletableFuture<Unit> =
CompletableFuture.supplyAsync(
{
var tempPath: java.nio.file.Path? = null

Check warning on line 280 in plugins/amazonq/shared/jetbrains-community/src/software/aws/toolkits/jetbrains/services/amazonq/lsp/AmazonQLanguageClientImpl.kt

View check run for this annotation

Codecov / codecov/patch

plugins/amazonq/shared/jetbrains-community/src/software/aws/toolkits/jetbrains/services/amazonq/lsp/AmazonQLanguageClientImpl.kt#L280

Added line #L280 was not covered by tests
try {
val contentFactory = DiffContentFactory.getInstance()
val fileName = Paths.get(params.originalFileUri).fileName.toString()
// Create a temporary virtual file for syntax highlighting
val fileExtension = fileName.substringAfterLast('.', "")
tempPath = Files.createTempFile(null, ".$fileExtension")
val virtualFile = tempPath.toFile()
.also { it.setReadOnly() }
.toVirtualFile()

Check warning on line 288 in plugins/amazonq/shared/jetbrains-community/src/software/aws/toolkits/jetbrains/services/amazonq/lsp/AmazonQLanguageClientImpl.kt

View check run for this annotation

Codecov / codecov/patch

plugins/amazonq/shared/jetbrains-community/src/software/aws/toolkits/jetbrains/services/amazonq/lsp/AmazonQLanguageClientImpl.kt#L284-L288

Added lines #L284 - L288 were not covered by tests

val originalContent = params.originalFileContent ?: run {
val file = File(params.originalFileUri)
if (file.exists()) file.readText() else ""
val sourceFile = File(params.originalFileUri)

Check warning on line 291 in plugins/amazonq/shared/jetbrains-community/src/software/aws/toolkits/jetbrains/services/amazonq/lsp/AmazonQLanguageClientImpl.kt

View check run for this annotation

Codecov / codecov/patch

plugins/amazonq/shared/jetbrains-community/src/software/aws/toolkits/jetbrains/services/amazonq/lsp/AmazonQLanguageClientImpl.kt#L291

Added line #L291 was not covered by tests
if (sourceFile.exists()) sourceFile.readText() else ""
}

val contentFactory = DiffContentFactory.getInstance()
var isNewFile = false

Check warning on line 296 in plugins/amazonq/shared/jetbrains-community/src/software/aws/toolkits/jetbrains/services/amazonq/lsp/AmazonQLanguageClientImpl.kt

View check run for this annotation

Codecov / codecov/patch

plugins/amazonq/shared/jetbrains-community/src/software/aws/toolkits/jetbrains/services/amazonq/lsp/AmazonQLanguageClientImpl.kt#L295-L296

Added lines #L295 - L296 were not covered by tests
val (leftContent, rightContent) = when {
params.isDeleted -> {
// For deleted files, show original on left, empty on right
contentFactory.create(originalContent) to
contentFactory.create(project, originalContent, virtualFile) to

Check warning on line 299 in plugins/amazonq/shared/jetbrains-community/src/software/aws/toolkits/jetbrains/services/amazonq/lsp/AmazonQLanguageClientImpl.kt

View check run for this annotation

Codecov / codecov/patch

plugins/amazonq/shared/jetbrains-community/src/software/aws/toolkits/jetbrains/services/amazonq/lsp/AmazonQLanguageClientImpl.kt#L299

Added line #L299 was not covered by tests
contentFactory.createEmpty()
}
else -> {
// For new or modified files
val newContent = params.fileContent.orEmpty()
contentFactory.create(originalContent) to
contentFactory.create(newContent)
isNewFile = newContent == originalContent
when {

Check warning on line 305 in plugins/amazonq/shared/jetbrains-community/src/software/aws/toolkits/jetbrains/services/amazonq/lsp/AmazonQLanguageClientImpl.kt

View check run for this annotation

Codecov / codecov/patch

plugins/amazonq/shared/jetbrains-community/src/software/aws/toolkits/jetbrains/services/amazonq/lsp/AmazonQLanguageClientImpl.kt#L304-L305

Added lines #L304 - L305 were not covered by tests
isNewFile -> {
contentFactory.createEmpty() to
contentFactory.create(project, newContent, virtualFile)

Check warning on line 308 in plugins/amazonq/shared/jetbrains-community/src/software/aws/toolkits/jetbrains/services/amazonq/lsp/AmazonQLanguageClientImpl.kt

View check run for this annotation

Codecov / codecov/patch

plugins/amazonq/shared/jetbrains-community/src/software/aws/toolkits/jetbrains/services/amazonq/lsp/AmazonQLanguageClientImpl.kt#L307-L308

Added lines #L307 - L308 were not covered by tests
}
else -> {
contentFactory.create(project, originalContent, virtualFile) to
contentFactory.create(project, newContent, virtualFile)

Check warning on line 312 in plugins/amazonq/shared/jetbrains-community/src/software/aws/toolkits/jetbrains/services/amazonq/lsp/AmazonQLanguageClientImpl.kt

View check run for this annotation

Codecov / codecov/patch

plugins/amazonq/shared/jetbrains-community/src/software/aws/toolkits/jetbrains/services/amazonq/lsp/AmazonQLanguageClientImpl.kt#L311-L312

Added lines #L311 - L312 were not covered by tests
}
}
}
}
val diffRequest = SimpleDiffRequest(
"$fileName ${message("aws.q.lsp.client.diff_message")}",
leftContent,
rightContent,
"Original",
if (params.isDeleted) "Deleted" else "Modified"
when {

Check warning on line 322 in plugins/amazonq/shared/jetbrains-community/src/software/aws/toolkits/jetbrains/services/amazonq/lsp/AmazonQLanguageClientImpl.kt

View check run for this annotation

Codecov / codecov/patch

plugins/amazonq/shared/jetbrains-community/src/software/aws/toolkits/jetbrains/services/amazonq/lsp/AmazonQLanguageClientImpl.kt#L322

Added line #L322 was not covered by tests
params.isDeleted -> "Deleted"
isNewFile -> "Created"
else -> "Modified"

Check warning on line 325 in plugins/amazonq/shared/jetbrains-community/src/software/aws/toolkits/jetbrains/services/amazonq/lsp/AmazonQLanguageClientImpl.kt

View check run for this annotation

Codecov / codecov/patch

plugins/amazonq/shared/jetbrains-community/src/software/aws/toolkits/jetbrains/services/amazonq/lsp/AmazonQLanguageClientImpl.kt#L325

Added line #L325 was not covered by tests
}
)
DiffManager.getInstance().showDiff(project, diffRequest)
(DiffManager.getInstance() as DiffManagerEx).showDiffBuiltin(project, diffRequest)

Check warning on line 328 in plugins/amazonq/shared/jetbrains-community/src/software/aws/toolkits/jetbrains/services/amazonq/lsp/AmazonQLanguageClientImpl.kt

View check run for this annotation

Codecov / codecov/patch

plugins/amazonq/shared/jetbrains-community/src/software/aws/toolkits/jetbrains/services/amazonq/lsp/AmazonQLanguageClientImpl.kt#L328

Added line #L328 was not covered by tests
} catch (e: Exception) {
LOG.warn { "Failed to open file diff: ${e.message}" }
} finally {
// Clean up the temporary file
try {

Check warning on line 333 in plugins/amazonq/shared/jetbrains-community/src/software/aws/toolkits/jetbrains/services/amazonq/lsp/AmazonQLanguageClientImpl.kt

View check run for this annotation

Codecov / codecov/patch

plugins/amazonq/shared/jetbrains-community/src/software/aws/toolkits/jetbrains/services/amazonq/lsp/AmazonQLanguageClientImpl.kt#L333

Added line #L333 was not covered by tests
tempPath?.let { Files.deleteIfExists(it) }
} catch (e: Exception) {
LOG.warn { "Failed to delete temporary file: ${e.message}" }

Check warning on line 336 in plugins/amazonq/shared/jetbrains-community/src/software/aws/toolkits/jetbrains/services/amazonq/lsp/AmazonQLanguageClientImpl.kt

View check run for this annotation

Codecov / codecov/patch

plugins/amazonq/shared/jetbrains-community/src/software/aws/toolkits/jetbrains/services/amazonq/lsp/AmazonQLanguageClientImpl.kt#L335-L336

Added lines #L335 - L336 were not covered by tests
}
}
},
ApplicationManager.getApplication()::invokeLater
Expand Down
Loading