Skip to content

Commit 5c26a62

Browse files
committed
feat(amazonq): Enable users to edit the original files directly on the diff view
1 parent d952d11 commit 5c26a62

File tree

1 file changed

+49
-40
lines changed

1 file changed

+49
-40
lines changed

packages/amazonq/src/lsp/chat/messages.ts

Lines changed: 49 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,8 @@ import {
6969
} from '@aws/language-server-runtimes/protocol'
7070
import { v4 as uuidv4 } from 'uuid'
7171
import * as vscode from 'vscode'
72+
import * as path from 'path'
73+
import * as os from 'os'
7274
import { Disposable, LanguageClient, Position, TextDocumentIdentifier } from 'vscode-languageclient'
7375
import { AmazonQChatViewProvider } from './webviewProvider'
7476
import {
@@ -81,22 +83,9 @@ import {
8183
SecurityIssueTreeViewProvider,
8284
CodeWhispererConstants,
8385
} from 'aws-core-vscode/codewhisperer'
84-
import {
85-
amazonQDiffScheme,
86-
AmazonQPromptSettings,
87-
messages,
88-
openUrl,
89-
isTextEditor,
90-
globals,
91-
setContext,
92-
} from 'aws-core-vscode/shared'
93-
import {
94-
DefaultAmazonQAppInitContext,
95-
messageDispatcher,
96-
EditorContentController,
97-
ViewDiffMessage,
98-
referenceLogText,
99-
} from 'aws-core-vscode/amazonq'
86+
import { AmazonQPromptSettings, messages, openUrl, isTextEditor, globals, setContext } from 'aws-core-vscode/shared'
87+
import { DefaultAmazonQAppInitContext, messageDispatcher, referenceLogText } from 'aws-core-vscode/amazonq'
88+
import { fs } from 'aws-core-vscode/shared'
10089
import { telemetry } from 'aws-core-vscode/telemetry'
10190
import { isValidResponseError } from './error'
10291
import { decryptResponse, encryptRequest } from '../encryption'
@@ -161,6 +150,7 @@ export function registerMessageListeners(
161150
encryptionKey: Buffer
162151
) {
163152
const chatStreamTokens = new Map<string, CancellationTokenSource>() // tab id -> token
153+
const tempDiffFiles = new Set<string>() // track temp files for cleanup
164154

165155
// Keep track of pending chat options to send when webview UI is ready
166156
const pendingChatOptions = languageClient.initializeResult?.awsServerCapabilities?.chatOptions
@@ -664,31 +654,50 @@ export function registerMessageListeners(
664654
)
665655

666656
languageClient.onNotification(openFileDiffNotificationType.method, async (params: OpenFileDiffParams) => {
667-
const ecc = new EditorContentController()
668-
const uri = params.originalFileUri
669-
const doc = await vscode.workspace.openTextDocument(uri)
670-
const entireDocumentSelection = new vscode.Selection(
671-
new vscode.Position(0, 0),
672-
new vscode.Position(doc.lineCount - 1, doc.lineAt(doc.lineCount - 1).text.length)
673-
)
674-
const viewDiffMessage: ViewDiffMessage = {
675-
context: {
676-
activeFileContext: {
677-
filePath: params.originalFileUri,
678-
fileText: params.originalFileContent ?? '',
679-
fileLanguage: undefined,
680-
matchPolicy: undefined,
681-
},
682-
focusAreaContext: {
683-
selectionInsideExtendedCodeBlock: entireDocumentSelection,
684-
codeBlock: '',
685-
extendedCodeBlock: '',
686-
names: undefined,
687-
},
688-
},
689-
code: params.fileContent ?? '',
657+
const currentFileUri = vscode.Uri.parse(params.originalFileUri)
658+
const originalContent = params.originalFileContent ?? ''
659+
660+
// Clean up any existing temp files first
661+
for (const tempFile of tempDiffFiles) {
662+
try {
663+
await fs.delete(tempFile)
664+
} catch {}
665+
}
666+
tempDiffFiles.clear()
667+
668+
// Create a temporary file with original content
669+
const fileName = path.basename(currentFileUri.fsPath)
670+
const tempFileName = `${path.parse(fileName).name}_original_${Date.now()}${path.extname(fileName)}`
671+
const tempFilePath = path.join(os.tmpdir(), tempFileName)
672+
673+
try {
674+
await fs.writeFile(tempFilePath, originalContent)
675+
const tempFileUri = vscode.Uri.file(tempFilePath)
676+
tempDiffFiles.add(tempFilePath)
677+
678+
// Open diff view with temp file (left) vs current file (right)
679+
await vscode.commands.executeCommand(
680+
'vscode.diff',
681+
tempFileUri,
682+
currentFileUri,
683+
`${vscode.workspace.asRelativePath(currentFileUri)} (Original ↔ Current)`,
684+
{ preview: false }
685+
)
686+
687+
// Clean up temp file when diff view is closed
688+
const disposable = vscode.window.onDidChangeVisibleTextEditors(() => {
689+
const isDiffViewOpen = vscode.window.visibleTextEditors.some(
690+
(editor) => editor.document.uri.toString() === tempFileUri.toString()
691+
)
692+
if (!isDiffViewOpen && tempDiffFiles.has(tempFilePath)) {
693+
fs.delete(tempFilePath).catch(() => {})
694+
tempDiffFiles.delete(tempFilePath)
695+
disposable.dispose()
696+
}
697+
})
698+
} catch (error) {
699+
languageClient.error(`[VSCode Client] Failed to create temp file for diff: ${error}`)
690700
}
691-
await ecc.viewDiff(viewDiffMessage, amazonQDiffScheme)
692701
})
693702

694703
languageClient.onNotification(chatUpdateNotificationType.method, (params: ChatUpdateParams) => {

0 commit comments

Comments
 (0)