From 9727eb60500657cd2c30e4a3992e17940c2cefba Mon Sep 17 00:00:00 2001 From: Benjamin Pasero Date: Mon, 18 Nov 2019 07:57:48 +0100 Subject: [PATCH] untitled - fix save with associated file path --- .../api/browser/mainThreadSaveParticipant.ts | 2 +- .../workbench/api/common/extHost.protocol.ts | 2 +- .../common/extHostDocumentSaveParticipant.ts | 2 +- .../api/common/extHostTypeConverters.ts | 2 +- .../browser/parts/editor/editorGroupView.ts | 2 +- .../browser/parts/editor/textEditor.ts | 3 +- src/vs/workbench/common/editor.ts | 83 ++++++++++++++++--- .../common/editor/untitledTextEditorInput.ts | 30 +++++-- .../common/editor/untitledTextEditorModel.ts | 4 +- .../customEditor/browser/customEditorInput.ts | 5 +- .../customEditor/common/customEditorModel.ts | 4 +- .../files/common/editors/fileEditorInput.ts | 3 +- .../test/browser/fileEditorInput.test.ts | 2 +- .../preferences/browser/preferencesEditor.ts | 2 +- .../browser/testCustomEditors.ts | 6 +- .../services/editor/browser/editorService.ts | 7 +- .../services/editor/common/editorService.ts | 3 +- .../textfile/browser/textFileService.ts | 2 +- .../textfile/common/textFileEditorModel.ts | 4 +- .../services/textfile/common/textfiles.ts | 4 +- .../workingCopy/common/workingCopyService.ts | 71 ---------------- .../test/common/workingCopyService.test.ts | 5 +- .../extHostDocumentSaveParticipant.test.ts | 2 +- .../api/mainThreadSaveParticipant.test.ts | 2 +- .../workbench/test/workbenchTestServices.ts | 4 +- 25 files changed, 130 insertions(+), 126 deletions(-) diff --git a/src/vs/workbench/api/browser/mainThreadSaveParticipant.ts b/src/vs/workbench/api/browser/mainThreadSaveParticipant.ts index 9d0778cfd0d..023e413f8cc 100644 --- a/src/vs/workbench/api/browser/mainThreadSaveParticipant.ts +++ b/src/vs/workbench/api/browser/mainThreadSaveParticipant.ts @@ -31,7 +31,7 @@ import { IProgressService, ProgressLocation } from 'vs/platform/progress/common/ import { extHostCustomer } from 'vs/workbench/api/common/extHostCustomers'; import { TextFileEditorModel } from 'vs/workbench/services/textfile/common/textFileEditorModel'; import { ISaveParticipant, IResolvedTextFileEditorModel } from 'vs/workbench/services/textfile/common/textfiles'; -import { SaveReason } from 'vs/workbench/services/workingCopy/common/workingCopyService'; +import { SaveReason } from 'vs/workbench/common/editor'; import { ExtHostContext, ExtHostDocumentSaveParticipantShape, IExtHostContext } from '../common/extHost.protocol'; export interface ICodeActionsOnSaveOptions { diff --git a/src/vs/workbench/api/common/extHost.protocol.ts b/src/vs/workbench/api/common/extHost.protocol.ts index 88d442643ff..e3a5c16efd3 100644 --- a/src/vs/workbench/api/common/extHost.protocol.ts +++ b/src/vs/workbench/api/common/extHost.protocol.ts @@ -45,7 +45,7 @@ import { ITerminalDimensions, IShellLaunchConfig } from 'vs/workbench/contrib/te import { ExtensionActivationError } from 'vs/workbench/services/extensions/common/extensions'; import { createExtHostContextProxyIdentifier as createExtId, createMainContextProxyIdentifier as createMainId, IRPCProtocol } from 'vs/workbench/services/extensions/common/proxyIdentifier'; import * as search from 'vs/workbench/services/search/common/search'; -import { SaveReason } from 'vs/workbench/services/workingCopy/common/workingCopyService'; +import { SaveReason } from 'vs/workbench/common/editor'; import { ExtensionActivationReason } from 'vs/workbench/api/common/extHostExtensionActivator'; export interface IEnvironment { diff --git a/src/vs/workbench/api/common/extHostDocumentSaveParticipant.ts b/src/vs/workbench/api/common/extHostDocumentSaveParticipant.ts index 3b1b80c1de4..63f885cc69a 100644 --- a/src/vs/workbench/api/common/extHostDocumentSaveParticipant.ts +++ b/src/vs/workbench/api/common/extHostDocumentSaveParticipant.ts @@ -11,7 +11,7 @@ import { ExtHostDocumentSaveParticipantShape, MainThreadTextEditorsShape, IResou import { TextEdit } from 'vs/workbench/api/common/extHostTypes'; import { Range, TextDocumentSaveReason, EndOfLine } from 'vs/workbench/api/common/extHostTypeConverters'; import { ExtHostDocuments } from 'vs/workbench/api/common/extHostDocuments'; -import { SaveReason } from 'vs/workbench/services/workingCopy/common/workingCopyService'; +import { SaveReason } from 'vs/workbench/common/editor'; import * as vscode from 'vscode'; import { LinkedList } from 'vs/base/common/linkedList'; import { ILogService } from 'vs/platform/log/common/log'; diff --git a/src/vs/workbench/api/common/extHostTypeConverters.ts b/src/vs/workbench/api/common/extHostTypeConverters.ts index 3361a6e5d66..08cfac73625 100644 --- a/src/vs/workbench/api/common/extHostTypeConverters.ts +++ b/src/vs/workbench/api/common/extHostTypeConverters.ts @@ -13,7 +13,7 @@ import { EndOfLineSequence, TrackedRangeStickiness } from 'vs/editor/common/mode import * as vscode from 'vscode'; import { URI, UriComponents } from 'vs/base/common/uri'; import { ProgressLocation as MainProgressLocation } from 'vs/platform/progress/common/progress'; -import { SaveReason } from 'vs/workbench/services/workingCopy/common/workingCopyService'; +import { SaveReason } from 'vs/workbench/common/editor'; import { IPosition } from 'vs/editor/common/core/position'; import * as editorRange from 'vs/editor/common/core/range'; import { ISelection } from 'vs/editor/common/core/selection'; diff --git a/src/vs/workbench/browser/parts/editor/editorGroupView.ts b/src/vs/workbench/browser/parts/editor/editorGroupView.ts index 87fdf2a8415..dc5ce544297 100644 --- a/src/vs/workbench/browser/parts/editor/editorGroupView.ts +++ b/src/vs/workbench/browser/parts/editor/editorGroupView.ts @@ -1310,7 +1310,7 @@ export class EditorGroupView extends Themable implements IEditorGroupView { // Otherwise, handle accordingly switch (res) { case ConfirmResult.SAVE: - const result = await editor.save(); + const result = await editor.save(this._group.id); return !result; case ConfirmResult.DONT_SAVE: diff --git a/src/vs/workbench/browser/parts/editor/textEditor.ts b/src/vs/workbench/browser/parts/editor/textEditor.ts index 8ba1dcd86e2..4dfe5dd897f 100644 --- a/src/vs/workbench/browser/parts/editor/textEditor.ts +++ b/src/vs/workbench/browser/parts/editor/textEditor.ts @@ -9,7 +9,7 @@ import { distinct, deepClone, assign } from 'vs/base/common/objects'; import { isObject, assertIsDefined, withNullAsUndefined } from 'vs/base/common/types'; import { Dimension } from 'vs/base/browser/dom'; import { CodeEditorWidget } from 'vs/editor/browser/widget/codeEditorWidget'; -import { EditorInput, EditorOptions, IEditorMemento, ITextEditor } from 'vs/workbench/common/editor'; +import { EditorInput, EditorOptions, IEditorMemento, ITextEditor, SaveReason } from 'vs/workbench/common/editor'; import { BaseEditor } from 'vs/workbench/browser/parts/editor/baseEditor'; import { IEditorViewState, IEditor } from 'vs/editor/common/editorCommon'; import { IStorageService } from 'vs/platform/storage/common/storage'; @@ -17,7 +17,6 @@ import { IInstantiationService } from 'vs/platform/instantiation/common/instanti import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry'; import { IThemeService } from 'vs/platform/theme/common/themeService'; import { ITextFileService } from 'vs/workbench/services/textfile/common/textfiles'; -import { SaveReason } from 'vs/workbench/services/workingCopy/common/workingCopyService'; import { ITextResourceConfigurationService } from 'vs/editor/common/services/resourceConfiguration'; import { IEditorOptions } from 'vs/editor/common/config/editorOptions'; import { isDiffEditor, isCodeEditor, getCodeEditor } from 'vs/editor/browser/editorBrowser'; diff --git a/src/vs/workbench/common/editor.ts b/src/vs/workbench/common/editor.ts index 938d57f515e..eb91ac79705 100644 --- a/src/vs/workbench/common/editor.ts +++ b/src/vs/workbench/common/editor.ts @@ -20,7 +20,6 @@ import { ActionRunner, IAction } from 'vs/base/common/actions'; import { IFileService } from 'vs/platform/files/common/files'; import { IPathData } from 'vs/platform/windows/common/windows'; import { coalesce, firstOrDefault } from 'vs/base/common/arrays'; -import { ISaveOptions, IRevertOptions } from 'vs/workbench/services/workingCopy/common/workingCopyService'; import { ITextFileSaveOptions, ITextFileService } from 'vs/workbench/services/textfile/common/textfiles'; import { IEditorService } from 'vs/workbench/services/editor/common/editorService'; import { isEqual } from 'vs/base/common/resources'; @@ -277,6 +276,68 @@ export const enum Verbosity { LONG } +export const enum SaveReason { + + /** + * Explicit user gesture. + */ + EXPLICIT = 1, + + /** + * Auto save after a timeout. + */ + AUTO = 2, + + /** + * Auto save after editor focus change. + */ + FOCUS_CHANGE = 3, + + /** + * Auto save after window change. + */ + WINDOW_CHANGE = 4 +} + +export interface ISaveOptions { + + /** + * An indicator how the save operation was triggered. + */ + reason?: SaveReason; + + /** + * Forces to load the contents of the working copy + * again even if the working copy is not dirty. + */ + force?: boolean; + + /** + * Instructs the save operation to skip any save participants. + */ + skipSaveParticipants?: boolean; + + /** + * A hint as to which file systems should be available for saving. + */ + availableFileSystems?: string[]; +} + +export interface IRevertOptions { + + /** + * Forces to load the contents of the working copy + * again even if the working copy is not dirty. + */ + force?: boolean; + + /** + * A soft revert will clear dirty state of a working copy + * but will not attempt to load it from its persisted state. + */ + soft?: boolean; +} + export interface IEditorInput extends IDisposable { /** @@ -330,9 +391,11 @@ export interface IEditorInput extends IDisposable { isDirty(): boolean; /** - * Saves the editor. + * Saves the editor. The provided groupId helps + * implementors to e.g. preserve view state of the editor + * and re-open it in the correct group after saving. */ - save(options?: ISaveOptions): Promise; + save(groupId: GroupIdentifier, options?: ISaveOptions): Promise; /** * Saves the editor to a different location. The provided groupId @@ -464,7 +527,7 @@ export abstract class EditorInput extends Disposable implements IEditorInput { /** * Saves the editor if it is dirty. Subclasses return a promise with a boolean indicating the success of the operation. */ - save(options?: ISaveOptions): Promise { + save(groupId: GroupIdentifier, options?: ISaveOptions): Promise { return Promise.resolve(true); } @@ -530,15 +593,15 @@ export abstract class TextEditorInput extends EditorInput { return this.resource; } - save(options?: ITextFileSaveOptions): Promise { + save(groupId: GroupIdentifier, options?: ITextFileSaveOptions): Promise { return this.textFileService.save(this.resource, options); } saveAs(group: GroupIdentifier, options?: ITextFileSaveOptions): Promise { - return this.doSaveAs(group, options); + return this.doSaveAs(group, () => this.textFileService.saveAs(this.resource, undefined, options)); } - protected async doSaveAs(group: GroupIdentifier, options?: ITextFileSaveOptions, replaceAllEditors?: boolean): Promise { + protected async doSaveAs(group: GroupIdentifier, saveRunnable: () => Promise, replaceAllEditors?: boolean): Promise { // Preserve view state by opening the editor first. In addition // this allows the user to review the contents of the editor. @@ -549,7 +612,7 @@ export abstract class TextEditorInput extends EditorInput { } // Save as - const target = await this.textFileService.saveAs(this.resource, undefined, options); + const target = await saveRunnable(); if (!target) { return false; // save cancelled } @@ -667,8 +730,8 @@ export class SideBySideEditorInput extends EditorInput { return this.master.isDirty(); } - save(options?: ISaveOptions): Promise { - return this.master.save(options); + save(groupId: GroupIdentifier, options?: ISaveOptions): Promise { + return this.master.save(groupId, options); } saveAs(groupId: GroupIdentifier, options?: ISaveOptions): Promise { diff --git a/src/vs/workbench/common/editor/untitledTextEditorInput.ts b/src/vs/workbench/common/editor/untitledTextEditorInput.ts index 9a7d62d909c..8be428a4931 100644 --- a/src/vs/workbench/common/editor/untitledTextEditorInput.ts +++ b/src/vs/workbench/common/editor/untitledTextEditorInput.ts @@ -7,17 +7,17 @@ import { URI } from 'vs/base/common/uri'; import { suggestFilename } from 'vs/base/common/mime'; import { createMemoizer } from 'vs/base/common/decorators'; import { PLAINTEXT_MODE_ID } from 'vs/editor/common/modes/modesRegistry'; -import { basenameOrAuthority, dirname } from 'vs/base/common/resources'; -import { IEncodingSupport, EncodingMode, Verbosity, IModeSupport, TextEditorInput, GroupIdentifier } from 'vs/workbench/common/editor'; +import { basenameOrAuthority, dirname, toLocalResource } from 'vs/base/common/resources'; +import { IEncodingSupport, EncodingMode, Verbosity, IModeSupport, TextEditorInput, GroupIdentifier, IRevertOptions } from 'vs/workbench/common/editor'; import { UntitledTextEditorModel } from 'vs/workbench/common/editor/untitledTextEditorModel'; import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation'; import { Emitter } from 'vs/base/common/event'; import { ITextFileService, ITextFileSaveOptions } from 'vs/workbench/services/textfile/common/textfiles'; import { ILabelService } from 'vs/platform/label/common/label'; import { IResolvedTextEditorModel } from 'vs/editor/common/services/resolverService'; -import { IRevertOptions } from 'vs/workbench/services/workingCopy/common/workingCopyService'; import { IEditorService } from 'vs/workbench/services/editor/common/editorService'; import { IEditorGroupsService } from 'vs/workbench/services/editor/common/editorGroupsService'; +import { IWorkbenchEnvironmentService } from 'vs/workbench/services/environment/common/environmentService'; /** * An editor input to be used for untitled text buffers. @@ -47,7 +47,8 @@ export class UntitledTextEditorInput extends TextEditorInput implements IEncodin @ITextFileService textFileService: ITextFileService, @ILabelService private readonly labelService: ILabelService, @IEditorService editorService: IEditorService, - @IEditorGroupsService editorGroupService: IEditorGroupsService + @IEditorGroupsService editorGroupService: IEditorGroupsService, + @IWorkbenchEnvironmentService private readonly environmentService: IWorkbenchEnvironmentService ) { super(resource, editorService, editorGroupService, textFileService); @@ -161,8 +162,27 @@ export class UntitledTextEditorInput extends TextEditorInput implements IEncodin return false; } + save(group: GroupIdentifier, options?: ITextFileSaveOptions): Promise { + return this.doSaveAs(group, async () => { + + // With associated file path, save to the path that is + // associated. Make sure to convert the result using + // remote authority properly. + if (this.hasAssociatedFilePath) { + if (await this.textFileService.save(this.resource, options)) { + return toLocalResource(this.resource, this.environmentService.configuration.remoteAuthority); + } + + return; + } + + // Without associated file path, do a normal "Save As" + return this.textFileService.saveAs(this.resource, undefined, options); + }, true /* replace editor across all groups */); + } + saveAs(group: GroupIdentifier, options?: ITextFileSaveOptions): Promise { - return this.doSaveAs(group, options, true /* replace editor across all groups */); + return this.doSaveAs(group, () => this.textFileService.saveAs(this.resource, undefined, options), true /* replace editor across all groups */); } revert(options?: IRevertOptions): Promise { diff --git a/src/vs/workbench/common/editor/untitledTextEditorModel.ts b/src/vs/workbench/common/editor/untitledTextEditorModel.ts index 280ad2c1068..ccb30868d92 100644 --- a/src/vs/workbench/common/editor/untitledTextEditorModel.ts +++ b/src/vs/workbench/common/editor/untitledTextEditorModel.ts @@ -3,7 +3,7 @@ * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ -import { IEncodingSupport } from 'vs/workbench/common/editor'; +import { IEncodingSupport, ISaveOptions } from 'vs/workbench/common/editor'; import { BaseTextEditorModel } from 'vs/workbench/common/editor/textEditorModel'; import { URI } from 'vs/base/common/uri'; import { CONTENT_CHANGE_EVENT_BUFFER_DELAY } from 'vs/platform/files/common/files'; @@ -16,7 +16,7 @@ import { ITextResourceConfigurationService } from 'vs/editor/common/services/res import { ITextBufferFactory } from 'vs/editor/common/model'; import { createTextBufferFactory } from 'vs/editor/common/model/textModel'; import { IResolvedTextEditorModel } from 'vs/editor/common/services/resolverService'; -import { IWorkingCopyService, IWorkingCopy, ISaveOptions } from 'vs/workbench/services/workingCopy/common/workingCopyService'; +import { IWorkingCopyService, IWorkingCopy } from 'vs/workbench/services/workingCopy/common/workingCopyService'; import { ITextFileService } from 'vs/workbench/services/textfile/common/textfiles'; export class UntitledTextEditorModel extends BaseTextEditorModel implements IEncodingSupport, IWorkingCopy { diff --git a/src/vs/workbench/contrib/customEditor/browser/customEditorInput.ts b/src/vs/workbench/contrib/customEditor/browser/customEditorInput.ts index 747f33c052c..9a2e4342f70 100644 --- a/src/vs/workbench/contrib/customEditor/browser/customEditorInput.ts +++ b/src/vs/workbench/contrib/customEditor/browser/customEditorInput.ts @@ -12,11 +12,10 @@ import { DataUri, isEqual } from 'vs/base/common/resources'; import { URI } from 'vs/base/common/uri'; import { ILabelService } from 'vs/platform/label/common/label'; import { ILifecycleService } from 'vs/platform/lifecycle/common/lifecycle'; -import { IEditorInput, Verbosity, GroupIdentifier } from 'vs/workbench/common/editor'; +import { IEditorInput, Verbosity, GroupIdentifier, ISaveOptions, IRevertOptions } from 'vs/workbench/common/editor'; import { WebviewEditorOverlay } from 'vs/workbench/contrib/webview/browser/webview'; import { IWebviewWorkbenchService, LazilyResolvedWebviewEditorInput } from 'vs/workbench/contrib/webview/browser/webviewWorkbenchService'; import { CustomEditorModel } from '../common/customEditorModel'; -import { ISaveOptions, IRevertOptions } from 'vs/workbench/services/workingCopy/common/workingCopyService'; export class CustomFileEditorInput extends LazilyResolvedWebviewEditorInput { @@ -125,7 +124,7 @@ export class CustomFileEditorInput extends LazilyResolvedWebviewEditorInput { return this._model ? this._model.isDirty() : false; } - public save(options?: ISaveOptions): Promise { + public save(groupId: GroupIdentifier, options?: ISaveOptions): Promise { return this._model ? this._model.save(options) : Promise.resolve(false); } diff --git a/src/vs/workbench/contrib/customEditor/common/customEditorModel.ts b/src/vs/workbench/contrib/customEditor/common/customEditorModel.ts index 9a34c46ead5..2d1988748da 100644 --- a/src/vs/workbench/contrib/customEditor/common/customEditorModel.ts +++ b/src/vs/workbench/contrib/customEditor/common/customEditorModel.ts @@ -7,8 +7,8 @@ import { Emitter, Event } from 'vs/base/common/event'; import { Disposable } from 'vs/base/common/lifecycle'; import { URI } from 'vs/base/common/uri'; import { ICustomEditorModel, CustomEditorEdit } from 'vs/workbench/contrib/customEditor/common/customEditor'; -import { IRevertOptions, ISaveOptions, WorkingCopyCapabilities } from 'vs/workbench/services/workingCopy/common/workingCopyService'; - +import { WorkingCopyCapabilities } from 'vs/workbench/services/workingCopy/common/workingCopyService'; +import { ISaveOptions, IRevertOptions } from 'vs/workbench/common/editor'; export class CustomEditorModel extends Disposable implements ICustomEditorModel { diff --git a/src/vs/workbench/contrib/files/common/editors/fileEditorInput.ts b/src/vs/workbench/contrib/files/common/editors/fileEditorInput.ts index 83ba201f267..553d195d02c 100644 --- a/src/vs/workbench/contrib/files/common/editors/fileEditorInput.ts +++ b/src/vs/workbench/contrib/files/common/editors/fileEditorInput.ts @@ -7,8 +7,7 @@ import { localize } from 'vs/nls'; import { createMemoizer } from 'vs/base/common/decorators'; import { dirname } from 'vs/base/common/resources'; import { URI } from 'vs/base/common/uri'; -import { EncodingMode, IFileEditorInput, ITextEditorModel, Verbosity, TextEditorInput } from 'vs/workbench/common/editor'; -import { IRevertOptions } from 'vs/workbench/services/workingCopy/common/workingCopyService'; +import { EncodingMode, IFileEditorInput, ITextEditorModel, Verbosity, TextEditorInput, IRevertOptions } from 'vs/workbench/common/editor'; import { TextFileEditorModel } from 'vs/workbench/services/textfile/common/textFileEditorModel'; import { BinaryEditorModel } from 'vs/workbench/common/editor/binaryEditorModel'; import { FileOperationError, FileOperationResult, IFileService, FileSystemProviderCapabilities } from 'vs/platform/files/common/files'; diff --git a/src/vs/workbench/contrib/files/test/browser/fileEditorInput.test.ts b/src/vs/workbench/contrib/files/test/browser/fileEditorInput.test.ts index 674d1f2a1e4..35e56e70a5f 100644 --- a/src/vs/workbench/contrib/files/test/browser/fileEditorInput.test.ts +++ b/src/vs/workbench/contrib/files/test/browser/fileEditorInput.test.ts @@ -141,7 +141,7 @@ suite('Files - FileEditorInput', () => { resolved.textEditorModel!.setValue('changed'); assert.ok(input.isDirty()); - await input.save(); + await input.save(0); assert.ok(!input.isDirty()); resolved.dispose(); }); diff --git a/src/vs/workbench/contrib/preferences/browser/preferencesEditor.ts b/src/vs/workbench/contrib/preferences/browser/preferencesEditor.ts index 144a775d045..77284a59676 100644 --- a/src/vs/workbench/contrib/preferences/browser/preferencesEditor.ts +++ b/src/vs/workbench/contrib/preferences/browser/preferencesEditor.ts @@ -255,7 +255,7 @@ export class PreferencesEditor extends BaseEditor { if (this.editorService.activeControl !== this) { this.focus(); } - const promise: Promise = this.input && this.input.isDirty() ? this.input.save() : Promise.resolve(true); + const promise: Promise = this.input && this.input.isDirty() ? this.input.save(this.group!.id) : Promise.resolve(true); promise.then(() => { if (target === ConfigurationTarget.USER_LOCAL) { this.preferencesService.switchSettings(ConfigurationTarget.USER_LOCAL, this.preferencesService.userSettingsResource, true); diff --git a/src/vs/workbench/contrib/testCustomEditors/browser/testCustomEditors.ts b/src/vs/workbench/contrib/testCustomEditors/browser/testCustomEditors.ts index b3602d62760..661b8412cad 100644 --- a/src/vs/workbench/contrib/testCustomEditors/browser/testCustomEditors.ts +++ b/src/vs/workbench/contrib/testCustomEditors/browser/testCustomEditors.ts @@ -6,7 +6,7 @@ import * as nls from 'vs/nls'; import { Action } from 'vs/base/common/actions'; import { BaseEditor } from 'vs/workbench/browser/parts/editor/baseEditor'; -import { IEditorInputFactory, EditorInput, IEditorInputFactoryRegistry, Extensions as EditorInputExtensions, EditorModel, EditorOptions, GroupIdentifier } from 'vs/workbench/common/editor'; +import { IEditorInputFactory, EditorInput, IEditorInputFactoryRegistry, Extensions as EditorInputExtensions, EditorModel, EditorOptions, GroupIdentifier, ISaveOptions, IRevertOptions } from 'vs/workbench/common/editor'; import { IEditorService } from 'vs/workbench/services/editor/common/editorService'; import { IEditorModel } from 'vs/platform/editor/common/editor'; import { Dimension, addDisposableListener, EventType } from 'vs/base/browser/dom'; @@ -24,7 +24,7 @@ import { isEqual } from 'vs/base/common/resources'; import { generateUuid } from 'vs/base/common/uuid'; import { CancellationToken } from 'vs/base/common/cancellation'; import { editorBackground, editorForeground } from 'vs/platform/theme/common/colorRegistry'; -import { IWorkingCopy, IWorkingCopyService, IRevertOptions, ISaveOptions } from 'vs/workbench/services/workingCopy/common/workingCopyService'; +import { IWorkingCopy, IWorkingCopyService } from 'vs/workbench/services/workingCopy/common/workingCopyService'; import { env } from 'vs/base/common/process'; const CUSTOM_SCHEME = 'testCustomEditor'; @@ -168,7 +168,7 @@ class TestCustomEditorInput extends EditorInput implements IWorkingCopy { return this.dirty; } - async save(options?: ISaveOptions): Promise { + async save(groupId: GroupIdentifier, options?: ISaveOptions): Promise { this.setDirty(false); return true; diff --git a/src/vs/workbench/services/editor/browser/editorService.ts b/src/vs/workbench/services/editor/browser/editorService.ts index 3140d640aba..c4a20fade35 100644 --- a/src/vs/workbench/services/editor/browser/editorService.ts +++ b/src/vs/workbench/services/editor/browser/editorService.ts @@ -5,7 +5,7 @@ import { IInstantiationService, ServicesAccessor } from 'vs/platform/instantiation/common/instantiation'; import { IResourceInput, ITextEditorOptions, IEditorOptions, EditorActivation } from 'vs/platform/editor/common/editor'; -import { IEditorInput, IEditor, GroupIdentifier, IFileEditorInput, IUntitledTextResourceInput, IResourceDiffInput, IResourceSideBySideInput, IEditorInputFactoryRegistry, Extensions as EditorExtensions, IFileInputFactory, EditorInput, SideBySideEditorInput, IEditorInputWithOptions, isEditorInputWithOptions, EditorOptions, TextEditorOptions, IEditorIdentifier, IEditorCloseEvent, ITextEditor, ITextDiffEditor, ITextSideBySideEditor, toResource, SideBySideEditor } from 'vs/workbench/common/editor'; +import { IEditorInput, IEditor, GroupIdentifier, IFileEditorInput, IUntitledTextResourceInput, IResourceDiffInput, IResourceSideBySideInput, IEditorInputFactoryRegistry, Extensions as EditorExtensions, IFileInputFactory, EditorInput, SideBySideEditorInput, IEditorInputWithOptions, isEditorInputWithOptions, EditorOptions, TextEditorOptions, IEditorIdentifier, IEditorCloseEvent, ITextEditor, ITextDiffEditor, ITextSideBySideEditor, toResource, SideBySideEditor, IRevertOptions } from 'vs/workbench/common/editor'; import { ResourceEditorInput } from 'vs/workbench/common/editor/resourceEditorInput'; import { DataUriEditorInput } from 'vs/workbench/common/editor/dataUriEditorInput'; import { Registry } from 'vs/platform/registry/common/platform'; @@ -28,7 +28,6 @@ import { IEditorGroupView, IEditorOpeningEvent, EditorServiceImpl } from 'vs/wor import { ILabelService } from 'vs/platform/label/common/label'; import { registerSingleton } from 'vs/platform/instantiation/common/extensions'; import { withNullAsUndefined } from 'vs/base/common/types'; -import { IRevertOptions } from 'vs/workbench/services/workingCopy/common/workingCopyService'; type CachedEditorInput = ResourceEditorInput | IFileEditorInput | DataUriEditorInput; type OpenInEditorGroup = IEditorGroup | GroupIdentifier | SIDE_GROUP_TYPE | ACTIVE_GROUP_TYPE; @@ -691,7 +690,7 @@ export class EditorService extends Disposable implements EditorServiceImpl { this.editorGroupService.getGroup(groupId)?.pinEditor(editor); // Save - return editor.save(options); + return editor.save(groupId, options); })); // Editors to save sequentially @@ -700,7 +699,7 @@ export class EditorService extends Disposable implements EditorServiceImpl { continue; // might have been disposed from from the save already } - const result = await editor.saveAs(groupId, options); + const result = options?.saveAs ? await editor.saveAs(groupId, options) : await editor.save(groupId, options); if (!result) { return false; // failed or cancelled, abort } diff --git a/src/vs/workbench/services/editor/common/editorService.ts b/src/vs/workbench/services/editor/common/editorService.ts index 2fb95f9f8ec..b1404cae396 100644 --- a/src/vs/workbench/services/editor/common/editorService.ts +++ b/src/vs/workbench/services/editor/common/editorService.ts @@ -5,12 +5,11 @@ import { createDecorator, ServicesAccessor } from 'vs/platform/instantiation/common/instantiation'; import { IResourceInput, IEditorOptions, ITextEditorOptions } from 'vs/platform/editor/common/editor'; -import { IEditorInput, IEditor, GroupIdentifier, IEditorInputWithOptions, IUntitledTextResourceInput, IResourceDiffInput, IResourceSideBySideInput, ITextEditor, ITextDiffEditor, ITextSideBySideEditor, IEditorIdentifier } from 'vs/workbench/common/editor'; +import { IEditorInput, IEditor, GroupIdentifier, IEditorInputWithOptions, IUntitledTextResourceInput, IResourceDiffInput, IResourceSideBySideInput, ITextEditor, ITextDiffEditor, ITextSideBySideEditor, IEditorIdentifier, ISaveOptions, IRevertOptions } from 'vs/workbench/common/editor'; import { Event } from 'vs/base/common/event'; import { IEditor as ICodeEditor } from 'vs/editor/common/editorCommon'; import { IEditorGroup, IEditorReplacement } from 'vs/workbench/services/editor/common/editorGroupsService'; import { IDisposable } from 'vs/base/common/lifecycle'; -import { ISaveOptions, IRevertOptions } from 'vs/workbench/services/workingCopy/common/workingCopyService'; export const IEditorService = createDecorator('editorService'); diff --git a/src/vs/workbench/services/textfile/browser/textFileService.ts b/src/vs/workbench/services/textfile/browser/textFileService.ts index 4d75a95a8e4..400006f193f 100644 --- a/src/vs/workbench/services/textfile/browser/textFileService.ts +++ b/src/vs/workbench/services/textfile/browser/textFileService.ts @@ -9,7 +9,7 @@ import { Emitter, AsyncEmitter } from 'vs/base/common/event'; import * as platform from 'vs/base/common/platform'; import { IBackupFileService } from 'vs/workbench/services/backup/common/backup'; import { IResult, ITextFileOperationResult, ITextFileService, ITextFileStreamContent, ITextFileEditorModelManager, ITextFileEditorModel, ModelState, ITextFileContent, IResourceEncodings, IReadTextFileOptions, IWriteTextFileOptions, toBufferOrReadable, TextFileOperationError, TextFileOperationResult, FileOperationWillRunEvent, FileOperationDidRunEvent, ITextFileSaveOptions } from 'vs/workbench/services/textfile/common/textfiles'; -import { SaveReason, IRevertOptions } from 'vs/workbench/services/workingCopy/common/workingCopyService'; +import { SaveReason, IRevertOptions } from 'vs/workbench/common/editor'; import { ILifecycleService, ShutdownReason, LifecyclePhase } from 'vs/platform/lifecycle/common/lifecycle'; import { IWorkspaceContextService, WorkbenchState } from 'vs/platform/workspace/common/workspace'; import { IFileService, FileOperationError, FileOperationResult, HotExitConfiguration, IFileStatWithMetadata, ICreateFileOptions, FileOperation } from 'vs/platform/files/common/files'; diff --git a/src/vs/workbench/services/textfile/common/textFileEditorModel.ts b/src/vs/workbench/services/textfile/common/textFileEditorModel.ts index f18c70d2aee..f125c5235e5 100644 --- a/src/vs/workbench/services/textfile/common/textFileEditorModel.ts +++ b/src/vs/workbench/services/textfile/common/textFileEditorModel.ts @@ -12,7 +12,7 @@ import { isUndefinedOrNull, assertIsDefined } from 'vs/base/common/types'; import { IWorkspaceContextService } from 'vs/platform/workspace/common/workspace'; import { IEnvironmentService } from 'vs/platform/environment/common/environment'; import { ITextFileService, ModelState, ITextFileEditorModel, ISaveErrorHandler, ISaveParticipant, StateChange, ITextFileStreamContent, ILoadOptions, LoadReason, IResolvedTextFileEditorModel, ITextFileSaveOptions } from 'vs/workbench/services/textfile/common/textfiles'; -import { EncodingMode } from 'vs/workbench/common/editor'; +import { EncodingMode, IRevertOptions, SaveReason } from 'vs/workbench/common/editor'; import { BaseTextEditorModel } from 'vs/workbench/common/editor/textEditorModel'; import { IBackupFileService } from 'vs/workbench/services/backup/common/backup'; import { IFileService, FileOperationError, FileOperationResult, CONTENT_CHANGE_EVENT_BUFFER_DELAY, FileChangesEvent, FileChangeType, IFileStatWithMetadata, ETAG_DISABLED } from 'vs/platform/files/common/files'; @@ -29,7 +29,7 @@ import { ILogService } from 'vs/platform/log/common/log'; import { isEqual, isEqualOrParent, extname, basename, joinPath } from 'vs/base/common/resources'; import { onUnexpectedError } from 'vs/base/common/errors'; import { Schemas } from 'vs/base/common/network'; -import { IWorkingCopyService, WorkingCopyCapabilities, SaveReason, IRevertOptions } from 'vs/workbench/services/workingCopy/common/workingCopyService'; +import { IWorkingCopyService, WorkingCopyCapabilities } from 'vs/workbench/services/workingCopy/common/workingCopyService'; import { IFilesConfigurationService, IAutoSaveConfiguration } from 'vs/workbench/services/filesConfiguration/common/filesConfigurationService'; export interface IBackupMetaData { diff --git a/src/vs/workbench/services/textfile/common/textfiles.ts b/src/vs/workbench/services/textfile/common/textfiles.ts index b29d7dc560d..51338221b40 100644 --- a/src/vs/workbench/services/textfile/common/textfiles.ts +++ b/src/vs/workbench/services/textfile/common/textfiles.ts @@ -6,7 +6,7 @@ import { URI } from 'vs/base/common/uri'; import { Event, IWaitUntil } from 'vs/base/common/event'; import { IDisposable } from 'vs/base/common/lifecycle'; -import { IEncodingSupport, IModeSupport } from 'vs/workbench/common/editor'; +import { IEncodingSupport, IModeSupport, ISaveOptions, IRevertOptions, SaveReason } from 'vs/workbench/common/editor'; import { IBaseStatWithMetadata, IFileStatWithMetadata, IReadFileOptions, IWriteFileOptions, FileOperationError, FileOperationResult, FileOperation } from 'vs/platform/files/common/files'; import { createDecorator } from 'vs/platform/instantiation/common/instantiation'; import { ITextEditorModel } from 'vs/editor/common/services/resolverService'; @@ -14,7 +14,7 @@ import { ITextBufferFactory, ITextModel, ITextSnapshot } from 'vs/editor/common/ import { VSBuffer, VSBufferReadable } from 'vs/base/common/buffer'; import { isUndefinedOrNull } from 'vs/base/common/types'; import { isNative } from 'vs/base/common/platform'; -import { IWorkingCopy, ISaveOptions, SaveReason, IRevertOptions } from 'vs/workbench/services/workingCopy/common/workingCopyService'; +import { IWorkingCopy } from 'vs/workbench/services/workingCopy/common/workingCopyService'; export const ITextFileService = createDecorator('textFileService'); diff --git a/src/vs/workbench/services/workingCopy/common/workingCopyService.ts b/src/vs/workbench/services/workingCopy/common/workingCopyService.ts index ecac6c3a877..fd4da1c641f 100644 --- a/src/vs/workbench/services/workingCopy/common/workingCopyService.ts +++ b/src/vs/workbench/services/workingCopy/common/workingCopyService.ts @@ -19,68 +19,6 @@ export const enum WorkingCopyCapabilities { AutoSave = 1 << 1 } -export const enum SaveReason { - - /** - * Explicit user gesture. - */ - EXPLICIT = 1, - - /** - * Auto save after a timeout. - */ - AUTO = 2, - - /** - * Auto save after editor focus change. - */ - FOCUS_CHANGE = 3, - - /** - * Auto save after window change. - */ - WINDOW_CHANGE = 4 -} - -export interface ISaveOptions { - - /** - * An indicator how the save operation was triggered. - */ - reason?: SaveReason; - - /** - * Forces to load the contents of the working copy - * again even if the working copy is not dirty. - */ - force?: boolean; - - /** - * Instructs the save operation to skip any save participants. - */ - skipSaveParticipants?: boolean; - - /** - * A hint as to which file systems should be available for saving. - */ - availableFileSystems?: string[]; -} - -export interface IRevertOptions { - - /** - * Forces to load the contents of the working copy - * again even if the working copy is not dirty. - */ - force?: boolean; - - /** - * A soft revert will clear dirty state of a working copy - * but will not attempt to load it from its persisted state. - */ - soft?: boolean; -} - export interface IWorkingCopy { //#region Dirty Tracking @@ -92,15 +30,6 @@ export interface IWorkingCopy { //#endregion - //#region Save/Revert - - save(options?: ISaveOptions): Promise; - - revert(options?: IRevertOptions): Promise; - - //#endregion - - readonly resource: URI; readonly capabilities: WorkingCopyCapabilities; diff --git a/src/vs/workbench/services/workingCopy/test/common/workingCopyService.test.ts b/src/vs/workbench/services/workingCopy/test/common/workingCopyService.test.ts index f9fe1649555..7110cd28582 100644 --- a/src/vs/workbench/services/workingCopy/test/common/workingCopyService.test.ts +++ b/src/vs/workbench/services/workingCopy/test/common/workingCopyService.test.ts @@ -4,7 +4,7 @@ *--------------------------------------------------------------------------------------------*/ import * as assert from 'assert'; -import { IWorkingCopy, ISaveOptions, IRevertOptions } from 'vs/workbench/services/workingCopy/common/workingCopyService'; +import { IWorkingCopy } from 'vs/workbench/services/workingCopy/common/workingCopyService'; import { URI } from 'vs/base/common/uri'; import { Emitter } from 'vs/base/common/event'; import { Disposable } from 'vs/base/common/lifecycle'; @@ -41,9 +41,6 @@ suite('WorkingCopyService', () => { return this.dirty; } - async save(options?: ISaveOptions): Promise { return true; } - async revert(options?: IRevertOptions): Promise { return true; } - dispose(): void { this._onDispose.fire(); diff --git a/src/vs/workbench/test/electron-browser/api/extHostDocumentSaveParticipant.test.ts b/src/vs/workbench/test/electron-browser/api/extHostDocumentSaveParticipant.test.ts index 0e4d2acb7bd..313272d338f 100644 --- a/src/vs/workbench/test/electron-browser/api/extHostDocumentSaveParticipant.test.ts +++ b/src/vs/workbench/test/electron-browser/api/extHostDocumentSaveParticipant.test.ts @@ -10,7 +10,7 @@ import { TextDocumentSaveReason, TextEdit, Position, EndOfLine } from 'vs/workbe import { MainThreadTextEditorsShape, IWorkspaceEditDto } from 'vs/workbench/api/common/extHost.protocol'; import { ExtHostDocumentSaveParticipant } from 'vs/workbench/api/common/extHostDocumentSaveParticipant'; import { SingleProxyRPCProtocol } from './testRPCProtocol'; -import { SaveReason } from 'vs/workbench/services/workingCopy/common/workingCopyService'; +import { SaveReason } from 'vs/workbench/common/editor'; import * as vscode from 'vscode'; import { mock } from 'vs/workbench/test/electron-browser/api/mock'; import { NullLogService } from 'vs/platform/log/common/log'; diff --git a/src/vs/workbench/test/electron-browser/api/mainThreadSaveParticipant.test.ts b/src/vs/workbench/test/electron-browser/api/mainThreadSaveParticipant.test.ts index c6122bedf48..40b3489c80f 100644 --- a/src/vs/workbench/test/electron-browser/api/mainThreadSaveParticipant.test.ts +++ b/src/vs/workbench/test/electron-browser/api/mainThreadSaveParticipant.test.ts @@ -14,7 +14,7 @@ import { Range } from 'vs/editor/common/core/range'; import { Selection } from 'vs/editor/common/core/selection'; import { TextFileEditorModel } from 'vs/workbench/services/textfile/common/textFileEditorModel'; import { ITextFileService, IResolvedTextFileEditorModel, snapshotToString } from 'vs/workbench/services/textfile/common/textfiles'; -import { SaveReason } from 'vs/workbench/services/workingCopy/common/workingCopyService'; +import { SaveReason } from 'vs/workbench/common/editor'; import { TextFileEditorModelManager } from 'vs/workbench/services/textfile/common/textFileEditorModelManager'; class ServiceAccessor { diff --git a/src/vs/workbench/test/workbenchTestServices.ts b/src/vs/workbench/test/workbenchTestServices.ts index 6268b95feee..5a73dc9c71d 100644 --- a/src/vs/workbench/test/workbenchTestServices.ts +++ b/src/vs/workbench/test/workbenchTestServices.ts @@ -11,7 +11,7 @@ import * as resources from 'vs/base/common/resources'; import { URI, UriComponents } from 'vs/base/common/uri'; import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry'; import { NullTelemetryService } from 'vs/platform/telemetry/common/telemetryUtils'; -import { IEditorInputWithOptions, CloseDirection, IEditorIdentifier, IUntitledTextResourceInput, IResourceDiffInput, IResourceSideBySideInput, IEditorInput, IEditor, IEditorCloseEvent, IEditorPartOptions } from 'vs/workbench/common/editor'; +import { IEditorInputWithOptions, CloseDirection, IEditorIdentifier, IUntitledTextResourceInput, IResourceDiffInput, IResourceSideBySideInput, IEditorInput, IEditor, IEditorCloseEvent, IEditorPartOptions, IRevertOptions } from 'vs/workbench/common/editor'; import { IEditorOpeningEvent, EditorServiceImpl, IEditorGroupView } from 'vs/workbench/browser/parts/editor/editor'; import { Event, Emitter } from 'vs/base/common/event'; import Severity from 'vs/base/common/severity'; @@ -92,7 +92,7 @@ import { IBackupMainService, IWorkspaceBackupInfo } from 'vs/platform/backup/ele import { IEmptyWindowBackupInfo } from 'vs/platform/backup/node/backup'; import { IDialogMainService } from 'vs/platform/dialogs/electron-main/dialogs'; import { find } from 'vs/base/common/arrays'; -import { WorkingCopyService, IWorkingCopyService, IRevertOptions } from 'vs/workbench/services/workingCopy/common/workingCopyService'; +import { WorkingCopyService, IWorkingCopyService } from 'vs/workbench/services/workingCopy/common/workingCopyService'; import { IFilesConfigurationService, FilesConfigurationService } from 'vs/workbench/services/filesConfiguration/common/filesConfigurationService'; export function createFileInput(instantiationService: IInstantiationService, resource: URI): FileEditorInput {