F6: diff-view toggle (Feature #17) #18
@@ -143,9 +143,77 @@ export class DiffViewController implements vscode.Disposable {
|
|||||||
return this.store?.baselinePath(docPath);
|
return this.store?.baselinePath(docPath);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Replaced by the real implementation in Task 4 (toggle UX, SLICE-3).
|
// ---- toggle UX (§6.5 PUC-1) --------------------------------------------------------
|
||||||
private toggle(_editor: vscode.TextEditor | undefined): void {
|
|
||||||
/* stub */
|
/**
|
||||||
|
* If this doc's baseline diff is the active/open tab → close it and reveal the
|
||||||
|
* normal editor; if the active editor is a tracked doc with no diff open →
|
||||||
|
* open vscode.diff (baseline left, the live document right). Untracked → warn,
|
||||||
|
* no diff.
|
||||||
|
*/
|
||||||
|
private async toggle(editor: vscode.TextEditor | undefined): Promise<void> {
|
||||||
|
if (!editor || !this.isTracked(editor.document)) {
|
||||||
|
void vscode.window.showWarningMessage(
|
||||||
|
"Cowriting: open a tracked workspace document to toggle its diff view.",
|
||||||
|
);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const document = editor.document;
|
||||||
|
const docPath = this.docPathOf(document.uri);
|
||||||
|
const openTab = this.findDiffTab(document.uri);
|
||||||
|
if (openTab) {
|
||||||
|
await vscode.window.tabGroups.close(openTab);
|
||||||
|
await vscode.window.showTextDocument(document, { preview: false });
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
this.ensureBaseline(document);
|
||||||
|
const baseline = this.baselines.get(docPath)!;
|
||||||
|
const title = `${path.basename(docPath)} — my changes since ${this.epochLabel(baseline)}`;
|
||||||
|
await vscode.commands.executeCommand(
|
||||||
|
"vscode.diff",
|
||||||
|
this.baselineUri(docPath),
|
||||||
|
document.uri,
|
||||||
|
title,
|
||||||
|
{ preview: false },
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/** The open baseline-diff tab for this document, if any. */
|
||||||
|
private findDiffTab(modified: vscode.Uri): vscode.Tab | undefined {
|
||||||
|
for (const group of vscode.window.tabGroups.all) {
|
||||||
|
for (const tab of group.tabs) {
|
||||||
|
const input = tab.input;
|
||||||
|
if (
|
||||||
|
input instanceof vscode.TabInputTextDiff &&
|
||||||
|
input.original.scheme === BASELINE_SCHEME &&
|
||||||
|
input.modified.toString() === modified.toString()
|
||||||
|
) {
|
||||||
|
return tab;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return undefined;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Human-readable epoch for the diff tab title (§5 / §6.5). */
|
||||||
|
private epochLabel(baseline: Baseline): string {
|
||||||
|
const time = new Date(baseline.capturedAt).toLocaleTimeString();
|
||||||
|
switch (baseline.reason) {
|
||||||
|
case "opened":
|
||||||
|
return `opened ${time}`;
|
||||||
|
case "machine-landing":
|
||||||
|
return `Claude landed ${time}`;
|
||||||
|
case "pinned":
|
||||||
|
return `pinned ${time}`;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Test-facing (§6.4): is this doc's baseline diff currently open in any tab
|
||||||
|
* group? The diff's `modified` side is the document's own file: URI.
|
||||||
|
*/
|
||||||
|
isDiffOpen(docPath: string): boolean {
|
||||||
|
return this.findDiffTab(vscode.Uri.file(path.join(this.rootDir, docPath))) !== undefined;
|
||||||
}
|
}
|
||||||
|
|
||||||
dispose(): void {
|
dispose(): void {
|
||||||
|
|||||||
Reference in New Issue
Block a user