diff --git a/src/vs/workbench/browser/parts/editor/editor.contribution.ts b/src/vs/workbench/browser/parts/editor/editor.contribution.ts index 54d76867204..132caa790ee 100644 --- a/src/vs/workbench/browser/parts/editor/editor.contribution.ts +++ b/src/vs/workbench/browser/parts/editor/editor.contribution.ts @@ -12,7 +12,7 @@ import { TextResourceEditor } from 'vs/workbench/browser/parts/editor/textResour import { SideBySideEditor } from 'vs/workbench/browser/parts/editor/sideBySideEditor'; import { DiffEditorInput } from 'vs/workbench/common/editor/diffEditorInput'; import { UntitledTextEditorInput } from 'vs/workbench/services/untitled/common/untitledTextEditorInput'; -import { ResourceEditorInput } from 'vs/workbench/common/editor/resourceEditorInput'; +import { TextResourceEditorInput } from 'vs/workbench/common/editor/textResourceEditorInput'; import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation'; import { TextDiffEditor } from 'vs/workbench/browser/parts/editor/textDiffEditor'; import { UntitledHintContribution } from 'vs/workbench/browser/parts/editor/untitledHint'; @@ -64,7 +64,7 @@ import { FileAccess } from 'vs/base/common/network'; import { Codicon } from 'vs/base/common/codicons'; import { registerIcon } from 'vs/platform/theme/common/iconRegistry'; -// Register String Editor +// Register Resource Text Editor Registry.as(EditorExtensions.Editors).registerEditor( EditorDescriptor.create( TextResourceEditor, @@ -73,7 +73,7 @@ Registry.as(EditorExtensions.Editors).registerEditor( ), [ new SyncDescriptor(UntitledTextEditorInput), - new SyncDescriptor(ResourceEditorInput) + new SyncDescriptor(TextResourceEditorInput) ] ); diff --git a/src/vs/workbench/browser/parts/editor/textResourceEditor.ts b/src/vs/workbench/browser/parts/editor/textResourceEditor.ts index 5105d227a4a..fd82899eddd 100644 --- a/src/vs/workbench/browser/parts/editor/textResourceEditor.ts +++ b/src/vs/workbench/browser/parts/editor/textResourceEditor.ts @@ -7,7 +7,7 @@ import { localize } from 'vs/nls'; import { assertIsDefined, isFunction, withNullAsUndefined } from 'vs/base/common/types'; import { ICodeEditor, getCodeEditor, IPasteEvent } from 'vs/editor/browser/editorBrowser'; import { TextEditorOptions, EditorInput, EditorOptions, IEditorOpenContext } from 'vs/workbench/common/editor'; -import { ResourceEditorInput } from 'vs/workbench/common/editor/resourceEditorInput'; +import { TextResourceEditorInput } from 'vs/workbench/common/editor/textResourceEditorInput'; import { BaseTextEditorModel } from 'vs/workbench/common/editor/textEditorModel'; import { UntitledTextEditorInput } from 'vs/workbench/services/untitled/common/untitledTextEditorInput'; import { BaseTextEditor } from 'vs/workbench/browser/parts/editor/textEditor'; @@ -98,7 +98,7 @@ export class AbstractTextResourceEditor extends BaseTextEditor { } private restoreTextResourceEditorViewState(editor: EditorInput, control: IEditor) { - if (editor instanceof UntitledTextEditorInput || editor instanceof ResourceEditorInput) { + if (editor instanceof UntitledTextEditorInput || editor instanceof TextResourceEditorInput) { const viewState = this.loadTextEditorViewState(editor.resource); if (viewState) { control.restoreViewState(viewState); @@ -144,7 +144,7 @@ export class AbstractTextResourceEditor extends BaseTextEditor { } private saveTextResourceEditorViewState(input: EditorInput | undefined): void { - if (!(input instanceof UntitledTextEditorInput) && !(input instanceof ResourceEditorInput)) { + if (!(input instanceof UntitledTextEditorInput) && !(input instanceof TextResourceEditorInput)) { return; // only enabled for untitled and resource inputs } diff --git a/src/vs/workbench/common/editor.ts b/src/vs/workbench/common/editor.ts index 9505a09a73f..d33a1daabce 100644 --- a/src/vs/workbench/common/editor.ts +++ b/src/vs/workbench/common/editor.ts @@ -748,22 +748,6 @@ export interface IFileEditorInput extends IEditorInput, IEncodingSupport, IModeS isResolved(): boolean; } -export function decorateFileEditorLabel(label: string, state: { orphaned: boolean, readonly: boolean }): string { - if (state.orphaned && state.readonly) { - return localize('orphanedReadonlyFile', "{0} (deleted, read-only)", label); - } - - if (state.orphaned) { - return localize('orphanedFile', "{0} (deleted)", label); - } - - if (state.readonly) { - return localize('readonlyFile', "{0} (read-only)", label); - } - - return label; -} - /** * Side by side editor inputs that have a primary and secondary side. */ diff --git a/src/vs/workbench/common/editor/diffEditorInput.ts b/src/vs/workbench/common/editor/diffEditorInput.ts index 93c0ed19cd2..7a21a642408 100644 --- a/src/vs/workbench/common/editor/diffEditorInput.ts +++ b/src/vs/workbench/common/editor/diffEditorInput.ts @@ -58,7 +58,7 @@ export class DiffEditorInput extends SideBySideEditorInput { return this.name; } - override getDescription(verbosity: Verbosity = Verbosity.MEDIUM): string | undefined { + override getDescription(verbosity = Verbosity.MEDIUM): string | undefined { if (typeof this.description !== 'string') { // Pass the description of the modified side in case both original diff --git a/src/vs/workbench/common/editor/resourceEditorInput.ts b/src/vs/workbench/common/editor/resourceEditorInput.ts index e897355fbea..83fc944940e 100644 --- a/src/vs/workbench/common/editor/resourceEditorInput.ts +++ b/src/vs/workbench/common/editor/resourceEditorInput.ts @@ -3,132 +3,194 @@ * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ +import { localize } from 'vs/nls'; +import { EditorInput, Verbosity, IEditorInputWithPreferredResource } from 'vs/workbench/common/editor'; import { URI } from 'vs/base/common/uri'; -import { IReference } from 'vs/base/common/lifecycle'; -import { ITextEditorModel, ITextModelService } from 'vs/editor/common/services/resolverService'; -import { ResourceEditorModel } from 'vs/workbench/common/editor/resourceEditorModel'; -import { IModeSupport, ITextFileService } from 'vs/workbench/services/textfile/common/textfiles'; -import { IEditorService } from 'vs/workbench/services/editor/common/editorService'; -import { IEditorGroupsService } from 'vs/workbench/services/editor/common/editorGroupsService'; -import { IFileService } from 'vs/platform/files/common/files'; +import { IFileService, FileSystemProviderCapabilities } from 'vs/platform/files/common/files'; import { ILabelService } from 'vs/platform/label/common/label'; -import { IFilesConfigurationService } from 'vs/workbench/services/filesConfiguration/common/filesConfigurationService'; -import { AbstractTextResourceEditorInput } from 'vs/workbench/common/editor/textResourceEditorInput'; -import { isEqual } from 'vs/base/common/resources'; +import { dirname, isEqual } from 'vs/base/common/resources'; /** - * A read-only text editor input whos contents are made of the provided resource that points to an existing - * code editor model. + * The base class for all editor inputs that open resources. */ -export class ResourceEditorInput extends AbstractTextResourceEditorInput implements IModeSupport { +export abstract class AbstractResourceEditorInput extends EditorInput implements IEditorInputWithPreferredResource { - static readonly ID: string = 'workbench.editors.resourceEditorInput'; - - override get typeId(): string { - return ResourceEditorInput.ID; - } - - private cachedModel: ResourceEditorModel | undefined = undefined; - private modelReference: Promise> | undefined = undefined; + private _preferredResource: URI; + get preferredResource(): URI { return this._preferredResource; } constructor( - resource: URI, - private name: string | undefined, - private description: string | undefined, - private preferredMode: string | undefined, - @ITextModelService private readonly textModelResolverService: ITextModelService, - @ITextFileService textFileService: ITextFileService, - @IEditorService editorService: IEditorService, - @IEditorGroupsService editorGroupService: IEditorGroupsService, - @IFileService fileService: IFileService, - @ILabelService labelService: ILabelService, - @IFilesConfigurationService filesConfigurationService: IFilesConfigurationService + public readonly resource: URI, + preferredResource: URI | undefined, + @ILabelService protected readonly labelService: ILabelService, + @IFileService protected readonly fileService: IFileService ) { - super(resource, undefined, editorService, editorGroupService, textFileService, labelService, fileService, filesConfigurationService); + super(); + + this._preferredResource = preferredResource || resource; + + this.registerListeners(); } - override getName(): string { - return this.name || super.getName(); + private registerListeners(): void { + + // Clear label memoizer on certain events that have impact + this._register(this.labelService.onDidChangeFormatters(e => this.onLabelEvent(e.scheme))); + this._register(this.fileService.onDidChangeFileSystemProviderRegistrations(e => this.onLabelEvent(e.scheme))); + this._register(this.fileService.onDidChangeFileSystemProviderCapabilities(e => this.onLabelEvent(e.scheme))); } - setName(name: string): void { - if (this.name !== name) { - this.name = name; - - this._onDidChangeLabel.fire(); + private onLabelEvent(scheme: string): void { + if (scheme === this._preferredResource.scheme) { + this.updateLabel(); } } - override getDescription(): string | undefined { - return this.description; + private updateLabel(): void { + + // Clear any cached labels from before + this._name = undefined; + this._shortDescription = undefined; + this._mediumDescription = undefined; + this._longDescription = undefined; + this._shortTitle = undefined; + this._mediumTitle = undefined; + this._longTitle = undefined; + + // Trigger recompute of label + this._onDidChangeLabel.fire(); } - setDescription(description: string): void { - if (this.description !== description) { - this.description = description; + setPreferredResource(preferredResource: URI): void { + if (!isEqual(preferredResource, this._preferredResource)) { + this._preferredResource = preferredResource; - this._onDidChangeLabel.fire(); + this.updateLabel(); } } - setMode(mode: string): void { - this.setPreferredMode(mode); + private _name: string | undefined = undefined; + override getName(skipDecorate?: boolean): string { + if (typeof this._name !== 'string') { + this._name = this.labelService.getUriBasenameLabel(this._preferredResource); + } - if (this.cachedModel) { - this.cachedModel.setMode(mode); + return skipDecorate ? this._name : this.decorateLabel(this._name); + } + + override getDescription(verbosity = Verbosity.MEDIUM): string | undefined { + switch (verbosity) { + case Verbosity.SHORT: + return this.shortDescription; + case Verbosity.LONG: + return this.longDescription; + case Verbosity.MEDIUM: + default: + return this.mediumDescription; } } - setPreferredMode(mode: string): void { - this.preferredMode = mode; + private _shortDescription: string | undefined = undefined; + private get shortDescription(): string { + if (typeof this._shortDescription !== 'string') { + this._shortDescription = this.labelService.getUriBasenameLabel(dirname(this._preferredResource)); + } + + return this._shortDescription; } - override async resolve(): Promise { - if (!this.modelReference) { - this.modelReference = this.textModelResolverService.createModelReference(this.resource); + private _mediumDescription: string | undefined = undefined; + private get mediumDescription(): string { + if (typeof this._mediumDescription !== 'string') { + this._mediumDescription = this.labelService.getUriLabel(dirname(this._preferredResource), { relative: true }); } - const ref = await this.modelReference; - - // Ensure the resolved model is of expected type - const model = ref.object; - if (!(model instanceof ResourceEditorModel)) { - ref.dispose(); - this.modelReference = undefined; - - throw new Error(`Unexpected model for ResourceEditorInput: ${this.resource}`); - } - - this.cachedModel = model; - - // Set mode if we have a preferred mode configured - if (this.preferredMode) { - model.setMode(this.preferredMode); - } - - return model; + return this._mediumDescription; } - override matches(otherInput: unknown): boolean { - if (otherInput === this) { - return true; + private _longDescription: string | undefined = undefined; + private get longDescription(): string { + if (typeof this._longDescription !== 'string') { + this._longDescription = this.labelService.getUriLabel(dirname(this._preferredResource)); } - if (otherInput instanceof ResourceEditorInput) { - return isEqual(otherInput.resource, this.resource); + return this._longDescription; + } + + private _shortTitle: string | undefined = undefined; + private get shortTitle(): string { + if (typeof this._shortTitle !== 'string') { + this._shortTitle = this.getName(true /* skip decorations */); } + return this._shortTitle; + } + + private _mediumTitle: string | undefined = undefined; + private get mediumTitle(): string { + if (typeof this._mediumTitle !== 'string') { + this._mediumTitle = this.labelService.getUriLabel(this._preferredResource, { relative: true }); + } + + return this._mediumTitle; + } + + private _longTitle: string | undefined = undefined; + private get longTitle(): string { + if (typeof this._longTitle !== 'string') { + this._longTitle = this.labelService.getUriLabel(this._preferredResource); + } + + return this._longTitle; + } + + override getTitle(verbosity?: Verbosity): string { + switch (verbosity) { + case Verbosity.SHORT: + return this.decorateLabel(this.shortTitle); + case Verbosity.LONG: + return this.decorateLabel(this.longTitle); + default: + case Verbosity.MEDIUM: + return this.decorateLabel(this.mediumTitle); + } + } + + private decorateLabel(label: string): string { + const readonly = this.isReadonly(); + const orphaned = this.isOrphaned(); + + return decorateFileEditorLabel(label, { orphaned, readonly }); + } + + override isUntitled(): boolean { + return !this.fileService.canHandleResource(this.resource); + } + + override isReadonly(): boolean { + if (this.isUntitled()) { + return false; // untitled is never readonly + } + + return this.fileService.hasCapability(this.resource, FileSystemProviderCapabilities.Readonly); + } + + isOrphaned(): boolean { return false; } - - override dispose(): void { - if (this.modelReference) { - this.modelReference.then(ref => ref.dispose()); - this.modelReference = undefined; - } - - this.cachedModel = undefined; - - super.dispose(); - } +} + +export function decorateFileEditorLabel(label: string, state: { orphaned: boolean, readonly: boolean }): string { + if (state.orphaned && state.readonly) { + return localize('orphanedReadonlyFile', "{0} (deleted, read-only)", label); + } + + if (state.orphaned) { + return localize('orphanedFile', "{0} (deleted)", label); + } + + if (state.readonly) { + return localize('readonlyFile', "{0} (read-only)", label); + } + + return label; } diff --git a/src/vs/workbench/common/editor/textResourceEditorInput.ts b/src/vs/workbench/common/editor/textResourceEditorInput.ts index 1a8168eeace..548e64782f5 100644 --- a/src/vs/workbench/common/editor/textResourceEditorInput.ts +++ b/src/vs/workbench/common/editor/textResourceEditorInput.ts @@ -3,179 +3,33 @@ * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ -import { EditorInput, Verbosity, GroupIdentifier, IEditorInput, IRevertOptions, IEditorInputWithPreferredResource } from 'vs/workbench/common/editor'; +import { GroupIdentifier, IEditorInput, IRevertOptions } from 'vs/workbench/common/editor'; +import { AbstractResourceEditorInput } from 'vs/workbench/common/editor/resourceEditorInput'; import { URI } from 'vs/base/common/uri'; -import { ITextFileService, ITextFileSaveOptions } from 'vs/workbench/services/textfile/common/textfiles'; +import { ITextFileService, ITextFileSaveOptions, IModeSupport } from 'vs/workbench/services/textfile/common/textfiles'; import { IEditorService } from 'vs/workbench/services/editor/common/editorService'; -import { IEditorGroupsService } from 'vs/workbench/services/editor/common/editorGroupsService'; -import { IFileService, FileSystemProviderCapabilities } from 'vs/platform/files/common/files'; +import { IFileService } from 'vs/platform/files/common/files'; import { ILabelService } from 'vs/platform/label/common/label'; -import { IFilesConfigurationService } from 'vs/workbench/services/filesConfiguration/common/filesConfigurationService'; import { Schemas } from 'vs/base/common/network'; -import { dirname, isEqual } from 'vs/base/common/resources'; +import { isEqual } from 'vs/base/common/resources'; +import { ITextEditorModel, ITextModelService } from 'vs/editor/common/services/resolverService'; +import { TextResourceEditorModel } from 'vs/workbench/common/editor/textResourceEditorModel'; +import { IReference } from 'vs/base/common/lifecycle'; /** * The base class for all editor inputs that open in text editors. */ -export abstract class AbstractTextResourceEditorInput extends EditorInput implements IEditorInputWithPreferredResource { - - private _preferredResource: URI; - get preferredResource(): URI { return this._preferredResource; } +export abstract class AbstractTextResourceEditorInput extends AbstractResourceEditorInput { constructor( - public readonly resource: URI, + resource: URI, preferredResource: URI | undefined, @IEditorService protected readonly editorService: IEditorService, - @IEditorGroupsService protected readonly editorGroupService: IEditorGroupsService, @ITextFileService protected readonly textFileService: ITextFileService, - @ILabelService protected readonly labelService: ILabelService, - @IFileService protected readonly fileService: IFileService, - @IFilesConfigurationService protected readonly filesConfigurationService: IFilesConfigurationService + @ILabelService labelService: ILabelService, + @IFileService fileService: IFileService ) { - super(); - - this._preferredResource = preferredResource || resource; - - this.registerListeners(); - } - - protected registerListeners(): void { - - // Clear label memoizer on certain events that have impact - this._register(this.labelService.onDidChangeFormatters(e => this.onLabelEvent(e.scheme))); - this._register(this.fileService.onDidChangeFileSystemProviderRegistrations(e => this.onLabelEvent(e.scheme))); - this._register(this.fileService.onDidChangeFileSystemProviderCapabilities(e => this.onLabelEvent(e.scheme))); - } - - private onLabelEvent(scheme: string): void { - if (scheme === this._preferredResource.scheme) { - this.updateLabel(); - } - } - - private updateLabel(): void { - - // Clear any cached labels from before - this._name = undefined; - this._shortDescription = undefined; - this._mediumDescription = undefined; - this._longDescription = undefined; - this._shortTitle = undefined; - this._mediumTitle = undefined; - this._longTitle = undefined; - - // Trigger recompute of label - this._onDidChangeLabel.fire(); - } - - setPreferredResource(preferredResource: URI): void { - if (!isEqual(preferredResource, this._preferredResource)) { - this._preferredResource = preferredResource; - - this.updateLabel(); - } - } - - private _name: string | undefined = undefined; - override getName(): string { - if (typeof this._name !== 'string') { - this._name = this.labelService.getUriBasenameLabel(this._preferredResource); - } - - return this._name; - } - - override getDescription(verbosity: Verbosity = Verbosity.MEDIUM): string | undefined { - switch (verbosity) { - case Verbosity.SHORT: - return this.shortDescription; - case Verbosity.LONG: - return this.longDescription; - case Verbosity.MEDIUM: - default: - return this.mediumDescription; - } - } - - private _shortDescription: string | undefined = undefined; - private get shortDescription(): string { - if (typeof this._shortDescription !== 'string') { - this._shortDescription = this.labelService.getUriBasenameLabel(dirname(this._preferredResource)); - } - - return this._shortDescription; - } - - private _mediumDescription: string | undefined = undefined; - private get mediumDescription(): string { - if (typeof this._mediumDescription !== 'string') { - this._mediumDescription = this.labelService.getUriLabel(dirname(this._preferredResource), { relative: true }); - } - - return this._mediumDescription; - } - - private _longDescription: string | undefined = undefined; - private get longDescription(): string { - if (typeof this._longDescription !== 'string') { - this._longDescription = this.labelService.getUriLabel(dirname(this._preferredResource)); - } - - return this._longDescription; - } - - private _shortTitle: string | undefined = undefined; - private get shortTitle(): string { - if (typeof this._shortTitle !== 'string') { - this._shortTitle = this.getName(); - } - - return this._shortTitle; - } - - private _mediumTitle: string | undefined = undefined; - private get mediumTitle(): string { - if (typeof this._mediumTitle !== 'string') { - this._mediumTitle = this.labelService.getUriLabel(this._preferredResource, { relative: true }); - } - - return this._mediumTitle; - } - - private _longTitle: string | undefined = undefined; - private get longTitle(): string { - if (typeof this._longTitle !== 'string') { - this._longTitle = this.labelService.getUriLabel(this._preferredResource); - } - - return this._longTitle; - } - - override getTitle(verbosity: Verbosity): string { - switch (verbosity) { - case Verbosity.SHORT: - return this.shortTitle; - case Verbosity.LONG: - return this.longTitle; - default: - case Verbosity.MEDIUM: - return this.mediumTitle; - } - } - - override isUntitled(): boolean { - // any file: is never untitled as it can be saved - // untitled: is untitled by definition - // any other: is untitled because it cannot be saved, as such we expect a "Save As" dialog - return !this.fileService.canHandleResource(this.resource); - } - - override isReadonly(): boolean { - if (this.isUntitled()) { - return false; // untitled is never readonly - } - - return this.fileService.hasCapability(this.resource, FileSystemProviderCapabilities.Readonly); + super(resource, preferredResource, labelService, fileService); } override save(group: GroupIdentifier, options?: ITextFileSaveOptions): Promise { @@ -225,3 +79,118 @@ export abstract class AbstractTextResourceEditorInput extends EditorInput implem await this.textFileService.revert(this.resource, options); } } + +/** + * A read-only text editor input whos contents are made of the provided resource that points to an existing + * code editor model. + */ +export class TextResourceEditorInput extends AbstractTextResourceEditorInput implements IModeSupport { + + static readonly ID: string = 'workbench.editors.resourceEditorInput'; + + override get typeId(): string { + return TextResourceEditorInput.ID; + } + + private cachedModel: TextResourceEditorModel | undefined = undefined; + private modelReference: Promise> | undefined = undefined; + + constructor( + resource: URI, + private name: string | undefined, + private description: string | undefined, + private preferredMode: string | undefined, + @ITextModelService private readonly textModelResolverService: ITextModelService, + @ITextFileService textFileService: ITextFileService, + @IEditorService editorService: IEditorService, + @IFileService fileService: IFileService, + @ILabelService labelService: ILabelService + ) { + super(resource, undefined, editorService, textFileService, labelService, fileService); + } + + override getName(): string { + return this.name || super.getName(); + } + + setName(name: string): void { + if (this.name !== name) { + this.name = name; + + this._onDidChangeLabel.fire(); + } + } + + override getDescription(): string | undefined { + return this.description; + } + + setDescription(description: string): void { + if (this.description !== description) { + this.description = description; + + this._onDidChangeLabel.fire(); + } + } + + setMode(mode: string): void { + this.setPreferredMode(mode); + + if (this.cachedModel) { + this.cachedModel.setMode(mode); + } + } + + setPreferredMode(mode: string): void { + this.preferredMode = mode; + } + + override async resolve(): Promise { + if (!this.modelReference) { + this.modelReference = this.textModelResolverService.createModelReference(this.resource); + } + + const ref = await this.modelReference; + + // Ensure the resolved model is of expected type + const model = ref.object; + if (!(model instanceof TextResourceEditorModel)) { + ref.dispose(); + this.modelReference = undefined; + + throw new Error(`Unexpected model for TextResourceEditorInput: ${this.resource}`); + } + + this.cachedModel = model; + + // Set mode if we have a preferred mode configured + if (this.preferredMode) { + model.setMode(this.preferredMode); + } + + return model; + } + + override matches(otherInput: unknown): boolean { + if (otherInput === this) { + return true; + } + + if (otherInput instanceof TextResourceEditorInput) { + return isEqual(otherInput.resource, this.resource); + } + + return false; + } + + override dispose(): void { + if (this.modelReference) { + this.modelReference.then(ref => ref.dispose()); + this.modelReference = undefined; + } + + this.cachedModel = undefined; + + super.dispose(); + } +} diff --git a/src/vs/workbench/common/editor/resourceEditorModel.ts b/src/vs/workbench/common/editor/textResourceEditorModel.ts similarity index 85% rename from src/vs/workbench/common/editor/resourceEditorModel.ts rename to src/vs/workbench/common/editor/textResourceEditorModel.ts index 661bbe6496f..6dab1e29f61 100644 --- a/src/vs/workbench/common/editor/resourceEditorModel.ts +++ b/src/vs/workbench/common/editor/textResourceEditorModel.ts @@ -9,9 +9,10 @@ import { IModeService } from 'vs/editor/common/services/modeService'; import { IModelService } from 'vs/editor/common/services/modelService'; /** - * An editor model for in-memory, readonly content that is backed by an existing editor model. + * An editor model for in-memory, readonly text content that + * is backed by an existing editor model. */ -export class ResourceEditorModel extends BaseTextEditorModel { +export class TextResourceEditorModel extends BaseTextEditorModel { constructor( resource: URI, diff --git a/src/vs/workbench/contrib/customEditor/browser/customEditorInput.ts b/src/vs/workbench/contrib/customEditor/browser/customEditorInput.ts index 76f35b5df69..7334c3f1d34 100644 --- a/src/vs/workbench/contrib/customEditor/browser/customEditorInput.ts +++ b/src/vs/workbench/contrib/customEditor/browser/customEditorInput.ts @@ -16,7 +16,8 @@ import { IFileDialogService } from 'vs/platform/dialogs/common/dialogs'; import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation'; import { ILabelService } from 'vs/platform/label/common/label'; import { IUndoRedoService } from 'vs/platform/undoRedo/common/undoRedo'; -import { decorateFileEditorLabel, GroupIdentifier, IEditorInput, IRevertOptions, ISaveOptions, Verbosity } from 'vs/workbench/common/editor'; +import { GroupIdentifier, IEditorInput, IRevertOptions, ISaveOptions, Verbosity } from 'vs/workbench/common/editor'; +import { decorateFileEditorLabel } from 'vs/workbench/common/editor/resourceEditorInput'; import { defaultCustomEditor } from 'vs/workbench/contrib/customEditor/common/contributedCustomEditors'; import { ICustomEditorModel, ICustomEditorService } from 'vs/workbench/contrib/customEditor/common/customEditor'; import { IWebviewService, WebviewOverlay } from 'vs/workbench/contrib/webview/browser/webview'; diff --git a/src/vs/workbench/contrib/files/common/editors/fileEditorInput.ts b/src/vs/workbench/contrib/files/common/editors/fileEditorInput.ts index 8bddb873143..fe66e3f3205 100644 --- a/src/vs/workbench/contrib/files/common/editors/fileEditorInput.ts +++ b/src/vs/workbench/contrib/files/common/editors/fileEditorInput.ts @@ -4,7 +4,7 @@ *--------------------------------------------------------------------------------------------*/ import { URI } from 'vs/base/common/uri'; -import { IFileEditorInput, Verbosity, GroupIdentifier, IMoveResult, isTextEditorPane, decorateFileEditorLabel } from 'vs/workbench/common/editor'; +import { IFileEditorInput, Verbosity, GroupIdentifier, IMoveResult, isTextEditorPane } from 'vs/workbench/common/editor'; import { AbstractTextResourceEditorInput } from 'vs/workbench/common/editor/textResourceEditorInput'; import { BinaryEditorModel } from 'vs/workbench/common/editor/binaryEditorModel'; import { FileOperationError, FileOperationResult, IFileService } from 'vs/platform/files/common/files'; @@ -16,7 +16,6 @@ import { FILE_EDITOR_INPUT_ID, TEXT_FILE_EDITOR_ID, BINARY_FILE_EDITOR_ID } from import { ILabelService } from 'vs/platform/label/common/label'; import { AutoSaveMode, IFilesConfigurationService } from 'vs/workbench/services/filesConfiguration/common/filesConfigurationService'; import { IEditorService } from 'vs/workbench/services/editor/common/editorService'; -import { IEditorGroupsService } from 'vs/workbench/services/editor/common/editorGroupsService'; import { isEqual } from 'vs/base/common/resources'; import { Event } from 'vs/base/common/event'; import { IEditorViewState } from 'vs/editor/common/editorCommon'; @@ -61,11 +60,10 @@ export class FileEditorInput extends AbstractTextResourceEditorInput implements @ITextModelService private readonly textModelResolverService: ITextModelService, @ILabelService labelService: ILabelService, @IFileService fileService: IFileService, - @IFilesConfigurationService filesConfigurationService: IFilesConfigurationService, - @IEditorService editorService: IEditorService, - @IEditorGroupsService editorGroupService: IEditorGroupsService + @IFilesConfigurationService private readonly filesConfigurationService: IFilesConfigurationService, + @IEditorService editorService: IEditorService ) { - super(resource, preferredResource, editorService, editorGroupService, textFileService, labelService, fileService, filesConfigurationService); + super(resource, preferredResource, editorService, textFileService, labelService, fileService); this.model = this.textFileService.files.get(resource); @@ -85,19 +83,15 @@ export class FileEditorInput extends AbstractTextResourceEditorInput implements this.setPreferredMode(preferredMode); } + // Attach to model that matches our resource once created + this._register(this.textFileService.files.onDidCreate(model => this.onDidCreateTextFileModel(model))); + // If a file model already exists, make sure to wire it in if (this.model) { this.registerModelListeners(this.model); } } - protected override registerListeners(): void { - super.registerListeners(); - - // Attach to model that matches our resource once created - this._register(this.textFileService.files.onDidCreate(model => this.onDidCreateTextFileModel(model))); - } - private onDidCreateTextFileModel(model: ITextFileEditorModel): void { // Once the text file model is created, we keep it inside @@ -131,7 +125,7 @@ export class FileEditorInput extends AbstractTextResourceEditorInput implements } override getName(): string { - return this.preferredName || this.decorateLabel(super.getName()); + return this.preferredName || super.getName(); } setPreferredName(name: string): void { @@ -174,23 +168,6 @@ export class FileEditorInput extends AbstractTextResourceEditorInput implements return this.preferredDescription; } - override getTitle(verbosity: Verbosity): string { - switch (verbosity) { - case Verbosity.SHORT: - return this.decorateLabel(super.getName()); - case Verbosity.MEDIUM: - case Verbosity.LONG: - return this.decorateLabel(super.getTitle(verbosity)); - } - } - - private decorateLabel(label: string): string { - const orphaned = this.model?.hasState(TextFileEditorModelState.ORPHAN); - const readonly = this.isReadonly(); - - return decorateFileEditorLabel(label, { orphaned: !!orphaned, readonly }); - } - getEncoding(): string | undefined { if (this.model) { return this.model.getEncoding(); @@ -253,6 +230,14 @@ export class FileEditorInput extends AbstractTextResourceEditorInput implements return super.isReadonly(); } + override isOrphaned(): boolean { + if (this.model) { + return this.model.hasState(TextFileEditorModelState.ORPHAN); + } + + return super.isOrphaned(); + } + override isSaving(): boolean { if (this.model?.hasState(TextFileEditorModelState.SAVED) || this.model?.hasState(TextFileEditorModelState.CONFLICT) || this.model?.hasState(TextFileEditorModelState.ERROR)) { return false; // require the model to be dirty and not in conflict or error state diff --git a/src/vs/workbench/contrib/notebook/common/notebookCommon.ts b/src/vs/workbench/contrib/notebook/common/notebookCommon.ts index ccefc1d83fe..5989476b870 100644 --- a/src/vs/workbench/contrib/notebook/common/notebookCommon.ts +++ b/src/vs/workbench/contrib/notebook/common/notebookCommon.ts @@ -687,12 +687,14 @@ export interface IResolvedNotebookEditorModel extends INotebookEditorModel { export interface INotebookEditorModel extends IEditorModel { readonly onDidChangeDirty: Event; readonly onDidSave: Event; + readonly onDidChangeOrphaned: Event; readonly resource: URI; readonly viewType: string; readonly notebook: NotebookTextModel | undefined; isResolved(): this is IResolvedNotebookEditorModel; isDirty(): boolean; isReadonly(): boolean; + isOrphaned(): boolean; load(options?: INotebookLoadOptions): Promise; save(options?: ISaveOptions): Promise; saveAs(target: URI): Promise; diff --git a/src/vs/workbench/contrib/notebook/common/notebookEditorInput.ts b/src/vs/workbench/contrib/notebook/common/notebookEditorInput.ts index 8dd4f231c30..51fcf8905a4 100644 --- a/src/vs/workbench/contrib/notebook/common/notebookEditorInput.ts +++ b/src/vs/workbench/contrib/notebook/common/notebookEditorInput.ts @@ -4,7 +4,7 @@ *--------------------------------------------------------------------------------------------*/ import * as glob from 'vs/base/common/glob'; -import { EditorInput, IEditorInput, GroupIdentifier, ISaveOptions, IMoveResult, IRevertOptions } from 'vs/workbench/common/editor'; +import { IEditorInput, GroupIdentifier, ISaveOptions, IMoveResult, IRevertOptions } from 'vs/workbench/common/editor'; import { INotebookService } from 'vs/workbench/contrib/notebook/common/notebookService'; import { URI } from 'vs/base/common/uri'; import { isEqual, joinPath } from 'vs/base/common/resources'; @@ -16,12 +16,14 @@ import { IResolvedNotebookEditorModel } from 'vs/workbench/contrib/notebook/comm import { ILabelService } from 'vs/platform/label/common/label'; import { Schemas } from 'vs/base/common/network'; import { mark } from 'vs/workbench/contrib/notebook/common/notebookPerformance'; +import { IFileService } from 'vs/platform/files/common/files'; +import { AbstractResourceEditorInput } from 'vs/workbench/common/editor/resourceEditorInput'; interface NotebookEditorInputOptions { startDirty?: boolean; } -export class NotebookEditorInput extends EditorInput { +export class NotebookEditorInput extends AbstractResourceEditorInput { static create(instantiationService: IInstantiationService, resource: URI, viewType: string, options: NotebookEditorInputOptions = {}) { return instantiationService.createInstance(NotebookEditorInput, resource, viewType, options); @@ -29,13 +31,11 @@ export class NotebookEditorInput extends EditorInput { static readonly ID: string = 'workbench.input.notebook'; - private readonly _name: string; - private _editorModelReference: IReference | null = null; private _defaultDirtyState: boolean = false; constructor( - public readonly resource: URI, + resource: URI, public readonly viewType: string, public readonly options: NotebookEditorInputOptions, @INotebookService private readonly _notebookService: INotebookService, @@ -43,10 +43,10 @@ export class NotebookEditorInput extends EditorInput { @IFileDialogService private readonly _fileDialogService: IFileDialogService, @IInstantiationService private readonly _instantiationService: IInstantiationService, @ILabelService labelService: ILabelService, + @IFileService fileService: IFileService ) { - super(); + super(resource, undefined, labelService, fileService); this._defaultDirtyState = !!options.startDirty; - this._name = labelService.getUriBasenameLabel(resource); } override dispose() { @@ -59,10 +59,6 @@ export class NotebookEditorInput extends EditorInput { return NotebookEditorInput.ID; } - override getName(): string { - return this._name; - } - override isDirty() { if (!this._editorModelReference) { return this._defaultDirtyState; @@ -82,6 +78,14 @@ export class NotebookEditorInput extends EditorInput { return this._editorModelReference.object.isReadonly(); } + override isOrphaned() { + if (!this._editorModelReference) { + return super.isOrphaned(); + } + + return this._editorModelReference.object.isOrphaned(); + } + override async save(group: GroupIdentifier, options?: ISaveOptions): Promise { if (this._editorModelReference) { @@ -108,7 +112,7 @@ export class NotebookEditorInput extends EditorInput { return undefined; } - const dialogPath = this.isUntitled() ? await this._suggestName(this._name) : this._editorModelReference.object.resource; + const dialogPath = this.isUntitled() ? await this._suggestName(this.labelService.getUriBasenameLabel(this.resource)) : this._editorModelReference.object.resource; const target = await this._fileDialogService.pickFileToSave(dialogPath, options?.availableFileSystems); if (!target) { @@ -175,6 +179,7 @@ export class NotebookEditorInput extends EditorInput { return null; } this._register(this._editorModelReference.object.onDidChangeDirty(() => this._onDidChangeDirty.fire())); + this._register(this._editorModelReference.object.onDidChangeOrphaned(() => this._onDidChangeLabel.fire())); if (this._editorModelReference.object.isDirty()) { this._onDidChangeDirty.fire(); } diff --git a/src/vs/workbench/contrib/notebook/common/notebookEditorModel.ts b/src/vs/workbench/contrib/notebook/common/notebookEditorModel.ts index c6bd5b396ba..47a80fc8aef 100644 --- a/src/vs/workbench/contrib/notebook/common/notebookEditorModel.ts +++ b/src/vs/workbench/contrib/notebook/common/notebookEditorModel.ts @@ -23,7 +23,7 @@ import { TaskSequentializer } from 'vs/base/common/async'; import { bufferToStream, streamToBuffer, VSBuffer, VSBufferReadableStream } from 'vs/base/common/buffer'; import { assertType } from 'vs/base/common/types'; import { IUntitledTextEditorService } from 'vs/workbench/services/untitled/common/untitledTextEditorService'; -import { IFileWorkingCopyModel, IFileWorkingCopyModelContentChangedEvent, IFileWorkingCopyModelFactory, IResolvedFileWorkingCopy } from 'vs/workbench/services/workingCopy/common/fileWorkingCopy'; +import { FileWorkingCopyState, IFileWorkingCopyModel, IFileWorkingCopyModelContentChangedEvent, IFileWorkingCopyModelFactory, IResolvedFileWorkingCopy } from 'vs/workbench/services/workingCopy/common/fileWorkingCopy'; import { DisposableStore, IDisposable } from 'vs/base/common/lifecycle'; import { canceled } from 'vs/base/common/errors'; import { NotebookEditorInput } from 'vs/workbench/contrib/notebook/common/notebookEditorInput'; @@ -41,6 +41,7 @@ export class ComplexNotebookEditorModel extends EditorModel implements INotebook readonly onDidSave = this._onDidSave.event; readonly onDidChangeDirty = this._onDidChangeDirty.event; + readonly onDidChangeOrphaned = Event.None; private _lastResolvedFileStat?: IFileStatWithMetadata; @@ -126,6 +127,10 @@ export class ComplexNotebookEditorModel extends EditorModel implements INotebook return false; } + isOrphaned(): boolean { + return false; + } + private _isUntitled(): boolean { return this.resource.scheme === Schemas.untitled; } @@ -411,9 +416,11 @@ export class SimpleNotebookEditorModel extends EditorModel implements INotebookE private readonly _onDidChangeDirty = new Emitter(); private readonly _onDidSave = new Emitter(); + private readonly _onDidChangeOrphaned = new Emitter(); readonly onDidChangeDirty: Event = this._onDidChangeDirty.event; readonly onDidSave: Event = this._onDidSave.event; + readonly onDidChangeOrphaned: Event = this._onDidChangeOrphaned.event; private _workingCopy?: IResolvedFileWorkingCopy; private readonly _workingCopyListeners = new DisposableStore(); @@ -423,7 +430,7 @@ export class SimpleNotebookEditorModel extends EditorModel implements INotebookE readonly viewType: string, private readonly _workingCopyManager: IFileWorkingCopyManager, @IInstantiationService private readonly _instantiationService: IInstantiationService, - @IFileService private readonly fileService: IFileService + @IFileService private readonly _fileService: IFileService ) { super(); } @@ -433,6 +440,7 @@ export class SimpleNotebookEditorModel extends EditorModel implements INotebookE this._workingCopy?.dispose(); this._onDidChangeDirty.dispose(); this._onDidSave.dispose(); + this._onDidChangeOrphaned.dispose(); super.dispose(); } @@ -448,8 +456,12 @@ export class SimpleNotebookEditorModel extends EditorModel implements INotebookE return this._workingCopy?.isDirty() ?? false; } + isOrphaned(): boolean { + return this._workingCopy?.hasState(FileWorkingCopyState.ORPHAN) ?? false; + } + isReadonly(): boolean { - return this.fileService.hasCapability(this.resource, FileSystemProviderCapabilities.Readonly); + return this._fileService.hasCapability(this.resource, FileSystemProviderCapabilities.Readonly); } revert(options?: IRevertOptions): Promise { @@ -468,6 +480,7 @@ export class SimpleNotebookEditorModel extends EditorModel implements INotebookE this._workingCopy = >workingCopy; this._workingCopy.onDidChangeDirty(() => this._onDidChangeDirty.fire(), this._workingCopyListeners); this._workingCopy.onDidSave(() => this._onDidSave.fire(), this._workingCopyListeners); + this._workingCopy.onDidChangeOrphaned(() => this._onDidChangeOrphaned.fire(), this._workingCopyListeners); } assertType(this.isResolved()); return this; diff --git a/src/vs/workbench/contrib/notebook/test/testNotebookEditor.ts b/src/vs/workbench/contrib/notebook/test/testNotebookEditor.ts index 44720746a48..20460f430cd 100644 --- a/src/vs/workbench/contrib/notebook/test/testNotebookEditor.ts +++ b/src/vs/workbench/contrib/notebook/test/testNotebookEditor.ts @@ -66,6 +66,8 @@ export class NotebookEditorTestModel extends EditorModel implements INotebookEdi protected readonly _onDidChangeDirty = this._register(new Emitter()); readonly onDidChangeDirty = this._onDidChangeDirty.event; + readonly onDidChangeOrphaned = Event.None; + private readonly _onDidChangeContent = this._register(new Emitter()); readonly onDidChangeContent: Event = this._onDidChangeContent.event; @@ -95,10 +97,15 @@ export class NotebookEditorTestModel extends EditorModel implements INotebookEdi })); } } + isReadonly(): boolean { return false; } + isOrphaned(): boolean { + return false; + } + isDirty() { return this._dirty; } diff --git a/src/vs/workbench/contrib/output/browser/logViewer.ts b/src/vs/workbench/contrib/output/browser/logViewer.ts index 4a7ab233c2d..b9c32a6bcb9 100644 --- a/src/vs/workbench/contrib/output/browser/logViewer.ts +++ b/src/vs/workbench/contrib/output/browser/logViewer.ts @@ -12,7 +12,7 @@ import { ITextResourceConfigurationService } from 'vs/editor/common/services/tex import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation'; import { AbstractTextResourceEditor } from 'vs/workbench/browser/parts/editor/textResourceEditor'; import { IThemeService } from 'vs/platform/theme/common/themeService'; -import { ResourceEditorInput } from 'vs/workbench/common/editor/resourceEditorInput'; +import { TextResourceEditorInput } from 'vs/workbench/common/editor/textResourceEditorInput'; import { URI } from 'vs/base/common/uri'; import { ITextModelService } from 'vs/editor/common/services/resolverService'; import { LOG_SCHEME } from 'vs/workbench/contrib/output/common/output'; @@ -22,9 +22,8 @@ import { IEditorService } from 'vs/workbench/services/editor/common/editorServic import { ITextFileService } from 'vs/workbench/services/textfile/common/textfiles'; import { IFileService } from 'vs/platform/files/common/files'; import { ILabelService } from 'vs/platform/label/common/label'; -import { IFilesConfigurationService } from 'vs/workbench/services/filesConfiguration/common/filesConfigurationService'; -export class LogViewerInput extends ResourceEditorInput { +export class LogViewerInput extends TextResourceEditorInput { static override readonly ID = 'workbench.editorinputs.output'; @@ -37,10 +36,8 @@ export class LogViewerInput extends ResourceEditorInput { @ITextModelService textModelResolverService: ITextModelService, @ITextFileService textFileService: ITextFileService, @IEditorService editorService: IEditorService, - @IEditorGroupsService editorGroupService: IEditorGroupsService, @IFileService fileService: IFileService, - @ILabelService labelService: ILabelService, - @IFilesConfigurationService filesConfigurationService: IFilesConfigurationService + @ILabelService labelService: ILabelService ) { super( URI.from({ scheme: LOG_SCHEME, path: outputChannelDescriptor.id }), @@ -50,10 +47,8 @@ export class LogViewerInput extends ResourceEditorInput { textModelResolverService, textFileService, editorService, - editorGroupService, fileService, - labelService, - filesConfigurationService + labelService ); } } diff --git a/src/vs/workbench/contrib/output/browser/outputView.ts b/src/vs/workbench/contrib/output/browser/outputView.ts index 1ec7055bbbf..7724bce7bd7 100644 --- a/src/vs/workbench/contrib/output/browser/outputView.ts +++ b/src/vs/workbench/contrib/output/browser/outputView.ts @@ -25,7 +25,7 @@ import { ViewPane, IViewPaneOptions } from 'vs/workbench/browser/parts/views/vie import { IKeybindingService } from 'vs/platform/keybinding/common/keybinding'; import { IContextMenuService, IContextViewService } from 'vs/platform/contextview/browser/contextView'; import { IViewDescriptorService } from 'vs/workbench/common/views'; -import { ResourceEditorInput } from 'vs/workbench/common/editor/resourceEditorInput'; +import { TextResourceEditorInput } from 'vs/workbench/common/editor/textResourceEditorInput'; import { IOpenerService } from 'vs/platform/opener/common/opener'; import { IOutputChannelDescriptor, IOutputChannelRegistry, Extensions } from 'vs/workbench/services/output/common/output'; import { Registry } from 'vs/platform/registry/common/platform'; @@ -156,8 +156,8 @@ export class OutputViewPane extends ViewPane { this.editorPromise = null; } - private createInput(channel: IOutputChannel): ResourceEditorInput { - return this.instantiationService.createInstance(ResourceEditorInput, channel.uri, nls.localize('output model title', "{0} - Output", channel.label), nls.localize('channel', "Output channel for '{0}'", channel.label), undefined); + private createInput(channel: IOutputChannel): TextResourceEditorInput { + return this.instantiationService.createInstance(TextResourceEditorInput, channel.uri, nls.localize('output model title', "{0} - Output", channel.label), nls.localize('channel', "Output channel for '{0}'", channel.label), undefined); } } diff --git a/src/vs/workbench/contrib/performance/browser/perfviewEditor.ts b/src/vs/workbench/contrib/performance/browser/perfviewEditor.ts index b5e17cc2fe2..d644d019771 100644 --- a/src/vs/workbench/contrib/performance/browser/perfviewEditor.ts +++ b/src/vs/workbench/contrib/performance/browser/perfviewEditor.ts @@ -5,7 +5,7 @@ import { localize } from 'vs/nls'; import { URI } from 'vs/base/common/uri'; -import { ResourceEditorInput } from 'vs/workbench/common/editor/resourceEditorInput'; +import { TextResourceEditorInput } from 'vs/workbench/common/editor/textResourceEditorInput'; import { ITextModelService, ITextModelContentProvider } from 'vs/editor/common/services/resolverService'; import { ITextModel } from 'vs/editor/common/model'; import { ILifecycleService, LifecyclePhase, StartupKindToString } from 'vs/workbench/services/lifecycle/common/lifecycle'; @@ -21,10 +21,8 @@ import { LoaderStats } from 'vs/base/common/amd'; import { IProductService } from 'vs/platform/product/common/productService'; import { ITextFileService } from 'vs/workbench/services/textfile/common/textfiles'; import { IEditorService } from 'vs/workbench/services/editor/common/editorService'; -import { IEditorGroupsService } from 'vs/workbench/services/editor/common/editorGroupsService'; import { ByteSize, IFileService } from 'vs/platform/files/common/files'; import { ILabelService } from 'vs/platform/label/common/label'; -import { IFilesConfigurationService } from 'vs/workbench/services/filesConfiguration/common/filesConfigurationService'; import { isWeb } from 'vs/base/common/platform'; export class PerfviewContrib { @@ -43,7 +41,7 @@ export class PerfviewContrib { } } -export class PerfviewInput extends ResourceEditorInput { +export class PerfviewInput extends TextResourceEditorInput { static readonly Id = 'PerfviewInput'; static readonly Uri = URI.from({ scheme: 'perf', path: 'Startup Performance' }); @@ -56,10 +54,8 @@ export class PerfviewInput extends ResourceEditorInput { @ITextModelService textModelResolverService: ITextModelService, @ITextFileService textFileService: ITextFileService, @IEditorService editorService: IEditorService, - @IEditorGroupsService editorGroupService: IEditorGroupsService, @IFileService fileService: IFileService, - @ILabelService labelService: ILabelService, - @IFilesConfigurationService filesConfigurationService: IFilesConfigurationService + @ILabelService labelService: ILabelService ) { super( PerfviewInput.Uri, @@ -69,10 +65,8 @@ export class PerfviewInput extends ResourceEditorInput { textModelResolverService, textFileService, editorService, - editorGroupService, fileService, - labelService, - filesConfigurationService + labelService ); } } diff --git a/src/vs/workbench/contrib/preferences/browser/preferencesEditor.ts b/src/vs/workbench/contrib/preferences/browser/preferencesEditor.ts index 398a6ee248c..4efef1c0eea 100644 --- a/src/vs/workbench/contrib/preferences/browser/preferencesEditor.ts +++ b/src/vs/workbench/contrib/preferences/browser/preferencesEditor.ts @@ -42,7 +42,7 @@ import { IEditorRegistry } from 'vs/workbench/browser/editor'; import { EditorPane } from 'vs/workbench/browser/parts/editor/editorPane'; import { BaseTextEditor } from 'vs/workbench/browser/parts/editor/textEditor'; import { EditorExtensions, EditorInput, EditorOptions, IEditorControl, IEditorOpenContext } from 'vs/workbench/common/editor'; -import { ResourceEditorModel } from 'vs/workbench/common/editor/resourceEditorModel'; +import { TextResourceEditorModel } from 'vs/workbench/common/editor/textResourceEditorModel'; import { DefaultSettingsRenderer, FolderSettingsRenderer, IPreferencesRenderer, UserSettingsRenderer, WorkspaceSettingsRenderer } from 'vs/workbench/contrib/preferences/browser/preferencesRenderers'; import { SearchWidget, SettingsTarget, SettingsTargetsWidget } from 'vs/workbench/contrib/preferences/browser/preferencesWidgets'; import { CONTEXT_SETTINGS_EDITOR, CONTEXT_SETTINGS_JSON_EDITOR, CONTEXT_SETTINGS_SEARCH_FOCUS, IPreferencesSearchService, ISearchProvider } from 'vs/workbench/contrib/preferences/common/preferences'; @@ -1035,7 +1035,7 @@ export class DefaultPreferencesEditor extends BaseTextEditor { return; } const editor = assertIsDefined(this.getControl()); - editor.setModel((editorModel).textEditorModel); + editor.setModel((editorModel).textEditorModel); } override clearInput(): void { diff --git a/src/vs/workbench/services/editor/browser/editorService.ts b/src/vs/workbench/services/editor/browser/editorService.ts index 187d165f9ce..9b1b454d2f9 100644 --- a/src/vs/workbench/services/editor/browser/editorService.ts +++ b/src/vs/workbench/services/editor/browser/editorService.ts @@ -6,7 +6,7 @@ import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation'; import { IResourceEditorInput, ITextEditorOptions, IEditorOptions, EditorActivation, EditorOverride, IResourceEditorInputIdentifier } from 'vs/platform/editor/common/editor'; import { SideBySideEditor, IEditorInput, IEditorPane, GroupIdentifier, IFileEditorInput, IUntitledTextResourceEditorInput, IResourceDiffEditorInput, IEditorInputFactoryRegistry, EditorExtensions, EditorInput, SideBySideEditorInput, IEditorInputWithOptions, isEditorInputWithOptions, EditorOptions, TextEditorOptions, IEditorIdentifier, IEditorCloseEvent, ITextEditorPane, ITextDiffEditorPane, IRevertOptions, SaveReason, EditorsOrder, isTextEditorPane, IWorkbenchEditorConfiguration, EditorResourceAccessor, IVisibleEditorPane, IEditorInputWithOptionsAndGroup } from 'vs/workbench/common/editor'; -import { ResourceEditorInput } from 'vs/workbench/common/editor/resourceEditorInput'; +import { TextResourceEditorInput } from 'vs/workbench/common/editor/textResourceEditorInput'; import { Registry } from 'vs/platform/registry/common/platform'; import { ResourceMap } from 'vs/base/common/map'; import { IUntitledTextEditorService } from 'vs/workbench/services/untitled/common/untitledTextEditorService'; @@ -38,7 +38,7 @@ import { ILogService } from 'vs/platform/log/common/log'; import { ContributedEditorPriority, DEFAULT_EDITOR_ASSOCIATION, IEditorOverrideService } from 'vs/workbench/services/editor/common/editorOverrideService'; import { IWorkingCopyService } from 'vs/workbench/services/workingCopy/common/workingCopyService'; -type CachedEditorInput = ResourceEditorInput | IFileEditorInput | UntitledTextEditorInput; +type CachedEditorInput = TextResourceEditorInput | IFileEditorInput | UntitledTextEditorInput; type OpenInEditorGroup = IEditorGroup | GroupIdentifier | SIDE_GROUP_TYPE | ACTIVE_GROUP_TYPE; export class EditorService extends Disposable implements EditorServiceImpl { @@ -1071,7 +1071,7 @@ export class EditorService extends Disposable implements EditorServiceImpl { } // Resource - return this.instantiationService.createInstance(ResourceEditorInput, canonicalResource, resourceEditorInput.label, resourceEditorInput.description, resourceEditorInput.mode); + return this.instantiationService.createInstance(TextResourceEditorInput, canonicalResource, resourceEditorInput.label, resourceEditorInput.description, resourceEditorInput.mode); }, cachedInput => { // Untitled @@ -1080,7 +1080,7 @@ export class EditorService extends Disposable implements EditorServiceImpl { } // Files - else if (!(cachedInput instanceof ResourceEditorInput)) { + else if (!(cachedInput instanceof TextResourceEditorInput)) { cachedInput.setPreferredResource(preferredResource); if (resourceEditorInput.label) { diff --git a/src/vs/workbench/services/editor/test/browser/editorService.test.ts b/src/vs/workbench/services/editor/test/browser/editorService.test.ts index 4d8fff4f27f..735dc057e4a 100644 --- a/src/vs/workbench/services/editor/test/browser/editorService.test.ts +++ b/src/vs/workbench/services/editor/test/browser/editorService.test.ts @@ -10,7 +10,7 @@ import { Event } from 'vs/base/common/event'; import { EditorPane } from 'vs/workbench/browser/parts/editor/editorPane'; import { EditorInput, EditorsOrder, SideBySideEditorInput } from 'vs/workbench/common/editor'; import { workbenchInstantiationService, TestServiceAccessor, registerTestEditor, TestFileEditorInput, ITestInstantiationService, registerTestResourceEditor, registerTestSideBySideEditor, createEditorPart } from 'vs/workbench/test/browser/workbenchTestServices'; -import { ResourceEditorInput } from 'vs/workbench/common/editor/resourceEditorInput'; +import { TextResourceEditorInput } from 'vs/workbench/common/editor/textResourceEditorInput'; import { TestThemeService } from 'vs/platform/theme/test/common/testThemeService'; import { EditorService, DelegatingEditorService } from 'vs/workbench/services/editor/browser/editorService'; import { IEditorGroup, IEditorGroupsService, GroupDirection, GroupsArrangement } from 'vs/workbench/services/editor/common/editorGroupsService'; @@ -362,7 +362,7 @@ suite('EditorService', () => { // Untyped Input (resource) input = service.createEditorInput({ resource: URI.parse('custom:resource') }); - assert(input instanceof ResourceEditorInput); + assert(input instanceof TextResourceEditorInput); // Untyped Input (diff) input = service.createEditorInput({ @@ -392,7 +392,7 @@ suite('EditorService', () => { const ed = instantiationService.createInstance(MyEditor, 'my.editor'); - const inp = instantiationService.createInstance(ResourceEditorInput, URI.parse('my://resource-delegate'), 'name', 'description', undefined); + const inp = instantiationService.createInstance(TextResourceEditorInput, URI.parse('my://resource-delegate'), 'name', 'description', undefined); const delegate = instantiationService.createInstance(DelegatingEditorService, async (group, delegate) => { assert.ok(group); diff --git a/src/vs/workbench/services/preferences/browser/preferencesEditorInput.ts b/src/vs/workbench/services/preferences/browser/preferencesEditorInput.ts index ccd36b4131d..6ab3d05f12a 100644 --- a/src/vs/workbench/services/preferences/browser/preferencesEditorInput.ts +++ b/src/vs/workbench/services/preferences/browser/preferencesEditorInput.ts @@ -9,16 +9,14 @@ import { ITextModelService } from 'vs/editor/common/services/resolverService'; import * as nls from 'vs/nls'; import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation'; import { EditorInput, SideBySideEditorInput, Verbosity } from 'vs/workbench/common/editor'; -import { ResourceEditorInput } from 'vs/workbench/common/editor/resourceEditorInput'; +import { TextResourceEditorInput } from 'vs/workbench/common/editor/textResourceEditorInput'; import { KeybindingsEditorModel } from 'vs/workbench/services/preferences/browser/keybindingsEditorModel'; import { IPreferencesService } from 'vs/workbench/services/preferences/common/preferences'; import { Settings2EditorModel } from 'vs/workbench/services/preferences/common/preferencesModels'; import { ITextFileService } from 'vs/workbench/services/textfile/common/textfiles'; import { IEditorService } from 'vs/workbench/services/editor/common/editorService'; -import { IEditorGroupsService } from 'vs/workbench/services/editor/common/editorGroupsService'; import { IFileService } from 'vs/platform/files/common/files'; import { ILabelService } from 'vs/platform/label/common/label'; -import { IFilesConfigurationService } from 'vs/workbench/services/filesConfiguration/common/filesConfigurationService'; import { Schemas } from 'vs/base/common/network'; export class PreferencesEditorInput extends SideBySideEditorInput { @@ -33,19 +31,17 @@ export class PreferencesEditorInput extends SideBySideEditorInput { } } -export class DefaultPreferencesEditorInput extends ResourceEditorInput { +export class DefaultPreferencesEditorInput extends TextResourceEditorInput { static override readonly ID = 'workbench.editorinputs.defaultpreferences'; constructor( defaultSettingsResource: URI, @ITextModelService textModelResolverService: ITextModelService, @ITextFileService textFileService: ITextFileService, @IEditorService editorService: IEditorService, - @IEditorGroupsService editorGroupService: IEditorGroupsService, @IFileService fileService: IFileService, - @ILabelService labelService: ILabelService, - @IFilesConfigurationService filesConfigurationService: IFilesConfigurationService + @ILabelService labelService: ILabelService ) { - super(defaultSettingsResource, nls.localize('settingsEditorName', "Default Settings"), '', undefined, textModelResolverService, textFileService, editorService, editorGroupService, fileService, labelService, filesConfigurationService); + super(defaultSettingsResource, nls.localize('settingsEditorName', "Default Settings"), '', undefined, textModelResolverService, textFileService, editorService, fileService, labelService); } override get typeId(): string { diff --git a/src/vs/workbench/services/textmodelResolver/common/textModelResolverService.ts b/src/vs/workbench/services/textmodelResolver/common/textModelResolverService.ts index e924b129cf2..0e811562e70 100644 --- a/src/vs/workbench/services/textmodelResolver/common/textModelResolverService.ts +++ b/src/vs/workbench/services/textmodelResolver/common/textModelResolverService.ts @@ -8,7 +8,7 @@ import { IInstantiationService } from 'vs/platform/instantiation/common/instanti import { ITextModel } from 'vs/editor/common/model'; import { IDisposable, toDisposable, IReference, ReferenceCollection, Disposable } from 'vs/base/common/lifecycle'; import { IModelService } from 'vs/editor/common/services/modelService'; -import { ResourceEditorModel } from 'vs/workbench/common/editor/resourceEditorModel'; +import { TextResourceEditorModel } from 'vs/workbench/common/editor/textResourceEditorModel'; import { ITextFileService, TextFileResolveReason } from 'vs/workbench/services/textfile/common/textfiles'; import { Schemas } from 'vs/base/common/network'; import { ITextModelService, ITextModelContentProvider, ITextEditorModel, IResolvedTextEditorModel } from 'vs/editor/common/services/resolverService'; @@ -50,7 +50,7 @@ class ResourceModelCollection extends ReferenceCollection { }); let resource = URI.from({ scheme: 'test', authority: null!, path: 'thePath' }); - let input: ResourceEditorInput = instantiationService.createInstance(ResourceEditorInput, resource, 'The Name', 'The Description', undefined); + let input = instantiationService.createInstance(TextResourceEditorInput, resource, 'The Name', 'The Description', undefined); const model = await input.resolve(); assert.ok(model); - assert.strictEqual(snapshotToString(((model as ResourceEditorModel).createSnapshot()!)), 'Hello Test'); + assert.strictEqual(snapshotToString(((model as TextResourceEditorModel).createSnapshot()!)), 'Hello Test'); let disposed = false; let disposedPromise = new Promise(resolve => { Event.once(model.onWillDispose)(() => { diff --git a/src/vs/workbench/services/untitled/common/untitledTextEditorInput.ts b/src/vs/workbench/services/untitled/common/untitledTextEditorInput.ts index 21eb878481d..f7c7af6cc9e 100644 --- a/src/vs/workbench/services/untitled/common/untitledTextEditorInput.ts +++ b/src/vs/workbench/services/untitled/common/untitledTextEditorInput.ts @@ -9,9 +9,7 @@ import { IUntitledTextEditorModel } from 'vs/workbench/services/untitled/common/ import { EncodingMode, IEncodingSupport, IModeSupport, ITextFileService } from 'vs/workbench/services/textfile/common/textfiles'; import { ILabelService } from 'vs/platform/label/common/label'; import { IEditorService } from 'vs/workbench/services/editor/common/editorService'; -import { IEditorGroupsService } from 'vs/workbench/services/editor/common/editorGroupsService'; import { IFileService } from 'vs/platform/files/common/files'; -import { IFilesConfigurationService } from 'vs/workbench/services/filesConfiguration/common/filesConfigurationService'; import { isEqual } from 'vs/base/common/resources'; /** @@ -32,11 +30,9 @@ export class UntitledTextEditorInput extends AbstractTextResourceEditorInput imp @ITextFileService textFileService: ITextFileService, @ILabelService labelService: ILabelService, @IEditorService editorService: IEditorService, - @IEditorGroupsService editorGroupService: IEditorGroupsService, - @IFileService fileService: IFileService, - @IFilesConfigurationService filesConfigurationService: IFilesConfigurationService + @IFileService fileService: IFileService ) { - super(model.resource, undefined, editorService, editorGroupService, textFileService, labelService, fileService, filesConfigurationService); + super(model.resource, undefined, editorService, textFileService, labelService, fileService); this.registerModelListeners(model); } @@ -55,7 +51,7 @@ export class UntitledTextEditorInput extends AbstractTextResourceEditorInput imp return this.model.name; } - override getDescription(verbosity: Verbosity = Verbosity.MEDIUM): string | undefined { + override getDescription(verbosity = Verbosity.MEDIUM): string | undefined { // Without associated path: only use if name and description differ if (!this.model.hasAssociatedFilePath) { diff --git a/src/vs/workbench/test/browser/parts/editor/editorDiffModel.test.ts b/src/vs/workbench/test/browser/parts/editor/editorDiffModel.test.ts index 4b2853494b2..bfd93f0e3d5 100644 --- a/src/vs/workbench/test/browser/parts/editor/editorDiffModel.test.ts +++ b/src/vs/workbench/test/browser/parts/editor/editorDiffModel.test.ts @@ -6,7 +6,7 @@ import * as assert from 'assert'; import { TextDiffEditorModel } from 'vs/workbench/common/editor/textDiffEditorModel'; import { DiffEditorInput } from 'vs/workbench/common/editor/diffEditorInput'; -import { ResourceEditorInput } from 'vs/workbench/common/editor/resourceEditorInput'; +import { TextResourceEditorInput } from 'vs/workbench/common/editor/textResourceEditorInput'; import { URI } from 'vs/base/common/uri'; import { workbenchInstantiationService, TestServiceAccessor } from 'vs/workbench/test/browser/workbenchTestServices'; import { ITextModel } from 'vs/editor/common/model'; @@ -36,8 +36,8 @@ suite('Workbench editor model', () => { } }); - let input = instantiationService.createInstance(ResourceEditorInput, URI.from({ scheme: 'test', authority: null!, path: 'thePath' }), 'name', 'description', undefined); - let otherInput = instantiationService.createInstance(ResourceEditorInput, URI.from({ scheme: 'test', authority: null!, path: 'thePath' }), 'name2', 'description', undefined); + let input = instantiationService.createInstance(TextResourceEditorInput, URI.from({ scheme: 'test', authority: null!, path: 'thePath' }), 'name', 'description', undefined); + let otherInput = instantiationService.createInstance(TextResourceEditorInput, URI.from({ scheme: 'test', authority: null!, path: 'thePath' }), 'name2', 'description', undefined); let diffInput = instantiationService.createInstance(DiffEditorInput, 'name', 'description', input, otherInput, undefined); let model = await diffInput.resolve() as TextDiffEditorModel; diff --git a/src/vs/workbench/test/browser/parts/editor/editorPane.test.ts b/src/vs/workbench/test/browser/parts/editor/editorPane.test.ts index ec093fb0691..13460815c1c 100644 --- a/src/vs/workbench/test/browser/parts/editor/editorPane.test.ts +++ b/src/vs/workbench/test/browser/parts/editor/editorPane.test.ts @@ -12,7 +12,7 @@ import { SyncDescriptor } from 'vs/platform/instantiation/common/descriptors'; import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry'; import { NullTelemetryService } from 'vs/platform/telemetry/common/telemetryUtils'; import { workbenchInstantiationService, TestEditorGroupView, TestEditorGroupsService, registerTestResourceEditor, TestEditorInput } from 'vs/workbench/test/browser/workbenchTestServices'; -import { ResourceEditorInput } from 'vs/workbench/common/editor/resourceEditorInput'; +import { TextResourceEditorInput } from 'vs/workbench/common/editor/textResourceEditorInput'; import { TestThemeService } from 'vs/platform/theme/test/common/testThemeService'; import { URI } from 'vs/base/common/uri'; import { IEditorRegistry, EditorDescriptor } from 'vs/workbench/browser/editor'; @@ -94,7 +94,7 @@ class OtherTestInput extends EditorInput { return null; } } -class TestResourceEditorInput extends ResourceEditorInput { } +class TestResourceEditorInput extends TextResourceEditorInput { } suite('Workbench EditorPane', () => { @@ -165,7 +165,7 @@ suite('Workbench EditorPane', () => { const editor = EditorRegistry.getEditor(inst.createInstance(TestResourceEditorInput, URI.file('/fake'), 'fake', '', undefined))!.instantiate(inst); assert.strictEqual(editor.getId(), 'testEditor'); - const otherEditor = EditorRegistry.getEditor(inst.createInstance(ResourceEditorInput, URI.file('/fake'), 'fake', '', undefined))!.instantiate(inst); + const otherEditor = EditorRegistry.getEditor(inst.createInstance(TextResourceEditorInput, URI.file('/fake'), 'fake', '', undefined))!.instantiate(inst); assert.strictEqual(otherEditor.getId(), 'workbench.editors.textResourceEditor'); disposables.dispose(); diff --git a/src/vs/workbench/test/browser/parts/editor/resourceEditorInput.test.ts b/src/vs/workbench/test/browser/parts/editor/textResourceEditorInput.test.ts similarity index 76% rename from src/vs/workbench/test/browser/parts/editor/resourceEditorInput.test.ts rename to src/vs/workbench/test/browser/parts/editor/textResourceEditorInput.test.ts index 09baace30db..9adf64d6826 100644 --- a/src/vs/workbench/test/browser/parts/editor/resourceEditorInput.test.ts +++ b/src/vs/workbench/test/browser/parts/editor/textResourceEditorInput.test.ts @@ -5,8 +5,8 @@ import * as assert from 'assert'; import { URI } from 'vs/base/common/uri'; -import { ResourceEditorInput } from 'vs/workbench/common/editor/resourceEditorInput'; -import { ResourceEditorModel } from 'vs/workbench/common/editor/resourceEditorModel'; +import { TextResourceEditorInput } from 'vs/workbench/common/editor/textResourceEditorInput'; +import { TextResourceEditorModel } from 'vs/workbench/common/editor/textResourceEditorModel'; import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation'; import { workbenchInstantiationService, TestServiceAccessor } from 'vs/workbench/test/browser/workbenchTestServices'; import { snapshotToString } from 'vs/workbench/services/textfile/common/textfiles'; @@ -26,12 +26,12 @@ suite('Resource text editors', () => { const resource = URI.from({ scheme: 'inmemory', authority: null!, path: 'thePath' }); accessor.modelService.createModel('function test() {}', accessor.modeService.create('text'), resource); - const input: ResourceEditorInput = instantiationService.createInstance(ResourceEditorInput, resource, 'The Name', 'The Description', undefined); + const input = instantiationService.createInstance(TextResourceEditorInput, resource, 'The Name', 'The Description', undefined); const model = await input.resolve(); assert.ok(model); - assert.strictEqual(snapshotToString(((model as ResourceEditorModel).createSnapshot()!)), 'function test() {}'); + assert.strictEqual(snapshotToString(((model as TextResourceEditorModel).createSnapshot()!)), 'function test() {}'); }); test('custom mode', async () => { @@ -42,7 +42,7 @@ suite('Resource text editors', () => { const resource = URI.from({ scheme: 'inmemory', authority: null!, path: 'thePath' }); accessor.modelService.createModel('function test() {}', accessor.modeService.create('text'), resource); - const input: ResourceEditorInput = instantiationService.createInstance(ResourceEditorInput, resource, 'The Name', 'The Description', 'resource-input-test'); + const input = instantiationService.createInstance(TextResourceEditorInput, resource, 'The Name', 'The Description', 'resource-input-test'); const model = await input.resolve(); assert.ok(model); diff --git a/src/vs/workbench/test/browser/workbenchTestServices.ts b/src/vs/workbench/test/browser/workbenchTestServices.ts index 3d1b220b320..b02ce7c0a2a 100644 --- a/src/vs/workbench/test/browser/workbenchTestServices.ts +++ b/src/vs/workbench/test/browser/workbenchTestServices.ts @@ -119,7 +119,7 @@ import { FileService } from 'vs/platform/files/common/fileService'; import { TextResourceEditor } from 'vs/workbench/browser/parts/editor/textResourceEditor'; import { TestCodeEditor } from 'vs/editor/test/browser/testCodeEditor'; import { TextFileEditor } from 'vs/workbench/contrib/files/browser/editors/textFileEditor'; -import { ResourceEditorInput } from 'vs/workbench/common/editor/resourceEditorInput'; +import { TextResourceEditorInput } from 'vs/workbench/common/editor/textResourceEditorInput'; import { UntitledTextEditorInput } from 'vs/workbench/services/untitled/common/untitledTextEditorInput'; import { SideBySideEditor } from 'vs/workbench/browser/parts/editor/sideBySideEditor'; import { IEnterWorkspaceResult, IRecent, IRecentlyOpened, IWorkspaceFolderCreationData, IWorkspaceIdentifier, IWorkspacesService } from 'vs/platform/workspaces/common/workspaces'; @@ -1366,7 +1366,7 @@ export function registerTestResourceEditor(): IDisposable { ), [ new SyncDescriptor(UntitledTextEditorInput), - new SyncDescriptor(ResourceEditorInput) + new SyncDescriptor(TextResourceEditorInput) ] ));