-
Notifications
You must be signed in to change notification settings - Fork 396
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
feat: support VSCode API: Workspace.save and Workspace.saveAs #4277
Conversation
Warning There were issues while running some tools. Please review the errors and either fix the tool’s configuration or disable the tool if it’s a critical failure. 🔧 eslint
warning eslint@8.57.1: This version is no longer supported. Please see https://eslint.org/version-support for other options. 概述演练此拉取请求引入了一系列文件保存和对话框交互的新功能。主要变更包括在多个服务和接口中添加 变更
建议的标签
建议的审阅者
可能相关的 PR
Thank you for using CodeRabbit. We offer it for free to the OSS community and would appreciate your support in helping us grow. If you find it useful, would you consider giving us a shout-out on your favorite social media? 🪧 TipsChatThere are 3 ways to chat with CodeRabbit:
Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments. CodeRabbit Commands (Invoked using PR comments)
Other keywords and placeholders
CodeRabbit Configuration File (
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 0
🧹 Nitpick comments (9)
packages/file-tree-next/src/browser/dialog/file-dialog.service.ts (3)
32-34
: 新增 workbenchEditorService 字段
工作台编辑器服务的注入有助于文件打开流程,但建议在后续调用时增加错误处理,以提高健壮性。
140-151
: saveAs 方法实现
- 建议在执行
this.workbenchEditorService.open(...)
之前对新文件路径做有效性或存在性校验。- 函数内含
TODO
标注,后续如果迁移 fileSystemProvider,需要确保依赖关系调整安全。
152-161
: createFile 方法实现
- 对
readFile
与createFile
操作建议增加异常捕获,以防出现网络或权限导致的错误无法及时处理。- 使用
content.toString()
并指定'utf8'
编码可行,但若存在其他编码文件需考虑兼容性。packages/extension/src/browser/vscode/api/main.thread.workspace.ts (1)
130-138
: 新增 $save 方法
- 通过
editorService.save()
完成当前资源保存,若异常则返回undefined
。- 可额外考虑在调用前后对传入 URI 进行校验,以免出现不合法状态。
packages/file-tree-next/src/browser/dialog/file-dialog.view.tsx (1)
75-81
: 对“saveAs”逻辑的条件判断在此处,当
options.saveAs
为真时才执行fileService.saveAs
。逻辑上可行,但建议确保oldFilePath
与newFilePath
的构建方式不会出现路径拼接错误或用户输入无效情况。如果需要更健壮,可在调用前验证路径的有效性并在界面给出提示。packages/extension/src/hosted/api/vscode/ext.host.workspace.ts (1)
2-11
: 关于新的公共引用导入此处批量引入了多种核心工具和类型,整体代码可读性尚可。但请留意确保只导入实际需要的依赖,以免增加包大小或引发循环依赖。
packages/editor/src/common/editor.ts (1)
552-561
: 新增的保存功能抽象方法
save()
和saveAs(uri: URI)
的抽象定义为编辑器提供了基础的保存操作扩展点,能与其他服务无缝衔接。确保在实现类中妥善处理异常情况,并考虑交互提示(如文件覆盖警告)。packages/extension/__tests__/browser/extension-service/extension-service-mock-helper.ts (2)
335-337
: 新增save()
方法逻辑尚未实现此处只是简单抛出了
Not implemented
错误。若需要在单元测试或集成测试中模拟具体保存行为,建议提供最少量的模拟逻辑(例如返回一个已完成的 Promise)或更完善的自定义实现,以便在测试环境下进行更真实的行为校验。
338-340
: 新增saveAs(uri: URI)
方法逻辑尚未实现同上,当前实现仅抛出
Not implemented
。如果后续测试需要校验保存到新文件路径产生的行为,建议在 Mock 中增加对应的模拟返回值或成功、失败的场景,以保证测试覆盖到相关逻辑。
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (11)
packages/editor/src/browser/workbench-editor.service.ts
(4 hunks)packages/editor/src/common/editor.ts
(1 hunks)packages/editor/src/common/mocks/workbench-editor.service.ts
(1 hunks)packages/extension/__tests__/browser/extension-service/extension-service-mock-helper.ts
(1 hunks)packages/extension/src/browser/vscode/api/main.thread.workspace.ts
(1 hunks)packages/extension/src/common/vscode/workspace.ts
(1 hunks)packages/extension/src/hosted/api/vscode/ext.host.workspace.ts
(3 hunks)packages/file-tree-next/src/browser/dialog/file-dialog.service.ts
(3 hunks)packages/file-tree-next/src/browser/dialog/file-dialog.view.tsx
(1 hunks)packages/overlay/src/common/index.ts
(1 hunks)packages/types/vscode/typings/vscode.workspace.d.ts
(1 hunks)
🔇 Additional comments (22)
packages/file-tree-next/src/browser/dialog/file-dialog.service.ts (3)
5-7
: 依赖引用检查
这些新增的导入语句为文件读取、编辑器服务和对话框功能提供支持,目前未发现冲突或重叠问题,使用合理。
29-31
: 新增 fileServiceClient 字段
此字段使该服务可直接调用文件服务进行文件操作,实现符合需求。
35-37
: 新增 dialogService 字段
注入对话框服务,用于与用户进行交互式对话,功能集成正常。
packages/editor/src/browser/workbench-editor.service.ts (9)
47-47
: isWindows 导入
此处导入用于根据操作系统区分路径处理,逻辑上无冲突。
51-51
: 引入 path
新增 path 工具辅助路径拼接与解析,十分实用。
53-53
: 引入 IFileServiceClient
为后续的文件读写及保存提供支持,导入无误。
55-55
: 引入 IWindowDialogService 等
为使用系统对话框进行保存路径选择作准备,场景适配合理。
131-133
: fileServiceClient 字段自动注入
便于统一管理文件存储操作,实现方式合理。
181-183
: windowDialogService 字段自动注入
弹窗服务为 saveAs
提供交互入口,与整体功能结合良好。
263-267
: 新增 save 方法
仅在当前编辑器组存在时保存当前资源,逻辑简单明了,符合预期。
269-281
: 新增 saveAs 方法
- 显示保存对话框让用户选择保存位置,体验较好。
- 在 Windows 下应注意非法路径字符,提高可用性和健壮性。
282-282
: 方法结束行
实现已完成,没有其他明显问题。
packages/editor/src/common/mocks/workbench-editor.service.ts (2)
34-36
: 添加 mock save 方法
此方法抛出未实现错误,如需单测覆盖可适当模拟保存行为。
38-40
: 添加 mock saveAs 方法
抛出未实现错误,用于在测试场景中模拟不同保存路径交互。
packages/overlay/src/common/index.ts (1)
95-95
: showSaveDialog 方法签名更新
增加可选 saveAs
字段,暂未发现与现有功能冲突,可增强对不同保存需求的适配。
packages/extension/src/browser/vscode/api/main.thread.workspace.ts (1)
140-148
: 新增 $saveAs 方法
与 editorService.saveAs(uri)
逻辑契合,异常处理方式一致且清晰。
packages/extension/src/common/vscode/workspace.ts (1)
14-15
: 新增方法的接口定义看起来合理
这两个方法 $save
与 $saveAs
在接口层面上符合保存逻辑的需求,能够为后续的具体实现提供清晰的契约。请在对应的实现中做好异常处理,防止未捕获错误导致线程异常退出。
packages/extension/src/hosted/api/vscode/ext.host.workspace.ts (3)
130-131
: 在 createWorkspaceApiFactory 中注入新方法
通过将 save
与 saveAs
暴露到 workspace
,可为外部插件提供统一的保存 API,增强扩展性。实现思路简单明了,可继续保持。
424-427
: ExtHostWorkspace 的 save
方法
此处 save(uri: URI)
向主线程代理调用 $save
,符合主从线程分离的架构。建议在后续实现时加入失败重试或错误提示,以提升用户体验。
428-431
: ExtHostWorkspace 的 saveAs
方法
与 save
方法一致,saveAs
同样通过代理调用 $saveAs
,在远程过程调用模型下逻辑清晰。请注意在调用时做好文件存储位置的验证和错误捕获。
packages/types/vscode/typings/vscode.workspace.d.ts (2)
407-416
: 新增 workspace.save(uri: Uri)
API
此方法允许通过给定的 Uri
保存对应的已打开编辑器,并返回保存后的资源路径或 undefined
。从接口设计看,功能完备度良好,但请确认所有调用端已做好相应的异常处理和空返回情况的兼容。当无法找到对应的编辑器或保存失败时,返回 undefined
合理但需注意使用方的容错逻辑。
418-429
: 新增 workspace.saveAs(uri: Uri)
API
此方法增加了“另存为”逻辑,同样返回 Uri | undefined
。建议在未来完善错误处理或用户取消操作时更明确地标识取消原因,以便调用方进行区分和处理。此外,请在相关的交互或 UI 上通知用户保存目标位置可能发生的异常状态。整体功能拓展性较好。
Codecov ReportAttention: Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## main #4277 +/- ##
==========================================
+ Coverage 53.72% 54.24% +0.51%
==========================================
Files 1622 1633 +11
Lines 98562 99804 +1242
Branches 20142 21660 +1518
==========================================
+ Hits 52951 54135 +1184
- Misses 37906 37944 +38
- Partials 7705 7725 +20
Flags with carried forward coverage won't be shown. Click here to find out more. ☔ View full report in Codecov by Sentry. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 3
🧹 Nitpick comments (1)
packages/editor/src/browser/workbench-editor.service.ts (1)
263-267
: save 方法实现可以增强当前实现过于简单,建议增加错误处理和状态检查。
建议按如下方式改进:
async save() { + if (!this._currentEditorGroup) { + return; + } + + try { await this._currentEditorGroup.saveCurrent(); + } catch (error) { + throw new Error(`保存失败: ${error.message}`); + } }
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (3)
packages/editor/src/browser/workbench-editor.service.ts
(4 hunks)packages/editor/src/common/editor.ts
(1 hunks)packages/file-tree-next/src/browser/dialog/file-dialog.service.ts
(3 hunks)
🔇 Additional comments (1)
packages/editor/src/common/editor.ts (1)
552-555
: 新增的抽象方法设计合理
这两个抽象方法的签名设计清晰且符合预期:
- save 方法返回 void Promise,符合保存操作的语义
- saveAs 方法接收 URI 参数并返回可选的新 URI,满足另存为的使用场景
packages/file-tree-next/src/browser/dialog/file-dialog.service.ts
Outdated
Show resolved
Hide resolved
packages/file-tree-next/src/browser/dialog/file-dialog.service.ts
Outdated
Show resolved
Hide resolved
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 1
🧹 Nitpick comments (1)
packages/editor/src/browser/workbench-editor.service.ts (1)
276-299
: saveAs 方法实现可以优化建议进行以下改进:
- 使用 localize 函数对错误消息和对话框标题进行国际化
- 添加类型注释提高代码可读性
private getDefaultSavePath(uri: URI): string { const defaultPath = uri.path.toString() !== '/' ? path.dirname(uri.path.toString()) : this.appConfig.workspaceDir; return isWindows ? defaultPath.replace(/\\/g, '/') : defaultPath; } async saveAs(uri: URI): Promise<URI | undefined> { if (!this._currentEditorGroup || !uri) { return undefined; } try { const defaultPath = this.getDefaultSavePath(uri); const result = await this.windowDialogService.showSaveDialog({ - saveLabel: 'SaveAs File:', + saveLabel: localize('saveAs.dialog.title', 'SaveAs File:'), showNameInput: true, defaultFileName: this._currentEditorGroup.currentResource?.name, defaultUri: URI.file(defaultPath), saveAs: true, }); return result; } catch (error) { - throw new Error(`SaveAs Failed: ${error.message}`); + throw new Error(localize('saveAs.error.failed', 'SaveAs Failed: {0}', error.message)); } }
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (3)
packages/editor/src/browser/workbench-editor.service.ts
(4 hunks)packages/editor/src/common/editor.ts
(1 hunks)packages/extension/src/browser/vscode/api/main.thread.workspace.ts
(1 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
- packages/extension/src/browser/vscode/api/main.thread.workspace.ts
🔇 Additional comments (4)
packages/editor/src/common/editor.ts (2)
552-553
: 方法签名定义正确!
save
方法的签名设计合理,与 VSCode API 保持一致。
554-555
: 方法签名设计合理!
saveAs
方法的签名设计合理:
- 返回类型
Promise<URI | undefined>
符合 VSCode API 规范,可以处理用户取消保存的场景 - 参数类型正确
packages/editor/src/browser/workbench-editor.service.ts (2)
131-133
: 依赖注入设计合理!
fileServiceClient
属性的设计合理:
- 使用
@Autowired
装饰器正确注入依赖 - 使用
protected readonly
修饰符保护访问权限
181-183
: 依赖注入设计合理!
windowDialogService
属性的设计合理:
- 使用
@Autowired
装饰器正确注入对话框服务 - 使用
private readonly
修饰符确保封装性
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 2
♻️ Duplicate comments (2)
packages/editor/src/browser/workbench-editor.service.ts (2)
263-280
: 🛠️ Refactor suggestionsave 方法实现需要改进
当前实现存在以下问题:
- find 回调函数中的 return 语句是多余的
- 缺少错误处理
- 未处理找不到资源的情况
建议按如下方式重构:
async save(uri: URI): Promise<URI | undefined> { + try { if (!this.editorGroups.length || !uri) { return undefined; } for (const editorGroup of this.editorGroups) { - const res = editorGroup.resources.find((resource) => { - if (resource.uri.isEqual(uri)) { - return resource; - } - }); + const res = editorGroup.resources.find((resource) => + resource.uri.isEqual(uri) + ); if (res) { - editorGroup.saveResource(res); + await editorGroup.saveResource(res); + return uri; } } - - return uri; + throw new Error(`找不到要保存的资源: ${uri.toString()}`); + } catch (error) { + throw new Error(`保存失败: ${error.message}`); } }
282-305
: 🛠️ Refactor suggestionsaveAs 方法需要改进路径处理和错误处理
当前实现存在以下问题:
- 路径处理逻辑可以提取为独立函数
- Windows 路径处理可以优化
- 错误处理可以增强
建议按如下方式重构:
private getDefaultSavePath(uri: URI): string { const defaultPath = uri.path.toString() !== '/' ? path.dirname(uri.path.toString()) : this.appConfig.workspaceDir; - return isWindows ? defaultPath.replace(/\\/g, '/') : defaultPath; + return isWindows ? defaultPath.replaceAll('\\', '/') : defaultPath; } async saveAs(uri: URI): Promise<URI | undefined> { + if (!this._currentEditorGroup) { + return undefined; + } + + if (!uri) { + throw new Error('URI is required'); + } + try { - if (!this._currentEditorGroup || !uri) { - return undefined; - } - const defaultPath = this.getDefaultSavePath(uri); const result = await this.windowDialogService.showSaveDialog({ saveLabel: 'SaveAs File:', showNameInput: true, defaultFileName: this._currentEditorGroup.currentResource?.name, defaultUri: URI.file(defaultPath), saveAs: true, }); return result; } catch (error) { - throw new Error(`SaveAs Failed: ${error.message}`); + const errorMessage = `另存为失败: ${error.message}`; + this.logger.error(errorMessage); + throw new Error(errorMessage); } }
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (4)
packages/editor/src/browser/workbench-editor.service.ts
(4 hunks)packages/editor/src/common/editor.ts
(1 hunks)packages/editor/src/common/mocks/workbench-editor.service.ts
(1 hunks)packages/extension/src/browser/vscode/api/main.thread.workspace.ts
(1 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
- packages/editor/src/common/mocks/workbench-editor.service.ts
🔇 Additional comments (1)
packages/editor/src/common/editor.ts (1)
552-555
: 接口定义正确且类型完整
新增的 save 和 saveAs 抽象方法定义清晰,返回类型合理。
packages/extension/src/browser/vscode/api/main.thread.workspace.ts
Outdated
Show resolved
Hide resolved
packages/extension/src/browser/vscode/api/main.thread.workspace.ts
Outdated
Show resolved
Hide resolved
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 0
🧹 Nitpick comments (1)
packages/editor/src/browser/workbench-editor.service.ts (1)
282-285
: 需要改进路径处理方法当前实现存在以下问题:
- 缺少对 uri 的空值检查
- Windows 路径处理可以优化
- 缺少对工作区目录的空值检查
建议按如下方式重构:
private getDefaultSavePath(uri: URI): string { + if (!uri) { + throw new Error('URI 不能为空'); + } + + if (!this.appConfig.workspaceDir) { + throw new Error('工作区目录未设置'); + } + const defaultPath = uri.path.toString() !== '/' ? path.dirname(uri.path.toString()) : this.appConfig.workspaceDir; - return isWindows ? defaultPath.replace(/\\/g, '/') : defaultPath; + return isWindows ? defaultPath.replaceAll('\\', '/') : defaultPath; }
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (2)
packages/editor/src/browser/workbench-editor.service.ts
(4 hunks)packages/extension/src/browser/vscode/api/main.thread.workspace.ts
(1 hunks)
🔇 Additional comments (4)
packages/extension/src/browser/vscode/api/main.thread.workspace.ts (2)
144-155
: 🛠️ Refactor suggestion
需要改进错误处理和空值检查
当前实现存在以下问题:
- URI 为空时直接返回 undefined,应该抛出错误
- 错误处理可以更详细
- 缺少对 windowDialogService 的空值检查
建议按如下方式重构:
async $saveAs(uri: URI): Promise<URI | undefined> {
if (!this._currentEditorGroup) {
return undefined;
}
+ if (!uri) {
+ throw new Error('URI 不能为空');
+ }
+
+ if (!this.windowDialogService) {
+ throw new Error('windowDialogService 未初始化');
+ }
try {
return await this.windowDialogService.showSaveDialog({
saveLabel: 'SaveAs File:',
showNameInput: true,
defaultFileName: this._currentEditorGroup.currentResource?.name,
defaultUri: URI.file(defaultPath),
saveAs: true,
});
} catch (error) {
- this.logger.error(`SaveAs Failed: ${error.message}`);
- return undefined;
+ const errorMessage = `另存为失败: ${error.message}`;
+ this.logger.error(errorMessage);
+ throw new Error(errorMessage);
}
}
Likely invalid or redundant comment.
130-142
: 🛠️ Refactor suggestion
需要改进错误处理和返回值逻辑
当前实现存在以下问题:
- 在找不到资源时直接返回 undefined,应该抛出错误
- 错误处理过于简单,应该区分不同类型的错误
- 成功保存后应该返回原始 URI
建议按如下方式重构:
async $save(uri: URI): Promise<URI | undefined> {
if (!this.editorGroups.length) {
return undefined;
}
try {
for (const editorGroup of this.editorGroups) {
const res = editorGroup.resources.find((resource) => resource.uri.isEqual(uri));
if (res) {
await editorGroup.saveResource(res);
+ return uri;
}
}
- return uri;
+ throw new Error(`找不到要保存的资源: ${uri.toString()}`);
} catch (error) {
- this.logger.error(`Save Failed: ${error.message}`);
- return undefined;
+ this.logger.error(`保存失败: ${error.message}`);
+ throw error;
}
}
Likely invalid or redundant comment.
packages/editor/src/browser/workbench-editor.service.ts (2)
263-280
: 🛠️ Refactor suggestion
需要改进 save 方法的实现
当前实现存在以下问题:
- 找不到资源时应该抛出错误
- 错误处理过于简单
- 保存成功后应该返回原始 URI
建议按如下方式重构:
async save(uri: URI): Promise<URI | undefined> {
if (!this.editorGroups.length) {
return undefined;
}
try {
+ let found = false;
for (const editorGroup of this.editorGroups) {
const res = editorGroup.resources.find((resource) => resource.uri.isEqual(uri));
if (res) {
+ found = true;
await editorGroup.saveResource(res);
}
}
+ if (!found) {
+ throw new Error(`找不到要保存的资源: ${uri.toString()}`);
+ }
return uri;
} catch (error) {
- throw new Error(`Save Failed: ${error.message}`);
+ const errorMessage = `保存失败: ${error.message}`;
+ this.logger.error(errorMessage);
+ throw new Error(errorMessage);
}
}
Likely invalid or redundant comment.
287-305
: 🛠️ Refactor suggestion
需要改进 saveAs 方法的实现
当前实现存在以下问题:
- 缺少对 windowDialogService 的空值检查
- 错误处理可以更详细
- 保存对话框的标签应该国际化
建议按如下方式重构:
async saveAs(uri: URI): Promise<URI | undefined> {
if (!this._currentEditorGroup) {
return undefined;
}
+ if (!this.windowDialogService) {
+ throw new Error('windowDialogService 未初始化');
+ }
try {
const defaultPath = this.getDefaultSavePath(uri);
const result = await this.windowDialogService.showSaveDialog({
- saveLabel: 'SaveAs File:',
+ saveLabel: localize('saveAs.dialog.label', '另存为文件:'),
showNameInput: true,
defaultFileName: this._currentEditorGroup.currentResource?.name,
defaultUri: URI.file(defaultPath),
saveAs: true,
});
return result;
} catch (error) {
- throw new Error(`SaveAs Failed: ${error.message}`);
+ const errorMessage = `另存为失败: ${error.message}`;
+ this.logger.error(errorMessage);
+ throw new Error(errorMessage);
}
}
Likely invalid or redundant comment.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 0
🧹 Nitpick comments (2)
packages/file-tree-next/src/browser/dialog/file-dialog.service.ts (2)
145-164
: 建议对 saveAs 方法进行以下改进
- 建议添加对文件路径合法性的验证
- 建议在打开文件失败时提供更友好的错误提示
- 建议考虑添加进度提示
建议按如下方式优化:
async saveAs(options: { oldFilePath: string; newFilePath: string }) { const { oldFilePath, newFilePath } = options; if (!oldFilePath || !newFilePath) { throw new Error('oldFilePath and newFilePath are required'); } + + // 验证文件路径合法性 + if (!URI.isUri(oldFilePath) || !URI.isUri(newFilePath)) { + throw new Error('无效的文件路径'); + } + + // 显示进度提示 + await this.dialogService.showProgress({ + title: '正在保存文件...', + task: async () => { await this.createFile(options); try { const openUri: URI = URI.file(options.newFilePath); const EDITOR_OPTIONS = { preview: false, focus: true, replace: true, forceClose: true, }; await this.workbenchEditorService.open(openUri, EDITOR_OPTIONS); this.fileTreeModelService.handleTreeFocus(); } catch (error) { - throw new Error(`Failed to open saveAs file: ${error.message}`); + throw new Error(`打开文件失败:${error.message}`); } + }}); }
166-185
: 建议对 createFile 方法进行以下改进
- 建议添加文件大小检查
- 建议添加文件权限检查
- 建议优化错误处理
建议按如下方式优化:
async createFile(options: { oldFilePath: string; newFilePath: string }) { try { const { oldFilePath, newFilePath } = options; let fileStat = await this.fileServiceClient.getFileStat(oldFilePath); if (!fileStat) { - throw new Error(`Source file not found: ${oldFilePath}`); + throw new Error(`源文件不存在:${oldFilePath}`); } + // 检查文件大小 + const MAX_FILE_SIZE = 50 * 1024 * 1024; // 50MB + if (fileStat.size > MAX_FILE_SIZE) { + throw new Error('文件过大,无法复制'); + } + + // 检查目标路径权限 + try { + await this.fileServiceClient.access(URI.parse(newFilePath).parent.toString(), 2); + } catch (e) { + throw new Error('没有写入权限'); + } const { content } = await this.fileServiceClient.readFile(oldFilePath); await this.fileServiceClient.createFile(newFilePath, { content: content.toString(), encoding: 'utf8', overwrite: true, }); } catch (e) { - throw new Error(`Failed to create file: ${e.message}`); + throw new Error(`创建文件失败:${e.message}`); } }
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (2)
packages/extension/__tests__/browser/extension-service/extension-service-mock-helper.ts
(1 hunks)packages/file-tree-next/src/browser/dialog/file-dialog.service.ts
(3 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
- packages/extension/tests/browser/extension-service/extension-service-mock-helper.ts
🔇 Additional comments (2)
packages/file-tree-next/src/browser/dialog/file-dialog.service.ts (2)
5-7
: 导入声明看起来没有问题!
新增的导入都被正确使用,并且放置在适当的位置。
30-40
: 依赖注入声明正确!
所有新增的依赖都使用了正确的访问修饰符和类型声明。
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 0
🧹 Nitpick comments (2)
packages/editor/src/browser/workbench-editor.service.ts (2)
263-280
: save 方法实现完善!实现包含以下亮点:
- 空值检查防止无编辑器组时的错误
- 完善的错误处理
- 正确的资源保存逻辑
建议优化:
- 可以考虑添加保存成功的日志记录
287-305
: saveAs 方法实现完善!实现包含以下亮点:
- 完善的参数验证
- 使用 try-catch 进行错误处理
- 对话框选项配置合理
建议优化:
- 可以考虑将对话框标签文本提取为常量或使用国际化
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (2)
packages/editor/src/browser/workbench-editor.service.ts
(4 hunks)packages/file-tree-next/src/browser/dialog/file-dialog.service.ts
(3 hunks)
🔇 Additional comments (7)
packages/file-tree-next/src/browser/dialog/file-dialog.service.ts (4)
5-7
: 导入声明看起来不错!
新增的导入声明与新功能的需求相符,包括:
- WorkbenchEditorService: 用于编辑器操作
- IFileServiceClient: 用于文件操作
- IDialogService: 用于对话框操作
31-44
: 依赖注入的属性声明合理!
新增的服务依赖包括:
- fileServiceClient: 用于文件操作
- workbenchEditorService: 用于编辑器操作
- dialogService: 用于对话框操作
- fileTreeModelService: 用于文件树模型操作
- fileTreeService: 用于文件树操作
访问修饰符的使用恰当,protected/private 的选择符合封装原则。
149-173
: saveAs 方法实现完善!
实现包含以下亮点:
- 完善的参数验证
- 使用 try-catch 进行错误处理
- 编辑器选项通过常量 EDITOR_OPTIONS 统一管理
- 包含文件装饰和导航功能
175-194
: createFile 方法实现合理!
实现包含以下亮点:
- 完善的错误处理
- 正确的文件操作顺序:
- 先检查源文件是否存在
- 再读取源文件内容
- 最后创建新文件
packages/editor/src/browser/workbench-editor.service.ts (3)
47-51
: 导入声明合理!
新增的导入包括:
- isWindows: 用于跨平台路径处理
- path: 用于路径操作
这些工具函数的导入对于实现跨平台的文件路径处理是必要的。
131-133
: 依赖注入的属性声明看起来不错!
新增的服务依赖:
- fileServiceClient: 用于文件操作
- windowDialogService: 用于窗口对话框操作
访问修饰符的使用恰当,protected/readonly 的选择有助于确保属性的不可变性。
Also applies to: 181-183
282-285
: getDefaultSavePath 方法实现合理!
实现包含以下亮点:
- 正确处理根路径和非根路径的情况
- 使用 replace 处理 Windows 路径分隔符
- 使用工作区目录作为默认路径
Types
Background or solution
Changelog
Summary by CodeRabbit
新功能
save
和saveAs
方法,允许用户保存当前编辑器状态或指定新文件名。文档
修复
2024-12-27.17.04.01.mov