Compare commits

...

4 Commits

Author SHA1 Message Date
abeatrix bc27b9990b open diff views in beside column to preserve user's work
Open diff editors in ViewColumn.Beside instead of the current column
to avoid hiding the user's active editor. Previously, diffs would
replace the visible tab in the same editor group despite preserveFocus.

- Add viewColumn parameter to showTextDocument and vscode.diff commands
- Remove outdated comments explaining the previous behavior limitation
2025-12-05 15:25:59 -08:00
Saoud Rizwan 6bccd48f28 fix vscode stealing focus when tab was already open before being diff edited 2025-12-05 14:56:29 -08:00
abeatrix e90c66acc2 open diff view in active column instead of beside
Remove `viewColumn: vscode.ViewColumn.Beside` parameter from diff editor
calls to allow diffs to open in the currently active editor column rather
than always opening in a new column beside the current one.

The diff editor will not take focus again after the initial opening allows user to continue their work if needed while the diff editor will continue in the other tab.
2025-12-05 13:31:36 -08:00
abeatrix e48ed3ded0 refactor: show diff editor without stealing focus
- Add preserveFocus and viewColumn options to open diff beside current editor
- Switch from onDidChangeActiveTextEditor to onDidChangeVisibleTextEditors
  since active editor events don't fire when preserveFocus is true
- Only update cursor position when diff editor is already focused
- Only show file after save if it was already open before editing
- Add preserveFocus parameter to showFile method

Avoids breaking user's workflow when Cline opens diff views.
2025-12-05 12:42:40 -08:00
3 changed files with 37 additions and 10 deletions
+5
View File
@@ -0,0 +1,5 @@
---
"claude-dev": patch
---
Preserves user's editor focus when diff editor is opened.
+25 -7
View File
@@ -23,7 +23,9 @@ export class VscodeDiffViewProvider extends DiffViewProvider {
const tabs = vscode.window.tabGroups.all
.flatMap((tg) => tg.tabs)
.filter((tab) => tab.input instanceof vscode.TabInputText && arePathsEqual(tab.input.uri.fsPath, this.absolutePath))
for (const tab of tabs) {
const isInDiffViewScheme = tab.input instanceof vscode.TabInputText && tab.input.uri.scheme === DIFF_VIEW_URI_SCHEME
if (!tab.isDirty) {
try {
await vscode.window.tabGroups.close(tab)
@@ -31,7 +33,9 @@ export class VscodeDiffViewProvider extends DiffViewProvider {
console.warn("Tab close retry failed:", error.message)
}
}
this.documentWasOpen = true
if (isInDiffViewScheme) {
this.documentWasOpen = true
}
}
const uri = vscode.Uri.file(this.absolutePath)
@@ -45,22 +49,32 @@ export class VscodeDiffViewProvider extends DiffViewProvider {
arePathsEqual(tab.input.modified.fsPath, uri.fsPath),
)
// Always open in beside column to avoid hiding the user's current work
const viewColumn = vscode.ViewColumn.Beside
if (diffTab && diffTab.input instanceof vscode.TabInputTextDiff) {
// Use already open diff editor.
this.activeDiffEditor = await vscode.window.showTextDocument(diffTab.input.modified, {
preserveFocus: true,
viewColumn,
})
} else {
// Open new diff editor.
// Always use preserveFocus: true to avoid stealing focus from the user's current editor.
// We use onDidChangeVisibleTextEditors to detect when the diff editor becomes visible,
// since onDidChangeActiveTextEditor won't fire when preserveFocus is true.
this.activeDiffEditor = await new Promise<vscode.TextEditor>((resolve, reject) => {
const fileName = path.basename(uri.fsPath)
const fileExists = this.editType === "modify"
const disposable = vscode.window.onDidChangeActiveTextEditor((editor) => {
if (editor && arePathsEqual(editor.document.uri.fsPath, uri.fsPath)) {
const disposable = vscode.window.onDidChangeVisibleTextEditors((editors) => {
const editor = editors.find((e) => e.document && arePathsEqual(e.document.uri.fsPath, uri.fsPath))
if (editor) {
disposable.dispose()
resolve(editor)
}
})
vscode.commands.executeCommand(
"vscode.diff",
vscode.Uri.from({
@@ -72,6 +86,7 @@ export class VscodeDiffViewProvider extends DiffViewProvider {
`${fileName}: ${fileExists ? "Original ↔ Cline's Changes" : "New File"} (Editable)`,
{
preserveFocus: true,
viewColumn,
},
)
// This may happen on very slow machines ie project idx
@@ -81,7 +96,6 @@ export class VscodeDiffViewProvider extends DiffViewProvider {
}, 10_000)
})
}
this.fadedOverlayController = new DecorationController("fadedOverlay", this.activeDiffEditor)
this.activeLineController = new DecorationController("activeLine", this.activeDiffEditor)
// Apply faded overlay to all lines initially
@@ -96,9 +110,13 @@ export class VscodeDiffViewProvider extends DiffViewProvider {
if (!this.activeDiffEditor || !this.activeDiffEditor.document) {
throw new Error("User closed text editor, unable to edit file...")
}
// Place cursor at the beginning of the diff editor to keep it out of the way of the stream animation
const beginningOfDocument = new vscode.Position(0, 0)
this.activeDiffEditor.selection = new vscode.Selection(beginningOfDocument, beginningOfDocument)
// Only update cursor position if the diff editor is currently active to avoid stealing focus
const isActiveDiffEditorFocused = vscode.window.activeTextEditor === this.activeDiffEditor
if (isActiveDiffEditorFocused) {
// Place cursor at the beginning of the diff editor to keep it out of the way of the stream animation
const beginningOfDocument = new vscode.Position(0, 0)
this.activeDiffEditor.selection = new vscode.Selection(beginningOfDocument, beginningOfDocument)
}
// Replace the text in the diff editor document.
const document = this.activeDiffEditor?.document
+7 -3
View File
@@ -224,8 +224,8 @@ export abstract class DiffViewProvider {
}
}
async showFile(absolutePath: string): Promise<void> {
await openFile(absolutePath, true)
async showFile(absolutePath: string, preserveFocus: boolean = false): Promise<void> {
await openFile(absolutePath, preserveFocus)
}
/**
@@ -268,7 +268,11 @@ export abstract class DiffViewProvider {
// get text after save in case there is any auto-formatting done by the editor
const postSaveContent = (await this.getDocumentText()) || ""
await this.showFile(this.absolutePath)
// Only show the file if it was already open before we started editing
// This avoids forcing the user back to a file they may have navigated away from
if (this.documentWasOpen) {
await this.showFile(this.absolutePath, true)
}
await this.closeAllDiffViews()
const newProblems = await this.getNewDiagnosticProblems()