mirror of
https://github.com/Gmaker689/ai-diff-preview.git
synced 2026-09-27 07:21:51 +08:00
122c38c51e
- 新增 nextEdit/prevEdit/showEditAtIndex 命令支持逐次查看编辑 - DiffViewer 增加 editIndex/totalEdits 跟踪编辑进度 - StatusBar 增加编辑计数和逐次导航按钮 - SnapshotManager 改进 EditRecord 粒度的 accept/reject - HookHandler 支持多次编辑的二级选择(聚合/逐次) - 更新 package.json 依赖(esbuild win32-x64) - 将 .claude/hooks/ 加入 .gitignore - 删除测试.md
141 lines
5.5 KiB
TypeScript
141 lines
5.5 KiB
TypeScript
/**
|
|
* 状态栏管理器 — 常驻显示
|
|
*
|
|
* 始终在左侧状态栏显示 AI Diff 状态:
|
|
* - 有 pending 变更: $(diff) AI Diff: N文件 M编辑 (黄色) — 点击打开文件列表
|
|
* - Diff 活跃: 右侧额外显示 Accept/Reject 按钮
|
|
* - 无变更: $(diff) AI Diff (暗色) — 点击打开文件列表
|
|
*/
|
|
|
|
import * as vscode from 'vscode';
|
|
import { ChangeSetManager } from '../snapshot/snapshotManager';
|
|
import { DiffViewer, DiffSession } from './diffViewer';
|
|
import { COMMANDS } from '../models/constants';
|
|
|
|
export class StatusBarManager {
|
|
/** ★ 常驻摘要按钮 */
|
|
private summaryItem: vscode.StatusBarItem;
|
|
/** Diff 模式 Accept 按钮(接受当前文件所有变更) */
|
|
private acceptBtn: vscode.StatusBarItem;
|
|
/** Diff 模式 Reject 按钮(拒绝当前文件所有变更) */
|
|
private rejectBtn: vscode.StatusBarItem;
|
|
/** ★ 上一次编辑按钮 */
|
|
private prevEditBtn: vscode.StatusBarItem;
|
|
/** ★ 下一次编辑按钮 */
|
|
private nextEditBtn: vscode.StatusBarItem;
|
|
|
|
constructor(
|
|
private changeSetManager: ChangeSetManager,
|
|
private diffViewer: DiffViewer
|
|
) {
|
|
// ★ 常驻摘要 — 始终显示
|
|
this.summaryItem = vscode.window.createStatusBarItem(vscode.StatusBarAlignment.Left, 100);
|
|
this.summaryItem.command = COMMANDS.SHOW_DIFF_PANEL;
|
|
this.summaryItem.text = '$(diff) AI Diff';
|
|
this.summaryItem.tooltip = 'AI Diff — 点击查看变更列表';
|
|
this.summaryItem.show();
|
|
|
|
// Accept 按钮(接受当前文件所有变更)
|
|
this.acceptBtn = vscode.window.createStatusBarItem(vscode.StatusBarAlignment.Right, 100);
|
|
this.acceptBtn.command = 'aiDiffPreview.acceptAllFromDiff';
|
|
|
|
// Reject 按钮(拒绝当前文件所有变更)
|
|
this.rejectBtn = vscode.window.createStatusBarItem(vscode.StatusBarAlignment.Right, 99);
|
|
this.rejectBtn.command = 'aiDiffPreview.rejectCurrentDiff';
|
|
|
|
// ★ 上一次编辑按钮
|
|
this.prevEditBtn = vscode.window.createStatusBarItem(vscode.StatusBarAlignment.Right, 98);
|
|
this.prevEditBtn.command = 'aiDiffPreview.prevEdit';
|
|
this.prevEditBtn.tooltip = '上一次编辑 (Alt+Left)';
|
|
|
|
// ★ 下一次编辑按钮
|
|
this.nextEditBtn = vscode.window.createStatusBarItem(vscode.StatusBarAlignment.Right, 97);
|
|
this.nextEditBtn.command = 'aiDiffPreview.nextEdit';
|
|
this.nextEditBtn.tooltip = '下一次编辑 (Alt+Right)';
|
|
}
|
|
|
|
enterDiffMode(session: DiffSession): void {
|
|
this.acceptBtn.text = '$(check) Accept';
|
|
this.acceptBtn.backgroundColor = new vscode.ThemeColor('statusBarItem.warningBackground');
|
|
this.acceptBtn.tooltip = '接受此文件所有变更';
|
|
this.acceptBtn.show();
|
|
|
|
this.rejectBtn.text = '$(close) Reject';
|
|
this.rejectBtn.backgroundColor = new vscode.ThemeColor('statusBarItem.errorBackground');
|
|
this.rejectBtn.tooltip = '拒绝此文件所有变更';
|
|
this.rejectBtn.show();
|
|
|
|
// ★ 根据 session 状态显示编辑导航按钮
|
|
if (session.editIndex !== undefined && session.totalEdits !== undefined) {
|
|
// 逐次编辑模式:显示 Prev/Next 和计数
|
|
this.prevEditBtn.text = `$(arrow-left) ${session.editIndex + 1}/${session.totalEdits}`;
|
|
this.prevEditBtn.command = 'aiDiffPreview.prevEdit';
|
|
this.prevEditBtn.tooltip = `上一次编辑 (Alt+Left) — 当前第 ${session.editIndex + 1}/${session.totalEdits} 次`;
|
|
this.prevEditBtn.show();
|
|
|
|
this.nextEditBtn.text = '$(arrow-right)';
|
|
this.nextEditBtn.command = 'aiDiffPreview.nextEdit';
|
|
this.nextEditBtn.tooltip = '下一次编辑 (Alt+Right)';
|
|
this.nextEditBtn.show();
|
|
} else {
|
|
// 聚合视图模式:显示"逐次查看"入口
|
|
this.prevEditBtn.text = '$(list-ordered) 逐次查看';
|
|
this.prevEditBtn.command = 'aiDiffPreview.showEditAtIndex';
|
|
this.prevEditBtn.tooltip = '切换到逐次编辑查看模式';
|
|
this.prevEditBtn.show();
|
|
this.nextEditBtn.hide();
|
|
}
|
|
}
|
|
|
|
exitDiffMode(): void {
|
|
this.acceptBtn.hide();
|
|
this.rejectBtn.hide();
|
|
this.prevEditBtn.hide();
|
|
this.nextEditBtn.hide();
|
|
}
|
|
|
|
/** ★ 常驻刷新 */
|
|
refresh(): void {
|
|
const session = this.diffViewer.getActiveSession();
|
|
if (session) {
|
|
this.enterDiffMode(session);
|
|
} else {
|
|
this.exitDiffMode();
|
|
}
|
|
|
|
const set = this.changeSetManager.getCurrentSet();
|
|
if (!set) {
|
|
// ★ 无变更集也常驻显示
|
|
this.summaryItem.text = '$(diff) AI Diff';
|
|
this.summaryItem.tooltip = 'AI Diff — 等待变更';
|
|
this.summaryItem.backgroundColor = undefined;
|
|
this.summaryItem.show();
|
|
return;
|
|
}
|
|
|
|
const pendingFiles = set.changes.filter(c => c.status === 'pending');
|
|
const totalEdits = pendingFiles.reduce(
|
|
(sum, c) => sum + c.edits.filter(e => e.status === 'pending').length, 0
|
|
);
|
|
|
|
if (pendingFiles.length === 0 && set.changes.length > 0) {
|
|
this.summaryItem.text = '$(diff) AI Diff: 已完成';
|
|
this.summaryItem.tooltip = '所有变更已处理';
|
|
this.summaryItem.backgroundColor = undefined;
|
|
} else if (pendingFiles.length > 0) {
|
|
this.summaryItem.text = `$(diff) AI Diff: ${pendingFiles.length}文件 ${totalEdits}编辑`;
|
|
this.summaryItem.tooltip = `点击查看变更列表\n${pendingFiles.map(c => `• ${c.filePath} (${c.edits.length}次)`).join('\n')}`;
|
|
this.summaryItem.backgroundColor = new vscode.ThemeColor('statusBarItem.warningBackground');
|
|
}
|
|
|
|
this.summaryItem.show();
|
|
}
|
|
|
|
dispose(): void {
|
|
this.summaryItem.dispose();
|
|
this.acceptBtn.dispose();
|
|
this.rejectBtn.dispose();
|
|
this.prevEditBtn.dispose();
|
|
this.nextEditBtn.dispose();
|
|
}
|
|
} |