Skip to content

Commit dc4747a

Browse files
committed
Restore the user's original editor tab groups and active editor focus after the chat response preview process concludes
1 parent 041fbe7 commit dc4747a

8 files changed

Lines changed: 87 additions & 51 deletions

File tree

‎packages/vscode/src/commands/apply-chat-response-command/apply-chat-response-command.ts‎

Lines changed: 81 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -23,13 +23,22 @@ import { ResponseHistoryItem } from '@shared/types/response-history-item'
2323
let in_progress = false
2424
let placeholder_created_at_for_update: number | undefined
2525

26-
export const apply_chat_response_command = (
27-
params: {
28-
context: vscode.ExtensionContext
29-
panel_provider: PanelProvider
30-
workspace_provider: WorkspaceProvider
31-
}
32-
) => {
26+
interface SavedEditorState {
27+
uri: string
28+
view_column: vscode.ViewColumn
29+
is_active: boolean
30+
}
31+
32+
interface SavedTabGroups {
33+
editors: SavedEditorState[]
34+
active_editor_uri?: string
35+
}
36+
37+
export const apply_chat_response_command = (params: {
38+
context: vscode.ExtensionContext
39+
panel_provider: PanelProvider
40+
workspace_provider: WorkspaceProvider
41+
}) => {
3342
return vscode.commands.registerCommand(
3443
'codeWebChat.applyChatResponse',
3544
async (args?: CommandArgs) => {
@@ -57,12 +66,10 @@ export const apply_chat_response_command = (
5766
}
5867

5968
if (in_progress && !response_preview_promise_resolve) {
60-
// Running intelligent update before response preview...
6169
return
6270
}
6371

6472
if (response_preview_promise_resolve) {
65-
// Previewing response...
6673
const history = params.panel_provider.response_history
6774

6875
const new_item: ResponseHistoryItem = {
@@ -95,7 +102,28 @@ export const apply_chat_response_command = (
95102

96103
in_progress = true
97104
let before_checkpoint: Checkpoint | undefined
105+
let saved_tab_groups: SavedTabGroups | undefined
106+
98107
try {
108+
// Save current tab groups before entering preview
109+
saved_tab_groups = {
110+
editors: [],
111+
active_editor_uri:
112+
vscode.window.activeTextEditor?.document.uri.toString()
113+
}
114+
115+
for (const tab_group of vscode.window.tabGroups.all) {
116+
for (const tab of tab_group.tabs) {
117+
if (tab.input instanceof vscode.TabInputText) {
118+
saved_tab_groups.editors.push({
119+
uri: tab.input.uri.toString(),
120+
view_column: tab_group.viewColumn,
121+
is_active: tab.isActive
122+
})
123+
}
124+
}
125+
}
126+
99127
before_checkpoint = await create_checkpoint(
100128
params.workspace_provider,
101129
params.context,
@@ -224,7 +252,9 @@ export const apply_chat_response_command = (
224252
})
225253
}
226254

227-
const history_for_checkpoint = [...params.panel_provider.response_history]
255+
const history_for_checkpoint = [
256+
...params.panel_provider.response_history
257+
]
228258
const changes_accepted = await preview_handler({
229259
original_states: review_data.original_states,
230260
chat_response: review_data.chat_response,
@@ -260,6 +290,11 @@ export const apply_chat_response_command = (
260290

261291
before_checkpoint = undefined
262292
}
293+
294+
// Restore tab groups after preview ends
295+
if (saved_tab_groups) {
296+
await restore_tab_groups(saved_tab_groups)
297+
}
263298
}
264299
} catch (err: any) {
265300
vscode.window.showErrorMessage(
@@ -278,3 +313,39 @@ export const apply_chat_response_command = (
278313
}
279314
)
280315
}
316+
317+
async function restore_tab_groups(saved_state: SavedTabGroups): Promise<void> {
318+
try {
319+
// Close all current tabs first
320+
await vscode.commands.executeCommand('workbench.action.closeAllEditors')
321+
322+
// Reopen saved editors in their original view columns
323+
for (const editor of saved_state.editors) {
324+
try {
325+
const uri = vscode.Uri.parse(editor.uri)
326+
await vscode.window.showTextDocument(uri, {
327+
viewColumn: editor.view_column,
328+
preview: false,
329+
preserveFocus: !editor.is_active
330+
})
331+
} catch (error) {
332+
// File might have been deleted or is no longer accessible
333+
console.error(`Failed to restore editor for ${editor.uri}:`, error)
334+
}
335+
}
336+
337+
// Restore active editor focus if it was saved
338+
if (saved_state.active_editor_uri) {
339+
try {
340+
const active_uri = vscode.Uri.parse(saved_state.active_editor_uri)
341+
await vscode.window.showTextDocument(active_uri, {
342+
preserveFocus: false
343+
})
344+
} catch (error) {
345+
console.error('Failed to restore active editor:', error)
346+
}
347+
}
348+
} catch (error) {
349+
console.error('Failed to restore tab groups:', error)
350+
}
351+
}

‎packages/vscode/src/commands/apply-chat-response-command/handlers/diff-handler.ts‎

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -476,8 +476,7 @@ export const apply_git_patch = async (
476476
undefined
477477

478478
if (patch_info.is_renaming) {
479-
// Skip git apply and fallbacks, renaming here is a base case
480-
// where no content is changing, just paths. File is already copied.
479+
// Skip git apply and fallbacks, renaming here is a base case where no content is changing, just paths. File is already copied.
481480
success = true
482481
}
483482

‎packages/vscode/src/commands/apply-chat-response-command/handlers/fast-replace-handler.ts‎

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -87,11 +87,8 @@ export const handle_fast_replace = async (
8787
}
8888
}
8989

90-
// --- Application Phase ---
91-
// Process all files that were deemed safe.
9290
const original_states: OriginalFileState[] = []
9391
for (const file of safe_files) {
94-
// Changed from accepted_files to safe_files
9592
let workspace_root = default_workspace
9693
if (file.workspace_name && workspace_map.has(file.workspace_name)) {
9794
workspace_root = workspace_map.get(file.workspace_name)!
@@ -208,8 +205,8 @@ export const handle_fast_replace = async (
208205

209206
Logger.info({
210207
function_name: 'handle_fast_replace',
211-
message: 'Files replaced successfully', // Updated log message
212-
data: { file_count: safe_files.length } // Changed from accepted_files to safe_files
208+
message: 'Files replaced successfully',
209+
data: { file_count: safe_files.length }
213210
})
214211
return { success: true, original_states }
215212
} catch (error: any) {

‎packages/vscode/src/commands/apply-chat-response-command/handlers/restore-preview-handler.ts‎

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -126,7 +126,6 @@ export const handle_restore_preview = async (
126126
}
127127
}
128128
} else if (file.content !== undefined) {
129-
// Create or update
130129
if (file_exists) {
131130
try {
132131
const file_uri = vscode.Uri.file(safe_path)
@@ -166,7 +165,6 @@ export const handle_restore_preview = async (
166165
)
167166
}
168167
} else {
169-
// New file
170168
const directory = path.dirname(safe_path)
171169
if (!fs.existsSync(directory)) {
172170
try {

‎packages/vscode/src/commands/apply-chat-response-command/response-processor.ts‎

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -452,8 +452,8 @@ export const process_chat_response = async (
452452
} else {
453453
let has_truncated_fragments = false
454454
if (
455-
args?.edit_format === undefined || // Is undefined when invoked manually
456-
args?.edit_format == 'truncated'
455+
args?.edit_format === undefined ||
456+
args?.edit_format == 'truncated' // Is undefined when invoked manually
457457
) {
458458
has_truncated_fragments = check_for_truncated_fragments(files)
459459
}

‎packages/vscode/src/commands/apply-chat-response-command/utils/diff-processor.ts‎

Lines changed: 1 addition & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -47,11 +47,6 @@ export const process_diff = async (params: {
4747
message: 'File saved successfully'
4848
})
4949
} catch (error) {
50-
// Logger.error({
51-
// function_name: 'process_diff',
52-
// message: 'Error saving file',
53-
// data: error
54-
// })
5550
throw new Error('Failed to save file after applying diff patch')
5651
}
5752
}
@@ -259,17 +254,6 @@ export const apply_diff = (params: {
259254
if (!found) {
260255
search_replace_block.search_block_start_index = -2 // Not found
261256

262-
// Logger.error({
263-
// function_name: 'apply_diff',
264-
// message: `Search block not found: ${search_string}`
265-
// })
266-
// Logger.error({
267-
// function_name: 'apply_diff',
268-
// message: `search_replace_block: ${JSON.stringify(
269-
// search_replace_block
270-
// )}`
271-
// })
272-
273257
throw new Error(`Search block not found: ${search_string}`)
274258
}
275259
}
@@ -279,7 +263,7 @@ export const apply_diff = (params: {
279263
)
280264
valid_blocks.sort((a, b) => b.get_start_index() - a.get_start_index())
281265

282-
const result_lines = [...original_code_lines] // Operate on a copy
266+
const result_lines = [...original_code_lines]
283267

284268
for (const block of valid_blocks) {
285269
const start_index =
@@ -288,17 +272,9 @@ export const apply_diff = (params: {
288272
const replacement_content = block.replace_lines
289273

290274
if (start_index < 0 || start_index > result_lines.length) {
291-
// start_index can be == result_lines.length for appending
292-
// Logger.error({
293-
// function_name: 'apply_diff',
294-
// message: `Invalid start index ${start_index} for block application. Max index: ${
295-
// result_lines.length - 1
296-
// }`
297-
// })
298275
continue
299276
}
300277

301-
// Ensure search_count does not exceed available lines from start_index
302278
const actual_search_count = Math.min(
303279
search_count,
304280
result_lines.length - start_index

‎packages/vscode/src/commands/apply-chat-response-command/utils/file-operations.ts‎

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -204,10 +204,8 @@ const relocate_file = async (params: {
204204
await vscode.commands.executeCommand('workbench.action.closeActiveEditor')
205205
}
206206

207-
// Move the file
208207
fs.renameSync(old_safe_path, new_safe_path)
209208

210-
// Clean up empty directory if needed
211209
await remove_directory_if_empty({
212210
dir_path: path.dirname(old_safe_path),
213211
workspace_root: params.workspace_root

‎packages/vscode/src/commands/apply-chat-response-command/utils/preview/workspace-listener.ts‎

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -109,7 +109,6 @@ export const setup_workspace_listeners = (
109109
file: changed_file_in_review.reviewable_file
110110
})
111111
} else {
112-
// A file not in the review has been changed. Add it to the review.
113112
const doc = event.document
114113
if (doc.uri.scheme != 'file') return
115114
const workspace_folder = vscode.workspace.getWorkspaceFolder(doc.uri)
@@ -616,7 +615,6 @@ export const setup_workspace_listeners = (
616615
}
617616

618617
if (!is_checked) {
619-
// This is the unchecking logic
620618
// Before reverting, capture current content if file exists
621619
if (fs.existsSync(file_to_toggle.sanitized_path)) {
622620
const document = await vscode.workspace.openTextDocument(
@@ -644,7 +642,6 @@ export const setup_workspace_listeners = (
644642
Buffer.from(file_to_toggle.original_content, 'utf8')
645643
)
646644
}
647-
// This is the checking logic
648645
} else {
649646
if (file_to_toggle.reviewable_file.is_deleted) {
650647
try {

0 commit comments

Comments
 (0)