Skip to content

Commit 007d686

Browse files
author
Benjamin Pasero
committed
workspaces - allow to same on same path
1 parent 5ee0133 commit 007d686

1 file changed

Lines changed: 36 additions & 7 deletions

File tree

src/vs/workbench/services/workspaces/browser/abstractWorkspaceEditingService.ts

Lines changed: 36 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -8,13 +8,13 @@ import { URI } from 'vs/base/common/uri';
88
import * as nls from 'vs/nls';
99
import { IWorkspaceContextService, WorkbenchState } from 'vs/platform/workspace/common/workspace';
1010
import { IJSONEditingService, JSONEditingError, JSONEditingErrorCode } from 'vs/workbench/services/configuration/common/jsonEditing';
11-
import { IWorkspaceIdentifier, IWorkspaceFolderCreationData, IWorkspacesService, rewriteWorkspaceFileForNewLocation, WORKSPACE_FILTER, IEnterWorkspaceResult, hasWorkspaceFileExtension, WORKSPACE_EXTENSION, isUntitledWorkspace } from 'vs/platform/workspaces/common/workspaces';
11+
import { IWorkspaceIdentifier, IWorkspaceFolderCreationData, IWorkspacesService, rewriteWorkspaceFileForNewLocation, WORKSPACE_FILTER, IEnterWorkspaceResult, hasWorkspaceFileExtension, WORKSPACE_EXTENSION, isUntitledWorkspace, IStoredWorkspace } from 'vs/platform/workspaces/common/workspaces';
1212
import { WorkspaceService } from 'vs/workbench/services/configuration/browser/configurationService';
1313
import { ConfigurationScope, IConfigurationRegistry, Extensions as ConfigurationExtensions, IConfigurationPropertySchema } from 'vs/platform/configuration/common/configurationRegistry';
1414
import { Registry } from 'vs/platform/registry/common/platform';
1515
import { ICommandService } from 'vs/platform/commands/common/commands';
1616
import { distinct } from 'vs/base/common/arrays';
17-
import { isEqual, getComparisonKey, isEqualAuthority } from 'vs/base/common/resources';
17+
import { isEqual, getComparisonKey, isEqualAuthority, extUri } from 'vs/base/common/resources';
1818
import { INotificationService, Severity } from 'vs/platform/notification/common/notification';
1919
import { IFileService } from 'vs/platform/files/common/files';
2020
import { IWorkbenchEnvironmentService } from 'vs/workbench/services/environment/common/environmentService';
@@ -24,14 +24,15 @@ import { IConfigurationService } from 'vs/platform/configuration/common/configur
2424
import { ITextFileService } from 'vs/workbench/services/textfile/common/textfiles';
2525
import { IHostService } from 'vs/workbench/services/host/browser/host';
2626
import { Schemas } from 'vs/base/common/network';
27+
import { SaveReason } from 'vs/workbench/common/editor';
2728

2829
export abstract class AbstractWorkspaceEditingService implements IWorkspaceEditingService {
2930

3031
declare readonly _serviceBrand: undefined;
3132

3233
constructor(
3334
@IJSONEditingService private readonly jsonEditingService: IJSONEditingService,
34-
@IWorkspaceContextService private readonly contextService: WorkspaceService,
35+
@IWorkspaceContextService protected readonly contextService: WorkspaceService,
3536
@IConfigurationService private readonly configurationService: IConfigurationService,
3637
@INotificationService private readonly notificationService: INotificationService,
3738
@ICommandService private readonly commandService: ICommandService,
@@ -206,12 +207,18 @@ export abstract class AbstractWorkspaceEditingService implements IWorkspaceEditi
206207
}
207208

208209
async saveAndEnterWorkspace(path: URI): Promise<void> {
209-
if (!await this.isValidTargetWorkspacePath(path)) {
210+
const workspaceIdentifier = this.getCurrentWorkspaceIdentifier();
211+
if (!workspaceIdentifier) {
210212
return;
211213
}
212214

213-
const workspaceIdentifier = this.getCurrentWorkspaceIdentifier();
214-
if (!workspaceIdentifier) {
215+
// Allow to save the workspace of the current window
216+
if (extUri.isEqual(workspaceIdentifier.configPath, path)) {
217+
return this.saveWorkspace(workspaceIdentifier);
218+
}
219+
220+
// From this moment on we require a valid target that is not opened already
221+
if (!await this.isValidTargetWorkspacePath(path)) {
215222
return;
216223
}
217224

@@ -224,7 +231,7 @@ export abstract class AbstractWorkspaceEditingService implements IWorkspaceEditi
224231
return true; // OK
225232
}
226233

227-
protected async saveWorkspaceAs(workspace: IWorkspaceIdentifier, targetConfigPathURI: URI): Promise<any> {
234+
protected async saveWorkspaceAs(workspace: IWorkspaceIdentifier, targetConfigPathURI: URI): Promise<void> {
228235
const configPathURI = workspace.configPath;
229236

230237
// Return early if target is same as source
@@ -240,6 +247,28 @@ export abstract class AbstractWorkspaceEditingService implements IWorkspaceEditi
240247
await this.textFileService.create(targetConfigPathURI, newRawWorkspaceContents, { overwrite: true });
241248
}
242249

250+
protected async saveWorkspace(workspace: IWorkspaceIdentifier): Promise<void> {
251+
const configPathURI = workspace.configPath;
252+
253+
// First: try to save any existing model as it could be dirty
254+
const existingModel = this.textFileService.files.get(configPathURI);
255+
if (existingModel) {
256+
await existingModel.save({ force: true, reason: SaveReason.EXPLICIT });
257+
return;
258+
}
259+
260+
// Second: if the file exists on disk, simply return
261+
const workspaceFileExists = await this.fileService.exists(configPathURI);
262+
if (workspaceFileExists) {
263+
return;
264+
}
265+
266+
// Finally, we need to re-create the file as it was deleted
267+
const newWorkspace: IStoredWorkspace = { folders: [] };
268+
const newRawWorkspaceContents = rewriteWorkspaceFileForNewLocation(JSON.stringify(newWorkspace, null, '\t'), configPathURI, false, configPathURI);
269+
await this.textFileService.create(configPathURI, newRawWorkspaceContents);
270+
}
271+
243272
private handleWorkspaceConfigurationEditingError(error: JSONEditingError): void {
244273
switch (error.code) {
245274
case JSONEditingErrorCode.ERROR_INVALID_FILE:

0 commit comments

Comments
 (0)