From 016052d21b4cb50d4fd4a074276ae0493d995021 Mon Sep 17 00:00:00 2001 From: "sijie.zsj" Date: Fri, 25 Oct 2024 13:57:54 +0800 Subject: [PATCH] feat: support WorkspaceEditMetadata --- .../vscode/api/main.thread.workspace.ts | 9 +++-- .../extension/src/common/vscode/model.api.ts | 4 +++ .../extension/src/common/vscode/workspace.ts | 2 +- .../hosted/api/vscode/ext.host.workspace.ts | 6 ++-- packages/types/sumi-worker/worker.editor.d.ts | 21 +++++++++--- packages/types/vscode/typings/vscode.d.ts | 10 ++++++ .../vscode/typings/vscode.workspace.d.ts | 33 ++++++++++--------- 7 files changed, 58 insertions(+), 27 deletions(-) diff --git a/packages/extension/src/browser/vscode/api/main.thread.workspace.ts b/packages/extension/src/browser/vscode/api/main.thread.workspace.ts index c7ea08c3c0..8cb85137e6 100644 --- a/packages/extension/src/browser/vscode/api/main.thread.workspace.ts +++ b/packages/extension/src/browser/vscode/api/main.thread.workspace.ts @@ -112,10 +112,15 @@ export class MainThreadWorkspace extends WithEventBus implements IMainThreadWork ); } - async $tryApplyWorkspaceEdit(dto: model.WorkspaceEditDto): Promise { + async $tryApplyWorkspaceEdit( + dto: model.WorkspaceEditDto, + metadata?: model.WorkspaceEditMetadataDto, + ): Promise { try { const edits = ResourceEdit.convert(dto); - const { success } = (await this.bulkEditService.apply(edits)) as IBulkEditResult & { success: boolean }; + const { success } = (await this.bulkEditService.apply(edits, { + respectAutoSaveConfig: metadata?.isRefactoring, + })) as IBulkEditResult & { success: boolean }; return success; } catch (e) { return false; diff --git a/packages/extension/src/common/vscode/model.api.ts b/packages/extension/src/common/vscode/model.api.ts index 5d38cc5b25..9e8c0c3939 100644 --- a/packages/extension/src/common/vscode/model.api.ts +++ b/packages/extension/src/common/vscode/model.api.ts @@ -63,6 +63,10 @@ export interface CustomCodeAction { isPreferred?: boolean; } +export interface WorkspaceEditMetadataDto { + isRefactoring?: boolean; +} + /** * A position in the editor. This interface is suitable for serialization. */ diff --git a/packages/extension/src/common/vscode/workspace.ts b/packages/extension/src/common/vscode/workspace.ts index 6d035d4704..a46d5d4413 100644 --- a/packages/extension/src/common/vscode/workspace.ts +++ b/packages/extension/src/common/vscode/workspace.ts @@ -12,7 +12,7 @@ import type vscode from 'vscode'; export interface IMainThreadWorkspace extends IDisposable { $saveAll(): Promise; - $tryApplyWorkspaceEdit(dto: model.WorkspaceEditDto): Promise; + $tryApplyWorkspaceEdit(dto: model.WorkspaceEditDto, metadata?: model.WorkspaceEditMetadataDto): Promise; $updateWorkspaceFolders( start: number, deleteCount?: number, diff --git a/packages/extension/src/hosted/api/vscode/ext.host.workspace.ts b/packages/extension/src/hosted/api/vscode/ext.host.workspace.ts index 5fd24bd2d0..27dcab07fb 100644 --- a/packages/extension/src/hosted/api/vscode/ext.host.workspace.ts +++ b/packages/extension/src/hosted/api/vscode/ext.host.workspace.ts @@ -70,7 +70,7 @@ export function createWorkspaceApiFactory( console.warn(false, '[Deprecated warning]: Use the corresponding function on the `tasks` namespace instead'); return extHostTasks.registerTaskProvider(type, provider, extension); }, - applyEdit: (edit) => extHostWorkspace.applyEdit(edit), + applyEdit: (edit, metadata?: vscode.WorkspaceEditMetadata) => extHostWorkspace.applyEdit(edit, metadata), get textDocuments() { return extHostDocument.getAllDocument(); }, @@ -405,9 +405,9 @@ export class ExtHostWorkspace implements IExtHostWorkspace { return this.folders.some((folder) => folder.uri.toString() === uri.toString()); } - applyEdit(edit: WorkspaceEdit): Promise { + applyEdit(edit: WorkspaceEdit, metadata?: vscode.WorkspaceEditMetadata): Promise { const dto = TypeConverts.WorkspaceEdit.from(edit, this.extHostDoc); - return this.proxy.$tryApplyWorkspaceEdit(dto); + return this.proxy.$tryApplyWorkspaceEdit(dto, metadata); } saveAll(): Promise { diff --git a/packages/types/sumi-worker/worker.editor.d.ts b/packages/types/sumi-worker/worker.editor.d.ts index 6fb416a601..0d84e643de 100644 --- a/packages/types/sumi-worker/worker.editor.d.ts +++ b/packages/types/sumi-worker/worker.editor.d.ts @@ -543,24 +543,35 @@ declare module 'sumi-worker' { Nine = 9, } + /** + * Additional data about a workspace edit. + */ + export interface WorkspaceEditMetadata { + /** + * Signal to the editor that this edit is a refactoring. + */ + isRefactoring?: boolean; + } + export namespace workspace { /** * Make changes to one or many resources or create, delete, and rename resources as defined by the given - * [workspace edit](#WorkspaceEdit). + * {@link WorkspaceEdit workspace edit}. * * All changes of a workspace edit are applied in the same order in which they have been added. If * multiple textual inserts are made at the same position, these strings appear in the resulting text - * in the order the 'inserts' were made. Invalid sequences like 'delete file a' -> 'insert text in file a' - * cause failure of the operation. + * in the order the 'inserts' were made, unless that are interleaved with resource edits. Invalid sequences + * like 'delete file a' -> 'insert text in file a' cause failure of the operation. * * When applying a workspace edit that consists only of text edits an 'all-or-nothing'-strategy is used. * A workspace edit with resource creations or deletions aborts the operation, e.g. consecutive edits will * not be attempted, when a single edit fails. * * @param edit A workspace edit. - * @return A thenable that resolves when the edit could be applied. + * @param metadata Optional {@link WorkspaceEditMetadata metadata} for the edit. + * @returns A thenable that resolves when the edit could be applied. */ - export function applyEdit(edit: WorkspaceEdit): Thenable; + export function applyEdit(edit: WorkspaceEdit, metadata?: WorkspaceEditMetadata): Thenable; } export namespace window { diff --git a/packages/types/vscode/typings/vscode.d.ts b/packages/types/vscode/typings/vscode.d.ts index 35d63afc0c..4e29f84690 100644 --- a/packages/types/vscode/typings/vscode.d.ts +++ b/packages/types/vscode/typings/vscode.d.ts @@ -1480,6 +1480,16 @@ declare module 'vscode' { iconPath?: Uri | { light: Uri; dark: Uri } | ThemeIcon; } + /** + * Additional data about a workspace edit. + */ + export interface WorkspaceEditMetadata { + /** + * Signal to the editor that this edit is a refactoring. + */ + isRefactoring?: boolean; + } + /** * A workspace edit is a collection of textual and files changes for * multiple resources and documents. diff --git a/packages/types/vscode/typings/vscode.workspace.d.ts b/packages/types/vscode/typings/vscode.workspace.d.ts index 2cb210d0cd..4a61bfa275 100644 --- a/packages/types/vscode/typings/vscode.workspace.d.ts +++ b/packages/types/vscode/typings/vscode.workspace.d.ts @@ -57,22 +57,23 @@ declare module 'vscode' { export function getWorkspaceFolder(uri: Uri): WorkspaceFolder | undefined; /** - * Make changes to one or many resources or create, delete, and rename resources as defined by the given - * [workspace edit](#WorkspaceEdit). - * - * All changes of a workspace edit are applied in the same order in which they have been added. If - * multiple textual inserts are made at the same position, these strings appear in the resulting text - * in the order the 'inserts' were made. Invalid sequences like 'delete file a' -> 'insert text in file a' - * cause failure of the operation. - * - * When applying a workspace edit that consists only of text edits an 'all-or-nothing'-strategy is used. - * A workspace edit with resource creations or deletions aborts the operation, e.g. consecutive edits will - * not be attempted, when a single edit fails. - * - * @param edit A workspace edit. - * @return A thenable that resolves when the edit could be applied. - */ - export function applyEdit(edit: WorkspaceEdit): Thenable; + * Make changes to one or many resources or create, delete, and rename resources as defined by the given + * {@link WorkspaceEdit workspace edit}. + * + * All changes of a workspace edit are applied in the same order in which they have been added. If + * multiple textual inserts are made at the same position, these strings appear in the resulting text + * in the order the 'inserts' were made, unless that are interleaved with resource edits. Invalid sequences + * like 'delete file a' -> 'insert text in file a' cause failure of the operation. + * + * When applying a workspace edit that consists only of text edits an 'all-or-nothing'-strategy is used. + * A workspace edit with resource creations or deletions aborts the operation, e.g. consecutive edits will + * not be attempted, when a single edit fails. + * + * @param edit A workspace edit. + * @param metadata Optional {@link WorkspaceEditMetadata metadata} for the edit. + * @returns A thenable that resolves when the edit could be applied. + */ + export function applyEdit(edit: WorkspaceEdit, metadata?: WorkspaceEditMetadata): Thenable; /** * Get a workspace configuration object.