chore(vscode): update to 1.56.0

This commit is contained in:
Akash Satheesan
2021-04-30 20:25:17 +05:30
1749 changed files with 88014 additions and 43316 deletions

View File

@@ -3,7 +3,6 @@
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import { IAction } from 'vs/base/common/actions';
import { Event } from 'vs/base/common/event';
export interface IComposite {
@@ -33,21 +32,6 @@ export interface IComposite {
*/
getTitle(): string | undefined;
/**
* Returns the primary actions of the composite.
*/
getActions(): ReadonlyArray<IAction>;
/**
* Returns the secondary actions of the composite.
*/
getSecondaryActions(): ReadonlyArray<IAction>;
/**
* Returns an array of actions to show in the context menu of the composite
*/
getContextMenuActions(): ReadonlyArray<IAction>;
/**
* Returns the underlying control of this composite.
*/

View File

@@ -13,7 +13,7 @@ import { IEditorModel, IEditorOptions, ITextEditorOptions, IBaseResourceEditorIn
import { IInstantiationService, IConstructorSignature0, ServicesAccessor, BrandedService } from 'vs/platform/instantiation/common/instantiation';
import { IContextKeyService, RawContextKey } from 'vs/platform/contextkey/common/contextkey';
import { Registry } from 'vs/platform/registry/common/platform';
import { ITextModel } from 'vs/editor/common/model';
import { IEncodingSupport, IModeSupport } from 'vs/workbench/services/textfile/common/textfiles';
import { GroupsOrder, IEditorGroup, IEditorGroupsService } from 'vs/workbench/services/editor/common/editorGroupsService';
import { ICompositeControl, IComposite } from 'vs/workbench/common/composite';
import { ActionRunner, IAction } from 'vs/base/common/actions';
@@ -24,6 +24,13 @@ import { ACTIVE_GROUP, IResourceEditorInputType, SIDE_GROUP } from 'vs/workbench
import { IRange } from 'vs/editor/common/core/range';
import { IExtUri } from 'vs/base/common/resources';
// Static values for editor contributions
export const EditorExtensions = {
Editors: 'workbench.contributions.editors',
Associations: 'workbench.editors.associations',
EditorInputFactories: 'workbench.contributions.editor.inputFactories'
};
// Editor State Context Keys
export const ActiveEditorDirtyContext = new RawContextKey<boolean>('activeEditorIsDirty', false, localize('activeEditorIsDirty', "Whether the active editor is dirty"));
export const ActiveEditorPinnedContext = new RawContextKey<boolean>('activeEditorIsNotPreview', false, localize('activeEditorIsNotPreview', "Whether the active editor is not in preview mode"));
@@ -175,6 +182,11 @@ export interface IEditorControl extends ICompositeControl { }
export interface IFileEditorInputFactory {
/**
* The type identifier of the file editor input.
*/
typeId: string;
/**
* Creates new new editor input capable of showing files.
*/
@@ -186,8 +198,19 @@ export interface IFileEditorInputFactory {
isFileEditorInput(obj: unknown): obj is IFileEditorInput;
}
/**
* @deprecated obsolete
*
* TODO@bpasero remove this API and users once the generic backup restorer has been removed
*/
export interface ICustomEditorInputFactory {
/**
* @deprecated obsolete
*/
createCustomEditorInput(resource: URI, instantiationService: IInstantiationService): Promise<IEditorInput>;
/**
* @deprecated obsolete
*/
canResolveBackup(editorInput: IEditorInput, backupResource: URI): boolean;
}
@@ -205,29 +228,33 @@ export interface IEditorInputFactoryRegistry {
/**
* Registers the custom editor input factory to use for custom inputs.
*
* @deprecated obsolete
*/
registerCustomEditorInputFactory(scheme: string, factory: ICustomEditorInputFactory): void;
/**
* Returns the custom editor input factory to use for custom inputs.
*
* @deprecated obsolete
*/
getCustomEditorInputFactory(scheme: string): ICustomEditorInputFactory | undefined;
/**
* Registers a editor input factory for the given editor input to the registry. An editor input factory
* is capable of serializing and deserializing editor inputs from string data.
* Registers a editor input serializer for the given editor input to the registry.
* An editor input serializer is capable of serializing and deserializing editor
* inputs from string data.
*
* @param editorInputId the identifier of the editor input
* @param factory the editor input factory for serialization/deserialization
* @param editorInputTypeId the type identifier of the editor input
* @param serializer the editor input serializer for serialization/deserialization
*/
registerEditorInputFactory<Services extends BrandedService[]>(editorInputId: string, ctor: { new(...Services: Services): IEditorInputFactory }): IDisposable;
registerEditorInputSerializer<Services extends BrandedService[]>(editorInputTypeId: string, ctor: { new(...Services: Services): IEditorInputSerializer }): IDisposable;
/**
* Returns the editor input factory for the given editor input.
*
* @param editorInputId the identifier of the editor input
* Returns the editor input serializer for the given editor input.
*/
getEditorInputFactory(editorInputId: string): IEditorInputFactory | undefined;
getEditorInputSerializer(editorInput: IEditorInput): IEditorInputSerializer | undefined;
getEditorInputSerializer(editorInputTypeId: string): IEditorInputSerializer | undefined;
/**
* Starts the registry by providing the required services.
@@ -235,10 +262,10 @@ export interface IEditorInputFactoryRegistry {
start(accessor: ServicesAccessor): void;
}
export interface IEditorInputFactory {
export interface IEditorInputSerializer {
/**
* Determines whether the given editor input can be serialized by the factory.
* Determines whether the given editor input can be serialized by the serializer.
*/
canSerialize(editorInput: IEditorInput): boolean;
@@ -373,9 +400,9 @@ export interface IMoveResult {
export interface IEditorInput extends IDisposable {
/**
* Triggered when this input is disposed.
* Triggered when this input is about to be disposed.
*/
readonly onDispose: Event<void>;
readonly onWillDispose: Event<void>;
/**
* Triggered when this input changes its dirty state.
@@ -387,6 +414,14 @@ export interface IEditorInput extends IDisposable {
*/
readonly onDidChangeLabel: Event<void>;
/**
* Unique type identifier for this inpput. Every editor input of the
* same class should share the same type identifier. The type identifier
* is used for example for serialising/deserialising editor inputs
* via the serialisers of the `IEditorInputFactoryRegistry`.
*/
readonly typeId: string;
/**
* Returns the optional associated resource of this input.
*
@@ -400,11 +435,6 @@ export interface IEditorInput extends IDisposable {
*/
readonly resource: URI | undefined;
/**
* Unique type identifier for this inpput.
*/
getTypeId(): string;
/**
* Returns the display name of this input.
*/
@@ -495,7 +525,7 @@ export interface IEditorInput extends IDisposable {
/**
* Subclasses can set this to false if it does not make sense to split the editor input.
*/
supportsSplitEditor(): boolean;
canSplit(): boolean;
/**
* Returns if the other object matches this input.
@@ -506,6 +536,11 @@ export interface IEditorInput extends IDisposable {
* Returns if this editor is disposed.
*/
isDisposed(): boolean;
/**
* Returns a copy of the current editor input. Used when we can't just reuse the input
*/
copy(): IEditorInput;
}
/**
@@ -520,17 +555,17 @@ export abstract class EditorInput extends Disposable implements IEditorInput {
protected readonly _onDidChangeLabel = this._register(new Emitter<void>());
readonly onDidChangeLabel = this._onDidChangeLabel.event;
private readonly _onDispose = this._register(new Emitter<void>());
readonly onDispose = this._onDispose.event;
private readonly _onWillDispose = this._register(new Emitter<void>());
readonly onWillDispose = this._onWillDispose.event;
private disposed: boolean = false;
abstract get typeId(): string;
abstract get resource(): URI | undefined;
abstract getTypeId(): string;
getName(): string {
return `Editor ${this.getTypeId()}`;
return `Editor ${this.typeId}`;
}
getDescription(verbosity?: Verbosity): string | undefined {
@@ -564,7 +599,7 @@ export abstract class EditorInput extends Disposable implements IEditorInput {
"typeId" : { "classification": "SystemMetaData", "purpose": "FeatureInsight" }
}
*/
return { typeId: this.getTypeId() };
return { typeId: this.typeId };
}
isReadonly(): boolean {
@@ -601,7 +636,7 @@ export abstract class EditorInput extends Disposable implements IEditorInput {
return undefined;
}
supportsSplitEditor(): boolean {
canSplit(): boolean {
return true;
}
@@ -609,54 +644,24 @@ export abstract class EditorInput extends Disposable implements IEditorInput {
return this === otherInput;
}
copy(): IEditorInput {
return this;
}
isDisposed(): boolean {
return this.disposed;
}
dispose(): void {
override dispose(): void {
if (!this.disposed) {
this.disposed = true;
this._onDispose.fire();
this._onWillDispose.fire();
}
super.dispose();
}
}
export const enum EncodingMode {
/**
* Instructs the encoding support to encode the current input with the provided encoding
*/
Encode,
/**
* Instructs the encoding support to decode the current input with the provided encoding
*/
Decode
}
export interface IEncodingSupport {
/**
* Gets the encoding of the type if known.
*/
getEncoding(): string | undefined;
/**
* Sets the encoding for the type for saving.
*/
setEncoding(encoding: string, mode: EncodingMode): void;
}
export interface IModeSupport {
/**
* Sets the language mode of the type.
*/
setMode(mode: string): void;
}
export interface IEditorInputWithPreferredResource {
/**
@@ -750,6 +755,10 @@ export class SideBySideEditorInput extends EditorInput {
static readonly ID: string = 'workbench.editorinputs.sidebysideEditorInput';
override get typeId(): string {
return SideBySideEditorInput.ID;
}
constructor(
protected readonly name: string | undefined,
protected readonly description: string | undefined,
@@ -764,14 +773,14 @@ export class SideBySideEditorInput extends EditorInput {
private registerListeners(): void {
// When the primary or secondary input gets disposed, dispose this diff editor input
const onceSecondaryDisposed = Event.once(this.secondary.onDispose);
const onceSecondaryDisposed = Event.once(this.secondary.onWillDispose);
this._register(onceSecondaryDisposed(() => {
if (!this.isDisposed()) {
this.dispose();
}
}));
const oncePrimaryDisposed = Event.once(this.primary.onDispose);
const oncePrimaryDisposed = Event.once(this.primary.onWillDispose);
this._register(oncePrimaryDisposed(() => {
if (!this.isDisposed()) {
this.dispose();
@@ -799,11 +808,7 @@ export class SideBySideEditorInput extends EditorInput {
return this._secondary;
}
getTypeId(): string {
return SideBySideEditorInput.ID;
}
getName(): string {
override getName(): string {
if (!this.name) {
return localize('sideBySideLabels', "{0} - {1}", this._secondary.getName(), this._primary.getName());
}
@@ -811,45 +816,45 @@ export class SideBySideEditorInput extends EditorInput {
return this.name;
}
getDescription(): string | undefined {
override getDescription(): string | undefined {
return this.description;
}
isReadonly(): boolean {
override isReadonly(): boolean {
return this.primary.isReadonly();
}
isUntitled(): boolean {
override isUntitled(): boolean {
return this.primary.isUntitled();
}
isDirty(): boolean {
override isDirty(): boolean {
return this.primary.isDirty();
}
isSaving(): boolean {
override isSaving(): boolean {
return this.primary.isSaving();
}
save(group: GroupIdentifier, options?: ISaveOptions): Promise<IEditorInput | undefined> {
override save(group: GroupIdentifier, options?: ISaveOptions): Promise<IEditorInput | undefined> {
return this.primary.save(group, options);
}
saveAs(group: GroupIdentifier, options?: ISaveOptions): Promise<IEditorInput | undefined> {
override saveAs(group: GroupIdentifier, options?: ISaveOptions): Promise<IEditorInput | undefined> {
return this.primary.saveAs(group, options);
}
revert(group: GroupIdentifier, options?: IRevertOptions): Promise<void> {
override revert(group: GroupIdentifier, options?: IRevertOptions): Promise<void> {
return this.primary.revert(group, options);
}
getTelemetryDescriptor(): { [key: string]: unknown } {
override getTelemetryDescriptor(): { [key: string]: unknown } {
const descriptor = this.primary.getTelemetryDescriptor();
return Object.assign(descriptor, super.getTelemetryDescriptor());
}
matches(otherInput: unknown): boolean {
override matches(otherInput: unknown): boolean {
if (otherInput === this) {
return true;
}
@@ -862,34 +867,31 @@ export class SideBySideEditorInput extends EditorInput {
}
}
export interface ITextEditorModel extends IEditorModel {
textEditorModel: ITextModel;
}
/**
* The editor model is the heavyweight counterpart of editor input. Depending on the editor input, it
* connects to the disk to retrieve content and may allow for saving it back or reverting it. Editor models
* are typically cached for some while because they are expensive to construct.
* resolves from a file system retrieve content and may allow for saving it back or reverting it.
* Editor models are typically cached for some while because they are expensive to construct.
*/
export class EditorModel extends Disposable implements IEditorModel {
private readonly _onDispose = this._register(new Emitter<void>());
readonly onDispose = this._onDispose.event;
private readonly _onWillDispose = this._register(new Emitter<void>());
readonly onWillDispose = this._onWillDispose.event;
private disposed = false;
private resolved = false;
/**
* Causes this model to load returning a promise when loading is completed.
* Causes this model to resolve returning a promise when loading is completed.
*/
async load(): Promise<IEditorModel> {
return this;
async resolve(): Promise<void> {
this.resolved = true;
}
/**
* Returns whether this model was loaded or not.
*/
isResolved(): boolean {
return true;
return this.resolved;
}
/**
@@ -902,9 +904,9 @@ export class EditorModel extends Disposable implements IEditorModel {
/**
* Subclasses should implement to free resources that have been claimed through loading.
*/
dispose(): void {
override dispose(): void {
this.disposed = true;
this._onDispose.fire();
this._onWillDispose.fire();
super.dispose();
}
@@ -915,6 +917,10 @@ export interface IEditorInputWithOptions {
options?: IEditorOptions | ITextEditorOptions;
}
export interface IEditorInputWithOptionsAndGroup extends IEditorInputWithOptions {
group?: IEditorGroup;
}
export function isEditorInputWithOptions(obj: unknown): obj is IEditorInputWithOptions {
const editorInputWithOptions = obj as IEditorInputWithOptions;
@@ -1110,7 +1116,7 @@ export class TextEditorOptions extends EditorOptions implements ITextEditorOptio
/**
* Helper to convert options bag to real class
*/
static create(options: ITextEditorOptions = Object.create(null)): TextEditorOptions {
static override create(options: ITextEditorOptions = Object.create(null)): TextEditorOptions {
const textEditorOptions = new TextEditorOptions();
textEditorOptions.overwrite(options);
@@ -1120,7 +1126,7 @@ export class TextEditorOptions extends EditorOptions implements ITextEditorOptio
/**
* Overwrites option values from the provided bag.
*/
overwrite(options: ITextEditorOptions): TextEditorOptions {
override overwrite(options: ITextEditorOptions): TextEditorOptions {
super.overwrite(options);
if (options.selection) {
@@ -1243,7 +1249,7 @@ export class EditorCommandsContextActionRunner extends ActionRunner {
super();
}
run(action: IAction): Promise<void> {
override run(action: IAction): Promise<void> {
return super.run(action, this.context);
}
}
@@ -1254,6 +1260,10 @@ export interface IEditorCloseEvent extends IEditorIdentifier {
sticky: boolean;
}
export interface IEditorMoveEvent extends IEditorIdentifier {
target: GroupIdentifier;
}
export type GroupIdentifier = number;
export interface IWorkbenchEditorConfiguration {
@@ -1463,29 +1473,33 @@ export interface IEditorMemento<T> {
class EditorInputFactoryRegistry implements IEditorInputFactoryRegistry {
private instantiationService: IInstantiationService | undefined;
private fileEditorInputFactory: IFileEditorInputFactory | undefined;
private readonly editorInputFactoryConstructors: Map<string, IConstructorSignature0<IEditorInputFactory>> = new Map();
private readonly editorInputFactoryInstances: Map<string, IEditorInputFactory> = new Map();
private readonly customEditorInputFactoryInstances: Map<string, ICustomEditorInputFactory> = new Map();
private readonly editorInputSerializerConstructors: Map<string /* Type ID */, IConstructorSignature0<IEditorInputSerializer>> = new Map();
private readonly editorInputSerializerInstances: Map<string /* Type ID */, IEditorInputSerializer> = new Map();
start(accessor: ServicesAccessor): void {
const instantiationService = this.instantiationService = accessor.get(IInstantiationService);
this.editorInputFactoryConstructors.forEach((ctor, key) => {
this.createEditorInputFactory(key, ctor, instantiationService);
});
for (const [key, ctor] of this.editorInputSerializerConstructors) {
this.createEditorInputSerializer(key, ctor, instantiationService);
}
this.editorInputFactoryConstructors.clear();
this.editorInputSerializerConstructors.clear();
}
private createEditorInputFactory(editorInputId: string, ctor: IConstructorSignature0<IEditorInputFactory>, instantiationService: IInstantiationService): void {
private createEditorInputSerializer(editorInputTypeId: string, ctor: IConstructorSignature0<IEditorInputSerializer>, instantiationService: IInstantiationService): void {
const instance = instantiationService.createInstance(ctor);
this.editorInputFactoryInstances.set(editorInputId, instance);
this.editorInputSerializerInstances.set(editorInputTypeId, instance);
}
registerFileEditorInputFactory(factory: IFileEditorInputFactory): void {
if (this.fileEditorInputFactory) {
throw new Error('Can only register one file editor input factory.');
}
this.fileEditorInputFactory = factory;
}
@@ -1493,6 +1507,29 @@ class EditorInputFactoryRegistry implements IEditorInputFactoryRegistry {
return assertIsDefined(this.fileEditorInputFactory);
}
registerEditorInputSerializer(editorInputTypeId: string, ctor: IConstructorSignature0<IEditorInputSerializer>): IDisposable {
if (this.editorInputSerializerConstructors.has(editorInputTypeId) || this.editorInputSerializerInstances.has(editorInputTypeId)) {
throw new Error(`A editor input serializer with type ID '${editorInputTypeId}' was already registered.`);
}
if (!this.instantiationService) {
this.editorInputSerializerConstructors.set(editorInputTypeId, ctor);
} else {
this.createEditorInputSerializer(editorInputTypeId, ctor, this.instantiationService);
}
return toDisposable(() => {
this.editorInputSerializerConstructors.delete(editorInputTypeId);
this.editorInputSerializerInstances.delete(editorInputTypeId);
});
}
getEditorInputSerializer(editorInput: IEditorInput): IEditorInputSerializer | undefined;
getEditorInputSerializer(editorInputTypeId: string): IEditorInputSerializer | undefined;
getEditorInputSerializer(arg1: string | IEditorInput): IEditorInputSerializer | undefined {
return this.editorInputSerializerInstances.get(typeof arg1 === 'string' ? arg1 : arg1.typeId);
}
registerCustomEditorInputFactory(scheme: string, factory: ICustomEditorInputFactory): void {
this.customEditorInputFactoryInstances.set(scheme, factory);
}
@@ -1500,30 +1537,9 @@ class EditorInputFactoryRegistry implements IEditorInputFactoryRegistry {
getCustomEditorInputFactory(scheme: string): ICustomEditorInputFactory | undefined {
return this.customEditorInputFactoryInstances.get(scheme);
}
registerEditorInputFactory(editorInputId: string, ctor: IConstructorSignature0<IEditorInputFactory>): IDisposable {
if (!this.instantiationService) {
this.editorInputFactoryConstructors.set(editorInputId, ctor);
} else {
this.createEditorInputFactory(editorInputId, ctor, this.instantiationService);
}
return toDisposable(() => {
this.editorInputFactoryConstructors.delete(editorInputId);
this.editorInputFactoryInstances.delete(editorInputId);
});
}
getEditorInputFactory(editorInputId: string): IEditorInputFactory | undefined {
return this.editorInputFactoryInstances.get(editorInputId);
}
}
export const Extensions = {
EditorInputFactories: 'workbench.contributions.editor.inputFactories'
};
Registry.add(Extensions.EditorInputFactories, new EditorInputFactoryRegistry());
Registry.add(EditorExtensions.EditorInputFactories, new EditorInputFactoryRegistry());
export async function pathsToEditors(paths: IPathData[] | undefined, fileService: IFileService): Promise<(IResourceEditorInput | IUntitledTextResourceEditorInput)[]> {
if (!paths || !paths.length) {
@@ -1579,29 +1595,6 @@ export const enum EditorsOrder {
SEQUENTIAL
}
export function computeEditorAriaLabel(input: IEditorInput, index: number | undefined, group: IEditorGroup | undefined, groupCount: number): string {
let ariaLabel = input.getAriaLabel();
if (group && !group.isPinned(input)) {
ariaLabel = localize('preview', "{0}, preview", ariaLabel);
}
if (group?.isSticky(index ?? input)) {
ariaLabel = localize('pinned', "{0}, pinned", ariaLabel);
}
// Apply group information to help identify in
// which group we are (only if more than one group
// is actually opened)
if (group && groupCount > 1) {
ariaLabel = `${ariaLabel}, ${group.ariaLabel}`;
}
return ariaLabel;
}
//#region Editor Group Column
/**
* A way to address editor groups through a column based system
* where `0` is the first column. Will fallback to `SIDE_GROUP`
@@ -1635,5 +1628,3 @@ export function editorGroupToViewColumn(editorGroupService: IEditorGroupsService
return editorGroupService.getGroups(GroupsOrder.GRID_APPEARANCE).indexOf(group);
}
//#endregion

View File

@@ -56,7 +56,7 @@ export class BinaryEditorModel extends EditorModel {
return this.etag;
}
async load(): Promise<BinaryEditorModel> {
override async resolve(): Promise<void> {
// Make sure to resolve up to date stat for file resources
if (this.fileService.canHandleResource(this.resource)) {
@@ -66,7 +66,5 @@ export class BinaryEditorModel extends EditorModel {
this.size = stat.size;
}
}
return this;
}
}

View File

@@ -21,13 +21,17 @@ import { withNullAsUndefined } from 'vs/base/common/types';
*/
export class DiffEditorInput extends SideBySideEditorInput {
static readonly ID = 'workbench.editors.diffEditorInput';
static override readonly ID = 'workbench.editors.diffEditorInput';
override get typeId(): string {
return DiffEditorInput.ID;
}
private cachedModel: DiffEditorModel | undefined = undefined;
constructor(
protected name: string | undefined,
protected description: string | undefined,
name: string | undefined,
description: string | undefined,
public readonly originalInput: EditorInput,
public readonly modifiedInput: EditorInput,
private readonly forceOpenAsBinary: boolean | undefined,
@@ -37,11 +41,7 @@ export class DiffEditorInput extends SideBySideEditorInput {
super(name, description, originalInput, modifiedInput);
}
getTypeId(): string {
return DiffEditorInput.ID;
}
getName(): string {
override getName(): string {
if (!this.name) {
// Craft a name from original and modified input that includes the
@@ -58,7 +58,7 @@ export class DiffEditorInput extends SideBySideEditorInput {
return this.name;
}
getDescription(verbosity: Verbosity = Verbosity.MEDIUM): string | undefined {
override getDescription(verbosity: Verbosity = Verbosity.MEDIUM): string | undefined {
if (typeof this.description !== 'string') {
// Pass the description of the modified side in case both original
@@ -88,7 +88,7 @@ export class DiffEditorInput extends SideBySideEditorInput {
return undefined;
}
async resolve(): Promise<EditorModel> {
override async resolve(): Promise<EditorModel> {
// Create Model - we never reuse our cached model if refresh is true because we cannot
// decide for the inputs within if the cached model can be reused or not. There may be
@@ -104,7 +104,7 @@ export class DiffEditorInput extends SideBySideEditorInput {
return this.cachedModel;
}
getPreferredEditorId(candidates: string[]): string {
override getPreferredEditorId(candidates: string[]): string {
return this.forceOpenAsBinary ? BINARY_DIFF_EDITOR_ID : TEXT_DIFF_EDITOR_ID;
}
@@ -125,7 +125,7 @@ export class DiffEditorInput extends SideBySideEditorInput {
return new DiffEditorModel(withNullAsUndefined(originalEditorModel), withNullAsUndefined(modifiedEditorModel));
}
matches(otherInput: unknown): boolean {
override matches(otherInput: unknown): boolean {
if (!super.matches(otherInput)) {
return false;
}
@@ -133,7 +133,7 @@ export class DiffEditorInput extends SideBySideEditorInput {
return otherInput instanceof DiffEditorInput && otherInput.forceOpenAsBinary === this.forceOpenAsBinary;
}
dispose(): void {
override dispose(): void {
// Free the diff editor model but do not propagate the dispose() call to the two inputs
// We never created the two inputs (original and modified) so we can not dispose

View File

@@ -25,20 +25,18 @@ export class DiffEditorModel extends EditorModel {
this._modifiedModel = modifiedModel;
}
async load(): Promise<EditorModel> {
override async resolve(): Promise<void> {
await Promise.all([
this._originalModel?.load(),
this._modifiedModel?.load()
this._originalModel?.resolve(),
this._modifiedModel?.resolve()
]);
return this;
}
isResolved(): boolean {
return this.originalModel instanceof EditorModel && this.originalModel.isResolved() && this.modifiedModel instanceof EditorModel && this.modifiedModel.isResolved();
override isResolved(): boolean {
return !!(this.originalModel?.isResolved() && this.modifiedModel?.isResolved());
}
dispose(): void {
override dispose(): void {
// Do not propagate the dispose() call to the two models inside. We never created the two models
// (original and modified) so we can not dispose them without sideeffects. Rather rely on the

View File

@@ -4,7 +4,7 @@
*--------------------------------------------------------------------------------------------*/
import { Event, Emitter } from 'vs/base/common/event';
import { Extensions, IEditorInputFactoryRegistry, EditorInput, IEditorIdentifier, IEditorCloseEvent, GroupIdentifier, SideBySideEditorInput, IEditorInput, EditorsOrder } from 'vs/workbench/common/editor';
import { IEditorInputFactoryRegistry, EditorInput, IEditorIdentifier, IEditorCloseEvent, GroupIdentifier, SideBySideEditorInput, IEditorInput, EditorsOrder, EditorExtensions } from 'vs/workbench/common/editor';
import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation';
import { IConfigurationService } from 'vs/platform/configuration/common/configuration';
import { dispose, Disposable, DisposableStore } from 'vs/base/common/lifecycle';
@@ -44,7 +44,7 @@ export interface ISerializedEditorInput {
readonly value: string;
}
export interface ISerializedEditorGroup {
export interface ISerializedEditorGroupModel {
readonly id: number;
readonly editors: ISerializedEditorInput[];
readonly mru: number[];
@@ -52,13 +52,13 @@ export interface ISerializedEditorGroup {
sticky?: number;
}
export function isSerializedEditorGroup(obj?: unknown): obj is ISerializedEditorGroup {
const group = obj as ISerializedEditorGroup;
export function isSerializedEditorGroupModel(obj?: unknown): obj is ISerializedEditorGroupModel {
const group = obj as ISerializedEditorGroupModel;
return !!(obj && typeof obj === 'object' && Array.isArray(group.editors) && Array.isArray(group.mru));
}
export class EditorGroup extends Disposable {
export class EditorGroupModel extends Disposable {
private static IDS = 0;
@@ -73,8 +73,8 @@ export class EditorGroup extends Disposable {
private readonly _onDidCloseEditor = this._register(new Emitter<EditorCloseEvent>());
readonly onDidCloseEditor = this._onDidCloseEditor.event;
private readonly _onDidDisposeEditor = this._register(new Emitter<EditorInput>());
readonly onDidDisposeEditor = this._onDidDisposeEditor.event;
private readonly _onWillDisposeEditor = this._register(new Emitter<EditorInput>());
readonly onWillDisposeEditor = this._onWillDisposeEditor.event;
private readonly _onDidChangeEditorDirty = this._register(new Emitter<EditorInput>());
readonly onDidChangeEditorDirty = this._onDidChangeEditorDirty.event;
@@ -107,16 +107,16 @@ export class EditorGroup extends Disposable {
private focusRecentEditorAfterClose: boolean | undefined;
constructor(
labelOrSerializedGroup: ISerializedEditorGroup | undefined,
labelOrSerializedGroup: ISerializedEditorGroupModel | undefined,
@IInstantiationService private readonly instantiationService: IInstantiationService,
@IConfigurationService private readonly configurationService: IConfigurationService
) {
super();
if (isSerializedEditorGroup(labelOrSerializedGroup)) {
if (isSerializedEditorGroupModel(labelOrSerializedGroup)) {
this._id = this.deserialize(labelOrSerializedGroup);
} else {
this._id = EditorGroup.IDS++;
this._id = EditorGroupModel.IDS++;
}
this.onConfigurationUpdated();
@@ -315,9 +315,9 @@ export class EditorGroup extends Disposable {
const listeners = new DisposableStore();
// Re-emit disposal of editor input as our own event
listeners.add(Event.once(editor.onDispose)(() => {
listeners.add(Event.once(editor.onWillDispose)(() => {
if (this.indexOf(editor) >= 0) {
this._onDidDisposeEditor.fire(editor);
this._onWillDisposeEditor.fire(editor);
}
}));
@@ -722,26 +722,26 @@ export class EditorGroup extends Disposable {
return editor.matches(candidate);
}
clone(): EditorGroup {
const group = this.instantiationService.createInstance(EditorGroup, undefined);
clone(): EditorGroupModel {
const clone = this.instantiationService.createInstance(EditorGroupModel, undefined);
// Copy over group properties
group.editors = this.editors.slice(0);
group.mru = this.mru.slice(0);
group.preview = this.preview;
group.active = this.active;
group.sticky = this.sticky;
clone.editors = this.editors.slice(0);
clone.mru = this.mru.slice(0);
clone.preview = this.preview;
clone.active = this.active;
clone.sticky = this.sticky;
// Ensure to register listeners for each editor
for (const editor of group.editors) {
group.registerEditorListeners(editor);
for (const editor of clone.editors) {
clone.registerEditorListeners(editor);
}
return group;
return clone;
}
serialize(): ISerializedEditorGroup {
const registry = Registry.as<IEditorInputFactoryRegistry>(Extensions.EditorInputFactories);
serialize(): ISerializedEditorGroupModel {
const registry = Registry.as<IEditorInputFactoryRegistry>(EditorExtensions.EditorInputFactories);
// Serialize all editor inputs so that we can store them.
// Editors that cannot be serialized need to be ignored
@@ -755,15 +755,15 @@ export class EditorGroup extends Disposable {
const editor = this.editors[i];
let canSerializeEditor = false;
const factory = registry.getEditorInputFactory(editor.getTypeId());
if (factory) {
const value = factory.serialize(editor);
const editorSerializer = registry.getEditorInputSerializer(editor);
if (editorSerializer) {
const value = editorSerializer.serialize(editor);
// Editor can be serialized
if (typeof value === 'string') {
canSerializeEditor = true;
serializedEditors.push({ id: editor.getTypeId(), value });
serializedEditors.push({ id: editor.typeId, value });
serializableEditors.push(editor);
if (this.preview === editor) {
@@ -794,23 +794,23 @@ export class EditorGroup extends Disposable {
};
}
private deserialize(data: ISerializedEditorGroup): number {
const registry = Registry.as<IEditorInputFactoryRegistry>(Extensions.EditorInputFactories);
private deserialize(data: ISerializedEditorGroupModel): number {
const registry = Registry.as<IEditorInputFactoryRegistry>(EditorExtensions.EditorInputFactories);
if (typeof data.id === 'number') {
this._id = data.id;
EditorGroup.IDS = Math.max(data.id + 1, EditorGroup.IDS); // make sure our ID generator is always larger
EditorGroupModel.IDS = Math.max(data.id + 1, EditorGroupModel.IDS); // make sure our ID generator is always larger
} else {
this._id = EditorGroup.IDS++; // backwards compatibility
this._id = EditorGroupModel.IDS++; // backwards compatibility
}
this.editors = coalesce(data.editors.map((e, index) => {
let editor: EditorInput | undefined = undefined;
const factory = registry.getEditorInputFactory(e.id);
if (factory) {
editor = factory.deserialize(this.instantiationService, e.value);
const editorSerializer = registry.getEditorInputSerializer(e.id);
if (editorSerializer) {
editor = editorSerializer.deserialize(this.instantiationService, e.value);
if (editor) {
this.registerEditorListeners(editor);
}

View File

@@ -3,12 +3,11 @@
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import { ITextEditorModel, IModeSupport } from 'vs/workbench/common/editor';
import { URI } from 'vs/base/common/uri';
import { IReference } from 'vs/base/common/lifecycle';
import { ITextModelService } from 'vs/editor/common/services/resolverService';
import { ITextEditorModel, ITextModelService } from 'vs/editor/common/services/resolverService';
import { ResourceEditorModel } from 'vs/workbench/common/editor/resourceEditorModel';
import { ITextFileService } from 'vs/workbench/services/textfile/common/textfiles';
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';
@@ -25,6 +24,10 @@ export class ResourceEditorInput extends AbstractTextResourceEditorInput impleme
static readonly ID: string = 'workbench.editors.resourceEditorInput';
override get typeId(): string {
return ResourceEditorInput.ID;
}
private cachedModel: ResourceEditorModel | undefined = undefined;
private modelReference: Promise<IReference<ITextEditorModel>> | undefined = undefined;
@@ -44,11 +47,7 @@ export class ResourceEditorInput extends AbstractTextResourceEditorInput impleme
super(resource, undefined, editorService, editorGroupService, textFileService, labelService, fileService, filesConfigurationService);
}
getTypeId(): string {
return ResourceEditorInput.ID;
}
getName(): string {
override getName(): string {
return this.name || super.getName();
}
@@ -60,7 +59,7 @@ export class ResourceEditorInput extends AbstractTextResourceEditorInput impleme
}
}
getDescription(): string | undefined {
override getDescription(): string | undefined {
return this.description;
}
@@ -84,7 +83,7 @@ export class ResourceEditorInput extends AbstractTextResourceEditorInput impleme
this.preferredMode = mode;
}
async resolve(): Promise<ITextEditorModel> {
override async resolve(): Promise<ITextEditorModel> {
if (!this.modelReference) {
this.modelReference = this.textModelResolverService.createModelReference(this.resource);
}
@@ -110,7 +109,7 @@ export class ResourceEditorInput extends AbstractTextResourceEditorInput impleme
return model;
}
matches(otherInput: unknown): boolean {
override matches(otherInput: unknown): boolean {
if (otherInput === this) {
return true;
}
@@ -122,7 +121,7 @@ export class ResourceEditorInput extends AbstractTextResourceEditorInput impleme
return false;
}
dispose(): void {
override dispose(): void {
if (this.modelReference) {
this.modelReference.then(ref => ref.dispose());
this.modelReference = undefined;

View File

@@ -21,7 +21,7 @@ export class ResourceEditorModel extends BaseTextEditorModel {
super(modelService, modeService, resource);
}
dispose(): void {
override dispose(): void {
// force this class to dispose the underlying model
if (this.textEditorModelHandle) {

View File

@@ -4,7 +4,6 @@
*--------------------------------------------------------------------------------------------*/
import { IDiffEditorModel } from 'vs/editor/common/editorCommon';
import { EditorModel } from 'vs/workbench/common/editor';
import { BaseTextEditorModel } from 'vs/workbench/common/editor/textEditorModel';
import { DiffEditorModel } from 'vs/workbench/common/editor/diffEditorModel';
@@ -14,11 +13,11 @@ import { DiffEditorModel } from 'vs/workbench/common/editor/diffEditorModel';
*/
export class TextDiffEditorModel extends DiffEditorModel {
protected readonly _originalModel: BaseTextEditorModel | undefined;
get originalModel(): BaseTextEditorModel | undefined { return this._originalModel; }
protected override readonly _originalModel: BaseTextEditorModel | undefined;
override get originalModel(): BaseTextEditorModel | undefined { return this._originalModel; }
protected readonly _modifiedModel: BaseTextEditorModel | undefined;
get modifiedModel(): BaseTextEditorModel | undefined { return this._modifiedModel; }
protected override readonly _modifiedModel: BaseTextEditorModel | undefined;
override get modifiedModel(): BaseTextEditorModel | undefined { return this._modifiedModel; }
private _textDiffEditorModel: IDiffEditorModel | undefined = undefined;
get textDiffEditorModel(): IDiffEditorModel | undefined { return this._textDiffEditorModel; }
@@ -32,12 +31,10 @@ export class TextDiffEditorModel extends DiffEditorModel {
this.updateTextDiffEditorModel();
}
async load(): Promise<EditorModel> {
await super.load();
override async resolve(): Promise<void> {
await super.resolve();
this.updateTextDiffEditorModel();
return this;
}
private updateTextDiffEditorModel(): void {
@@ -59,7 +56,7 @@ export class TextDiffEditorModel extends DiffEditorModel {
}
}
isResolved(): boolean {
override isResolved(): boolean {
return !!this._textDiffEditorModel;
}
@@ -67,7 +64,7 @@ export class TextDiffEditorModel extends DiffEditorModel {
return !!this.modifiedModel && this.modifiedModel.isReadonly();
}
dispose(): void {
override dispose(): void {
// Free the diff editor model but do not propagate the dispose() call to the two models
// inside. We never created the two models (original and modified) so we can not dispose

View File

@@ -4,7 +4,8 @@
*--------------------------------------------------------------------------------------------*/
import { ITextModel, ITextBufferFactory, ITextSnapshot, ModelConstants } from 'vs/editor/common/model';
import { EditorModel, IModeSupport } from 'vs/workbench/common/editor';
import { EditorModel } from 'vs/workbench/common/editor';
import { IModeSupport } from 'vs/workbench/services/textfile/common/textfiles';
import { URI } from 'vs/base/common/uri';
import { ITextEditorModel, IResolvedTextEditorModel } from 'vs/editor/common/services/resolverService';
import { IModeService, ILanguageSelection } from 'vs/editor/common/services/modeService';
@@ -167,11 +168,11 @@ export class BaseTextEditorModel extends EditorModel implements ITextEditorModel
return this.textEditorModel.createSnapshot(true /* preserve BOM */);
}
isResolved(): this is IResolvedTextEditorModel {
override isResolved(): this is IResolvedTextEditorModel {
return !!this.textEditorModelHandle;
}
dispose(): void {
override dispose(): void {
this.modelDisposeListener.dispose(); // dispose this first because it will trigger another dispose() otherwise
if (this.textEditorModelHandle && this.createdEditorModel) {

View File

@@ -77,7 +77,7 @@ export abstract class AbstractTextResourceEditorInput extends EditorInput implem
}
private _name: string | undefined = undefined;
getName(): string {
override getName(): string {
if (typeof this._name !== 'string') {
this._name = this.labelService.getUriBasenameLabel(this._preferredResource);
}
@@ -85,7 +85,7 @@ export abstract class AbstractTextResourceEditorInput extends EditorInput implem
return this._name;
}
getDescription(verbosity: Verbosity = Verbosity.MEDIUM): string | undefined {
override getDescription(verbosity: Verbosity = Verbosity.MEDIUM): string | undefined {
switch (verbosity) {
case Verbosity.SHORT:
return this.shortDescription;
@@ -151,7 +151,7 @@ export abstract class AbstractTextResourceEditorInput extends EditorInput implem
return this._longTitle;
}
getTitle(verbosity: Verbosity): string {
override getTitle(verbosity: Verbosity): string {
switch (verbosity) {
case Verbosity.SHORT:
return this.shortTitle;
@@ -163,14 +163,14 @@ export abstract class AbstractTextResourceEditorInput extends EditorInput implem
}
}
isUntitled(): boolean {
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);
}
isReadonly(): boolean {
override isReadonly(): boolean {
if (this.isUntitled()) {
return false; // untitled is never readonly
}
@@ -178,7 +178,7 @@ export abstract class AbstractTextResourceEditorInput extends EditorInput implem
return this.fileService.hasCapability(this.resource, FileSystemProviderCapabilities.Readonly);
}
isSaving(): boolean {
override isSaving(): boolean {
if (this.isUntitled()) {
return false; // untitled is never saving automatically
}
@@ -190,7 +190,7 @@ export abstract class AbstractTextResourceEditorInput extends EditorInput implem
return false;
}
save(group: GroupIdentifier, options?: ITextFileSaveOptions): Promise<IEditorInput | undefined> {
override save(group: GroupIdentifier, options?: ITextFileSaveOptions): Promise<IEditorInput | undefined> {
// If this is neither an `untitled` resource, nor a resource
// we can handle with the file service, we can only "Save As..."
@@ -202,7 +202,7 @@ export abstract class AbstractTextResourceEditorInput extends EditorInput implem
return this.doSave(options, false);
}
saveAs(group: GroupIdentifier, options?: ITextFileSaveOptions): Promise<IEditorInput | undefined> {
override saveAs(group: GroupIdentifier, options?: ITextFileSaveOptions): Promise<IEditorInput | undefined> {
return this.doSave(options, true);
}
@@ -233,7 +233,7 @@ export abstract class AbstractTextResourceEditorInput extends EditorInput implem
return this;
}
async revert(group: GroupIdentifier, options?: IRevertOptions): Promise<void> {
override async revert(group: GroupIdentifier, options?: IRevertOptions): Promise<void> {
await this.textFileService.revert(this.resource, options);
}
}

View File

@@ -275,6 +275,7 @@ export class NotificationsModel extends Disposable implements INotificationsMode
}
export interface INotificationViewItem {
readonly id: string | undefined;
readonly severity: Severity;
readonly sticky: boolean;
readonly silent: boolean;
@@ -468,7 +469,7 @@ export class NotificationViewItem extends Disposable implements INotificationVie
actions = { primary: notification.message.actions };
}
return new NotificationViewItem(severity, notification.sticky, notification.silent || filter === NotificationsFilter.SILENT || (filter === NotificationsFilter.ERROR && notification.severity !== Severity.Error), message, notification.source, notification.progress, actions);
return new NotificationViewItem(notification.id, severity, notification.sticky, notification.silent || filter === NotificationsFilter.SILENT || (filter === NotificationsFilter.ERROR && notification.severity !== Severity.Error), message, notification.source, notification.progress, actions);
}
private static parseNotificationMessage(input: NotificationMessage): INotificationMessage | undefined {
@@ -500,6 +501,7 @@ export class NotificationViewItem extends Disposable implements INotificationVie
}
private constructor(
readonly id: string | undefined,
private _severity: Severity,
private _sticky: boolean | undefined,
private _silent: boolean | undefined,
@@ -684,7 +686,15 @@ export class NotificationViewItem extends Disposable implements INotificationVie
return false;
}
if (this._source !== other.source) {
if (typeof this.id === 'string' || typeof other.id === 'string') {
return this.id === other.id;
}
if (typeof this._source === 'object') {
if (this._source.label !== other.source || this._source.id !== other.sourceId) {
return false;
}
} else if (this._source !== other.source) {
return false;
}
@@ -694,7 +704,7 @@ export class NotificationViewItem extends Disposable implements INotificationVie
const primaryActions = (this._actions && this._actions.primary) || [];
const otherPrimaryActions = (other.actions && other.actions.primary) || [];
return equals(primaryActions, otherPrimaryActions, (a, b) => (a.id + a.label) === (b.id + b.label));
return equals(primaryActions, otherPrimaryActions, (action, otherAction) => (action.id + action.label) === (otherAction.id + otherAction.label));
}
}