mirror of
https://github.com/RooVetGit/Roo-Code.git
synced 2026-09-09 22:31:08 +00:00
fix: correct tab closing logic for autoCloseRooTabs setting
- Fixed logic to only close the edited file when autoCloseRooTabs is true but autoCloseAllRooTabs is false - Updated tests to properly mock vscode.window.tabGroups.close() method - Added isDirty property to test tab mocks
This commit is contained in:
parent
8722906284
commit
d7d9baded4
3 changed files with 56 additions and 55 deletions
|
|
@ -473,7 +473,7 @@ export class DiffViewProvider {
|
|||
.map((tab) =>
|
||||
vscode.window.tabGroups.close(tab).then(
|
||||
() => undefined,
|
||||
(err) => {
|
||||
(err: any) => {
|
||||
console.error(`Failed to close diff tab ${tab.label}`, err)
|
||||
},
|
||||
),
|
||||
|
|
|
|||
|
|
@ -77,8 +77,18 @@ export class PostEditBehaviorUtils {
|
|||
if (tab.input instanceof vscode.TabInputText) {
|
||||
const tabPath = tab.input.uri.fsPath
|
||||
|
||||
// Skip the currently edited file to avoid closing it immediately
|
||||
if (editedFilePath && arePathsEqual(tabPath, editedFilePath)) {
|
||||
// If only autoCloseRooTabs is enabled (not autoCloseAllRooTabs),
|
||||
// only close the edited file tab
|
||||
if (autoCloseRooTabs && !autoCloseAllRooTabs) {
|
||||
// Only close if this is the edited file AND it was opened by Roo
|
||||
if (editedFilePath && arePathsEqual(tabPath, editedFilePath)) {
|
||||
// Check if this file was opened by Roo
|
||||
for (const trackedPath of rooOpenedTabs) {
|
||||
if (arePathsEqual(tabPath, trackedPath)) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
|
|
@ -91,16 +101,6 @@ export class PostEditBehaviorUtils {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
// If only autoCloseRooTabs is enabled, close tabs that Roo opened (not pre-existing)
|
||||
if (autoCloseRooTabs && !autoCloseAllRooTabs) {
|
||||
// This requires the tab to be in our tracked set
|
||||
for (const trackedPath of rooOpenedTabs) {
|
||||
if (arePathsEqual(tabPath, trackedPath)) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return false
|
||||
|
|
@ -115,32 +115,32 @@ export class PostEditBehaviorUtils {
|
|||
preEditActiveEditor: vscode.TextEditor | undefined,
|
||||
editedFilePath?: string,
|
||||
): Promise<void> {
|
||||
// Try to restore focus to the pre-edit active editor if it still exists
|
||||
if (preEditActiveEditor) {
|
||||
const stillExists = vscode.window.visibleTextEditors.some(
|
||||
(editor) => editor.document.uri.toString() === preEditActiveEditor.document.uri.toString(),
|
||||
)
|
||||
try {
|
||||
// Try to restore focus to the pre-edit active editor if it still exists
|
||||
if (preEditActiveEditor) {
|
||||
const stillExists = vscode.window.visibleTextEditors.some(
|
||||
(editor) => editor.document.uri.toString() === preEditActiveEditor.document.uri.toString(),
|
||||
)
|
||||
|
||||
if (stillExists) {
|
||||
await vscode.window.showTextDocument(preEditActiveEditor.document, {
|
||||
preserveFocus: false,
|
||||
preview: false,
|
||||
})
|
||||
return
|
||||
if (stillExists) {
|
||||
await vscode.window.showTextDocument(preEditActiveEditor.document, {
|
||||
preserveFocus: false,
|
||||
preview: false,
|
||||
})
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Otherwise, try to focus on the edited file
|
||||
if (editedFilePath) {
|
||||
try {
|
||||
// Otherwise, try to focus on the edited file
|
||||
if (editedFilePath) {
|
||||
await vscode.window.showTextDocument(vscode.Uri.file(editedFilePath), {
|
||||
preserveFocus: false,
|
||||
preview: false,
|
||||
})
|
||||
} catch (err) {
|
||||
// File might not exist or be accessible
|
||||
console.debug(`Could not restore focus to edited file: ${err}`)
|
||||
}
|
||||
} catch (err) {
|
||||
// File might not exist or be accessible
|
||||
console.debug(`Could not restore focus: ${err}`)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -9,6 +9,7 @@ vi.mock("vscode", () => ({
|
|||
window: {
|
||||
tabGroups: {
|
||||
all: [],
|
||||
close: vi.fn(),
|
||||
},
|
||||
showTextDocument: vi.fn(),
|
||||
createTextEditorDecorationType: vi.fn(() => ({
|
||||
|
|
@ -51,6 +52,7 @@ describe("PostEditBehaviorUtils", () => {
|
|||
// Reset mocks
|
||||
vi.mocked(vscode.window).tabGroups = {
|
||||
all: mockTabGroups,
|
||||
close: vi.fn().mockResolvedValue(true),
|
||||
} as any
|
||||
vi.mocked(vscode.window).showTextDocument = mockShowTextDocument
|
||||
vi.mocked(vscode.window).visibleTextEditors = mockVisibleTextEditors
|
||||
|
|
@ -68,11 +70,11 @@ describe("PostEditBehaviorUtils", () => {
|
|||
tabs: [
|
||||
{
|
||||
input: { uri: { fsPath: "/path/to/file1.ts" } },
|
||||
close: vi.fn(),
|
||||
isDirty: false,
|
||||
},
|
||||
{
|
||||
input: { uri: { fsPath: "/path/to/file2.ts" } },
|
||||
close: vi.fn(),
|
||||
isDirty: false,
|
||||
},
|
||||
],
|
||||
}
|
||||
|
|
@ -87,8 +89,7 @@ describe("PostEditBehaviorUtils", () => {
|
|||
)
|
||||
|
||||
// Assert
|
||||
expect(mockTabGroup.tabs[0].close).not.toHaveBeenCalled()
|
||||
expect(mockTabGroup.tabs[1].close).not.toHaveBeenCalled()
|
||||
expect(vi.mocked(vscode.window).tabGroups.close).not.toHaveBeenCalled()
|
||||
})
|
||||
|
||||
it("should close only the edited file tab when autoCloseRooTabs is true and autoCloseAllRooTabs is false", async () => {
|
||||
|
|
@ -99,11 +100,11 @@ describe("PostEditBehaviorUtils", () => {
|
|||
tabs: [
|
||||
{
|
||||
input: new (vi.mocked(vscode).TabInputText)(vscode.Uri.file("/path/to/file1.ts")),
|
||||
close: vi.fn().mockResolvedValue(true),
|
||||
isDirty: false,
|
||||
},
|
||||
{
|
||||
input: new (vi.mocked(vscode).TabInputText)(vscode.Uri.file("/path/to/file2.ts")),
|
||||
close: vi.fn().mockResolvedValue(true),
|
||||
isDirty: false,
|
||||
},
|
||||
],
|
||||
}
|
||||
|
|
@ -118,8 +119,8 @@ describe("PostEditBehaviorUtils", () => {
|
|||
)
|
||||
|
||||
// Assert
|
||||
expect(mockTabGroup.tabs[0].close).toHaveBeenCalled()
|
||||
expect(mockTabGroup.tabs[1].close).not.toHaveBeenCalled()
|
||||
expect(vi.mocked(vscode.window).tabGroups.close).toHaveBeenCalledWith(mockTabGroup.tabs[0])
|
||||
expect(vi.mocked(vscode.window).tabGroups.close).not.toHaveBeenCalledWith(mockTabGroup.tabs[1])
|
||||
})
|
||||
|
||||
it("should close all Roo-opened tabs when autoCloseAllRooTabs is true", async () => {
|
||||
|
|
@ -130,15 +131,15 @@ describe("PostEditBehaviorUtils", () => {
|
|||
tabs: [
|
||||
{
|
||||
input: new (vi.mocked(vscode).TabInputText)(vscode.Uri.file("/path/to/file1.ts")),
|
||||
close: vi.fn().mockResolvedValue(true),
|
||||
isDirty: false,
|
||||
},
|
||||
{
|
||||
input: new (vi.mocked(vscode).TabInputText)(vscode.Uri.file("/path/to/file2.ts")),
|
||||
close: vi.fn().mockResolvedValue(true),
|
||||
isDirty: false,
|
||||
},
|
||||
{
|
||||
input: new (vi.mocked(vscode).TabInputText)(vscode.Uri.file("/path/to/file3.ts")),
|
||||
close: vi.fn().mockResolvedValue(true),
|
||||
isDirty: false,
|
||||
},
|
||||
],
|
||||
}
|
||||
|
|
@ -153,9 +154,9 @@ describe("PostEditBehaviorUtils", () => {
|
|||
)
|
||||
|
||||
// Assert
|
||||
expect(mockTabGroup.tabs[0].close).toHaveBeenCalled()
|
||||
expect(mockTabGroup.tabs[1].close).toHaveBeenCalled()
|
||||
expect(mockTabGroup.tabs[2].close).not.toHaveBeenCalled() // file3 was not opened by Roo
|
||||
expect(vi.mocked(vscode.window).tabGroups.close).toHaveBeenCalledWith(mockTabGroup.tabs[0])
|
||||
expect(vi.mocked(vscode.window).tabGroups.close).toHaveBeenCalledWith(mockTabGroup.tabs[1])
|
||||
expect(vi.mocked(vscode.window).tabGroups.close).not.toHaveBeenCalledWith(mockTabGroup.tabs[2]) // file3 was not opened by Roo
|
||||
})
|
||||
|
||||
it("should not close tabs that were not opened by Roo", async () => {
|
||||
|
|
@ -166,11 +167,11 @@ describe("PostEditBehaviorUtils", () => {
|
|||
tabs: [
|
||||
{
|
||||
input: new (vi.mocked(vscode).TabInputText)(vscode.Uri.file("/path/to/file1.ts")),
|
||||
close: vi.fn().mockResolvedValue(true),
|
||||
isDirty: false,
|
||||
},
|
||||
{
|
||||
input: new (vi.mocked(vscode).TabInputText)(vscode.Uri.file("/path/to/file2.ts")), // Not in rooOpenedTabs
|
||||
close: vi.fn().mockResolvedValue(true),
|
||||
isDirty: false,
|
||||
},
|
||||
],
|
||||
}
|
||||
|
|
@ -185,8 +186,8 @@ describe("PostEditBehaviorUtils", () => {
|
|||
)
|
||||
|
||||
// Assert
|
||||
expect(mockTabGroup.tabs[0].close).toHaveBeenCalled()
|
||||
expect(mockTabGroup.tabs[1].close).not.toHaveBeenCalled()
|
||||
expect(vi.mocked(vscode.window).tabGroups.close).toHaveBeenCalledWith(mockTabGroup.tabs[0])
|
||||
expect(vi.mocked(vscode.window).tabGroups.close).not.toHaveBeenCalledWith(mockTabGroup.tabs[1])
|
||||
})
|
||||
|
||||
it("should handle tabs without URI input gracefully", async () => {
|
||||
|
|
@ -196,15 +197,15 @@ describe("PostEditBehaviorUtils", () => {
|
|||
tabs: [
|
||||
{
|
||||
input: new (vi.mocked(vscode).TabInputText)(vscode.Uri.file("/path/to/file1.ts")),
|
||||
close: vi.fn().mockResolvedValue(true),
|
||||
isDirty: false,
|
||||
},
|
||||
{
|
||||
input: {}, // No URI
|
||||
close: vi.fn().mockResolvedValue(true),
|
||||
isDirty: false,
|
||||
},
|
||||
{
|
||||
input: null, // Null input
|
||||
close: vi.fn().mockResolvedValue(true),
|
||||
isDirty: false,
|
||||
},
|
||||
],
|
||||
}
|
||||
|
|
@ -219,9 +220,9 @@ describe("PostEditBehaviorUtils", () => {
|
|||
)
|
||||
|
||||
// Assert
|
||||
expect(mockTabGroup.tabs[0].close).toHaveBeenCalled()
|
||||
expect(mockTabGroup.tabs[1].close).not.toHaveBeenCalled()
|
||||
expect(mockTabGroup.tabs[2].close).not.toHaveBeenCalled()
|
||||
expect(vi.mocked(vscode.window).tabGroups.close).toHaveBeenCalledWith(mockTabGroup.tabs[0])
|
||||
expect(vi.mocked(vscode.window).tabGroups.close).not.toHaveBeenCalledWith(mockTabGroup.tabs[1])
|
||||
expect(vi.mocked(vscode.window).tabGroups.close).not.toHaveBeenCalledWith(mockTabGroup.tabs[2])
|
||||
})
|
||||
})
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue