Merge from vscode 1df23554b2e3d5f1efc6fbc76ee61d3f7f186c6d

This commit is contained in:
ADS Merger
2020-03-12 06:51:03 +00:00
parent a68a6b9e44
commit b5592959c7
56 changed files with 1091 additions and 558 deletions

View File

@@ -280,16 +280,7 @@ export class TextFileEditorModelManager extends Disposable implements ITextFileE
const newModel = model = this.instantiationService.createInstance(TextFileEditorModel, resource, options ? options.encoding : undefined, options ? options.mode : undefined);
modelPromise = model.load(options);
// Install model listeners
const modelListeners = new DisposableStore();
modelListeners.add(model.onDidLoad(reason => this._onDidLoad.fire({ model: newModel, reason })));
modelListeners.add(model.onDidChangeDirty(() => this._onDidChangeDirty.fire(newModel)));
modelListeners.add(model.onDidSaveError(() => this._onDidSaveError.fire(newModel)));
modelListeners.add(model.onDidSave(reason => this._onDidSave.fire({ model: newModel, reason })));
modelListeners.add(model.onDidRevert(() => this._onDidRevert.fire(newModel)));
modelListeners.add(model.onDidChangeEncoding(() => this._onDidChangeEncoding.fire(newModel)));
this.mapResourceToModelListeners.set(resource, modelListeners);
this.registerModel(newModel);
}
// Store pending loads to avoid race conditions
@@ -298,9 +289,15 @@ export class TextFileEditorModelManager extends Disposable implements ITextFileE
// Make known to manager (if not already known)
this.add(resource, model);
// Signal as event if we created the model
// Emit some events if we created the model
if (didCreateModel) {
this._onDidCreate.fire(model);
// If the model is dirty right from the beginning,
// make sure to emit this as an event
if (model.isDirty()) {
this._onDidChangeDirty.fire(model);
}
}
try {
@@ -335,6 +332,21 @@ export class TextFileEditorModelManager extends Disposable implements ITextFileE
}
}
private registerModel(model: TextFileEditorModel): void {
// Install model listeners
const modelListeners = new DisposableStore();
modelListeners.add(model.onDidLoad(reason => this._onDidLoad.fire({ model, reason })));
modelListeners.add(model.onDidChangeDirty(() => this._onDidChangeDirty.fire(model)));
modelListeners.add(model.onDidSaveError(() => this._onDidSaveError.fire(model)));
modelListeners.add(model.onDidSave(reason => this._onDidSave.fire({ model: model, reason })));
modelListeners.add(model.onDidRevert(() => this._onDidRevert.fire(model)));
modelListeners.add(model.onDidChangeEncoding(() => this._onDidChangeEncoding.fire(model)));
// Keep for disposal
this.mapResourceToModelListeners.set(model.resource, modelListeners);
}
add(resource: URI, model: TextFileEditorModel): void {
const knownModel = this.mapResourceToModel.get(resource);
if (knownModel === model) {

View File

@@ -219,11 +219,13 @@ export class UntitledTextEditorService extends Disposable implements IUntitledTe
}
private registerModel(model: UntitledTextEditorModel): void {
const modelDisposables = new DisposableStore();
modelDisposables.add(model.onDidChangeDirty(() => this._onDidChangeDirty.fire(model)));
modelDisposables.add(model.onDidChangeName(() => this._onDidChangeLabel.fire(model)));
modelDisposables.add(model.onDidChangeEncoding(() => this._onDidChangeEncoding.fire(model)));
modelDisposables.add(model.onDispose(() => this._onDidDispose.fire(model)));
// Install model listeners
const modelListeners = new DisposableStore();
modelListeners.add(model.onDidChangeDirty(() => this._onDidChangeDirty.fire(model)));
modelListeners.add(model.onDidChangeName(() => this._onDidChangeLabel.fire(model)));
modelListeners.add(model.onDidChangeEncoding(() => this._onDidChangeEncoding.fire(model)));
modelListeners.add(model.onDispose(() => this._onDidDispose.fire(model)));
// Remove from cache on dispose
Event.once(model.onDispose)(() => {
@@ -232,11 +234,17 @@ export class UntitledTextEditorService extends Disposable implements IUntitledTe
this.mapResourceToModel.delete(model.resource);
// Listeners
modelDisposables.dispose();
modelListeners.dispose();
});
// Add to cache
this.mapResourceToModel.set(model.resource, model);
// If the model is dirty right from the beginning,
// make sure to emit this as an event
if (model.isDirty()) {
this._onDidChangeDirty.fire(model);
}
}
}

