Merge branch 'master' into ben/electron-sandbox
This commit is contained in:
commit
76590a7764
|
@ -207,6 +207,7 @@
|
||||||
"vs/nls",
|
"vs/nls",
|
||||||
"**/vs/base/common/**",
|
"**/vs/base/common/**",
|
||||||
"**/vs/base/parts/*/common/**",
|
"**/vs/base/parts/*/common/**",
|
||||||
|
"**/vs/base/test/common/**",
|
||||||
"**/vs/platform/*/common/**",
|
"**/vs/platform/*/common/**",
|
||||||
"**/vs/platform/*/test/common/**"
|
"**/vs/platform/*/test/common/**"
|
||||||
]
|
]
|
||||||
|
|
211
src/vs/platform/undoRedo/test/common/undoRedoService.test.ts
Normal file
211
src/vs/platform/undoRedo/test/common/undoRedoService.test.ts
Normal file
|
@ -0,0 +1,211 @@
|
||||||
|
/*---------------------------------------------------------------------------------------------
|
||||||
|
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||||
|
* Licensed under the MIT License. See License.txt in the project root for license information.
|
||||||
|
*--------------------------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
import * as assert from 'assert';
|
||||||
|
import { UndoRedoService } from 'vs/platform/undoRedo/common/undoRedoService';
|
||||||
|
import { TestDialogService } from 'vs/platform/dialogs/test/common/testDialogService';
|
||||||
|
import { TestNotificationService } from 'vs/platform/notification/test/common/testNotificationService';
|
||||||
|
import { UndoRedoElementType, IUndoRedoElement } from 'vs/platform/undoRedo/common/undoRedo';
|
||||||
|
import { URI } from 'vs/base/common/uri';
|
||||||
|
import { mock } from 'vs/base/test/common/mock';
|
||||||
|
import { IDialogService } from 'vs/platform/dialogs/common/dialogs';
|
||||||
|
|
||||||
|
suite('UndoRedoService', () => {
|
||||||
|
|
||||||
|
function createUndoRedoService(dialogService: IDialogService = new TestDialogService()): UndoRedoService {
|
||||||
|
const notificationService = new TestNotificationService();
|
||||||
|
return new UndoRedoService(dialogService, notificationService);
|
||||||
|
}
|
||||||
|
|
||||||
|
test('simple single resource elements', () => {
|
||||||
|
const resource = URI.file('test.txt');
|
||||||
|
const service = createUndoRedoService();
|
||||||
|
|
||||||
|
assert.equal(service.canUndo(resource), false);
|
||||||
|
assert.equal(service.canRedo(resource), false);
|
||||||
|
assert.equal(service.hasElements(resource), false);
|
||||||
|
assert.ok(service.getLastElement(resource) === null);
|
||||||
|
|
||||||
|
let undoCall1 = 0;
|
||||||
|
let redoCall1 = 0;
|
||||||
|
const element1: IUndoRedoElement = {
|
||||||
|
type: UndoRedoElementType.Resource,
|
||||||
|
resource: resource,
|
||||||
|
label: 'typing 1',
|
||||||
|
undo: () => { undoCall1++; },
|
||||||
|
redo: () => { redoCall1++; }
|
||||||
|
};
|
||||||
|
service.pushElement(element1);
|
||||||
|
|
||||||
|
assert.equal(undoCall1, 0);
|
||||||
|
assert.equal(redoCall1, 0);
|
||||||
|
assert.equal(service.canUndo(resource), true);
|
||||||
|
assert.equal(service.canRedo(resource), false);
|
||||||
|
assert.equal(service.hasElements(resource), true);
|
||||||
|
assert.ok(service.getLastElement(resource) === element1);
|
||||||
|
|
||||||
|
service.undo(resource);
|
||||||
|
assert.equal(undoCall1, 1);
|
||||||
|
assert.equal(redoCall1, 0);
|
||||||
|
assert.equal(service.canUndo(resource), false);
|
||||||
|
assert.equal(service.canRedo(resource), true);
|
||||||
|
assert.equal(service.hasElements(resource), true);
|
||||||
|
assert.ok(service.getLastElement(resource) === null);
|
||||||
|
|
||||||
|
service.redo(resource);
|
||||||
|
assert.equal(undoCall1, 1);
|
||||||
|
assert.equal(redoCall1, 1);
|
||||||
|
assert.equal(service.canUndo(resource), true);
|
||||||
|
assert.equal(service.canRedo(resource), false);
|
||||||
|
assert.equal(service.hasElements(resource), true);
|
||||||
|
assert.ok(service.getLastElement(resource) === element1);
|
||||||
|
|
||||||
|
let undoCall2 = 0;
|
||||||
|
let redoCall2 = 0;
|
||||||
|
const element2: IUndoRedoElement = {
|
||||||
|
type: UndoRedoElementType.Resource,
|
||||||
|
resource: resource,
|
||||||
|
label: 'typing 2',
|
||||||
|
undo: () => { undoCall2++; },
|
||||||
|
redo: () => { redoCall2++; }
|
||||||
|
};
|
||||||
|
service.pushElement(element2);
|
||||||
|
|
||||||
|
assert.equal(undoCall1, 1);
|
||||||
|
assert.equal(redoCall1, 1);
|
||||||
|
assert.equal(undoCall2, 0);
|
||||||
|
assert.equal(redoCall2, 0);
|
||||||
|
assert.equal(service.canUndo(resource), true);
|
||||||
|
assert.equal(service.canRedo(resource), false);
|
||||||
|
assert.equal(service.hasElements(resource), true);
|
||||||
|
assert.ok(service.getLastElement(resource) === element2);
|
||||||
|
|
||||||
|
service.undo(resource);
|
||||||
|
|
||||||
|
assert.equal(undoCall1, 1);
|
||||||
|
assert.equal(redoCall1, 1);
|
||||||
|
assert.equal(undoCall2, 1);
|
||||||
|
assert.equal(redoCall2, 0);
|
||||||
|
assert.equal(service.canUndo(resource), true);
|
||||||
|
assert.equal(service.canRedo(resource), true);
|
||||||
|
assert.equal(service.hasElements(resource), true);
|
||||||
|
assert.ok(service.getLastElement(resource) === null);
|
||||||
|
|
||||||
|
let undoCall3 = 0;
|
||||||
|
let redoCall3 = 0;
|
||||||
|
const element3: IUndoRedoElement = {
|
||||||
|
type: UndoRedoElementType.Resource,
|
||||||
|
resource: resource,
|
||||||
|
label: 'typing 2',
|
||||||
|
undo: () => { undoCall3++; },
|
||||||
|
redo: () => { redoCall3++; }
|
||||||
|
};
|
||||||
|
service.pushElement(element3);
|
||||||
|
|
||||||
|
assert.equal(undoCall1, 1);
|
||||||
|
assert.equal(redoCall1, 1);
|
||||||
|
assert.equal(undoCall2, 1);
|
||||||
|
assert.equal(redoCall2, 0);
|
||||||
|
assert.equal(undoCall3, 0);
|
||||||
|
assert.equal(redoCall3, 0);
|
||||||
|
assert.equal(service.canUndo(resource), true);
|
||||||
|
assert.equal(service.canRedo(resource), false);
|
||||||
|
assert.equal(service.hasElements(resource), true);
|
||||||
|
assert.ok(service.getLastElement(resource) === element3);
|
||||||
|
|
||||||
|
service.undo(resource);
|
||||||
|
|
||||||
|
assert.equal(undoCall1, 1);
|
||||||
|
assert.equal(redoCall1, 1);
|
||||||
|
assert.equal(undoCall2, 1);
|
||||||
|
assert.equal(redoCall2, 0);
|
||||||
|
assert.equal(undoCall3, 1);
|
||||||
|
assert.equal(redoCall3, 0);
|
||||||
|
assert.equal(service.canUndo(resource), true);
|
||||||
|
assert.equal(service.canRedo(resource), true);
|
||||||
|
assert.equal(service.hasElements(resource), true);
|
||||||
|
assert.ok(service.getLastElement(resource) === null);
|
||||||
|
});
|
||||||
|
|
||||||
|
test('multi resource elements', async () => {
|
||||||
|
const resource1 = URI.file('test1.txt');
|
||||||
|
const resource2 = URI.file('test2.txt');
|
||||||
|
const service = createUndoRedoService(new class extends mock<IDialogService>() {
|
||||||
|
async show() {
|
||||||
|
return {
|
||||||
|
choice: 0 // confirm!
|
||||||
|
};
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
let undoCall1 = 0, undoCall11 = 0, undoCall12 = 0;
|
||||||
|
let redoCall1 = 0, redoCall11 = 0, redoCall12 = 0;
|
||||||
|
const element1: IUndoRedoElement = {
|
||||||
|
type: UndoRedoElementType.Workspace,
|
||||||
|
resources: [resource1, resource2],
|
||||||
|
label: 'typing 1',
|
||||||
|
undo: () => { undoCall1++; },
|
||||||
|
redo: () => { redoCall1++; },
|
||||||
|
split: () => {
|
||||||
|
return [
|
||||||
|
{
|
||||||
|
type: UndoRedoElementType.Resource,
|
||||||
|
resource: resource1,
|
||||||
|
label: 'typing 1.1',
|
||||||
|
undo: () => { undoCall11++; },
|
||||||
|
redo: () => { redoCall11++; }
|
||||||
|
},
|
||||||
|
{
|
||||||
|
type: UndoRedoElementType.Resource,
|
||||||
|
resource: resource2,
|
||||||
|
label: 'typing 1.2',
|
||||||
|
undo: () => { undoCall12++; },
|
||||||
|
redo: () => { redoCall12++; }
|
||||||
|
}
|
||||||
|
];
|
||||||
|
}
|
||||||
|
};
|
||||||
|
service.pushElement(element1);
|
||||||
|
|
||||||
|
assert.equal(service.canUndo(resource1), true);
|
||||||
|
assert.equal(service.canRedo(resource1), false);
|
||||||
|
assert.equal(service.hasElements(resource1), true);
|
||||||
|
assert.ok(service.getLastElement(resource1) === element1);
|
||||||
|
assert.equal(service.canUndo(resource2), true);
|
||||||
|
assert.equal(service.canRedo(resource2), false);
|
||||||
|
assert.equal(service.hasElements(resource2), true);
|
||||||
|
assert.ok(service.getLastElement(resource2) === element1);
|
||||||
|
|
||||||
|
await service.undo(resource1);
|
||||||
|
|
||||||
|
assert.equal(undoCall1, 1);
|
||||||
|
assert.equal(redoCall1, 0);
|
||||||
|
assert.equal(service.canUndo(resource1), false);
|
||||||
|
assert.equal(service.canRedo(resource1), true);
|
||||||
|
assert.equal(service.hasElements(resource1), true);
|
||||||
|
assert.ok(service.getLastElement(resource1) === null);
|
||||||
|
assert.equal(service.canUndo(resource2), false);
|
||||||
|
assert.equal(service.canRedo(resource2), true);
|
||||||
|
assert.equal(service.hasElements(resource2), true);
|
||||||
|
assert.ok(service.getLastElement(resource2) === null);
|
||||||
|
|
||||||
|
await service.redo(resource2);
|
||||||
|
assert.equal(undoCall1, 1);
|
||||||
|
assert.equal(redoCall1, 1);
|
||||||
|
assert.equal(undoCall11, 0);
|
||||||
|
assert.equal(redoCall11, 0);
|
||||||
|
assert.equal(undoCall12, 0);
|
||||||
|
assert.equal(redoCall12, 0);
|
||||||
|
assert.equal(service.canUndo(resource1), true);
|
||||||
|
assert.equal(service.canRedo(resource1), false);
|
||||||
|
assert.equal(service.hasElements(resource1), true);
|
||||||
|
assert.ok(service.getLastElement(resource1) === element1);
|
||||||
|
assert.equal(service.canUndo(resource2), true);
|
||||||
|
assert.equal(service.canRedo(resource2), false);
|
||||||
|
assert.equal(service.hasElements(resource2), true);
|
||||||
|
assert.ok(service.getLastElement(resource2) === element1);
|
||||||
|
|
||||||
|
});
|
||||||
|
});
|
|
@ -246,7 +246,7 @@ export abstract class AbstractSynchroniser extends Disposable {
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
if (e instanceof UserDataSyncError) {
|
if (e instanceof UserDataSyncError) {
|
||||||
switch (e.code) {
|
switch (e.code) {
|
||||||
case UserDataSyncErrorCode.RemotePreconditionFailed:
|
case UserDataSyncErrorCode.PreconditionFailed:
|
||||||
// Rejected as there is a new remote version. Syncing again...
|
// Rejected as there is a new remote version. Syncing again...
|
||||||
this.logService.info(`${this.syncResourceLogLabel}: Failed to synchronize as there is a new remote version available. Synchronizing again...`);
|
this.logService.info(`${this.syncResourceLogLabel}: Failed to synchronize as there is a new remote version available. Synchronizing again...`);
|
||||||
|
|
||||||
|
|
|
@ -184,18 +184,19 @@ export interface IUserDataSyncBackupStoreService {
|
||||||
// #region User Data Sync Error
|
// #region User Data Sync Error
|
||||||
|
|
||||||
export enum UserDataSyncErrorCode {
|
export enum UserDataSyncErrorCode {
|
||||||
// Server Errors
|
// Client Errors (>= 400 )
|
||||||
Unauthorized = 'Unauthorized',
|
Unauthorized = 'Unauthorized', /* 401 */
|
||||||
Forbidden = 'Forbidden',
|
PreconditionFailed = 'PreconditionFailed', /* 412 */
|
||||||
|
TooLarge = 'TooLarge', /* 413 */
|
||||||
|
UpgradeRequired = 'UpgradeRequired', /* 426 */
|
||||||
|
PreconditionRequired = 'PreconditionRequired', /* 428 */
|
||||||
|
TooManyRequests = 'RemoteTooManyRequests', /* 429 */
|
||||||
|
|
||||||
|
// Local Errors
|
||||||
ConnectionRefused = 'ConnectionRefused',
|
ConnectionRefused = 'ConnectionRefused',
|
||||||
RemotePreconditionFailed = 'RemotePreconditionFailed',
|
|
||||||
TooManyRequests = 'RemoteTooManyRequests',
|
|
||||||
TooLarge = 'TooLarge',
|
|
||||||
NoRef = 'NoRef',
|
NoRef = 'NoRef',
|
||||||
TurnedOff = 'TurnedOff',
|
TurnedOff = 'TurnedOff',
|
||||||
SessionExpired = 'SessionExpired',
|
SessionExpired = 'SessionExpired',
|
||||||
|
|
||||||
// Local Errors
|
|
||||||
LocalTooManyRequests = 'LocalTooManyRequests',
|
LocalTooManyRequests = 'LocalTooManyRequests',
|
||||||
LocalPreconditionFailed = 'LocalPreconditionFailed',
|
LocalPreconditionFailed = 'LocalPreconditionFailed',
|
||||||
LocalInvalidContent = 'LocalInvalidContent',
|
LocalInvalidContent = 'LocalInvalidContent',
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
* Licensed under the MIT License. See License.txt in the project root for license information.
|
* Licensed under the MIT License. See License.txt in the project root for license information.
|
||||||
*--------------------------------------------------------------------------------------------*/
|
*--------------------------------------------------------------------------------------------*/
|
||||||
|
|
||||||
import { IUserDataSyncService, SyncStatus, IUserDataSyncStoreService, SyncResource, IUserDataSyncLogService, IUserDataSynchroniser, UserDataSyncStoreError, UserDataSyncErrorCode, UserDataSyncError, SyncResourceConflicts, ISyncResourceHandle } from 'vs/platform/userDataSync/common/userDataSync';
|
import { IUserDataSyncService, SyncStatus, IUserDataSyncStoreService, SyncResource, IUserDataSyncLogService, IUserDataSynchroniser, UserDataSyncErrorCode, UserDataSyncError, SyncResourceConflicts, ISyncResourceHandle } from 'vs/platform/userDataSync/common/userDataSync';
|
||||||
import { Disposable } from 'vs/base/common/lifecycle';
|
import { Disposable } from 'vs/base/common/lifecycle';
|
||||||
import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation';
|
import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation';
|
||||||
import { Emitter, Event } from 'vs/base/common/event';
|
import { Emitter, Event } from 'vs/base/common/event';
|
||||||
|
@ -26,7 +26,7 @@ import { platform, PlatformToString } from 'vs/base/common/platform';
|
||||||
import { escapeRegExpCharacters } from 'vs/base/common/strings';
|
import { escapeRegExpCharacters } from 'vs/base/common/strings';
|
||||||
|
|
||||||
type SyncClassification = {
|
type SyncClassification = {
|
||||||
source?: { classification: 'SystemMetaData', purpose: 'FeatureInsight', isMeasurement: true };
|
resource?: { classification: 'SystemMetaData', purpose: 'FeatureInsight', isMeasurement: true };
|
||||||
};
|
};
|
||||||
|
|
||||||
const SESSION_ID_KEY = 'sync.sessionId';
|
const SESSION_ID_KEY = 'sync.sessionId';
|
||||||
|
@ -96,26 +96,40 @@ export class UserDataSyncService extends Disposable implements IUserDataSyncServ
|
||||||
|
|
||||||
async pull(): Promise<void> {
|
async pull(): Promise<void> {
|
||||||
await this.checkEnablement();
|
await this.checkEnablement();
|
||||||
for (const synchroniser of this.synchronisers) {
|
try {
|
||||||
try {
|
for (const synchroniser of this.synchronisers) {
|
||||||
await synchroniser.pull();
|
try {
|
||||||
} catch (e) {
|
await synchroniser.pull();
|
||||||
this.handleSyncError(e, synchroniser.resource);
|
} catch (e) {
|
||||||
|
this.handleSynchronizerError(e, synchroniser.resource);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
this.updateLastSyncTime();
|
||||||
|
} catch (error) {
|
||||||
|
if (error instanceof UserDataSyncError) {
|
||||||
|
this.telemetryService.publicLog2<{ resource?: string }, SyncClassification>(`sync/error/${UserDataSyncErrorCode.TooLarge}`, { resource: error.resource });
|
||||||
|
}
|
||||||
|
throw error;
|
||||||
}
|
}
|
||||||
this.updateLastSyncTime();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
async push(): Promise<void> {
|
async push(): Promise<void> {
|
||||||
await this.checkEnablement();
|
await this.checkEnablement();
|
||||||
for (const synchroniser of this.synchronisers) {
|
try {
|
||||||
try {
|
for (const synchroniser of this.synchronisers) {
|
||||||
await synchroniser.push();
|
try {
|
||||||
} catch (e) {
|
await synchroniser.push();
|
||||||
this.handleSyncError(e, synchroniser.resource);
|
} catch (e) {
|
||||||
|
this.handleSynchronizerError(e, synchroniser.resource);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
this.updateLastSyncTime();
|
||||||
|
} catch (error) {
|
||||||
|
if (error instanceof UserDataSyncError) {
|
||||||
|
this.telemetryService.publicLog2<{ resource?: string }, SyncClassification>(`sync/error/${UserDataSyncErrorCode.TooLarge}`, { resource: error.resource });
|
||||||
|
}
|
||||||
|
throw error;
|
||||||
}
|
}
|
||||||
this.updateLastSyncTime();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private recoveredSettings: boolean = false;
|
private recoveredSettings: boolean = false;
|
||||||
|
@ -169,7 +183,7 @@ export class UserDataSyncService extends Disposable implements IUserDataSyncServ
|
||||||
try {
|
try {
|
||||||
await synchroniser.sync(manifest);
|
await synchroniser.sync(manifest);
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
this.handleSyncError(e, synchroniser.resource);
|
this.handleSynchronizerError(e, synchroniser.resource);
|
||||||
this._syncErrors.push([synchroniser.resource, UserDataSyncError.toUserDataSyncError(e)]);
|
this._syncErrors.push([synchroniser.resource, UserDataSyncError.toUserDataSyncError(e)]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -192,6 +206,11 @@ export class UserDataSyncService extends Disposable implements IUserDataSyncServ
|
||||||
this.logService.info(`Sync done. Took ${new Date().getTime() - startTime}ms`);
|
this.logService.info(`Sync done. Took ${new Date().getTime() - startTime}ms`);
|
||||||
this.updateLastSyncTime();
|
this.updateLastSyncTime();
|
||||||
|
|
||||||
|
} catch (error) {
|
||||||
|
if (error instanceof UserDataSyncError) {
|
||||||
|
this.telemetryService.publicLog2<{ resource?: string }, SyncClassification>(`sync/error/${UserDataSyncErrorCode.TooLarge}`, { resource: error.resource });
|
||||||
|
}
|
||||||
|
throw error;
|
||||||
} finally {
|
} finally {
|
||||||
this.updateStatus();
|
this.updateStatus();
|
||||||
this._onSyncErrors.fire(this._syncErrors);
|
this._onSyncErrors.fire(this._syncErrors);
|
||||||
|
@ -374,18 +393,16 @@ export class UserDataSyncService extends Disposable implements IUserDataSyncServ
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private handleSyncError(e: Error, source: SyncResource): void {
|
private handleSynchronizerError(e: Error, source: SyncResource): void {
|
||||||
if (e instanceof UserDataSyncStoreError) {
|
if (e instanceof UserDataSyncError) {
|
||||||
switch (e.code) {
|
switch (e.code) {
|
||||||
case UserDataSyncErrorCode.TooLarge:
|
case UserDataSyncErrorCode.TooLarge:
|
||||||
this.telemetryService.publicLog2<{ source: string }, SyncClassification>(`sync/error/${UserDataSyncErrorCode.TooLarge}`, { source });
|
|
||||||
break;
|
|
||||||
case UserDataSyncErrorCode.TooManyRequests:
|
case UserDataSyncErrorCode.TooManyRequests:
|
||||||
case UserDataSyncErrorCode.LocalTooManyRequests:
|
case UserDataSyncErrorCode.LocalTooManyRequests:
|
||||||
this.telemetryService.publicLog2(`sync/error/${e.code}`);
|
case UserDataSyncErrorCode.UpgradeRequired:
|
||||||
break;
|
case UserDataSyncErrorCode.Incompatible:
|
||||||
|
throw e;
|
||||||
}
|
}
|
||||||
throw e;
|
|
||||||
}
|
}
|
||||||
this.logService.error(e);
|
this.logService.error(e);
|
||||||
this.logService.error(`${source}: ${toErrorMessage(e)}`);
|
this.logService.error(`${source}: ${toErrorMessage(e)}`);
|
||||||
|
|
|
@ -262,18 +262,18 @@ export class UserDataSyncStoreService extends Disposable implements IUserDataSyn
|
||||||
throw new UserDataSyncStoreError(`Request '${options.url?.toString()}' failed because of Unauthorized (401).`, UserDataSyncErrorCode.Unauthorized);
|
throw new UserDataSyncStoreError(`Request '${options.url?.toString()}' failed because of Unauthorized (401).`, UserDataSyncErrorCode.Unauthorized);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (context.res.statusCode === 403) {
|
|
||||||
throw new UserDataSyncStoreError(`Request '${options.url?.toString()}' is Forbidden (403).`, UserDataSyncErrorCode.Forbidden);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (context.res.statusCode === 412) {
|
if (context.res.statusCode === 412) {
|
||||||
throw new UserDataSyncStoreError(`${options.type} request '${options.url?.toString()}' failed because of Precondition Failed (412). There is new data exists for this resource. Make the request again with latest data.`, UserDataSyncErrorCode.RemotePreconditionFailed);
|
throw new UserDataSyncStoreError(`${options.type} request '${options.url?.toString()}' failed because of Precondition Failed (412). There is new data exists for this resource. Make the request again with latest data.`, UserDataSyncErrorCode.PreconditionFailed);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (context.res.statusCode === 413) {
|
if (context.res.statusCode === 413) {
|
||||||
throw new UserDataSyncStoreError(`${options.type} request '${options.url?.toString()}' failed because of too large payload (413).`, UserDataSyncErrorCode.TooLarge);
|
throw new UserDataSyncStoreError(`${options.type} request '${options.url?.toString()}' failed because of too large payload (413).`, UserDataSyncErrorCode.TooLarge);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (context.res.statusCode === 426) {
|
||||||
|
throw new UserDataSyncStoreError(`${options.type} request '${options.url?.toString()}' failed with status Upgrade Required (426). Please upgrade the client and try again.`, UserDataSyncErrorCode.UpgradeRequired);
|
||||||
|
}
|
||||||
|
|
||||||
if (context.res.statusCode === 429) {
|
if (context.res.statusCode === 429) {
|
||||||
throw new UserDataSyncStoreError(`${options.type} request '${options.url?.toString()}' failed because of too many requests (429).`, UserDataSyncErrorCode.TooManyRequests);
|
throw new UserDataSyncStoreError(`${options.type} request '${options.url?.toString()}' failed because of too many requests (429).`, UserDataSyncErrorCode.TooManyRequests);
|
||||||
}
|
}
|
||||||
|
|
|
@ -24,6 +24,11 @@ import { IWorkbenchEnvironmentService } from 'vs/workbench/services/environment/
|
||||||
import { dirname } from 'vs/base/common/resources';
|
import { dirname } from 'vs/base/common/resources';
|
||||||
import { IWorkspaceContextService } from 'vs/platform/workspace/common/workspace';
|
import { IWorkspaceContextService } from 'vs/platform/workspace/common/workspace';
|
||||||
|
|
||||||
|
export interface WebviewIntialized {
|
||||||
|
__vscode_notebook_message: boolean;
|
||||||
|
type: 'initialized'
|
||||||
|
}
|
||||||
|
|
||||||
export interface IDimensionMessage {
|
export interface IDimensionMessage {
|
||||||
__vscode_notebook_message: boolean;
|
__vscode_notebook_message: boolean;
|
||||||
type: 'dimension';
|
type: 'dimension';
|
||||||
|
@ -107,6 +112,7 @@ export interface IScrollRequestMessage {
|
||||||
export interface IUpdatePreloadResourceMessage {
|
export interface IUpdatePreloadResourceMessage {
|
||||||
type: 'preload';
|
type: 'preload';
|
||||||
resources: string[];
|
resources: string[];
|
||||||
|
source: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
interface ICachedInset {
|
interface ICachedInset {
|
||||||
|
@ -124,7 +130,7 @@ function html(strings: TemplateStringsArray, ...values: any[]): string {
|
||||||
return str;
|
return str;
|
||||||
}
|
}
|
||||||
|
|
||||||
type IMessage = IDimensionMessage | IScrollAckMessage | IWheelMessage | IMouseEnterMessage | IMouseLeaveMessage | IBlurOutputMessage;
|
type IMessage = IDimensionMessage | IScrollAckMessage | IWheelMessage | IMouseEnterMessage | IMouseLeaveMessage | IBlurOutputMessage | WebviewIntialized;
|
||||||
|
|
||||||
let version = 0;
|
let version = 0;
|
||||||
export class BackLayerWebView extends Disposable {
|
export class BackLayerWebView extends Disposable {
|
||||||
|
@ -134,12 +140,12 @@ export class BackLayerWebView extends Disposable {
|
||||||
hiddenInsetMapping: Set<IOutput> = new Set();
|
hiddenInsetMapping: Set<IOutput> = new Set();
|
||||||
reversedInsetMapping: Map<string, IOutput> = new Map();
|
reversedInsetMapping: Map<string, IOutput> = new Map();
|
||||||
preloadsCache: Map<string, boolean> = new Map();
|
preloadsCache: Map<string, boolean> = new Map();
|
||||||
kernelPreloadsCache: Map<string, boolean> = new Map();
|
|
||||||
localResourceRootsCache: URI[] | undefined = undefined;
|
localResourceRootsCache: URI[] | undefined = undefined;
|
||||||
rendererRootsCache: URI[] = [];
|
rendererRootsCache: URI[] = [];
|
||||||
kernelRootsCache: URI[] = [];
|
kernelRootsCache: URI[] = [];
|
||||||
private readonly _onMessage = this._register(new Emitter<any>());
|
private readonly _onMessage = this._register(new Emitter<any>());
|
||||||
public readonly onMessage: Event<any> = this._onMessage.event;
|
public readonly onMessage: Event<any> = this._onMessage.event;
|
||||||
|
private _loaded!: Promise<void>;
|
||||||
private _initalized: Promise<void>;
|
private _initalized: Promise<void>;
|
||||||
private _disposed = false;
|
private _disposed = false;
|
||||||
|
|
||||||
|
@ -473,6 +479,11 @@ ${loaderJs}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
vscode.postMessage({
|
||||||
|
__vscode_notebook_message: true,
|
||||||
|
type: 'initialized'
|
||||||
|
});
|
||||||
}());
|
}());
|
||||||
|
|
||||||
</script>
|
</script>
|
||||||
|
@ -584,6 +595,19 @@ ${loaderJs}
|
||||||
allowScripts: true,
|
allowScripts: true,
|
||||||
localResourceRoots: this.localResourceRootsCache
|
localResourceRoots: this.localResourceRootsCache
|
||||||
}, undefined);
|
}, undefined);
|
||||||
|
|
||||||
|
let resolveFunc: () => void;
|
||||||
|
this._loaded = new Promise<void>((resolve, reject) => {
|
||||||
|
resolveFunc = resolve;
|
||||||
|
});
|
||||||
|
|
||||||
|
let dispose = webview.onMessage((data: IMessage) => {
|
||||||
|
if (data.__vscode_notebook_message && data.type === 'initialized') {
|
||||||
|
resolveFunc();
|
||||||
|
dispose.dispose();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
webview.html = content;
|
webview.html = content;
|
||||||
return webview;
|
return webview;
|
||||||
}
|
}
|
||||||
|
@ -744,11 +768,13 @@ ${loaderJs}
|
||||||
}, 50);
|
}, 50);
|
||||||
}
|
}
|
||||||
|
|
||||||
updateKernelPreloads(extensionLocations: URI[], preloads: URI[]) {
|
async updateKernelPreloads(extensionLocations: URI[], preloads: URI[]) {
|
||||||
if (this._disposed) {
|
if (this._disposed) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
await this._loaded;
|
||||||
|
|
||||||
let resources: string[] = [];
|
let resources: string[] = [];
|
||||||
preloads = preloads.map(preload => {
|
preloads = preloads.map(preload => {
|
||||||
if (this.environmentService.isExtensionDevelopment && (preload.scheme === 'http' || preload.scheme === 'https')) {
|
if (this.environmentService.isExtensionDevelopment && (preload.scheme === 'http' || preload.scheme === 'https')) {
|
||||||
|
@ -758,9 +784,9 @@ ${loaderJs}
|
||||||
});
|
});
|
||||||
|
|
||||||
preloads.forEach(e => {
|
preloads.forEach(e => {
|
||||||
if (!this.kernelPreloadsCache.has(e.toString())) {
|
if (!this.preloadsCache.has(e.toString())) {
|
||||||
resources.push(e.toString());
|
resources.push(e.toString());
|
||||||
this.kernelPreloadsCache.set(e.toString(), true);
|
this.preloadsCache.set(e.toString(), true);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -769,14 +795,16 @@ ${loaderJs}
|
||||||
}
|
}
|
||||||
|
|
||||||
this.kernelRootsCache = [...extensionLocations, ...this.kernelRootsCache];
|
this.kernelRootsCache = [...extensionLocations, ...this.kernelRootsCache];
|
||||||
this._updatePreloads(resources);
|
this._updatePreloads(resources, 'kernel');
|
||||||
}
|
}
|
||||||
|
|
||||||
updateRendererPreloads(preloads: ReadonlySet<number>) {
|
async updateRendererPreloads(preloads: ReadonlySet<number>) {
|
||||||
if (this._disposed) {
|
if (this._disposed) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
await this._loaded;
|
||||||
|
|
||||||
let resources: string[] = [];
|
let resources: string[] = [];
|
||||||
let extensionLocations: URI[] = [];
|
let extensionLocations: URI[] = [];
|
||||||
preloads.forEach(preload => {
|
preloads.forEach(preload => {
|
||||||
|
@ -799,23 +827,23 @@ ${loaderJs}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
if (!resources.length) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
this.rendererRootsCache = extensionLocations;
|
this.rendererRootsCache = extensionLocations;
|
||||||
this._updatePreloads(resources);
|
this._updatePreloads(resources, 'renderer');
|
||||||
}
|
}
|
||||||
|
|
||||||
private _updatePreloads(resources: string[]) {
|
private _updatePreloads(resources: string[], source: string) {
|
||||||
const mixedResourceRoots = [...(this.localResourceRootsCache || []), ...this.rendererRootsCache, ...this.kernelRootsCache];
|
const mixedResourceRoots = [...(this.localResourceRootsCache || []), ...this.rendererRootsCache, ...this.kernelRootsCache];
|
||||||
|
|
||||||
this.webview.contentOptions = {
|
this.webview.localResourcesRoot = mixedResourceRoots;
|
||||||
allowMultipleAPIAcquire: true,
|
|
||||||
allowScripts: true,
|
|
||||||
enableCommandUris: true,
|
|
||||||
localResourceRoots: mixedResourceRoots
|
|
||||||
};
|
|
||||||
|
|
||||||
let message: IUpdatePreloadResourceMessage = {
|
let message: IUpdatePreloadResourceMessage = {
|
||||||
type: 'preload',
|
type: 'preload',
|
||||||
resources: resources
|
resources: resources,
|
||||||
|
source: source
|
||||||
};
|
};
|
||||||
|
|
||||||
this.webview.sendMessage(message);
|
this.webview.sendMessage(message);
|
||||||
|
|
|
@ -28,7 +28,7 @@ const languageScopeSchemaId = 'vscode://schemas/snippets';
|
||||||
|
|
||||||
const snippetSchemaProperties: IJSONSchemaMap = {
|
const snippetSchemaProperties: IJSONSchemaMap = {
|
||||||
prefix: {
|
prefix: {
|
||||||
description: nls.localize('snippetSchema.json.prefix', 'The prefix to used when selecting the snippet in intellisense'),
|
description: nls.localize('snippetSchema.json.prefix', 'The prefix to use when selecting the snippet in intellisense'),
|
||||||
type: ['string', 'array']
|
type: ['string', 'array']
|
||||||
},
|
},
|
||||||
body: {
|
body: {
|
||||||
|
|
|
@ -2515,38 +2515,58 @@ export abstract class AbstractTaskService extends Disposable implements ITaskSer
|
||||||
location: ProgressLocation.Window,
|
location: ProgressLocation.Window,
|
||||||
title: nls.localize('TaskService.fetchingBuildTasks', 'Fetching build tasks...')
|
title: nls.localize('TaskService.fetchingBuildTasks', 'Fetching build tasks...')
|
||||||
};
|
};
|
||||||
let promise = this.getTasksForGroup(TaskGroup.Build).then((tasks) => {
|
let promise = this.getWorkspaceTasks().then(tasks => {
|
||||||
if (tasks.length > 0) {
|
const buildTasks: ConfiguringTask[] = [];
|
||||||
let { defaults, users } = this.splitPerGroupType(tasks);
|
for (const taskSource of tasks) {
|
||||||
if (defaults.length === 1) {
|
for (const task in taskSource[1].configurations?.byIdentifier) {
|
||||||
this.run(defaults[0]).then(undefined, reason => {
|
if ((taskSource[1].configurations?.byIdentifier[task].configurationProperties.group === TaskGroup.Build) &&
|
||||||
// eat the error, it has already been surfaced to the user and we don't care about it here
|
(taskSource[1].configurations?.byIdentifier[task].configurationProperties.groupType === GroupType.default)) {
|
||||||
});
|
buildTasks.push(taskSource[1].configurations.byIdentifier[task]);
|
||||||
return;
|
}
|
||||||
} else if (defaults.length + users.length > 0) {
|
|
||||||
tasks = defaults.concat(users);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
this.showIgnoredFoldersMessage().then(() => {
|
if (buildTasks.length === 1) {
|
||||||
this.showQuickPick(tasks,
|
this.tryResolveTask(buildTasks[0]).then(resolvedTask => {
|
||||||
nls.localize('TaskService.pickBuildTask', 'Select the build task to run'),
|
this.run(resolvedTask).then(undefined, reason => {
|
||||||
{
|
// eat the error, it has already been surfaced to the user and we don't care about it here
|
||||||
label: nls.localize('TaskService.noBuildTask', 'No build task to run found. Configure Build Task...'),
|
});
|
||||||
task: null
|
});
|
||||||
},
|
return;
|
||||||
true).then((entry) => {
|
}
|
||||||
let task: Task | undefined | null = entry ? entry.task : undefined;
|
|
||||||
if (task === undefined) {
|
return this.getTasksForGroup(TaskGroup.Build).then((tasks) => {
|
||||||
return;
|
if (tasks.length > 0) {
|
||||||
}
|
let { defaults, users } = this.splitPerGroupType(tasks);
|
||||||
if (task === null) {
|
if (defaults.length === 1) {
|
||||||
this.runConfigureDefaultBuildTask();
|
this.run(defaults[0]).then(undefined, reason => {
|
||||||
return;
|
|
||||||
}
|
|
||||||
this.run(task, { attachProblemMatcher: true }).then(undefined, reason => {
|
|
||||||
// eat the error, it has already been surfaced to the user and we don't care about it here
|
// eat the error, it has already been surfaced to the user and we don't care about it here
|
||||||
});
|
});
|
||||||
});
|
return;
|
||||||
|
} else if (defaults.length + users.length > 0) {
|
||||||
|
tasks = defaults.concat(users);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
this.showIgnoredFoldersMessage().then(() => {
|
||||||
|
this.showQuickPick(tasks,
|
||||||
|
nls.localize('TaskService.pickBuildTask', 'Select the build task to run'),
|
||||||
|
{
|
||||||
|
label: nls.localize('TaskService.noBuildTask', 'No build task to run found. Configure Build Task...'),
|
||||||
|
task: null
|
||||||
|
},
|
||||||
|
true).then((entry) => {
|
||||||
|
let task: Task | undefined | null = entry ? entry.task : undefined;
|
||||||
|
if (task === undefined) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (task === null) {
|
||||||
|
this.runConfigureDefaultBuildTask();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
this.run(task, { attachProblemMatcher: true }).then(undefined, reason => {
|
||||||
|
// eat the error, it has already been surfaced to the user and we don't care about it here
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
this.progressService.withProgress(options, () => promise);
|
this.progressService.withProgress(options, () => promise);
|
||||||
|
|
|
@ -1276,9 +1276,6 @@ export class TerminalTaskSystem implements ITaskSystem {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (basename === 'cmd' && platform === Platform.Platform.Windows && commandQuoted && argQuoted) {
|
|
||||||
commandLine = '"' + commandLine + '"';
|
|
||||||
}
|
|
||||||
return commandLine;
|
return commandLine;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -136,7 +136,7 @@ export class UserDataSyncWorkbenchContribution extends Disposable implements IWo
|
||||||
this.userDataSyncWorkbenchService.onDidChangeAccountStatus
|
this.userDataSyncWorkbenchService.onDidChangeAccountStatus
|
||||||
)(() => this.updateBadge()));
|
)(() => this.updateBadge()));
|
||||||
this._register(userDataSyncService.onDidChangeConflicts(() => this.onDidChangeConflicts(this.userDataSyncService.conflicts)));
|
this._register(userDataSyncService.onDidChangeConflicts(() => this.onDidChangeConflicts(this.userDataSyncService.conflicts)));
|
||||||
this._register(userDataSyncService.onSyncErrors(errors => this.onSyncErrors(errors)));
|
this._register(userDataSyncService.onSyncErrors(errors => this.onSynchronizerErrors(errors)));
|
||||||
this._register(userDataAutoSyncService.onError(error => this.onAutoSyncError(error)));
|
this._register(userDataAutoSyncService.onError(error => this.onAutoSyncError(error)));
|
||||||
|
|
||||||
this.registerActions();
|
this.registerActions();
|
||||||
|
@ -261,7 +261,7 @@ export class UserDataSyncWorkbenchContribution extends Disposable implements IWo
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private onAutoSyncError(error: UserDataSyncError): void {
|
private onAutoSyncError(error: UserDataSyncError): boolean {
|
||||||
switch (error.code) {
|
switch (error.code) {
|
||||||
case UserDataSyncErrorCode.TurnedOff:
|
case UserDataSyncErrorCode.TurnedOff:
|
||||||
case UserDataSyncErrorCode.SessionExpired:
|
case UserDataSyncErrorCode.SessionExpired:
|
||||||
|
@ -272,7 +272,7 @@ export class UserDataSyncWorkbenchContribution extends Disposable implements IWo
|
||||||
primary: [new Action('turn on sync', localize('turn on sync', "Turn on Preferences Sync..."), undefined, true, () => this.turnOn())]
|
primary: [new Action('turn on sync', localize('turn on sync', "Turn on Preferences Sync..."), undefined, true, () => this.turnOn())]
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
return;
|
return true;
|
||||||
case UserDataSyncErrorCode.TooLarge:
|
case UserDataSyncErrorCode.TooLarge:
|
||||||
if (error.resource === SyncResource.Keybindings || error.resource === SyncResource.Settings) {
|
if (error.resource === SyncResource.Keybindings || error.resource === SyncResource.Settings) {
|
||||||
this.disableSync(error.resource);
|
this.disableSync(error.resource);
|
||||||
|
@ -286,19 +286,21 @@ export class UserDataSyncWorkbenchContribution extends Disposable implements IWo
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
return;
|
return true;
|
||||||
case UserDataSyncErrorCode.Incompatible:
|
case UserDataSyncErrorCode.Incompatible:
|
||||||
|
case UserDataSyncErrorCode.UpgradeRequired:
|
||||||
this.disableSync();
|
this.disableSync();
|
||||||
this.notificationService.notify({
|
this.notificationService.notify({
|
||||||
severity: Severity.Error,
|
severity: Severity.Error,
|
||||||
message: localize('error incompatible', "Turned off sync because local data is incompatible with the data in the cloud. Please update {0} and turn on sync to continue syncing.", this.productService.nameLong),
|
message: localize('error upgrade required', "Turned off sync because the current version ({0}) of {1} is not compatible with the Preferences Sync Service. Please update and turn on sync to continue syncing.", this.productService.version, this.productService.nameLong),
|
||||||
});
|
});
|
||||||
return;
|
return true;
|
||||||
}
|
}
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
private readonly invalidContentErrorDisposables = new Map<SyncResource, IDisposable>();
|
private readonly invalidContentErrorDisposables = new Map<SyncResource, IDisposable>();
|
||||||
private onSyncErrors(errors: [SyncResource, UserDataSyncError][]): void {
|
private onSynchronizerErrors(errors: [SyncResource, UserDataSyncError][]): void {
|
||||||
if (errors.length) {
|
if (errors.length) {
|
||||||
for (const [source, error] of errors) {
|
for (const [source, error] of errors) {
|
||||||
switch (error.code) {
|
switch (error.code) {
|
||||||
|
@ -392,6 +394,14 @@ export class UserDataSyncWorkbenchContribution extends Disposable implements IWo
|
||||||
}
|
}
|
||||||
await this.userDataSyncWorkbenchService.turnOn();
|
await this.userDataSyncWorkbenchService.turnOn();
|
||||||
this.storageService.store('sync.donotAskPreviewConfirmation', true, StorageScope.GLOBAL);
|
this.storageService.store('sync.donotAskPreviewConfirmation', true, StorageScope.GLOBAL);
|
||||||
|
} catch (e) {
|
||||||
|
if (isPromiseCanceledError(e)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (e instanceof UserDataSyncError && this.onAutoSyncError(e)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
this.notificationService.error(localize('turn on failed', "Error while starting Sync: {0}", toErrorMessage(e)));
|
||||||
} finally {
|
} finally {
|
||||||
this.turningOnSync = false;
|
this.turningOnSync = false;
|
||||||
}
|
}
|
||||||
|
@ -616,15 +626,7 @@ export class UserDataSyncWorkbenchContribution extends Disposable implements IWo
|
||||||
|
|
||||||
private registerTurnOnSyncAction(): void {
|
private registerTurnOnSyncAction(): void {
|
||||||
const turnOnSyncWhenContext = ContextKeyExpr.and(CONTEXT_SYNC_STATE.notEqualsTo(SyncStatus.Uninitialized), CONTEXT_SYNC_ENABLEMENT.toNegated(), CONTEXT_ACCOUNT_STATE.notEqualsTo(AccountStatus.Uninitialized), CONTEXT_TURNING_ON_STATE.negate());
|
const turnOnSyncWhenContext = ContextKeyExpr.and(CONTEXT_SYNC_STATE.notEqualsTo(SyncStatus.Uninitialized), CONTEXT_SYNC_ENABLEMENT.toNegated(), CONTEXT_ACCOUNT_STATE.notEqualsTo(AccountStatus.Uninitialized), CONTEXT_TURNING_ON_STATE.negate());
|
||||||
CommandsRegistry.registerCommand(turnOnSyncCommand.id, async () => {
|
CommandsRegistry.registerCommand(turnOnSyncCommand.id, () => this.turnOn());
|
||||||
try {
|
|
||||||
await this.turnOn();
|
|
||||||
} catch (e) {
|
|
||||||
if (!isPromiseCanceledError(e)) {
|
|
||||||
this.notificationService.error(localize('turn on failed', "Error while starting Sync: {0}", toErrorMessage(e)));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
MenuRegistry.appendMenuItem(MenuId.GlobalActivity, {
|
MenuRegistry.appendMenuItem(MenuId.GlobalActivity, {
|
||||||
group: '5_sync',
|
group: '5_sync',
|
||||||
command: {
|
command: {
|
||||||
|
|
|
@ -6,6 +6,7 @@
|
||||||
import { addClass } from 'vs/base/browser/dom';
|
import { addClass } from 'vs/base/browser/dom';
|
||||||
import { IMouseWheelEvent } from 'vs/base/browser/mouseEvent';
|
import { IMouseWheelEvent } from 'vs/base/browser/mouseEvent';
|
||||||
import { Emitter } from 'vs/base/common/event';
|
import { Emitter } from 'vs/base/common/event';
|
||||||
|
import { URI } from 'vs/base/common/uri';
|
||||||
import { Disposable, IDisposable } from 'vs/base/common/lifecycle';
|
import { Disposable, IDisposable } from 'vs/base/common/lifecycle';
|
||||||
import { IEnvironmentService } from 'vs/platform/environment/common/environment';
|
import { IEnvironmentService } from 'vs/platform/environment/common/environment';
|
||||||
import { ExtensionIdentifier } from 'vs/platform/extensions/common/extensions';
|
import { ExtensionIdentifier } from 'vs/platform/extensions/common/extensions';
|
||||||
|
@ -248,6 +249,10 @@ export abstract class BaseWebview<T extends HTMLElement> extends Disposable {
|
||||||
this.doUpdateContent();
|
this.doUpdateContent();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public set localResourcesRoot(resources: URI[]) {
|
||||||
|
/** no op */
|
||||||
|
}
|
||||||
|
|
||||||
public set state(state: string | undefined) {
|
public set state(state: string | undefined) {
|
||||||
this.content = {
|
this.content = {
|
||||||
html: this.content.html,
|
html: this.content.html,
|
||||||
|
|
|
@ -7,6 +7,7 @@ import { Dimension } from 'vs/base/browser/dom';
|
||||||
import { IMouseWheelEvent } from 'vs/base/browser/mouseEvent';
|
import { IMouseWheelEvent } from 'vs/base/browser/mouseEvent';
|
||||||
import { memoize } from 'vs/base/common/decorators';
|
import { memoize } from 'vs/base/common/decorators';
|
||||||
import { Emitter, Event } from 'vs/base/common/event';
|
import { Emitter, Event } from 'vs/base/common/event';
|
||||||
|
import { URI } from 'vs/base/common/uri';
|
||||||
import { Disposable, DisposableStore, MutableDisposable } from 'vs/base/common/lifecycle';
|
import { Disposable, DisposableStore, MutableDisposable } from 'vs/base/common/lifecycle';
|
||||||
import { IContextKey, IContextKeyService } from 'vs/platform/contextkey/common/contextkey';
|
import { IContextKey, IContextKeyService } from 'vs/platform/contextkey/common/contextkey';
|
||||||
import { ExtensionIdentifier } from 'vs/platform/extensions/common/extensions';
|
import { ExtensionIdentifier } from 'vs/platform/extensions/common/extensions';
|
||||||
|
@ -174,6 +175,10 @@ export class DynamicWebviewEditorOverlay extends Disposable implements WebviewOv
|
||||||
this.withWebview(webview => webview.contentOptions = value);
|
this.withWebview(webview => webview.contentOptions = value);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public set localResourcesRoot(resources: URI[]) {
|
||||||
|
this.withWebview(webview => webview.localResourcesRoot = resources);
|
||||||
|
}
|
||||||
|
|
||||||
private readonly _onDidFocus = this._register(new Emitter<void>());
|
private readonly _onDidFocus = this._register(new Emitter<void>());
|
||||||
public readonly onDidFocus: Event<void> = this._onDidFocus.event;
|
public readonly onDidFocus: Event<void> = this._onDidFocus.event;
|
||||||
|
|
||||||
|
|
|
@ -76,6 +76,7 @@ export interface WebviewExtensionDescription {
|
||||||
export interface Webview extends IDisposable {
|
export interface Webview extends IDisposable {
|
||||||
html: string;
|
html: string;
|
||||||
contentOptions: WebviewContentOptions;
|
contentOptions: WebviewContentOptions;
|
||||||
|
localResourcesRoot: URI[];
|
||||||
extension: WebviewExtensionDescription | undefined;
|
extension: WebviewExtensionDescription | undefined;
|
||||||
initialScrollProgress: number;
|
initialScrollProgress: number;
|
||||||
state: string | undefined;
|
state: string | undefined;
|
||||||
|
|
|
@ -381,6 +381,11 @@ export class ElectronWebviewBasedWebview extends BaseWebview<WebviewTag> impleme
|
||||||
super.contentOptions = options;
|
super.contentOptions = options;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public set localResourcesRoot(resources: URI[]) {
|
||||||
|
this._protocolProvider.update(resources || []);
|
||||||
|
super.localResourcesRoot = resources;
|
||||||
|
}
|
||||||
|
|
||||||
protected readonly extraContentOptions = {};
|
protected readonly extraContentOptions = {};
|
||||||
|
|
||||||
public set html(value: string) {
|
public set html(value: string) {
|
||||||
|
|
|
@ -421,22 +421,6 @@ class KeybindingItemMatches {
|
||||||
return this.wordMatchesMetaModifier(word);
|
return this.wordMatchesMetaModifier(word);
|
||||||
}
|
}
|
||||||
|
|
||||||
private wordMatchesMetaModifier(word: string): boolean {
|
|
||||||
if (matchesPrefix(this.modifierLabels.ui.metaKey, word)) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
if (matchesPrefix(this.modifierLabels.aria.metaKey, word)) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
if (matchesPrefix(this.modifierLabels.user.metaKey, word)) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
if (matchesPrefix(localize('meta', "meta"), word)) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
private matchesCtrlModifier(keybinding: ResolvedKeybindingPart | null, word: string): boolean {
|
private matchesCtrlModifier(keybinding: ResolvedKeybindingPart | null, word: string): boolean {
|
||||||
if (!keybinding) {
|
if (!keybinding) {
|
||||||
return false;
|
return false;
|
||||||
|
@ -447,19 +431,6 @@ class KeybindingItemMatches {
|
||||||
return this.wordMatchesCtrlModifier(word);
|
return this.wordMatchesCtrlModifier(word);
|
||||||
}
|
}
|
||||||
|
|
||||||
private wordMatchesCtrlModifier(word: string): boolean {
|
|
||||||
if (matchesPrefix(this.modifierLabels.ui.ctrlKey, word)) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
if (matchesPrefix(this.modifierLabels.aria.ctrlKey, word)) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
if (matchesPrefix(this.modifierLabels.user.ctrlKey, word)) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
private matchesShiftModifier(keybinding: ResolvedKeybindingPart | null, word: string): boolean {
|
private matchesShiftModifier(keybinding: ResolvedKeybindingPart | null, word: string): boolean {
|
||||||
if (!keybinding) {
|
if (!keybinding) {
|
||||||
return false;
|
return false;
|
||||||
|
@ -470,19 +441,6 @@ class KeybindingItemMatches {
|
||||||
return this.wordMatchesShiftModifier(word);
|
return this.wordMatchesShiftModifier(word);
|
||||||
}
|
}
|
||||||
|
|
||||||
private wordMatchesShiftModifier(word: string): boolean {
|
|
||||||
if (matchesPrefix(this.modifierLabels.ui.shiftKey, word)) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
if (matchesPrefix(this.modifierLabels.aria.shiftKey, word)) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
if (matchesPrefix(this.modifierLabels.user.shiftKey, word)) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
private matchesAltModifier(keybinding: ResolvedKeybindingPart | null, word: string): boolean {
|
private matchesAltModifier(keybinding: ResolvedKeybindingPart | null, word: string): boolean {
|
||||||
if (!keybinding) {
|
if (!keybinding) {
|
||||||
return false;
|
return false;
|
||||||
|
@ -493,22 +451,6 @@ class KeybindingItemMatches {
|
||||||
return this.wordMatchesAltModifier(word);
|
return this.wordMatchesAltModifier(word);
|
||||||
}
|
}
|
||||||
|
|
||||||
private wordMatchesAltModifier(word: string): boolean {
|
|
||||||
if (matchesPrefix(this.modifierLabels.ui.altKey, word)) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
if (matchesPrefix(this.modifierLabels.aria.altKey, word)) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
if (matchesPrefix(this.modifierLabels.user.altKey, word)) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
if (matchesPrefix(localize('option', "option"), word)) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
private hasAnyMatch(keybindingMatch: KeybindingMatch): boolean {
|
private hasAnyMatch(keybindingMatch: KeybindingMatch): boolean {
|
||||||
return !!keybindingMatch.altKey ||
|
return !!keybindingMatch.altKey ||
|
||||||
!!keybindingMatch.ctrlKey ||
|
!!keybindingMatch.ctrlKey ||
|
||||||
|
@ -574,4 +516,62 @@ class KeybindingItemMatches {
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private wordMatchesAltModifier(word: string): boolean {
|
||||||
|
if (strings.equalsIgnoreCase(this.modifierLabels.ui.altKey, word)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if (strings.equalsIgnoreCase(this.modifierLabels.aria.altKey, word)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if (strings.equalsIgnoreCase(this.modifierLabels.user.altKey, word)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if (strings.equalsIgnoreCase(localize('option', "option"), word)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
private wordMatchesCtrlModifier(word: string): boolean {
|
||||||
|
if (strings.equalsIgnoreCase(this.modifierLabels.ui.ctrlKey, word)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if (strings.equalsIgnoreCase(this.modifierLabels.aria.ctrlKey, word)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if (strings.equalsIgnoreCase(this.modifierLabels.user.ctrlKey, word)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
private wordMatchesMetaModifier(word: string): boolean {
|
||||||
|
if (strings.equalsIgnoreCase(this.modifierLabels.ui.metaKey, word)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if (strings.equalsIgnoreCase(this.modifierLabels.aria.metaKey, word)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if (strings.equalsIgnoreCase(this.modifierLabels.user.metaKey, word)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if (strings.equalsIgnoreCase(localize('meta', "meta"), word)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
private wordMatchesShiftModifier(word: string): boolean {
|
||||||
|
if (strings.equalsIgnoreCase(this.modifierLabels.ui.shiftKey, word)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if (strings.equalsIgnoreCase(this.modifierLabels.aria.shiftKey, word)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if (strings.equalsIgnoreCase(this.modifierLabels.user.shiftKey, word)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -34,7 +34,7 @@ class AnAction extends Action {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
suite('KeybindingsEditorModel test', () => {
|
suite('KeybindingsEditorModel', () => {
|
||||||
|
|
||||||
let instantiationService: TestInstantiationService;
|
let instantiationService: TestInstantiationService;
|
||||||
let testObject: KeybindingsEditorModel;
|
let testObject: KeybindingsEditorModel;
|
||||||
|
@ -568,6 +568,46 @@ suite('KeybindingsEditorModel test', () => {
|
||||||
assert.deepEqual(actual[0].keybindingMatches!.firstPart, { keyCode: true });
|
assert.deepEqual(actual[0].keybindingMatches!.firstPart, { keyCode: true });
|
||||||
});
|
});
|
||||||
|
|
||||||
|
test('filter modifiers are not matched when not completely matched (prefix)', async () => {
|
||||||
|
testObject = instantiationService.createInstance(KeybindingsEditorModel, OperatingSystem.Macintosh);
|
||||||
|
const term = `alt.${uuid.generateUuid()}`;
|
||||||
|
const command = `command.${term}`;
|
||||||
|
const expected = aResolvedKeybindingItem({ command, firstPart: { keyCode: KeyCode.Escape }, isDefault: false });
|
||||||
|
prepareKeybindingService(expected, aResolvedKeybindingItem({ command: 'some_command', firstPart: { keyCode: KeyCode.Escape, modifiers: { altKey: true } }, isDefault: false }));
|
||||||
|
|
||||||
|
await testObject.resolve(new Map<string, string>());
|
||||||
|
const actual = testObject.fetch(term);
|
||||||
|
assert.equal(1, actual.length);
|
||||||
|
assert.equal(command, actual[0].keybindingItem.command);
|
||||||
|
assert.equal(1, actual[0].commandIdMatches?.length);
|
||||||
|
});
|
||||||
|
|
||||||
|
test('filter modifiers are not matched when not completely matched (includes)', async () => {
|
||||||
|
testObject = instantiationService.createInstance(KeybindingsEditorModel, OperatingSystem.Macintosh);
|
||||||
|
const term = `abcaltdef.${uuid.generateUuid()}`;
|
||||||
|
const command = `command.${term}`;
|
||||||
|
const expected = aResolvedKeybindingItem({ command, firstPart: { keyCode: KeyCode.Escape }, isDefault: false });
|
||||||
|
prepareKeybindingService(expected, aResolvedKeybindingItem({ command: 'some_command', firstPart: { keyCode: KeyCode.Escape, modifiers: { altKey: true } }, isDefault: false }));
|
||||||
|
|
||||||
|
await testObject.resolve(new Map<string, string>());
|
||||||
|
const actual = testObject.fetch(term);
|
||||||
|
assert.equal(1, actual.length);
|
||||||
|
assert.equal(command, actual[0].keybindingItem.command);
|
||||||
|
assert.equal(1, actual[0].commandIdMatches?.length);
|
||||||
|
});
|
||||||
|
|
||||||
|
test('filter modifiers are matched with complete term', async () => {
|
||||||
|
testObject = instantiationService.createInstance(KeybindingsEditorModel, OperatingSystem.Macintosh);
|
||||||
|
const command = `command.${uuid.generateUuid()}`;
|
||||||
|
const expected = aResolvedKeybindingItem({ command, firstPart: { keyCode: KeyCode.Escape, modifiers: { altKey: true } }, isDefault: false });
|
||||||
|
prepareKeybindingService(expected, aResolvedKeybindingItem({ command: 'some_command', firstPart: { keyCode: KeyCode.Escape }, isDefault: false }));
|
||||||
|
|
||||||
|
await testObject.resolve(new Map<string, string>());
|
||||||
|
const actual = testObject.fetch('alt').filter(element => element.keybindingItem.command === command);
|
||||||
|
assert.equal(1, actual.length);
|
||||||
|
assert.deepEqual(actual[0].keybindingMatches!.firstPart, { altKey: true });
|
||||||
|
});
|
||||||
|
|
||||||
function prepareKeybindingService(...keybindingItems: ResolvedKeybindingItem[]): ResolvedKeybindingItem[] {
|
function prepareKeybindingService(...keybindingItems: ResolvedKeybindingItem[]): ResolvedKeybindingItem[] {
|
||||||
instantiationService.stub(IKeybindingService, 'getKeybindings', () => keybindingItems);
|
instantiationService.stub(IKeybindingService, 'getKeybindings', () => keybindingItems);
|
||||||
instantiationService.stub(IKeybindingService, 'getDefaultKeybindings', () => keybindingItems);
|
instantiationService.stub(IKeybindingService, 'getDefaultKeybindings', () => keybindingItems);
|
||||||
|
|
|
@ -30,7 +30,7 @@ import { ITextModel } from 'vs/editor/common/model';
|
||||||
import { nullExtensionDescription, IExtensionService } from 'vs/workbench/services/extensions/common/extensions';
|
import { nullExtensionDescription, IExtensionService } from 'vs/workbench/services/extensions/common/extensions';
|
||||||
import { dispose } from 'vs/base/common/lifecycle';
|
import { dispose } from 'vs/base/common/lifecycle';
|
||||||
import { IEditorWorkerService } from 'vs/editor/common/services/editorWorkerService';
|
import { IEditorWorkerService } from 'vs/editor/common/services/editorWorkerService';
|
||||||
import { mock } from 'vs/workbench/test/browser/api/mock';
|
import { mock } from 'vs/base/test/common/mock';
|
||||||
import { NullApiDeprecationService } from 'vs/workbench/api/common/extHostApiDeprecationService';
|
import { NullApiDeprecationService } from 'vs/workbench/api/common/extHostApiDeprecationService';
|
||||||
import { ServiceCollection } from 'vs/platform/instantiation/common/serviceCollection';
|
import { ServiceCollection } from 'vs/platform/instantiation/common/serviceCollection';
|
||||||
import { SyncDescriptor } from 'vs/platform/instantiation/common/descriptors';
|
import { SyncDescriptor } from 'vs/platform/instantiation/common/descriptors';
|
||||||
|
|
|
@ -8,7 +8,7 @@ import { ExtHostCommands } from 'vs/workbench/api/common/extHostCommands';
|
||||||
import { MainThreadCommandsShape } from 'vs/workbench/api/common/extHost.protocol';
|
import { MainThreadCommandsShape } from 'vs/workbench/api/common/extHost.protocol';
|
||||||
import { CommandsRegistry } from 'vs/platform/commands/common/commands';
|
import { CommandsRegistry } from 'vs/platform/commands/common/commands';
|
||||||
import { SingleProxyRPCProtocol } from './testRPCProtocol';
|
import { SingleProxyRPCProtocol } from './testRPCProtocol';
|
||||||
import { mock } from 'vs/workbench/test/browser/api/mock';
|
import { mock } from 'vs/base/test/common/mock';
|
||||||
import { NullLogService } from 'vs/platform/log/common/log';
|
import { NullLogService } from 'vs/platform/log/common/log';
|
||||||
|
|
||||||
suite('ExtHostCommands', function () {
|
suite('ExtHostCommands', function () {
|
||||||
|
|
|
@ -10,7 +10,7 @@ import { ExtHostConfigProvider } from 'vs/workbench/api/common/extHostConfigurat
|
||||||
import { MainThreadConfigurationShape, IConfigurationInitData } from 'vs/workbench/api/common/extHost.protocol';
|
import { MainThreadConfigurationShape, IConfigurationInitData } from 'vs/workbench/api/common/extHost.protocol';
|
||||||
import { ConfigurationModel, ConfigurationModelParser } from 'vs/platform/configuration/common/configurationModels';
|
import { ConfigurationModel, ConfigurationModelParser } from 'vs/platform/configuration/common/configurationModels';
|
||||||
import { TestRPCProtocol } from './testRPCProtocol';
|
import { TestRPCProtocol } from './testRPCProtocol';
|
||||||
import { mock } from 'vs/workbench/test/browser/api/mock';
|
import { mock } from 'vs/base/test/common/mock';
|
||||||
import { IWorkspaceFolder, WorkspaceFolder } from 'vs/platform/workspace/common/workspace';
|
import { IWorkspaceFolder, WorkspaceFolder } from 'vs/platform/workspace/common/workspace';
|
||||||
import { ConfigurationTarget, IConfigurationModel, IConfigurationChange } from 'vs/platform/configuration/common/configuration';
|
import { ConfigurationTarget, IConfigurationModel, IConfigurationChange } from 'vs/platform/configuration/common/configuration';
|
||||||
import { NullLogService } from 'vs/platform/log/common/log';
|
import { NullLogService } from 'vs/platform/log/common/log';
|
||||||
|
|
|
@ -9,7 +9,7 @@ import { DiagnosticCollection, ExtHostDiagnostics } from 'vs/workbench/api/commo
|
||||||
import { Diagnostic, DiagnosticSeverity, Range, DiagnosticRelatedInformation, Location } from 'vs/workbench/api/common/extHostTypes';
|
import { Diagnostic, DiagnosticSeverity, Range, DiagnosticRelatedInformation, Location } from 'vs/workbench/api/common/extHostTypes';
|
||||||
import { MainThreadDiagnosticsShape, IMainContext } from 'vs/workbench/api/common/extHost.protocol';
|
import { MainThreadDiagnosticsShape, IMainContext } from 'vs/workbench/api/common/extHost.protocol';
|
||||||
import { IMarkerData, MarkerSeverity } from 'vs/platform/markers/common/markers';
|
import { IMarkerData, MarkerSeverity } from 'vs/platform/markers/common/markers';
|
||||||
import { mock } from 'vs/workbench/test/browser/api/mock';
|
import { mock } from 'vs/base/test/common/mock';
|
||||||
import { Emitter, Event } from 'vs/base/common/event';
|
import { Emitter, Event } from 'vs/base/common/event';
|
||||||
import { NullLogService } from 'vs/platform/log/common/log';
|
import { NullLogService } from 'vs/platform/log/common/log';
|
||||||
import type * as vscode from 'vscode';
|
import type * as vscode from 'vscode';
|
||||||
|
|
|
@ -10,7 +10,7 @@ import { Position } from 'vs/workbench/api/common/extHostTypes';
|
||||||
import { Range } from 'vs/editor/common/core/range';
|
import { Range } from 'vs/editor/common/core/range';
|
||||||
import { MainThreadDocumentsShape } from 'vs/workbench/api/common/extHost.protocol';
|
import { MainThreadDocumentsShape } from 'vs/workbench/api/common/extHost.protocol';
|
||||||
import { IModelChangedEvent } from 'vs/editor/common/model/mirrorTextModel';
|
import { IModelChangedEvent } from 'vs/editor/common/model/mirrorTextModel';
|
||||||
import { mock } from 'vs/workbench/test/browser/api/mock';
|
import { mock } from 'vs/base/test/common/mock';
|
||||||
|
|
||||||
|
|
||||||
suite('ExtHostDocumentData', () => {
|
suite('ExtHostDocumentData', () => {
|
||||||
|
|
|
@ -12,7 +12,7 @@ import { ExtHostDocumentSaveParticipant } from 'vs/workbench/api/common/extHostD
|
||||||
import { SingleProxyRPCProtocol } from './testRPCProtocol';
|
import { SingleProxyRPCProtocol } from './testRPCProtocol';
|
||||||
import { SaveReason } from 'vs/workbench/common/editor';
|
import { SaveReason } from 'vs/workbench/common/editor';
|
||||||
import type * as vscode from 'vscode';
|
import type * as vscode from 'vscode';
|
||||||
import { mock } from 'vs/workbench/test/browser/api/mock';
|
import { mock } from 'vs/base/test/common/mock';
|
||||||
import { NullLogService } from 'vs/platform/log/common/log';
|
import { NullLogService } from 'vs/platform/log/common/log';
|
||||||
import { timeout } from 'vs/base/common/async';
|
import { timeout } from 'vs/base/common/async';
|
||||||
import { ExtensionIdentifier, IExtensionDescription } from 'vs/platform/extensions/common/extensions';
|
import { ExtensionIdentifier, IExtensionDescription } from 'vs/platform/extensions/common/extensions';
|
||||||
|
|
|
@ -43,7 +43,7 @@ import { getColors } from 'vs/editor/contrib/colorPicker/color';
|
||||||
import { CancellationToken } from 'vs/base/common/cancellation';
|
import { CancellationToken } from 'vs/base/common/cancellation';
|
||||||
import { nullExtensionDescription as defaultExtension } from 'vs/workbench/services/extensions/common/extensions';
|
import { nullExtensionDescription as defaultExtension } from 'vs/workbench/services/extensions/common/extensions';
|
||||||
import { provideSelectionRanges } from 'vs/editor/contrib/smartSelect/smartSelect';
|
import { provideSelectionRanges } from 'vs/editor/contrib/smartSelect/smartSelect';
|
||||||
import { mock } from 'vs/workbench/test/browser/api/mock';
|
import { mock } from 'vs/base/test/common/mock';
|
||||||
import { IEditorWorkerService } from 'vs/editor/common/services/editorWorkerService';
|
import { IEditorWorkerService } from 'vs/editor/common/services/editorWorkerService';
|
||||||
import { dispose } from 'vs/base/common/lifecycle';
|
import { dispose } from 'vs/base/common/lifecycle';
|
||||||
import { withNullAsUndefined } from 'vs/base/common/types';
|
import { withNullAsUndefined } from 'vs/base/common/types';
|
||||||
|
|
|
@ -8,7 +8,7 @@ import { MainThreadMessageService } from 'vs/workbench/api/browser/mainThreadMes
|
||||||
import { IDialogService } from 'vs/platform/dialogs/common/dialogs';
|
import { IDialogService } from 'vs/platform/dialogs/common/dialogs';
|
||||||
import { INotificationService, INotification, NoOpNotification, INotificationHandle, Severity, IPromptChoice, IPromptOptions, IStatusMessageOptions, NotificationsFilter } from 'vs/platform/notification/common/notification';
|
import { INotificationService, INotification, NoOpNotification, INotificationHandle, Severity, IPromptChoice, IPromptOptions, IStatusMessageOptions, NotificationsFilter } from 'vs/platform/notification/common/notification';
|
||||||
import { ICommandService } from 'vs/platform/commands/common/commands';
|
import { ICommandService } from 'vs/platform/commands/common/commands';
|
||||||
import { mock } from 'vs/workbench/test/browser/api/mock';
|
import { mock } from 'vs/base/test/common/mock';
|
||||||
import { IDisposable, Disposable } from 'vs/base/common/lifecycle';
|
import { IDisposable, Disposable } from 'vs/base/common/lifecycle';
|
||||||
import * as platform from 'vs/base/common/platform';
|
import * as platform from 'vs/base/common/platform';
|
||||||
|
|
||||||
|
|
|
@ -9,7 +9,7 @@ import { MainThreadTextEditorsShape, IResolvedTextEditorConfiguration, ITextEdit
|
||||||
import { ExtHostTextEditorOptions, ExtHostTextEditor } from 'vs/workbench/api/common/extHostTextEditor';
|
import { ExtHostTextEditorOptions, ExtHostTextEditor } from 'vs/workbench/api/common/extHostTextEditor';
|
||||||
import { ExtHostDocumentData } from 'vs/workbench/api/common/extHostDocumentData';
|
import { ExtHostDocumentData } from 'vs/workbench/api/common/extHostDocumentData';
|
||||||
import { URI } from 'vs/base/common/uri';
|
import { URI } from 'vs/base/common/uri';
|
||||||
import { mock } from 'vs/workbench/test/browser/api/mock';
|
import { mock } from 'vs/base/test/common/mock';
|
||||||
import { NullLogService } from 'vs/platform/log/common/log';
|
import { NullLogService } from 'vs/platform/log/common/log';
|
||||||
|
|
||||||
suite('ExtHostTextEditor', () => {
|
suite('ExtHostTextEditor', () => {
|
||||||
|
|
|
@ -6,7 +6,7 @@ import * as assert from 'assert';
|
||||||
import * as extHostTypes from 'vs/workbench/api/common/extHostTypes';
|
import * as extHostTypes from 'vs/workbench/api/common/extHostTypes';
|
||||||
import { MainContext, MainThreadTextEditorsShape, IWorkspaceEditDto } from 'vs/workbench/api/common/extHost.protocol';
|
import { MainContext, MainThreadTextEditorsShape, IWorkspaceEditDto } from 'vs/workbench/api/common/extHost.protocol';
|
||||||
import { URI } from 'vs/base/common/uri';
|
import { URI } from 'vs/base/common/uri';
|
||||||
import { mock } from 'vs/workbench/test/browser/api/mock';
|
import { mock } from 'vs/base/test/common/mock';
|
||||||
import { ExtHostDocumentsAndEditors } from 'vs/workbench/api/common/extHostDocumentsAndEditors';
|
import { ExtHostDocumentsAndEditors } from 'vs/workbench/api/common/extHostDocumentsAndEditors';
|
||||||
import { SingleProxyRPCProtocol, TestRPCProtocol } from 'vs/workbench/test/browser/api/testRPCProtocol';
|
import { SingleProxyRPCProtocol, TestRPCProtocol } from 'vs/workbench/test/browser/api/testRPCProtocol';
|
||||||
import { ExtHostEditors } from 'vs/workbench/api/common/extHostTextEditors';
|
import { ExtHostEditors } from 'vs/workbench/api/common/extHostTextEditors';
|
||||||
|
|
|
@ -14,7 +14,7 @@ import { TestRPCProtocol } from './testRPCProtocol';
|
||||||
import { TestInstantiationService } from 'vs/platform/instantiation/test/common/instantiationServiceMock';
|
import { TestInstantiationService } from 'vs/platform/instantiation/test/common/instantiationServiceMock';
|
||||||
import { MainThreadCommands } from 'vs/workbench/api/browser/mainThreadCommands';
|
import { MainThreadCommands } from 'vs/workbench/api/browser/mainThreadCommands';
|
||||||
import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation';
|
import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation';
|
||||||
import { mock } from 'vs/workbench/test/browser/api/mock';
|
import { mock } from 'vs/base/test/common/mock';
|
||||||
import { TreeItemCollapsibleState, ITreeItem } from 'vs/workbench/common/views';
|
import { TreeItemCollapsibleState, ITreeItem } from 'vs/workbench/common/views';
|
||||||
import { NullLogService } from 'vs/platform/log/common/log';
|
import { NullLogService } from 'vs/platform/log/common/log';
|
||||||
import { IExtensionDescription } from 'vs/platform/extensions/common/extensions';
|
import { IExtensionDescription } from 'vs/platform/extensions/common/extensions';
|
||||||
|
|
|
@ -11,7 +11,7 @@ import { NullLogService } from 'vs/platform/log/common/log';
|
||||||
import { MainThreadWebviews } from 'vs/workbench/api/browser/mainThreadWebview';
|
import { MainThreadWebviews } from 'vs/workbench/api/browser/mainThreadWebview';
|
||||||
import { ExtHostWebviews } from 'vs/workbench/api/common/extHostWebview';
|
import { ExtHostWebviews } from 'vs/workbench/api/common/extHostWebview';
|
||||||
import { EditorViewColumn } from 'vs/workbench/api/common/shared/editor';
|
import { EditorViewColumn } from 'vs/workbench/api/common/shared/editor';
|
||||||
import { mock } from 'vs/workbench/test/browser/api/mock';
|
import { mock } from 'vs/base/test/common/mock';
|
||||||
import { SingleProxyRPCProtocol } from './testRPCProtocol';
|
import { SingleProxyRPCProtocol } from './testRPCProtocol';
|
||||||
import { ExtHostDocumentsAndEditors } from 'vs/workbench/api/common/extHostDocumentsAndEditors';
|
import { ExtHostDocumentsAndEditors } from 'vs/workbench/api/common/extHostDocumentsAndEditors';
|
||||||
import { ExtHostDocuments } from 'vs/workbench/api/common/extHostDocuments';
|
import { ExtHostDocuments } from 'vs/workbench/api/common/extHostDocuments';
|
||||||
|
|
|
@ -14,7 +14,7 @@ import { MainThreadWorkspace } from 'vs/workbench/api/browser/mainThreadWorkspac
|
||||||
import { IMainContext, IWorkspaceData, MainContext, ITextSearchComplete } from 'vs/workbench/api/common/extHost.protocol';
|
import { IMainContext, IWorkspaceData, MainContext, ITextSearchComplete } from 'vs/workbench/api/common/extHost.protocol';
|
||||||
import { RelativePattern } from 'vs/workbench/api/common/extHostTypes';
|
import { RelativePattern } from 'vs/workbench/api/common/extHostTypes';
|
||||||
import { ExtHostWorkspace } from 'vs/workbench/api/common/extHostWorkspace';
|
import { ExtHostWorkspace } from 'vs/workbench/api/common/extHostWorkspace';
|
||||||
import { mock } from 'vs/workbench/test/browser/api/mock';
|
import { mock } from 'vs/base/test/common/mock';
|
||||||
import { TestRPCProtocol } from './testRPCProtocol';
|
import { TestRPCProtocol } from './testRPCProtocol';
|
||||||
import { ExtHostRpcService } from 'vs/workbench/api/common/extHostRpcService';
|
import { ExtHostRpcService } from 'vs/workbench/api/common/extHostRpcService';
|
||||||
import { IExtHostInitDataService } from 'vs/workbench/api/common/extHostInitDataService';
|
import { IExtHostInitDataService } from 'vs/workbench/api/common/extHostInitDataService';
|
||||||
|
|
|
@ -8,7 +8,7 @@ import { MainThreadCommands } from 'vs/workbench/api/browser/mainThreadCommands'
|
||||||
import { CommandsRegistry, ICommandService } from 'vs/platform/commands/common/commands';
|
import { CommandsRegistry, ICommandService } from 'vs/platform/commands/common/commands';
|
||||||
import { SingleProxyRPCProtocol } from './testRPCProtocol';
|
import { SingleProxyRPCProtocol } from './testRPCProtocol';
|
||||||
import { IExtensionService } from 'vs/workbench/services/extensions/common/extensions';
|
import { IExtensionService } from 'vs/workbench/services/extensions/common/extensions';
|
||||||
import { mock } from 'vs/workbench/test/browser/api/mock';
|
import { mock } from 'vs/base/test/common/mock';
|
||||||
|
|
||||||
suite('MainThreadCommands', function () {
|
suite('MainThreadCommands', function () {
|
||||||
|
|
||||||
|
|
|
@ -7,7 +7,7 @@ import * as assert from 'assert';
|
||||||
import { URI } from 'vs/base/common/uri';
|
import { URI } from 'vs/base/common/uri';
|
||||||
import { MainThreadDocumentContentProviders } from 'vs/workbench/api/browser/mainThreadDocumentContentProviders';
|
import { MainThreadDocumentContentProviders } from 'vs/workbench/api/browser/mainThreadDocumentContentProviders';
|
||||||
import { createTextModel } from 'vs/editor/test/common/editorTestUtils';
|
import { createTextModel } from 'vs/editor/test/common/editorTestUtils';
|
||||||
import { mock } from 'vs/workbench/test/browser/api/mock';
|
import { mock } from 'vs/base/test/common/mock';
|
||||||
import { IModelService } from 'vs/editor/common/services/modelService';
|
import { IModelService } from 'vs/editor/common/services/modelService';
|
||||||
import { IEditorWorkerService } from 'vs/editor/common/services/editorWorkerService';
|
import { IEditorWorkerService } from 'vs/editor/common/services/editorWorkerService';
|
||||||
import { TestRPCProtocol } from 'vs/workbench/test/browser/api/testRPCProtocol';
|
import { TestRPCProtocol } from 'vs/workbench/test/browser/api/testRPCProtocol';
|
||||||
|
|
|
@ -12,7 +12,7 @@ import { TestCodeEditorService } from 'vs/editor/test/browser/editorTestServices
|
||||||
import { ITextFileService } from 'vs/workbench/services/textfile/common/textfiles';
|
import { ITextFileService } from 'vs/workbench/services/textfile/common/textfiles';
|
||||||
import { ExtHostDocumentsAndEditorsShape, IDocumentsAndEditorsDelta } from 'vs/workbench/api/common/extHost.protocol';
|
import { ExtHostDocumentsAndEditorsShape, IDocumentsAndEditorsDelta } from 'vs/workbench/api/common/extHost.protocol';
|
||||||
import { createTestCodeEditor, ITestCodeEditor } from 'vs/editor/test/browser/testCodeEditor';
|
import { createTestCodeEditor, ITestCodeEditor } from 'vs/editor/test/browser/testCodeEditor';
|
||||||
import { mock } from 'vs/workbench/test/browser/api/mock';
|
import { mock } from 'vs/base/test/common/mock';
|
||||||
import { TestEditorService, TestEditorGroupsService, TestEnvironmentService } from 'vs/workbench/test/browser/workbenchTestServices';
|
import { TestEditorService, TestEditorGroupsService, TestEnvironmentService } from 'vs/workbench/test/browser/workbenchTestServices';
|
||||||
import { Event } from 'vs/base/common/event';
|
import { Event } from 'vs/base/common/event';
|
||||||
import { ITextModel } from 'vs/editor/common/model';
|
import { ITextModel } from 'vs/editor/common/model';
|
||||||
|
|
|
@ -11,7 +11,7 @@ import { ModelServiceImpl } from 'vs/editor/common/services/modelServiceImpl';
|
||||||
import { TestCodeEditorService } from 'vs/editor/test/browser/editorTestServices';
|
import { TestCodeEditorService } from 'vs/editor/test/browser/editorTestServices';
|
||||||
import { ITextFileService } from 'vs/workbench/services/textfile/common/textfiles';
|
import { ITextFileService } from 'vs/workbench/services/textfile/common/textfiles';
|
||||||
import { ExtHostDocumentsAndEditorsShape, ExtHostContext, ExtHostDocumentsShape, IWorkspaceTextEditDto } from 'vs/workbench/api/common/extHost.protocol';
|
import { ExtHostDocumentsAndEditorsShape, ExtHostContext, ExtHostDocumentsShape, IWorkspaceTextEditDto } from 'vs/workbench/api/common/extHost.protocol';
|
||||||
import { mock } from 'vs/workbench/test/browser/api/mock';
|
import { mock } from 'vs/base/test/common/mock';
|
||||||
import { Event } from 'vs/base/common/event';
|
import { Event } from 'vs/base/common/event';
|
||||||
import { MainThreadTextEditors } from 'vs/workbench/api/browser/mainThreadEditors';
|
import { MainThreadTextEditors } from 'vs/workbench/api/browser/mainThreadEditors';
|
||||||
import { URI } from 'vs/base/common/uri';
|
import { URI } from 'vs/base/common/uri';
|
||||||
|
|
|
@ -19,7 +19,7 @@ import { TestRPCProtocol } from 'vs/workbench/test/browser/api/testRPCProtocol';
|
||||||
import type * as vscode from 'vscode';
|
import type * as vscode from 'vscode';
|
||||||
import { NullLogService } from 'vs/platform/log/common/log';
|
import { NullLogService } from 'vs/platform/log/common/log';
|
||||||
import { URITransformerService } from 'vs/workbench/api/common/extHostUriTransformerService';
|
import { URITransformerService } from 'vs/workbench/api/common/extHostUriTransformerService';
|
||||||
import { mock } from 'vs/workbench/test/browser/api/mock';
|
import { mock } from 'vs/base/test/common/mock';
|
||||||
import { IExtHostInitDataService } from 'vs/workbench/api/common/extHostInitDataService';
|
import { IExtHostInitDataService } from 'vs/workbench/api/common/extHostInitDataService';
|
||||||
import { TextSearchManager } from 'vs/workbench/services/search/common/textSearchManager';
|
import { TextSearchManager } from 'vs/workbench/services/search/common/textSearchManager';
|
||||||
import { NativeTextSearchManager } from 'vs/workbench/services/search/node/textSearchManager';
|
import { NativeTextSearchManager } from 'vs/workbench/services/search/node/textSearchManager';
|
||||||
|
|
Loading…
Reference in a new issue