提交 41150cfa 编写于 作者: B Benjamin Pasero

Files: unable to "Save as.." with same name, different case (fix #98864)

上级 06524e63
...@@ -163,8 +163,14 @@ export interface IEditorControl extends ICompositeControl { } ...@@ -163,8 +163,14 @@ export interface IEditorControl extends ICompositeControl { }
export interface IFileEditorInputFactory { export interface IFileEditorInputFactory {
/**
* Creates new new editor input capable of showing files.
*/
createFileEditorInput(resource: URI, encoding: string | undefined, mode: string | undefined, instantiationService: IInstantiationService): IFileEditorInput; createFileEditorInput(resource: URI, encoding: string | undefined, mode: string | undefined, instantiationService: IInstantiationService): IFileEditorInput;
/**
* Check if the provided object is a file editor input.
*/
isFileEditorInput(obj: unknown): obj is IFileEditorInput; isFileEditorInput(obj: unknown): obj is IFileEditorInput;
} }
......
...@@ -58,6 +58,8 @@ import { TestTextResourcePropertiesService, TestContextService, TestWorkingCopyS ...@@ -58,6 +58,8 @@ import { TestTextResourcePropertiesService, TestContextService, TestWorkingCopyS
import { IThemeService } from 'vs/platform/theme/common/themeService'; import { IThemeService } from 'vs/platform/theme/common/themeService';
import { TestThemeService } from 'vs/platform/theme/test/common/testThemeService'; import { TestThemeService } from 'vs/platform/theme/test/common/testThemeService';
import { IPathService } from 'vs/workbench/services/path/common/pathService'; import { IPathService } from 'vs/workbench/services/path/common/pathService';
import { IUriIdentityService } from 'vs/workbench/services/uriIdentity/common/uriIdentity';
import { UriIdentityService } from 'vs/workbench/services/uriIdentity/common/uriIdentityService';
class TestEnvironmentService extends NativeWorkbenchEnvironmentService { class TestEnvironmentService extends NativeWorkbenchEnvironmentService {
...@@ -117,6 +119,7 @@ suite('KeybindingsEditing', () => { ...@@ -117,6 +119,7 @@ suite('KeybindingsEditing', () => {
fileService.registerProvider(Schemas.file, diskFileSystemProvider); fileService.registerProvider(Schemas.file, diskFileSystemProvider);
fileService.registerProvider(Schemas.userData, new FileUserDataProvider(environmentService.appSettingsHome, environmentService.backupHome, diskFileSystemProvider, environmentService, new NullLogService())); fileService.registerProvider(Schemas.userData, new FileUserDataProvider(environmentService.appSettingsHome, environmentService.backupHome, diskFileSystemProvider, environmentService, new NullLogService()));
instantiationService.stub(IFileService, fileService); instantiationService.stub(IFileService, fileService);
instantiationService.stub(IUriIdentityService, new UriIdentityService(fileService));
instantiationService.stub(IWorkingCopyService, new TestWorkingCopyService()); instantiationService.stub(IWorkingCopyService, new TestWorkingCopyService());
instantiationService.stub(IWorkingCopyFileService, instantiationService.createInstance(WorkingCopyFileService)); instantiationService.stub(IWorkingCopyFileService, instantiationService.createInstance(WorkingCopyFileService));
instantiationService.stub(ITextFileService, instantiationService.createInstance(TestTextFileService)); instantiationService.stub(ITextFileService, instantiationService.createInstance(TestTextFileService));
......
...@@ -34,6 +34,7 @@ import { suggestFilename } from 'vs/base/common/mime'; ...@@ -34,6 +34,7 @@ import { suggestFilename } from 'vs/base/common/mime';
import { IPathService } from 'vs/workbench/services/path/common/pathService'; import { IPathService } from 'vs/workbench/services/path/common/pathService';
import { isValidBasename } from 'vs/base/common/extpath'; import { isValidBasename } from 'vs/base/common/extpath';
import { IWorkingCopyFileService } from 'vs/workbench/services/workingCopy/common/workingCopyFileService'; import { IWorkingCopyFileService } from 'vs/workbench/services/workingCopy/common/workingCopyFileService';
import { IUriIdentityService } from 'vs/workbench/services/uriIdentity/common/uriIdentity';
/** /**
* The workbench file service implementation implements the raw file service spec and adds additional methods on top. * The workbench file service implementation implements the raw file service spec and adds additional methods on top.
...@@ -69,7 +70,8 @@ export abstract class AbstractTextFileService extends Disposable implements ITex ...@@ -69,7 +70,8 @@ export abstract class AbstractTextFileService extends Disposable implements ITex
@ITextModelService private readonly textModelService: ITextModelService, @ITextModelService private readonly textModelService: ITextModelService,
@ICodeEditorService private readonly codeEditorService: ICodeEditorService, @ICodeEditorService private readonly codeEditorService: ICodeEditorService,
@IPathService private readonly pathService: IPathService, @IPathService private readonly pathService: IPathService,
@IWorkingCopyFileService private readonly workingCopyFileService: IWorkingCopyFileService @IWorkingCopyFileService private readonly workingCopyFileService: IWorkingCopyFileService,
@IUriIdentityService private readonly uriIdentitiyService: IUriIdentityService
) { ) {
super(); super();
...@@ -226,6 +228,15 @@ export abstract class AbstractTextFileService extends Disposable implements ITex ...@@ -226,6 +228,15 @@ export abstract class AbstractTextFileService extends Disposable implements ITex
return this.save(source, options); return this.save(source, options);
} }
// If the target is different but of same identity, we
// move the source to the target, knowing that the
// underlying file system cannot have both and then save.
if (this.fileService.canHandleResource(source) && this.uriIdentitiyService.extUri.isEqual(source, target)) {
await this.workingCopyFileService.move(source, target);
return this.save(target, options);
}
// Do it // Do it
return this.doSaveAs(source, target, options); return this.doSaveAs(source, target, options);
} }
......
...@@ -40,6 +40,7 @@ import { IPathService } from 'vs/workbench/services/path/common/pathService'; ...@@ -40,6 +40,7 @@ import { IPathService } from 'vs/workbench/services/path/common/pathService';
import { IWorkingCopyFileService } from 'vs/workbench/services/workingCopy/common/workingCopyFileService'; import { IWorkingCopyFileService } from 'vs/workbench/services/workingCopy/common/workingCopyFileService';
import { INativeWorkbenchEnvironmentService } from 'vs/workbench/services/environment/electron-browser/environmentService'; import { INativeWorkbenchEnvironmentService } from 'vs/workbench/services/environment/electron-browser/environmentService';
import { ILogService } from 'vs/platform/log/common/log'; import { ILogService } from 'vs/platform/log/common/log';
import { IUriIdentityService } from 'vs/workbench/services/uriIdentity/common/uriIdentity';
export class NativeTextFileService extends AbstractTextFileService { export class NativeTextFileService extends AbstractTextFileService {
...@@ -59,9 +60,10 @@ export class NativeTextFileService extends AbstractTextFileService { ...@@ -59,9 +60,10 @@ export class NativeTextFileService extends AbstractTextFileService {
@ICodeEditorService codeEditorService: ICodeEditorService, @ICodeEditorService codeEditorService: ICodeEditorService,
@IPathService pathService: IPathService, @IPathService pathService: IPathService,
@IWorkingCopyFileService workingCopyFileService: IWorkingCopyFileService, @IWorkingCopyFileService workingCopyFileService: IWorkingCopyFileService,
@ILogService private readonly logService: ILogService @ILogService private readonly logService: ILogService,
@IUriIdentityService uriIdentitiyService: IUriIdentityService
) { ) {
super(fileService, untitledTextEditorService, lifecycleService, instantiationService, modelService, environmentService, dialogService, fileDialogService, textResourceConfigurationService, filesConfigurationService, textModelService, codeEditorService, pathService, workingCopyFileService); super(fileService, untitledTextEditorService, lifecycleService, instantiationService, modelService, environmentService, dialogService, fileDialogService, textResourceConfigurationService, filesConfigurationService, textModelService, codeEditorService, pathService, workingCopyFileService, uriIdentitiyService);
} }
private _encoding: EncodingOracle | undefined; private _encoding: EncodingOracle | undefined;
......
...@@ -223,7 +223,8 @@ export class TestTextFileService extends BrowserTextFileService { ...@@ -223,7 +223,8 @@ export class TestTextFileService extends BrowserTextFileService {
@ITextModelService textModelService: ITextModelService, @ITextModelService textModelService: ITextModelService,
@ICodeEditorService codeEditorService: ICodeEditorService, @ICodeEditorService codeEditorService: ICodeEditorService,
@IPathService pathService: IPathService, @IPathService pathService: IPathService,
@IWorkingCopyFileService workingCopyFileService: IWorkingCopyFileService @IWorkingCopyFileService workingCopyFileService: IWorkingCopyFileService,
@IUriIdentityService uriIdentitiyService: IUriIdentityService
) { ) {
super( super(
fileService, fileService,
...@@ -239,7 +240,8 @@ export class TestTextFileService extends BrowserTextFileService { ...@@ -239,7 +240,8 @@ export class TestTextFileService extends BrowserTextFileService {
textModelService, textModelService,
codeEditorService, codeEditorService,
pathService, pathService,
workingCopyFileService workingCopyFileService,
uriIdentitiyService
); );
} }
......
...@@ -38,6 +38,7 @@ import { IWorkingCopyService } from 'vs/workbench/services/workingCopy/common/wo ...@@ -38,6 +38,7 @@ import { IWorkingCopyService } from 'vs/workbench/services/workingCopy/common/wo
import { IEditorService } from 'vs/workbench/services/editor/common/editorService'; import { IEditorService } from 'vs/workbench/services/editor/common/editorService';
import { INativeWindowConfiguration } from 'vs/platform/windows/node/window'; import { INativeWindowConfiguration } from 'vs/platform/windows/node/window';
import { TestContextService } from 'vs/workbench/test/common/workbenchTestServices'; import { TestContextService } from 'vs/workbench/test/common/workbenchTestServices';
import { IUriIdentityService } from 'vs/workbench/services/uriIdentity/common/uriIdentity';
export const TestWindowConfiguration: INativeWindowConfiguration = { export const TestWindowConfiguration: INativeWindowConfiguration = {
windowId: 0, windowId: 0,
...@@ -74,7 +75,8 @@ export class TestTextFileService extends NativeTextFileService { ...@@ -74,7 +75,8 @@ export class TestTextFileService extends NativeTextFileService {
@ICodeEditorService codeEditorService: ICodeEditorService, @ICodeEditorService codeEditorService: ICodeEditorService,
@IPathService athService: IPathService, @IPathService athService: IPathService,
@IWorkingCopyFileService workingCopyFileService: IWorkingCopyFileService, @IWorkingCopyFileService workingCopyFileService: IWorkingCopyFileService,
@ILogService logService: ILogService @ILogService logService: ILogService,
@IUriIdentityService uriIdentitiyService: IUriIdentityService
) { ) {
super( super(
fileService, fileService,
...@@ -92,7 +94,8 @@ export class TestTextFileService extends NativeTextFileService { ...@@ -92,7 +94,8 @@ export class TestTextFileService extends NativeTextFileService {
codeEditorService, codeEditorService,
athService, athService,
workingCopyFileService, workingCopyFileService,
logService logService,
uriIdentitiyService
); );
} }
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册