View File

@@ -14,6 +14,7 @@ import { ModesRegistry, PLAINTEXT_MODE_ID } from 'vs/editor/common/modes/modesRe
import { IIdentifiedSingleEditOperation } from 'vs/editor/common/model';
import { Range } from 'vs/editor/common/core/range';
import { UntitledTextEditorInput } from 'vs/workbench/services/untitled/common/untitledTextEditorInput';
import { IUntitledTextEditorModel } from 'vs/workbench/services/untitled/common/untitledTextEditorModel';
suite('Untitled text editors', () => {
@@ -120,15 +121,23 @@ suite('Untitled text editors', () => {
const service = accessor.untitledTextEditorService;
const file = URI.file(join('C:\\', '/foo/file.txt'));
const untitled = instantiationService.createInstance(UntitledTextEditorInput, service.create({ associatedResource: file }));
let onDidChangeDirtyModel: IUntitledTextEditorModel | undefined = undefined;
const listener = service.onDidChangeDirty(model => {
onDidChangeDirtyModel = model;
});
const model = service.create({ associatedResource: file });
const untitled = instantiationService.createInstance(UntitledTextEditorInput, model);
assert.ok(untitled.isDirty());
assert.equal(model, onDidChangeDirtyModel);
const model = await untitled.resolve();
const resolvedModel = await untitled.resolve();
assert.ok(model.hasAssociatedFilePath);
assert.ok(resolvedModel.hasAssociatedFilePath);
assert.equal(untitled.isDirty(), true);
untitled.dispose();
listener.dispose();
});
test('no longer dirty when content gets empty (not with associated resource)', async () => {

View File

@@ -3,7 +3,7 @@
* Licensed under the Source EULA. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import { SyncStatus, ISettingsSyncService, IConflictSetting, SyncSource } from 'vs/platform/userDataSync/common/userDataSync';
import { SyncStatus, ISettingsSyncService, IConflictSetting, SyncResource } from 'vs/platform/userDataSync/common/userDataSync';
import { ISharedProcessService } from 'vs/platform/ipc/electron-browser/sharedProcessService';
import { Disposable } from 'vs/base/common/lifecycle';
import { Emitter, Event } from 'vs/base/common/event';
@@ -17,7 +17,7 @@ export class SettingsSyncService extends Disposable implements ISettingsSyncServ
private readonly channel: IChannel;
readonly resourceKey = 'settings';
readonly source = SyncSource.Settings;
readonly resource = SyncResource.Settings;
private _status: SyncStatus = SyncStatus.Uninitialized;
get status(): SyncStatus { return this._status; }

View File

@@ -3,7 +3,7 @@
* Licensed under the Source EULA. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import { ResourceKey, IResourceRefHandle, IUserDataSyncBackupStoreService } from 'vs/platform/userDataSync/common/userDataSync';
import { IResourceRefHandle, IUserDataSyncBackupStoreService, SyncResource } from 'vs/platform/userDataSync/common/userDataSync';
import { ISharedProcessService } from 'vs/platform/ipc/electron-browser/sharedProcessService';
import { IChannel } from 'vs/base/parts/ipc/common/ipc';
import { registerSingleton } from 'vs/platform/instantiation/common/extensions';
@@ -19,16 +19,16 @@ export class UserDataSyncBackupStoreService implements IUserDataSyncBackupStoreS
this.channel = sharedProcessService.getChannel('userDataSyncBackupStoreService');
}
backup(key: ResourceKey, content: string): Promise<void> {
backup(key: SyncResource, content: string): Promise<void> {
return this.channel.call('backup', [key, content]);
}
getAllRefs(key: ResourceKey): Promise<IResourceRefHandle[]> {
getAllRefs(key: SyncResource): Promise<IResourceRefHandle[]> {
return this.channel.call('getAllRefs', [key]);
}
resolveContent(key: ResourceKey, ref: string): Promise<string | null> {
resolveContent(key: SyncResource, ref: string): Promise<string | null> {
return this.channel.call('resolveContent', [key, ref]);
}

View File

@@ -3,7 +3,7 @@
* Licensed under the Source EULA. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import { SyncStatus, SyncSource, IUserDataSyncService, UserDataSyncError } from 'vs/platform/userDataSync/common/userDataSync';
import { SyncStatus, SyncResource, IUserDataSyncService, UserDataSyncError } from 'vs/platform/userDataSync/common/userDataSync';
import { ISharedProcessService } from 'vs/platform/ipc/electron-browser/sharedProcessService';
import { Disposable } from 'vs/base/common/lifecycle';
import { Emitter, Event } from 'vs/base/common/event';
@@ -23,20 +23,20 @@ export class UserDataSyncService extends Disposable implements IUserDataSyncServ
private _onDidChangeStatus: Emitter<SyncStatus> = this._register(new Emitter<SyncStatus>());
readonly onDidChangeStatus: Event<SyncStatus> = this._onDidChangeStatus.event;
get onDidChangeLocal(): Event<SyncSource> { return this.channel.listen<SyncSource>('onDidChangeLocal'); }
get onDidChangeLocal(): Event<SyncResource> { return this.channel.listen<SyncResource>('onDidChangeLocal'); }
private _conflictsSources: SyncSource[] = [];
get conflictsSources(): SyncSource[] { return this._conflictsSources; }
private _onDidChangeConflicts: Emitter<SyncSource[]> = this._register(new Emitter<SyncSource[]>());
readonly onDidChangeConflicts: Event<SyncSource[]> = this._onDidChangeConflicts.event;
private _conflictsSources: SyncResource[] = [];
get conflictsSources(): SyncResource[] { return this._conflictsSources; }
private _onDidChangeConflicts: Emitter<SyncResource[]> = this._register(new Emitter<SyncResource[]>());
readonly onDidChangeConflicts: Event<SyncResource[]> = this._onDidChangeConflicts.event;
private _lastSyncTime: number | undefined = undefined;
get lastSyncTime(): number | undefined { return this._lastSyncTime; }
private _onDidChangeLastSyncTime: Emitter<number> = this._register(new Emitter<number>());
readonly onDidChangeLastSyncTime: Event<number> = this._onDidChangeLastSyncTime.event;
private _onSyncErrors: Emitter<[SyncSource, UserDataSyncError][]> = this._register(new Emitter<[SyncSource, UserDataSyncError][]>());
readonly onSyncErrors: Event<[SyncSource, UserDataSyncError][]> = this._onSyncErrors.event;
private _onSyncErrors: Emitter<[SyncResource, UserDataSyncError][]> = this._register(new Emitter<[SyncResource, UserDataSyncError][]>());
readonly onSyncErrors: Event<[SyncResource, UserDataSyncError][]> = this._onSyncErrors.event;
constructor(
@ISharedProcessService sharedProcessService: ISharedProcessService
@@ -52,7 +52,7 @@ export class UserDataSyncService extends Disposable implements IUserDataSyncServ
return userDataSyncChannel.listen(event, arg);
}
};
this.channel.call<[SyncStatus, SyncSource[], number | undefined]>('_getInitialData').then(([status, conflicts, lastSyncTime]) => {
this.channel.call<[SyncStatus, SyncResource[], number | undefined]>('_getInitialData').then(([status, conflicts, lastSyncTime]) => {
this.updateStatus(status);
this.updateConflicts(conflicts);
if (lastSyncTime) {
@@ -61,8 +61,8 @@ export class UserDataSyncService extends Disposable implements IUserDataSyncServ
this._register(this.channel.listen<SyncStatus>('onDidChangeStatus')(status => this.updateStatus(status)));
this._register(this.channel.listen<number>('onDidChangeLastSyncTime')(lastSyncTime => this.updateLastSyncTime(lastSyncTime)));
});
this._register(this.channel.listen<SyncSource[]>('onDidChangeConflicts')(conflicts => this.updateConflicts(conflicts)));
this._register(this.channel.listen<[SyncSource, Error][]>('onSyncErrors')(errors => this._onSyncErrors.fire(errors.map(([source, error]) => ([source, UserDataSyncError.toUserDataSyncError(error)])))));
this._register(this.channel.listen<SyncResource[]>('onDidChangeConflicts')(conflicts => this.updateConflicts(conflicts)));
this._register(this.channel.listen<[SyncResource, Error][]>('onSyncErrors')(errors => this._onSyncErrors.fire(errors.map(([source, error]) => ([source, UserDataSyncError.toUserDataSyncError(error)])))));
}
pull(): Promise<void> {
@@ -73,7 +73,7 @@ export class UserDataSyncService extends Disposable implements IUserDataSyncServ
return this.channel.call('sync');
}
accept(source: SyncSource, content: string): Promise<void> {
accept(source: SyncResource, content: string): Promise<void> {
return this.channel.call('accept', [source, content]);
}
@@ -102,7 +102,7 @@ export class UserDataSyncService extends Disposable implements IUserDataSyncServ
this._onDidChangeStatus.fire(status);
}
private async updateConflicts(conflicts: SyncSource[]): Promise<void> {
private async updateConflicts(conflicts: SyncResource[]): Promise<void> {
this._conflictsSources = conflicts;
this._onDidChangeConflicts.fire(conflicts);
}

View File

@@ -3,7 +3,7 @@
* Licensed under the Source EULA. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import { SyncSource, IUserDataSyncStoreService, IUserDataSyncStore, getUserDataSyncStore, ResourceKey, IUserData, IUserDataManifest, IResourceRefHandle } from 'vs/platform/userDataSync/common/userDataSync';
import { SyncResource, IUserDataSyncStoreService, IUserDataSyncStore, getUserDataSyncStore, IUserData, IUserDataManifest, IResourceRefHandle } from 'vs/platform/userDataSync/common/userDataSync';
import { ISharedProcessService } from 'vs/platform/ipc/electron-browser/sharedProcessService';
import { IChannel } from 'vs/base/parts/ipc/common/ipc';
import { registerSingleton } from 'vs/platform/instantiation/common/extensions';
@@ -25,11 +25,11 @@ export class UserDataSyncStoreService implements IUserDataSyncStoreService {
this.userDataSyncStore = getUserDataSyncStore(productService, configurationService);
}
read(key: ResourceKey, oldValue: IUserData | null, source?: SyncSource): Promise<IUserData> {
read(key: SyncResource, oldValue: IUserData | null, source?: SyncResource): Promise<IUserData> {
throw new Error('Not Supported');
}
write(key: ResourceKey, content: string, ref: string | null, source?: SyncSource): Promise<string> {
write(key: SyncResource, content: string, ref: string | null, source?: SyncResource): Promise<string> {
throw new Error('Not Supported');
}
@@ -41,15 +41,15 @@ export class UserDataSyncStoreService implements IUserDataSyncStoreService {
throw new Error('Not Supported');
}
getAllRefs(key: ResourceKey): Promise<IResourceRefHandle[]> {
getAllRefs(key: SyncResource): Promise<IResourceRefHandle[]> {
return this.channel.call('getAllRefs', [key]);
}
resolveContent(key: ResourceKey, ref: string): Promise<string | null> {
resolveContent(key: SyncResource, ref: string): Promise<string | null> {
return this.channel.call('resolveContent', [key, ref]);
}
delete(key: ResourceKey): Promise<void> {
delete(key: SyncResource): Promise<void> {
return this.channel.call('delete', [key]);
}