fix: Diff打开后立即触发状态栏刷新 + 临时文件只在Accept/Reject时删除

This commit is contained in:
2026-06-18 21:31:02 +08:00
parent a87773e76f
commit 23337a2aef
+30 -9
View File
@@ -30,6 +30,7 @@ export class DiffViewer {
private tmpFiles: string[] = []; private tmpFiles: string[] = [];
/** ★ 原子锁:Diff 正在打开中,禁止清除 session */ /** ★ 原子锁:Diff 正在打开中,禁止清除 session */
private isOpening = false; private isOpening = false;
private closeListener: vscode.Disposable | null = null;
/** 外部回调:Diff 操作完成后通知(用于刷新 UI) */ /** 外部回调:Diff 操作完成后通知(用于刷新 UI) */
onDiffAction?: () => void; onDiffAction?: () => void;
@@ -51,19 +52,19 @@ export class DiffViewer {
const afterPath = this.makeTmpFile(`ai-diff-after-${editRecord.id.slice(0, 8)}${ext}`, editRecord.afterContent); const afterPath = this.makeTmpFile(`ai-diff-after-${editRecord.id.slice(0, 8)}${ext}`, editRecord.afterContent);
this.isOpening = true; this.isOpening = true;
this.activeSession = { this.setSession({
fileId: fileChangeId, fileId: fileChangeId,
editId: editRecord.id, editId: editRecord.id,
beforeTmpPath: beforePath, beforeTmpPath: beforePath,
afterTmpPath: afterPath, afterTmpPath: afterPath,
beforeUri: vscode.Uri.file(beforePath), beforeUri: vscode.Uri.file(beforePath),
afterUri: vscode.Uri.file(afterPath), afterUri: vscode.Uri.file(afterPath),
}; });
await vscode.commands.executeCommand( await vscode.commands.executeCommand(
'vscode.diff', 'vscode.diff',
this.activeSession.beforeUri, this.activeSession!.beforeUri,
this.activeSession.afterUri, this.activeSession!.afterUri,
`${fileName} — AI ${toolLabel} #${editRecord.id.slice(0, 6)} · 状态栏操作` `${fileName} — AI ${toolLabel} #${editRecord.id.slice(0, 6)} · 状态栏操作`
); );
@@ -79,18 +80,18 @@ export class DiffViewer {
const afterPath = this.makeTmpFile(`ai-diff-after-${fileChange.id.slice(0, 8)}${ext}`, fileChange.latestContent); const afterPath = this.makeTmpFile(`ai-diff-after-${fileChange.id.slice(0, 8)}${ext}`, fileChange.latestContent);
this.isOpening = true; this.isOpening = true;
this.activeSession = { this.setSession({
fileId: fileChange.id, fileId: fileChange.id,
beforeTmpPath: beforePath, beforeTmpPath: beforePath,
afterTmpPath: afterPath, afterTmpPath: afterPath,
beforeUri: vscode.Uri.file(beforePath), beforeUri: vscode.Uri.file(beforePath),
afterUri: vscode.Uri.file(afterPath), afterUri: vscode.Uri.file(afterPath),
}; });
await vscode.commands.executeCommand( await vscode.commands.executeCommand(
'vscode.diff', 'vscode.diff',
this.activeSession.beforeUri, this.activeSession!.beforeUri,
this.activeSession.afterUri, this.activeSession!.afterUri,
`${fileName} — ${fileChange.edits.length} 次 AI 编辑 · 状态栏操作` `${fileName} — ${fileChange.edits.length} 次 AI 编辑 · 状态栏操作`
); );
@@ -188,11 +189,31 @@ export class DiffViewer {
if (this.activeSession) { if (this.activeSession) {
try { await vscode.commands.executeCommand('workbench.action.closeActiveEditor'); } catch { /* ok */ } try { await vscode.commands.executeCommand('workbench.action.closeActiveEditor'); } catch { /* ok */ }
} }
this.activeSession = null; this.clearSession();
} }
// ---- 内部 ---- // ---- 内部 ----
private setSession(session: DiffSession): void {
this.clearSession();
this.activeSession = session;
// ★ isOpening 锁保护:只有非 opening 状态下的关闭才清除 session
this.closeListener = vscode.window.onDidChangeVisibleTextEditors(() => {
if (this.isOpening) return; // ← 打开中,不检测
if (!this.activeSession) return;
const stillOpen = vscode.window.visibleTextEditors.some(
e => e.document.uri.toString() === this.activeSession!.beforeUri.toString() ||
e.document.uri.toString() === this.activeSession!.afterUri.toString()
);
if (!stillOpen) this.clearSession();
});
}
private clearSession(): void {
this.activeSession = null;
if (this.closeListener) { this.closeListener.dispose(); this.closeListener = null; }
}
private makeTmpFile(name: string, content: string): string { private makeTmpFile(name: string, content: string): string {
const dir = path.join(os.tmpdir(), 'ai-diff-preview'); const dir = path.join(os.tmpdir(), 'ai-diff-preview');
if (!fs.existsSync(dir)) fs.mkdirSync(dir, { recursive: true }); if (!fs.existsSync(dir)) fs.mkdirSync(dir, { recursive: true });